LLDB mainline
ObjectFileMachO.cpp
Go to the documentation of this file.
1//===-- ObjectFileMachO.cpp -----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ADT/ScopeExit.h"
10#include "llvm/ADT/StringRef.h"
11
12#include <algorithm>
13
18#include "lldb/Core/Debugger.h"
19#include "lldb/Core/Module.h"
22#include "lldb/Core/Progress.h"
23#include "lldb/Core/Section.h"
24#include "lldb/Host/Host.h"
30#include "lldb/Target/Process.h"
32#include "lldb/Target/Target.h"
33#include "lldb/Target/Thread.h"
40#include "lldb/Utility/Log.h"
43#include "lldb/Utility/Status.h"
45#include "lldb/Utility/Timer.h"
46#include "lldb/Utility/UUID.h"
47
48#include "lldb/Host/SafeMachO.h"
49
50#include "llvm/ADT/DenseSet.h"
51#include "llvm/Support/Compression.h"
52#include "llvm/Support/Endian.h"
53#include "llvm/Support/FormatVariadic.h"
54#include "llvm/Support/MemoryBuffer.h"
55
56#include "MachOTrie.h"
57#include "ObjectFileMachO.h"
58
59#if defined(__APPLE__)
60#include <TargetConditionals.h>
61// GetLLDBSharedCacheUUID() needs to call dlsym()
62#include <dlfcn.h>
63#include <mach/mach_init.h>
64#include <mach/vm_map.h>
65#include <lldb/Host/SafeMachO.h>
66#endif
67
68#ifndef __APPLE__
70#else
71#include <uuid/uuid.h>
72#endif
73
74#include <bitset>
75#include <memory>
76#include <optional>
77
78// Unfortunately the signpost header pulls in the system MachO header, too.
79#ifdef CPU_TYPE_ARM
80#undef CPU_TYPE_ARM
81#endif
82#ifdef CPU_TYPE_ARM64
83#undef CPU_TYPE_ARM64
84#endif
85#ifdef CPU_TYPE_ARM64_32
86#undef CPU_TYPE_ARM64_32
87#endif
88#ifdef CPU_TYPE_X86_64
89#undef CPU_TYPE_X86_64
90#endif
91#ifdef MH_DYLINKER
92#undef MH_DYLINKER
93#endif
94#ifdef MH_OBJECT
95#undef MH_OBJECT
96#endif
97#ifdef LC_VERSION_MIN_MACOSX
98#undef LC_VERSION_MIN_MACOSX
99#endif
100#ifdef LC_VERSION_MIN_IPHONEOS
101#undef LC_VERSION_MIN_IPHONEOS
102#endif
103#ifdef LC_VERSION_MIN_TVOS
104#undef LC_VERSION_MIN_TVOS
105#endif
106#ifdef LC_VERSION_MIN_WATCHOS
107#undef LC_VERSION_MIN_WATCHOS
108#endif
109#ifdef LC_BUILD_VERSION
110#undef LC_BUILD_VERSION
111#endif
112#ifdef PLATFORM_MACOS
113#undef PLATFORM_MACOS
114#endif
115#ifdef PLATFORM_MACCATALYST
116#undef PLATFORM_MACCATALYST
117#endif
118#ifdef PLATFORM_IOS
119#undef PLATFORM_IOS
120#endif
121#ifdef PLATFORM_IOSSIMULATOR
122#undef PLATFORM_IOSSIMULATOR
123#endif
124#ifdef PLATFORM_TVOS
125#undef PLATFORM_TVOS
126#endif
127#ifdef PLATFORM_TVOSSIMULATOR
128#undef PLATFORM_TVOSSIMULATOR
129#endif
130#ifdef PLATFORM_WATCHOS
131#undef PLATFORM_WATCHOS
132#endif
133#ifdef PLATFORM_WATCHOSSIMULATOR
134#undef PLATFORM_WATCHOSSIMULATOR
135#endif
136
137using namespace lldb;
138using namespace lldb_private;
139using namespace llvm::MachO;
140
141static constexpr llvm::StringLiteral g_loader_path = "@loader_path";
142static constexpr llvm::StringLiteral g_executable_path = "@executable_path";
143
145
146/// Read a Mach-O load-command header (cmd + cmdsize) from \p data at
147/// \p offset into \p cmd, advancing \p offset by 8 bytes. \p T may be
148/// \c llvm::MachO::load_command or any of its richer variants
149/// (\c thread_command, \c dylib_command, \c encryption_info_command, ...);
150/// only the leading cmd/cmdsize fields are touched by this read. Returns
151/// false on EOF or on a cmdsize smaller than sizeof(load_command), in which
152/// case callers should break out of their load-command loop to avoid spinning
153/// on malformed input.
154template <typename T>
155static bool ReadMachOCommand(const DataExtractor &data, lldb::offset_t &offset,
156 T &cmd) {
157 static_assert(offsetof(T, cmd) == 0, "T::cmd must be the first field");
158 static_assert(offsetof(T, cmdsize) == sizeof(uint32_t),
159 "T::cmdsize must immediately follow T::cmd");
160 static_assert(std::is_same<decltype(T::cmd), uint32_t>::value,
161 "T::cmd must be uint32_t");
162 static_assert(std::is_same<decltype(T::cmdsize), uint32_t>::value,
163 "T::cmdsize must be uint32_t");
164 if (data.GetU32(&offset, &cmd, 2) == nullptr)
165 return false;
166 if (cmd.cmdsize < sizeof(load_command))
167 return false;
168 return true;
169}
170
171static void PrintRegisterValue(RegisterContext *reg_ctx, const char *name,
172 const char *alt_name, size_t reg_byte_size,
173 Stream &data) {
174 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
175 if (reg_info == nullptr)
176 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
177 if (reg_info) {
179 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
180 if (reg_info->byte_size >= reg_byte_size)
181 data.Write(reg_value.GetBytes(), reg_byte_size);
182 else {
183 data.Write(reg_value.GetBytes(), reg_info->byte_size);
184 for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n; ++i)
185 data.PutChar(0);
186 }
187 return;
188 }
189 }
190 // Just write zeros if all else fails
191 for (size_t i = 0; i < reg_byte_size; ++i)
192 data.PutChar(0);
193}
194
196public:
202
203 void InvalidateAllRegisters() override {
204 // Do nothing... registers are always valid...
205 }
206
208 lldb::offset_t offset = 0;
209 SetError(GPRRegSet, Read, -1);
210 SetError(FPURegSet, Read, -1);
211 SetError(EXCRegSet, Read, -1);
212
213 while (offset < data.GetByteSize()) {
214 int flavor = data.GetU32(&offset);
215 if (flavor == 0)
216 break;
217 uint32_t count = data.GetU32(&offset);
218 switch (flavor) {
219 case GPRRegSet: {
220 uint32_t *gpr_data = reinterpret_cast<uint32_t *>(&gpr.rax);
221 for (uint32_t i = 0; i < count && offset < data.GetByteSize(); ++i)
222 gpr_data[i] = data.GetU32(&offset);
224 } break;
225 case FPURegSet:
226 // TODO: fill in FPU regs....
227 SetError(FPURegSet, Read, -1);
228 break;
229 case EXCRegSet:
230 exc.trapno = data.GetU32(&offset);
231 exc.err = data.GetU32(&offset);
232 exc.faultvaddr = data.GetU64(&offset);
234 break;
235 default:
236 offset += count * 4;
237 break;
238 }
239 }
240 }
241
242 static bool Create_LC_THREAD(Thread *thread, Stream &data) {
243 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
244 if (reg_ctx_sp) {
245 RegisterContext *reg_ctx = reg_ctx_sp.get();
246
247 data.PutHex32(GPRRegSet); // Flavor
249 PrintRegisterValue(reg_ctx, "rax", nullptr, 8, data);
250 PrintRegisterValue(reg_ctx, "rbx", nullptr, 8, data);
251 PrintRegisterValue(reg_ctx, "rcx", nullptr, 8, data);
252 PrintRegisterValue(reg_ctx, "rdx", nullptr, 8, data);
253 PrintRegisterValue(reg_ctx, "rdi", nullptr, 8, data);
254 PrintRegisterValue(reg_ctx, "rsi", nullptr, 8, data);
255 PrintRegisterValue(reg_ctx, "rbp", nullptr, 8, data);
256 PrintRegisterValue(reg_ctx, "rsp", nullptr, 8, data);
257 PrintRegisterValue(reg_ctx, "r8", nullptr, 8, data);
258 PrintRegisterValue(reg_ctx, "r9", nullptr, 8, data);
259 PrintRegisterValue(reg_ctx, "r10", nullptr, 8, data);
260 PrintRegisterValue(reg_ctx, "r11", nullptr, 8, data);
261 PrintRegisterValue(reg_ctx, "r12", nullptr, 8, data);
262 PrintRegisterValue(reg_ctx, "r13", nullptr, 8, data);
263 PrintRegisterValue(reg_ctx, "r14", nullptr, 8, data);
264 PrintRegisterValue(reg_ctx, "r15", nullptr, 8, data);
265 PrintRegisterValue(reg_ctx, "rip", nullptr, 8, data);
266 PrintRegisterValue(reg_ctx, "rflags", nullptr, 8, data);
267 PrintRegisterValue(reg_ctx, "cs", nullptr, 8, data);
268 PrintRegisterValue(reg_ctx, "fs", nullptr, 8, data);
269 PrintRegisterValue(reg_ctx, "gs", nullptr, 8, data);
270
271 // // Write out the FPU registers
272 // const size_t fpu_byte_size = sizeof(FPU);
273 // size_t bytes_written = 0;
274 // data.PutHex32 (FPURegSet);
275 // data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
276 // bytes_written += data.PutHex32(0); // uint32_t pad[0]
277 // bytes_written += data.PutHex32(0); // uint32_t pad[1]
278 // bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2,
279 // data); // uint16_t fcw; // "fctrl"
280 // bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2,
281 // data); // uint16_t fsw; // "fstat"
282 // bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1,
283 // data); // uint8_t ftw; // "ftag"
284 // bytes_written += data.PutHex8 (0); // uint8_t pad1;
285 // bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2,
286 // data); // uint16_t fop; // "fop"
287 // bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4,
288 // data); // uint32_t ip; // "fioff"
289 // bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2,
290 // data); // uint16_t cs; // "fiseg"
291 // bytes_written += data.PutHex16 (0); // uint16_t pad2;
292 // bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4,
293 // data); // uint32_t dp; // "fooff"
294 // bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2,
295 // data); // uint16_t ds; // "foseg"
296 // bytes_written += data.PutHex16 (0); // uint16_t pad3;
297 // bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4,
298 // data); // uint32_t mxcsr;
299 // bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL,
300 // 4, data);// uint32_t mxcsrmask;
301 // bytes_written += WriteRegister (reg_ctx, "stmm0", NULL,
302 // sizeof(MMSReg), data);
303 // bytes_written += WriteRegister (reg_ctx, "stmm1", NULL,
304 // sizeof(MMSReg), data);
305 // bytes_written += WriteRegister (reg_ctx, "stmm2", NULL,
306 // sizeof(MMSReg), data);
307 // bytes_written += WriteRegister (reg_ctx, "stmm3", NULL,
308 // sizeof(MMSReg), data);
309 // bytes_written += WriteRegister (reg_ctx, "stmm4", NULL,
310 // sizeof(MMSReg), data);
311 // bytes_written += WriteRegister (reg_ctx, "stmm5", NULL,
312 // sizeof(MMSReg), data);
313 // bytes_written += WriteRegister (reg_ctx, "stmm6", NULL,
314 // sizeof(MMSReg), data);
315 // bytes_written += WriteRegister (reg_ctx, "stmm7", NULL,
316 // sizeof(MMSReg), data);
317 // bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL,
318 // sizeof(XMMReg), data);
319 // bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL,
320 // sizeof(XMMReg), data);
321 // bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL,
322 // sizeof(XMMReg), data);
323 // bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL,
324 // sizeof(XMMReg), data);
325 // bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL,
326 // sizeof(XMMReg), data);
327 // bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL,
328 // sizeof(XMMReg), data);
329 // bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL,
330 // sizeof(XMMReg), data);
331 // bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL,
332 // sizeof(XMMReg), data);
333 // bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL,
334 // sizeof(XMMReg), data);
335 // bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL,
336 // sizeof(XMMReg), data);
337 // bytes_written += WriteRegister (reg_ctx, "xmm10", NULL,
338 // sizeof(XMMReg), data);
339 // bytes_written += WriteRegister (reg_ctx, "xmm11", NULL,
340 // sizeof(XMMReg), data);
341 // bytes_written += WriteRegister (reg_ctx, "xmm12", NULL,
342 // sizeof(XMMReg), data);
343 // bytes_written += WriteRegister (reg_ctx, "xmm13", NULL,
344 // sizeof(XMMReg), data);
345 // bytes_written += WriteRegister (reg_ctx, "xmm14", NULL,
346 // sizeof(XMMReg), data);
347 // bytes_written += WriteRegister (reg_ctx, "xmm15", NULL,
348 // sizeof(XMMReg), data);
349 //
350 // // Fill rest with zeros
351 // for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++
352 // i)
353 // data.PutChar(0);
354
355 // Write out the EXC registers
356 data.PutHex32(EXCRegSet);
358 PrintRegisterValue(reg_ctx, "trapno", nullptr, 4, data);
359 PrintRegisterValue(reg_ctx, "err", nullptr, 4, data);
360 PrintRegisterValue(reg_ctx, "faultvaddr", nullptr, 8, data);
361 return true;
362 }
363 return false;
364 }
365
366protected:
367 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
368
369 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
370
371 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
372
373 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
374 return 0;
375 }
376
377 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
378 return 0;
379 }
380
381 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
382 return 0;
383 }
384};
385
387public:
393
394 void InvalidateAllRegisters() override {
395 // Do nothing... registers are always valid...
396 }
397
399 lldb::offset_t offset = 0;
400 SetError(GPRRegSet, Read, -1);
401 SetError(FPURegSet, Read, -1);
402 SetError(EXCRegSet, Read, -1);
403
404 while (offset < data.GetByteSize()) {
405 int flavor = data.GetU32(&offset);
406 uint32_t count = data.GetU32(&offset);
407 offset_t next_thread_state = offset + (count * 4);
408 switch (flavor) {
409 case GPRAltRegSet:
410 case GPRRegSet: {
411 // r0-r15, plus CPSR
412 uint32_t gpr_buf_count = (sizeof(gpr.r) / sizeof(gpr.r[0])) + 1;
413 if (count == gpr_buf_count) {
414 for (uint32_t i = 0; i < (count - 1); ++i) {
415 gpr.r[i] = data.GetU32(&offset);
416 }
417 gpr.cpsr = data.GetU32(&offset);
418
420 }
421 } break;
422
423 case FPURegSet: {
424 uint8_t *fpu_reg_buf = (uint8_t *)&fpu.floats;
425 const int fpu_reg_buf_size = sizeof(fpu.floats);
426 if (data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
427 fpu_reg_buf) == fpu_reg_buf_size) {
428 offset += fpu_reg_buf_size;
429 fpu.fpscr = data.GetU32(&offset);
431 }
432 } break;
433
434 case EXCRegSet:
435 if (count == 3) {
436 exc.exception = data.GetU32(&offset);
437 exc.fsr = data.GetU32(&offset);
438 exc.far = data.GetU32(&offset);
440 }
441 break;
442 }
443 offset = next_thread_state;
444 }
445 }
446
447 static bool Create_LC_THREAD(Thread *thread, Stream &data) {
448 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
449 if (reg_ctx_sp) {
450 RegisterContext *reg_ctx = reg_ctx_sp.get();
451
452 data.PutHex32(GPRRegSet); // Flavor
454 PrintRegisterValue(reg_ctx, "r0", nullptr, 4, data);
455 PrintRegisterValue(reg_ctx, "r1", nullptr, 4, data);
456 PrintRegisterValue(reg_ctx, "r2", nullptr, 4, data);
457 PrintRegisterValue(reg_ctx, "r3", nullptr, 4, data);
458 PrintRegisterValue(reg_ctx, "r4", nullptr, 4, data);
459 PrintRegisterValue(reg_ctx, "r5", nullptr, 4, data);
460 PrintRegisterValue(reg_ctx, "r6", nullptr, 4, data);
461 PrintRegisterValue(reg_ctx, "r7", nullptr, 4, data);
462 PrintRegisterValue(reg_ctx, "r8", nullptr, 4, data);
463 PrintRegisterValue(reg_ctx, "r9", nullptr, 4, data);
464 PrintRegisterValue(reg_ctx, "r10", nullptr, 4, data);
465 PrintRegisterValue(reg_ctx, "r11", nullptr, 4, data);
466 PrintRegisterValue(reg_ctx, "r12", nullptr, 4, data);
467 PrintRegisterValue(reg_ctx, "sp", nullptr, 4, data);
468 PrintRegisterValue(reg_ctx, "lr", nullptr, 4, data);
469 PrintRegisterValue(reg_ctx, "pc", nullptr, 4, data);
470 PrintRegisterValue(reg_ctx, "cpsr", nullptr, 4, data);
471
472 // Write out the EXC registers
473 // data.PutHex32 (EXCRegSet);
474 // data.PutHex32 (EXCWordCount);
475 // WriteRegister (reg_ctx, "exception", NULL, 4, data);
476 // WriteRegister (reg_ctx, "fsr", NULL, 4, data);
477 // WriteRegister (reg_ctx, "far", NULL, 4, data);
478 return true;
479 }
480 return false;
481 }
482
483protected:
484 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
485
486 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
487
488 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
489
490 int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }
491
492 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
493 return 0;
494 }
495
496 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
497 return 0;
498 }
499
500 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
501 return 0;
502 }
503
504 int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
505 return -1;
506 }
507};
508
510public:
516
517 void InvalidateAllRegisters() override {
518 // Do nothing... registers are always valid...
519 }
520
522 lldb::offset_t offset = 0;
523 SetError(GPRRegSet, Read, -1);
524 SetError(FPURegSet, Read, -1);
525 SetError(EXCRegSet, Read, -1);
526 while (offset < data.GetByteSize()) {
527 int flavor = data.GetU32(&offset);
528 uint32_t count = data.GetU32(&offset);
529 offset_t next_thread_state = offset + (count * 4);
530 switch (flavor) {
531 case GPRRegSet:
532 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1
533 // 32-bit register)
534 if (count >= (33 * 2) + 1) {
535 for (uint32_t i = 0; i < 29; ++i)
536 gpr.x[i] = data.GetU64(&offset);
537 gpr.fp = data.GetU64(&offset);
538 gpr.lr = data.GetU64(&offset);
539 gpr.sp = data.GetU64(&offset);
540 gpr.pc = data.GetU64(&offset);
541 gpr.cpsr = data.GetU32(&offset);
543 }
544 break;
545 case FPURegSet: {
546 uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0];
547 const int fpu_reg_buf_size = sizeof(fpu);
548 if (fpu_reg_buf_size == count * sizeof(uint32_t) &&
549 data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
550 fpu_reg_buf) == fpu_reg_buf_size) {
552 }
553 } break;
554 case EXCRegSet:
555 if (count == 4) {
556 exc.far = data.GetU64(&offset);
557 exc.esr = data.GetU32(&offset);
558 exc.exception = data.GetU32(&offset);
560 }
561 break;
562 }
563 offset = next_thread_state;
564 }
565 }
566
567 static bool Create_LC_THREAD(Thread *thread, Stream &data) {
568 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
569 if (reg_ctx_sp) {
570 RegisterContext *reg_ctx = reg_ctx_sp.get();
571
572 data.PutHex32(GPRRegSet); // Flavor
574 PrintRegisterValue(reg_ctx, "x0", nullptr, 8, data);
575 PrintRegisterValue(reg_ctx, "x1", nullptr, 8, data);
576 PrintRegisterValue(reg_ctx, "x2", nullptr, 8, data);
577 PrintRegisterValue(reg_ctx, "x3", nullptr, 8, data);
578 PrintRegisterValue(reg_ctx, "x4", nullptr, 8, data);
579 PrintRegisterValue(reg_ctx, "x5", nullptr, 8, data);
580 PrintRegisterValue(reg_ctx, "x6", nullptr, 8, data);
581 PrintRegisterValue(reg_ctx, "x7", nullptr, 8, data);
582 PrintRegisterValue(reg_ctx, "x8", nullptr, 8, data);
583 PrintRegisterValue(reg_ctx, "x9", nullptr, 8, data);
584 PrintRegisterValue(reg_ctx, "x10", nullptr, 8, data);
585 PrintRegisterValue(reg_ctx, "x11", nullptr, 8, data);
586 PrintRegisterValue(reg_ctx, "x12", nullptr, 8, data);
587 PrintRegisterValue(reg_ctx, "x13", nullptr, 8, data);
588 PrintRegisterValue(reg_ctx, "x14", nullptr, 8, data);
589 PrintRegisterValue(reg_ctx, "x15", nullptr, 8, data);
590 PrintRegisterValue(reg_ctx, "x16", nullptr, 8, data);
591 PrintRegisterValue(reg_ctx, "x17", nullptr, 8, data);
592 PrintRegisterValue(reg_ctx, "x18", nullptr, 8, data);
593 PrintRegisterValue(reg_ctx, "x19", nullptr, 8, data);
594 PrintRegisterValue(reg_ctx, "x20", nullptr, 8, data);
595 PrintRegisterValue(reg_ctx, "x21", nullptr, 8, data);
596 PrintRegisterValue(reg_ctx, "x22", nullptr, 8, data);
597 PrintRegisterValue(reg_ctx, "x23", nullptr, 8, data);
598 PrintRegisterValue(reg_ctx, "x24", nullptr, 8, data);
599 PrintRegisterValue(reg_ctx, "x25", nullptr, 8, data);
600 PrintRegisterValue(reg_ctx, "x26", nullptr, 8, data);
601 PrintRegisterValue(reg_ctx, "x27", nullptr, 8, data);
602 PrintRegisterValue(reg_ctx, "x28", nullptr, 8, data);
603 PrintRegisterValue(reg_ctx, "fp", nullptr, 8, data);
604 PrintRegisterValue(reg_ctx, "lr", nullptr, 8, data);
605 PrintRegisterValue(reg_ctx, "sp", nullptr, 8, data);
606 PrintRegisterValue(reg_ctx, "pc", nullptr, 8, data);
607 PrintRegisterValue(reg_ctx, "cpsr", nullptr, 4, data);
608 data.PutHex32(0); // uint32_t pad at the end
609
610 // Write out the EXC registers
611 data.PutHex32(EXCRegSet);
613 PrintRegisterValue(reg_ctx, "far", nullptr, 8, data);
614 PrintRegisterValue(reg_ctx, "esr", nullptr, 4, data);
615 PrintRegisterValue(reg_ctx, "exception", nullptr, 4, data);
616 return true;
617 }
618 return false;
619 }
620
621protected:
622 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
623
624 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
625
626 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
627
628 int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }
629
630 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
631 return 0;
632 }
633
634 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
635 return 0;
636 }
637
638 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
639 return 0;
640 }
641
642 int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
643 return -1;
644 }
645};
646
649public:
655
656 void InvalidateAllRegisters() override {
657 // Do nothing... registers are always valid...
658 }
659
661 lldb::offset_t offset = 0;
662 SetError(GPRRegSet, Read, -1);
663 SetError(FPURegSet, Read, -1);
664 SetError(EXCRegSet, Read, -1);
665 SetError(CSRRegSet, Read, -1);
666 while (offset < data.GetByteSize()) {
667 int flavor = data.GetU32(&offset);
668 uint32_t count = data.GetU32(&offset);
669 offset_t next_thread_state = offset + (count * 4);
670 switch (flavor) {
671 case GPRRegSet:
672 // x0-x31 + pc
673 if (count >= 32) {
674 for (uint32_t i = 0; i < 32; ++i)
675 ((uint32_t *)&gpr.x0)[i] = data.GetU32(&offset);
676 gpr.pc = data.GetU32(&offset);
678 }
679 break;
680 case FPURegSet: {
681 // f0-f31 + fcsr
682 if (count >= 32) {
683 for (uint32_t i = 0; i < 32; ++i)
684 ((uint32_t *)&fpr.f0)[i] = data.GetU32(&offset);
685 fpr.fcsr = data.GetU32(&offset);
687 }
688 } break;
689 case EXCRegSet:
690 if (count == 3) {
691 exc.exception = data.GetU32(&offset);
692 exc.fsr = data.GetU32(&offset);
693 exc.far = data.GetU32(&offset);
695 }
696 break;
697 }
698 offset = next_thread_state;
699 }
700 }
701
702 static bool Create_LC_THREAD(Thread *thread, Stream &data) {
703 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
704 if (reg_ctx_sp) {
705 RegisterContext *reg_ctx = reg_ctx_sp.get();
706
707 data.PutHex32(GPRRegSet); // Flavor
709 PrintRegisterValue(reg_ctx, "x0", nullptr, 4, data);
710 PrintRegisterValue(reg_ctx, "x1", nullptr, 4, data);
711 PrintRegisterValue(reg_ctx, "x2", nullptr, 4, data);
712 PrintRegisterValue(reg_ctx, "x3", nullptr, 4, data);
713 PrintRegisterValue(reg_ctx, "x4", nullptr, 4, data);
714 PrintRegisterValue(reg_ctx, "x5", nullptr, 4, data);
715 PrintRegisterValue(reg_ctx, "x6", nullptr, 4, data);
716 PrintRegisterValue(reg_ctx, "x7", nullptr, 4, data);
717 PrintRegisterValue(reg_ctx, "x8", nullptr, 4, data);
718 PrintRegisterValue(reg_ctx, "x9", nullptr, 4, data);
719 PrintRegisterValue(reg_ctx, "x10", nullptr, 4, data);
720 PrintRegisterValue(reg_ctx, "x11", nullptr, 4, data);
721 PrintRegisterValue(reg_ctx, "x12", nullptr, 4, data);
722 PrintRegisterValue(reg_ctx, "x13", nullptr, 4, data);
723 PrintRegisterValue(reg_ctx, "x14", nullptr, 4, data);
724 PrintRegisterValue(reg_ctx, "x15", nullptr, 4, data);
725 PrintRegisterValue(reg_ctx, "x16", nullptr, 4, data);
726 PrintRegisterValue(reg_ctx, "x17", nullptr, 4, data);
727 PrintRegisterValue(reg_ctx, "x18", nullptr, 4, data);
728 PrintRegisterValue(reg_ctx, "x19", nullptr, 4, data);
729 PrintRegisterValue(reg_ctx, "x20", nullptr, 4, data);
730 PrintRegisterValue(reg_ctx, "x21", nullptr, 4, data);
731 PrintRegisterValue(reg_ctx, "x22", nullptr, 4, data);
732 PrintRegisterValue(reg_ctx, "x23", nullptr, 4, data);
733 PrintRegisterValue(reg_ctx, "x24", nullptr, 4, data);
734 PrintRegisterValue(reg_ctx, "x25", nullptr, 4, data);
735 PrintRegisterValue(reg_ctx, "x26", nullptr, 4, data);
736 PrintRegisterValue(reg_ctx, "x27", nullptr, 4, data);
737 PrintRegisterValue(reg_ctx, "x28", nullptr, 4, data);
738 PrintRegisterValue(reg_ctx, "x29", nullptr, 4, data);
739 PrintRegisterValue(reg_ctx, "x30", nullptr, 4, data);
740 PrintRegisterValue(reg_ctx, "x31", nullptr, 4, data);
741 PrintRegisterValue(reg_ctx, "pc", nullptr, 4, data);
742 data.PutHex32(0); // uint32_t pad at the end
743
744 // Write out the EXC registers
745 data.PutHex32(EXCRegSet);
747 PrintRegisterValue(reg_ctx, "exception", nullptr, 4, data);
748 PrintRegisterValue(reg_ctx, "fsr", nullptr, 4, data);
749 PrintRegisterValue(reg_ctx, "far", nullptr, 4, data);
750 return true;
751 }
752 return false;
753 }
754
755protected:
756 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
757
758 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
759
760 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
761
762 int DoReadCSR(lldb::tid_t tid, int flavor, CSR &csr) override { return -1; }
763
764 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
765 return 0;
766 }
767
768 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
769 return 0;
770 }
771
772 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
773 return 0;
774 }
775
776 int DoWriteCSR(lldb::tid_t tid, int flavor, const CSR &csr) override {
777 return 0;
778 }
779};
780
781static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
782 switch (magic) {
783 case MH_MAGIC:
784 case MH_CIGAM:
785 return sizeof(struct llvm::MachO::mach_header);
786
787 case MH_MAGIC_64:
788 case MH_CIGAM_64:
789 return sizeof(struct llvm::MachO::mach_header_64);
790 break;
791
792 default:
793 break;
794 }
795 return 0;
796}
797
798#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
799
801
807
811
813 DataExtractorSP extractor_sp,
814 lldb::offset_t data_offset,
815 const FileSpec *file,
816 lldb::offset_t file_offset,
817 lldb::offset_t length) {
818 if (!extractor_sp || !extractor_sp->HasData()) {
819 DataBufferSP data_sp = MapFileData(*file, length, file_offset);
820 if (!data_sp)
821 return nullptr;
822 data_offset = 0;
823 extractor_sp = std::make_shared<DataExtractor>(data_sp);
824 }
825
826 if (!ObjectFileMachO::MagicBytesMatch(extractor_sp, data_offset, length))
827 return nullptr;
828
829 // Update the data to contain the entire file if it doesn't already
830 if (extractor_sp->GetByteSize() < length) {
831 DataBufferSP data_sp = MapFileData(*file, length, file_offset);
832 if (!data_sp)
833 return nullptr;
834 data_offset = 0;
835 extractor_sp = std::make_shared<DataExtractor>(data_sp);
836 }
837 auto objfile_up = std::make_unique<ObjectFileMachO>(
838 module_sp, extractor_sp, data_offset, file, file_offset, length);
839 if (!objfile_up || !objfile_up->ParseHeader())
840 return nullptr;
841
842 return objfile_up.release();
843}
844
846 const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
847 const ProcessSP &process_sp, lldb::addr_t header_addr) {
848 DataExtractorSP extractor_sp = std::make_shared<DataExtractor>(data_sp);
849 if (ObjectFileMachO::MagicBytesMatch(extractor_sp, 0,
850 extractor_sp->GetByteSize())) {
851 std::unique_ptr<ObjectFile> objfile_up(
852 new ObjectFileMachO(module_sp, data_sp, process_sp, header_addr));
853 if (objfile_up.get() && objfile_up->ParseHeader())
854 return objfile_up.release();
855 }
856 return nullptr;
857}
858
860 const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
861 lldb::offset_t file_offset, lldb::offset_t length) {
862 if (!extractor_sp || !extractor_sp->HasData())
863 return {};
864
865 ModuleSpecList specs;
866 if (ObjectFileMachO::MagicBytesMatch(extractor_sp, 0,
867 extractor_sp->GetByteSize())) {
868 llvm::MachO::mach_header header;
869 offset_t data_offset = 0;
870 if (ParseHeader(extractor_sp, &data_offset, header)) {
871 size_t header_and_load_cmds =
872 header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
873 if (header_and_load_cmds >= extractor_sp->GetByteSize()) {
874 DataBufferSP file_data_sp =
875 MapFileData(file, header_and_load_cmds, file_offset);
876 if (file_data_sp)
877 extractor_sp->SetData(file_data_sp);
878 data_offset = MachHeaderSizeFromMagic(header.magic);
879 }
880 if (extractor_sp && extractor_sp->HasData()) {
881 ModuleSpec base_spec;
882 base_spec.GetFileSpec() = file;
883 base_spec.SetObjectOffset(file_offset);
884 base_spec.SetObjectSize(length);
885 GetAllArchSpecs(header, *extractor_sp, data_offset, base_spec, specs);
886 }
887 }
888 }
889 return specs;
890}
891
893 static constexpr llvm::StringLiteral g_segment_name_TEXT("__TEXT");
894 return g_segment_name_TEXT;
895}
896
898 static constexpr llvm::StringLiteral g_segment_name_DATA("__DATA");
899 return g_segment_name_DATA;
900}
901
903 static constexpr llvm::StringLiteral g_segment_name("__DATA_DIRTY");
904 return g_segment_name;
905}
906
908 static constexpr llvm::StringLiteral g_segment_name("__DATA_CONST");
909 return g_segment_name;
910}
911
913 static constexpr llvm::StringLiteral g_segment_name_OBJC("__OBJC");
914 return g_segment_name_OBJC;
915}
916
918 static constexpr llvm::StringLiteral g_section_name_LINKEDIT("__LINKEDIT");
919 return g_section_name_LINKEDIT;
920}
921
923 static constexpr llvm::StringLiteral g_section_name("__DWARF");
924 return g_section_name;
925}
926
928 static constexpr llvm::StringLiteral g_section_name("__LLVM_COV");
929 return g_section_name;
930}
931
933 static constexpr llvm::StringLiteral g_section_name_eh_frame("__eh_frame");
934 return g_section_name_eh_frame;
935}
936
938 static constexpr llvm::StringLiteral g_section_name_lldb_no_nlist(
939 "__lldb_no_nlist");
940 return g_section_name_lldb_no_nlist;
941}
942
944 lldb::addr_t data_offset,
945 lldb::addr_t data_length) {
946 lldb::offset_t offset = data_offset;
947 uint32_t magic = extractor_sp->GetU32(&offset);
948
949 offset += 4; // cputype
950 offset += 4; // cpusubtype
951 uint32_t filetype = extractor_sp->GetU32(&offset);
952
953 // A fileset has a Mach-O header but is not an
954 // individual file and must be handled via an
955 // ObjectContainer plugin.
956 if (filetype == llvm::MachO::MH_FILESET)
957 return false;
958
959 return MachHeaderSizeFromMagic(magic) != 0;
960}
961
963 DataExtractorSP extractor_sp,
964 lldb::offset_t data_offset,
965 const FileSpec *file,
966 lldb::offset_t file_offset,
967 lldb::offset_t length)
968 : ObjectFile(module_sp, file, file_offset, length, extractor_sp,
969 data_offset),
973 ::memset(&m_header, 0, sizeof(m_header));
974 ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
975}
976
978 lldb::WritableDataBufferSP header_data_sp,
979 const lldb::ProcessSP &process_sp,
980 lldb::addr_t header_addr)
981 : ObjectFile(module_sp, process_sp, header_addr,
982 std::make_shared<DataExtractor>(header_data_sp)),
986 ::memset(&m_header, 0, sizeof(m_header));
987 ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
988}
989
991 lldb::offset_t *data_offset_ptr,
992 llvm::MachO::mach_header &header) {
993 extractor_sp->SetByteOrder(endian::InlHostByteOrder());
994 // Leave magic in the original byte order
995 header.magic = extractor_sp->GetU32(data_offset_ptr);
996 bool can_parse = false;
997 bool is_64_bit = false;
998 switch (header.magic) {
999 case MH_MAGIC:
1000 extractor_sp->SetByteOrder(endian::InlHostByteOrder());
1001 extractor_sp->SetAddressByteSize(4);
1002 can_parse = true;
1003 break;
1004
1005 case MH_MAGIC_64:
1006 extractor_sp->SetByteOrder(endian::InlHostByteOrder());
1007 extractor_sp->SetAddressByteSize(8);
1008 can_parse = true;
1009 is_64_bit = true;
1010 break;
1011
1012 case MH_CIGAM:
1013 extractor_sp->SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
1015 : eByteOrderBig);
1016 extractor_sp->SetAddressByteSize(4);
1017 can_parse = true;
1018 break;
1019
1020 case MH_CIGAM_64:
1021 extractor_sp->SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
1023 : eByteOrderBig);
1024 extractor_sp->SetAddressByteSize(8);
1025 is_64_bit = true;
1026 can_parse = true;
1027 break;
1028
1029 default:
1030 break;
1031 }
1032
1033 if (can_parse) {
1034 extractor_sp->GetU32(data_offset_ptr, &header.cputype, 6);
1035 if (is_64_bit)
1036 *data_offset_ptr += 4;
1037 return true;
1038 } else {
1039 memset(&header, 0, sizeof(header));
1040 }
1041 return false;
1042}
1043
1045 ModuleSP module_sp(GetModule());
1046 if (!module_sp)
1047 return false;
1048
1049 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
1050 bool can_parse = false;
1051 lldb::offset_t offset = 0;
1052 m_data_nsp->SetByteOrder(endian::InlHostByteOrder());
1053 // Leave magic in the original byte order
1054 m_header.magic = m_data_nsp->GetU32(&offset);
1055 switch (m_header.magic) {
1056 case MH_MAGIC:
1057 m_data_nsp->SetByteOrder(endian::InlHostByteOrder());
1058 m_data_nsp->SetAddressByteSize(4);
1059 can_parse = true;
1060 break;
1061
1062 case MH_MAGIC_64:
1063 m_data_nsp->SetByteOrder(endian::InlHostByteOrder());
1064 m_data_nsp->SetAddressByteSize(8);
1065 can_parse = true;
1066 break;
1067
1068 case MH_CIGAM:
1071 : eByteOrderBig);
1072 m_data_nsp->SetAddressByteSize(4);
1073 can_parse = true;
1074 break;
1075
1076 case MH_CIGAM_64:
1079 : eByteOrderBig);
1080 m_data_nsp->SetAddressByteSize(8);
1081 can_parse = true;
1082 break;
1083
1084 default:
1085 break;
1086 }
1087
1088 if (can_parse) {
1089 m_data_nsp->GetU32(&offset, &m_header.cputype, 6);
1090
1091 ModuleSpecList all_specs;
1092 ModuleSpec base_spec;
1094 MachHeaderSizeFromMagic(m_header.magic), base_spec,
1095 all_specs);
1096
1097 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
1098 ArchSpec mach_arch =
1100
1101 // Check if the module has a required architecture
1102 const ArchSpec &module_arch = module_sp->GetArchitecture();
1103 if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
1104 continue;
1105
1106 if (SetModulesArchitecture(mach_arch)) {
1107 const size_t header_and_lc_size =
1108 m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
1109 if (m_data_nsp->GetByteSize() < header_and_lc_size) {
1110 DataBufferSP data_sp;
1111 ProcessSP process_sp(m_process_wp.lock());
1112 if (process_sp) {
1113 data_sp = ReadMemory(process_sp, m_memory_addr, header_and_lc_size);
1114 } else {
1115 // Read in all only the load command data from the file on disk
1116 data_sp = MapFileData(m_file, header_and_lc_size, m_file_offset);
1117 if (data_sp->GetByteSize() != header_and_lc_size)
1118 continue;
1119 }
1120 if (data_sp)
1121 m_data_nsp->SetData(data_sp);
1122 }
1123 }
1124 return true;
1125 }
1126 // None found.
1127 return false;
1128 } else {
1129 memset(&m_header, 0, sizeof(struct llvm::MachO::mach_header));
1130 }
1131 return false;
1132}
1133
1135 return m_data_nsp->GetByteOrder();
1136}
1137
1139 return m_header.filetype == MH_EXECUTE;
1140}
1141
1143 return m_header.filetype == MH_DYLINKER;
1144}
1145
1147 return m_header.flags & MH_DYLIB_IN_CACHE;
1148}
1149
1151 return m_header.filetype == MH_KEXT_BUNDLE;
1152}
1153
1155 return m_data_nsp->GetAddressByteSize();
1156}
1157
1159 Symtab *symtab = GetSymtab();
1160 if (!symtab)
1162
1163 const Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
1164 if (symbol) {
1165 if (symbol->ValueIsAddress()) {
1166 SectionSP section_sp(symbol->GetAddressRef().GetSection());
1167 if (section_sp) {
1168 const lldb::SectionType section_type = section_sp->GetType();
1169 switch (section_type) {
1172
1173 case eSectionTypeCode:
1174 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1175 // For ARM we have a bit in the n_desc field of the symbol that
1176 // tells us ARM/Thumb which is bit 0x0008.
1179 }
1180 return AddressClass::eCode;
1181
1184
1185 case eSectionTypeData:
1189 case eSectionTypeData4:
1190 case eSectionTypeData8:
1191 case eSectionTypeData16:
1199 return AddressClass::eData;
1200
1201 case eSectionTypeDebug:
1236 case eSectionTypeCTF:
1240 return AddressClass::eDebug;
1241
1247
1253 case eSectionTypeOther:
1255 }
1256 }
1257 }
1258
1259 const SymbolType symbol_type = symbol->GetType();
1260 switch (symbol_type) {
1261 case eSymbolTypeAny:
1265
1266 case eSymbolTypeCode:
1269 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1270 // For ARM we have a bit in the n_desc field of the symbol that tells
1271 // us ARM/Thumb which is bit 0x0008.
1274 }
1275 return AddressClass::eCode;
1276
1277 case eSymbolTypeData:
1278 return AddressClass::eData;
1279 case eSymbolTypeRuntime:
1284 return AddressClass::eDebug;
1286 return AddressClass::eDebug;
1288 return AddressClass::eDebug;
1290 return AddressClass::eDebug;
1291 case eSymbolTypeBlock:
1292 return AddressClass::eDebug;
1293 case eSymbolTypeLocal:
1294 return AddressClass::eData;
1295 case eSymbolTypeParam:
1296 return AddressClass::eData;
1298 return AddressClass::eData;
1300 return AddressClass::eDebug;
1302 return AddressClass::eDebug;
1304 return AddressClass::eDebug;
1306 return AddressClass::eDebug;
1308 return AddressClass::eDebug;
1312 return AddressClass::eDebug;
1314 return AddressClass::eDebug;
1325 }
1326 }
1328}
1329
1331 if (m_dysymtab.cmd == 0) {
1332 ModuleSP module_sp(GetModule());
1333 if (module_sp) {
1335 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
1336 const lldb::offset_t load_cmd_offset = offset;
1337
1338 llvm::MachO::load_command lc = {};
1339 if (!ReadMachOCommand(*m_data_nsp, offset, lc))
1340 break;
1341 if (lc.cmd == LC_DYSYMTAB) {
1342 m_dysymtab.cmd = lc.cmd;
1343 m_dysymtab.cmdsize = lc.cmdsize;
1344 if (m_data_nsp->GetU32(&offset, &m_dysymtab.ilocalsym,
1345 (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) ==
1346 nullptr) {
1347 // Clear m_dysymtab if we were unable to read all items from the
1348 // load command
1349 ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
1350 }
1351 }
1352 offset = load_cmd_offset + lc.cmdsize;
1353 }
1354 }
1355 }
1356 if (m_dysymtab.cmd)
1357 return m_dysymtab.nlocalsym <= 1;
1358 return false;
1359}
1360
1362 EncryptedFileRanges result;
1364
1365 llvm::MachO::encryption_info_command encryption_cmd;
1366 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
1367 const lldb::offset_t load_cmd_offset = offset;
1368 if (!ReadMachOCommand(*m_data_nsp, offset, encryption_cmd))
1369 break;
1370
1371 // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for the
1372 // 3 fields we care about, so treat them the same.
1373 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
1374 encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
1375 if (m_data_nsp->GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
1376 if (encryption_cmd.cryptid != 0) {
1378 entry.SetRangeBase(encryption_cmd.cryptoff);
1379 entry.SetByteSize(encryption_cmd.cryptsize);
1380 result.Append(entry);
1381 }
1382 }
1383 }
1384 offset = load_cmd_offset + encryption_cmd.cmdsize;
1385 }
1386
1387 return result;
1388}
1389
1391 llvm::MachO::segment_command_64 &seg_cmd, uint32_t cmd_idx) {
1392 if (m_length == 0 || seg_cmd.filesize == 0)
1393 return;
1394
1395 if (IsSharedCacheBinary() && !IsInMemory()) {
1396 // In shared cache images, the load commands are relative to the
1397 // shared cache file, and not the specific image we are
1398 // examining. Let's fix this up so that it looks like a normal
1399 // image.
1400 llvm::StringRef segname(seg_cmd.segname,
1401 strnlen(seg_cmd.segname, sizeof(seg_cmd.segname)));
1402 if (segname == GetSegmentNameTEXT())
1403 m_text_address = seg_cmd.vmaddr;
1404 if (segname == GetSegmentNameLINKEDIT())
1405 m_linkedit_original_offset = seg_cmd.fileoff;
1406
1407 seg_cmd.fileoff = seg_cmd.vmaddr - m_text_address;
1408 }
1409
1410 if (seg_cmd.fileoff > m_length) {
1411 // We have a load command that says it extends past the end of the file.
1412 // This is likely a corrupt file. We don't have any way to return an error
1413 // condition here (this method was likely invoked from something like
1414 // ObjectFile::GetSectionList()), so we just null out the section contents,
1415 // and dump a message to stdout. The most common case here is core file
1416 // debugging with a truncated file.
1417 const char *lc_segment_name =
1418 seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
1419 GetModule()->ReportWarning(
1420 "load command {0} {1} has a fileoff ({2:x16}) that extends beyond "
1421 "the end of the file ({3:x16}), ignoring this section",
1422 cmd_idx, lc_segment_name, seg_cmd.fileoff, m_length);
1423
1424 seg_cmd.fileoff = 0;
1425 seg_cmd.filesize = 0;
1426 }
1427
1428 if (seg_cmd.fileoff + seg_cmd.filesize > m_length) {
1429 // We have a load command that says it extends past the end of the file.
1430 // This is likely a corrupt file. We don't have any way to return an error
1431 // condition here (this method was likely invoked from something like
1432 // ObjectFile::GetSectionList()), so we just null out the section contents,
1433 // and dump a message to stdout. The most common case here is core file
1434 // debugging with a truncated file.
1435 const char *lc_segment_name =
1436 seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
1437 GetModule()->ReportWarning(
1438 "load command {0} {1} has a fileoff + filesize ({2:x16}) that "
1439 "extends beyond the end of the file ({3:x16}), the segment will be "
1440 "truncated to match",
1441 cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize, m_length);
1442
1443 // Truncate the length
1444 seg_cmd.filesize = m_length - seg_cmd.fileoff;
1445 }
1446}
1447
1448static uint32_t
1449GetSegmentPermissions(const llvm::MachO::segment_command_64 &seg_cmd) {
1450 uint32_t result = 0;
1451 if (seg_cmd.initprot & VM_PROT_READ)
1452 result |= ePermissionsReadable;
1453 if (seg_cmd.initprot & VM_PROT_WRITE)
1454 result |= ePermissionsWritable;
1455 if (seg_cmd.initprot & VM_PROT_EXECUTE)
1456 result |= ePermissionsExecutable;
1457 return result;
1458}
1459
1460static lldb::SectionType GetSectionType(uint32_t flags,
1461 llvm::StringRef section_name) {
1462
1463 if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1464 return eSectionTypeCode;
1465
1466 uint32_t mach_sect_type = flags & SECTION_TYPE;
1467 static constexpr llvm::StringLiteral g_sect_name_objc_data("__objc_data");
1468 static constexpr llvm::StringLiteral g_sect_name_objc_msgrefs(
1469 "__objc_msgrefs");
1470 static constexpr llvm::StringLiteral g_sect_name_objc_selrefs(
1471 "__objc_selrefs");
1472 static constexpr llvm::StringLiteral g_sect_name_objc_classrefs(
1473 "__objc_classrefs");
1474 static constexpr llvm::StringLiteral g_sect_name_objc_superrefs(
1475 "__objc_superrefs");
1476 static constexpr llvm::StringLiteral g_sect_name_objc_const("__objc_const");
1477 static constexpr llvm::StringLiteral g_sect_name_objc_classlist(
1478 "__objc_classlist");
1479 static constexpr llvm::StringLiteral g_sect_name_cfstring("__cfstring");
1480
1481 static constexpr llvm::StringLiteral g_sect_name_dwarf_debug_str_offs(
1482 "__debug_str_offs");
1483 static constexpr llvm::StringLiteral g_sect_name_dwarf_debug_str_offs_dwo(
1484 "__debug_str_offs.dwo");
1485 static constexpr llvm::StringLiteral g_sect_name_dwarf_apple_names(
1486 "__apple_names");
1487 static constexpr llvm::StringLiteral g_sect_name_dwarf_apple_types(
1488 "__apple_types");
1489 static constexpr llvm::StringLiteral g_sect_name_dwarf_apple_namespaces(
1490 "__apple_namespac");
1491 static constexpr llvm::StringLiteral g_sect_name_dwarf_apple_objc(
1492 "__apple_objc");
1493 static constexpr llvm::StringLiteral g_sect_name_eh_frame("__eh_frame");
1494 static constexpr llvm::StringLiteral g_sect_name_compact_unwind(
1495 "__unwind_info");
1496 static constexpr llvm::StringLiteral g_sect_name_text("__text");
1497 static constexpr llvm::StringLiteral g_sect_name_data("__data");
1498 static constexpr llvm::StringLiteral g_sect_name_go_symtab("__gosymtab");
1499 static constexpr llvm::StringLiteral g_sect_name_ctf("__ctf");
1500 static constexpr llvm::StringLiteral g_sect_name_lldb_summaries(
1501 "__lldbsummaries");
1502 static constexpr llvm::StringLiteral g_sect_name_lldb_formatters(
1503 "__lldbformatters");
1504 static constexpr llvm::StringLiteral g_sect_name_swift_ast("__swift_ast");
1505
1506 if (section_name == g_sect_name_dwarf_debug_str_offs)
1508 if (section_name == g_sect_name_dwarf_debug_str_offs_dwo)
1510
1511 llvm::StringRef stripped_name = section_name;
1512 if (stripped_name.consume_front("__debug_"))
1513 return ObjectFile::GetDWARFSectionTypeFromName(stripped_name);
1514
1515 if (section_name == g_sect_name_dwarf_apple_names)
1517 if (section_name == g_sect_name_dwarf_apple_types)
1519 if (section_name == g_sect_name_dwarf_apple_namespaces)
1521 if (section_name == g_sect_name_dwarf_apple_objc)
1523 if (section_name == g_sect_name_objc_selrefs)
1525 if (section_name == g_sect_name_objc_msgrefs)
1527 if (section_name == g_sect_name_eh_frame)
1528 return eSectionTypeEHFrame;
1529 if (section_name == g_sect_name_compact_unwind)
1531 if (section_name == g_sect_name_cfstring)
1533 if (section_name == g_sect_name_go_symtab)
1534 return eSectionTypeGoSymtab;
1535 if (section_name == g_sect_name_ctf)
1536 return eSectionTypeCTF;
1537 if (section_name == g_sect_name_lldb_summaries)
1539 if (section_name == g_sect_name_lldb_formatters)
1541 if (section_name == g_sect_name_swift_ast)
1543 if (section_name == g_sect_name_objc_data ||
1544 section_name == g_sect_name_objc_classrefs ||
1545 section_name == g_sect_name_objc_superrefs ||
1546 section_name == g_sect_name_objc_const ||
1547 section_name == g_sect_name_objc_classlist) {
1549 }
1550
1551 switch (mach_sect_type) {
1552 // TODO: categorize sections by other flags for regular sections
1553 case S_REGULAR:
1554 if (section_name == g_sect_name_text)
1555 return eSectionTypeCode;
1556 if (section_name == g_sect_name_data)
1557 return eSectionTypeData;
1558 return eSectionTypeOther;
1559 case S_ZEROFILL:
1560 return eSectionTypeZeroFill;
1561 case S_CSTRING_LITERALS: // section with only literal C strings
1563 case S_4BYTE_LITERALS: // section with only 4 byte literals
1564 return eSectionTypeData4;
1565 case S_8BYTE_LITERALS: // section with only 8 byte literals
1566 return eSectionTypeData8;
1567 case S_LITERAL_POINTERS: // section with only pointers to literals
1569 case S_NON_LAZY_SYMBOL_POINTERS: // section with only non-lazy symbol pointers
1571 case S_LAZY_SYMBOL_POINTERS: // section with only lazy symbol pointers
1573 case S_SYMBOL_STUBS: // section with only symbol stubs, byte size of stub in
1574 // the reserved2 field
1575 return eSectionTypeCode;
1576 case S_MOD_INIT_FUNC_POINTERS: // section with only function pointers for
1577 // initialization
1579 case S_MOD_TERM_FUNC_POINTERS: // section with only function pointers for
1580 // termination
1582 case S_COALESCED:
1583 return eSectionTypeOther;
1584 case S_GB_ZEROFILL:
1585 return eSectionTypeZeroFill;
1586 case S_INTERPOSING: // section with only pairs of function pointers for
1587 // interposing
1588 return eSectionTypeCode;
1589 case S_16BYTE_LITERALS: // section with only 16 byte literals
1590 return eSectionTypeData16;
1591 case S_DTRACE_DOF:
1592 return eSectionTypeDebug;
1593 case S_LAZY_DYLIB_SYMBOL_POINTERS:
1595 default:
1596 return eSectionTypeOther;
1597 }
1598}
1599
1611
1613 const llvm::MachO::load_command &load_cmd_, lldb::offset_t offset,
1614 uint32_t cmd_idx, SegmentParsingContext &context) {
1615 llvm::MachO::segment_command_64 load_cmd;
1616 memcpy(&load_cmd, &load_cmd_, sizeof(load_cmd_));
1617
1618 if (!m_data_nsp->GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
1619 return;
1620
1621 ModuleSP module_sp = GetModule();
1622 const bool is_core = GetType() == eTypeCoreFile;
1623 const bool is_dsym = (m_header.filetype == MH_DSYM);
1624 bool add_section = true;
1625 bool add_to_unified = true;
1626 llvm::StringRef segname(load_cmd.segname,
1627 strnlen(load_cmd.segname, sizeof(load_cmd.segname)));
1628
1629 SectionSP unified_section_sp(context.UnifiedList.FindSectionByName(segname));
1630 if (is_dsym && unified_section_sp) {
1631 if (segname == GetSegmentNameLINKEDIT()) {
1632 // We need to keep the __LINKEDIT segment private to this object file
1633 // only
1634 add_to_unified = false;
1635 } else {
1636 // This is the dSYM file and this section has already been created by the
1637 // object file, no need to create it.
1638 add_section = false;
1639 }
1640 }
1641 load_cmd.vmaddr = m_data_nsp->GetAddress(&offset);
1642 load_cmd.vmsize = m_data_nsp->GetAddress(&offset);
1643 load_cmd.fileoff = m_data_nsp->GetAddress(&offset);
1644 load_cmd.filesize = m_data_nsp->GetAddress(&offset);
1645 if (!m_data_nsp->GetU32(&offset, &load_cmd.maxprot, 4))
1646 return;
1647
1648 SanitizeSegmentCommand(load_cmd, cmd_idx);
1649
1650 const uint32_t segment_permissions = GetSegmentPermissions(load_cmd);
1651 const bool segment_is_encrypted =
1652 (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
1653
1654 // Use a segment ID of the segment index shifted left by 8 so they never
1655 // conflict with any of the sections.
1656 SectionSP segment_sp;
1657 if (add_section && (!segname.empty() || is_core)) {
1658 segment_sp = std::make_shared<Section>(
1659 module_sp, // Module to which this section belongs
1660 this, // Object file to which this sections belongs
1661 ++context.NextSegmentIdx
1662 << 8, // Section ID is the 1 based segment index
1663 // shifted right by 8 bits as not to collide with any of the 256
1664 // section IDs that are possible
1665 segname.str(), // Name of this section
1666 eSectionTypeContainer, // This section is a container of other
1667 // sections.
1668 load_cmd.vmaddr, // File VM address == addresses as they are
1669 // found in the object file
1670 load_cmd.vmsize, // VM size in bytes of this section
1671 load_cmd.fileoff, // Offset to the data for this section in
1672 // the file
1673 load_cmd.filesize, // Size in bytes of this section as found
1674 // in the file
1675 0, // Segments have no alignment information
1676 load_cmd.flags); // Flags for this section
1677
1678 segment_sp->SetIsEncrypted(segment_is_encrypted);
1679 m_sections_up->AddSection(segment_sp);
1680 segment_sp->SetPermissions(segment_permissions);
1681 if (add_to_unified)
1682 context.UnifiedList.AddSection(segment_sp);
1683 } else if (unified_section_sp) {
1684 // If this is a dSYM and the file addresses in the dSYM differ from the
1685 // file addresses in the ObjectFile, we must use the file base address for
1686 // the Section from the dSYM for the DWARF to resolve correctly.
1687 // This only happens with binaries in the shared cache in practice;
1688 // normally a mismatch like this would give a binary & dSYM that do not
1689 // match UUIDs. When a binary is included in the shared cache, its
1690 // segments are rearranged to optimize the shared cache, so its file
1691 // addresses will differ from what the ObjectFile had originally,
1692 // and what the dSYM has.
1693 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
1695 "Installing dSYM's {0} segment file address over ObjectFile's "
1696 "so symbol table/debug info resolves correctly for {1}",
1697 segname, module_sp->GetFileSpec().GetFilename());
1698
1699 // Make sure we've parsed the symbol table from the ObjectFile before
1700 // we go around changing its Sections.
1701 module_sp->GetObjectFile()->GetSymtab();
1702 // eh_frame would present the same problems but we parse that on a per-
1703 // function basis as-needed so it's more difficult to remove its use of
1704 // the Sections. Realistically, the environments where this code path
1705 // will be taken will not have eh_frame sections.
1706
1707 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
1708
1709 // Notify the module that the section addresses have been changed once
1710 // we're done so any file-address caches can be updated.
1711 context.FileAddressesChanged = true;
1712 }
1713 m_sections_up->AddSection(unified_section_sp);
1714 }
1715
1716 llvm::MachO::section_64 sect64;
1717 ::memset(&sect64, 0, sizeof(sect64));
1718 // Push a section into our mach sections for the section at index zero
1719 // (NO_SECT) if we don't have any mach sections yet...
1720 if (m_mach_sections.empty())
1721 m_mach_sections.push_back(sect64);
1722 uint32_t segment_sect_idx;
1723 const lldb::user_id_t first_segment_sectID = context.NextSectionIdx + 1;
1724
1725 // 64 bit mach-o files have sections with 32 bit file offsets. If any section
1726 // data end will exceed UINT32_MAX, then we need to do some bookkeeping to
1727 // ensure we can access this data correctly.
1728 uint64_t section_offset_adjust = 0;
1729 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
1730 for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
1731 ++segment_sect_idx) {
1732 if (m_data_nsp->GetU8(&offset, (uint8_t *)sect64.sectname,
1733 sizeof(sect64.sectname)) == nullptr)
1734 break;
1735 if (m_data_nsp->GetU8(&offset, (uint8_t *)sect64.segname,
1736 sizeof(sect64.segname)) == nullptr)
1737 break;
1738 sect64.addr = m_data_nsp->GetAddress(&offset);
1739 sect64.size = m_data_nsp->GetAddress(&offset);
1740
1741 if (m_data_nsp->GetU32(&offset, &sect64.offset, num_u32s) == nullptr)
1742 break;
1743
1744 if (IsSharedCacheBinary() && !IsInMemory()) {
1745 sect64.offset = sect64.addr - m_text_address;
1746 }
1747
1748 // Keep a list of mach sections around in case we need to get at data that
1749 // isn't stored in the abstracted Sections.
1750 m_mach_sections.push_back(sect64);
1751
1752 // Make sure we can load sections in mach-o files where some sections cross
1753 // a 4GB boundary. llvm::MachO::section_64 have only 32 bit file offsets
1754 // for the file offset of the section contents, so we need to track and
1755 // sections that overflow and adjust the offsets accordingly.
1756 const uint64_t section_file_offset =
1757 (uint64_t)sect64.offset + section_offset_adjust;
1758 const uint64_t end_section_offset = (uint64_t)sect64.offset + sect64.size;
1759 if (end_section_offset >= UINT32_MAX)
1760 section_offset_adjust += end_section_offset & 0xFFFFFFFF00000000ull;
1761
1762 if (add_section) {
1763 llvm::StringRef section_name(
1764 sect64.sectname, strnlen(sect64.sectname, sizeof(sect64.sectname)));
1765 if (segname.empty()) {
1766 // We have a segment with no name so we need to conjure up segments
1767 // that correspond to the section's segname if there isn't already such
1768 // a section. If there is such a section, we resize the section so that
1769 // it spans all sections. We also mark these sections as fake so
1770 // address matches don't hit if they land in the gaps between the child
1771 // sections.
1772 segname = llvm::StringRef(
1773 sect64.segname, strnlen(sect64.segname, sizeof(sect64.segname)));
1774 segment_sp = context.UnifiedList.FindSectionByName(segname);
1775 if (segment_sp.get()) {
1776 Section *segment = segment_sp.get();
1777 // Grow the section size as needed.
1778 const lldb::addr_t sect64_min_addr = sect64.addr;
1779 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1780 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
1781 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
1782 const lldb::addr_t curr_seg_max_addr =
1783 curr_seg_min_addr + curr_seg_byte_size;
1784 if (sect64_min_addr >= curr_seg_min_addr) {
1785 const lldb::addr_t new_seg_byte_size =
1786 sect64_max_addr - curr_seg_min_addr;
1787 // Only grow the section size if needed
1788 if (new_seg_byte_size > curr_seg_byte_size)
1789 segment->SetByteSize(new_seg_byte_size);
1790 } else {
1791 // We need to change the base address of the segment and adjust the
1792 // child section offsets for all existing children.
1793 const lldb::addr_t slide_amount =
1794 sect64_min_addr - curr_seg_min_addr;
1795 segment->Slide(slide_amount, false);
1796 segment->GetChildren().Slide(-slide_amount, false);
1797 segment->SetByteSize(curr_seg_max_addr - sect64_min_addr);
1798 }
1799
1800 // Grow the section size as needed.
1801 if (section_file_offset) {
1802 const lldb::addr_t segment_min_file_offset =
1803 segment->GetFileOffset();
1804 const lldb::addr_t segment_max_file_offset =
1805 segment_min_file_offset + segment->GetFileSize();
1806
1807 const lldb::addr_t section_min_file_offset = section_file_offset;
1808 const lldb::addr_t section_max_file_offset =
1809 section_min_file_offset + sect64.size;
1810 const lldb::addr_t new_file_offset =
1811 std::min(section_min_file_offset, segment_min_file_offset);
1812 const lldb::addr_t new_file_size =
1813 std::max(section_max_file_offset, segment_max_file_offset) -
1814 new_file_offset;
1815 segment->SetFileOffset(new_file_offset);
1816 segment->SetFileSize(new_file_size);
1817 }
1818 } else {
1819 // Create a fake section for the section's named segment
1820 segment_sp = std::make_shared<Section>(
1821 segment_sp, // Parent section
1822 module_sp, // Module to which this section belongs
1823 this, // Object file to which this section belongs
1824 ++context.NextSegmentIdx
1825 << 8, // Section ID is the 1 based segment index
1826 // shifted right by 8 bits as not to
1827 // collide with any of the 256 section IDs
1828 // that are possible
1829 segname.str(), // Name of this section
1830 eSectionTypeContainer, // This section is a container of
1831 // other sections.
1832 sect64.addr, // File VM address == addresses as they are
1833 // found in the object file
1834 sect64.size, // VM size in bytes of this section
1835 section_file_offset, // Offset to the data for this section in
1836 // the file
1837 section_file_offset ? sect64.size : 0, // Size in bytes of
1838 // this section as
1839 // found in the file
1840 sect64.align,
1841 load_cmd.flags); // Flags for this section
1842 segment_sp->SetIsFake(true);
1843 segment_sp->SetPermissions(segment_permissions);
1844 m_sections_up->AddSection(segment_sp);
1845 if (add_to_unified)
1846 context.UnifiedList.AddSection(segment_sp);
1847 segment_sp->SetIsEncrypted(segment_is_encrypted);
1848 }
1849 }
1850 assert(segment_sp.get());
1851
1852 lldb::SectionType sect_type = GetSectionType(sect64.flags, section_name);
1853
1854 SectionSP section_sp = std::make_shared<Section>(
1855 segment_sp, module_sp, this, ++context.NextSectionIdx,
1856 section_name.str(), sect_type,
1857 sect64.addr - segment_sp->GetFileAddress(), sect64.size,
1858 section_file_offset, section_file_offset == 0 ? 0 : sect64.size,
1859 sect64.align, sect64.flags);
1860 // Set the section to be encrypted to match the segment
1861
1862 bool section_is_encrypted = false;
1863 if (!segment_is_encrypted && load_cmd.filesize != 0)
1864 section_is_encrypted = context.EncryptedRanges.FindEntryThatContains(
1865 section_file_offset) != nullptr;
1866
1867 section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
1868 section_sp->SetPermissions(segment_permissions);
1869 segment_sp->GetChildren().AddSection(section_sp);
1870
1871 if (segment_sp->IsFake()) {
1872 segment_sp.reset();
1873 segname = {};
1874 }
1875 }
1876 }
1877 if (segment_sp && is_dsym) {
1878 if (first_segment_sectID <= context.NextSectionIdx) {
1879 lldb::user_id_t sect_uid;
1880 for (sect_uid = first_segment_sectID; sect_uid <= context.NextSectionIdx;
1881 ++sect_uid) {
1882 SectionSP curr_section_sp(
1883 segment_sp->GetChildren().FindSectionByID(sect_uid));
1884 SectionSP next_section_sp;
1885 if (sect_uid + 1 <= context.NextSectionIdx)
1886 next_section_sp =
1887 segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
1888
1889 if (curr_section_sp.get()) {
1890 if (curr_section_sp->GetByteSize() == 0) {
1891 if (next_section_sp.get() != nullptr)
1892 curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
1893 curr_section_sp->GetFileAddress());
1894 else
1895 curr_section_sp->SetByteSize(load_cmd.vmsize);
1896 }
1897 }
1898 }
1899 }
1900 }
1901}
1902
1904 const llvm::MachO::load_command &load_cmd, lldb::offset_t offset) {
1905 m_dysymtab.cmd = load_cmd.cmd;
1906 m_dysymtab.cmdsize = load_cmd.cmdsize;
1907 m_data_nsp->GetU32(&offset, &m_dysymtab.ilocalsym,
1908 (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1909}
1910
1912 if (m_sections_up)
1913 return;
1914
1915 m_sections_up = std::make_unique<SectionList>();
1916
1918 // bool dump_sections = false;
1919 ModuleSP module_sp(GetModule());
1920
1921 offset = MachHeaderSizeFromMagic(m_header.magic);
1922
1923 SegmentParsingContext context(GetEncryptedFileRanges(), unified_section_list);
1924 llvm::MachO::load_command load_cmd;
1925 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
1926 const lldb::offset_t load_cmd_offset = offset;
1927 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
1928 break;
1929
1930 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
1931 ProcessSegmentCommand(load_cmd, offset, i, context);
1932 else if (load_cmd.cmd == LC_DYSYMTAB)
1933 ProcessDysymtabCommand(load_cmd, offset);
1934
1935 offset = load_cmd_offset + load_cmd.cmdsize;
1936 }
1937
1938 if (context.FileAddressesChanged && module_sp)
1939 module_sp->SectionFileAddressesChanged();
1940}
1941
1943public:
1945 : m_section_list(section_list), m_section_infos() {
1946 // Get the number of sections down to a depth of 1 to include all segments
1947 // and their sections, but no other sections that may be added for debug
1948 // map or
1949 m_section_infos.resize(section_list->GetNumSections(1));
1950 }
1951
1952 SectionSP GetSection(uint8_t n_sect, addr_t file_addr) {
1953 if (n_sect == 0)
1954 return SectionSP();
1955 if (n_sect < m_section_infos.size()) {
1956 if (!m_section_infos[n_sect].section_sp) {
1957 SectionSP section_sp(m_section_list->FindSectionByID(n_sect));
1958 m_section_infos[n_sect].section_sp = section_sp;
1959 if (section_sp) {
1960 m_section_infos[n_sect].vm_range.SetRangeBase(
1961 section_sp->GetFileAddress());
1962 m_section_infos[n_sect].vm_range.SetByteSize(
1963 section_sp->GetByteSize());
1964 } else {
1965 std::string filename = "<unknown>";
1966 SectionSP first_section_sp(m_section_list->GetSectionAtIndex(0));
1967 if (first_section_sp)
1968 filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();
1969
1971 llvm::formatv("unable to find section {0} for a symbol in "
1972 "{1}, corrupt file?",
1973 n_sect, filename));
1974 }
1975 }
1976 if (m_section_infos[n_sect].vm_range.Contains(file_addr)) {
1977 // Symbol is in section.
1978 return m_section_infos[n_sect].section_sp;
1979 } else if (m_section_infos[n_sect].vm_range.GetByteSize() == 0 &&
1980 m_section_infos[n_sect].vm_range.GetRangeBase() == file_addr) {
1981 // Symbol is in section with zero size, but has the same start address
1982 // as the section. This can happen with linker symbols (symbols that
1983 // start with the letter 'l' or 'L'.
1984 return m_section_infos[n_sect].section_sp;
1985 }
1986 }
1987 return m_section_list->FindSectionContainingFileAddress(file_addr);
1988 }
1989
1990protected:
1998 std::vector<SectionInfo> m_section_infos;
1999};
2000
2001static bool
2002TryParseV2ObjCMetadataSymbol(const char *&symbol_name,
2003 const char *&symbol_name_non_abi_mangled,
2004 SymbolType &type) {
2005 static constexpr llvm::StringLiteral g_objc_v2_prefix_class("_OBJC_CLASS_$_");
2006 static constexpr llvm::StringLiteral g_objc_v2_prefix_metaclass(
2007 "_OBJC_METACLASS_$_");
2008 static constexpr llvm::StringLiteral g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
2009
2010 llvm::StringRef symbol_name_ref(symbol_name);
2011 if (symbol_name_ref.empty())
2012 return false;
2013
2014 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
2015 symbol_name_non_abi_mangled = symbol_name + 1;
2016 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2017 type = eSymbolTypeObjCClass;
2018 return true;
2019 }
2020
2021 if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
2022 symbol_name_non_abi_mangled = symbol_name + 1;
2023 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2025 return true;
2026 }
2027
2028 if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
2029 symbol_name_non_abi_mangled = symbol_name + 1;
2030 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2031 type = eSymbolTypeObjCIVar;
2032 return true;
2033 }
2034
2035 return false;
2036}
2037
2038static SymbolType GetSymbolType(const char *&symbol_name,
2039 bool &demangled_is_synthesized,
2040 const SectionSP &text_section_sp,
2041 const SectionSP &data_section_sp,
2042 const SectionSP &data_dirty_section_sp,
2043 const SectionSP &data_const_section_sp,
2044 const SectionSP &symbol_section) {
2046
2047 llvm::StringRef symbol_sect_name = symbol_section->GetName();
2048 if (symbol_section->IsDescendant(text_section_sp.get())) {
2049 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
2050 S_ATTR_SELF_MODIFYING_CODE |
2051 S_ATTR_SOME_INSTRUCTIONS))
2052 type = eSymbolTypeData;
2053 else
2054 type = eSymbolTypeCode;
2055 } else if (symbol_section->IsDescendant(data_section_sp.get()) ||
2056 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
2057 symbol_section->IsDescendant(data_const_section_sp.get())) {
2058 if (symbol_sect_name.starts_with("__objc")) {
2059 type = eSymbolTypeRuntime;
2060
2061 if (symbol_name) {
2062 llvm::StringRef symbol_name_ref(symbol_name);
2063 if (symbol_name_ref.starts_with("OBJC_")) {
2064 static const llvm::StringRef g_objc_v2_prefix_class("OBJC_CLASS_$_");
2065 static const llvm::StringRef g_objc_v2_prefix_metaclass(
2066 "OBJC_METACLASS_$_");
2067 static const llvm::StringRef g_objc_v2_prefix_ivar("OBJC_IVAR_$_");
2068 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
2069 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2070 type = eSymbolTypeObjCClass;
2071 demangled_is_synthesized = true;
2072 } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
2073 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2075 demangled_is_synthesized = true;
2076 } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
2077 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2078 type = eSymbolTypeObjCIVar;
2079 demangled_is_synthesized = true;
2080 }
2081 }
2082 }
2083 } else if (symbol_sect_name.starts_with("__gcc_except_tab")) {
2084 type = eSymbolTypeException;
2085 } else {
2086 type = eSymbolTypeData;
2087 }
2088 } else if (symbol_sect_name.starts_with("__IMPORT")) {
2089 type = eSymbolTypeTrampoline;
2090 }
2091 return type;
2092}
2093
2094static std::optional<struct nlist_64>
2095ParseNList(DataExtractor &nlist_data, lldb::offset_t &nlist_data_offset,
2096 size_t nlist_byte_size) {
2097 struct nlist_64 nlist;
2098 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
2099 return {};
2100 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
2101 nlist.n_type = nlist_data.GetU8_unchecked(&nlist_data_offset);
2102 nlist.n_sect = nlist_data.GetU8_unchecked(&nlist_data_offset);
2103 nlist.n_desc = nlist_data.GetU16_unchecked(&nlist_data_offset);
2104 nlist.n_value = nlist_data.GetAddress_unchecked(&nlist_data_offset);
2105 return nlist;
2106}
2107
2108enum { DebugSymbols = true, NonDebugSymbols = false };
2109
2111 ModuleSP module_sp(GetModule());
2112 if (!module_sp)
2113 return;
2114
2115 Log *log = GetLog(LLDBLog::Symbols);
2116
2117 const FileSpec &file = m_file ? m_file : module_sp->GetFileSpec();
2118 llvm::StringRef file_name = file.GetFilename().nonEmptyOr("<Unknown>");
2119 LLDB_SCOPED_TIMERF("ObjectFileMachO::ParseSymtab () module = %s",
2120 file_name.str().c_str());
2121 LLDB_LOG(log, "Parsing symbol table for {0}", file_name);
2122 Progress progress("Parsing symbol table", file_name.str());
2123
2124 LinkeditDataCommandLargeOffsets function_starts_load_command;
2125 LinkeditDataCommandLargeOffsets exports_trie_load_command;
2128 SymtabCommandLargeOffsets symtab_load_command;
2129 // The data element of type bool indicates that this entry is thumb
2130 // code.
2131 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
2132
2133 // Record the address of every function/data that we add to the symtab.
2134 // We add symbols to the table in the order of most information (nlist
2135 // records) to least (function starts), and avoid duplicating symbols
2136 // via this set.
2137 llvm::DenseSet<addr_t> symbols_added;
2138
2139 // We are using a llvm::DenseSet for "symbols_added" so we must be sure we
2140 // do not add the empty key to the set.
2141 auto add_symbol_addr = [&symbols_added](lldb::addr_t file_addr) {
2142 // Don't add the empty key.
2143 if (file_addr == UINT64_MAX)
2144 return;
2145 symbols_added.insert(file_addr);
2146 };
2147 FunctionStarts function_starts;
2149 uint32_t i;
2150 FileSpecList dylib_files;
2151 UUID image_uuid;
2152
2153 for (i = 0; i < m_header.ncmds; ++i) {
2154 const lldb::offset_t cmd_offset = offset;
2155 // Read in the load command and load command size
2156 llvm::MachO::load_command lc;
2157 if (!ReadMachOCommand(*m_data_nsp, offset, lc))
2158 break;
2159 // Watch for the symbol table load command
2160 switch (lc.cmd) {
2161 case LC_SYMTAB: {
2162 llvm::MachO::symtab_command lc_obj;
2163 if (m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2164 lc_obj.cmd = lc.cmd;
2165 lc_obj.cmdsize = lc.cmdsize;
2166 symtab_load_command = lc_obj;
2167 }
2168 } break;
2169
2170 case LC_DYLD_INFO:
2171 case LC_DYLD_INFO_ONLY: {
2172 llvm::MachO::dyld_info_command lc_obj;
2173 if (m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2174 lc_obj.cmd = lc.cmd;
2175 lc_obj.cmdsize = lc.cmdsize;
2176 dyld_info = lc_obj;
2177 }
2178 } break;
2179
2180 case LC_LOAD_DYLIB:
2181 case LC_LOAD_WEAK_DYLIB:
2182 case LC_REEXPORT_DYLIB:
2183 case LC_LOADFVMLIB:
2184 case LC_LOAD_UPWARD_DYLIB: {
2185 uint32_t name_offset = cmd_offset + m_data_nsp->GetU32(&offset);
2186 if (std::optional<llvm::StringRef> path =
2187 m_data_nsp->PeekCStr(name_offset)) {
2188 FileSpec file_spec(*path);
2189 // Strip the path if there is @rpath, @executable, etc so we just use
2190 // the basename
2191 if (path->starts_with("@"))
2192 file_spec.ClearDirectory();
2193
2194 if (lc.cmd == LC_REEXPORT_DYLIB) {
2195 m_reexported_dylibs.AppendIfUnique(file_spec);
2196 }
2197
2198 dylib_files.Append(file_spec);
2199 }
2200 } break;
2201
2202 case LC_DYLD_EXPORTS_TRIE: {
2203 llvm::MachO::linkedit_data_command lc_obj;
2204 lc_obj.cmd = lc.cmd;
2205 lc_obj.cmdsize = lc.cmdsize;
2206 if (m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2207 exports_trie_load_command = lc_obj;
2208 } break;
2209 case LC_FUNCTION_STARTS: {
2210 llvm::MachO::linkedit_data_command lc_obj;
2211 lc_obj.cmd = lc.cmd;
2212 lc_obj.cmdsize = lc.cmdsize;
2213 if (m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2214 function_starts_load_command = lc_obj;
2215 } break;
2216
2217 case LC_UUID: {
2218 const uint8_t *uuid_bytes = m_data_nsp->PeekData(offset, 16);
2219
2220 if (uuid_bytes)
2221 image_uuid = UUID(uuid_bytes, 16);
2222 break;
2223 }
2224
2225 default:
2226 break;
2227 }
2228 offset = cmd_offset + lc.cmdsize;
2229 }
2230
2231 if (!symtab_load_command.cmd)
2232 return;
2233
2234 SectionList *section_list = GetSectionList();
2235 if (section_list == nullptr)
2236 return;
2237
2238 const uint32_t addr_byte_size = m_data_nsp->GetAddressByteSize();
2239 const ByteOrder byte_order = m_data_nsp->GetByteOrder();
2240 bool bit_width_32 = addr_byte_size == 4;
2241 const size_t nlist_byte_size =
2242 bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
2243
2244 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2245 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2246 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2247 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2248 addr_byte_size);
2249 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2250
2251 const addr_t nlist_data_byte_size =
2252 symtab_load_command.nsyms * nlist_byte_size;
2253 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
2254 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
2255
2256 ProcessSP process_sp(m_process_wp.lock());
2257 Process *process = process_sp.get();
2258
2259 uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
2260 bool is_shared_cache_image = IsSharedCacheBinary();
2261 bool is_local_shared_cache_image = is_shared_cache_image && !IsInMemory();
2262
2263 SectionSP text_section_sp(
2264 section_list->FindSectionByName(GetSegmentNameTEXT()));
2265 SectionSP data_section_sp(
2266 section_list->FindSectionByName(GetSegmentNameDATA()));
2267 SectionSP linkedit_section_sp(
2268 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2269 SectionSP data_dirty_section_sp(
2270 section_list->FindSectionByName(GetSegmentNameDATA_DIRTY()));
2271 SectionSP data_const_section_sp(
2272 section_list->FindSectionByName(GetSegmentNameDATA_CONST()));
2273 SectionSP objc_section_sp(
2274 section_list->FindSectionByName(GetSegmentNameOBJC()));
2275 SectionSP eh_frame_section_sp;
2276 SectionSP lldb_no_nlist_section_sp;
2277 llvm::StringRef g_section_name_eh_frame = GetSectionNameEHFrame();
2278 llvm::StringRef g_section_name_lldb_no_nlist = GetSectionNameLLDBNoNlist();
2279 if (text_section_sp.get()) {
2280 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2281 g_section_name_eh_frame);
2282 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2283 g_section_name_lldb_no_nlist);
2284 } else {
2285 eh_frame_section_sp =
2286 section_list->FindSectionByName(g_section_name_eh_frame);
2287 lldb_no_nlist_section_sp =
2288 section_list->FindSectionByName(g_section_name_lldb_no_nlist);
2289 }
2290
2291 if (process && m_header.filetype != llvm::MachO::MH_OBJECT &&
2292 !is_local_shared_cache_image) {
2293 Target &target = process->GetTarget();
2294
2295 memory_module_load_level = target.GetMemoryModuleLoadLevel();
2296
2297 // If __TEXT,__lldb_no_nlist section is present in this binary,
2298 // and we're reading it out of memory, do not read any of the
2299 // nlist entries. They are not needed in lldb and it may be
2300 // expensive to load these. This is to handle a dylib consisting
2301 // of only metadata, no code, but it has many nlist entries.
2302 if (lldb_no_nlist_section_sp)
2303 memory_module_load_level = eMemoryModuleLoadLevelMinimal;
2304
2305 // Reading mach file from memory in a process or core file...
2306
2307 if (linkedit_section_sp) {
2308 addr_t linkedit_load_addr =
2309 linkedit_section_sp->GetLoadBaseAddress(&target);
2310 if (linkedit_load_addr == LLDB_INVALID_ADDRESS) {
2311 // We might be trying to access the symbol table before the
2312 // __LINKEDIT's load address has been set in the target. We can't
2313 // fail to read the symbol table, so calculate the right address
2314 // manually
2315 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
2316 m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2317 }
2318
2319 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2320 const addr_t symoff_addr = linkedit_load_addr +
2321 symtab_load_command.symoff -
2322 linkedit_file_offset;
2323 strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
2324 linkedit_file_offset;
2325
2326 // Always load dyld - the dynamic linker - from memory if we didn't
2327 // find a binary anywhere else. lldb will not register
2328 // dylib/framework/bundle loads/unloads if we don't have the dyld
2329 // symbols, we force dyld to load from memory despite the user's
2330 // target.memory-module-load-level setting.
2331 if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||
2332 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2333 DataBufferSP nlist_data_sp(
2334 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2335 if (nlist_data_sp)
2336 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2337 if (dysymtab.nindirectsyms != 0) {
2338 const addr_t indirect_syms_addr = linkedit_load_addr +
2339 dysymtab.indirectsymoff -
2340 linkedit_file_offset;
2341 DataBufferSP indirect_syms_data_sp(ReadMemory(
2342 process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));
2343 if (indirect_syms_data_sp)
2344 indirect_symbol_index_data.SetData(
2345 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2346 // If this binary is outside the shared cache,
2347 // cache the string table.
2348 // Binaries in the shared cache all share a giant string table,
2349 // and we can't share the string tables across multiple
2350 // ObjectFileMachO's, so we'd end up re-reading this mega-strtab
2351 // for every binary in the shared cache - it would be a big perf
2352 // problem. For binaries outside the shared cache, it's faster to
2353 // read the entire strtab at once instead of piece-by-piece as we
2354 // process the nlist records.
2355 if (!is_shared_cache_image) {
2356 DataBufferSP strtab_data_sp(
2357 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2358 if (strtab_data_sp) {
2359 strtab_data.SetData(strtab_data_sp, 0,
2360 strtab_data_sp->GetByteSize());
2361 }
2362 }
2363 }
2364 if (memory_module_load_level >= eMemoryModuleLoadLevelPartial) {
2365 if (function_starts_load_command.cmd) {
2366 const addr_t func_start_addr =
2367 linkedit_load_addr + function_starts_load_command.dataoff -
2368 linkedit_file_offset;
2369 DataBufferSP func_start_data_sp(
2370 ReadMemory(process_sp, func_start_addr,
2371 function_starts_load_command.datasize));
2372 if (func_start_data_sp)
2373 function_starts_data.SetData(func_start_data_sp, 0,
2374 func_start_data_sp->GetByteSize());
2375 }
2376 }
2377 }
2378 }
2379 } else {
2380 if (is_local_shared_cache_image && linkedit_section_sp) {
2381 // The load commands in shared cache images are relative to the
2382 // beginning of the shared cache, not the library image. The
2383 // data we get handed when creating the ObjectFileMachO starts
2384 // at the beginning of a specific library and spans to the end
2385 // of the cache to be able to reach the shared LINKEDIT
2386 // segments. We need to convert the load command offsets to be
2387 // relative to the beginning of our specific image.
2388 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2389 lldb::offset_t linkedit_slide =
2390 linkedit_offset - m_linkedit_original_offset;
2391 symtab_load_command.symoff += linkedit_slide;
2392 symtab_load_command.stroff += linkedit_slide;
2393 dyld_info.export_off += linkedit_slide;
2394 dysymtab.indirectsymoff += linkedit_slide;
2395 function_starts_load_command.dataoff += linkedit_slide;
2396 exports_trie_load_command.dataoff += linkedit_slide;
2397 }
2398
2399 nlist_data = *m_data_nsp->GetSubsetExtractorSP(symtab_load_command.symoff,
2400 nlist_data_byte_size);
2401 strtab_data = *m_data_nsp->GetSubsetExtractorSP(symtab_load_command.stroff,
2402 strtab_data_byte_size);
2403
2404 // We shouldn't have exports data from both the LC_DYLD_INFO command
2405 // AND the LC_DYLD_EXPORTS_TRIE command in the same binary:
2406 lldbassert(!((dyld_info.export_size > 0)
2407 && (exports_trie_load_command.datasize > 0)));
2408 if (dyld_info.export_size > 0) {
2409 dyld_trie_data = *m_data_nsp->GetSubsetExtractorSP(dyld_info.export_off,
2410 dyld_info.export_size);
2411 } else if (exports_trie_load_command.datasize > 0) {
2412 dyld_trie_data =
2413 *m_data_nsp->GetSubsetExtractorSP(exports_trie_load_command.dataoff,
2414 exports_trie_load_command.datasize);
2415 }
2416
2417 if (dysymtab.nindirectsyms != 0) {
2418 indirect_symbol_index_data = *m_data_nsp->GetSubsetExtractorSP(
2419 dysymtab.indirectsymoff, dysymtab.nindirectsyms * 4);
2420 }
2421 if (function_starts_load_command.cmd) {
2422 function_starts_data = *m_data_nsp->GetSubsetExtractorSP(
2423 function_starts_load_command.dataoff,
2424 function_starts_load_command.datasize);
2425 }
2426 }
2427
2428 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2429
2430 const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2431 const bool always_thumb = GetArchitecture().IsAlwaysThumbInstructions();
2432
2433 // lldb works best if it knows the start address of all functions in a
2434 // module. Linker symbols or debug info are normally the best source of
2435 // information for start addr / size but they may be stripped in a released
2436 // binary. Two additional sources of information exist in Mach-O binaries:
2437 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each
2438 // function's start address in the
2439 // binary, relative to the text section.
2440 // eh_frame - the eh_frame FDEs have the start addr & size of
2441 // each function
2442 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on
2443 // all modern binaries.
2444 // Binaries built to run on older releases may need to use eh_frame
2445 // information.
2446
2447 if (text_section_sp && function_starts_data.GetByteSize()) {
2448 FunctionStarts::Entry function_start_entry;
2449 function_start_entry.data = false;
2450 lldb::offset_t function_start_offset = 0;
2451 function_start_entry.addr = text_section_sp->GetFileAddress();
2452 uint64_t delta;
2453 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2454 0) {
2455 // Now append the current entry
2456 function_start_entry.addr += delta;
2457 if (is_arm) {
2458 if (function_start_entry.addr & 1) {
2459 function_start_entry.addr &= THUMB_ADDRESS_BIT_MASK;
2460 function_start_entry.data = true;
2461 } else if (always_thumb) {
2462 function_start_entry.data = true;
2463 }
2464 }
2465 function_starts.Append(function_start_entry);
2466 }
2467 } else {
2468 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the
2469 // load command claiming an eh_frame but it doesn't actually have the
2470 // eh_frame content. And if we have a dSYM, we don't need to do any of
2471 // this fill-in-the-missing-symbols works anyway - the debug info should
2472 // give us all the functions in the module.
2473 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2475 DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp,
2478 eh_frame.GetFunctionAddressAndSizeVector(functions);
2479 addr_t text_base_addr = text_section_sp->GetFileAddress();
2480 size_t count = functions.GetSize();
2481 for (size_t i = 0; i < count; ++i) {
2483 functions.GetEntryAtIndex(i);
2484 if (func) {
2485 FunctionStarts::Entry function_start_entry;
2486 function_start_entry.addr = func->base - text_base_addr;
2487 if (is_arm) {
2488 if (function_start_entry.addr & 1) {
2489 function_start_entry.addr &= THUMB_ADDRESS_BIT_MASK;
2490 function_start_entry.data = true;
2491 } else if (always_thumb) {
2492 function_start_entry.data = true;
2493 }
2494 }
2495 function_starts.Append(function_start_entry);
2496 }
2497 }
2498 }
2499 }
2500
2501 const size_t function_starts_count = function_starts.GetSize();
2502
2503 // For user process binaries (executables, dylibs, frameworks, bundles), if
2504 // we don't have LC_FUNCTION_STARTS/eh_frame section in this binary, we're
2505 // going to assume the binary has been stripped. Don't allow assembly
2506 // language instruction emulation because we don't know proper function
2507 // start boundaries.
2508 //
2509 // For all other types of binaries (kernels, stand-alone bare board
2510 // binaries, kexts), they may not have LC_FUNCTION_STARTS / eh_frame
2511 // sections - we should not make any assumptions about them based on that.
2512 if (function_starts_count == 0 && CalculateStrata() == eStrataUser) {
2514 Log *unwind_or_symbol_log(GetLog(LLDBLog::Symbols | LLDBLog::Unwind));
2515
2516 if (unwind_or_symbol_log)
2517 module_sp->LogMessage(
2518 unwind_or_symbol_log,
2519 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2520 }
2521
2522 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2523 ? eh_frame_section_sp->GetID()
2524 : static_cast<user_id_t>(NO_SECT);
2525
2526 uint32_t N_SO_index = UINT32_MAX;
2527
2528 MachSymtabSectionInfo section_info(section_list);
2529 std::vector<uint32_t> N_FUN_indexes;
2530 std::vector<uint32_t> N_NSYM_indexes;
2531 std::vector<uint32_t> N_INCL_indexes;
2532 std::vector<uint32_t> N_BRAC_indexes;
2533 std::vector<uint32_t> N_COMM_indexes;
2534 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2535 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2536 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2537 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2538 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2539 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2540 // Any symbols that get merged into another will get an entry in this map
2541 // so we know
2542 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2543 uint32_t nlist_idx = 0;
2544 Symbol *symbol_ptr = nullptr;
2545
2546 uint32_t sym_idx = 0;
2547 Symbol *sym = nullptr;
2548 size_t num_syms = 0;
2549 std::string memory_symbol_name;
2550 uint32_t unmapped_local_symbols_found = 0;
2551
2552 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2553 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2554 std::set<lldb::addr_t> resolver_addresses;
2555
2556 const size_t dyld_trie_data_size = dyld_trie_data.GetByteSize();
2557 if (dyld_trie_data_size > 0) {
2558 LLDB_LOG(log, "Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2559 SectionSP text_segment_sp =
2561 lldb::addr_t text_segment_file_addr = LLDB_INVALID_ADDRESS;
2562 if (text_segment_sp)
2563 text_segment_file_addr = text_segment_sp->GetFileAddress();
2564 ParseTrieEntries(dyld_trie_data, is_arm, text_segment_file_addr,
2565 resolver_addresses, reexport_trie_entries,
2566 external_sym_trie_entries);
2567 }
2568
2569 typedef std::set<ConstString> IndirectSymbols;
2570 IndirectSymbols indirect_symbol_names;
2571
2572#if TARGET_OS_IPHONE
2573
2574 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been
2575 // optimized by moving LOCAL symbols out of the memory mapped portion of
2576 // the DSC. The symbol information has all been retained, but it isn't
2577 // available in the normal nlist data. However, there *are* duplicate
2578 // entries of *some*
2579 // LOCAL symbols in the normal nlist data. To handle this situation
2580 // correctly, we must first attempt
2581 // to parse any DSC unmapped symbol information. If we find any, we set a
2582 // flag that tells the normal nlist parser to ignore all LOCAL symbols.
2583
2584 if (IsSharedCacheBinary()) {
2585 // Before we can start mapping the DSC, we need to make certain the
2586 // target process is actually using the cache we can find.
2587
2588 // Next we need to determine the correct path for the dyld shared cache.
2589
2590 ArchSpec header_arch = GetArchitecture();
2591
2592 UUID dsc_uuid;
2593 UUID process_shared_cache_uuid;
2594 addr_t process_shared_cache_base_addr;
2595
2596 if (process) {
2597 GetProcessSharedCacheUUID(process, process_shared_cache_base_addr,
2598 process_shared_cache_uuid);
2599 }
2600
2601 __block bool found_image = false;
2602 __block void *nlist_buffer = nullptr;
2603 __block unsigned nlist_count = 0;
2604 __block char *string_table = nullptr;
2605 __block vm_offset_t vm_nlist_memory = 0;
2606 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2607 __block vm_offset_t vm_string_memory = 0;
2608 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2609
2610 llvm::scope_exit _(^{
2611 if (vm_nlist_memory)
2612 vm_deallocate(mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2613 if (vm_string_memory)
2614 vm_deallocate(mach_task_self(), vm_string_memory, vm_string_bytes_read);
2615 });
2616
2617 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2618 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2619 UndefinedNameToDescMap undefined_name_to_desc;
2620 SymbolIndexToName reexport_shlib_needs_fixup;
2621
2622 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2623 uuid_t cache_uuid;
2624 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2625 if (found_image)
2626 return;
2627
2628 if (process_shared_cache_uuid.IsValid() &&
2629 process_shared_cache_uuid != UUID(&cache_uuid, 16))
2630 return;
2631
2632 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2633 uuid_t dsc_image_uuid;
2634 if (found_image)
2635 return;
2636
2637 dyld_image_copy_uuid(image, &dsc_image_uuid);
2638 if (image_uuid != UUID(dsc_image_uuid, 16))
2639 return;
2640
2641 found_image = true;
2642
2643 // Compute the size of the string table. We need to ask dyld for a
2644 // new SPI to avoid this step.
2645 dyld_image_local_nlist_content_4Symbolication(
2646 image, ^(const void *nlistStart, uint64_t nlistCount,
2647 const char *stringTable) {
2648 if (!nlistStart || !nlistCount)
2649 return;
2650
2651 // The buffers passed here are valid only inside the block.
2652 // Use vm_read to make a cheap copy of them available for our
2653 // processing later.
2654 kern_return_t ret =
2655 vm_read(mach_task_self(), (vm_address_t)nlistStart,
2656 nlist_byte_size * nlistCount, &vm_nlist_memory,
2657 &vm_nlist_bytes_read);
2658 if (ret != KERN_SUCCESS)
2659 return;
2660 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2661
2662 // We don't know the size of the string table. It's cheaper
2663 // to map the whole VM region than to determine the size by
2664 // parsing all the nlist entries.
2665 vm_address_t string_address = (vm_address_t)stringTable;
2666 vm_size_t region_size;
2667 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2668 vm_region_basic_info_data_t info;
2669 memory_object_name_t object;
2670 ret = vm_region_64(mach_task_self(), &string_address,
2671 &region_size, VM_REGION_BASIC_INFO_64,
2672 (vm_region_info_t)&info, &info_count, &object);
2673 if (ret != KERN_SUCCESS)
2674 return;
2675
2676 ret = vm_read(mach_task_self(), (vm_address_t)stringTable,
2677 region_size -
2678 ((vm_address_t)stringTable - string_address),
2679 &vm_string_memory, &vm_string_bytes_read);
2680 if (ret != KERN_SUCCESS)
2681 return;
2682
2683 nlist_buffer = (void *)vm_nlist_memory;
2684 string_table = (char *)vm_string_memory;
2685 nlist_count = nlistCount;
2686 });
2687 });
2688 });
2689 if (nlist_buffer) {
2690 DataExtractor dsc_local_symbols_data(nlist_buffer,
2691 nlist_count * nlist_byte_size,
2692 byte_order, addr_byte_size);
2693 DataExtractor dsc_string_table_data(string_table, vm_string_bytes_read,
2694 byte_order, addr_byte_size);
2695 unmapped_local_symbols_found = nlist_count;
2696
2697 // The normal nlist code cannot correctly size the Symbols
2698 // array, we need to allocate it here.
2699 sym = symtab.Resize(
2700 symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
2701 unmapped_local_symbols_found - m_dysymtab.nlocalsym);
2702 num_syms = symtab.GetNumSymbols();
2703
2704 lldb::offset_t nlist_data_offset = 0;
2705
2706 for (uint32_t nlist_index = 0;
2707 nlist_index < nlist_count;
2708 nlist_index++) {
2709 /////////////////////////////
2710 {
2711 std::optional<struct nlist_64> nlist_maybe =
2712 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2713 nlist_byte_size);
2714 if (!nlist_maybe)
2715 break;
2716 struct nlist_64 nlist = *nlist_maybe;
2717
2719 const char *symbol_name = NULL;
2720 std::optional<llvm::StringRef> name =
2721 dsc_string_table_data.PeekCStr(nlist.n_strx);
2722
2723 if (!name) {
2724 // No symbol should be NULL, even the symbols with no
2725 // string values should have an offset zero which
2726 // points to an empty C-string
2727 Debugger::ReportError(llvm::formatv(
2728 "DSC unmapped local symbol[{0}] has invalid or "
2729 "unterminated string table offset {1:x} in {2}, "
2730 "ignoring symbol",
2731 nlist_index, nlist.n_strx,
2732 module_sp->GetFileSpec().GetPath()));
2733 continue;
2734 }
2735 // The code below spells "no name" as a NULL pointer.
2736 if (!name->empty())
2737 symbol_name = name->data();
2738
2739 const char *symbol_name_non_abi_mangled = NULL;
2740
2741 SectionSP symbol_section;
2742 bool add_nlist = true;
2743 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2744 bool demangled_is_synthesized = false;
2745 bool is_gsym = false;
2746 bool set_value = true;
2747
2748 assert(sym_idx < num_syms);
2749
2750 sym[sym_idx].SetDebug(is_debug);
2751
2752 if (is_debug) {
2753 switch (nlist.n_type) {
2754 case N_GSYM:
2755 // global symbol: name,,NO_SECT,type,0
2756 // Sometimes the N_GSYM value contains the address.
2757
2758 // FIXME: In the .o files, we have a GSYM and a debug
2759 // symbol for all the ObjC data. They
2760 // have the same address, but we want to ensure that
2761 // we always find only the real symbol, 'cause we
2762 // don't currently correctly attribute the
2763 // GSYM one to the ObjCClass/Ivar/MetaClass
2764 // symbol type. This is a temporary hack to make
2765 // sure the ObjectiveC symbols get treated correctly.
2766 // To do this right, we should coalesce all the GSYM
2767 // & global symbols that have the same address.
2768
2769 is_gsym = true;
2770 sym[sym_idx].SetExternal(true);
2771
2773 symbol_name, symbol_name_non_abi_mangled,
2774 type)) {
2775 demangled_is_synthesized = true;
2776 } else {
2777 if (nlist.n_value != 0)
2778 symbol_section = section_info.GetSection(
2779 nlist.n_sect, nlist.n_value);
2780
2781 type = eSymbolTypeData;
2782 }
2783 break;
2784
2785 case N_FNAME:
2786 // procedure name (f77 kludge): name,,NO_SECT,0,0
2787 type = eSymbolTypeCompiler;
2788 break;
2789
2790 case N_FUN:
2791 // procedure: name,,n_sect,linenumber,address
2792 if (symbol_name) {
2793 type = eSymbolTypeCode;
2794 symbol_section = section_info.GetSection(
2795 nlist.n_sect, nlist.n_value);
2796
2797 N_FUN_addr_to_sym_idx.insert(
2798 std::make_pair(nlist.n_value, sym_idx));
2799 // We use the current number of symbols in the
2800 // symbol table in lieu of using nlist_idx in case
2801 // we ever start trimming entries out
2802 N_FUN_indexes.push_back(sym_idx);
2803 } else {
2804 type = eSymbolTypeCompiler;
2805
2806 if (!N_FUN_indexes.empty()) {
2807 // Copy the size of the function into the
2808 // original
2809 // STAB entry so we don't have
2810 // to hunt for it later
2811 symtab.SymbolAtIndex(N_FUN_indexes.back())
2812 ->SetByteSize(nlist.n_value);
2813 N_FUN_indexes.pop_back();
2814 // We don't really need the end function STAB as
2815 // it contains the size which we already placed
2816 // with the original symbol, so don't add it if
2817 // we want a minimal symbol table
2818 add_nlist = false;
2819 }
2820 }
2821 break;
2822
2823 case N_STSYM:
2824 // static symbol: name,,n_sect,type,address
2825 N_STSYM_addr_to_sym_idx.insert(
2826 std::make_pair(nlist.n_value, sym_idx));
2827 symbol_section = section_info.GetSection(nlist.n_sect,
2828 nlist.n_value);
2829 if (symbol_name && symbol_name[0]) {
2831 symbol_name + 1, eSymbolTypeData);
2832 }
2833 break;
2834
2835 case N_LCSYM:
2836 // .lcomm symbol: name,,n_sect,type,address
2837 symbol_section = section_info.GetSection(nlist.n_sect,
2838 nlist.n_value);
2840 break;
2841
2842 case N_BNSYM:
2843 // We use the current number of symbols in the symbol
2844 // table in lieu of using nlist_idx in case we ever
2845 // start trimming entries out Skip these if we want
2846 // minimal symbol tables
2847 add_nlist = false;
2848 break;
2849
2850 case N_ENSYM:
2851 // Set the size of the N_BNSYM to the terminating
2852 // index of this N_ENSYM so that we can always skip
2853 // the entire symbol if we need to navigate more
2854 // quickly at the source level when parsing STABS
2855 // Skip these if we want minimal symbol tables
2856 add_nlist = false;
2857 break;
2858
2859 case N_OPT:
2860 // emitted with gcc2_compiled and in gcc source
2861 type = eSymbolTypeCompiler;
2862 break;
2863
2864 case N_RSYM:
2865 // register sym: name,,NO_SECT,type,register
2866 type = eSymbolTypeVariable;
2867 break;
2868
2869 case N_SLINE:
2870 // src line: 0,,n_sect,linenumber,address
2871 symbol_section = section_info.GetSection(nlist.n_sect,
2872 nlist.n_value);
2873 type = eSymbolTypeLineEntry;
2874 break;
2875
2876 case N_SSYM:
2877 // structure elt: name,,NO_SECT,type,struct_offset
2879 break;
2880
2881 case N_SO:
2882 // source file name
2883 type = eSymbolTypeSourceFile;
2884 if (symbol_name == NULL) {
2885 add_nlist = false;
2886 if (N_SO_index != UINT32_MAX) {
2887 // Set the size of the N_SO to the terminating
2888 // index of this N_SO so that we can always skip
2889 // the entire N_SO if we need to navigate more
2890 // quickly at the source level when parsing STABS
2891 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
2892 symbol_ptr->SetByteSize(sym_idx);
2893 symbol_ptr->SetSizeIsSibling(true);
2894 }
2895 N_NSYM_indexes.clear();
2896 N_INCL_indexes.clear();
2897 N_BRAC_indexes.clear();
2898 N_COMM_indexes.clear();
2899 N_FUN_indexes.clear();
2900 N_SO_index = UINT32_MAX;
2901 } else {
2902 // We use the current number of symbols in the
2903 // symbol table in lieu of using nlist_idx in case
2904 // we ever start trimming entries out
2905 const bool N_SO_has_full_path = symbol_name[0] == '/';
2906 if (N_SO_has_full_path) {
2907 if ((N_SO_index == sym_idx - 1) &&
2908 ((sym_idx - 1) < num_syms)) {
2909 // We have two consecutive N_SO entries where
2910 // the first contains a directory and the
2911 // second contains a full path.
2912 sym[sym_idx - 1].GetMangled().SetValue(
2913 ConstString(symbol_name));
2914 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2915 add_nlist = false;
2916 } else {
2917 // This is the first entry in a N_SO that
2918 // contains a directory or
2919 // a full path to the source file
2920 N_SO_index = sym_idx;
2921 }
2922 } else if ((N_SO_index == sym_idx - 1) &&
2923 ((sym_idx - 1) < num_syms)) {
2924 // This is usually the second N_SO entry that
2925 // contains just the filename, so here we combine
2926 // it with the first one if we are minimizing the
2927 // symbol table
2928 const char *so_path = sym[sym_idx - 1]
2929 .GetMangled()
2931 .AsCString();
2932 if (so_path && so_path[0]) {
2933 std::string full_so_path(so_path);
2934 const size_t double_slash_pos =
2935 full_so_path.find("//");
2936 if (double_slash_pos != std::string::npos) {
2937 // The linker has been generating bad N_SO
2938 // entries with doubled up paths
2939 // in the format "%s%s" where the first
2940 // string in the DW_AT_comp_dir, and the
2941 // second is the directory for the source
2942 // file so you end up with a path that looks
2943 // like "/tmp/src//tmp/src/"
2944 FileSpec so_dir(so_path);
2945 if (!FileSystem::Instance().Exists(so_dir)) {
2946 so_dir.SetFile(
2947 &full_so_path[double_slash_pos + 1],
2948 FileSpec::Style::native);
2949 if (FileSystem::Instance().Exists(so_dir)) {
2950 // Trim off the incorrect path
2951 full_so_path.erase(0, double_slash_pos + 1);
2952 }
2953 }
2954 }
2955 if (*full_so_path.rbegin() != '/')
2956 full_so_path += '/';
2957 full_so_path += symbol_name;
2958 sym[sym_idx - 1].GetMangled().SetValue(
2959 ConstString(full_so_path.c_str()));
2960 add_nlist = false;
2961 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2962 }
2963 } else {
2964 // This could be a relative path to a N_SO
2965 N_SO_index = sym_idx;
2966 }
2967 }
2968 break;
2969
2970 case N_OSO:
2971 // object file name: name,,0,0,st_mtime
2972 type = eSymbolTypeObjectFile;
2973 break;
2974
2975 case N_LSYM:
2976 // local sym: name,,NO_SECT,type,offset
2977 type = eSymbolTypeLocal;
2978 break;
2979
2980 // INCL scopes
2981 case N_BINCL:
2982 // include file beginning: name,,NO_SECT,0,sum We use
2983 // the current number of symbols in the symbol table
2984 // in lieu of using nlist_idx in case we ever start
2985 // trimming entries out
2986 N_INCL_indexes.push_back(sym_idx);
2987 type = eSymbolTypeScopeBegin;
2988 break;
2989
2990 case N_EINCL:
2991 // include file end: name,,NO_SECT,0,0
2992 // Set the size of the N_BINCL to the terminating
2993 // index of this N_EINCL so that we can always skip
2994 // the entire symbol if we need to navigate more
2995 // quickly at the source level when parsing STABS
2996 if (!N_INCL_indexes.empty()) {
2997 symbol_ptr =
2998 symtab.SymbolAtIndex(N_INCL_indexes.back());
2999 symbol_ptr->SetByteSize(sym_idx + 1);
3000 symbol_ptr->SetSizeIsSibling(true);
3001 N_INCL_indexes.pop_back();
3002 }
3003 type = eSymbolTypeScopeEnd;
3004 break;
3005
3006 case N_SOL:
3007 // #included file name: name,,n_sect,0,address
3008 type = eSymbolTypeHeaderFile;
3009
3010 // We currently don't use the header files on darwin
3011 add_nlist = false;
3012 break;
3013
3014 case N_PARAMS:
3015 // compiler parameters: name,,NO_SECT,0,0
3016 type = eSymbolTypeCompiler;
3017 break;
3018
3019 case N_VERSION:
3020 // compiler version: name,,NO_SECT,0,0
3021 type = eSymbolTypeCompiler;
3022 break;
3023
3024 case N_OLEVEL:
3025 // compiler -O level: name,,NO_SECT,0,0
3026 type = eSymbolTypeCompiler;
3027 break;
3028
3029 case N_PSYM:
3030 // parameter: name,,NO_SECT,type,offset
3031 type = eSymbolTypeVariable;
3032 break;
3033
3034 case N_ENTRY:
3035 // alternate entry: name,,n_sect,linenumber,address
3036 symbol_section = section_info.GetSection(nlist.n_sect,
3037 nlist.n_value);
3038 type = eSymbolTypeLineEntry;
3039 break;
3040
3041 // Left and Right Braces
3042 case N_LBRAC:
3043 // left bracket: 0,,NO_SECT,nesting level,address We
3044 // use the current number of symbols in the symbol
3045 // table in lieu of using nlist_idx in case we ever
3046 // start trimming entries out
3047 symbol_section = section_info.GetSection(nlist.n_sect,
3048 nlist.n_value);
3049 N_BRAC_indexes.push_back(sym_idx);
3050 type = eSymbolTypeScopeBegin;
3051 break;
3052
3053 case N_RBRAC:
3054 // right bracket: 0,,NO_SECT,nesting level,address
3055 // Set the size of the N_LBRAC to the terminating
3056 // index of this N_RBRAC so that we can always skip
3057 // the entire symbol if we need to navigate more
3058 // quickly at the source level when parsing STABS
3059 symbol_section = section_info.GetSection(nlist.n_sect,
3060 nlist.n_value);
3061 if (!N_BRAC_indexes.empty()) {
3062 symbol_ptr =
3063 symtab.SymbolAtIndex(N_BRAC_indexes.back());
3064 symbol_ptr->SetByteSize(sym_idx + 1);
3065 symbol_ptr->SetSizeIsSibling(true);
3066 N_BRAC_indexes.pop_back();
3067 }
3068 type = eSymbolTypeScopeEnd;
3069 break;
3070
3071 case N_EXCL:
3072 // deleted include file: name,,NO_SECT,0,sum
3073 type = eSymbolTypeHeaderFile;
3074 break;
3075
3076 // COMM scopes
3077 case N_BCOMM:
3078 // begin common: name,,NO_SECT,0,0
3079 // We use the current number of symbols in the symbol
3080 // table in lieu of using nlist_idx in case we ever
3081 // start trimming entries out
3082 type = eSymbolTypeScopeBegin;
3083 N_COMM_indexes.push_back(sym_idx);
3084 break;
3085
3086 case N_ECOML:
3087 // end common (local name): 0,,n_sect,0,address
3088 symbol_section = section_info.GetSection(nlist.n_sect,
3089 nlist.n_value);
3090 // Fall through
3091
3092 case N_ECOMM:
3093 // end common: name,,n_sect,0,0
3094 // Set the size of the N_BCOMM to the terminating
3095 // index of this N_ECOMM/N_ECOML so that we can
3096 // always skip the entire symbol if we need to
3097 // navigate more quickly at the source level when
3098 // parsing STABS
3099 if (!N_COMM_indexes.empty()) {
3100 symbol_ptr =
3101 symtab.SymbolAtIndex(N_COMM_indexes.back());
3102 symbol_ptr->SetByteSize(sym_idx + 1);
3103 symbol_ptr->SetSizeIsSibling(true);
3104 N_COMM_indexes.pop_back();
3105 }
3106 type = eSymbolTypeScopeEnd;
3107 break;
3108
3109 case N_LENG:
3110 // second stab entry with length information
3111 type = eSymbolTypeAdditional;
3112 break;
3113
3114 default:
3115 break;
3116 }
3117 } else {
3118 // uint8_t n_pext = N_PEXT & nlist.n_type;
3119 uint8_t n_type = N_TYPE & nlist.n_type;
3120 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3121
3122 switch (n_type) {
3123 case N_INDR: {
3124 std::optional<llvm::StringRef> reexport_name_str =
3125 strtab_data.PeekCStr(nlist.n_value);
3126 if (reexport_name_str && !reexport_name_str->empty()) {
3127 type = eSymbolTypeReExported;
3128 ConstString reexport_name(
3129 reexport_name_str->drop_front(
3130 reexport_name_str->front() == '_' ? 1 : 0));
3131 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3132 set_value = false;
3133 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3134 indirect_symbol_names.insert(ConstString(
3135 symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
3136 } else
3137 type = eSymbolTypeUndefined;
3138 } break;
3139
3140 case N_UNDF:
3141 if (symbol_name && symbol_name[0]) {
3142 ConstString undefined_name(
3143 symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
3144 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3145 }
3146 // Fall through
3147 case N_PBUD:
3148 type = eSymbolTypeUndefined;
3149 break;
3150
3151 case N_ABS:
3152 type = eSymbolTypeAbsolute;
3153 break;
3154
3155 case N_SECT: {
3156 symbol_section = section_info.GetSection(nlist.n_sect,
3157 nlist.n_value);
3158
3159 if (symbol_section == NULL) {
3160 // TODO: warn about this?
3161 add_nlist = false;
3162 break;
3163 }
3164
3165 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3166 type = eSymbolTypeException;
3167 } else {
3168 uint32_t section_type =
3169 symbol_section->Get() & SECTION_TYPE;
3170
3171 switch (section_type) {
3172 case S_CSTRING_LITERALS:
3173 type = eSymbolTypeData;
3174 break; // section with only literal C strings
3175 case S_4BYTE_LITERALS:
3176 type = eSymbolTypeData;
3177 break; // section with only 4 byte literals
3178 case S_8BYTE_LITERALS:
3179 type = eSymbolTypeData;
3180 break; // section with only 8 byte literals
3181 case S_LITERAL_POINTERS:
3182 type = eSymbolTypeTrampoline;
3183 break; // section with only pointers to literals
3184 case S_NON_LAZY_SYMBOL_POINTERS:
3185 type = eSymbolTypeTrampoline;
3186 break; // section with only non-lazy symbol
3187 // pointers
3188 case S_LAZY_SYMBOL_POINTERS:
3189 type = eSymbolTypeTrampoline;
3190 break; // section with only lazy symbol pointers
3191 case S_SYMBOL_STUBS:
3192 type = eSymbolTypeTrampoline;
3193 break; // section with only symbol stubs, byte
3194 // size of stub in the reserved2 field
3195 case S_MOD_INIT_FUNC_POINTERS:
3196 type = eSymbolTypeCode;
3197 break; // section with only function pointers for
3198 // initialization
3199 case S_MOD_TERM_FUNC_POINTERS:
3200 type = eSymbolTypeCode;
3201 break; // section with only function pointers for
3202 // termination
3203 case S_INTERPOSING:
3204 type = eSymbolTypeTrampoline;
3205 break; // section with only pairs of function
3206 // pointers for interposing
3207 case S_16BYTE_LITERALS:
3208 type = eSymbolTypeData;
3209 break; // section with only 16 byte literals
3210 case S_DTRACE_DOF:
3212 break;
3213 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3214 type = eSymbolTypeTrampoline;
3215 break;
3216 default:
3217 switch (symbol_section->GetType()) {
3219 type = eSymbolTypeCode;
3220 break;
3221 case eSectionTypeData:
3222 case eSectionTypeDataCString: // Inlined C string
3223 // data
3224 case eSectionTypeDataCStringPointers: // Pointers
3225 // to C
3226 // string
3227 // data
3228 case eSectionTypeDataSymbolAddress: // Address of
3229 // a symbol in
3230 // the symbol
3231 // table
3232 case eSectionTypeData4:
3233 case eSectionTypeData8:
3234 case eSectionTypeData16:
3235 type = eSymbolTypeData;
3236 break;
3237 default:
3238 break;
3239 }
3240 break;
3241 }
3242
3243 if (type == eSymbolTypeInvalid) {
3244 llvm::StringRef symbol_sect_name =
3245 symbol_section->GetName();
3246 if (symbol_section->IsDescendant(
3247 text_section_sp.get())) {
3248 if (symbol_section->IsClear(
3249 S_ATTR_PURE_INSTRUCTIONS |
3250 S_ATTR_SELF_MODIFYING_CODE |
3251 S_ATTR_SOME_INSTRUCTIONS))
3252 type = eSymbolTypeData;
3253 else
3254 type = eSymbolTypeCode;
3255 } else if (symbol_section->IsDescendant(
3256 data_section_sp.get()) ||
3257 symbol_section->IsDescendant(
3258 data_dirty_section_sp.get()) ||
3259 symbol_section->IsDescendant(
3260 data_const_section_sp.get())) {
3261 if (symbol_sect_name.starts_with("__objc")) {
3262 type = eSymbolTypeRuntime;
3263
3265 symbol_name,
3266 symbol_name_non_abi_mangled, type))
3267 demangled_is_synthesized = true;
3268 } else if (symbol_sect_name.starts_with("__gcc_except_tab")) {
3269 type = eSymbolTypeException;
3270 } else {
3271 type = eSymbolTypeData;
3272 }
3273 } else if (symbol_sect_name.starts_with("__IMPORT"))
3274 type = eSymbolTypeTrampoline;
3275 } else if (symbol_section->IsDescendant(
3276 objc_section_sp.get())) {
3277 type = eSymbolTypeRuntime;
3278 if (symbol_name && symbol_name[0] == '.') {
3279 llvm::StringRef symbol_name_ref(symbol_name);
3280 llvm::StringRef
3281 g_objc_v1_prefix_class(".objc_class_name_");
3282 if (symbol_name_ref.starts_with(
3283 g_objc_v1_prefix_class)) {
3284 symbol_name_non_abi_mangled = symbol_name;
3285 symbol_name = symbol_name +
3286 g_objc_v1_prefix_class.size();
3287 type = eSymbolTypeObjCClass;
3288 demangled_is_synthesized = true;
3289 }
3290 }
3291 }
3292 }
3293 }
3294 } break;
3295 }
3296 }
3297
3298 if (add_nlist) {
3299 uint64_t symbol_value = nlist.n_value;
3300 if (symbol_name_non_abi_mangled) {
3301 sym[sym_idx].GetMangled().SetMangledName(
3302 ConstString(symbol_name_non_abi_mangled));
3303 sym[sym_idx].GetMangled().SetDemangledName(
3304 ConstString(symbol_name));
3305 } else {
3306 if (symbol_name && symbol_name[0] == '_') {
3307 symbol_name++; // Skip the leading underscore
3308 }
3309
3310 if (symbol_name) {
3311 ConstString const_symbol_name(symbol_name);
3312 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
3313 if (is_gsym && is_debug) {
3314 const char *gsym_name =
3315 sym[sym_idx]
3316 .GetMangled()
3318 .GetCString();
3319 if (gsym_name)
3320 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3321 }
3322 }
3323 }
3324 if (symbol_section) {
3325 const addr_t section_file_addr =
3326 symbol_section->GetFileAddress();
3327 symbol_value -= section_file_addr;
3328 }
3329
3330 if (is_debug == false) {
3331 if (type == eSymbolTypeCode) {
3332 // See if we can find a N_FUN entry for any code
3333 // symbols. If we do find a match, and the name
3334 // matches, then we can merge the two into just the
3335 // function symbol to avoid duplicate entries in
3336 // the symbol table
3337 auto range =
3338 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3339 if (range.first != range.second) {
3340 bool found_it = false;
3341 for (auto pos = range.first; pos != range.second;
3342 ++pos) {
3343 if (sym[sym_idx].GetMangled().GetName(
3345 sym[pos->second].GetMangled().GetName(
3347 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3348 // We just need the flags from the linker
3349 // symbol, so put these flags
3350 // into the N_FUN flags to avoid duplicate
3351 // symbols in the symbol table
3352 sym[pos->second].SetExternal(
3353 sym[sym_idx].IsExternal());
3354 sym[pos->second].SetFlags(nlist.n_type << 16 |
3355 nlist.n_desc);
3356 if (resolver_addresses.find(nlist.n_value) !=
3357 resolver_addresses.end())
3358 sym[pos->second].SetType(eSymbolTypeResolver);
3359 sym[sym_idx].Clear();
3360 found_it = true;
3361 break;
3362 }
3363 }
3364 if (found_it)
3365 continue;
3366 } else {
3367 if (resolver_addresses.find(nlist.n_value) !=
3368 resolver_addresses.end())
3369 type = eSymbolTypeResolver;
3370 }
3371 } else if (type == eSymbolTypeData ||
3372 type == eSymbolTypeObjCClass ||
3373 type == eSymbolTypeObjCMetaClass ||
3374 type == eSymbolTypeObjCIVar) {
3375 // See if we can find a N_STSYM entry for any data
3376 // symbols. If we do find a match, and the name
3377 // matches, then we can merge the two into just the
3378 // Static symbol to avoid duplicate entries in the
3379 // symbol table
3380 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3381 nlist.n_value);
3382 if (range.first != range.second) {
3383 bool found_it = false;
3384 for (auto pos = range.first; pos != range.second;
3385 ++pos) {
3386 if (sym[sym_idx].GetMangled().GetName(
3388 sym[pos->second].GetMangled().GetName(
3390 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3391 // We just need the flags from the linker
3392 // symbol, so put these flags
3393 // into the N_STSYM flags to avoid duplicate
3394 // symbols in the symbol table
3395 sym[pos->second].SetExternal(
3396 sym[sym_idx].IsExternal());
3397 sym[pos->second].SetFlags(nlist.n_type << 16 |
3398 nlist.n_desc);
3399 sym[sym_idx].Clear();
3400 found_it = true;
3401 break;
3402 }
3403 }
3404 if (found_it)
3405 continue;
3406 } else {
3407 const char *gsym_name =
3408 sym[sym_idx]
3409 .GetMangled()
3411 .GetCString();
3412 if (gsym_name) {
3413 // Combine N_GSYM stab entries with the non
3414 // stab symbol
3415 ConstNameToSymbolIndexMap::const_iterator pos =
3416 N_GSYM_name_to_sym_idx.find(gsym_name);
3417 if (pos != N_GSYM_name_to_sym_idx.end()) {
3418 const uint32_t GSYM_sym_idx = pos->second;
3419 m_nlist_idx_to_sym_idx[nlist_idx] =
3420 GSYM_sym_idx;
3421 // Copy the address, because often the N_GSYM
3422 // address has an invalid address of zero
3423 // when the global is a common symbol
3424 sym[GSYM_sym_idx].GetAddressRef() =
3425 Address(symbol_section, symbol_value);
3426 add_symbol_addr(sym[GSYM_sym_idx]
3427 .GetAddress()
3428 .GetFileAddress());
3429 // We just need the flags from the linker
3430 // symbol, so put these flags
3431 // into the N_GSYM flags to avoid duplicate
3432 // symbols in the symbol table
3433 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 |
3434 nlist.n_desc);
3435 sym[sym_idx].Clear();
3436 continue;
3437 }
3438 }
3439 }
3440 }
3441 }
3442
3443 sym[sym_idx].SetID(nlist_idx);
3444 sym[sym_idx].SetType(type);
3445 if (set_value) {
3446 sym[sym_idx].GetAddressRef() =
3447 Address(symbol_section, symbol_value);
3448 add_symbol_addr(
3449 sym[sym_idx].GetAddress().GetFileAddress());
3450 }
3451 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
3452
3453 if (demangled_is_synthesized)
3454 sym[sym_idx].SetDemangledNameIsSynthesized(true);
3455 ++sym_idx;
3456 } else {
3457 sym[sym_idx].Clear();
3458 }
3459 }
3460 /////////////////////////////
3461 }
3462 }
3463
3464 for (const auto &pos : reexport_shlib_needs_fixup) {
3465 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3466 if (undef_pos != undefined_name_to_desc.end()) {
3467 const uint8_t dylib_ordinal =
3468 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3469 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
3470 sym[pos.first].SetReExportedSymbolSharedLibrary(
3471 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
3472 }
3473 }
3474 }
3475
3476#endif
3477 lldb::offset_t nlist_data_offset = 0;
3478
3479 if (nlist_data.GetByteSize() > 0) {
3480
3481 const uint64_t max_nsyms = nlist_data.GetByteSize() / nlist_byte_size;
3482 const uint64_t max_nindirectsyms =
3483 indirect_symbol_index_data.GetByteSize() / sizeof(uint32_t);
3484
3485 // If the sym array was not created while parsing the DSC unmapped
3486 // symbols, create it now.
3487 if (sym == nullptr) {
3488 sym = symtab.Resize(
3489 std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms) +
3490 std::min<uint64_t>(m_dysymtab.nindirectsyms, max_nindirectsyms));
3491 num_syms = symtab.GetNumSymbols();
3492 }
3493
3494 if (unmapped_local_symbols_found) {
3495 assert(m_dysymtab.ilocalsym == 0);
3496 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3497 nlist_idx = m_dysymtab.nlocalsym;
3498 } else {
3499 nlist_idx = 0;
3500 }
3501
3502 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3503 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3504 UndefinedNameToDescMap undefined_name_to_desc;
3505 SymbolIndexToName reexport_shlib_needs_fixup;
3506
3507 // Symtab parsing is a huge mess. Everything is entangled and the code
3508 // requires access to a ridiculous amount of variables. LLDB depends
3509 // heavily on the proper merging of symbols and to get that right we need
3510 // to make sure we have parsed all the debug symbols first. Therefore we
3511 // invoke the lambda twice, once to parse only the debug symbols and then
3512 // once more to parse the remaining symbols.
3513 auto ParseSymbolLambda = [&](struct nlist_64 &nlist, uint32_t nlist_idx,
3514 bool debug_only) {
3515 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3516 if (is_debug != debug_only)
3517 return true;
3518
3519 const char *symbol_name_non_abi_mangled = nullptr;
3520 const char *symbol_name = nullptr;
3521
3522 if (have_strtab_data) {
3523 std::optional<llvm::StringRef> name =
3524 strtab_data.PeekCStr(nlist.n_strx);
3525
3526 if (!name) {
3527 // No symbol should be NULL, even the symbols with no string values
3528 // should have an offset zero which points to an empty C-string
3529 Debugger::ReportError(llvm::formatv(
3530 "symbol[{0}] has invalid or unterminated string table offset "
3531 "{1:x} in {2}, ignoring symbol",
3532 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3533 return true;
3534 }
3535 // The code below spells "no name" as a nullptr.
3536 if (!name->empty())
3537 symbol_name = name->data();
3538 } else {
3539 const addr_t str_addr = strtab_addr + nlist.n_strx;
3540 Status str_error;
3541 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3542 str_error))
3543 symbol_name = memory_symbol_name.c_str();
3544 }
3545
3547 SectionSP symbol_section;
3548 bool add_nlist = true;
3549 bool is_gsym = false;
3550 bool demangled_is_synthesized = false;
3551 bool set_value = true;
3552
3553 assert(sym_idx < num_syms);
3554 sym[sym_idx].SetDebug(is_debug);
3555
3556 if (is_debug) {
3557 switch (nlist.n_type) {
3558 case N_GSYM: {
3559 // global symbol: name,,NO_SECT,type,0
3560 // Sometimes the N_GSYM value contains the address.
3561
3562 // FIXME: In the .o files, we have a GSYM and a debug symbol for all
3563 // the ObjC data. They
3564 // have the same address, but we want to ensure that we always find
3565 // only the real symbol, 'cause we don't currently correctly
3566 // attribute the GSYM one to the ObjCClass/Ivar/MetaClass symbol
3567 // type. This is a temporary hack to make sure the ObjectiveC
3568 // symbols get treated correctly. To do this right, we should
3569 // coalesce all the GSYM & global symbols that have the same
3570 // address.
3571 is_gsym = true;
3572 sym[sym_idx].SetExternal(true);
3573
3574 if (TryParseV2ObjCMetadataSymbol(symbol_name,
3575 symbol_name_non_abi_mangled, type)) {
3576 demangled_is_synthesized = true;
3577 } else {
3578 if (nlist.n_value != 0)
3579 symbol_section =
3580 section_info.GetSection(nlist.n_sect, nlist.n_value);
3581
3582 type = eSymbolTypeData;
3583 }
3584 } break;
3585
3586 case N_FNAME:
3587 // procedure name (f77 kludge): name,,NO_SECT,0,0
3588 type = eSymbolTypeCompiler;
3589 break;
3590
3591 case N_FUN:
3592 // procedure: name,,n_sect,linenumber,address
3593 if (symbol_name) {
3594 type = eSymbolTypeCode;
3595 symbol_section =
3596 section_info.GetSection(nlist.n_sect, nlist.n_value);
3597
3598 N_FUN_addr_to_sym_idx.insert(
3599 std::make_pair(nlist.n_value, sym_idx));
3600 // We use the current number of symbols in the symbol table in
3601 // lieu of using nlist_idx in case we ever start trimming entries
3602 // out
3603 N_FUN_indexes.push_back(sym_idx);
3604 } else {
3605 type = eSymbolTypeCompiler;
3606
3607 if (!N_FUN_indexes.empty()) {
3608 // Copy the size of the function into the original STAB entry
3609 // so we don't have to hunt for it later
3610 symtab.SymbolAtIndex(N_FUN_indexes.back())
3611 ->SetByteSize(nlist.n_value);
3612 N_FUN_indexes.pop_back();
3613 // We don't really need the end function STAB as it contains
3614 // the size which we already placed with the original symbol,
3615 // so don't add it if we want a minimal symbol table
3616 add_nlist = false;
3617 }
3618 }
3619 break;
3620
3621 case N_STSYM:
3622 // static symbol: name,,n_sect,type,address
3623 N_STSYM_addr_to_sym_idx.insert(
3624 std::make_pair(nlist.n_value, sym_idx));
3625 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3626 if (symbol_name && symbol_name[0]) {
3627 type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1,
3629 }
3630 break;
3631
3632 case N_LCSYM:
3633 // .lcomm symbol: name,,n_sect,type,address
3634 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3636 break;
3637
3638 case N_BNSYM:
3639 // We use the current number of symbols in the symbol table in lieu
3640 // of using nlist_idx in case we ever start trimming entries out
3641 // Skip these if we want minimal symbol tables
3642 add_nlist = false;
3643 break;
3644
3645 case N_ENSYM:
3646 // Set the size of the N_BNSYM to the terminating index of this
3647 // N_ENSYM so that we can always skip the entire symbol if we need
3648 // to navigate more quickly at the source level when parsing STABS
3649 // Skip these if we want minimal symbol tables
3650 add_nlist = false;
3651 break;
3652
3653 case N_OPT:
3654 // emitted with gcc2_compiled and in gcc source
3655 type = eSymbolTypeCompiler;
3656 break;
3657
3658 case N_RSYM:
3659 // register sym: name,,NO_SECT,type,register
3660 type = eSymbolTypeVariable;
3661 break;
3662
3663 case N_SLINE:
3664 // src line: 0,,n_sect,linenumber,address
3665 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3666 type = eSymbolTypeLineEntry;
3667 break;
3668
3669 case N_SSYM:
3670 // structure elt: name,,NO_SECT,type,struct_offset
3672 break;
3673
3674 case N_SO:
3675 // source file name
3676 type = eSymbolTypeSourceFile;
3677 if (symbol_name == nullptr) {
3678 add_nlist = false;
3679 if (N_SO_index != UINT32_MAX) {
3680 // Set the size of the N_SO to the terminating index of this
3681 // N_SO so that we can always skip the entire N_SO if we need
3682 // to navigate more quickly at the source level when parsing
3683 // STABS
3684 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
3685 symbol_ptr->SetByteSize(sym_idx);
3686 symbol_ptr->SetSizeIsSibling(true);
3687 }
3688 N_NSYM_indexes.clear();
3689 N_INCL_indexes.clear();
3690 N_BRAC_indexes.clear();
3691 N_COMM_indexes.clear();
3692 N_FUN_indexes.clear();
3693 N_SO_index = UINT32_MAX;
3694 } else {
3695 // We use the current number of symbols in the symbol table in
3696 // lieu of using nlist_idx in case we ever start trimming entries
3697 // out
3698 const bool N_SO_has_full_path = symbol_name[0] == '/';
3699 if (N_SO_has_full_path) {
3700 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3701 // We have two consecutive N_SO entries where the first
3702 // contains a directory and the second contains a full path.
3703 sym[sym_idx - 1].GetMangled().SetValue(
3704 ConstString(symbol_name));
3705 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3706 add_nlist = false;
3707 } else {
3708 // This is the first entry in a N_SO that contains a
3709 // directory or a full path to the source file
3710 N_SO_index = sym_idx;
3711 }
3712 } else if ((N_SO_index == sym_idx - 1) &&
3713 ((sym_idx - 1) < num_syms)) {
3714 // This is usually the second N_SO entry that contains just the
3715 // filename, so here we combine it with the first one if we are
3716 // minimizing the symbol table
3717 llvm::StringRef so_path = sym[sym_idx - 1]
3718 .GetMangled()
3719 .GetDemangledName()
3720 .GetStringRef();
3721 if (!so_path.empty()) {
3722 std::string full_so_path(so_path);
3723 const size_t double_slash_pos = full_so_path.find("//");
3724 if (double_slash_pos != std::string::npos) {
3725 // The linker has been generating bad N_SO entries with
3726 // doubled up paths in the format "%s%s" where the first
3727 // string in the DW_AT_comp_dir, and the second is the
3728 // directory for the source file so you end up with a path
3729 // that looks like "/tmp/src//tmp/src/"
3730 FileSpec so_dir(so_path);
3731 if (!FileSystem::Instance().Exists(so_dir)) {
3732 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
3733 FileSpec::Style::native);
3734 if (FileSystem::Instance().Exists(so_dir)) {
3735 // Trim off the incorrect path
3736 full_so_path.erase(0, double_slash_pos + 1);
3737 }
3738 }
3739 }
3740 if (*full_so_path.rbegin() != '/')
3741 full_so_path += '/';
3742 full_so_path += symbol_name;
3743 sym[sym_idx - 1].GetMangled().SetValue(
3744 ConstString(full_so_path.c_str()));
3745 add_nlist = false;
3746 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3747 }
3748 } else {
3749 // This could be a relative path to a N_SO
3750 N_SO_index = sym_idx;
3751 }
3752 }
3753 break;
3754
3755 case N_OSO:
3756 // object file name: name,,0,0,st_mtime
3757 type = eSymbolTypeObjectFile;
3758 break;
3759
3760 case N_LSYM:
3761 // local sym: name,,NO_SECT,type,offset
3762 type = eSymbolTypeLocal;
3763 break;
3764
3765 // INCL scopes
3766 case N_BINCL:
3767 // include file beginning: name,,NO_SECT,0,sum We use the current
3768 // number of symbols in the symbol table in lieu of using nlist_idx
3769 // in case we ever start trimming entries out
3770 N_INCL_indexes.push_back(sym_idx);
3771 type = eSymbolTypeScopeBegin;
3772 break;
3773
3774 case N_EINCL:
3775 // include file end: name,,NO_SECT,0,0
3776 // Set the size of the N_BINCL to the terminating index of this
3777 // N_EINCL so that we can always skip the entire symbol if we need
3778 // to navigate more quickly at the source level when parsing STABS
3779 if (!N_INCL_indexes.empty()) {
3780 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
3781 symbol_ptr->SetByteSize(sym_idx + 1);
3782 symbol_ptr->SetSizeIsSibling(true);
3783 N_INCL_indexes.pop_back();
3784 }
3785 type = eSymbolTypeScopeEnd;
3786 break;
3787
3788 case N_SOL:
3789 // #included file name: name,,n_sect,0,address
3790 type = eSymbolTypeHeaderFile;
3791
3792 // We currently don't use the header files on darwin
3793 add_nlist = false;
3794 break;
3795
3796 case N_PARAMS:
3797 // compiler parameters: name,,NO_SECT,0,0
3798 type = eSymbolTypeCompiler;
3799 break;
3800
3801 case N_VERSION:
3802 // compiler version: name,,NO_SECT,0,0
3803 type = eSymbolTypeCompiler;
3804 break;
3805
3806 case N_OLEVEL:
3807 // compiler -O level: name,,NO_SECT,0,0
3808 type = eSymbolTypeCompiler;
3809 break;
3810
3811 case N_PSYM:
3812 // parameter: name,,NO_SECT,type,offset
3813 type = eSymbolTypeVariable;
3814 break;
3815
3816 case N_ENTRY:
3817 // alternate entry: name,,n_sect,linenumber,address
3818 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3819 type = eSymbolTypeLineEntry;
3820 break;
3821
3822 // Left and Right Braces
3823 case N_LBRAC:
3824 // left bracket: 0,,NO_SECT,nesting level,address We use the
3825 // current number of symbols in the symbol table in lieu of using
3826 // nlist_idx in case we ever start trimming entries out
3827 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3828 N_BRAC_indexes.push_back(sym_idx);
3829 type = eSymbolTypeScopeBegin;
3830 break;
3831
3832 case N_RBRAC:
3833 // right bracket: 0,,NO_SECT,nesting level,address Set the size of
3834 // the N_LBRAC to the terminating index of this N_RBRAC so that we
3835 // can always skip the entire symbol if we need to navigate more
3836 // quickly at the source level when parsing STABS
3837 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3838 if (!N_BRAC_indexes.empty()) {
3839 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
3840 symbol_ptr->SetByteSize(sym_idx + 1);
3841 symbol_ptr->SetSizeIsSibling(true);
3842 N_BRAC_indexes.pop_back();
3843 }
3844 type = eSymbolTypeScopeEnd;
3845 break;
3846
3847 case N_EXCL:
3848 // deleted include file: name,,NO_SECT,0,sum
3849 type = eSymbolTypeHeaderFile;
3850 break;
3851
3852 // COMM scopes
3853 case N_BCOMM:
3854 // begin common: name,,NO_SECT,0,0
3855 // We use the current number of symbols in the symbol table in lieu
3856 // of using nlist_idx in case we ever start trimming entries out
3857 type = eSymbolTypeScopeBegin;
3858 N_COMM_indexes.push_back(sym_idx);
3859 break;
3860
3861 case N_ECOML:
3862 // end common (local name): 0,,n_sect,0,address
3863 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3864 [[fallthrough]];
3865
3866 case N_ECOMM:
3867 // end common: name,,n_sect,0,0
3868 // Set the size of the N_BCOMM to the terminating index of this
3869 // N_ECOMM/N_ECOML so that we can always skip the entire symbol if
3870 // we need to navigate more quickly at the source level when
3871 // parsing STABS
3872 if (!N_COMM_indexes.empty()) {
3873 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
3874 symbol_ptr->SetByteSize(sym_idx + 1);
3875 symbol_ptr->SetSizeIsSibling(true);
3876 N_COMM_indexes.pop_back();
3877 }
3878 type = eSymbolTypeScopeEnd;
3879 break;
3880
3881 case N_LENG:
3882 // second stab entry with length information
3883 type = eSymbolTypeAdditional;
3884 break;
3885
3886 default:
3887 break;
3888 }
3889 } else {
3890 uint8_t n_type = N_TYPE & nlist.n_type;
3891 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3892
3893 switch (n_type) {
3894 case N_INDR: {
3895 std::optional<llvm::StringRef> reexport_name_str =
3896 strtab_data.PeekCStr(nlist.n_value);
3897 if (reexport_name_str && !reexport_name_str->empty() && symbol_name) {
3898 type = eSymbolTypeReExported;
3899 ConstString reexport_name(reexport_name_str->drop_front(
3900 reexport_name_str->front() == '_' ? 1 : 0));
3901 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3902 set_value = false;
3903 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3904 indirect_symbol_names.insert(
3905 ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
3906 } else
3907 type = eSymbolTypeUndefined;
3908 } break;
3909
3910 case N_UNDF:
3911 if (symbol_name && symbol_name[0]) {
3912 ConstString undefined_name(symbol_name +
3913 ((symbol_name[0] == '_') ? 1 : 0));
3914 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3915 }
3916 [[fallthrough]];
3917
3918 case N_PBUD:
3919 type = eSymbolTypeUndefined;
3920 break;
3921
3922 case N_ABS:
3923 type = eSymbolTypeAbsolute;
3924 break;
3925
3926 case N_SECT: {
3927 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3928
3929 if (!symbol_section) {
3930 // TODO: warn about this?
3931 add_nlist = false;
3932 break;
3933 }
3934
3935 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3936 type = eSymbolTypeException;
3937 } else {
3938 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3939
3940 switch (section_type) {
3941 case S_CSTRING_LITERALS:
3942 type = eSymbolTypeData;
3943 break; // section with only literal C strings
3944 case S_4BYTE_LITERALS:
3945 type = eSymbolTypeData;
3946 break; // section with only 4 byte literals
3947 case S_8BYTE_LITERALS:
3948 type = eSymbolTypeData;
3949 break; // section with only 8 byte literals
3950 case S_LITERAL_POINTERS:
3951 type = eSymbolTypeTrampoline;
3952 break; // section with only pointers to literals
3953 case S_NON_LAZY_SYMBOL_POINTERS:
3954 type = eSymbolTypeTrampoline;
3955 break; // section with only non-lazy symbol pointers
3956 case S_LAZY_SYMBOL_POINTERS:
3957 type = eSymbolTypeTrampoline;
3958 break; // section with only lazy symbol pointers
3959 case S_SYMBOL_STUBS:
3960 type = eSymbolTypeTrampoline;
3961 break; // section with only symbol stubs, byte size of stub in
3962 // the reserved2 field
3963 case S_MOD_INIT_FUNC_POINTERS:
3964 type = eSymbolTypeCode;
3965 break; // section with only function pointers for initialization
3966 case S_MOD_TERM_FUNC_POINTERS:
3967 type = eSymbolTypeCode;
3968 break; // section with only function pointers for termination
3969 case S_INTERPOSING:
3970 type = eSymbolTypeTrampoline;
3971 break; // section with only pairs of function pointers for
3972 // interposing
3973 case S_16BYTE_LITERALS:
3974 type = eSymbolTypeData;
3975 break; // section with only 16 byte literals
3976 case S_DTRACE_DOF:
3978 break;
3979 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3980 type = eSymbolTypeTrampoline;
3981 break;
3982 default:
3983 switch (symbol_section->GetType()) {
3985 type = eSymbolTypeCode;
3986 break;
3987 case eSectionTypeData:
3988 case eSectionTypeDataCString: // Inlined C string data
3989 case eSectionTypeDataCStringPointers: // Pointers to C string
3990 // data
3991 case eSectionTypeDataSymbolAddress: // Address of a symbol in
3992 // the symbol table
3993 case eSectionTypeData4:
3994 case eSectionTypeData8:
3995 case eSectionTypeData16:
3996 type = eSymbolTypeData;
3997 break;
3998 default:
3999 break;
4000 }
4001 break;
4002 }
4003
4004 if (type == eSymbolTypeInvalid) {
4005 llvm::StringRef symbol_sect_name = symbol_section->GetName();
4006 if (symbol_section->IsDescendant(text_section_sp.get())) {
4007 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4008 S_ATTR_SELF_MODIFYING_CODE |
4009 S_ATTR_SOME_INSTRUCTIONS))
4010 type = eSymbolTypeData;
4011 else
4012 type = eSymbolTypeCode;
4013 } else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4014 symbol_section->IsDescendant(
4015 data_dirty_section_sp.get()) ||
4016 symbol_section->IsDescendant(
4017 data_const_section_sp.get())) {
4018 if (symbol_sect_name.starts_with("__objc")) {
4019 type = eSymbolTypeRuntime;
4020
4022 symbol_name, symbol_name_non_abi_mangled, type))
4023 demangled_is_synthesized = true;
4024 } else if (symbol_sect_name.starts_with("__gcc_except_tab")) {
4025 type = eSymbolTypeException;
4026 } else {
4027 type = eSymbolTypeData;
4028 }
4029 } else if (symbol_sect_name.starts_with("__IMPORT")) {
4030 type = eSymbolTypeTrampoline;
4031 } else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4032 type = eSymbolTypeRuntime;
4033 if (symbol_name && symbol_name[0] == '.') {
4034 llvm::StringRef symbol_name_ref(symbol_name);
4035 llvm::StringRef g_objc_v1_prefix_class(
4036 ".objc_class_name_");
4037 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4038 symbol_name_non_abi_mangled = symbol_name;
4039 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4040 type = eSymbolTypeObjCClass;
4041 demangled_is_synthesized = true;
4042 }
4043 }
4044 }
4045 }
4046 }
4047 } break;
4048 }
4049 }
4050
4051 if (!add_nlist) {
4052 sym[sym_idx].Clear();
4053 return true;
4054 }
4055
4056 uint64_t symbol_value = nlist.n_value;
4057
4058 if (symbol_name_non_abi_mangled) {
4059 sym[sym_idx].GetMangled().SetMangledName(
4060 ConstString(symbol_name_non_abi_mangled));
4061 sym[sym_idx].GetMangled().SetDemangledName(ConstString(symbol_name));
4062 } else {
4063
4064 if (symbol_name && symbol_name[0] == '_') {
4065 symbol_name++; // Skip the leading underscore
4066 }
4067
4068 if (symbol_name) {
4069 ConstString const_symbol_name(symbol_name);
4070 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
4071 }
4072 }
4073
4074 if (is_gsym) {
4075 const char *gsym_name = sym[sym_idx]
4076 .GetMangled()
4077 .GetName(Mangled::ePreferMangled)
4078 .GetCString();
4079 if (gsym_name)
4080 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4081 }
4082
4083 if (symbol_section) {
4084 const addr_t section_file_addr = symbol_section->GetFileAddress();
4085 symbol_value -= section_file_addr;
4086 }
4087
4088 if (!is_debug) {
4089 if (type == eSymbolTypeCode) {
4090 // See if we can find a N_FUN entry for any code symbols. If we do
4091 // find a match, and the name matches, then we can merge the two into
4092 // just the function symbol to avoid duplicate entries in the symbol
4093 // table.
4094 std::pair<ValueToSymbolIndexMap::const_iterator,
4095 ValueToSymbolIndexMap::const_iterator>
4096 range;
4097 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4098 if (range.first != range.second) {
4099 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4100 pos != range.second; ++pos) {
4101 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==
4102 sym[pos->second].GetMangled().GetName(
4104 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4105 // We just need the flags from the linker symbol, so put these
4106 // flags into the N_FUN flags to avoid duplicate symbols in the
4107 // symbol table.
4108 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4109 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4110 if (resolver_addresses.find(nlist.n_value) !=
4111 resolver_addresses.end())
4112 sym[pos->second].SetType(eSymbolTypeResolver);
4113 sym[sym_idx].Clear();
4114 return true;
4115 }
4116 }
4117 } else {
4118 if (resolver_addresses.find(nlist.n_value) !=
4119 resolver_addresses.end())
4120 type = eSymbolTypeResolver;
4121 }
4122 } else if (type == eSymbolTypeData || type == eSymbolTypeObjCClass ||
4123 type == eSymbolTypeObjCMetaClass ||
4124 type == eSymbolTypeObjCIVar) {
4125 // See if we can find a N_STSYM entry for any data symbols. If we do
4126 // find a match, and the name matches, then we can merge the two into
4127 // just the Static symbol to avoid duplicate entries in the symbol
4128 // table.
4129 std::pair<ValueToSymbolIndexMap::const_iterator,
4130 ValueToSymbolIndexMap::const_iterator>
4131 range;
4132 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4133 if (range.first != range.second) {
4134 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4135 pos != range.second; ++pos) {
4136 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==
4137 sym[pos->second].GetMangled().GetName(
4139 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4140 // We just need the flags from the linker symbol, so put these
4141 // flags into the N_STSYM flags to avoid duplicate symbols in
4142 // the symbol table.
4143 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4144 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4145 sym[sym_idx].Clear();
4146 return true;
4147 }
4148 }
4149 } else {
4150 // Combine N_GSYM stab entries with the non stab symbol.
4151 const char *gsym_name = sym[sym_idx]
4152 .GetMangled()
4153 .GetName(Mangled::ePreferMangled)
4154 .GetCString();
4155 if (gsym_name) {
4156 ConstNameToSymbolIndexMap::const_iterator pos =
4157 N_GSYM_name_to_sym_idx.find(gsym_name);
4158 if (pos != N_GSYM_name_to_sym_idx.end()) {
4159 const uint32_t GSYM_sym_idx = pos->second;
4160 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4161 // Copy the address, because often the N_GSYM address has an
4162 // invalid address of zero when the global is a common symbol.
4163 sym[GSYM_sym_idx].GetAddressRef() =
4164 Address(symbol_section, symbol_value);
4165 add_symbol_addr(
4166 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4167 // We just need the flags from the linker symbol, so put these
4168 // flags into the N_GSYM flags to avoid duplicate symbols in
4169 // the symbol table.
4170 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4171 sym[sym_idx].Clear();
4172 return true;
4173 }
4174 }
4175 }
4176 }
4177 }
4178
4179 sym[sym_idx].SetID(nlist_idx);
4180 sym[sym_idx].SetType(type);
4181 if (set_value) {
4182 sym[sym_idx].GetAddressRef() = Address(symbol_section, symbol_value);
4183 if (symbol_section)
4184 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4185 }
4186 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4187 if (nlist.n_desc & N_WEAK_REF)
4188 sym[sym_idx].SetIsWeak(true);
4189
4190 if (demangled_is_synthesized)
4191 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4192
4193 ++sym_idx;
4194 return true;
4195 };
4196
4197 // First parse all the nlists but don't process them yet. See the next
4198 // comment for an explanation why.
4199 std::vector<struct nlist_64> nlists;
4200 nlists.reserve(std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms));
4201 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4202 if (auto nlist =
4203 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4204 nlists.push_back(*nlist);
4205 else
4206 break;
4207 }
4208
4209 // Now parse all the debug symbols. This is needed to merge non-debug
4210 // symbols in the next step. Non-debug symbols are always coalesced into
4211 // the debug symbol. Doing this in one step would mean that some symbols
4212 // won't be merged.
4213 nlist_idx = 0;
4214 for (auto &nlist : nlists) {
4215 if (!ParseSymbolLambda(nlist, nlist_idx++, DebugSymbols))
4216 break;
4217 }
4218
4219 // Finally parse all the non debug symbols.
4220 nlist_idx = 0;
4221 for (auto &nlist : nlists) {
4222 if (!ParseSymbolLambda(nlist, nlist_idx++, NonDebugSymbols))
4223 break;
4224 }
4225
4226 for (const auto &pos : reexport_shlib_needs_fixup) {
4227 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4228 if (undef_pos != undefined_name_to_desc.end()) {
4229 const uint8_t dylib_ordinal =
4230 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4231 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4232 sym[pos.first].SetReExportedSymbolSharedLibrary(
4233 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4234 }
4235 }
4236 }
4237
4238 // Count how many trie symbols we'll add to the symbol table
4239 int trie_symbol_table_augment_count = 0;
4240 for (auto &e : external_sym_trie_entries) {
4241 if (!symbols_added.contains(e.entry.address))
4242 trie_symbol_table_augment_count++;
4243 }
4244
4245 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4246 num_syms = sym_idx + trie_symbol_table_augment_count;
4247 sym = symtab.Resize(num_syms);
4248 }
4249 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4250
4251 // Add symbols from the trie to the symbol table.
4252 for (auto &e : external_sym_trie_entries) {
4253 if (symbols_added.contains(e.entry.address))
4254 continue;
4255
4256 // Find the section that this trie address is in, use that to annotate
4257 // symbol type as we add the trie address and name to the symbol table.
4258 Address symbol_addr;
4259 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4260 SectionSP symbol_section(symbol_addr.GetSection());
4261 const char *symbol_name = e.entry.name.GetCString();
4262 bool demangled_is_synthesized = false;
4263 SymbolType type =
4264 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4265 data_section_sp, data_dirty_section_sp,
4266 data_const_section_sp, symbol_section);
4267
4268 sym[sym_idx].SetType(type);
4269 if (symbol_section) {
4270 sym[sym_idx].SetID(synthetic_sym_id++);
4271 sym[sym_idx].GetMangled().SetMangledName(ConstString(symbol_name));
4272 if (demangled_is_synthesized)
4273 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4274 sym[sym_idx].SetIsSynthetic(true);
4275 sym[sym_idx].SetExternal(true);
4276 sym[sym_idx].GetAddressRef() = symbol_addr;
4277 add_symbol_addr(symbol_addr.GetFileAddress());
4278 if (e.entry.flags & TRIE_SYMBOL_IS_THUMB)
4279 sym[sym_idx].SetFlags(MACHO_NLIST_ARM_SYMBOL_IS_THUMB);
4280 ++sym_idx;
4281 }
4282 }
4283 }
4284
4285 if (function_starts_count > 0) {
4286 uint32_t num_synthetic_function_symbols = 0;
4287 for (i = 0; i < function_starts_count; ++i) {
4288 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4289 ++num_synthetic_function_symbols;
4290 }
4291
4292 if (num_synthetic_function_symbols > 0) {
4293 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4294 num_syms = sym_idx + num_synthetic_function_symbols;
4295 sym = symtab.Resize(num_syms);
4296 }
4297 for (i = 0; i < function_starts_count; ++i) {
4298 const FunctionStarts::Entry *func_start_entry =
4299 function_starts.GetEntryAtIndex(i);
4300 if (!symbols_added.contains(func_start_entry->addr)) {
4301 addr_t symbol_file_addr = func_start_entry->addr;
4302 uint32_t symbol_flags = 0;
4303 if (func_start_entry->data)
4304 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
4305 Address symbol_addr;
4306 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4307 SectionSP symbol_section(symbol_addr.GetSection());
4308 if (symbol_section) {
4309 sym[sym_idx].SetID(synthetic_sym_id++);
4310 // Don't set the name for any synthetic symbols, the Symbol
4311 // object will generate one if needed when the name is accessed
4312 // via accessors.
4313 sym[sym_idx].GetMangled().SetDemangledName(ConstString());
4314 sym[sym_idx].SetType(eSymbolTypeCode);
4315 sym[sym_idx].SetIsSynthetic(true);
4316 sym[sym_idx].GetAddressRef() = symbol_addr;
4317 add_symbol_addr(symbol_addr.GetFileAddress());
4318 if (symbol_flags)
4319 sym[sym_idx].SetFlags(symbol_flags);
4320 ++sym_idx;
4321 }
4322 }
4323 }
4324 }
4325 }
4326 }
4327
4328 // Trim our symbols down to just what we ended up with after removing any
4329 // symbols.
4330 if (sym_idx < num_syms) {
4331 num_syms = sym_idx;
4332 sym = symtab.Resize(num_syms);
4333 }
4334
4335 // Now synthesize indirect symbols
4336 if (m_dysymtab.nindirectsyms != 0) {
4337 if (indirect_symbol_index_data.GetByteSize()) {
4338 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4339 m_nlist_idx_to_sym_idx.end();
4340
4341 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4342 ++sect_idx) {
4343 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4344 S_SYMBOL_STUBS) {
4345 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4346 if (symbol_stub_byte_size == 0)
4347 continue;
4348
4349 const uint32_t num_symbol_stubs =
4350 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4351
4352 if (num_symbol_stubs == 0)
4353 continue;
4354
4355 const uint32_t symbol_stub_index_offset =
4356 m_mach_sections[sect_idx].reserved1;
4357 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4358 const uint32_t symbol_stub_index =
4359 symbol_stub_index_offset + stub_idx;
4360 const lldb::addr_t symbol_stub_addr =
4361 m_mach_sections[sect_idx].addr +
4362 (stub_idx * symbol_stub_byte_size);
4363 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
4364 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4365 symbol_stub_offset, 4)) {
4366 const uint32_t stub_sym_id =
4367 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4368 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4369 continue;
4370
4371 NListIndexToSymbolIndexMap::const_iterator index_pos =
4372 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4373 Symbol *stub_symbol = nullptr;
4374 if (index_pos != end_index_pos) {
4375 // We have a remapping from the original nlist index to a
4376 // current symbol index, so just look this up by index
4377 stub_symbol = symtab.SymbolAtIndex(index_pos->second);
4378 } else {
4379 // We need to lookup a symbol using the original nlist symbol
4380 // index since this index is coming from the S_SYMBOL_STUBS
4381 stub_symbol = symtab.FindSymbolByID(stub_sym_id);
4382 }
4383
4384 if (stub_symbol) {
4385 Address so_addr(symbol_stub_addr, section_list);
4386
4387 if (stub_symbol->GetType() == eSymbolTypeUndefined) {
4388 // Change the external symbol into a trampoline that makes
4389 // sense These symbols were N_UNDF N_EXT, and are useless
4390 // to us, so we can re-use them so we don't have to make up
4391 // a synthetic symbol for no good reason.
4392 if (resolver_addresses.find(symbol_stub_addr) ==
4393 resolver_addresses.end())
4394 stub_symbol->SetType(eSymbolTypeTrampoline);
4395 else
4396 stub_symbol->SetType(eSymbolTypeResolver);
4397 stub_symbol->SetExternal(false);
4398 stub_symbol->GetAddressRef() = so_addr;
4399 stub_symbol->SetByteSize(symbol_stub_byte_size);
4400 } else {
4401 // Make a synthetic symbol to describe the trampoline stub
4402 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
4403 if (sym_idx >= num_syms) {
4404 sym = symtab.Resize(++num_syms);
4405 stub_symbol = nullptr; // this pointer no longer valid
4406 }
4407 sym[sym_idx].SetID(synthetic_sym_id++);
4408 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4409 if (resolver_addresses.find(symbol_stub_addr) ==
4410 resolver_addresses.end())
4411 sym[sym_idx].SetType(eSymbolTypeTrampoline);
4412 else
4413 sym[sym_idx].SetType(eSymbolTypeResolver);
4414 sym[sym_idx].SetIsSynthetic(true);
4415 sym[sym_idx].GetAddressRef() = so_addr;
4416 add_symbol_addr(so_addr.GetFileAddress());
4417 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4418 ++sym_idx;
4419 }
4420 } else {
4421 LLDB_LOGF(log,
4422 "warning: symbol stub referencing symbol table "
4423 "symbol %u that isn't in our minimal symbol table, "
4424 "fix this!!!",
4425 stub_sym_id);
4426 }
4427 }
4428 }
4429 }
4430 }
4431 }
4432 }
4433
4434 if (!reexport_trie_entries.empty()) {
4435 for (const auto &e : reexport_trie_entries) {
4436 if (e.entry.import_name) {
4437 // Only add indirect symbols from the Trie entries if we didn't have
4438 // a N_INDR nlist entry for this already
4439 if (indirect_symbol_names.find(e.entry.name) ==
4440 indirect_symbol_names.end()) {
4441 // Make a synthetic symbol to describe re-exported symbol.
4442 if (sym_idx >= num_syms)
4443 sym = symtab.Resize(++num_syms);
4444 sym[sym_idx].SetID(synthetic_sym_id++);
4445 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4446 sym[sym_idx].SetType(eSymbolTypeReExported);
4447 sym[sym_idx].SetIsSynthetic(true);
4448 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4449 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4450 sym[sym_idx].SetReExportedSymbolSharedLibrary(
4451 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
4452 }
4453 ++sym_idx;
4454 }
4455 }
4456 }
4457 }
4458}
4459
4461 ModuleSP module_sp(GetModule());
4462 if (module_sp) {
4463 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4464 s->Printf("%p: ", static_cast<void *>(this));
4465 s->Indent();
4466 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
4467 s->PutCString("ObjectFileMachO64");
4468 else
4469 s->PutCString("ObjectFileMachO32");
4470
4471 *s << ", file = '" << m_file;
4472 ModuleSpecList all_specs;
4473 ModuleSpec base_spec;
4475 MachHeaderSizeFromMagic(m_header.magic), base_spec,
4476 all_specs);
4477 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
4478 *s << "', triple";
4479 if (e)
4480 s->Printf("[%d]", i);
4481 *s << " = ";
4482 *s << all_specs.GetModuleSpecRefAtIndex(i)
4484 .GetTriple()
4485 .getTriple();
4486 }
4487 *s << "\n";
4488 SectionList *sections = GetSectionList();
4489 if (sections)
4490 sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
4491 UINT32_MAX);
4492
4493 if (m_symtab_up)
4494 m_symtab_up->Dump(s, nullptr, eSortOrderNone);
4495 }
4496}
4497
4498UUID ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
4499 const lldb_private::DataExtractor &data,
4500 lldb::offset_t lc_offset) {
4501 uint32_t i;
4502 llvm::MachO::uuid_command load_cmd;
4503
4504 lldb::offset_t offset = lc_offset;
4505 for (i = 0; i < header.ncmds; ++i) {
4506 const lldb::offset_t cmd_offset = offset;
4507 if (!ReadMachOCommand(data, offset, load_cmd))
4508 break;
4509
4510 if (load_cmd.cmd == LC_UUID) {
4511 const uint8_t *uuid_bytes = data.PeekData(offset, 16);
4512
4513 if (uuid_bytes) {
4514 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4515 // We pretend these object files have no UUID to prevent crashing.
4516
4517 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4518 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4519 0xbb, 0x14, 0xf0, 0x0d};
4520
4521 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4522 return UUID();
4523
4524 return UUID(uuid_bytes, 16);
4525 }
4526 return UUID();
4527 }
4528 offset = cmd_offset + load_cmd.cmdsize;
4529 }
4530 return UUID();
4531}
4532
4533static llvm::StringRef GetOSName(uint32_t cmd) {
4534 switch (cmd) {
4535 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4536 return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4537 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4538 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4539 case llvm::MachO::LC_VERSION_MIN_TVOS:
4540 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4541 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4542 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4543 default:
4544 llvm_unreachable("unexpected LC_VERSION load command");
4545 }
4546}
4547
4548namespace {
4549struct OSEnv {
4550 llvm::StringRef os_type;
4551 llvm::StringRef environment;
4552 OSEnv(uint32_t cmd) {
4553 switch (cmd) {
4554 case llvm::MachO::PLATFORM_MACOS:
4555 os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4556 return;
4557 case llvm::MachO::PLATFORM_IOS:
4558 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4559 return;
4560 case llvm::MachO::PLATFORM_TVOS:
4561 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4562 return;
4563 case llvm::MachO::PLATFORM_WATCHOS:
4564 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4565 return;
4566 case llvm::MachO::PLATFORM_BRIDGEOS:
4567 os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
4568 return;
4569 case llvm::MachO::PLATFORM_DRIVERKIT:
4570 os_type = llvm::Triple::getOSTypeName(llvm::Triple::DriverKit);
4571 return;
4572 case llvm::MachO::PLATFORM_MACCATALYST:
4573 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4574 environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);
4575 return;
4576 case llvm::MachO::PLATFORM_IOSSIMULATOR:
4577 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4578 environment =
4579 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4580 return;
4581 case llvm::MachO::PLATFORM_TVOSSIMULATOR:
4582 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4583 environment =
4584 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4585 return;
4586 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:
4587 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4588 environment =
4589 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4590 return;
4591 case llvm::MachO::PLATFORM_XROS:
4592 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4593 return;
4594 case llvm::MachO::PLATFORM_XROS_SIMULATOR:
4595 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4596 environment =
4597 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4598 return;
4599 default: {
4600 Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));
4601 LLDB_LOGF(log, "unsupported platform in LC_BUILD_VERSION");
4602 }
4603 }
4604 }
4605};
4606
4607struct MinOS {
4608 uint32_t major_version, minor_version, patch_version;
4609 MinOS(uint32_t version)
4610 : major_version(version >> 16), minor_version((version >> 8) & 0xffu),
4611 patch_version(version & 0xffu) {}
4612};
4613} // namespace
4614
4615void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header &header,
4616 const lldb_private::DataExtractor &data,
4617 lldb::offset_t lc_offset,
4618 ModuleSpec &base_spec,
4619 lldb_private::ModuleSpecList &all_specs) {
4620 auto &base_arch = base_spec.GetArchitecture();
4621 base_arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype);
4622 if (!base_arch.IsValid())
4623 return;
4624
4625 bool found_any = false;
4626 auto add_triple = [&](const llvm::Triple &triple) {
4627 auto spec = base_spec;
4628 spec.GetArchitecture().GetTriple() = triple;
4629 if (spec.GetArchitecture().IsValid()) {
4630 spec.GetUUID() = ObjectFileMachO::GetUUID(header, data, lc_offset);
4631 all_specs.Append(spec);
4632 found_any = true;
4633 }
4634 };
4635
4636 // Set OS to an unspecified unknown or a "*" so it can match any OS
4637 llvm::Triple base_triple = base_arch.GetTriple();
4638 base_triple.setOS(llvm::Triple::UnknownOS);
4639 base_triple.setOSName(llvm::StringRef());
4640
4641 if (header.filetype == MH_PRELOAD) {
4642 if (header.cputype == CPU_TYPE_ARM) {
4643 // If this is a 32-bit arm binary, and it's a standalone binary, force
4644 // the Vendor to Apple so we don't accidentally pick up the generic
4645 // armv7 ABI at runtime. Apple's armv7 ABI always uses r7 for the
4646 // frame pointer register; most other armv7 ABIs use a combination of
4647 // r7 and r11.
4648 base_triple.setVendor(llvm::Triple::Apple);
4649 } else {
4650 // Set vendor to an unspecified unknown or a "*" so it can match any
4651 // vendor This is required for correct behavior of EFI debugging on
4652 // x86_64
4653 base_triple.setVendor(llvm::Triple::UnknownVendor);
4654 base_triple.setVendorName(llvm::StringRef());
4655 }
4656 return add_triple(base_triple);
4657 }
4658
4659 llvm::MachO::load_command load_cmd;
4660
4661 // See if there is an LC_VERSION_MIN_* load command that can give
4662 // us the OS type.
4663 lldb::offset_t offset = lc_offset;
4664 for (uint32_t i = 0; i < header.ncmds; ++i) {
4665 const lldb::offset_t cmd_offset = offset;
4666 if (!ReadMachOCommand(data, offset, load_cmd))
4667 break;
4668
4669 llvm::MachO::version_min_command version_min;
4670 switch (load_cmd.cmd) {
4671 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4672 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4673 case llvm::MachO::LC_VERSION_MIN_TVOS:
4674 case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
4675 if (load_cmd.cmdsize != sizeof(version_min))
4676 break;
4677 if (data.ExtractBytes(cmd_offset, sizeof(version_min),
4678 data.GetByteOrder(), &version_min) == 0)
4679 break;
4680 MinOS min_os(version_min.version);
4681 llvm::SmallString<32> os_name;
4682 llvm::raw_svector_ostream os(os_name);
4683 os << GetOSName(load_cmd.cmd) << min_os.major_version << '.'
4684 << min_os.minor_version << '.' << min_os.patch_version;
4685
4686 auto triple = base_triple;
4687 triple.setOSName(os.str());
4688
4689 // Disambiguate legacy simulator platforms.
4690 if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
4691 (base_triple.getArch() == llvm::Triple::x86_64 ||
4692 base_triple.getArch() == llvm::Triple::x86)) {
4693 // The combination of legacy LC_VERSION_MIN load command and
4694 // x86 architecture always indicates a simulator environment.
4695 // The combination of LC_VERSION_MIN and arm architecture only
4696 // appears for native binaries. Back-deploying simulator
4697 // binaries on Apple Silicon Macs use the modern unambigous
4698 // LC_BUILD_VERSION load commands; no special handling required.
4699 triple.setEnvironment(llvm::Triple::Simulator);
4700 }
4701 add_triple(triple);
4702 break;
4703 }
4704 default:
4705 break;
4706 }
4707
4708 offset = cmd_offset + load_cmd.cmdsize;
4709 }
4710
4711 // See if there are LC_BUILD_VERSION load commands that can give
4712 // us the OS type.
4713 offset = lc_offset;
4714 for (uint32_t i = 0; i < header.ncmds; ++i) {
4715 const lldb::offset_t cmd_offset = offset;
4716 if (!ReadMachOCommand(data, offset, load_cmd))
4717 break;
4718
4719 do {
4720 if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
4721 llvm::MachO::build_version_command build_version;
4722 if (load_cmd.cmdsize < sizeof(build_version)) {
4723 // Malformed load command.
4724 break;
4725 }
4726 if (data.ExtractBytes(cmd_offset, sizeof(build_version),
4727 data.GetByteOrder(), &build_version) == 0)
4728 break;
4729 MinOS min_os(build_version.minos);
4730 OSEnv os_env(build_version.platform);
4731 llvm::SmallString<16> os_name;
4732 llvm::raw_svector_ostream os(os_name);
4733 os << os_env.os_type << min_os.major_version << '.'
4734 << min_os.minor_version << '.' << min_os.patch_version;
4735 auto triple = base_triple;
4736 triple.setOSName(os.str());
4737 os_name.clear();
4738 if (!os_env.environment.empty())
4739 triple.setEnvironmentName(os_env.environment);
4740 add_triple(triple);
4741 }
4742 } while (false);
4743 offset = cmd_offset + load_cmd.cmdsize;
4744 }
4745
4746 if (!found_any) {
4747 add_triple(base_triple);
4748 }
4749}
4750
4752 ModuleSP module_sp, const llvm::MachO::mach_header &header,
4753 const lldb_private::DataExtractor &data, lldb::offset_t lc_offset) {
4754 ModuleSpecList all_specs;
4755 ModuleSpec base_spec;
4756 GetAllArchSpecs(header, data, MachHeaderSizeFromMagic(header.magic),
4757 base_spec, all_specs);
4758
4759 // If the object file offers multiple alternative load commands,
4760 // pick the one that matches the module.
4761 if (module_sp) {
4762 const ArchSpec &module_arch = module_sp->GetArchitecture();
4763 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
4764 ArchSpec mach_arch =
4766 if (module_arch.IsCompatibleMatch(mach_arch))
4767 return mach_arch;
4768 }
4769 }
4770
4771 // Return the first arch we found.
4772 if (all_specs.GetSize() == 0)
4773 return {};
4774 return all_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();
4775}
4776
4778 ModuleSP module_sp(GetModule());
4779 if (module_sp) {
4780 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4782 return GetUUID(m_header, *m_data_nsp, offset);
4783 }
4784 return UUID();
4785}
4786
4788 ModuleSP module_sp = GetModule();
4789 if (!module_sp)
4790 return 0;
4791
4792 uint32_t count = 0;
4793 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4794 llvm::MachO::load_command load_cmd;
4796 std::vector<std::string> rpath_paths;
4797 std::vector<std::string> rpath_relative_paths;
4798 std::vector<std::string> at_exec_relative_paths;
4799 uint32_t i;
4800 for (i = 0; i < m_header.ncmds; ++i) {
4801 const uint32_t cmd_offset = offset;
4802 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
4803 break;
4804
4805 switch (load_cmd.cmd) {
4806 case LC_RPATH:
4807 case LC_LOAD_DYLIB:
4808 case LC_LOAD_WEAK_DYLIB:
4809 case LC_REEXPORT_DYLIB:
4810 case LC_LOAD_DYLINKER:
4811 case LC_LOADFVMLIB:
4812 case LC_LOAD_UPWARD_DYLIB: {
4813 uint32_t name_offset = cmd_offset + m_data_nsp->GetU32(&offset);
4814 // For LC_LOAD_DYLIB there is an alternate encoding
4815 // which adds a uint32_t `flags` field for `DYLD_USE_*`
4816 // flags. This can be detected by a timestamp field with
4817 // the `DYLIB_USE_MARKER` constant value.
4818 bool is_delayed_init = false;
4819 uint32_t use_command_marker = m_data_nsp->GetU32(&offset);
4820 if (use_command_marker == 0x1a741800 /* DYLIB_USE_MARKER */) {
4821 offset += 4; /* uint32_t current_version */
4822 offset += 4; /* uint32_t compat_version */
4823 uint32_t flags = m_data_nsp->GetU32(&offset);
4824 // If this LC_LOAD_DYLIB is marked delay-init,
4825 // don't report it as a dependent library -- it
4826 // may be loaded in the process at some point,
4827 // but will most likely not be load at launch.
4828 if (flags & 0x08 /* DYLIB_USE_DELAYED_INIT */)
4829 is_delayed_init = true;
4830 }
4831 std::optional<llvm::StringRef> maybe_path =
4832 m_data_nsp->PeekCStr(name_offset);
4833 if (maybe_path && !is_delayed_init) {
4834 llvm::StringRef path = *maybe_path;
4835 if (load_cmd.cmd == LC_RPATH)
4836 rpath_paths.push_back(path.str());
4837 else if (path.consume_front("@rpath"))
4838 rpath_relative_paths.push_back(path.str());
4839 else if (path.consume_front("@executable_path"))
4840 at_exec_relative_paths.push_back(path.str());
4841 else if (!path.starts_with("@")) {
4842 FileSpec file_spec(path);
4843 if (files.AppendIfUnique(file_spec))
4844 count++;
4845 }
4846 }
4847 } break;
4848
4849 default:
4850 break;
4851 }
4852 offset = cmd_offset + load_cmd.cmdsize;
4853 }
4854
4855 FileSpec this_file_spec(m_file);
4856 FileSystem::Instance().Resolve(this_file_spec);
4857
4858 if (!rpath_paths.empty()) {
4859 // Fixup all LC_RPATH values to be absolute paths.
4860 const std::string this_directory = this_file_spec.GetDirectory().str();
4861 for (auto &rpath : rpath_paths) {
4862 if (llvm::StringRef(rpath).starts_with(g_loader_path))
4863 rpath = this_directory + rpath.substr(g_loader_path.size());
4864 else if (llvm::StringRef(rpath).starts_with(g_executable_path))
4865 rpath = this_directory + rpath.substr(g_executable_path.size());
4866 }
4867
4868 for (const auto &rpath_relative_path : rpath_relative_paths) {
4869 for (const auto &rpath : rpath_paths) {
4870 std::string path = rpath;
4871 path += rpath_relative_path;
4872 // It is OK to resolve this path because we must find a file on disk
4873 // for us to accept it anyway if it is rpath relative.
4874 FileSpec file_spec(path);
4875 FileSystem::Instance().Resolve(file_spec);
4876 if (FileSystem::Instance().Exists(file_spec) &&
4877 files.AppendIfUnique(file_spec)) {
4878 count++;
4879 break;
4880 }
4881 }
4882 }
4883 }
4884
4885 // We may have @executable_paths but no RPATHS. Figure those out here.
4886 // Only do this if this object file is the executable. We have no way to
4887 // get back to the actual executable otherwise, so we won't get the right
4888 // path.
4889 if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) {
4890 FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent();
4891 for (const auto &at_exec_relative_path : at_exec_relative_paths) {
4892 FileSpec file_spec =
4893 exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
4894 if (FileSystem::Instance().Exists(file_spec) &&
4895 files.AppendIfUnique(file_spec))
4896 count++;
4897 }
4898 }
4899 return count;
4900}
4901
4903 // If the object file is not an executable it can't hold the entry point.
4904 // m_entry_point_address is initialized to an invalid address, so we can just
4905 // return that. If m_entry_point_address is valid it means we've found it
4906 // already, so return the cached value.
4907
4908 if ((!IsExecutable() && !IsDynamicLoader()) ||
4909 m_entry_point_address.IsValid()) {
4910 return m_entry_point_address;
4911 }
4912
4913 // Otherwise, look for the UnixThread or Thread command. The data for the
4914 // Thread command is given in /usr/include/mach-o.h, but it is basically:
4915 //
4916 // uint32_t flavor - this is the flavor argument you would pass to
4917 // thread_get_state
4918 // uint32_t count - this is the count of longs in the thread state data
4919 // struct XXX_thread_state state - this is the structure from
4920 // <machine/thread_status.h> corresponding to the flavor.
4921 // <repeat this trio>
4922 //
4923 // So we just keep reading the various register flavors till we find the GPR
4924 // one, then read the PC out of there.
4925 // FIXME: We will need to have a "RegisterContext data provider" class at some
4926 // point that can get all the registers
4927 // out of data in this form & attach them to a given thread. That should
4928 // underlie the MacOS X User process plugin, and we'll also need it for the
4929 // MacOS X Core File process plugin. When we have that we can also use it
4930 // here.
4931 //
4932 // For now we hard-code the offsets and flavors we need:
4933 //
4934 //
4935
4936 ModuleSP module_sp(GetModule());
4937 if (module_sp) {
4938 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4939 llvm::MachO::load_command load_cmd;
4941 uint32_t i;
4942 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
4943 bool done = false;
4944
4945 for (i = 0; i < m_header.ncmds; ++i) {
4946 const lldb::offset_t cmd_offset = offset;
4947 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
4948 break;
4949
4950 switch (load_cmd.cmd) {
4951 case LC_UNIXTHREAD:
4952 case LC_THREAD: {
4953 while (offset < cmd_offset + load_cmd.cmdsize) {
4954 uint32_t flavor = m_data_nsp->GetU32(&offset);
4955 uint32_t count = m_data_nsp->GetU32(&offset);
4956 if (count == 0) {
4957 // We've gotten off somehow, log and exit;
4958 return m_entry_point_address;
4959 }
4960
4961 switch (m_header.cputype) {
4962 case llvm::MachO::CPU_TYPE_ARM:
4963 if (flavor == 1 ||
4964 flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32
4965 // from mach/arm/thread_status.h
4966 {
4967 offset += 60; // This is the offset of pc in the GPR thread state
4968 // data structure.
4969 start_address = m_data_nsp->GetU32(&offset);
4970 done = true;
4971 }
4972 break;
4973 case llvm::MachO::CPU_TYPE_ARM64:
4974 case llvm::MachO::CPU_TYPE_ARM64_32:
4975 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
4976 {
4977 offset += 256; // This is the offset of pc in the GPR thread state
4978 // data structure.
4979 start_address = m_data_nsp->GetU64(&offset);
4980 done = true;
4981 }
4982 break;
4983 case llvm::MachO::CPU_TYPE_X86_64:
4984 if (flavor ==
4985 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
4986 {
4987 offset += 16 * 8; // This is the offset of rip in the GPR thread
4988 // state data structure.
4989 start_address = m_data_nsp->GetU64(&offset);
4990 done = true;
4991 }
4992 break;
4993 default:
4994 return m_entry_point_address;
4995 }
4996 // Haven't found the GPR flavor yet, skip over the data for this
4997 // flavor:
4998 if (done)
4999 break;
5000 offset += count * 4;
5001 }
5002 } break;
5003 case LC_MAIN: {
5004 uint64_t entryoffset = m_data_nsp->GetU64(&offset);
5005 SectionSP text_segment_sp =
5007 if (text_segment_sp) {
5008 done = true;
5009 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5010 }
5011 } break;
5012
5013 default:
5014 break;
5015 }
5016 if (done)
5017 break;
5018
5019 // Go to the next load command:
5020 offset = cmd_offset + load_cmd.cmdsize;
5021 }
5022
5023 if (start_address == LLDB_INVALID_ADDRESS && IsDynamicLoader()) {
5024 if (GetSymtab()) {
5025 const Symbol *dyld_start_sym =
5029 if (dyld_start_sym && dyld_start_sym->GetAddress().IsValid()) {
5030 start_address = dyld_start_sym->GetAddress().GetFileAddress();
5031 }
5032 }
5033 }
5034
5035 if (start_address != LLDB_INVALID_ADDRESS) {
5036 // We got the start address from the load commands, so now resolve that
5037 // address in the sections of this ObjectFile:
5038 if (!m_entry_point_address.ResolveAddressUsingFileSections(
5039 start_address, GetSectionList())) {
5040 m_entry_point_address.Clear();
5041 }
5042 } else {
5043 // We couldn't read the UnixThread load command - maybe it wasn't there.
5044 // As a fallback look for the "start" symbol in the main executable.
5045
5046 ModuleSP module_sp(GetModule());
5047
5048 if (module_sp) {
5049 SymbolContextList contexts;
5050 SymbolContext context;
5051 module_sp->FindSymbolsWithNameAndType(ConstString("start"),
5052 eSymbolTypeCode, contexts);
5053 if (contexts.GetSize()) {
5054 if (contexts.GetContextAtIndex(0, context))
5056 }
5057 }
5058 }
5059 }
5060
5061 return m_entry_point_address;
5062}
5063
5065 lldb_private::Address header_addr;
5066 SectionList *section_list = GetSectionList();
5067 if (section_list) {
5068 SectionSP text_segment_sp(
5069 section_list->FindSectionByName(GetSegmentNameTEXT()));
5070 if (text_segment_sp)
5071 header_addr = Address(text_segment_sp, /*offset=*/0);
5072 }
5073 return header_addr;
5074}
5075
5077 ModuleSP module_sp(GetModule());
5078 if (module_sp) {
5079 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5083 FileRangeArray::Entry file_range;
5084 llvm::MachO::thread_command thread_cmd;
5085 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5086 const uint32_t cmd_offset = offset;
5087 if (!ReadMachOCommand(*m_data_nsp, offset, thread_cmd))
5088 break;
5089
5090 if (thread_cmd.cmd == LC_THREAD) {
5091 file_range.SetRangeBase(offset);
5092 file_range.SetByteSize(thread_cmd.cmdsize - 8);
5093 m_thread_context_offsets.Append(file_range);
5094 }
5095 offset = cmd_offset + thread_cmd.cmdsize;
5096 }
5097 }
5098 }
5099 return m_thread_context_offsets.GetSize();
5100}
5101
5102std::vector<std::tuple<offset_t, offset_t>>
5104 std::vector<std::tuple<offset_t, offset_t>> results;
5105 ModuleSP module_sp(GetModule());
5106 if (module_sp) {
5107 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5108
5110 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5111 const uint32_t cmd_offset = offset;
5112 llvm::MachO::load_command lc = {};
5113 if (!ReadMachOCommand(*m_data_nsp, offset, lc))
5114 break;
5115 if (lc.cmd == LC_NOTE) {
5116 char data_owner[17];
5117 m_data_nsp->CopyData(offset, 16, data_owner);
5118 data_owner[16] = '\0';
5119 offset += 16;
5120
5121 if (name == data_owner) {
5122 offset_t payload_offset = m_data_nsp->GetU64_unchecked(&offset);
5123 offset_t payload_size = m_data_nsp->GetU64_unchecked(&offset);
5124 results.push_back({payload_offset, payload_size});
5125 }
5126 }
5127 offset = cmd_offset + lc.cmdsize;
5128 }
5129 }
5130 return results;
5131}
5132
5134 Log *log(
5136 ModuleSP module_sp(GetModule());
5137 if (module_sp) {
5138 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5139
5140 auto lc_notes = FindLC_NOTEByName("kern ver str");
5141 for (auto lc_note : lc_notes) {
5142 offset_t payload_offset = std::get<0>(lc_note);
5143 offset_t payload_size = std::get<1>(lc_note);
5144 uint32_t version;
5145 if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr) {
5146 if (version == 1) {
5147 uint32_t strsize = payload_size - sizeof(uint32_t);
5148 std::string result(strsize, '\0');
5149 m_data_nsp->CopyData(payload_offset, strsize, result.data());
5150 LLDB_LOGF(log, "LC_NOTE 'kern ver str' found with text '%s'",
5151 result.c_str());
5152 return result;
5153 }
5154 }
5155 }
5156
5157 // Second, make a pass over the load commands looking for an obsolete
5158 // LC_IDENT load command.
5160 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5161 const uint32_t cmd_offset = offset;
5162 llvm::MachO::ident_command ident_command;
5163 if (!ReadMachOCommand(*m_data_nsp, offset, ident_command))
5164 break;
5165 if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
5166 std::string result(ident_command.cmdsize, '\0');
5167 if (m_data_nsp->CopyData(offset, ident_command.cmdsize,
5168 result.data()) == ident_command.cmdsize) {
5169 LLDB_LOGF(log, "LC_IDENT found with text '%s'", result.c_str());
5170 return result;
5171 }
5172 }
5173 offset = cmd_offset + ident_command.cmdsize;
5174 }
5175 }
5176 return {};
5177}
5178
5180 AddressableBits addressable_bits;
5181
5183 ModuleSP module_sp(GetModule());
5184 if (module_sp) {
5185 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5186 auto lc_notes = FindLC_NOTEByName("addrable bits");
5187 for (auto lc_note : lc_notes) {
5188 offset_t payload_offset = std::get<0>(lc_note);
5189 uint32_t version;
5190 if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr) {
5191 if (version == 3) {
5192 uint32_t num_addr_bits =
5193 m_data_nsp->GetU32_unchecked(&payload_offset);
5194 addressable_bits.SetAddressableBits(num_addr_bits);
5195 LLDB_LOGF(log,
5196 "LC_NOTE 'addrable bits' v3 found, value %d "
5197 "bits",
5198 num_addr_bits);
5199 }
5200 if (version == 4) {
5201 uint32_t lo_addr_bits = m_data_nsp->GetU32_unchecked(&payload_offset);
5202 uint32_t hi_addr_bits = m_data_nsp->GetU32_unchecked(&payload_offset);
5203
5204 if (lo_addr_bits == hi_addr_bits)
5205 addressable_bits.SetAddressableBits(lo_addr_bits);
5206 else
5207 addressable_bits.SetAddressableBits(lo_addr_bits, hi_addr_bits);
5208 LLDB_LOGF(log, "LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
5209 lo_addr_bits, hi_addr_bits);
5210 }
5211 }
5212 }
5213 }
5214 return addressable_bits;
5215}
5216
5218 bool &value_is_offset,
5219 UUID &uuid,
5220 ObjectFile::BinaryType &type) {
5221 Log *log(
5223 value = LLDB_INVALID_ADDRESS;
5224 value_is_offset = false;
5225 uuid.Clear();
5226 uint32_t log2_pagesize = 0; // not currently passed up to caller
5227 uint32_t platform = 0; // not currently passed up to caller
5228 ModuleSP module_sp(GetModule());
5229 if (module_sp) {
5230 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5231
5232 auto lc_notes = FindLC_NOTEByName("main bin spec");
5233 for (auto lc_note : lc_notes) {
5234 offset_t payload_offset = std::get<0>(lc_note);
5235
5236 // struct main_bin_spec
5237 // {
5238 // uint32_t version; // currently 2
5239 // uint32_t type; // 0 == unspecified,
5240 // // 1 == kernel
5241 // // 2 == user process,
5242 // dyld mach-o binary addr
5243 // // 3 == standalone binary
5244 // // 4 == user process,
5245 // // dyld_all_image_infos addr
5246 // uint64_t address; // UINT64_MAX if address not specified
5247 // uint64_t slide; // slide, UINT64_MAX if unspecified
5248 // // 0 if no slide needs to be applied to
5249 // // file address
5250 // uuid_t uuid; // all zero's if uuid not specified
5251 // uint32_t log2_pagesize; // process page size in log base 2,
5252 // // e.g. 4k pages are 12.
5253 // // 0 for unspecified
5254 // uint32_t platform; // The Mach-O platform for this corefile.
5255 // // 0 for unspecified.
5256 // // The values are defined in
5257 // // <mach-o/loader.h>, PLATFORM_*.
5258 // } __attribute((packed));
5259
5260 // "main bin spec" (main binary specification) data payload is
5261 // formatted:
5262 // uint32_t version [currently 1]
5263 // uint32_t type [0 == unspecified, 1 == kernel,
5264 // 2 == user process, 3 == firmware ]
5265 // uint64_t address [ UINT64_MAX if address not specified ]
5266 // uuid_t uuid [ all zero's if uuid not specified ]
5267 // uint32_t log2_pagesize [ process page size in log base
5268 // 2, e.g. 4k pages are 12.
5269 // 0 for unspecified ]
5270 // uint32_t unused [ for alignment ]
5271
5272 uint32_t version;
5273 if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr &&
5274 version <= 2) {
5275 uint32_t binspec_type = 0;
5276 uuid_t raw_uuid;
5277 memset(raw_uuid, 0, sizeof(uuid_t));
5278
5279 if (!m_data_nsp->GetU32(&payload_offset, &binspec_type, 1))
5280 return false;
5281 if (!m_data_nsp->GetU64(&payload_offset, &value, 1))
5282 return false;
5283 uint64_t slide = LLDB_INVALID_ADDRESS;
5284 if (version > 1 && !m_data_nsp->GetU64(&payload_offset, &slide, 1))
5285 return false;
5286 if (value == LLDB_INVALID_ADDRESS && slide != LLDB_INVALID_ADDRESS) {
5287 value = slide;
5288 value_is_offset = true;
5289 }
5290
5291 if (m_data_nsp->CopyData(payload_offset, sizeof(uuid_t), raw_uuid) !=
5292 0) {
5293 uuid = UUID(raw_uuid, sizeof(uuid_t));
5294 // convert the "main bin spec" type into our
5295 // ObjectFile::BinaryType enum
5296 const char *typestr = "unrecognized type";
5297 type = eBinaryTypeInvalid;
5298 switch (binspec_type) {
5299 case 0:
5300 type = eBinaryTypeUnknown;
5301 typestr = "uknown";
5302 break;
5303 case 1:
5304 type = eBinaryTypeKernel;
5305 typestr = "xnu kernel";
5306 break;
5307 case 2:
5308 type = eBinaryTypeUser;
5309 typestr = "userland dyld";
5310 break;
5311 case 3:
5312 type = eBinaryTypeStandalone;
5313 typestr = "standalone";
5314 break;
5315 case 4:
5317 typestr = "userland dyld_all_image_infos";
5318 break;
5319 }
5320 LLDB_LOGF(log,
5321 "LC_NOTE 'main bin spec' found, version %d type %d "
5322 "(%s), value 0x%" PRIx64 " value-is-slide==%s uuid %s",
5323 version, type, typestr, value,
5324 value_is_offset ? "true" : "false",
5325 uuid.GetAsString().c_str());
5326 if (!m_data_nsp->GetU32(&payload_offset, &log2_pagesize, 1))
5327 return false;
5328 if (version > 1 && !m_data_nsp->GetU32(&payload_offset, &platform, 1))
5329 return false;
5330 return true;
5331 }
5332 }
5333 }
5334 }
5335 return false;
5336}
5337
5339 std::vector<lldb::tid_t> &tids) {
5340 tids.clear();
5341 ModuleSP module_sp(GetModule());
5342 if (module_sp) {
5343 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5344
5347 StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
5348 StructuredData::Array *threads;
5349 if (!dict->GetValueForKeyAsArray("threads", threads) || !threads) {
5350 LLDB_LOGF(log,
5351 "'process metadata' LC_NOTE does not have a 'threads' key");
5352 return false;
5353 }
5354 if (threads->GetSize() != GetNumThreadContexts()) {
5355 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, number of "
5356 "threads does not match number of LC_THREADS.");
5357 return false;
5358 }
5359 const size_t num_threads = threads->GetSize();
5360 for (size_t i = 0; i < num_threads; i++) {
5361 std::optional<StructuredData::Dictionary *> maybe_thread =
5362 threads->GetItemAtIndexAsDictionary(i);
5363 if (!maybe_thread) {
5364 LLDB_LOGF(log,
5365 "Unable to read 'process metadata' LC_NOTE, threads "
5366 "array does not have a dictionary at index %zu.",
5367 i);
5368 return false;
5369 }
5370 StructuredData::Dictionary *thread = *maybe_thread;
5372 if (thread->GetValueForKeyAsInteger<lldb::tid_t>("thread_id", tid))
5373 if (tid == 0)
5375 tids.push_back(tid);
5376 }
5377
5378 if (log) {
5379 StreamString logmsg;
5380 logmsg.Printf("LC_NOTE 'process metadata' found: ");
5381 dict->Dump(logmsg, /* pretty_print */ false);
5382 LLDB_LOGF(log, "%s", logmsg.GetData());
5383 }
5384 return true;
5385 }
5386 }
5387 return false;
5388}
5389
5390/// Return the payload of an LC_NOTE, decompressing it if needed.
5391///
5392/// A payload is either stored as is, or compressed in the layout of a GNU
5393/// .zdebug section:
5394///
5395/// offset size contents
5396/// 0 4 magic "ZLIB"
5397/// 4 8 uncompressed size, big-endian uint64_t
5398/// 12 n RFC 1950 zlib stream
5399///
5400/// The size is big-endian regardless of the corefile's byte order. An
5401/// uncompressed payload must not start with the magic.
5402static llvm::Expected<std::string> ReadLCNotePayload(const DataExtractor &data,
5403 lldb::offset_t offset,
5404 uint64_t size) {
5405 const uint8_t *bytes = data.PeekData(offset, size);
5406 if (!bytes)
5407 return llvm::createStringError(
5408 "payload of %" PRIu64 " bytes is out of bounds", size);
5409 llvm::ArrayRef<uint8_t> payload(bytes, size);
5410
5411 constexpr llvm::StringLiteral magic = "ZLIB";
5412 constexpr size_t header_size = magic.size() + sizeof(uint64_t);
5413 if (!llvm::toStringRef(payload).starts_with(magic))
5414 return llvm::toStringRef(payload).str();
5415 if (payload.size() < header_size)
5416 return llvm::createStringError("compressed payload header is truncated");
5417
5418 uint64_t uncompressed_size =
5419 llvm::support::endian::read64be(payload.data() + magic.size());
5420 llvm::ArrayRef<uint8_t> compressed = payload.drop_front(header_size);
5421 // Deflate cannot exceed a 1032:1 ratio. A larger claimed size is corrupt and
5422 // must not size the allocation.
5423 if (uncompressed_size / 1032 > compressed.size())
5424 return llvm::createStringError("uncompressed size %" PRIu64
5425 " is impossible for %zu compressed bytes",
5426 uncompressed_size, compressed.size());
5427 if (!llvm::compression::zlib::isAvailable())
5428 return llvm::createStringError(
5429 "payload is zlib-compressed but LLDB was built without zlib");
5430
5431 llvm::SmallVector<uint8_t, 0> uncompressed;
5432 if (llvm::Error err = llvm::compression::zlib::decompress(
5433 compressed, uncompressed, uncompressed_size))
5434 return err;
5435 return llvm::toStringRef(uncompressed).str();
5436}
5437
5439 ModuleSP module_sp(GetModule());
5440 if (!module_sp)
5441 return {};
5442
5444 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5445 auto lc_notes = FindLC_NOTEByName("process metadata");
5446 if (lc_notes.size() == 0)
5447 return {};
5448
5449 if (lc_notes.size() > 1)
5450 LLDB_LOGF(
5451 log,
5452 "Multiple 'process metadata' LC_NOTEs found, only using the first.");
5453
5454 auto [payload_offset, payload_size] = lc_notes[0];
5455 llvm::Expected<std::string> json =
5456 ReadLCNotePayload(*m_data_nsp, payload_offset, payload_size);
5457 if (!json) {
5458 LLDB_LOG_ERROR(log, json.takeError(),
5459 "Unable to read 'process metadata' LC_NOTE: {0}");
5460 return {};
5461 }
5462 StructuredData::ObjectSP object_sp =
5463 StructuredData::ParseJSON(llvm::StringRef(*json).rtrim('\0'));
5464 if (!object_sp) {
5465 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
5466 "parse as valid JSON.");
5467 return {};
5468 }
5469 StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
5470 if (!dict) {
5471 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
5472 "get a dictionary.");
5473 return {};
5474 }
5475
5476 return object_sp;
5477}
5478
5481 lldb_private::Thread &thread) {
5482 lldb::RegisterContextSP reg_ctx_sp;
5483
5484 ModuleSP module_sp(GetModule());
5485 if (module_sp) {
5486 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5489
5490 const FileRangeArray::Entry *thread_context_file_range =
5491 m_thread_context_offsets.GetEntryAtIndex(idx);
5492 if (thread_context_file_range) {
5493
5494 DataExtractor data(*m_data_nsp, thread_context_file_range->GetRangeBase(),
5495 thread_context_file_range->GetByteSize());
5496
5497 switch (m_header.cputype) {
5498 case llvm::MachO::CPU_TYPE_ARM64:
5499 case llvm::MachO::CPU_TYPE_ARM64_32:
5500 reg_ctx_sp =
5501 std::make_shared<RegisterContextDarwin_arm64_Mach>(thread, data);
5502 break;
5503
5504 case llvm::MachO::CPU_TYPE_ARM:
5505 reg_ctx_sp =
5506 std::make_shared<RegisterContextDarwin_arm_Mach>(thread, data);
5507 break;
5508
5509 case llvm::MachO::CPU_TYPE_X86_64:
5510 reg_ctx_sp =
5511 std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);
5512 break;
5513
5514 case llvm::MachO::CPU_TYPE_RISCV:
5515 reg_ctx_sp =
5516 std::make_shared<RegisterContextDarwin_riscv32_Mach>(thread, data);
5517 break;
5518 }
5519 }
5520 }
5521 return reg_ctx_sp;
5522}
5523
5525 switch (m_header.filetype) {
5526 case MH_OBJECT: // 0x1u
5527 if (GetAddressByteSize() == 4) {
5528 // 32 bit kexts are just object files, but they do have a valid
5529 // UUID load command.
5530 if (GetUUID()) {
5531 // this checking for the UUID load command is not enough we could
5532 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
5533 // this is required of kexts
5534 if (m_strata == eStrataInvalid)
5536 return eTypeSharedLibrary;
5537 }
5538 }
5539 return eTypeObjectFile;
5540
5541 case MH_EXECUTE:
5542 return eTypeExecutable; // 0x2u
5543 case MH_FVMLIB:
5544 return eTypeSharedLibrary; // 0x3u
5545 case MH_CORE:
5546 return eTypeCoreFile; // 0x4u
5547 case MH_PRELOAD:
5548 return eTypeSharedLibrary; // 0x5u
5549 case MH_DYLIB:
5550 return eTypeSharedLibrary; // 0x6u
5551 case MH_DYLINKER:
5552 return eTypeDynamicLinker; // 0x7u
5553 case MH_BUNDLE:
5554 return eTypeSharedLibrary; // 0x8u
5555 case MH_DYLIB_STUB:
5556 return eTypeStubLibrary; // 0x9u
5557 case MH_DSYM:
5558 return eTypeDebugInfo; // 0xAu
5559 case MH_KEXT_BUNDLE:
5560 return eTypeSharedLibrary; // 0xBu
5561 default:
5562 break;
5563 }
5564 return eTypeUnknown;
5565}
5566
5568 switch (m_header.filetype) {
5569 case MH_OBJECT: // 0x1u
5570 {
5571 // 32 bit kexts are just object files, but they do have a valid
5572 // UUID load command.
5573 if (GetUUID()) {
5574 // this checking for the UUID load command is not enough we could
5575 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
5576 // this is required of kexts
5577 if (m_type == eTypeInvalid)
5579
5580 return eStrataKernel;
5581 }
5582 }
5583 return eStrataUnknown;
5584
5585 case MH_EXECUTE: // 0x2u
5586 // Check for the MH_DYLDLINK bit in the flags
5587 if (m_header.flags & MH_DYLDLINK) {
5588 return eStrataUser;
5589 } else {
5590 SectionList *section_list = GetSectionList();
5591 if (section_list) {
5592 if (section_list->FindSectionByName("__KLD"))
5593 return eStrataKernel;
5594 }
5595 }
5596 return eStrataRawImage;
5597
5598 case MH_FVMLIB:
5599 return eStrataUser; // 0x3u
5600 case MH_CORE:
5601 return eStrataUnknown; // 0x4u
5602 case MH_PRELOAD:
5603 return eStrataRawImage; // 0x5u
5604 case MH_DYLIB:
5605 return eStrataUser; // 0x6u
5606 case MH_DYLINKER:
5607 return eStrataUser; // 0x7u
5608 case MH_BUNDLE:
5609 return eStrataUser; // 0x8u
5610 case MH_DYLIB_STUB:
5611 return eStrataUser; // 0x9u
5612 case MH_DSYM:
5613 return eStrataUnknown; // 0xAu
5614 case MH_KEXT_BUNDLE:
5615 return eStrataKernel; // 0xBu
5616 default:
5617 break;
5618 }
5619 return eStrataUnknown;
5620}
5621
5622llvm::VersionTuple ObjectFileMachO::GetVersion() {
5623 ModuleSP module_sp(GetModule());
5624 if (module_sp) {
5625 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5626 llvm::MachO::dylib_command load_cmd;
5628 uint32_t version_cmd = 0;
5629 uint64_t version = 0;
5630 uint32_t i;
5631 for (i = 0; i < m_header.ncmds; ++i) {
5632 const lldb::offset_t cmd_offset = offset;
5633 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
5634 break;
5635
5636 if (load_cmd.cmd == LC_ID_DYLIB) {
5637 if (version_cmd == 0) {
5638 version_cmd = load_cmd.cmd;
5639 if (m_data_nsp->GetU32(&offset, &load_cmd.dylib, 4) == nullptr)
5640 break;
5641 version = load_cmd.dylib.current_version;
5642 }
5643 break; // Break for now unless there is another more complete version
5644 // number load command in the future.
5645 }
5646 offset = cmd_offset + load_cmd.cmdsize;
5647 }
5648
5649 if (version_cmd == LC_ID_DYLIB) {
5650 unsigned major = (version & 0xFFFF0000ull) >> 16;
5651 unsigned minor = (version & 0x0000FF00ull) >> 8;
5652 unsigned subminor = (version & 0x000000FFull);
5653 return llvm::VersionTuple(major, minor, subminor);
5654 }
5655 }
5656 return llvm::VersionTuple();
5657}
5658
5660 ModuleSP module_sp(GetModule());
5661 ArchSpec arch;
5662 if (module_sp) {
5663 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5664
5665 return GetArchitecture(module_sp, m_header, *m_data_nsp,
5667 }
5668 return arch;
5669}
5670
5672 addr_t &base_addr, UUID &uuid) {
5673 uuid.Clear();
5674 base_addr = LLDB_INVALID_ADDRESS;
5675 if (process && process->GetDynamicLoader()) {
5676 DynamicLoader *dl = process->GetDynamicLoader();
5677 LazyBool using_shared_cache;
5678 LazyBool private_shared_cache;
5679 FileSpec sc_filepath;
5680 std::optional<uint64_t> size;
5681 dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,
5682 private_shared_cache, sc_filepath, size);
5683 }
5685 LLDB_LOGF(
5686 log,
5687 "inferior process shared cache has a UUID of %s, base address 0x%" PRIx64,
5688 uuid.GetAsString().c_str(), base_addr);
5689}
5690
5691// From dyld SPI header dyld_process_info.h
5692typedef void *dyld_process_info;
5694 uuid_t cacheUUID; // UUID of cache used by process
5695 uint64_t cacheBaseAddress; // load address of dyld shared cache
5696 bool noCache; // process is running without a dyld cache
5697 bool privateCache; // process is using a private copy of its dyld cache
5698};
5699
5700// #including mach/mach.h pulls in machine.h & CPU_TYPE_ARM etc conflicts with
5701// llvm enum definitions llvm::MachO::CPU_TYPE_ARM turning them into compile
5702// errors. So we need to use the actual underlying types of task_t and
5703// kern_return_t below.
5704extern "C" unsigned int /*task_t*/ mach_task_self();
5705
5707 uuid.Clear();
5708 base_addr = LLDB_INVALID_ADDRESS;
5709
5710#if defined(__APPLE__)
5711 uint8_t *(*dyld_get_all_image_infos)(void);
5712 dyld_get_all_image_infos =
5713 (uint8_t * (*)()) dlsym(RTLD_DEFAULT, "_dyld_get_all_image_infos");
5714 if (dyld_get_all_image_infos) {
5715 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5716 if (dyld_all_image_infos_address) {
5717 uint32_t *version = (uint32_t *)
5718 dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
5719 if (*version >= 13) {
5720 uuid_t *sharedCacheUUID_address = 0;
5721 int wordsize = sizeof(uint8_t *);
5722 if (wordsize == 8) {
5723 sharedCacheUUID_address =
5724 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5725 160); // sharedCacheUUID <mach-o/dyld_images.h>
5726 if (*version >= 15)
5727 base_addr =
5728 *(uint64_t
5729 *)((uint8_t *)dyld_all_image_infos_address +
5730 176); // sharedCacheBaseAddress <mach-o/dyld_images.h>
5731 } else {
5732 sharedCacheUUID_address =
5733 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5734 84); // sharedCacheUUID <mach-o/dyld_images.h>
5735 if (*version >= 15) {
5736 base_addr = 0;
5737 base_addr =
5738 *(uint32_t
5739 *)((uint8_t *)dyld_all_image_infos_address +
5740 100); // sharedCacheBaseAddress <mach-o/dyld_images.h>
5741 }
5742 }
5743 uuid = UUID(sharedCacheUUID_address, sizeof(uuid_t));
5744 }
5745 }
5746 } else {
5747 // Exists in macOS 10.12 and later, iOS 10.0 and later - dyld SPI
5748 dyld_process_info (*dyld_process_info_create)(
5749 unsigned int /* task_t */ task, uint64_t timestamp,
5750 unsigned int /*kern_return_t*/ *kernelError);
5751 void (*dyld_process_info_get_cache)(void *info, void *cacheInfo);
5752 void (*dyld_process_info_release)(dyld_process_info info);
5753
5754 dyld_process_info_create = (void *(*)(unsigned int /* task_t */, uint64_t,
5755 unsigned int /*kern_return_t*/ *))
5756 dlsym(RTLD_DEFAULT, "_dyld_process_info_create");
5757 dyld_process_info_get_cache = (void (*)(void *, void *))dlsym(
5758 RTLD_DEFAULT, "_dyld_process_info_get_cache");
5759 dyld_process_info_release =
5760 (void (*)(void *))dlsym(RTLD_DEFAULT, "_dyld_process_info_release");
5761
5762 if (dyld_process_info_create && dyld_process_info_get_cache) {
5763 unsigned int /*kern_return_t */ kern_ret;
5764 dyld_process_info process_info =
5765 dyld_process_info_create(::mach_task_self(), 0, &kern_ret);
5766 if (process_info) {
5768 memset(&sc_info, 0, sizeof(struct lldb_copy__dyld_process_cache_info));
5769 dyld_process_info_get_cache(process_info, &sc_info);
5770 if (sc_info.cacheBaseAddress != 0) {
5771 base_addr = sc_info.cacheBaseAddress;
5772 uuid = UUID(sc_info.cacheUUID, sizeof(uuid_t));
5773 }
5774 dyld_process_info_release(process_info);
5775 }
5776 }
5777 }
5779 if (log && uuid.IsValid())
5780 LLDB_LOGF(log,
5781 "lldb's in-memory shared cache has a UUID of %s base address of "
5782 "0x%" PRIx64,
5783 uuid.GetAsString().c_str(), base_addr);
5784#endif
5785}
5786
5787static llvm::VersionTuple FindMinimumVersionInfo(DataExtractor &data,
5788 lldb::offset_t offset,
5789 size_t ncmds) {
5790 for (size_t i = 0; i < ncmds; i++) {
5791 const lldb::offset_t load_cmd_offset = offset;
5792 llvm::MachO::load_command lc = {};
5793 if (!ReadMachOCommand(data, offset, lc))
5794 break;
5795
5796 uint32_t version = 0;
5797 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
5798 lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
5799 lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
5800 lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
5801 // struct version_min_command {
5802 // uint32_t cmd; // LC_VERSION_MIN_*
5803 // uint32_t cmdsize;
5804 // uint32_t version; // X.Y.Z encoded in nibbles xxxx.yy.zz
5805 // uint32_t sdk;
5806 // };
5807 // We want to read version.
5808 version = data.GetU32(&offset);
5809 } else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
5810 // struct build_version_command {
5811 // uint32_t cmd; // LC_BUILD_VERSION
5812 // uint32_t cmdsize;
5813 // uint32_t platform;
5814 // uint32_t minos; // X.Y.Z encoded in nibbles xxxx.yy.zz
5815 // uint32_t sdk;
5816 // uint32_t ntools;
5817 // };
5818 // We want to read minos.
5819 offset += sizeof(uint32_t); // Skip over platform
5820 version = data.GetU32(&offset); // Extract minos
5821 }
5822
5823 if (version) {
5824 const uint32_t xxxx = version >> 16;
5825 const uint32_t yy = (version >> 8) & 0xffu;
5826 const uint32_t zz = version & 0xffu;
5827 if (xxxx)
5828 return llvm::VersionTuple(xxxx, yy, zz);
5829 }
5830 offset = load_cmd_offset + lc.cmdsize;
5831 }
5832 return llvm::VersionTuple();
5833}
5834
5841
5848
5850 return m_header.filetype == llvm::MachO::MH_DYLINKER;
5851}
5852
5854 // Dsymutil guarantees that the .debug_aranges accelerator is complete and can
5855 // be trusted by LLDB.
5856 return m_header.filetype == llvm::MachO::MH_DSYM;
5857}
5858
5862
5864 // Find the first address of the mach header which is the first non-zero file
5865 // sized section whose file offset is zero. This is the base file address of
5866 // the mach-o file which can be subtracted from the vmaddr of the other
5867 // segments found in memory and added to the load address
5868 ModuleSP module_sp = GetModule();
5869 if (!module_sp)
5870 return nullptr;
5871 SectionList *section_list = GetSectionList();
5872 if (!section_list)
5873 return nullptr;
5874
5875 // Some binaries can have a TEXT segment with a non-zero file offset.
5876 // Binaries in the shared cache are one example. Some hand-generated
5877 // binaries may not be laid out in the normal TEXT,DATA,LC_SYMTAB order
5878 // in the file, even though they're laid out correctly in vmaddr terms.
5879 SectionSP text_segment_sp =
5880 section_list->FindSectionByName(GetSegmentNameTEXT());
5881 if (text_segment_sp.get() && SectionIsLoadable(text_segment_sp.get()))
5882 return text_segment_sp.get();
5883
5884 const size_t num_sections = section_list->GetSize();
5885 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
5886 Section *section = section_list->GetSectionAtIndex(sect_idx).get();
5887 if (section->GetFileOffset() == 0 && SectionIsLoadable(section))
5888 return section;
5889 }
5890
5891 return nullptr;
5892}
5893
5895 assert(section.GetObjectFile() == this && "Wrong object file!");
5896 SectionSP segment = section.GetParent();
5897 if (!segment)
5898 return false;
5899
5900 const bool is_data_const_got =
5901 segment->GetName() == "__DATA_CONST" && section.GetName() == "__got";
5902 const bool is_auth_const_ptr =
5903 segment->GetName() == "__AUTH_CONST" &&
5904 (section.GetName() == "__auth_got" || section.GetName() == "__auth_ptr");
5905 return is_data_const_got || is_auth_const_ptr;
5906}
5907
5909 if (!section)
5910 return false;
5911 if (section->IsThreadSpecific())
5912 return false;
5913 if (GetModule().get() != section->GetModule().get())
5914 return false;
5915 // firmware style binaries with llvm gcov segment do
5916 // not have that segment mapped into memory.
5917 if (section->GetName() == GetSegmentNameLLVM_COV()) {
5918 const Strata strata = GetStrata();
5919 if (strata == eStrataKernel || strata == eStrataRawImage)
5920 return false;
5921 }
5922 // Be careful with __LINKEDIT and __DWARF segments
5923 if (section->GetName() == GetSegmentNameLINKEDIT() ||
5924 section->GetName() == GetSegmentNameDWARF()) {
5925 // Only map __LINKEDIT and __DWARF if we have an in memory image and
5926 // this isn't a kernel binary like a kext or mach_kernel.
5927 const bool is_memory_image = (bool)m_process_wp.lock();
5928 const Strata strata = GetStrata();
5929 if (is_memory_image == false || strata == eStrataKernel)
5930 return false;
5931 }
5932 return true;
5933}
5934
5936 lldb::addr_t header_load_address, const Section *header_section,
5937 const Section *section) {
5938 ModuleSP module_sp = GetModule();
5939 if (module_sp && header_section && section &&
5940 header_load_address != LLDB_INVALID_ADDRESS) {
5941 lldb::addr_t file_addr = header_section->GetFileAddress();
5942 if (file_addr != LLDB_INVALID_ADDRESS && SectionIsLoadable(section))
5943 return section->GetFileAddress() - file_addr + header_load_address;
5944 }
5945 return LLDB_INVALID_ADDRESS;
5946}
5947
5949 bool value_is_offset) {
5951 ModuleSP module_sp = GetModule();
5952 if (!module_sp)
5953 return false;
5954
5955 SectionList *section_list = GetSectionList();
5956 if (!section_list)
5957 return false;
5958
5959 size_t num_loaded_sections = 0;
5960 const size_t num_sections = section_list->GetSize();
5961
5962 // Warn if some top-level segments map to the same address. The binary may be
5963 // malformed.
5964 const bool warn_multiple = true;
5965
5966 if (log) {
5967 StreamString logmsg;
5968 logmsg << "ObjectFileMachO::SetLoadAddress ";
5969 if (GetFileSpec())
5970 logmsg << "path='" << GetFileSpec().GetPath() << "' ";
5971 if (GetUUID()) {
5972 logmsg << "uuid=" << GetUUID().GetAsString();
5973 }
5974 LLDB_LOGF(log, "%s", logmsg.GetData());
5975 }
5976 if (value_is_offset) {
5977 // "value" is an offset to apply to each top level segment
5978 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
5979 // Iterate through the object file sections to find all of the
5980 // sections that size on disk (to avoid __PAGEZERO) and load them
5981 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
5982 if (SectionIsLoadable(section_sp.get())) {
5983 LLDB_LOG(
5984 log,
5985 "ObjectFileMachO::SetLoadAddress segment '{0}' load addr is {1:x}",
5986 section_sp->GetName(), section_sp->GetFileAddress() + value);
5987 if (target.SetSectionLoadAddress(section_sp,
5988 section_sp->GetFileAddress() + value,
5989 warn_multiple))
5990 ++num_loaded_sections;
5991 }
5992 }
5993 } else {
5994 // "value" is the new base address of the mach_header, adjust each
5995 // section accordingly
5996
5997 Section *mach_header_section = GetMachHeaderSection();
5998 if (mach_header_section) {
5999 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6000 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
6001
6002 lldb::addr_t section_load_addr =
6004 value, mach_header_section, section_sp.get());
6005 if (section_load_addr != LLDB_INVALID_ADDRESS) {
6006 LLDB_LOG(log,
6007 "ObjectFileMachO::SetLoadAddress segment '{0}' load addr is "
6008 "{1:x}",
6009 section_sp->GetName(), section_load_addr);
6010 if (target.SetSectionLoadAddress(section_sp, section_load_addr,
6011 warn_multiple))
6012 ++num_loaded_sections;
6013 }
6014 }
6015 }
6016 }
6017 return num_loaded_sections > 0;
6018}
6019
6021 uint32_t version; // currently 1
6022 uint32_t imgcount; // number of binary images
6023 uint64_t entries_fileoff; // file offset in the corefile of where the array of
6024 // struct entry's begin.
6025 uint32_t entries_size; // size of 'struct entry'.
6026 uint32_t unused;
6027};
6028
6030 uint64_t filepath_offset; // offset in corefile to c-string of the file path,
6031 // UINT64_MAX if unavailable.
6032 uuid_t uuid; // uint8_t[16]. should be set to all zeroes if
6033 // uuid is unknown.
6034 uint64_t load_address; // UINT64_MAX if unknown.
6035 uint64_t seg_addrs_offset; // offset to the array of struct segment_vmaddr's.
6036 uint32_t segment_count; // The number of segments for this binary.
6037 uint32_t unused;
6038
6041 memset(&uuid, 0, sizeof(uuid_t));
6042 segment_count = 0;
6045 unused = 0;
6046 }
6049 memcpy(&uuid, &rhs.uuid, sizeof(uuid_t));
6053 unused = rhs.unused;
6054 }
6055};
6056
6058 char segname[16];
6059 uint64_t vmaddr;
6060 uint64_t unused;
6061
6063 memset(&segname, 0, 16);
6065 unused = 0;
6066 }
6068 memcpy(&segname, &rhs.segname, 16);
6069 vmaddr = rhs.vmaddr;
6070 unused = rhs.unused;
6071 }
6072};
6073
6074// Write the payload for the "all image infos" LC_NOTE into
6075// the supplied all_image_infos_payload, assuming that this
6076// will be written into the corefile starting at
6077// initial_file_offset.
6078//
6079// The placement of this payload is a little tricky. We're
6080// laying this out as
6081//
6082// 1. header (struct all_image_info_header)
6083// 2. Array of fixed-size (struct image_entry)'s, one
6084// per binary image present in the process.
6085// 3. Arrays of (struct segment_vmaddr)'s, a varying number
6086// for each binary image.
6087// 4. Variable length c-strings of binary image filepaths,
6088// one per binary.
6089//
6090// To compute where everything will be laid out in the
6091// payload, we need to iterate over the images and calculate
6092// how many segment_vmaddr structures each image will need,
6093// and how long each image's filepath c-string is. There
6094// are some multiple passes over the image list while calculating
6095// everything.
6096
6097static offset_t
6099 offset_t initial_file_offset,
6100 StreamString &all_image_infos_payload,
6102 Target &target = process_sp->GetTarget();
6103 ModuleList modules = target.GetImages();
6104
6105 // stack-only corefiles have no reason to include binaries that
6106 // are not executing; we're trying to make the smallest corefile
6107 // we can, so leave the rest out.
6109 modules.Clear();
6110
6111 std::set<std::string> executing_uuids;
6112 std::vector<ThreadSP> thread_list =
6113 process_sp->CalculateCoreFileThreadList(options);
6114 for (const ThreadSP &thread_sp : thread_list) {
6115 uint32_t stack_frame_count = thread_sp->GetStackFrameCount();
6116 for (uint32_t j = 0; j < stack_frame_count; j++) {
6117 StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);
6118 Address pc = stack_frame_sp->GetFrameCodeAddress();
6119 ModuleSP module_sp = pc.GetModule();
6120 if (module_sp) {
6121 UUID uuid = module_sp->GetUUID();
6122 if (uuid.IsValid()) {
6123 executing_uuids.insert(uuid.GetAsString());
6124 modules.AppendIfNeeded(module_sp);
6125 }
6126 }
6127 }
6128 }
6129 size_t modules_count = modules.GetSize();
6130
6131 struct all_image_infos_header infos;
6132 infos.version = 1;
6133 infos.imgcount = modules_count;
6134 infos.entries_size = sizeof(image_entry);
6135 infos.entries_fileoff = initial_file_offset + sizeof(all_image_infos_header);
6136 infos.unused = 0;
6137
6138 all_image_infos_payload.PutHex32(infos.version);
6139 all_image_infos_payload.PutHex32(infos.imgcount);
6140 all_image_infos_payload.PutHex64(infos.entries_fileoff);
6141 all_image_infos_payload.PutHex32(infos.entries_size);
6142 all_image_infos_payload.PutHex32(infos.unused);
6143
6144 // First create the structures for all of the segment name+vmaddr vectors
6145 // for each module, so we will know the size of them as we add the
6146 // module entries.
6147 std::vector<std::vector<segment_vmaddr>> modules_segment_vmaddrs;
6148 for (size_t i = 0; i < modules_count; i++) {
6149 ModuleSP module = modules.GetModuleAtIndex(i);
6150
6151 SectionList *sections = module->GetSectionList();
6152 size_t sections_count = sections->GetSize();
6153 std::vector<segment_vmaddr> segment_vmaddrs;
6154 for (size_t j = 0; j < sections_count; j++) {
6155 SectionSP section = sections->GetSectionAtIndex(j);
6156 if (!section->GetParent().get()) {
6157 addr_t vmaddr = section->GetLoadBaseAddress(&target);
6158 if (vmaddr == LLDB_INVALID_ADDRESS)
6159 continue;
6160 llvm::StringRef name = section->GetName();
6161 segment_vmaddr seg_vmaddr;
6162 // This is the uncommon case where strncpy is exactly
6163 // the right one, doesn't need to be null-terminated.
6164 // The segment name in a Mach-O LC_SEGMENT/LC_SEGMENT_64 is char[16] and
6165 // is not guaranteed to be null-terminated if all 16 characters are
6166 // used.
6167 // coverity[buffer_size_warning]
6168 strncpy(seg_vmaddr.segname, name.data(),
6169 std::min(name.size(), sizeof(seg_vmaddr.segname)));
6170 seg_vmaddr.vmaddr = vmaddr;
6171 seg_vmaddr.unused = 0;
6172 segment_vmaddrs.push_back(seg_vmaddr);
6173 }
6174 }
6175 modules_segment_vmaddrs.push_back(segment_vmaddrs);
6176 }
6177
6178 offset_t size_of_vmaddr_structs = 0;
6179 for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6180 size_of_vmaddr_structs +=
6181 modules_segment_vmaddrs[i].size() * sizeof(segment_vmaddr);
6182 }
6183
6184 offset_t size_of_filepath_cstrings = 0;
6185 for (size_t i = 0; i < modules_count; i++) {
6186 ModuleSP module_sp = modules.GetModuleAtIndex(i);
6187 size_of_filepath_cstrings += module_sp->GetFileSpec().GetPath().size() + 1;
6188 }
6189
6190 // Calculate the file offsets of our "all image infos" payload in the
6191 // corefile. initial_file_offset the original value passed in to this method.
6192
6193 offset_t start_of_entries =
6194 initial_file_offset + sizeof(all_image_infos_header);
6195 offset_t start_of_seg_vmaddrs =
6196 start_of_entries + sizeof(image_entry) * modules_count;
6197 offset_t start_of_filenames = start_of_seg_vmaddrs + size_of_vmaddr_structs;
6198
6199 offset_t final_file_offset = start_of_filenames + size_of_filepath_cstrings;
6200
6201 // Now write the one-per-module 'struct image_entry' into the
6202 // StringStream; keep track of where the struct segment_vmaddr
6203 // entries for each module will end up in the corefile.
6204
6205 offset_t current_string_offset = start_of_filenames;
6206 offset_t current_segaddrs_offset = start_of_seg_vmaddrs;
6207 for (size_t i = 0; i < modules_count; i++) {
6208 ModuleSP module_sp = modules.GetModuleAtIndex(i);
6209
6210 struct image_entry ent;
6211 memcpy(&ent.uuid, module_sp->GetUUID().GetBytes().data(), sizeof(ent.uuid));
6212 if (modules_segment_vmaddrs[i].size() > 0) {
6213 ent.segment_count = modules_segment_vmaddrs[i].size();
6214 ent.seg_addrs_offset = current_segaddrs_offset;
6215 }
6216 ent.filepath_offset = current_string_offset;
6217 ObjectFile *objfile = module_sp->GetObjectFile();
6218 if (objfile) {
6219 Address base_addr(objfile->GetBaseAddress());
6220 if (base_addr.IsValid()) {
6221 ent.load_address = base_addr.GetLoadAddress(&target);
6222 }
6223 }
6224
6225 all_image_infos_payload.PutHex64(ent.filepath_offset);
6226 all_image_infos_payload.PutRawBytes(ent.uuid, sizeof(ent.uuid));
6227 all_image_infos_payload.PutHex64(ent.load_address);
6228 all_image_infos_payload.PutHex64(ent.seg_addrs_offset);
6229 all_image_infos_payload.PutHex32(ent.segment_count);
6230
6231 if (executing_uuids.find(module_sp->GetUUID().GetAsString()) !=
6232 executing_uuids.end())
6233 all_image_infos_payload.PutHex32(1);
6234 else
6235 all_image_infos_payload.PutHex32(0);
6236
6237 current_segaddrs_offset += ent.segment_count * sizeof(segment_vmaddr);
6238 current_string_offset += module_sp->GetFileSpec().GetPath().size() + 1;
6239 }
6240
6241 // Now write the struct segment_vmaddr entries into the StringStream.
6242
6243 for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6244 if (modules_segment_vmaddrs[i].size() == 0)
6245 continue;
6246 for (struct segment_vmaddr segvm : modules_segment_vmaddrs[i]) {
6247 all_image_infos_payload.PutRawBytes(segvm.segname, sizeof(segvm.segname));
6248 all_image_infos_payload.PutHex64(segvm.vmaddr);
6249 all_image_infos_payload.PutHex64(segvm.unused);
6250 }
6251 }
6252
6253 for (size_t i = 0; i < modules_count; i++) {
6254 ModuleSP module_sp = modules.GetModuleAtIndex(i);
6255 std::string filepath = module_sp->GetFileSpec().GetPath();
6256 all_image_infos_payload.PutRawBytes(filepath.data(), filepath.size() + 1);
6257 }
6258
6259 return final_file_offset;
6260}
6261
6262// Temp struct used to combine contiguous memory regions with
6263// identical permissions.
6269
6272 Status &error) {
6273 // The FileSpec and Process are already checked in PluginManager::SaveCore.
6274 assert(options.GetOutputFile().has_value());
6275 assert(process_sp);
6276 const FileSpec outfile = options.GetOutputFile().value();
6277
6278 // MachO defaults to dirty pages
6281
6282 Target &target = process_sp->GetTarget();
6283 const ArchSpec target_arch = target.GetArchitecture();
6284 const llvm::Triple &target_triple = target_arch.GetTriple();
6285 if (target_triple.getVendor() == llvm::Triple::Apple &&
6286 (target_triple.getOS() == llvm::Triple::MacOSX ||
6287 target_triple.getOS() == llvm::Triple::IOS ||
6288 target_triple.getOS() == llvm::Triple::WatchOS ||
6289 target_triple.getOS() == llvm::Triple::TvOS ||
6290 target_triple.getOS() == llvm::Triple::BridgeOS ||
6291 target_triple.getOS() == llvm::Triple::XROS)) {
6292 bool make_core = false;
6293 switch (target_arch.GetMachine()) {
6294 case llvm::Triple::aarch64:
6295 case llvm::Triple::aarch64_32:
6296 case llvm::Triple::arm:
6297 case llvm::Triple::thumb:
6298 case llvm::Triple::x86:
6299 case llvm::Triple::x86_64:
6300 make_core = true;
6301 break;
6302 default:
6304 "unsupported core architecture: %s", target_triple.str().c_str());
6305 break;
6306 }
6307
6308 if (make_core) {
6309 CoreFileMemoryRanges core_ranges;
6310 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6311 if (error.Success()) {
6312 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
6313 const ByteOrder byte_order = target_arch.GetByteOrder();
6314 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6315 for (const auto &core_range_info : core_ranges) {
6316 // TODO: Refactor RangeDataVector to have a data iterator.
6317 const auto &core_range = core_range_info.data;
6318 uint32_t cmd_type = LC_SEGMENT_64;
6319 uint32_t segment_size = sizeof(llvm::MachO::segment_command_64);
6320 if (addr_byte_size == 4) {
6321 cmd_type = LC_SEGMENT;
6322 segment_size = sizeof(llvm::MachO::segment_command);
6323 }
6324 // Skip any ranges with no read/write/execute permissions and empty
6325 // ranges.
6326 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6327 continue;
6328 uint32_t vm_prot = 0;
6329 if (core_range.lldb_permissions & ePermissionsReadable)
6330 vm_prot |= VM_PROT_READ;
6331 if (core_range.lldb_permissions & ePermissionsWritable)
6332 vm_prot |= VM_PROT_WRITE;
6333 if (core_range.lldb_permissions & ePermissionsExecutable)
6334 vm_prot |= VM_PROT_EXECUTE;
6335 const addr_t vm_addr = core_range.range.start();
6336 const addr_t vm_size = core_range.range.size();
6337 llvm::MachO::segment_command_64 segment = {
6338 cmd_type, // uint32_t cmd;
6339 segment_size, // uint32_t cmdsize;
6340 {0}, // char segname[16];
6341 vm_addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
6342 vm_size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
6343 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
6344 vm_size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
6345 vm_prot, // uint32_t maxprot;
6346 vm_prot, // uint32_t initprot;
6347 0, // uint32_t nsects;
6348 0}; // uint32_t flags;
6349 segment_load_commands.push_back(segment);
6350 }
6351
6352 StreamString buffer(Stream::eBinary, byte_order);
6353
6354 llvm::MachO::mach_header_64 mach_header;
6355 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6356 mach_header.cputype = target_arch.GetMachOCPUType();
6357 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
6358 mach_header.filetype = MH_CORE;
6359 mach_header.ncmds = segment_load_commands.size();
6360 mach_header.flags = 0;
6361 mach_header.reserved = 0;
6362 ThreadList &thread_list = process_sp->GetThreadList();
6363 const uint32_t num_threads = thread_list.GetSize();
6364
6365 // Make an array of LC_THREAD data items. Each one contains the
6366 // contents of the LC_THREAD load command. The data doesn't contain
6367 // the load command + load command size, we will add the load command
6368 // and load command size as we emit the data.
6369 std::vector<StreamString> LC_THREAD_datas(num_threads);
6370 for (auto &LC_THREAD_data : LC_THREAD_datas) {
6371 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
6372 LC_THREAD_data.SetByteOrder(byte_order);
6373 }
6374 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6375 ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
6376 if (thread_sp) {
6377 switch (mach_header.cputype) {
6378 case llvm::MachO::CPU_TYPE_ARM64:
6379 case llvm::MachO::CPU_TYPE_ARM64_32:
6381 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6382 break;
6383
6384 case llvm::MachO::CPU_TYPE_ARM:
6386 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6387 break;
6388
6389 case llvm::MachO::CPU_TYPE_X86_64:
6391 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6392 break;
6393
6394 case llvm::MachO::CPU_TYPE_RISCV:
6396 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6397 break;
6398 }
6399 }
6400 }
6401
6402 // The size of the load command is the size of the segments...
6403 if (addr_byte_size == 8) {
6404 mach_header.sizeofcmds = segment_load_commands.size() *
6405 sizeof(llvm::MachO::segment_command_64);
6406 } else {
6407 mach_header.sizeofcmds = segment_load_commands.size() *
6408 sizeof(llvm::MachO::segment_command);
6409 }
6410
6411 // and the size of all LC_THREAD load command
6412 for (const auto &LC_THREAD_data : LC_THREAD_datas) {
6413 ++mach_header.ncmds;
6414 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6415 }
6416
6417 // Bits will be set to indicate which bits are NOT used in
6418 // addressing in this process or 0 for unknown.
6419 uint64_t address_mask = process_sp->GetCodeAddressMask();
6420 if (address_mask != LLDB_INVALID_ADDRESS_MASK) {
6421 // LC_NOTE "addrable bits"
6422 mach_header.ncmds++;
6423 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
6424 }
6425
6426 // LC_NOTE "process metadata"
6427 mach_header.ncmds++;
6428 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
6429
6430 // LC_NOTE "all image infos"
6431 mach_header.ncmds++;
6432 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
6433
6434 // Write the mach header
6435 buffer.PutHex32(mach_header.magic);
6436 buffer.PutHex32(mach_header.cputype);
6437 buffer.PutHex32(mach_header.cpusubtype);
6438 buffer.PutHex32(mach_header.filetype);
6439 buffer.PutHex32(mach_header.ncmds);
6440 buffer.PutHex32(mach_header.sizeofcmds);
6441 buffer.PutHex32(mach_header.flags);
6442 if (addr_byte_size == 8) {
6443 buffer.PutHex32(mach_header.reserved);
6444 }
6445
6446 // Skip the mach header and all load commands and align to the next
6447 // 0x1000 byte boundary
6448 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
6449
6450 file_offset = llvm::alignTo(file_offset, 16);
6451 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6452
6453 // Add "addrable bits" LC_NOTE when an address mask is available
6454 if (address_mask != LLDB_INVALID_ADDRESS_MASK) {
6455 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6456 new LCNoteEntry(byte_order));
6457 addrable_bits_lcnote_up->name = "addrable bits";
6458 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6459 int bits = std::bitset<64>(~address_mask).count();
6460 addrable_bits_lcnote_up->payload.PutHex32(4); // version
6461 addrable_bits_lcnote_up->payload.PutHex32(
6462 bits); // # of bits used for low addresses
6463 addrable_bits_lcnote_up->payload.PutHex32(
6464 bits); // # of bits used for high addresses
6465 addrable_bits_lcnote_up->payload.PutHex32(0); // reserved
6466
6467 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6468
6469 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6470 }
6471
6472 // Add "process metadata" LC_NOTE
6473 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6474 new LCNoteEntry(byte_order));
6475 thread_extrainfo_lcnote_up->name = "process metadata";
6476 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6477
6479 std::make_shared<StructuredData::Dictionary>());
6481 std::make_shared<StructuredData::Array>());
6482 for (const ThreadSP &thread_sp :
6483 process_sp->CalculateCoreFileThreadList(options)) {
6485 std::make_shared<StructuredData::Dictionary>());
6486 thread->AddIntegerItem("thread_id", thread_sp->GetID());
6487 threads->AddItem(thread);
6488 }
6489 dict->AddItem("threads", threads);
6490 StreamString strm;
6491 dict->Dump(strm, /* pretty */ false);
6492 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.GetData(),
6493 strm.GetSize());
6494
6495 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6496 file_offset = llvm::alignTo(file_offset, 16);
6497 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6498
6499 // Add "all image infos" LC_NOTE
6500 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6501 new LCNoteEntry(byte_order));
6502 all_image_infos_lcnote_up->name = "all image infos";
6503 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6504 file_offset = CreateAllImageInfosPayload(
6505 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6506 options);
6507 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6508
6509 // Add LC_NOTE load commands
6510 for (auto &lcnote : lc_notes) {
6511 // Add the LC_NOTE load command to the file.
6512 buffer.PutHex32(LC_NOTE);
6513 buffer.PutHex32(sizeof(llvm::MachO::note_command));
6514 char namebuf[16];
6515 memset(namebuf, 0, sizeof(namebuf));
6516 // This is the uncommon case where strncpy is exactly
6517 // the right one, doesn't need to be null-terminated.
6518 // LC_NOTE name field is char[16] and is not guaranteed to be
6519 // null-terminated.
6520 // coverity[buffer_size_warning]
6521 strncpy(namebuf, lcnote->name.c_str(), sizeof(namebuf));
6522 buffer.PutRawBytes(namebuf, sizeof(namebuf));
6523 buffer.PutHex64(lcnote->payload_file_offset);
6524 buffer.PutHex64(lcnote->payload.GetSize());
6525 }
6526
6527 // Align to 4096-byte page boundary for the LC_SEGMENTs.
6528 file_offset = llvm::alignTo(file_offset, 4096);
6529
6530 for (auto &segment : segment_load_commands) {
6531 segment.fileoff = file_offset;
6532 file_offset += segment.filesize;
6533 }
6534
6535 // Write out all of the LC_THREAD load commands
6536 for (const auto &LC_THREAD_data : LC_THREAD_datas) {
6537 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6538 buffer.PutHex32(LC_THREAD);
6539 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
6540 buffer.Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6541 }
6542
6543 // Write out all of the segment load commands
6544 for (const auto &segment : segment_load_commands) {
6545 buffer.PutHex32(segment.cmd);
6546 buffer.PutHex32(segment.cmdsize);
6547 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
6548 if (addr_byte_size == 8) {
6549 buffer.PutHex64(segment.vmaddr);
6550 buffer.PutHex64(segment.vmsize);
6551 buffer.PutHex64(segment.fileoff);
6552 buffer.PutHex64(segment.filesize);
6553 } else {
6554 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
6555 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
6556 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
6557 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
6558 }
6559 buffer.PutHex32(segment.maxprot);
6560 buffer.PutHex32(segment.initprot);
6561 buffer.PutHex32(segment.nsects);
6562 buffer.PutHex32(segment.flags);
6563 }
6564
6565 std::string core_file_path(outfile.GetPath());
6566 auto core_file = FileSystem::Instance().Open(
6569 if (!core_file) {
6570 error = Status::FromError(core_file.takeError());
6571 } else {
6572 // Read 1 page at a time
6573 uint8_t bytes[0x1000];
6574 // Write the mach header and load commands out to the core file
6575 size_t bytes_written = buffer.GetString().size();
6576 error =
6577 core_file.get()->Write(buffer.GetString().data(), bytes_written);
6578 if (error.Success()) {
6579
6580 for (auto &lcnote : lc_notes) {
6581 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6582 -1) {
6584 "Unable to seek to corefile pos "
6585 "to write '%s' LC_NOTE payload",
6586 lcnote->name.c_str());
6587 return false;
6588 }
6589 bytes_written = lcnote->payload.GetSize();
6590 error = core_file.get()->Write(lcnote->payload.GetData(),
6591 bytes_written);
6592 if (!error.Success())
6593 return false;
6594 }
6595
6596 // Now write the file data for all memory segments in the process
6597 for (const auto &segment : segment_load_commands) {
6598 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6600 "unable to seek to offset 0x%" PRIx64 " in '%s'",
6601 segment.fileoff, core_file_path.c_str());
6602 break;
6603 }
6604
6605 target.GetDebugger().GetAsyncOutputStream()->Printf(
6606 "Saving %" PRId64
6607 " bytes of data for memory region at 0x%" PRIx64 "\n",
6608 segment.vmsize, segment.vmaddr);
6609 addr_t bytes_left = segment.vmsize;
6610 addr_t addr = segment.vmaddr;
6612 while (bytes_left > 0 && error.Success()) {
6613 const size_t bytes_to_read =
6614 bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
6615
6616 // In a savecore setting, we don't really care about caching,
6617 // as the data is dumped and very likely never read again,
6618 // so we call ReadMemoryFromInferior to bypass it.
6619 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6620 addr, bytes, bytes_to_read, memory_read_error);
6621
6622 if (bytes_read == bytes_to_read) {
6623 size_t bytes_written = bytes_read;
6624 error = core_file.get()->Write(bytes, bytes_written);
6625 bytes_left -= bytes_read;
6626 addr += bytes_read;
6627 } else {
6628 // Some pages within regions are not readable, those should
6629 // be zero filled
6630 memset(bytes, 0, bytes_to_read);
6631 size_t bytes_written = bytes_to_read;
6632 error = core_file.get()->Write(bytes, bytes_written);
6633 bytes_left -= bytes_to_read;
6634 addr += bytes_to_read;
6635 }
6636 }
6637 }
6638 }
6639 }
6640 }
6641 }
6642 return true; // This is the right plug to handle saving core files for
6643 // this process
6644 }
6645 return false;
6646}
6647
6650 MachOCorefileAllImageInfos image_infos;
6653
6654 auto lc_notes = FindLC_NOTEByName("all image infos");
6655 for (auto lc_note : lc_notes) {
6656 offset_t payload_offset = std::get<0>(lc_note);
6657 // Read the struct all_image_infos_header.
6658 uint32_t version = m_data_nsp->GetU32(&payload_offset);
6659 if (version != 1) {
6660 return image_infos;
6661 }
6662 uint32_t imgcount = m_data_nsp->GetU32(&payload_offset);
6663 uint64_t entries_fileoff = m_data_nsp->GetU64(&payload_offset);
6664 // 'entries_size' is not used, nor is the 'unused' entry.
6665 // offset += 4; // uint32_t entries_size;
6666 // offset += 4; // uint32_t unused;
6667
6668 LLDB_LOGF(log, "LC_NOTE 'all image infos' found version %d with %d images",
6669 version, imgcount);
6670 payload_offset = entries_fileoff;
6671 for (uint32_t i = 0; i < imgcount; i++) {
6672 // Read the struct image_entry.
6673 offset_t filepath_offset = m_data_nsp->GetU64(&payload_offset);
6674 uuid_t uuid;
6675 memcpy(&uuid, m_data_nsp->GetData(&payload_offset, sizeof(uuid_t)),
6676 sizeof(uuid_t));
6677 uint64_t load_address = m_data_nsp->GetU64(&payload_offset);
6678 offset_t seg_addrs_offset = m_data_nsp->GetU64(&payload_offset);
6679 uint32_t segment_count = m_data_nsp->GetU32(&payload_offset);
6680 uint32_t currently_executing = m_data_nsp->GetU32(&payload_offset);
6681
6683 image_entry.filename =
6684 (const char *)m_data_nsp->GetCStr(&filepath_offset);
6685 image_entry.uuid = UUID(uuid, sizeof(uuid_t));
6686 image_entry.load_address = load_address;
6687 image_entry.currently_executing = currently_executing;
6688
6689 offset_t seg_vmaddrs_offset = seg_addrs_offset;
6690 for (uint32_t j = 0; j < segment_count; j++) {
6691 char segname[17];
6692 m_data_nsp->CopyData(seg_vmaddrs_offset, 16, segname);
6693 segname[16] = '\0';
6694 seg_vmaddrs_offset += 16;
6695 uint64_t vmaddr = m_data_nsp->GetU64(&seg_vmaddrs_offset);
6696 seg_vmaddrs_offset += 8; /* unused */
6697
6698 std::tuple<ConstString, addr_t> new_seg{ConstString(segname), vmaddr};
6699 image_entry.segment_load_addresses.push_back(new_seg);
6700 }
6701 LLDB_LOGF(log, " image entry: %s %s 0x%" PRIx64 " %s",
6702 image_entry.filename.c_str(),
6703 image_entry.uuid.GetAsString().c_str(),
6705 image_entry.currently_executing ? "currently executing"
6706 : "not currently executing");
6707 image_infos.all_image_infos.push_back(image_entry);
6708 }
6709 }
6710
6711 lc_notes = FindLC_NOTEByName("load binary");
6712 for (auto lc_note : lc_notes) {
6713 offset_t payload_offset = std::get<0>(lc_note);
6714 uint32_t version = m_data_nsp->GetU32(&payload_offset);
6715 if (version == 1) {
6716 uuid_t uuid;
6717 memcpy(&uuid, m_data_nsp->GetData(&payload_offset, sizeof(uuid_t)),
6718 sizeof(uuid_t));
6719 uint64_t load_address = m_data_nsp->GetU64(&payload_offset);
6720 uint64_t slide = m_data_nsp->GetU64(&payload_offset);
6721 std::string filename = m_data_nsp->GetCStr(&payload_offset);
6722
6724 image_entry.filename = filename;
6725 image_entry.uuid = UUID(uuid, sizeof(uuid_t));
6726 image_entry.load_address = load_address;
6727 image_entry.slide = slide;
6728 image_entry.currently_executing = true;
6729 image_infos.all_image_infos.push_back(image_entry);
6730 LLDB_LOGF(log,
6731 "LC_NOTE 'load binary' found, filename %s uuid %s load "
6732 "address 0x%" PRIx64 " slide 0x%" PRIx64,
6733 filename.c_str(),
6734 image_entry.uuid.IsValid()
6735 ? image_entry.uuid.GetAsString().c_str()
6736 : "00000000-0000-0000-0000-000000000000",
6737 load_address, slide);
6738 }
6739 }
6740
6741 return image_infos;
6742}
6743
6747
6748 bool found_platform_binary = false;
6749 ModuleList added_modules;
6750
6751 llvm::SmallVector<const MachOCorefileImageEntry *> pending_images;
6752 std::vector<DynamicLoader::BinarySpec> pending_specs;
6753
6754 for (MachOCorefileImageEntry &image : image_infos.all_image_infos) {
6755 // If this is a platform binary, it has been loaded (or registered with
6756 // the DynamicLoader to be loaded), we don't need to do any further
6757 // processing. We're not going to call ModulesDidLoad on this in this
6758 // method, so notify==true.
6759 //
6760 // Setting up a platform binary can replace the Target's platform and
6761 // dynamic loader, so no image is searched for until this loop has run to
6762 // the end.
6763 if (process.GetTarget()
6764 .GetDebugger()
6767 true /* notify */)) {
6768 LLDB_LOGF(log,
6769 "ObjectFileMachO::%s binary at 0x%" PRIx64
6770 " is a platform binary, has been handled by a Platform plugin.",
6771 __FUNCTION__, image.load_address);
6772 found_platform_binary = true;
6773 continue;
6774 }
6775
6776 bool value_is_offset = image.load_address == LLDB_INVALID_ADDRESS;
6777 uint64_t value = value_is_offset ? image.slide : image.load_address;
6778 if (value_is_offset && value == LLDB_INVALID_ADDRESS) {
6779 // We have neither address nor slide; so we will find the binary
6780 // by UUID and load it at slide/offset 0.
6781 value = 0;
6782 }
6783
6784 // We have either a UUID, or we have a load address which
6785 // and can try to read load commands and find a UUID.
6786 if (!image.uuid.IsValid() &&
6787 (value_is_offset || value == LLDB_INVALID_ADDRESS))
6788 continue;
6789
6791 bin_spec.name = image.filename;
6792 bin_spec.uuid = image.uuid;
6793 bin_spec.value = value;
6794 bin_spec.value_is_offset = value_is_offset;
6796 bin_spec.notify = false;
6797 // Userland Darwin binaries will have segment load addresses via
6798 // the `all image infos` LC_NOTE.
6799 bin_spec.set_address_in_target = image.segment_load_addresses.empty();
6801 !image.segment_load_addresses.empty();
6802
6803 pending_images.push_back(&image);
6804 pending_specs.push_back(std::move(bin_spec));
6805 }
6806
6807 DynamicLoader::LocateBinaries(&process, pending_specs);
6808
6809 for (auto [image, bin_spec] :
6810 llvm::zip_equal(pending_images, pending_specs)) {
6811 ModuleSP module_sp;
6812 if (llvm::Expected<ModuleSP> loaded =
6813 DynamicLoader::LoadBinaryInTarget(&process, bin_spec)) {
6814 module_sp = *loaded;
6815 } else if (bin_spec.force_symbol_search) {
6817 << llvm::toString(loaded.takeError()) << "\n";
6818 } else {
6819 // A corefile image that isn't on this machine is routine, and has
6820 // already been logged.
6821 llvm::consumeError(loaded.takeError());
6822 }
6823
6824 if (!module_sp)
6825 continue;
6826
6827 added_modules.Append(module_sp, false /* notify */);
6828
6829 // We have a list of segment load address
6830 if (image->segment_load_addresses.size() > 0) {
6831 if (log) {
6832 std::string uuidstr = image->uuid.GetAsString();
6833 log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
6834 "UUID %s with section load addresses",
6835 module_sp->GetFileSpec().GetPath().c_str(),
6836 uuidstr.c_str());
6837 }
6838 ObjectFile *objfile = module_sp->GetObjectFile();
6839 SectionList *sectlist = objfile ? objfile->GetSectionList() : nullptr;
6840 for (auto name_vmaddr_tuple : image->segment_load_addresses) {
6841 if (sectlist) {
6842 SectionSP sect_sp =
6843 sectlist->FindSectionByName(std::get<0>(name_vmaddr_tuple));
6844 if (sect_sp) {
6846 sect_sp, std::get<1>(name_vmaddr_tuple));
6847 }
6848 }
6849 }
6850 } else {
6851 if (log) {
6852 std::string uuidstr = image->uuid.GetAsString();
6853 log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
6854 "UUID %s with %s 0x%" PRIx64,
6855 module_sp->GetFileSpec().GetPath().c_str(), uuidstr.c_str(),
6856 bin_spec.value_is_offset ? "slide" : "load address",
6857 bin_spec.value);
6858 }
6859 bool changed;
6860 module_sp->SetLoadAddress(process.GetTarget(), bin_spec.value,
6861 bin_spec.value_is_offset, changed);
6862 }
6863 }
6864
6865 if (added_modules.GetSize() > 0) {
6866 process.GetTarget().ModulesDidLoad(added_modules);
6867 process.Flush();
6868 return true;
6869 }
6870 // Return true if the only binary we found was the platform binary,
6871 // and it was loaded outside the scope of this method.
6872 if (found_platform_binary)
6873 return true;
6874
6875 // No binaries.
6876 return false;
6877}
unsigned char uuid_t[16]
static llvm::raw_ostream & error(Stream &strm)
void dyld_shared_cache_copy_uuid(dyld_shared_cache_t cache, uuid_t *uuid)
struct dyld_image_s * dyld_image_t
struct dyld_shared_cache_s * dyld_shared_cache_t
bool dyld_image_copy_uuid(dyld_image_t cache, uuid_t *uuid)
void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache, void(^block)(dyld_image_t image))
static const char * memory_read_error
#define lldbassert(x)
Definition LLDBAssert.h:16
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_LOGF(log,...)
Definition Log.h:389
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
static bool ReadMachOCommand(DataExtractor &data, lldb::offset_t &offset, T &cmd)
Read a Mach-O load-command header (cmd + cmdsize) from data at offset into cmd, advancing offset by 8...
static uint32_t MachHeaderSizeFromMagic(uint32_t magic)
static uint32_t GetSegmentPermissions(const llvm::MachO::segment_command_64 &seg_cmd)
static constexpr llvm::StringLiteral g_loader_path
static std::optional< struct nlist_64 > ParseNList(DataExtractor &nlist_data, lldb::offset_t &nlist_data_offset, size_t nlist_byte_size)
static bool ReadMachOCommand(const DataExtractor &data, lldb::offset_t &offset, T &cmd)
Read a Mach-O load-command header (cmd + cmdsize) from data at offset into cmd, advancing offset by 8...
static constexpr llvm::StringLiteral g_executable_path
static void PrintRegisterValue(RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
static llvm::Expected< std::string > ReadLCNotePayload(const DataExtractor &data, lldb::offset_t offset, uint64_t size)
Return the payload of an LC_NOTE, decompressing it if needed.
static lldb::SectionType GetSectionType(uint32_t flags, llvm::StringRef section_name)
static llvm::StringRef GetOSName(uint32_t cmd)
static llvm::VersionTuple FindMinimumVersionInfo(DataExtractor &data, lldb::offset_t offset, size_t ncmds)
unsigned int mach_task_self()
#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB
@ NonDebugSymbols
@ DebugSymbols
void * dyld_process_info
static uint32_t MachHeaderSizeFromMagic(uint32_t magic)
static offset_t CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp, offset_t initial_file_offset, StreamString &all_image_infos_payload, lldb_private::SaveCoreOptions &options)
static bool TryParseV2ObjCMetadataSymbol(const char *&symbol_name, const char *&symbol_name_non_abi_mangled, SymbolType &type)
static SymbolType GetSymbolType(const char *&symbol_name, bool &demangled_is_synthesized, const SectionSP &text_section_sp, const SectionSP &data_section_sp, const SectionSP &data_dirty_section_sp, const SectionSP &data_const_section_sp, const SectionSP &symbol_section)
#define LLDB_PLUGIN_DEFINE(PluginName)
#define KERN_SUCCESS
Constants returned by various RegisterContextDarwin_*** functions.
#define LLDB_SCOPED_TIMERF(...)
Definition Timer.h:86
static llvm::StringRef GetName(XcodeSDK::Type type)
Definition XcodeSDK.cpp:21
std::vector< SectionInfo > m_section_infos
SectionSP GetSection(uint8_t n_sect, addr_t file_addr)
MachSymtabSectionInfo(SectionList *section_list)
bool SectionIsLoadable(const lldb_private::Section *section)
llvm::MachO::mach_header m_header
bool m_allow_assembly_emulation_unwind_plans
std::optional< llvm::VersionTuple > m_min_os_version
lldb_private::AddressableBits GetAddressableBits() override
Some object files may have the number of bits used for addressing embedded in them,...
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override
Extract the dependent modules from an object file.
static lldb_private::ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
FileRangeArray m_thread_context_offsets
ObjectFile::Type CalculateType() override
The object file should be able to calculate its type by looking at its file header and possibly the s...
lldb_private::RangeVector< uint32_t, uint32_t, 8 > EncryptedFileRanges
static bool MagicBytesMatch(lldb::DataExtractorSP extractor_sp, lldb::addr_t offset, lldb::addr_t length)
std::vector< std::tuple< lldb::offset_t, lldb::offset_t > > FindLC_NOTEByName(std::string name)
void Dump(lldb_private::Stream *s) override
Dump a description of this object to a Stream.
bool AllowAssemblyEmulationUnwindPlans() override
Returns if the function bounds for symbols in this symbol file are likely accurate.
std::string GetIdentifierString() override
Some object files may have an identifier string embedded in them, e.g.
void ProcessSegmentCommand(const llvm::MachO::load_command &load_cmd, lldb::offset_t offset, uint32_t cmd_idx, SegmentParsingContext &context)
std::vector< llvm::MachO::section_64 > m_mach_sections
static llvm::StringRef GetSegmentNameLINKEDIT()
bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override
Sets the load address for an entire module, assuming a rigid slide of sections, if possible in the im...
void GetProcessSharedCacheUUID(lldb_private::Process *, lldb::addr_t &base_addr, lldb_private::UUID &uuid)
Intended for same-host arm device debugging where lldb needs to detect libraries in the shared cache ...
bool IsGOTSection(const lldb_private::Section &section) const override
Returns true if the section is a global offset table section.
bool GetIsDynamicLinkEditor() override
Return true if this file is a dynamic link editor (dyld)
lldb::ByteOrder GetByteOrder() const override
Gets whether endian swapping should occur when extracting data from this object file.
bool ParseHeader() override
Attempts to parse the object header.
bool IsStripped() override
Detect if this object file has been stripped of local symbols.
lldb_private::UUID GetUUID() override
Gets the UUID for this object file.
llvm::VersionTuple GetMinimumOSVersion() override
Get the minimum OS version this object file can run on.
static llvm::StringRef GetPluginDescriptionStatic()
static llvm::StringRef GetPluginNameStatic()
lldb::RegisterContextSP GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override
lldb_private::FileSpecList m_reexported_dylibs
static void GetAllArchSpecs(const llvm::MachO::mach_header &header, const lldb_private::DataExtractor &data, lldb::offset_t lc_offset, lldb_private::ModuleSpec &base_spec, lldb_private::ModuleSpecList &all_specs)
Enumerate all ArchSpecs supported by this Mach-O file.
bool GetCorefileThreadExtraInfos(std::vector< lldb::tid_t > &tids) override
Get metadata about thread ids from the corefile.
static llvm::StringRef GetSectionNameEHFrame()
bool IsDynamicLoader() const
static void Terminate()
bool IsExecutable() const override
Tells whether this object file is capable of being the main executable for a process.
lldb_private::Address GetEntryPointAddress() override
Returns the address of the Entry Point in this object file - if the object file doesn't have an entry...
lldb_private::Address m_entry_point_address
static void Initialize()
bool LoadCoreFileImages(lldb_private::Process &process) override
Load binaries listed in a corefile.
bool CanTrustAddressRanges() override
Can we trust the address ranges accelerator associated with this object file to be complete.
void SanitizeSegmentCommand(llvm::MachO::segment_command_64 &seg_cmd, uint32_t cmd_idx)
static lldb_private::ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
bool IsSharedCacheBinary() const
llvm::VersionTuple GetSDKVersion() override
Get the SDK OS version this object file was built with.
lldb_private::ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
lldb_private::Address GetBaseAddress() override
Returns base address of this object file.
size_t ParseSymtab()
static llvm::StringRef GetSectionNameLLDBNoNlist()
lldb::addr_t m_text_address
uint32_t GetAddressByteSize() const override
Gets the address size in bytes for the current object file.
static lldb_private::ModuleSpecList GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp, lldb::offset_t file_offset, lldb::offset_t length)
static llvm::StringRef GetSegmentNameDATA()
llvm::MachO::dysymtab_command m_dysymtab
bool GetCorefileMainBinaryInfo(lldb::addr_t &value, bool &value_is_offset, lldb_private::UUID &uuid, ObjectFile::BinaryType &type) override
static llvm::StringRef GetSegmentNameDATA_DIRTY()
static bool SaveCore(const lldb::ProcessSP &process_sp, lldb_private::SaveCoreOptions &options, lldb_private::Status &error)
void ProcessDysymtabCommand(const llvm::MachO::load_command &load_cmd, lldb::offset_t offset)
static llvm::StringRef GetSegmentNameLLVM_COV()
MachOCorefileAllImageInfos GetCorefileAllImageInfos()
Get the list of binary images that were present in the process when the corefile was produced.
lldb::addr_t CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const lldb_private::Section *mach_header_section, const lldb_private::Section *section)
bool m_thread_context_offsets_valid
ObjectFile::Strata CalculateStrata() override
The object file should be able to calculate the strata of the object file.
void CreateSections(lldb_private::SectionList &unified_section_list) override
static llvm::StringRef GetSegmentNameDATA_CONST()
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override
Get the address type given a file address in an object file.
lldb_private::StructuredData::ObjectSP GetCorefileProcessMetadata() override
Get process metadata from the corefile in a StructuredData dictionary.
static llvm::StringRef GetSegmentNameOBJC()
std::optional< llvm::VersionTuple > m_sdk_versions
ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
void GetLLDBSharedCacheUUID(lldb::addr_t &base_addir, lldb_private::UUID &uuid)
Intended for same-host arm device debugging where lldb will read shared cache libraries out of its ow...
llvm::VersionTuple GetVersion() override
Get the object file version numbers.
EncryptedFileRanges GetEncryptedFileRanges()
uint32_t GetNumThreadContexts() override
static llvm::StringRef GetSegmentNameDWARF()
static llvm::StringRef GetSegmentNameTEXT()
lldb::offset_t m_linkedit_original_offset
lldb_private::Section * GetMachHeaderSection()
int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
RegisterContextDarwin_arm64_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
bool SetError(int flavor, uint32_t err_idx, int err)
RegisterContextDarwin_arm64(lldb_private::Thread &thread, uint32_t concrete_frame_idx)
RegisterContextDarwin_arm_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
RegisterContextDarwin_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx)
bool SetError(int flavor, uint32_t err_idx, int err)
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
int DoWriteCSR(lldb::tid_t tid, int flavor, const CSR &csr) override
RegisterContextDarwin_riscv32_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoReadCSR(lldb::tid_t tid, int flavor, CSR &csr) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
RegisterContextDarwin_riscv32(lldb_private::Thread &thread, uint32_t concrete_frame_idx)
bool SetError(int flavor, uint32_t err_idx, int err)
RegisterContextDarwin_x86_64_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
RegisterContextDarwin_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx)
bool SetError(int flavor, uint32_t err_idx, int err)
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:303
lldb::SectionSP GetSection() const
Get const accessor for the section.
Definition Address.h:426
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:283
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:894
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:455
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:547
bool IsAlwaysThumbInstructions() const
Detect whether this architecture uses thumb code exclusively.
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
uint32_t GetMachOCPUSubType() const
Definition ArchSpec.cpp:878
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
Definition ArchSpec.h:599
uint32_t GetMachOCPUType() const
Definition ArchSpec.cpp:874
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:943
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:886
A uniqued constant string class.
Definition ConstString.h:40
const char * GetCString() const
Get the string value as a C string.
const char * AsCString(const char *value_if_empty) const
Get the string value as a C string.
void GetFunctionAddressAndSizeVector(FunctionAddressAndSizeVector &function_info)
RangeVector< lldb::addr_t, uint32_t > FunctionAddressAndSizeVector
An data extractor class.
virtual uint32_t GetU32_unchecked(lldb::offset_t *offset_ptr) const
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
bool ValidOffsetForDataOfSize(lldb::offset_t offset, lldb::offset_t length) const
Test the availability of length bytes of data from offset.
virtual const uint8_t * PeekData(lldb::offset_t offset, lldb::offset_t length) const
Peek at a bytes at offset.
virtual uint64_t GetByteSize() const
Get the number of bytes contained in this object.
uint64_t GetAddress_unchecked(lldb::offset_t *offset_ptr) const
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
virtual uint8_t GetU8_unchecked(lldb::offset_t *offset_ptr) const
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
virtual uint16_t GetU16_unchecked(lldb::offset_t *offset_ptr) const
std::optional< llvm::StringRef > PeekCStr(lldb::offset_t offset) const
Peek at a null-terminated C string at offset.
size_t ExtractBytes(lldb::offset_t offset, lldb::offset_t length, lldb::ByteOrder dst_byte_order, void *dst) const
Extract an arbitrary number of bytes in the specified byte order.
lldb::StreamUP GetAsyncErrorStream()
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
PlatformList & GetPlatformList()
Definition Debugger.h:227
lldb::StreamUP GetAsyncOutputStream()
A plug-in interface definition class for dynamic loaders.
static void LocateBinaries(Process *process, llvm::MutableArrayRef< BinarySpec > bin_specs)
Search for a batch of binaries, without mutating the Target.
virtual bool GetSharedCacheInformation(lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache, LazyBool &private_shared_cache, lldb_private::FileSpec &shared_cache_path, std::optional< uint64_t > &size)
Get information about the shared cache for a process, if possible.
static llvm::Expected< lldb::ModuleSP > LoadBinaryInTarget(Process *process, BinarySpec &bin_spec)
Add a binary that LocateBinaries searched for to the Target, and set its load address.
A file collection class.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
void Append(const FileSpec &file)
Append a FileSpec object to the list.
size_t GetSize() const
Get the number of files in the file list.
bool AppendIfUnique(const FileSpec &file)
Append a FileSpec object if unique.
A file utility class.
Definition FileSpec.h:56
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
Definition FileSpec.cpp:425
void ClearDirectory()
Clear the directory in this object.
Definition FileSpec.cpp:373
llvm::StringRef GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:248
llvm::StringRef GetDirectory() const
Directory string const get accessor.
Definition FileSpec.h:233
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
FileSpec CopyByRemovingLastPathComponent() const
Definition FileSpec.cpp:431
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
void void Printf(const char *format,...) __attribute__((format(printf
Prefer using LLDB_LOGF whenever possible.
Definition Log.cpp:177
A class that handles mangled names.
Definition Mangled.h:34
void SetDemangledName(ConstString name)
Definition Mangled.h:162
ConstString GetDemangledName() const
Demangled name get accessor.
Definition Mangled.cpp:171
void SetMangledName(ConstString name)
Definition Mangled.h:164
void SetValue(ConstString name)
Set the string value in this object.
Definition Mangled.cpp:123
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition Mangled.cpp:257
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A collection class for Module objects.
Definition ModuleList.h:128
void Clear()
Clear the object's state.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
size_t GetSize() const
Gets the size of the module list.
void Append(const ModuleSpec &spec)
Definition ModuleSpec.h:371
ModuleSpec & GetModuleSpecRefAtIndex(size_t i)
Definition ModuleSpec.h:384
void SetObjectSize(uint64_t object_size)
Definition ModuleSpec.h:119
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
void SetObjectOffset(uint64_t object_offset)
Definition ModuleSpec.h:113
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
std::unique_ptr< lldb_private::SectionList > m_sections_up
Definition ObjectFile.h:786
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
std::unique_ptr< lldb_private::Symtab > m_symtab_up
Definition ObjectFile.h:789
const lldb::addr_t m_memory_addr
Set if the object file only exists in memory.
Definition ObjectFile.h:784
static lldb::SectionType GetDWARFSectionTypeFromName(llvm::StringRef name)
Parses the section type from a section name for DWARF sections.
Symtab * GetSymtab(bool can_create=true)
Gets the symbol table for the currently selected architecture (and object for archives).
DataExtractorNSP m_data_nsp
The data for this object file so things can be parsed lazily.
Definition ObjectFile.h:778
static lldb::WritableDataBufferSP ReadMemory(const lldb::ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
@ eTypeExecutable
A normal executable.
Definition ObjectFile.h:55
@ eTypeDebugInfo
An object file that contains only debug information.
Definition ObjectFile.h:57
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
Definition ObjectFile.h:65
@ eTypeObjectFile
An intermediate object file.
Definition ObjectFile.h:61
@ eTypeDynamicLinker
The platform's dynamic linker executable.
Definition ObjectFile.h:59
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
Definition ObjectFile.h:53
@ eTypeSharedLibrary
A shared library that can be used during execution.
Definition ObjectFile.h:63
lldb::addr_t m_file_offset
The offset in bytes into the file, or the address in memory.
Definition ObjectFile.h:773
static lldb::SymbolType GetSymbolTypeFromName(llvm::StringRef name, lldb::SymbolType symbol_type_hint=lldb::eSymbolTypeUndefined)
bool SetModulesArchitecture(const ArchSpec &new_arch)
Sets the architecture for a module.
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition ObjectFile.h:281
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
bool IsInMemory() const
Returns true if the object file exists only in memory.
Definition ObjectFile.h:692
lldb::ProcessWP m_process_wp
Definition ObjectFile.h:782
lldb::addr_t m_length
The length of this object file if it is known (can be zero if length is unknown or can't be determine...
Definition ObjectFile.h:775
BinaryType
If we have a corefile binary hint, this enum specifies the binary type which we can use to select the...
Definition ObjectFile.h:83
@ eBinaryTypeKernel
kernel binary
Definition ObjectFile.h:87
@ eBinaryTypeUser
user process binary, dyld addr
Definition ObjectFile.h:89
@ eBinaryTypeUserAllImageInfos
user process binary, dyld_all_image_infos addr
Definition ObjectFile.h:91
@ eBinaryTypeStandalone
standalone binary / firmware
Definition ObjectFile.h:93
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
Definition ObjectFile.h:469
bool LoadPlatformBinaryAndSetup(Process *process, lldb::addr_t addr, bool notify)
Detect a binary in memory that will determine which Platform and DynamicLoader should be used in this...
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
Definition Process.h:369
void Flush()
Flush all data in the process.
Definition Process.cpp:6273
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
Definition Process.cpp:3125
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1270
A Progress indicator helper class.
Definition Progress.h:60
const Entry * FindEntryThatContains(B addr) const
Definition RangeMap.h:338
const Entry * GetEntryAtIndex(size_t i) const
Definition RangeMap.h:297
void Append(const Entry &entry)
Definition RangeMap.h:179
size_t GetSize() const
Definition RangeMap.h:295
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
const void * GetBytes() const
const std::optional< lldb_private::FileSpec > GetOutputFile() const
lldb::SaveCoreStyle GetStyle() const
void SetStyle(lldb::SaveCoreStyle style)
size_t GetNumSections(uint32_t depth) const
Definition Section.cpp:544
size_t GetSize() const
Definition Section.h:76
lldb::SectionSP FindSectionByName(llvm::StringRef section_name) const
Definition Section.cpp:562
size_t AddSection(const lldb::SectionSP &section_sp)
Definition Section.cpp:483
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
Definition Section.cpp:648
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition Section.cpp:555
bool IsThreadSpecific() const
Definition Section.h:220
lldb::SectionSP GetParent() const
Definition Section.h:218
lldb::offset_t GetFileOffset() const
Definition Section.h:180
llvm::StringRef GetName() const
Definition Section.h:210
lldb::addr_t GetFileAddress() const
Definition Section.cpp:194
ObjectFile * GetObjectFile()
Definition Section.h:230
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
Definition Stream.h:111
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:405
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition Stream.cpp:157
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:307
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
size_t PutChar(char ch)
Definition Stream.cpp:131
@ eBinary
Get and put data as binary instead of as the default string mode.
Definition Stream.h:32
size_t PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:291
size_t PutRawBytes(const void *s, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:364
unsigned GetIndentLevel() const
Get the current indentation level.
Definition Stream.cpp:193
std::optional< Dictionary * > GetItemAtIndexAsDictionary(size_t idx) const
Retrieves the element at index idx from a StructuredData::Array if it is a Dictionary.
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
std::shared_ptr< Array > ArraySP
Defines a list of symbol context objects.
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
uint32_t GetSize() const
Get accessor for a symbol context list size.
Defines a symbol context baton that can be handed other debug core functions.
Symbol * symbol
The Symbol for a given query.
bool ValueIsAddress() const
Definition Symbol.cpp:191
void SetReExportedSymbolName(ConstString name)
Definition Symbol.cpp:221
void SetType(lldb::SymbolType type)
Definition Symbol.h:199
void SetSizeIsSibling(bool b)
Definition Symbol.h:248
Mangled & GetMangled()
Definition Symbol.h:162
Address & GetAddressRef()
Definition Symbol.h:78
uint32_t GetFlags() const
Definition Symbol.h:203
bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
Definition Symbol.cpp:230
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:469
lldb::SymbolType GetType() const
Definition Symbol.h:197
void SetFlags(uint32_t flags)
Definition Symbol.h:205
Address GetAddress() const
Definition Symbol.h:98
void SetByteSize(lldb::addr_t size)
Definition Symbol.h:241
void SetDemangledNameIsSynthesized(bool b)
Definition Symbol.h:265
void SetExternal(bool b)
Definition Symbol.h:227
void SetDebug(bool b)
Definition Symbol.h:223
void SetID(uint32_t uid)
Definition Symbol.h:160
Symbol * SymbolAtIndex(size_t idx)
Definition Symtab.cpp:226
Symbol * FindFirstSymbolWithNameAndType(ConstString name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
Definition Symtab.cpp:842
Symbol * Resize(size_t count)
Definition Symtab.cpp:55
Symbol * FindSymbolContainingFileAddress(lldb::addr_t file_addr)
Definition Symtab.cpp:1012
size_t GetNumSymbols() const
Definition Symtab.cpp:75
MemoryModuleLoadLevel GetMemoryModuleLoadLevel() const
Definition Target.cpp:5854
void ModulesDidLoad(ModuleList &module_list)
This call may preload module symbols, and may do so in parallel depending on the following target set...
Definition Target.cpp:1975
Debugger & GetDebugger() const
Definition Target.h:1365
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1282
const ArchSpec & GetArchitecture() const
Definition Target.h:1324
bool SetSectionLoadAddress(const lldb::SectionSP &section, lldb::addr_t load_addr, bool warn_multiple=false)
Definition Target.cpp:3532
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
Represents UUID's of various sizes.
Definition UUID.h:27
void Clear()
Definition UUID.h:62
std::string GetAsString(llvm::StringRef separator="-") const
Definition UUID.cpp:54
bool IsValid() const
Definition UUID.h:69
#define UINT64_MAX
#define LLDB_INVALID_ADDRESS_MASK
Address Mask Bits not used for addressing are set to 1 in the mask; all mask bits set is an invalid v...
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
lldb::ByteOrder InlHostByteOrder()
Definition Endian.h:25
A class that represents a running process on the host machine.
constexpr uint64_t THUMB_ADDRESS_BIT_MASK
Mask that clears the low Thumb bit from an ARM function address.
Definition MachOTrie.h:30
bool ParseTrieEntries(DataExtractor &data, const bool is_arm, lldb::addr_t text_seg_base_addr, std::set< lldb::addr_t > &resolver_addresses, std::vector< TrieEntryWithOffset > &reexports, std::vector< TrieEntryWithOffset > &ext_symbols)
Parse the Mach-O export trie (the dyld symbol trie from LC_DYLD_INFO or LC_DYLD_EXPORTS_TRIE) startin...
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
constexpr uint64_t TRIE_SYMBOL_IS_THUMB
Set on TrieEntry::flags for an ARM symbol whose address has the low Thumb bit set; the bit is strippe...
Definition MachOTrie.h:27
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition ARMUtils.h:265
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
uint64_t offset_t
Definition lldb-types.h:86
std::shared_ptr< lldb_private::Process > ProcessSP
SymbolType
Symbol types.
@ eSymbolTypeUndefined
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeReExported
@ eSymbolTypeObjCClass
@ eSymbolTypeObjectFile
@ eSymbolTypeTrampoline
@ eSymbolTypeResolver
@ eSymbolTypeSourceFile
@ eSymbolTypeException
@ eSymbolTypeVariable
@ eSymbolTypeAbsolute
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
@ eSymbolTypeHeaderFile
@ eSymbolTypeCommonBlock
@ eSymbolTypeCompiler
@ eSymbolTypeLineHeader
@ eSymbolTypeObjCIVar
@ eSymbolTypeLineEntry
@ eSymbolTypeScopeBegin
@ eSymbolTypeScopeEnd
ByteOrder
Byte ordering definitions.
uint64_t user_id_t
Definition lldb-types.h:83
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
@ eSectionTypeDWARFDebugStrOffsets
@ eSectionTypeELFDynamicSymbols
Elf SHT_DYNSYM section.
@ eSectionTypeInvalid
@ eSectionTypeDWARFDebugPubNames
@ eSectionTypeDataObjCCFStrings
Objective-C const CFString/NSString objects.
@ eSectionTypeZeroFill
@ eSectionTypeDWARFDebugLocDwo
@ eSectionTypeDWARFDebugFrame
@ eSectionTypeARMextab
@ eSectionTypeContainer
The section contains child sections.
@ eSectionTypeDWARFDebugLocLists
DWARF v5 .debug_loclists.
@ eSectionTypeDWARFDebugTypes
DWARF .debug_types section.
@ eSectionTypeDataSymbolAddress
Address of a symbol in the symbol table.
@ eSectionTypeELFDynamicLinkInfo
Elf SHT_DYNAMIC section.
@ eSectionTypeDWARFDebugMacInfo
@ eSectionTypeAbsoluteAddress
Dummy section for symbols with absolute address.
@ eSectionTypeCompactUnwind
compact unwind section in Mach-O, __TEXT,__unwind_info
@ eSectionTypeELFRelocationEntries
Elf SHT_REL or SHT_REL section.
@ eSectionTypeDWARFAppleNamespaces
@ eSectionTypeLLDBFormatters
@ eSectionTypeDWARFDebugNames
DWARF v5 .debug_names.
@ eSectionTypeDWARFDebugRngLists
DWARF v5 .debug_rnglists.
@ eSectionTypeEHFrame
@ eSectionTypeDWARFDebugStrOffsetsDwo
@ eSectionTypeDWARFDebugMacro
@ eSectionTypeDWARFAppleTypes
@ eSectionTypeWasmGlobal
@ eSectionTypeDWARFDebugInfo
@ eSectionTypeDWARFDebugTypesDwo
@ eSectionTypeDWARFDebugRanges
@ eSectionTypeDWARFDebugRngListsDwo
@ eSectionTypeLLDBTypeSummaries
@ eSectionTypeGoSymtab
@ eSectionTypeARMexidx
@ eSectionTypeDWARFDebugLine
@ eSectionTypeDWARFDebugPubTypes
@ eSectionTypeDataObjCMessageRefs
Pointer to function pointer + selector.
@ eSectionTypeDWARFDebugTuIndex
@ eSectionTypeDWARFDebugStr
@ eSectionTypeDWARFDebugLineStr
DWARF v5 .debug_line_str.
@ eSectionTypeDWARFDebugLoc
@ eSectionTypeDWARFAppleNames
@ eSectionTypeDataCStringPointers
Pointers to C string data.
@ eSectionTypeDWARFAppleObjC
@ eSectionTypeSwiftModules
@ eSectionTypeDWARFDebugCuIndex
@ eSectionTypeDWARFDebugAranges
@ eSectionTypeDWARFDebugAbbrevDwo
@ eSectionTypeDWARFGNUDebugAltLink
@ eSectionTypeDWARFDebugStrDwo
@ eSectionTypeDWARFDebugAbbrev
@ eSectionTypeDataPointers
@ eSectionTypeDWARFDebugLocListsDwo
@ eSectionTypeDWARFDebugInfoDwo
@ eSectionTypeDWARFDebugAddr
@ eSectionTypeWasmName
@ eSectionTypeDataCString
Inlined C string data.
@ eSectionTypeELFSymbolTable
Elf SHT_SYMTAB section.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
uint64_t tid_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Module > ModuleSP
The LC_DYSYMTAB's dysymtab_command has 32-bit file offsets that we will use as virtual address offset...
std::vector< MachOCorefileImageEntry > all_image_infos
A corefile may include metadata about all of the binaries that were present in the process when the c...
std::vector< std::tuple< lldb_private::ConstString, lldb::addr_t > > segment_load_addresses
lldb_private::SectionList & UnifiedList
SegmentParsingContext(EncryptedFileRanges EncryptedRanges, lldb_private::SectionList &UnifiedList)
uint32_t segment_count
uint64_t load_address
uint64_t filepath_offset
image_entry(const image_entry &rhs)
uint32_t unused
uint64_t seg_addrs_offset
uuid_t uuid
image_entry()
A binary to find and load into a Target.
lldb::addr_t value
Address where the binary should be loaded, or read out of memory.
bool allow_memory_image_last_resort
If no better binary image can be found, allow reading the binary out of memory, if possible,...
UUID uuid
UUID of the binary to be loaded.
std::string name
Name of the binary, if available.
bool force_symbol_search
Allow the search to do a possibly expensive external search for the ObjectFile and/or SymbolFile.
bool set_address_in_target
Whether the address of the binary should be set in the Target if it is added.
bool notify
Whether ModulesDidLoad should be called once the binary has been added to the Target.
bool value_is_offset
A flag indicating that value is an address, or an offset to be applied to the file addresses.
BaseType GetRangeBase() const
Definition RangeMap.h:45
SizeType GetByteSize() const
Definition RangeMap.h:87
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
Definition RangeMap.h:48
void SetByteSize(SizeType s)
Definition RangeMap.h:89
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_size
Size in bytes of the register.
segment_vmaddr(const segment_vmaddr &rhs)