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(nullptr);
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(
3274 "__IMPORT")) {
3275 type = eSymbolTypeTrampoline;
3276 } else if (symbol_section->IsDescendant(
3277 objc_section_sp.get())) {
3278 type = eSymbolTypeRuntime;
3279 if (symbol_name && symbol_name[0] == '.') {
3280 llvm::StringRef symbol_name_ref(symbol_name);
3281 llvm::StringRef
3282 g_objc_v1_prefix_class(".objc_class_name_");
3283 if (symbol_name_ref.starts_with(
3284 g_objc_v1_prefix_class)) {
3285 symbol_name_non_abi_mangled = symbol_name;
3286 symbol_name = symbol_name +
3287 g_objc_v1_prefix_class.size();
3288 type = eSymbolTypeObjCClass;
3289 demangled_is_synthesized = true;
3290 }
3291 }
3292 }
3293 }
3294 }
3295 } break;
3296 }
3297 }
3298
3299 if (add_nlist) {
3300 uint64_t symbol_value = nlist.n_value;
3301 if (symbol_name_non_abi_mangled) {
3302 sym[sym_idx].GetMangled().SetMangledName(
3303 ConstString(symbol_name_non_abi_mangled));
3304 sym[sym_idx].GetMangled().SetDemangledName(
3305 ConstString(symbol_name));
3306 } else {
3307 if (symbol_name && symbol_name[0] == '_') {
3308 symbol_name++; // Skip the leading underscore
3309 }
3310
3311 if (symbol_name) {
3312 ConstString const_symbol_name(symbol_name);
3313 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
3314 if (is_gsym && is_debug) {
3315 const char *gsym_name =
3316 sym[sym_idx]
3317 .GetMangled()
3319 .GetCString();
3320 if (gsym_name)
3321 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3322 }
3323 }
3324 }
3325 if (symbol_section) {
3326 const addr_t section_file_addr =
3327 symbol_section->GetFileAddress();
3328 symbol_value -= section_file_addr;
3329 }
3330
3331 if (is_debug == false) {
3332 if (type == eSymbolTypeCode) {
3333 // See if we can find a N_FUN entry for any code
3334 // symbols. If we do find a match, and the name
3335 // matches, then we can merge the two into just the
3336 // function symbol to avoid duplicate entries in
3337 // the symbol table
3338 auto range =
3339 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3340 if (range.first != range.second) {
3341 bool found_it = false;
3342 for (auto pos = range.first; pos != range.second;
3343 ++pos) {
3344 if (sym[sym_idx].GetMangled().GetName(
3346 sym[pos->second].GetMangled().GetName(
3348 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3349 // We just need the flags from the linker
3350 // symbol, so put these flags
3351 // into the N_FUN flags to avoid duplicate
3352 // symbols in the symbol table
3353 sym[pos->second].SetExternal(
3354 sym[sym_idx].IsExternal());
3355 sym[pos->second].SetFlags(nlist.n_type << 16 |
3356 nlist.n_desc);
3357 if (resolver_addresses.find(nlist.n_value) !=
3358 resolver_addresses.end())
3359 sym[pos->second].SetType(eSymbolTypeResolver);
3360 sym[sym_idx].Clear();
3361 found_it = true;
3362 break;
3363 }
3364 }
3365 if (found_it)
3366 continue;
3367 } else {
3368 if (resolver_addresses.find(nlist.n_value) !=
3369 resolver_addresses.end())
3370 type = eSymbolTypeResolver;
3371 }
3372 } else if (type == eSymbolTypeData ||
3373 type == eSymbolTypeObjCClass ||
3374 type == eSymbolTypeObjCMetaClass ||
3375 type == eSymbolTypeObjCIVar) {
3376 // See if we can find a N_STSYM entry for any data
3377 // symbols. If we do find a match, and the name
3378 // matches, then we can merge the two into just the
3379 // Static symbol to avoid duplicate entries in the
3380 // symbol table
3381 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3382 nlist.n_value);
3383 if (range.first != range.second) {
3384 bool found_it = false;
3385 for (auto pos = range.first; pos != range.second;
3386 ++pos) {
3387 if (sym[sym_idx].GetMangled().GetName(
3389 sym[pos->second].GetMangled().GetName(
3391 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3392 // We just need the flags from the linker
3393 // symbol, so put these flags
3394 // into the N_STSYM flags to avoid duplicate
3395 // symbols in the symbol table
3396 sym[pos->second].SetExternal(
3397 sym[sym_idx].IsExternal());
3398 sym[pos->second].SetFlags(nlist.n_type << 16 |
3399 nlist.n_desc);
3400 sym[sym_idx].Clear();
3401 found_it = true;
3402 break;
3403 }
3404 }
3405 if (found_it)
3406 continue;
3407 } else {
3408 const char *gsym_name =
3409 sym[sym_idx]
3410 .GetMangled()
3412 .GetCString();
3413 if (gsym_name) {
3414 // Combine N_GSYM stab entries with the non
3415 // stab symbol
3416 ConstNameToSymbolIndexMap::const_iterator pos =
3417 N_GSYM_name_to_sym_idx.find(gsym_name);
3418 if (pos != N_GSYM_name_to_sym_idx.end()) {
3419 const uint32_t GSYM_sym_idx = pos->second;
3420 m_nlist_idx_to_sym_idx[nlist_idx] =
3421 GSYM_sym_idx;
3422 // Copy the address, because often the N_GSYM
3423 // address has an invalid address of zero
3424 // when the global is a common symbol
3425 sym[GSYM_sym_idx].GetAddressRef() =
3426 Address(symbol_section, symbol_value);
3427 add_symbol_addr(sym[GSYM_sym_idx]
3428 .GetAddress()
3429 .GetFileAddress());
3430 // We just need the flags from the linker
3431 // symbol, so put these flags
3432 // into the N_GSYM flags to avoid duplicate
3433 // symbols in the symbol table
3434 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 |
3435 nlist.n_desc);
3436 sym[sym_idx].Clear();
3437 continue;
3438 }
3439 }
3440 }
3441 }
3442 }
3443
3444 sym[sym_idx].SetID(nlist_idx);
3445 sym[sym_idx].SetType(type);
3446 if (set_value) {
3447 sym[sym_idx].GetAddressRef() =
3448 Address(symbol_section, symbol_value);
3449 add_symbol_addr(
3450 sym[sym_idx].GetAddress().GetFileAddress());
3451 }
3452 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
3453
3454 if (demangled_is_synthesized)
3455 sym[sym_idx].SetDemangledNameIsSynthesized(true);
3456 ++sym_idx;
3457 } else {
3458 sym[sym_idx].Clear();
3459 }
3460 }
3461 /////////////////////////////
3462 }
3463 }
3464
3465 for (const auto &pos : reexport_shlib_needs_fixup) {
3466 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3467 if (undef_pos != undefined_name_to_desc.end()) {
3468 const uint8_t dylib_ordinal =
3469 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3470 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
3471 sym[pos.first].SetReExportedSymbolSharedLibrary(
3472 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
3473 }
3474 }
3475 }
3476
3477#endif
3478 lldb::offset_t nlist_data_offset = 0;
3479
3480 if (nlist_data.GetByteSize() > 0) {
3481
3482 const uint64_t max_nsyms = nlist_data.GetByteSize() / nlist_byte_size;
3483 const uint64_t max_nindirectsyms =
3484 indirect_symbol_index_data.GetByteSize() / sizeof(uint32_t);
3485
3486 // If the sym array was not created while parsing the DSC unmapped
3487 // symbols, create it now.
3488 if (sym == nullptr) {
3489 sym = symtab.Resize(
3490 std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms) +
3491 std::min<uint64_t>(m_dysymtab.nindirectsyms, max_nindirectsyms));
3492 num_syms = symtab.GetNumSymbols();
3493 }
3494
3495 if (unmapped_local_symbols_found) {
3496 assert(m_dysymtab.ilocalsym == 0);
3497 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3498 nlist_idx = m_dysymtab.nlocalsym;
3499 } else {
3500 nlist_idx = 0;
3501 }
3502
3503 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3504 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3505 UndefinedNameToDescMap undefined_name_to_desc;
3506 SymbolIndexToName reexport_shlib_needs_fixup;
3507
3508 // Symtab parsing is a huge mess. Everything is entangled and the code
3509 // requires access to a ridiculous amount of variables. LLDB depends
3510 // heavily on the proper merging of symbols and to get that right we need
3511 // to make sure we have parsed all the debug symbols first. Therefore we
3512 // invoke the lambda twice, once to parse only the debug symbols and then
3513 // once more to parse the remaining symbols.
3514 auto ParseSymbolLambda = [&](struct nlist_64 &nlist, uint32_t nlist_idx,
3515 bool debug_only) {
3516 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3517 if (is_debug != debug_only)
3518 return true;
3519
3520 const char *symbol_name_non_abi_mangled = nullptr;
3521 const char *symbol_name = nullptr;
3522
3523 if (have_strtab_data) {
3524 std::optional<llvm::StringRef> name =
3525 strtab_data.PeekCStr(nlist.n_strx);
3526
3527 if (!name) {
3528 // No symbol should be NULL, even the symbols with no string values
3529 // should have an offset zero which points to an empty C-string
3530 Debugger::ReportError(llvm::formatv(
3531 "symbol[{0}] has invalid or unterminated string table offset "
3532 "{1:x} in {2}, ignoring symbol",
3533 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3534 return true;
3535 }
3536 // The code below spells "no name" as a nullptr.
3537 if (!name->empty())
3538 symbol_name = name->data();
3539 } else {
3540 const addr_t str_addr = strtab_addr + nlist.n_strx;
3541 Status str_error;
3542 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3543 str_error))
3544 symbol_name = memory_symbol_name.c_str();
3545 }
3546
3548 SectionSP symbol_section;
3549 bool add_nlist = true;
3550 bool is_gsym = false;
3551 bool demangled_is_synthesized = false;
3552 bool set_value = true;
3553
3554 assert(sym_idx < num_syms);
3555 sym[sym_idx].SetDebug(is_debug);
3556
3557 if (is_debug) {
3558 switch (nlist.n_type) {
3559 case N_GSYM: {
3560 // global symbol: name,,NO_SECT,type,0
3561 // Sometimes the N_GSYM value contains the address.
3562
3563 // FIXME: In the .o files, we have a GSYM and a debug symbol for all
3564 // the ObjC data. They
3565 // have the same address, but we want to ensure that we always find
3566 // only the real symbol, 'cause we don't currently correctly
3567 // attribute the GSYM one to the ObjCClass/Ivar/MetaClass symbol
3568 // type. This is a temporary hack to make sure the ObjectiveC
3569 // symbols get treated correctly. To do this right, we should
3570 // coalesce all the GSYM & global symbols that have the same
3571 // address.
3572 is_gsym = true;
3573 sym[sym_idx].SetExternal(true);
3574
3575 if (TryParseV2ObjCMetadataSymbol(symbol_name,
3576 symbol_name_non_abi_mangled, type)) {
3577 demangled_is_synthesized = true;
3578 } else {
3579 if (nlist.n_value != 0)
3580 symbol_section =
3581 section_info.GetSection(nlist.n_sect, nlist.n_value);
3582
3583 type = eSymbolTypeData;
3584 }
3585 } break;
3586
3587 case N_FNAME:
3588 // procedure name (f77 kludge): name,,NO_SECT,0,0
3589 type = eSymbolTypeCompiler;
3590 break;
3591
3592 case N_FUN:
3593 // procedure: name,,n_sect,linenumber,address
3594 if (symbol_name) {
3595 type = eSymbolTypeCode;
3596 symbol_section =
3597 section_info.GetSection(nlist.n_sect, nlist.n_value);
3598
3599 N_FUN_addr_to_sym_idx.insert(
3600 std::make_pair(nlist.n_value, sym_idx));
3601 // We use the current number of symbols in the symbol table in
3602 // lieu of using nlist_idx in case we ever start trimming entries
3603 // out
3604 N_FUN_indexes.push_back(sym_idx);
3605 } else {
3606 type = eSymbolTypeCompiler;
3607
3608 if (!N_FUN_indexes.empty()) {
3609 // Copy the size of the function into the original STAB entry
3610 // so we don't have to hunt for it later
3611 symtab.SymbolAtIndex(N_FUN_indexes.back())
3612 ->SetByteSize(nlist.n_value);
3613 N_FUN_indexes.pop_back();
3614 // We don't really need the end function STAB as it contains
3615 // the size which we already placed with the original symbol,
3616 // so don't add it if we want a minimal symbol table
3617 add_nlist = false;
3618 }
3619 }
3620 break;
3621
3622 case N_STSYM:
3623 // static symbol: name,,n_sect,type,address
3624 N_STSYM_addr_to_sym_idx.insert(
3625 std::make_pair(nlist.n_value, sym_idx));
3626 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3627 if (symbol_name && symbol_name[0]) {
3628 type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1,
3630 }
3631 break;
3632
3633 case N_LCSYM:
3634 // .lcomm symbol: name,,n_sect,type,address
3635 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3637 break;
3638
3639 case N_BNSYM:
3640 // We use the current number of symbols in the symbol table in lieu
3641 // of using nlist_idx in case we ever start trimming entries out
3642 // Skip these if we want minimal symbol tables
3643 add_nlist = false;
3644 break;
3645
3646 case N_ENSYM:
3647 // Set the size of the N_BNSYM to the terminating index of this
3648 // N_ENSYM so that we can always skip the entire symbol if we need
3649 // to navigate more quickly at the source level when parsing STABS
3650 // Skip these if we want minimal symbol tables
3651 add_nlist = false;
3652 break;
3653
3654 case N_OPT:
3655 // emitted with gcc2_compiled and in gcc source
3656 type = eSymbolTypeCompiler;
3657 break;
3658
3659 case N_RSYM:
3660 // register sym: name,,NO_SECT,type,register
3661 type = eSymbolTypeVariable;
3662 break;
3663
3664 case N_SLINE:
3665 // src line: 0,,n_sect,linenumber,address
3666 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3667 type = eSymbolTypeLineEntry;
3668 break;
3669
3670 case N_SSYM:
3671 // structure elt: name,,NO_SECT,type,struct_offset
3673 break;
3674
3675 case N_SO:
3676 // source file name
3677 type = eSymbolTypeSourceFile;
3678 if (symbol_name == nullptr) {
3679 add_nlist = false;
3680 if (N_SO_index != UINT32_MAX) {
3681 // Set the size of the N_SO to the terminating index of this
3682 // N_SO so that we can always skip the entire N_SO if we need
3683 // to navigate more quickly at the source level when parsing
3684 // STABS
3685 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
3686 symbol_ptr->SetByteSize(sym_idx);
3687 symbol_ptr->SetSizeIsSibling(true);
3688 }
3689 N_NSYM_indexes.clear();
3690 N_INCL_indexes.clear();
3691 N_BRAC_indexes.clear();
3692 N_COMM_indexes.clear();
3693 N_FUN_indexes.clear();
3694 N_SO_index = UINT32_MAX;
3695 } else {
3696 // We use the current number of symbols in the symbol table in
3697 // lieu of using nlist_idx in case we ever start trimming entries
3698 // out
3699 const bool N_SO_has_full_path = symbol_name[0] == '/';
3700 if (N_SO_has_full_path) {
3701 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3702 // We have two consecutive N_SO entries where the first
3703 // contains a directory and the second contains a full path.
3704 sym[sym_idx - 1].GetMangled().SetValue(
3705 ConstString(symbol_name));
3706 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3707 add_nlist = false;
3708 } else {
3709 // This is the first entry in a N_SO that contains a
3710 // directory or a full path to the source file
3711 N_SO_index = sym_idx;
3712 }
3713 } else if ((N_SO_index == sym_idx - 1) &&
3714 ((sym_idx - 1) < num_syms)) {
3715 // This is usually the second N_SO entry that contains just the
3716 // filename, so here we combine it with the first one if we are
3717 // minimizing the symbol table
3718 llvm::StringRef so_path = sym[sym_idx - 1]
3719 .GetMangled()
3721 .GetStringRef();
3722 if (!so_path.empty()) {
3723 std::string full_so_path(so_path);
3724 const size_t double_slash_pos = full_so_path.find("//");
3725 if (double_slash_pos != std::string::npos) {
3726 // The linker has been generating bad N_SO entries with
3727 // doubled up paths in the format "%s%s" where the first
3728 // string in the DW_AT_comp_dir, and the second is the
3729 // directory for the source file so you end up with a path
3730 // that looks like "/tmp/src//tmp/src/"
3731 FileSpec so_dir(so_path);
3732 if (!FileSystem::Instance().Exists(so_dir)) {
3733 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
3734 FileSpec::Style::native);
3735 if (FileSystem::Instance().Exists(so_dir)) {
3736 // Trim off the incorrect path
3737 full_so_path.erase(0, double_slash_pos + 1);
3738 }
3739 }
3740 }
3741 if (*full_so_path.rbegin() != '/')
3742 full_so_path += '/';
3743 full_so_path += symbol_name;
3744 sym[sym_idx - 1].GetMangled().SetValue(
3745 ConstString(full_so_path.c_str()));
3746 add_nlist = false;
3747 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3748 }
3749 } else {
3750 // This could be a relative path to a N_SO
3751 N_SO_index = sym_idx;
3752 }
3753 }
3754 break;
3755
3756 case N_OSO:
3757 // object file name: name,,0,0,st_mtime
3758 type = eSymbolTypeObjectFile;
3759 break;
3760
3761 case N_LSYM:
3762 // local sym: name,,NO_SECT,type,offset
3763 type = eSymbolTypeLocal;
3764 break;
3765
3766 // INCL scopes
3767 case N_BINCL:
3768 // include file beginning: name,,NO_SECT,0,sum We use the current
3769 // number of symbols in the symbol table in lieu of using nlist_idx
3770 // in case we ever start trimming entries out
3771 N_INCL_indexes.push_back(sym_idx);
3772 type = eSymbolTypeScopeBegin;
3773 break;
3774
3775 case N_EINCL:
3776 // include file end: name,,NO_SECT,0,0
3777 // Set the size of the N_BINCL to the terminating index of this
3778 // N_EINCL so that we can always skip the entire symbol if we need
3779 // to navigate more quickly at the source level when parsing STABS
3780 if (!N_INCL_indexes.empty()) {
3781 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
3782 symbol_ptr->SetByteSize(sym_idx + 1);
3783 symbol_ptr->SetSizeIsSibling(true);
3784 N_INCL_indexes.pop_back();
3785 }
3786 type = eSymbolTypeScopeEnd;
3787 break;
3788
3789 case N_SOL:
3790 // #included file name: name,,n_sect,0,address
3791 type = eSymbolTypeHeaderFile;
3792
3793 // We currently don't use the header files on darwin
3794 add_nlist = false;
3795 break;
3796
3797 case N_PARAMS:
3798 // compiler parameters: name,,NO_SECT,0,0
3799 type = eSymbolTypeCompiler;
3800 break;
3801
3802 case N_VERSION:
3803 // compiler version: name,,NO_SECT,0,0
3804 type = eSymbolTypeCompiler;
3805 break;
3806
3807 case N_OLEVEL:
3808 // compiler -O level: name,,NO_SECT,0,0
3809 type = eSymbolTypeCompiler;
3810 break;
3811
3812 case N_PSYM:
3813 // parameter: name,,NO_SECT,type,offset
3814 type = eSymbolTypeVariable;
3815 break;
3816
3817 case N_ENTRY:
3818 // alternate entry: name,,n_sect,linenumber,address
3819 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3820 type = eSymbolTypeLineEntry;
3821 break;
3822
3823 // Left and Right Braces
3824 case N_LBRAC:
3825 // left bracket: 0,,NO_SECT,nesting level,address We use the
3826 // current number of symbols in the symbol table in lieu of using
3827 // nlist_idx in case we ever start trimming entries out
3828 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3829 N_BRAC_indexes.push_back(sym_idx);
3830 type = eSymbolTypeScopeBegin;
3831 break;
3832
3833 case N_RBRAC:
3834 // right bracket: 0,,NO_SECT,nesting level,address Set the size of
3835 // the N_LBRAC to the terminating index of this N_RBRAC so that we
3836 // can always skip the entire symbol if we need to navigate more
3837 // quickly at the source level when parsing STABS
3838 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3839 if (!N_BRAC_indexes.empty()) {
3840 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
3841 symbol_ptr->SetByteSize(sym_idx + 1);
3842 symbol_ptr->SetSizeIsSibling(true);
3843 N_BRAC_indexes.pop_back();
3844 }
3845 type = eSymbolTypeScopeEnd;
3846 break;
3847
3848 case N_EXCL:
3849 // deleted include file: name,,NO_SECT,0,sum
3850 type = eSymbolTypeHeaderFile;
3851 break;
3852
3853 // COMM scopes
3854 case N_BCOMM:
3855 // begin common: name,,NO_SECT,0,0
3856 // We use the current number of symbols in the symbol table in lieu
3857 // of using nlist_idx in case we ever start trimming entries out
3858 type = eSymbolTypeScopeBegin;
3859 N_COMM_indexes.push_back(sym_idx);
3860 break;
3861
3862 case N_ECOML:
3863 // end common (local name): 0,,n_sect,0,address
3864 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3865 [[fallthrough]];
3866
3867 case N_ECOMM:
3868 // end common: name,,n_sect,0,0
3869 // Set the size of the N_BCOMM to the terminating index of this
3870 // N_ECOMM/N_ECOML so that we can always skip the entire symbol if
3871 // we need to navigate more quickly at the source level when
3872 // parsing STABS
3873 if (!N_COMM_indexes.empty()) {
3874 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
3875 symbol_ptr->SetByteSize(sym_idx + 1);
3876 symbol_ptr->SetSizeIsSibling(true);
3877 N_COMM_indexes.pop_back();
3878 }
3879 type = eSymbolTypeScopeEnd;
3880 break;
3881
3882 case N_LENG:
3883 // second stab entry with length information
3884 type = eSymbolTypeAdditional;
3885 break;
3886
3887 default:
3888 break;
3889 }
3890 } else {
3891 uint8_t n_type = N_TYPE & nlist.n_type;
3892 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3893
3894 switch (n_type) {
3895 case N_INDR: {
3896 std::optional<llvm::StringRef> reexport_name_str =
3897 strtab_data.PeekCStr(nlist.n_value);
3898 if (reexport_name_str && !reexport_name_str->empty() && symbol_name) {
3899 type = eSymbolTypeReExported;
3900 ConstString reexport_name(reexport_name_str->drop_front(
3901 reexport_name_str->front() == '_' ? 1 : 0));
3902 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3903 set_value = false;
3904 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3905 indirect_symbol_names.insert(
3906 ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
3907 } else
3908 type = eSymbolTypeUndefined;
3909 } break;
3910
3911 case N_UNDF:
3912 if (symbol_name && symbol_name[0]) {
3913 ConstString undefined_name(symbol_name +
3914 ((symbol_name[0] == '_') ? 1 : 0));
3915 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3916 }
3917 [[fallthrough]];
3918
3919 case N_PBUD:
3920 type = eSymbolTypeUndefined;
3921 break;
3922
3923 case N_ABS:
3924 type = eSymbolTypeAbsolute;
3925 break;
3926
3927 case N_SECT: {
3928 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3929
3930 if (!symbol_section) {
3931 // TODO: warn about this?
3932 add_nlist = false;
3933 break;
3934 }
3935
3936 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3937 type = eSymbolTypeException;
3938 } else {
3939 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3940
3941 switch (section_type) {
3942 case S_CSTRING_LITERALS:
3943 type = eSymbolTypeData;
3944 break; // section with only literal C strings
3945 case S_4BYTE_LITERALS:
3946 type = eSymbolTypeData;
3947 break; // section with only 4 byte literals
3948 case S_8BYTE_LITERALS:
3949 type = eSymbolTypeData;
3950 break; // section with only 8 byte literals
3951 case S_LITERAL_POINTERS:
3952 type = eSymbolTypeTrampoline;
3953 break; // section with only pointers to literals
3954 case S_NON_LAZY_SYMBOL_POINTERS:
3955 type = eSymbolTypeTrampoline;
3956 break; // section with only non-lazy symbol pointers
3957 case S_LAZY_SYMBOL_POINTERS:
3958 type = eSymbolTypeTrampoline;
3959 break; // section with only lazy symbol pointers
3960 case S_SYMBOL_STUBS:
3961 type = eSymbolTypeTrampoline;
3962 break; // section with only symbol stubs, byte size of stub in
3963 // the reserved2 field
3964 case S_MOD_INIT_FUNC_POINTERS:
3965 type = eSymbolTypeCode;
3966 break; // section with only function pointers for initialization
3967 case S_MOD_TERM_FUNC_POINTERS:
3968 type = eSymbolTypeCode;
3969 break; // section with only function pointers for termination
3970 case S_INTERPOSING:
3971 type = eSymbolTypeTrampoline;
3972 break; // section with only pairs of function pointers for
3973 // interposing
3974 case S_16BYTE_LITERALS:
3975 type = eSymbolTypeData;
3976 break; // section with only 16 byte literals
3977 case S_DTRACE_DOF:
3979 break;
3980 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3981 type = eSymbolTypeTrampoline;
3982 break;
3983 default:
3984 switch (symbol_section->GetType()) {
3986 type = eSymbolTypeCode;
3987 break;
3988 case eSectionTypeData:
3989 case eSectionTypeDataCString: // Inlined C string data
3990 case eSectionTypeDataCStringPointers: // Pointers to C string
3991 // data
3992 case eSectionTypeDataSymbolAddress: // Address of a symbol in
3993 // the symbol table
3994 case eSectionTypeData4:
3995 case eSectionTypeData8:
3996 case eSectionTypeData16:
3997 type = eSymbolTypeData;
3998 break;
3999 default:
4000 break;
4001 }
4002 break;
4003 }
4004
4005 if (type == eSymbolTypeInvalid) {
4006 llvm::StringRef symbol_sect_name = symbol_section->GetName();
4007 if (symbol_section->IsDescendant(text_section_sp.get())) {
4008 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4009 S_ATTR_SELF_MODIFYING_CODE |
4010 S_ATTR_SOME_INSTRUCTIONS))
4011 type = eSymbolTypeData;
4012 else
4013 type = eSymbolTypeCode;
4014 } else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4015 symbol_section->IsDescendant(
4016 data_dirty_section_sp.get()) ||
4017 symbol_section->IsDescendant(
4018 data_const_section_sp.get())) {
4019 if (symbol_sect_name.starts_with("__objc")) {
4020 type = eSymbolTypeRuntime;
4021
4023 symbol_name, symbol_name_non_abi_mangled, type))
4024 demangled_is_synthesized = true;
4025 } else if (symbol_sect_name.starts_with("__gcc_except_tab")) {
4026 type = eSymbolTypeException;
4027 } else {
4028 type = eSymbolTypeData;
4029 }
4030 } else if (symbol_sect_name.starts_with("__IMPORT")) {
4031 type = eSymbolTypeTrampoline;
4032 } else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4033 type = eSymbolTypeRuntime;
4034 if (symbol_name && symbol_name[0] == '.') {
4035 llvm::StringRef symbol_name_ref(symbol_name);
4036 llvm::StringRef g_objc_v1_prefix_class(
4037 ".objc_class_name_");
4038 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4039 symbol_name_non_abi_mangled = symbol_name;
4040 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4041 type = eSymbolTypeObjCClass;
4042 demangled_is_synthesized = true;
4043 }
4044 }
4045 }
4046 }
4047 }
4048 } break;
4049 }
4050 }
4051
4052 if (!add_nlist) {
4053 sym[sym_idx].Clear();
4054 return true;
4055 }
4056
4057 uint64_t symbol_value = nlist.n_value;
4058
4059 if (symbol_name_non_abi_mangled) {
4060 sym[sym_idx].GetMangled().SetMangledName(
4061 ConstString(symbol_name_non_abi_mangled));
4062 sym[sym_idx].GetMangled().SetDemangledName(ConstString(symbol_name));
4063 } else {
4064
4065 if (symbol_name && symbol_name[0] == '_') {
4066 symbol_name++; // Skip the leading underscore
4067 }
4068
4069 if (symbol_name) {
4070 ConstString const_symbol_name(symbol_name);
4071 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
4072 }
4073 }
4074
4075 if (is_gsym) {
4076 const char *gsym_name = sym[sym_idx]
4077 .GetMangled()
4079 .GetCString();
4080 if (gsym_name)
4081 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4082 }
4083
4084 if (symbol_section) {
4085 const addr_t section_file_addr = symbol_section->GetFileAddress();
4086 symbol_value -= section_file_addr;
4087 }
4088
4089 if (!is_debug) {
4090 if (type == eSymbolTypeCode) {
4091 // See if we can find a N_FUN entry for any code symbols. If we do
4092 // find a match, and the name matches, then we can merge the two into
4093 // just the function symbol to avoid duplicate entries in the symbol
4094 // table.
4095 std::pair<ValueToSymbolIndexMap::const_iterator,
4096 ValueToSymbolIndexMap::const_iterator>
4097 range;
4098 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4099 if (range.first != range.second) {
4100 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4101 pos != range.second; ++pos) {
4102 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==
4103 sym[pos->second].GetMangled().GetName(
4105 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4106 // We just need the flags from the linker symbol, so put these
4107 // flags into the N_FUN flags to avoid duplicate symbols in the
4108 // symbol table.
4109 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4110 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4111 if (resolver_addresses.find(nlist.n_value) !=
4112 resolver_addresses.end())
4113 sym[pos->second].SetType(eSymbolTypeResolver);
4114 sym[sym_idx].Clear();
4115 return true;
4116 }
4117 }
4118 } else {
4119 if (resolver_addresses.find(nlist.n_value) !=
4120 resolver_addresses.end())
4121 type = eSymbolTypeResolver;
4122 }
4123 } else if (type == eSymbolTypeData || type == eSymbolTypeObjCClass ||
4124 type == eSymbolTypeObjCMetaClass ||
4125 type == eSymbolTypeObjCIVar) {
4126 // See if we can find a N_STSYM entry for any data symbols. If we do
4127 // find a match, and the name matches, then we can merge the two into
4128 // just the Static symbol to avoid duplicate entries in the symbol
4129 // table.
4130 std::pair<ValueToSymbolIndexMap::const_iterator,
4131 ValueToSymbolIndexMap::const_iterator>
4132 range;
4133 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4134 if (range.first != range.second) {
4135 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4136 pos != range.second; ++pos) {
4137 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==
4138 sym[pos->second].GetMangled().GetName(
4140 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4141 // We just need the flags from the linker symbol, so put these
4142 // flags into the N_STSYM flags to avoid duplicate symbols in
4143 // the symbol table.
4144 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4145 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4146 sym[sym_idx].Clear();
4147 return true;
4148 }
4149 }
4150 } else {
4151 // Combine N_GSYM stab entries with the non stab symbol.
4152 const char *gsym_name = sym[sym_idx]
4153 .GetMangled()
4155 .GetCString();
4156 if (gsym_name) {
4157 ConstNameToSymbolIndexMap::const_iterator pos =
4158 N_GSYM_name_to_sym_idx.find(gsym_name);
4159 if (pos != N_GSYM_name_to_sym_idx.end()) {
4160 const uint32_t GSYM_sym_idx = pos->second;
4161 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4162 // Copy the address, because often the N_GSYM address has an
4163 // invalid address of zero when the global is a common symbol.
4164 sym[GSYM_sym_idx].GetAddressRef() =
4165 Address(symbol_section, symbol_value);
4166 add_symbol_addr(
4167 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4168 // We just need the flags from the linker symbol, so put these
4169 // flags into the N_GSYM flags to avoid duplicate symbols in
4170 // the symbol table.
4171 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4172 sym[sym_idx].Clear();
4173 return true;
4174 }
4175 }
4176 }
4177 }
4178 }
4179
4180 sym[sym_idx].SetID(nlist_idx);
4181 sym[sym_idx].SetType(type);
4182 if (set_value) {
4183 sym[sym_idx].GetAddressRef() = Address(symbol_section, symbol_value);
4184 if (symbol_section)
4185 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4186 }
4187 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4188 if (nlist.n_desc & N_WEAK_REF)
4189 sym[sym_idx].SetIsWeak(true);
4190
4191 if (demangled_is_synthesized)
4192 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4193
4194 ++sym_idx;
4195 return true;
4196 };
4197
4198 // First parse all the nlists but don't process them yet. See the next
4199 // comment for an explanation why.
4200 std::vector<struct nlist_64> nlists;
4201 nlists.reserve(std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms));
4202 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4203 if (auto nlist =
4204 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4205 nlists.push_back(*nlist);
4206 else
4207 break;
4208 }
4209
4210 // Now parse all the debug symbols. This is needed to merge non-debug
4211 // symbols in the next step. Non-debug symbols are always coalesced into
4212 // the debug symbol. Doing this in one step would mean that some symbols
4213 // won't be merged.
4214 nlist_idx = 0;
4215 for (auto &nlist : nlists) {
4216 if (!ParseSymbolLambda(nlist, nlist_idx++, DebugSymbols))
4217 break;
4218 }
4219
4220 // Finally parse all the non debug symbols.
4221 nlist_idx = 0;
4222 for (auto &nlist : nlists) {
4223 if (!ParseSymbolLambda(nlist, nlist_idx++, NonDebugSymbols))
4224 break;
4225 }
4226
4227 for (const auto &pos : reexport_shlib_needs_fixup) {
4228 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4229 if (undef_pos != undefined_name_to_desc.end()) {
4230 const uint8_t dylib_ordinal =
4231 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4232 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4233 sym[pos.first].SetReExportedSymbolSharedLibrary(
4234 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4235 }
4236 }
4237 }
4238
4239 // Count how many trie symbols we'll add to the symbol table
4240 int trie_symbol_table_augment_count = 0;
4241 for (auto &e : external_sym_trie_entries) {
4242 if (!symbols_added.contains(e.entry.address))
4243 trie_symbol_table_augment_count++;
4244 }
4245
4246 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4247 num_syms = sym_idx + trie_symbol_table_augment_count;
4248 sym = symtab.Resize(num_syms);
4249 }
4250 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4251
4252 // Add symbols from the trie to the symbol table.
4253 for (auto &e : external_sym_trie_entries) {
4254 if (symbols_added.contains(e.entry.address))
4255 continue;
4256
4257 // Find the section that this trie address is in, use that to annotate
4258 // symbol type as we add the trie address and name to the symbol table.
4259 Address symbol_addr;
4260 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4261 SectionSP symbol_section(symbol_addr.GetSection());
4262 const char *symbol_name = e.entry.name.GetCString();
4263 bool demangled_is_synthesized = false;
4264 SymbolType type =
4265 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4266 data_section_sp, data_dirty_section_sp,
4267 data_const_section_sp, symbol_section);
4268
4269 sym[sym_idx].SetType(type);
4270 if (symbol_section) {
4271 sym[sym_idx].SetID(synthetic_sym_id++);
4272 sym[sym_idx].GetMangled().SetMangledName(ConstString(symbol_name));
4273 if (demangled_is_synthesized)
4274 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4275 sym[sym_idx].SetIsSynthetic(true);
4276 sym[sym_idx].SetExternal(true);
4277 sym[sym_idx].GetAddressRef() = symbol_addr;
4278 add_symbol_addr(symbol_addr.GetFileAddress());
4279 if (e.entry.flags & TRIE_SYMBOL_IS_THUMB)
4281 ++sym_idx;
4282 }
4283 }
4284 }
4285
4286 if (function_starts_count > 0) {
4287 uint32_t num_synthetic_function_symbols = 0;
4288 for (i = 0; i < function_starts_count; ++i) {
4289 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4290 ++num_synthetic_function_symbols;
4291 }
4292
4293 if (num_synthetic_function_symbols > 0) {
4294 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4295 num_syms = sym_idx + num_synthetic_function_symbols;
4296 sym = symtab.Resize(num_syms);
4297 }
4298 for (i = 0; i < function_starts_count; ++i) {
4299 const FunctionStarts::Entry *func_start_entry =
4300 function_starts.GetEntryAtIndex(i);
4301 if (!symbols_added.contains(func_start_entry->addr)) {
4302 addr_t symbol_file_addr = func_start_entry->addr;
4303 uint32_t symbol_flags = 0;
4304 if (func_start_entry->data)
4305 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
4306 Address symbol_addr;
4307 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4308 SectionSP symbol_section(symbol_addr.GetSection());
4309 if (symbol_section) {
4310 sym[sym_idx].SetID(synthetic_sym_id++);
4311 // Don't set the name for any synthetic symbols, the Symbol
4312 // object will generate one if needed when the name is accessed
4313 // via accessors.
4314 sym[sym_idx].GetMangled().SetDemangledName(ConstString());
4315 sym[sym_idx].SetType(eSymbolTypeCode);
4316 sym[sym_idx].SetIsSynthetic(true);
4317 sym[sym_idx].GetAddressRef() = symbol_addr;
4318 add_symbol_addr(symbol_addr.GetFileAddress());
4319 if (symbol_flags)
4320 sym[sym_idx].SetFlags(symbol_flags);
4321 ++sym_idx;
4322 }
4323 }
4324 }
4325 }
4326 }
4327 }
4328
4329 // Trim our symbols down to just what we ended up with after removing any
4330 // symbols.
4331 if (sym_idx < num_syms) {
4332 num_syms = sym_idx;
4333 sym = symtab.Resize(num_syms);
4334 }
4335
4336 // Now synthesize indirect symbols
4337 if (m_dysymtab.nindirectsyms != 0) {
4338 if (indirect_symbol_index_data.GetByteSize()) {
4339 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4340 m_nlist_idx_to_sym_idx.end();
4341
4342 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4343 ++sect_idx) {
4344 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4345 S_SYMBOL_STUBS) {
4346 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4347 if (symbol_stub_byte_size == 0)
4348 continue;
4349
4350 const uint32_t num_symbol_stubs =
4351 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4352
4353 if (num_symbol_stubs == 0)
4354 continue;
4355
4356 const uint32_t symbol_stub_index_offset =
4357 m_mach_sections[sect_idx].reserved1;
4358 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4359 const uint32_t symbol_stub_index =
4360 symbol_stub_index_offset + stub_idx;
4361 const lldb::addr_t symbol_stub_addr =
4362 m_mach_sections[sect_idx].addr +
4363 (stub_idx * symbol_stub_byte_size);
4364 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
4365 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4366 symbol_stub_offset, 4)) {
4367 const uint32_t stub_sym_id =
4368 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4369 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4370 continue;
4371
4372 NListIndexToSymbolIndexMap::const_iterator index_pos =
4373 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4374 Symbol *stub_symbol = nullptr;
4375 if (index_pos != end_index_pos) {
4376 // We have a remapping from the original nlist index to a
4377 // current symbol index, so just look this up by index
4378 stub_symbol = symtab.SymbolAtIndex(index_pos->second);
4379 } else {
4380 // We need to lookup a symbol using the original nlist symbol
4381 // index since this index is coming from the S_SYMBOL_STUBS
4382 stub_symbol = symtab.FindSymbolByID(stub_sym_id);
4383 }
4384
4385 if (stub_symbol) {
4386 Address so_addr(symbol_stub_addr, section_list);
4387
4388 if (stub_symbol->GetType() == eSymbolTypeUndefined) {
4389 // Change the external symbol into a trampoline that makes
4390 // sense These symbols were N_UNDF N_EXT, and are useless
4391 // to us, so we can re-use them so we don't have to make up
4392 // a synthetic symbol for no good reason.
4393 if (resolver_addresses.find(symbol_stub_addr) ==
4394 resolver_addresses.end())
4395 stub_symbol->SetType(eSymbolTypeTrampoline);
4396 else
4397 stub_symbol->SetType(eSymbolTypeResolver);
4398 stub_symbol->SetExternal(false);
4399 stub_symbol->GetAddressRef() = so_addr;
4400 stub_symbol->SetByteSize(symbol_stub_byte_size);
4401 } else {
4402 // Make a synthetic symbol to describe the trampoline stub
4403 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
4404 if (sym_idx >= num_syms) {
4405 sym = symtab.Resize(++num_syms);
4406 stub_symbol = nullptr; // this pointer no longer valid
4407 }
4408 sym[sym_idx].SetID(synthetic_sym_id++);
4409 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4410 if (resolver_addresses.find(symbol_stub_addr) ==
4411 resolver_addresses.end())
4412 sym[sym_idx].SetType(eSymbolTypeTrampoline);
4413 else
4414 sym[sym_idx].SetType(eSymbolTypeResolver);
4415 sym[sym_idx].SetIsSynthetic(true);
4416 sym[sym_idx].GetAddressRef() = so_addr;
4417 add_symbol_addr(so_addr.GetFileAddress());
4418 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4419 ++sym_idx;
4420 }
4421 } else {
4422 LLDB_LOGF(log,
4423 "warning: symbol stub referencing symbol table "
4424 "symbol %u that isn't in our minimal symbol table, "
4425 "fix this!!!",
4426 stub_sym_id);
4427 }
4428 }
4429 }
4430 }
4431 }
4432 }
4433 }
4434
4435 if (!reexport_trie_entries.empty()) {
4436 for (const auto &e : reexport_trie_entries) {
4437 if (e.entry.import_name) {
4438 // Only add indirect symbols from the Trie entries if we didn't have
4439 // a N_INDR nlist entry for this already
4440 if (indirect_symbol_names.find(e.entry.name) ==
4441 indirect_symbol_names.end()) {
4442 // Make a synthetic symbol to describe re-exported symbol.
4443 if (sym_idx >= num_syms)
4444 sym = symtab.Resize(++num_syms);
4445 sym[sym_idx].SetID(synthetic_sym_id++);
4446 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4447 sym[sym_idx].SetType(eSymbolTypeReExported);
4448 sym[sym_idx].SetIsSynthetic(true);
4449 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4450 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4452 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
4453 }
4454 ++sym_idx;
4455 }
4456 }
4457 }
4458 }
4459}
4460
4462 ModuleSP module_sp(GetModule());
4463 if (module_sp) {
4464 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4465 s->Printf("%p: ", static_cast<void *>(this));
4466 s->Indent();
4467 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
4468 s->PutCString("ObjectFileMachO64");
4469 else
4470 s->PutCString("ObjectFileMachO32");
4471
4472 *s << ", file = '" << m_file;
4473 ModuleSpecList all_specs;
4474 ModuleSpec base_spec;
4476 MachHeaderSizeFromMagic(m_header.magic), base_spec,
4477 all_specs);
4478 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
4479 *s << "', triple";
4480 if (e)
4481 s->Printf("[%d]", i);
4482 *s << " = ";
4483 *s << all_specs.GetModuleSpecRefAtIndex(i)
4485 .GetTriple()
4486 .getTriple();
4487 }
4488 *s << "\n";
4489 SectionList *sections = GetSectionList();
4490 if (sections)
4491 sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
4492 UINT32_MAX);
4493
4494 if (m_symtab_up)
4495 m_symtab_up->Dump(s, nullptr, eSortOrderNone);
4496 }
4497}
4498
4499UUID ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
4500 const lldb_private::DataExtractor &data,
4501 lldb::offset_t lc_offset) {
4502 uint32_t i;
4503 llvm::MachO::uuid_command load_cmd;
4504
4505 lldb::offset_t offset = lc_offset;
4506 for (i = 0; i < header.ncmds; ++i) {
4507 const lldb::offset_t cmd_offset = offset;
4508 if (!ReadMachOCommand(data, offset, load_cmd))
4509 break;
4510
4511 if (load_cmd.cmd == LC_UUID) {
4512 const uint8_t *uuid_bytes = data.PeekData(offset, 16);
4513
4514 if (uuid_bytes) {
4515 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4516 // We pretend these object files have no UUID to prevent crashing.
4517
4518 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4519 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4520 0xbb, 0x14, 0xf0, 0x0d};
4521
4522 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4523 return UUID();
4524
4525 return UUID(uuid_bytes, 16);
4526 }
4527 return UUID();
4528 }
4529 offset = cmd_offset + load_cmd.cmdsize;
4530 }
4531 return UUID();
4532}
4533
4534static llvm::StringRef GetOSName(uint32_t cmd) {
4535 switch (cmd) {
4536 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4537 return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4538 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4539 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4540 case llvm::MachO::LC_VERSION_MIN_TVOS:
4541 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4542 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4543 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4544 default:
4545 llvm_unreachable("unexpected LC_VERSION load command");
4546 }
4547}
4548
4549namespace {
4550struct OSEnv {
4551 llvm::StringRef os_type;
4552 llvm::StringRef environment;
4553 OSEnv(uint32_t cmd) {
4554 switch (cmd) {
4555 case llvm::MachO::PLATFORM_MACOS:
4556 os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4557 return;
4558 case llvm::MachO::PLATFORM_IOS:
4559 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4560 return;
4561 case llvm::MachO::PLATFORM_TVOS:
4562 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4563 return;
4564 case llvm::MachO::PLATFORM_WATCHOS:
4565 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4566 return;
4567 case llvm::MachO::PLATFORM_BRIDGEOS:
4568 os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
4569 return;
4570 case llvm::MachO::PLATFORM_DRIVERKIT:
4571 os_type = llvm::Triple::getOSTypeName(llvm::Triple::DriverKit);
4572 return;
4573 case llvm::MachO::PLATFORM_MACCATALYST:
4574 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4575 environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);
4576 return;
4577 case llvm::MachO::PLATFORM_IOSSIMULATOR:
4578 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4579 environment =
4580 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4581 return;
4582 case llvm::MachO::PLATFORM_TVOSSIMULATOR:
4583 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4584 environment =
4585 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4586 return;
4587 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:
4588 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4589 environment =
4590 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4591 return;
4592 case llvm::MachO::PLATFORM_XROS:
4593 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4594 return;
4595 case llvm::MachO::PLATFORM_XROS_SIMULATOR:
4596 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4597 environment =
4598 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4599 return;
4600 default: {
4601 Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));
4602 LLDB_LOGF(log, "unsupported platform in LC_BUILD_VERSION");
4603 }
4604 }
4605 }
4606};
4607
4608struct MinOS {
4609 uint32_t major_version, minor_version, patch_version;
4610 MinOS(uint32_t version)
4611 : major_version(version >> 16), minor_version((version >> 8) & 0xffu),
4612 patch_version(version & 0xffu) {}
4613};
4614} // namespace
4615
4616void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header &header,
4617 const lldb_private::DataExtractor &data,
4618 lldb::offset_t lc_offset,
4619 ModuleSpec &base_spec,
4620 lldb_private::ModuleSpecList &all_specs) {
4621 auto &base_arch = base_spec.GetArchitecture();
4622 base_arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype);
4623 if (!base_arch.IsValid())
4624 return;
4625
4626 bool found_any = false;
4627 auto add_triple = [&](const llvm::Triple &triple) {
4628 auto spec = base_spec;
4629 spec.GetArchitecture().GetTriple() = triple;
4630 if (spec.GetArchitecture().IsValid()) {
4631 spec.GetUUID() = ObjectFileMachO::GetUUID(header, data, lc_offset);
4632 all_specs.Append(spec);
4633 found_any = true;
4634 }
4635 };
4636
4637 // Set OS to an unspecified unknown or a "*" so it can match any OS
4638 llvm::Triple base_triple = base_arch.GetTriple();
4639 base_triple.setOS(llvm::Triple::UnknownOS);
4640 base_triple.setOSName(llvm::StringRef());
4641
4642 if (header.filetype == MH_PRELOAD) {
4643 if (header.cputype == CPU_TYPE_ARM) {
4644 // If this is a 32-bit arm binary, and it's a standalone binary, force
4645 // the Vendor to Apple so we don't accidentally pick up the generic
4646 // armv7 ABI at runtime. Apple's armv7 ABI always uses r7 for the
4647 // frame pointer register; most other armv7 ABIs use a combination of
4648 // r7 and r11.
4649 base_triple.setVendor(llvm::Triple::Apple);
4650 } else {
4651 // Set vendor to an unspecified unknown or a "*" so it can match any
4652 // vendor This is required for correct behavior of EFI debugging on
4653 // x86_64
4654 base_triple.setVendor(llvm::Triple::UnknownVendor);
4655 base_triple.setVendorName(llvm::StringRef());
4656 }
4657 return add_triple(base_triple);
4658 }
4659
4660 llvm::MachO::load_command load_cmd;
4661
4662 // See if there is an LC_VERSION_MIN_* load command that can give
4663 // us the OS type.
4664 lldb::offset_t offset = lc_offset;
4665 for (uint32_t i = 0; i < header.ncmds; ++i) {
4666 const lldb::offset_t cmd_offset = offset;
4667 if (!ReadMachOCommand(data, offset, load_cmd))
4668 break;
4669
4670 llvm::MachO::version_min_command version_min;
4671 switch (load_cmd.cmd) {
4672 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4673 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4674 case llvm::MachO::LC_VERSION_MIN_TVOS:
4675 case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
4676 if (load_cmd.cmdsize != sizeof(version_min))
4677 break;
4678 if (data.ExtractBytes(cmd_offset, sizeof(version_min),
4679 data.GetByteOrder(), &version_min) == 0)
4680 break;
4681 MinOS min_os(version_min.version);
4682 llvm::SmallString<32> os_name;
4683 llvm::raw_svector_ostream os(os_name);
4684 os << GetOSName(load_cmd.cmd) << min_os.major_version << '.'
4685 << min_os.minor_version << '.' << min_os.patch_version;
4686
4687 auto triple = base_triple;
4688 triple.setOSName(os.str());
4689
4690 // Disambiguate legacy simulator platforms.
4691 if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
4692 (base_triple.getArch() == llvm::Triple::x86_64 ||
4693 base_triple.getArch() == llvm::Triple::x86)) {
4694 // The combination of legacy LC_VERSION_MIN load command and
4695 // x86 architecture always indicates a simulator environment.
4696 // The combination of LC_VERSION_MIN and arm architecture only
4697 // appears for native binaries. Back-deploying simulator
4698 // binaries on Apple Silicon Macs use the modern unambigous
4699 // LC_BUILD_VERSION load commands; no special handling required.
4700 triple.setEnvironment(llvm::Triple::Simulator);
4701 }
4702 add_triple(triple);
4703 break;
4704 }
4705 default:
4706 break;
4707 }
4708
4709 offset = cmd_offset + load_cmd.cmdsize;
4710 }
4711
4712 // See if there are LC_BUILD_VERSION load commands that can give
4713 // us the OS type.
4714 offset = lc_offset;
4715 for (uint32_t i = 0; i < header.ncmds; ++i) {
4716 const lldb::offset_t cmd_offset = offset;
4717 if (!ReadMachOCommand(data, offset, load_cmd))
4718 break;
4719
4720 do {
4721 if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
4722 llvm::MachO::build_version_command build_version;
4723 if (load_cmd.cmdsize < sizeof(build_version)) {
4724 // Malformed load command.
4725 break;
4726 }
4727 if (data.ExtractBytes(cmd_offset, sizeof(build_version),
4728 data.GetByteOrder(), &build_version) == 0)
4729 break;
4730 MinOS min_os(build_version.minos);
4731 OSEnv os_env(build_version.platform);
4732 llvm::SmallString<16> os_name;
4733 llvm::raw_svector_ostream os(os_name);
4734 os << os_env.os_type << min_os.major_version << '.'
4735 << min_os.minor_version << '.' << min_os.patch_version;
4736 auto triple = base_triple;
4737 triple.setOSName(os.str());
4738 os_name.clear();
4739 if (!os_env.environment.empty())
4740 triple.setEnvironmentName(os_env.environment);
4741 add_triple(triple);
4742 }
4743 } while (false);
4744 offset = cmd_offset + load_cmd.cmdsize;
4745 }
4746
4747 if (!found_any) {
4748 add_triple(base_triple);
4749 }
4750}
4751
4753 ModuleSP module_sp, const llvm::MachO::mach_header &header,
4754 const lldb_private::DataExtractor &data, lldb::offset_t lc_offset) {
4755 ModuleSpecList all_specs;
4756 ModuleSpec base_spec;
4757 GetAllArchSpecs(header, data, MachHeaderSizeFromMagic(header.magic),
4758 base_spec, all_specs);
4759
4760 // If the object file offers multiple alternative load commands,
4761 // pick the one that matches the module.
4762 if (module_sp) {
4763 const ArchSpec &module_arch = module_sp->GetArchitecture();
4764 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
4765 ArchSpec mach_arch =
4767 if (module_arch.IsCompatibleMatch(mach_arch))
4768 return mach_arch;
4769 }
4770 }
4771
4772 // Return the first arch we found.
4773 if (all_specs.GetSize() == 0)
4774 return {};
4775 return all_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();
4776}
4777
4779 ModuleSP module_sp(GetModule());
4780 if (module_sp) {
4781 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4783 return GetUUID(m_header, *m_data_nsp, offset);
4784 }
4785 return UUID();
4786}
4787
4789 ModuleSP module_sp = GetModule();
4790 if (!module_sp)
4791 return 0;
4792
4793 uint32_t count = 0;
4794 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4795 llvm::MachO::load_command load_cmd;
4797 std::vector<std::string> rpath_paths;
4798 std::vector<std::string> rpath_relative_paths;
4799 std::vector<std::string> at_exec_relative_paths;
4800 uint32_t i;
4801 for (i = 0; i < m_header.ncmds; ++i) {
4802 const uint32_t cmd_offset = offset;
4803 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
4804 break;
4805
4806 switch (load_cmd.cmd) {
4807 case LC_RPATH:
4808 case LC_LOAD_DYLIB:
4809 case LC_LOAD_WEAK_DYLIB:
4810 case LC_REEXPORT_DYLIB:
4811 case LC_LOAD_DYLINKER:
4812 case LC_LOADFVMLIB:
4813 case LC_LOAD_UPWARD_DYLIB: {
4814 uint32_t name_offset = cmd_offset + m_data_nsp->GetU32(&offset);
4815 // For LC_LOAD_DYLIB there is an alternate encoding
4816 // which adds a uint32_t `flags` field for `DYLD_USE_*`
4817 // flags. This can be detected by a timestamp field with
4818 // the `DYLIB_USE_MARKER` constant value.
4819 bool is_delayed_init = false;
4820 uint32_t use_command_marker = m_data_nsp->GetU32(&offset);
4821 if (use_command_marker == 0x1a741800 /* DYLIB_USE_MARKER */) {
4822 offset += 4; /* uint32_t current_version */
4823 offset += 4; /* uint32_t compat_version */
4824 uint32_t flags = m_data_nsp->GetU32(&offset);
4825 // If this LC_LOAD_DYLIB is marked delay-init,
4826 // don't report it as a dependent library -- it
4827 // may be loaded in the process at some point,
4828 // but will most likely not be load at launch.
4829 if (flags & 0x08 /* DYLIB_USE_DELAYED_INIT */)
4830 is_delayed_init = true;
4831 }
4832 std::optional<llvm::StringRef> maybe_path =
4833 m_data_nsp->PeekCStr(name_offset);
4834 if (maybe_path && !is_delayed_init) {
4835 llvm::StringRef path = *maybe_path;
4836 if (load_cmd.cmd == LC_RPATH)
4837 rpath_paths.push_back(path.str());
4838 else if (path.consume_front("@rpath"))
4839 rpath_relative_paths.push_back(path.str());
4840 else if (path.consume_front("@executable_path"))
4841 at_exec_relative_paths.push_back(path.str());
4842 else if (!path.starts_with("@")) {
4843 FileSpec file_spec(path);
4844 if (files.AppendIfUnique(file_spec))
4845 count++;
4846 }
4847 }
4848 } break;
4849
4850 default:
4851 break;
4852 }
4853 offset = cmd_offset + load_cmd.cmdsize;
4854 }
4855
4856 FileSpec this_file_spec(m_file);
4857 FileSystem::Instance().Resolve(this_file_spec);
4858
4859 if (!rpath_paths.empty()) {
4860 // Fixup all LC_RPATH values to be absolute paths.
4861 const std::string this_directory = this_file_spec.GetDirectory().str();
4862 for (auto &rpath : rpath_paths) {
4863 if (llvm::StringRef(rpath).starts_with(g_loader_path))
4864 rpath = this_directory + rpath.substr(g_loader_path.size());
4865 else if (llvm::StringRef(rpath).starts_with(g_executable_path))
4866 rpath = this_directory + rpath.substr(g_executable_path.size());
4867 }
4868
4869 for (const auto &rpath_relative_path : rpath_relative_paths) {
4870 for (const auto &rpath : rpath_paths) {
4871 std::string path = rpath;
4872 path += rpath_relative_path;
4873 // It is OK to resolve this path because we must find a file on disk
4874 // for us to accept it anyway if it is rpath relative.
4875 FileSpec file_spec(path);
4876 FileSystem::Instance().Resolve(file_spec);
4877 if (FileSystem::Instance().Exists(file_spec) &&
4878 files.AppendIfUnique(file_spec)) {
4879 count++;
4880 break;
4881 }
4882 }
4883 }
4884 }
4885
4886 // We may have @executable_paths but no RPATHS. Figure those out here.
4887 // Only do this if this object file is the executable. We have no way to
4888 // get back to the actual executable otherwise, so we won't get the right
4889 // path.
4890 if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) {
4891 FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent();
4892 for (const auto &at_exec_relative_path : at_exec_relative_paths) {
4893 FileSpec file_spec =
4894 exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
4895 if (FileSystem::Instance().Exists(file_spec) &&
4896 files.AppendIfUnique(file_spec))
4897 count++;
4898 }
4899 }
4900 return count;
4901}
4902
4904 // If the object file is not an executable it can't hold the entry point.
4905 // m_entry_point_address is initialized to an invalid address, so we can just
4906 // return that. If m_entry_point_address is valid it means we've found it
4907 // already, so return the cached value.
4908
4909 if ((!IsExecutable() && !IsDynamicLoader()) ||
4910 m_entry_point_address.IsValid()) {
4911 return m_entry_point_address;
4912 }
4913
4914 // Otherwise, look for the UnixThread or Thread command. The data for the
4915 // Thread command is given in /usr/include/mach-o.h, but it is basically:
4916 //
4917 // uint32_t flavor - this is the flavor argument you would pass to
4918 // thread_get_state
4919 // uint32_t count - this is the count of longs in the thread state data
4920 // struct XXX_thread_state state - this is the structure from
4921 // <machine/thread_status.h> corresponding to the flavor.
4922 // <repeat this trio>
4923 //
4924 // So we just keep reading the various register flavors till we find the GPR
4925 // one, then read the PC out of there.
4926 // FIXME: We will need to have a "RegisterContext data provider" class at some
4927 // point that can get all the registers
4928 // out of data in this form & attach them to a given thread. That should
4929 // underlie the MacOS X User process plugin, and we'll also need it for the
4930 // MacOS X Core File process plugin. When we have that we can also use it
4931 // here.
4932 //
4933 // For now we hard-code the offsets and flavors we need:
4934 //
4935 //
4936
4937 ModuleSP module_sp(GetModule());
4938 if (module_sp) {
4939 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4940 llvm::MachO::load_command load_cmd;
4942 uint32_t i;
4943 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
4944 bool done = false;
4945
4946 for (i = 0; i < m_header.ncmds; ++i) {
4947 const lldb::offset_t cmd_offset = offset;
4948 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
4949 break;
4950
4951 switch (load_cmd.cmd) {
4952 case LC_UNIXTHREAD:
4953 case LC_THREAD: {
4954 while (offset < cmd_offset + load_cmd.cmdsize) {
4955 uint32_t flavor = m_data_nsp->GetU32(&offset);
4956 uint32_t count = m_data_nsp->GetU32(&offset);
4957 if (count == 0) {
4958 // We've gotten off somehow, log and exit;
4959 return m_entry_point_address;
4960 }
4961
4962 switch (m_header.cputype) {
4963 case llvm::MachO::CPU_TYPE_ARM:
4964 if (flavor == 1 ||
4965 flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32
4966 // from mach/arm/thread_status.h
4967 {
4968 offset += 60; // This is the offset of pc in the GPR thread state
4969 // data structure.
4970 start_address = m_data_nsp->GetU32(&offset);
4971 done = true;
4972 }
4973 break;
4974 case llvm::MachO::CPU_TYPE_ARM64:
4975 case llvm::MachO::CPU_TYPE_ARM64_32:
4976 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
4977 {
4978 offset += 256; // This is the offset of pc in the GPR thread state
4979 // data structure.
4980 start_address = m_data_nsp->GetU64(&offset);
4981 done = true;
4982 }
4983 break;
4984 case llvm::MachO::CPU_TYPE_X86_64:
4985 if (flavor ==
4986 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
4987 {
4988 offset += 16 * 8; // This is the offset of rip in the GPR thread
4989 // state data structure.
4990 start_address = m_data_nsp->GetU64(&offset);
4991 done = true;
4992 }
4993 break;
4994 default:
4995 return m_entry_point_address;
4996 }
4997 // Haven't found the GPR flavor yet, skip over the data for this
4998 // flavor:
4999 if (done)
5000 break;
5001 offset += count * 4;
5002 }
5003 } break;
5004 case LC_MAIN: {
5005 uint64_t entryoffset = m_data_nsp->GetU64(&offset);
5006 SectionSP text_segment_sp =
5008 if (text_segment_sp) {
5009 done = true;
5010 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5011 }
5012 } break;
5013
5014 default:
5015 break;
5016 }
5017 if (done)
5018 break;
5019
5020 // Go to the next load command:
5021 offset = cmd_offset + load_cmd.cmdsize;
5022 }
5023
5024 if (start_address == LLDB_INVALID_ADDRESS && IsDynamicLoader()) {
5025 if (GetSymtab()) {
5026 const Symbol *dyld_start_sym =
5030 if (dyld_start_sym && dyld_start_sym->GetAddress().IsValid()) {
5031 start_address = dyld_start_sym->GetAddress().GetFileAddress();
5032 }
5033 }
5034 }
5035
5036 if (start_address != LLDB_INVALID_ADDRESS) {
5037 // We got the start address from the load commands, so now resolve that
5038 // address in the sections of this ObjectFile:
5039 if (!m_entry_point_address.ResolveAddressUsingFileSections(
5040 start_address, GetSectionList())) {
5041 m_entry_point_address.Clear();
5042 }
5043 } else {
5044 // We couldn't read the UnixThread load command - maybe it wasn't there.
5045 // As a fallback look for the "start" symbol in the main executable.
5046
5047 ModuleSP module_sp(GetModule());
5048
5049 if (module_sp) {
5050 SymbolContextList contexts;
5051 SymbolContext context;
5052 module_sp->FindSymbolsWithNameAndType(ConstString("start"),
5053 eSymbolTypeCode, contexts);
5054 if (contexts.GetSize()) {
5055 if (contexts.GetContextAtIndex(0, context))
5057 }
5058 }
5059 }
5060 }
5061
5062 return m_entry_point_address;
5063}
5064
5066 lldb_private::Address header_addr;
5067 SectionList *section_list = GetSectionList();
5068 if (section_list) {
5069 SectionSP text_segment_sp(
5070 section_list->FindSectionByName(GetSegmentNameTEXT()));
5071 if (text_segment_sp)
5072 header_addr = Address(text_segment_sp, /*offset=*/0);
5073 }
5074 return header_addr;
5075}
5076
5078 ModuleSP module_sp(GetModule());
5079 if (module_sp) {
5080 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5084 FileRangeArray::Entry file_range;
5085 llvm::MachO::thread_command thread_cmd;
5086 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5087 const uint32_t cmd_offset = offset;
5088 if (!ReadMachOCommand(*m_data_nsp, offset, thread_cmd))
5089 break;
5090
5091 if (thread_cmd.cmd == LC_THREAD) {
5092 file_range.SetRangeBase(offset);
5093 file_range.SetByteSize(thread_cmd.cmdsize - 8);
5094 m_thread_context_offsets.Append(file_range);
5095 }
5096 offset = cmd_offset + thread_cmd.cmdsize;
5097 }
5098 }
5099 }
5100 return m_thread_context_offsets.GetSize();
5101}
5102
5103std::vector<std::tuple<offset_t, offset_t>>
5105 std::vector<std::tuple<offset_t, offset_t>> results;
5106 ModuleSP module_sp(GetModule());
5107 if (module_sp) {
5108 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5109
5111 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5112 const uint32_t cmd_offset = offset;
5113 llvm::MachO::load_command lc = {};
5114 if (!ReadMachOCommand(*m_data_nsp, offset, lc))
5115 break;
5116 if (lc.cmd == LC_NOTE) {
5117 char data_owner[17];
5118 m_data_nsp->CopyData(offset, 16, data_owner);
5119 data_owner[16] = '\0';
5120 offset += 16;
5121
5122 if (name == data_owner) {
5123 offset_t payload_offset = m_data_nsp->GetU64_unchecked(&offset);
5124 offset_t payload_size = m_data_nsp->GetU64_unchecked(&offset);
5125 results.push_back({payload_offset, payload_size});
5126 }
5127 }
5128 offset = cmd_offset + lc.cmdsize;
5129 }
5130 }
5131 return results;
5132}
5133
5135 Log *log(
5137 ModuleSP module_sp(GetModule());
5138 if (module_sp) {
5139 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5140
5141 auto lc_notes = FindLC_NOTEByName("kern ver str");
5142 for (auto lc_note : lc_notes) {
5143 offset_t payload_offset = std::get<0>(lc_note);
5144 offset_t payload_size = std::get<1>(lc_note);
5145 uint32_t version;
5146 if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr) {
5147 if (version == 1) {
5148 uint32_t strsize = payload_size - sizeof(uint32_t);
5149 std::string result(strsize, '\0');
5150 m_data_nsp->CopyData(payload_offset, strsize, result.data());
5151 LLDB_LOGF(log, "LC_NOTE 'kern ver str' found with text '%s'",
5152 result.c_str());
5153 return result;
5154 }
5155 }
5156 }
5157
5158 // Second, make a pass over the load commands looking for an obsolete
5159 // LC_IDENT load command.
5161 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5162 const uint32_t cmd_offset = offset;
5163 llvm::MachO::ident_command ident_command;
5164 if (!ReadMachOCommand(*m_data_nsp, offset, ident_command))
5165 break;
5166 if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
5167 std::string result(ident_command.cmdsize, '\0');
5168 if (m_data_nsp->CopyData(offset, ident_command.cmdsize,
5169 result.data()) == ident_command.cmdsize) {
5170 LLDB_LOGF(log, "LC_IDENT found with text '%s'", result.c_str());
5171 return result;
5172 }
5173 }
5174 offset = cmd_offset + ident_command.cmdsize;
5175 }
5176 }
5177 return {};
5178}
5179
5181 AddressableBits addressable_bits;
5182
5184 ModuleSP module_sp(GetModule());
5185 if (module_sp) {
5186 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5187 auto lc_notes = FindLC_NOTEByName("addrable bits");
5188 for (auto lc_note : lc_notes) {
5189 offset_t payload_offset = std::get<0>(lc_note);
5190 uint32_t version;
5191 if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr) {
5192 if (version == 3) {
5193 uint32_t num_addr_bits =
5194 m_data_nsp->GetU32_unchecked(&payload_offset);
5195 addressable_bits.SetAddressableBits(num_addr_bits);
5196 LLDB_LOGF(log,
5197 "LC_NOTE 'addrable bits' v3 found, value %d "
5198 "bits",
5199 num_addr_bits);
5200 }
5201 if (version == 4) {
5202 uint32_t lo_addr_bits = m_data_nsp->GetU32_unchecked(&payload_offset);
5203 uint32_t hi_addr_bits = m_data_nsp->GetU32_unchecked(&payload_offset);
5204
5205 if (lo_addr_bits == hi_addr_bits)
5206 addressable_bits.SetAddressableBits(lo_addr_bits);
5207 else
5208 addressable_bits.SetAddressableBits(lo_addr_bits, hi_addr_bits);
5209 LLDB_LOGF(log, "LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
5210 lo_addr_bits, hi_addr_bits);
5211 }
5212 }
5213 }
5214 }
5215 return addressable_bits;
5216}
5217
5219 bool &value_is_offset,
5220 UUID &uuid,
5221 ObjectFile::BinaryType &type) {
5222 Log *log(
5224 value = LLDB_INVALID_ADDRESS;
5225 value_is_offset = false;
5226 uuid.Clear();
5227 uint32_t log2_pagesize = 0; // not currently passed up to caller
5228 uint32_t platform = 0; // not currently passed up to caller
5229 ModuleSP module_sp(GetModule());
5230 if (module_sp) {
5231 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5232
5233 auto lc_notes = FindLC_NOTEByName("main bin spec");
5234 for (auto lc_note : lc_notes) {
5235 offset_t payload_offset = std::get<0>(lc_note);
5236
5237 // struct main_bin_spec
5238 // {
5239 // uint32_t version; // currently 2
5240 // uint32_t type; // 0 == unspecified,
5241 // // 1 == kernel
5242 // // 2 == user process,
5243 // dyld mach-o binary addr
5244 // // 3 == standalone binary
5245 // // 4 == user process,
5246 // // dyld_all_image_infos addr
5247 // uint64_t address; // UINT64_MAX if address not specified
5248 // uint64_t slide; // slide, UINT64_MAX if unspecified
5249 // // 0 if no slide needs to be applied to
5250 // // file address
5251 // uuid_t uuid; // all zero's if uuid not specified
5252 // uint32_t log2_pagesize; // process page size in log base 2,
5253 // // e.g. 4k pages are 12.
5254 // // 0 for unspecified
5255 // uint32_t platform; // The Mach-O platform for this corefile.
5256 // // 0 for unspecified.
5257 // // The values are defined in
5258 // // <mach-o/loader.h>, PLATFORM_*.
5259 // } __attribute((packed));
5260
5261 // "main bin spec" (main binary specification) data payload is
5262 // formatted:
5263 // uint32_t version [currently 1]
5264 // uint32_t type [0 == unspecified, 1 == kernel,
5265 // 2 == user process, 3 == firmware ]
5266 // uint64_t address [ UINT64_MAX if address not specified ]
5267 // uuid_t uuid [ all zero's if uuid not specified ]
5268 // uint32_t log2_pagesize [ process page size in log base
5269 // 2, e.g. 4k pages are 12.
5270 // 0 for unspecified ]
5271 // uint32_t unused [ for alignment ]
5272
5273 uint32_t version;
5274 if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr &&
5275 version <= 2) {
5276 uint32_t binspec_type = 0;
5277 uuid_t raw_uuid;
5278 memset(raw_uuid, 0, sizeof(uuid_t));
5279
5280 if (!m_data_nsp->GetU32(&payload_offset, &binspec_type, 1))
5281 return false;
5282 if (!m_data_nsp->GetU64(&payload_offset, &value, 1))
5283 return false;
5284 uint64_t slide = LLDB_INVALID_ADDRESS;
5285 if (version > 1 && !m_data_nsp->GetU64(&payload_offset, &slide, 1))
5286 return false;
5287 if (value == LLDB_INVALID_ADDRESS && slide != LLDB_INVALID_ADDRESS) {
5288 value = slide;
5289 value_is_offset = true;
5290 }
5291
5292 if (m_data_nsp->CopyData(payload_offset, sizeof(uuid_t), raw_uuid) !=
5293 0) {
5294 uuid = UUID(raw_uuid, sizeof(uuid_t));
5295 // convert the "main bin spec" type into our
5296 // ObjectFile::BinaryType enum
5297 const char *typestr = "unrecognized type";
5298 type = eBinaryTypeInvalid;
5299 switch (binspec_type) {
5300 case 0:
5301 type = eBinaryTypeUnknown;
5302 typestr = "uknown";
5303 break;
5304 case 1:
5305 type = eBinaryTypeKernel;
5306 typestr = "xnu kernel";
5307 break;
5308 case 2:
5309 type = eBinaryTypeUser;
5310 typestr = "userland dyld";
5311 break;
5312 case 3:
5313 type = eBinaryTypeStandalone;
5314 typestr = "standalone";
5315 break;
5316 case 4:
5318 typestr = "userland dyld_all_image_infos";
5319 break;
5320 }
5321 LLDB_LOGF(log,
5322 "LC_NOTE 'main bin spec' found, version %d type %d "
5323 "(%s), value 0x%" PRIx64 " value-is-slide==%s uuid %s",
5324 version, type, typestr, value,
5325 value_is_offset ? "true" : "false",
5326 uuid.GetAsString().c_str());
5327 if (!m_data_nsp->GetU32(&payload_offset, &log2_pagesize, 1))
5328 return false;
5329 if (version > 1 && !m_data_nsp->GetU32(&payload_offset, &platform, 1))
5330 return false;
5331 return true;
5332 }
5333 }
5334 }
5335 }
5336 return false;
5337}
5338
5340 std::vector<lldb::tid_t> &tids) {
5341 tids.clear();
5342 ModuleSP module_sp(GetModule());
5343 if (module_sp) {
5344 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5345
5348 StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
5349 StructuredData::Array *threads;
5350 if (!dict->GetValueForKeyAsArray("threads", threads) || !threads) {
5351 LLDB_LOGF(log,
5352 "'process metadata' LC_NOTE does not have a 'threads' key");
5353 return false;
5354 }
5355 if (threads->GetSize() != GetNumThreadContexts()) {
5356 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, number of "
5357 "threads does not match number of LC_THREADS.");
5358 return false;
5359 }
5360 const size_t num_threads = threads->GetSize();
5361 for (size_t i = 0; i < num_threads; i++) {
5362 std::optional<StructuredData::Dictionary *> maybe_thread =
5363 threads->GetItemAtIndexAsDictionary(i);
5364 if (!maybe_thread) {
5365 LLDB_LOGF(log,
5366 "Unable to read 'process metadata' LC_NOTE, threads "
5367 "array does not have a dictionary at index %zu.",
5368 i);
5369 return false;
5370 }
5371 StructuredData::Dictionary *thread = *maybe_thread;
5373 if (thread->GetValueForKeyAsInteger<lldb::tid_t>("thread_id", tid))
5374 if (tid == 0)
5376 tids.push_back(tid);
5377 }
5378
5379 if (log) {
5380 StreamString logmsg;
5381 logmsg.Printf("LC_NOTE 'process metadata' found: ");
5382 dict->Dump(logmsg, /* pretty_print */ false);
5383 LLDB_LOGF(log, "%s", logmsg.GetData());
5384 }
5385 return true;
5386 }
5387 }
5388 return false;
5389}
5390
5391/// Return the payload of an LC_NOTE, decompressing it if needed.
5392///
5393/// A payload is either stored as is, or compressed in the layout of a GNU
5394/// .zdebug section:
5395///
5396/// offset size contents
5397/// 0 4 magic "ZLIB"
5398/// 4 8 uncompressed size, big-endian uint64_t
5399/// 12 n RFC 1950 zlib stream
5400///
5401/// The size is big-endian regardless of the corefile's byte order. An
5402/// uncompressed payload must not start with the magic.
5403static llvm::Expected<std::string> ReadLCNotePayload(const DataExtractor &data,
5404 lldb::offset_t offset,
5405 uint64_t size) {
5406 const uint8_t *bytes = data.PeekData(offset, size);
5407 if (!bytes)
5408 return llvm::createStringError(
5409 "payload of %" PRIu64 " bytes is out of bounds", size);
5410 llvm::ArrayRef<uint8_t> payload(bytes, size);
5411
5412 constexpr llvm::StringLiteral magic = "ZLIB";
5413 constexpr size_t header_size = magic.size() + sizeof(uint64_t);
5414 if (!llvm::toStringRef(payload).starts_with(magic))
5415 return llvm::toStringRef(payload).str();
5416 if (payload.size() < header_size)
5417 return llvm::createStringError("compressed payload header is truncated");
5418
5419 uint64_t uncompressed_size =
5420 llvm::support::endian::read64be(payload.data() + magic.size());
5421 llvm::ArrayRef<uint8_t> compressed = payload.drop_front(header_size);
5422 // Deflate cannot exceed a 1032:1 ratio. A larger claimed size is corrupt and
5423 // must not size the allocation.
5424 if (uncompressed_size / 1032 > compressed.size())
5425 return llvm::createStringError("uncompressed size %" PRIu64
5426 " is impossible for %zu compressed bytes",
5427 uncompressed_size, compressed.size());
5428 if (!llvm::compression::zlib::isAvailable())
5429 return llvm::createStringError(
5430 "payload is zlib-compressed but LLDB was built without zlib");
5431
5432 llvm::SmallVector<uint8_t, 0> uncompressed;
5433 if (llvm::Error err = llvm::compression::zlib::decompress(
5434 compressed, uncompressed, uncompressed_size))
5435 return err;
5436 return llvm::toStringRef(uncompressed).str();
5437}
5438
5440 ModuleSP module_sp(GetModule());
5441 if (!module_sp)
5442 return {};
5443
5445 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5446 auto lc_notes = FindLC_NOTEByName("process metadata");
5447 if (lc_notes.size() == 0)
5448 return {};
5449
5450 if (lc_notes.size() > 1)
5451 LLDB_LOGF(
5452 log,
5453 "Multiple 'process metadata' LC_NOTEs found, only using the first.");
5454
5455 auto [payload_offset, payload_size] = lc_notes[0];
5456 llvm::Expected<std::string> json =
5457 ReadLCNotePayload(*m_data_nsp, payload_offset, payload_size);
5458 if (!json) {
5459 LLDB_LOG_ERROR(log, json.takeError(),
5460 "Unable to read 'process metadata' LC_NOTE: {0}");
5461 return {};
5462 }
5463 StructuredData::ObjectSP object_sp =
5464 StructuredData::ParseJSON(llvm::StringRef(*json).rtrim('\0'));
5465 if (!object_sp) {
5466 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
5467 "parse as valid JSON.");
5468 return {};
5469 }
5470 StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
5471 if (!dict) {
5472 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
5473 "get a dictionary.");
5474 return {};
5475 }
5476
5477 return object_sp;
5478}
5479
5482 lldb_private::Thread &thread) {
5483 lldb::RegisterContextSP reg_ctx_sp;
5484
5485 ModuleSP module_sp(GetModule());
5486 if (module_sp) {
5487 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5490
5491 const FileRangeArray::Entry *thread_context_file_range =
5492 m_thread_context_offsets.GetEntryAtIndex(idx);
5493 if (thread_context_file_range) {
5494
5495 DataExtractor data(*m_data_nsp, thread_context_file_range->GetRangeBase(),
5496 thread_context_file_range->GetByteSize());
5497
5498 switch (m_header.cputype) {
5499 case llvm::MachO::CPU_TYPE_ARM64:
5500 case llvm::MachO::CPU_TYPE_ARM64_32:
5501 reg_ctx_sp =
5502 std::make_shared<RegisterContextDarwin_arm64_Mach>(thread, data);
5503 break;
5504
5505 case llvm::MachO::CPU_TYPE_ARM:
5506 reg_ctx_sp =
5507 std::make_shared<RegisterContextDarwin_arm_Mach>(thread, data);
5508 break;
5509
5510 case llvm::MachO::CPU_TYPE_X86_64:
5511 reg_ctx_sp =
5512 std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);
5513 break;
5514
5515 case llvm::MachO::CPU_TYPE_RISCV:
5516 reg_ctx_sp =
5517 std::make_shared<RegisterContextDarwin_riscv32_Mach>(thread, data);
5518 break;
5519 }
5520 }
5521 }
5522 return reg_ctx_sp;
5523}
5524
5526 switch (m_header.filetype) {
5527 case MH_OBJECT: // 0x1u
5528 if (GetAddressByteSize() == 4) {
5529 // 32 bit kexts are just object files, but they do have a valid
5530 // UUID load command.
5531 if (GetUUID()) {
5532 // this checking for the UUID load command is not enough we could
5533 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
5534 // this is required of kexts
5535 if (m_strata == eStrataInvalid)
5537 return eTypeSharedLibrary;
5538 }
5539 }
5540 return eTypeObjectFile;
5541
5542 case MH_EXECUTE:
5543 return eTypeExecutable; // 0x2u
5544 case MH_FVMLIB:
5545 return eTypeSharedLibrary; // 0x3u
5546 case MH_CORE:
5547 return eTypeCoreFile; // 0x4u
5548 case MH_PRELOAD:
5549 return eTypeSharedLibrary; // 0x5u
5550 case MH_DYLIB:
5551 return eTypeSharedLibrary; // 0x6u
5552 case MH_DYLINKER:
5553 return eTypeDynamicLinker; // 0x7u
5554 case MH_BUNDLE:
5555 return eTypeSharedLibrary; // 0x8u
5556 case MH_DYLIB_STUB:
5557 return eTypeStubLibrary; // 0x9u
5558 case MH_DSYM:
5559 return eTypeDebugInfo; // 0xAu
5560 case MH_KEXT_BUNDLE:
5561 return eTypeSharedLibrary; // 0xBu
5562 default:
5563 break;
5564 }
5565 return eTypeUnknown;
5566}
5567
5569 switch (m_header.filetype) {
5570 case MH_OBJECT: // 0x1u
5571 {
5572 // 32 bit kexts are just object files, but they do have a valid
5573 // UUID load command.
5574 if (GetUUID()) {
5575 // this checking for the UUID load command is not enough we could
5576 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
5577 // this is required of kexts
5578 if (m_type == eTypeInvalid)
5580
5581 return eStrataKernel;
5582 }
5583 }
5584 return eStrataUnknown;
5585
5586 case MH_EXECUTE: // 0x2u
5587 // Check for the MH_DYLDLINK bit in the flags
5588 if (m_header.flags & MH_DYLDLINK) {
5589 return eStrataUser;
5590 } else {
5591 SectionList *section_list = GetSectionList();
5592 if (section_list) {
5593 if (section_list->FindSectionByName("__KLD"))
5594 return eStrataKernel;
5595 }
5596 }
5597 return eStrataRawImage;
5598
5599 case MH_FVMLIB:
5600 return eStrataUser; // 0x3u
5601 case MH_CORE:
5602 return eStrataUnknown; // 0x4u
5603 case MH_PRELOAD:
5604 return eStrataRawImage; // 0x5u
5605 case MH_DYLIB:
5606 return eStrataUser; // 0x6u
5607 case MH_DYLINKER:
5608 return eStrataUser; // 0x7u
5609 case MH_BUNDLE:
5610 return eStrataUser; // 0x8u
5611 case MH_DYLIB_STUB:
5612 return eStrataUser; // 0x9u
5613 case MH_DSYM:
5614 return eStrataUnknown; // 0xAu
5615 case MH_KEXT_BUNDLE:
5616 return eStrataKernel; // 0xBu
5617 default:
5618 break;
5619 }
5620 return eStrataUnknown;
5621}
5622
5623llvm::VersionTuple ObjectFileMachO::GetVersion() {
5624 ModuleSP module_sp(GetModule());
5625 if (module_sp) {
5626 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5627 llvm::MachO::dylib_command load_cmd;
5629 uint32_t version_cmd = 0;
5630 uint64_t version = 0;
5631 uint32_t i;
5632 for (i = 0; i < m_header.ncmds; ++i) {
5633 const lldb::offset_t cmd_offset = offset;
5634 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
5635 break;
5636
5637 if (load_cmd.cmd == LC_ID_DYLIB) {
5638 if (version_cmd == 0) {
5639 version_cmd = load_cmd.cmd;
5640 if (m_data_nsp->GetU32(&offset, &load_cmd.dylib, 4) == nullptr)
5641 break;
5642 version = load_cmd.dylib.current_version;
5643 }
5644 break; // Break for now unless there is another more complete version
5645 // number load command in the future.
5646 }
5647 offset = cmd_offset + load_cmd.cmdsize;
5648 }
5649
5650 if (version_cmd == LC_ID_DYLIB) {
5651 unsigned major = (version & 0xFFFF0000ull) >> 16;
5652 unsigned minor = (version & 0x0000FF00ull) >> 8;
5653 unsigned subminor = (version & 0x000000FFull);
5654 return llvm::VersionTuple(major, minor, subminor);
5655 }
5656 }
5657 return llvm::VersionTuple();
5658}
5659
5661 ModuleSP module_sp(GetModule());
5662 ArchSpec arch;
5663 if (module_sp) {
5664 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5665
5666 return GetArchitecture(module_sp, m_header, *m_data_nsp,
5668 }
5669 return arch;
5670}
5671
5673 addr_t &base_addr, UUID &uuid) {
5674 uuid.Clear();
5675 base_addr = LLDB_INVALID_ADDRESS;
5676 if (process && process->GetDynamicLoader()) {
5677 DynamicLoader *dl = process->GetDynamicLoader();
5678 LazyBool using_shared_cache;
5679 LazyBool private_shared_cache;
5680 FileSpec sc_filepath;
5681 std::optional<uint64_t> size;
5682 dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,
5683 private_shared_cache, sc_filepath, size);
5684 }
5686 LLDB_LOGF(
5687 log,
5688 "inferior process shared cache has a UUID of %s, base address 0x%" PRIx64,
5689 uuid.GetAsString().c_str(), base_addr);
5690}
5691
5692// From dyld SPI header dyld_process_info.h
5693typedef void *dyld_process_info;
5695 uuid_t cacheUUID; // UUID of cache used by process
5696 uint64_t cacheBaseAddress; // load address of dyld shared cache
5697 bool noCache; // process is running without a dyld cache
5698 bool privateCache; // process is using a private copy of its dyld cache
5699};
5700
5701// #including mach/mach.h pulls in machine.h & CPU_TYPE_ARM etc conflicts with
5702// llvm enum definitions llvm::MachO::CPU_TYPE_ARM turning them into compile
5703// errors. So we need to use the actual underlying types of task_t and
5704// kern_return_t below.
5705extern "C" unsigned int /*task_t*/ mach_task_self();
5706
5708 uuid.Clear();
5709 base_addr = LLDB_INVALID_ADDRESS;
5710
5711#if defined(__APPLE__)
5712 uint8_t *(*dyld_get_all_image_infos)(void);
5713 dyld_get_all_image_infos =
5714 (uint8_t * (*)()) dlsym(RTLD_DEFAULT, "_dyld_get_all_image_infos");
5715 if (dyld_get_all_image_infos) {
5716 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5717 if (dyld_all_image_infos_address) {
5718 uint32_t *version = (uint32_t *)
5719 dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
5720 if (*version >= 13) {
5721 uuid_t *sharedCacheUUID_address = 0;
5722 int wordsize = sizeof(uint8_t *);
5723 if (wordsize == 8) {
5724 sharedCacheUUID_address =
5725 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5726 160); // sharedCacheUUID <mach-o/dyld_images.h>
5727 if (*version >= 15)
5728 base_addr =
5729 *(uint64_t
5730 *)((uint8_t *)dyld_all_image_infos_address +
5731 176); // sharedCacheBaseAddress <mach-o/dyld_images.h>
5732 } else {
5733 sharedCacheUUID_address =
5734 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5735 84); // sharedCacheUUID <mach-o/dyld_images.h>
5736 if (*version >= 15) {
5737 base_addr = 0;
5738 base_addr =
5739 *(uint32_t
5740 *)((uint8_t *)dyld_all_image_infos_address +
5741 100); // sharedCacheBaseAddress <mach-o/dyld_images.h>
5742 }
5743 }
5744 uuid = UUID(sharedCacheUUID_address, sizeof(uuid_t));
5745 }
5746 }
5747 } else {
5748 // Exists in macOS 10.12 and later, iOS 10.0 and later - dyld SPI
5749 dyld_process_info (*dyld_process_info_create)(
5750 unsigned int /* task_t */ task, uint64_t timestamp,
5751 unsigned int /*kern_return_t*/ *kernelError);
5752 void (*dyld_process_info_get_cache)(void *info, void *cacheInfo);
5753 void (*dyld_process_info_release)(dyld_process_info info);
5754
5755 dyld_process_info_create = (void *(*)(unsigned int /* task_t */, uint64_t,
5756 unsigned int /*kern_return_t*/ *))
5757 dlsym(RTLD_DEFAULT, "_dyld_process_info_create");
5758 dyld_process_info_get_cache = (void (*)(void *, void *))dlsym(
5759 RTLD_DEFAULT, "_dyld_process_info_get_cache");
5760 dyld_process_info_release =
5761 (void (*)(void *))dlsym(RTLD_DEFAULT, "_dyld_process_info_release");
5762
5763 if (dyld_process_info_create && dyld_process_info_get_cache) {
5764 unsigned int /*kern_return_t */ kern_ret;
5765 dyld_process_info process_info =
5766 dyld_process_info_create(::mach_task_self(), 0, &kern_ret);
5767 if (process_info) {
5769 memset(&sc_info, 0, sizeof(struct lldb_copy__dyld_process_cache_info));
5770 dyld_process_info_get_cache(process_info, &sc_info);
5771 if (sc_info.cacheBaseAddress != 0) {
5772 base_addr = sc_info.cacheBaseAddress;
5773 uuid = UUID(sc_info.cacheUUID, sizeof(uuid_t));
5774 }
5775 dyld_process_info_release(process_info);
5776 }
5777 }
5778 }
5780 if (log && uuid.IsValid())
5781 LLDB_LOGF(log,
5782 "lldb's in-memory shared cache has a UUID of %s base address of "
5783 "0x%" PRIx64,
5784 uuid.GetAsString().c_str(), base_addr);
5785#endif
5786}
5787
5788static llvm::VersionTuple FindMinimumVersionInfo(DataExtractor &data,
5789 lldb::offset_t offset,
5790 size_t ncmds) {
5791 for (size_t i = 0; i < ncmds; i++) {
5792 const lldb::offset_t load_cmd_offset = offset;
5793 llvm::MachO::load_command lc = {};
5794 if (!ReadMachOCommand(data, offset, lc))
5795 break;
5796
5797 uint32_t version = 0;
5798 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
5799 lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
5800 lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
5801 lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
5802 // struct version_min_command {
5803 // uint32_t cmd; // LC_VERSION_MIN_*
5804 // uint32_t cmdsize;
5805 // uint32_t version; // X.Y.Z encoded in nibbles xxxx.yy.zz
5806 // uint32_t sdk;
5807 // };
5808 // We want to read version.
5809 version = data.GetU32(&offset);
5810 } else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
5811 // struct build_version_command {
5812 // uint32_t cmd; // LC_BUILD_VERSION
5813 // uint32_t cmdsize;
5814 // uint32_t platform;
5815 // uint32_t minos; // X.Y.Z encoded in nibbles xxxx.yy.zz
5816 // uint32_t sdk;
5817 // uint32_t ntools;
5818 // };
5819 // We want to read minos.
5820 offset += sizeof(uint32_t); // Skip over platform
5821 version = data.GetU32(&offset); // Extract minos
5822 }
5823
5824 if (version) {
5825 const uint32_t xxxx = version >> 16;
5826 const uint32_t yy = (version >> 8) & 0xffu;
5827 const uint32_t zz = version & 0xffu;
5828 if (xxxx)
5829 return llvm::VersionTuple(xxxx, yy, zz);
5830 }
5831 offset = load_cmd_offset + lc.cmdsize;
5832 }
5833 return llvm::VersionTuple();
5834}
5835
5842
5849
5851 return m_header.filetype == llvm::MachO::MH_DYLINKER;
5852}
5853
5855 // Dsymutil guarantees that the .debug_aranges accelerator is complete and can
5856 // be trusted by LLDB.
5857 return m_header.filetype == llvm::MachO::MH_DSYM;
5858}
5859
5863
5865 // Find the first address of the mach header which is the first non-zero file
5866 // sized section whose file offset is zero. This is the base file address of
5867 // the mach-o file which can be subtracted from the vmaddr of the other
5868 // segments found in memory and added to the load address
5869 ModuleSP module_sp = GetModule();
5870 if (!module_sp)
5871 return nullptr;
5872 SectionList *section_list = GetSectionList();
5873 if (!section_list)
5874 return nullptr;
5875
5876 // Some binaries can have a TEXT segment with a non-zero file offset.
5877 // Binaries in the shared cache are one example. Some hand-generated
5878 // binaries may not be laid out in the normal TEXT,DATA,LC_SYMTAB order
5879 // in the file, even though they're laid out correctly in vmaddr terms.
5880 SectionSP text_segment_sp =
5881 section_list->FindSectionByName(GetSegmentNameTEXT());
5882 if (text_segment_sp.get() && SectionIsLoadable(text_segment_sp.get()))
5883 return text_segment_sp.get();
5884
5885 const size_t num_sections = section_list->GetSize();
5886 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
5887 Section *section = section_list->GetSectionAtIndex(sect_idx).get();
5888 if (section->GetFileOffset() == 0 && SectionIsLoadable(section))
5889 return section;
5890 }
5891
5892 return nullptr;
5893}
5894
5896 assert(section.GetObjectFile() == this && "Wrong object file!");
5897 SectionSP segment = section.GetParent();
5898 if (!segment)
5899 return false;
5900
5901 const bool is_data_const_got =
5902 segment->GetName() == "__DATA_CONST" && section.GetName() == "__got";
5903 const bool is_auth_const_ptr =
5904 segment->GetName() == "__AUTH_CONST" &&
5905 (section.GetName() == "__auth_got" || section.GetName() == "__auth_ptr");
5906 return is_data_const_got || is_auth_const_ptr;
5907}
5908
5910 if (!section)
5911 return false;
5912 if (section->IsThreadSpecific())
5913 return false;
5914 if (GetModule().get() != section->GetModule().get())
5915 return false;
5916 // firmware style binaries with llvm gcov segment do
5917 // not have that segment mapped into memory.
5918 if (section->GetName() == GetSegmentNameLLVM_COV()) {
5919 const Strata strata = GetStrata();
5920 if (strata == eStrataKernel || strata == eStrataRawImage)
5921 return false;
5922 }
5923 // Be careful with __LINKEDIT and __DWARF segments
5924 if (section->GetName() == GetSegmentNameLINKEDIT() ||
5925 section->GetName() == GetSegmentNameDWARF()) {
5926 // Only map __LINKEDIT and __DWARF if we have an in memory image and
5927 // this isn't a kernel binary like a kext or mach_kernel.
5928 const bool is_memory_image = (bool)m_process_wp.lock();
5929 const Strata strata = GetStrata();
5930 if (is_memory_image == false || strata == eStrataKernel)
5931 return false;
5932 }
5933 return true;
5934}
5935
5937 lldb::addr_t header_load_address, const Section *header_section,
5938 const Section *section) {
5939 ModuleSP module_sp = GetModule();
5940 if (module_sp && header_section && section &&
5941 header_load_address != LLDB_INVALID_ADDRESS) {
5942 lldb::addr_t file_addr = header_section->GetFileAddress();
5943 if (file_addr != LLDB_INVALID_ADDRESS && SectionIsLoadable(section))
5944 return section->GetFileAddress() - file_addr + header_load_address;
5945 }
5946 return LLDB_INVALID_ADDRESS;
5947}
5948
5950 bool value_is_offset) {
5952 ModuleSP module_sp = GetModule();
5953 if (!module_sp)
5954 return false;
5955
5956 SectionList *section_list = GetSectionList();
5957 if (!section_list)
5958 return false;
5959
5960 size_t num_loaded_sections = 0;
5961 const size_t num_sections = section_list->GetSize();
5962
5963 // Warn if some top-level segments map to the same address. The binary may be
5964 // malformed.
5965 const bool warn_multiple = true;
5966
5967 if (log) {
5968 StreamString logmsg;
5969 logmsg << "ObjectFileMachO::SetLoadAddress ";
5970 if (GetFileSpec())
5971 logmsg << "path='" << GetFileSpec().GetPath() << "' ";
5972 if (GetUUID()) {
5973 logmsg << "uuid=" << GetUUID().GetAsString();
5974 }
5975 LLDB_LOGF(log, "%s", logmsg.GetData());
5976 }
5977 if (value_is_offset) {
5978 // "value" is an offset to apply to each top level segment
5979 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
5980 // Iterate through the object file sections to find all of the
5981 // sections that size on disk (to avoid __PAGEZERO) and load them
5982 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
5983 if (SectionIsLoadable(section_sp.get())) {
5984 LLDB_LOG(
5985 log,
5986 "ObjectFileMachO::SetLoadAddress segment '{0}' load addr is {1:x}",
5987 section_sp->GetName(), section_sp->GetFileAddress() + value);
5988 if (target.SetSectionLoadAddress(section_sp,
5989 section_sp->GetFileAddress() + value,
5990 warn_multiple))
5991 ++num_loaded_sections;
5992 }
5993 }
5994 } else {
5995 // "value" is the new base address of the mach_header, adjust each
5996 // section accordingly
5997
5998 Section *mach_header_section = GetMachHeaderSection();
5999 if (mach_header_section) {
6000 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6001 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
6002
6003 lldb::addr_t section_load_addr =
6005 value, mach_header_section, section_sp.get());
6006 if (section_load_addr != LLDB_INVALID_ADDRESS) {
6007 LLDB_LOG(log,
6008 "ObjectFileMachO::SetLoadAddress segment '{0}' load addr is "
6009 "{1:x}",
6010 section_sp->GetName(), section_load_addr);
6011 if (target.SetSectionLoadAddress(section_sp, section_load_addr,
6012 warn_multiple))
6013 ++num_loaded_sections;
6014 }
6015 }
6016 }
6017 }
6018 return num_loaded_sections > 0;
6019}
6020
6022 uint32_t version; // currently 1
6023 uint32_t imgcount; // number of binary images
6024 uint64_t entries_fileoff; // file offset in the corefile of where the array of
6025 // struct entry's begin.
6026 uint32_t entries_size; // size of 'struct entry'.
6027 uint32_t unused;
6028};
6029
6031 uint64_t filepath_offset; // offset in corefile to c-string of the file path,
6032 // UINT64_MAX if unavailable.
6033 uuid_t uuid; // uint8_t[16]. should be set to all zeroes if
6034 // uuid is unknown.
6035 uint64_t load_address; // UINT64_MAX if unknown.
6036 uint64_t seg_addrs_offset; // offset to the array of struct segment_vmaddr's.
6037 uint32_t segment_count; // The number of segments for this binary.
6038 uint32_t unused;
6039
6042 memset(&uuid, 0, sizeof(uuid_t));
6043 segment_count = 0;
6046 unused = 0;
6047 }
6050 memcpy(&uuid, &rhs.uuid, sizeof(uuid_t));
6054 unused = rhs.unused;
6055 }
6056};
6057
6059 char segname[16];
6060 uint64_t vmaddr;
6061 uint64_t unused;
6062
6064 memset(&segname, 0, 16);
6066 unused = 0;
6067 }
6069 memcpy(&segname, &rhs.segname, 16);
6070 vmaddr = rhs.vmaddr;
6071 unused = rhs.unused;
6072 }
6073};
6074
6075// Write the payload for the "all image infos" LC_NOTE into
6076// the supplied all_image_infos_payload, assuming that this
6077// will be written into the corefile starting at
6078// initial_file_offset.
6079//
6080// The placement of this payload is a little tricky. We're
6081// laying this out as
6082//
6083// 1. header (struct all_image_info_header)
6084// 2. Array of fixed-size (struct image_entry)'s, one
6085// per binary image present in the process.
6086// 3. Arrays of (struct segment_vmaddr)'s, a varying number
6087// for each binary image.
6088// 4. Variable length c-strings of binary image filepaths,
6089// one per binary.
6090//
6091// To compute where everything will be laid out in the
6092// payload, we need to iterate over the images and calculate
6093// how many segment_vmaddr structures each image will need,
6094// and how long each image's filepath c-string is. There
6095// are some multiple passes over the image list while calculating
6096// everything.
6097
6098static offset_t
6100 offset_t initial_file_offset,
6101 StreamString &all_image_infos_payload,
6103 Target &target = process_sp->GetTarget();
6104 ModuleList modules = target.GetImages();
6105
6106 // stack-only corefiles have no reason to include binaries that
6107 // are not executing; we're trying to make the smallest corefile
6108 // we can, so leave the rest out.
6110 modules.Clear();
6111
6112 std::set<std::string> executing_uuids;
6113 std::vector<ThreadSP> thread_list =
6114 process_sp->CalculateCoreFileThreadList(options);
6115 for (const ThreadSP &thread_sp : thread_list) {
6116 uint32_t stack_frame_count = thread_sp->GetStackFrameCount();
6117 for (uint32_t j = 0; j < stack_frame_count; j++) {
6118 StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);
6119 Address pc = stack_frame_sp->GetFrameCodeAddress();
6120 ModuleSP module_sp = pc.GetModule();
6121 if (module_sp) {
6122 UUID uuid = module_sp->GetUUID();
6123 if (uuid.IsValid()) {
6124 executing_uuids.insert(uuid.GetAsString());
6125 modules.AppendIfNeeded(module_sp);
6126 }
6127 }
6128 }
6129 }
6130 size_t modules_count = modules.GetSize();
6131
6132 struct all_image_infos_header infos;
6133 infos.version = 1;
6134 infos.imgcount = modules_count;
6135 infos.entries_size = sizeof(image_entry);
6136 infos.entries_fileoff = initial_file_offset + sizeof(all_image_infos_header);
6137 infos.unused = 0;
6138
6139 all_image_infos_payload.PutHex32(infos.version);
6140 all_image_infos_payload.PutHex32(infos.imgcount);
6141 all_image_infos_payload.PutHex64(infos.entries_fileoff);
6142 all_image_infos_payload.PutHex32(infos.entries_size);
6143 all_image_infos_payload.PutHex32(infos.unused);
6144
6145 // First create the structures for all of the segment name+vmaddr vectors
6146 // for each module, so we will know the size of them as we add the
6147 // module entries.
6148 std::vector<std::vector<segment_vmaddr>> modules_segment_vmaddrs;
6149 for (size_t i = 0; i < modules_count; i++) {
6150 ModuleSP module = modules.GetModuleAtIndex(i);
6151
6152 SectionList *sections = module->GetSectionList();
6153 size_t sections_count = sections->GetSize();
6154 std::vector<segment_vmaddr> segment_vmaddrs;
6155 for (size_t j = 0; j < sections_count; j++) {
6156 SectionSP section = sections->GetSectionAtIndex(j);
6157 if (!section->GetParent().get()) {
6158 addr_t vmaddr = section->GetLoadBaseAddress(&target);
6159 if (vmaddr == LLDB_INVALID_ADDRESS)
6160 continue;
6161 llvm::StringRef name = section->GetName();
6162 segment_vmaddr seg_vmaddr;
6163 // This is the uncommon case where strncpy is exactly
6164 // the right one, doesn't need to be null-terminated.
6165 // The segment name in a Mach-O LC_SEGMENT/LC_SEGMENT_64 is char[16] and
6166 // is not guaranteed to be null-terminated if all 16 characters are
6167 // used.
6168 // coverity[buffer_size_warning]
6169 strncpy(seg_vmaddr.segname, name.data(),
6170 std::min(name.size(), sizeof(seg_vmaddr.segname)));
6171 seg_vmaddr.vmaddr = vmaddr;
6172 seg_vmaddr.unused = 0;
6173 segment_vmaddrs.push_back(seg_vmaddr);
6174 }
6175 }
6176 modules_segment_vmaddrs.push_back(segment_vmaddrs);
6177 }
6178
6179 offset_t size_of_vmaddr_structs = 0;
6180 for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6181 size_of_vmaddr_structs +=
6182 modules_segment_vmaddrs[i].size() * sizeof(segment_vmaddr);
6183 }
6184
6185 offset_t size_of_filepath_cstrings = 0;
6186 for (size_t i = 0; i < modules_count; i++) {
6187 ModuleSP module_sp = modules.GetModuleAtIndex(i);
6188 size_of_filepath_cstrings += module_sp->GetFileSpec().GetPath().size() + 1;
6189 }
6190
6191 // Calculate the file offsets of our "all image infos" payload in the
6192 // corefile. initial_file_offset the original value passed in to this method.
6193
6194 offset_t start_of_entries =
6195 initial_file_offset + sizeof(all_image_infos_header);
6196 offset_t start_of_seg_vmaddrs =
6197 start_of_entries + sizeof(image_entry) * modules_count;
6198 offset_t start_of_filenames = start_of_seg_vmaddrs + size_of_vmaddr_structs;
6199
6200 offset_t final_file_offset = start_of_filenames + size_of_filepath_cstrings;
6201
6202 // Now write the one-per-module 'struct image_entry' into the
6203 // StringStream; keep track of where the struct segment_vmaddr
6204 // entries for each module will end up in the corefile.
6205
6206 offset_t current_string_offset = start_of_filenames;
6207 offset_t current_segaddrs_offset = start_of_seg_vmaddrs;
6208 for (size_t i = 0; i < modules_count; i++) {
6209 ModuleSP module_sp = modules.GetModuleAtIndex(i);
6210
6211 struct image_entry ent;
6212 memcpy(&ent.uuid, module_sp->GetUUID().GetBytes().data(), sizeof(ent.uuid));
6213 if (modules_segment_vmaddrs[i].size() > 0) {
6214 ent.segment_count = modules_segment_vmaddrs[i].size();
6215 ent.seg_addrs_offset = current_segaddrs_offset;
6216 }
6217 ent.filepath_offset = current_string_offset;
6218 ObjectFile *objfile = module_sp->GetObjectFile();
6219 if (objfile) {
6220 Address base_addr(objfile->GetBaseAddress());
6221 if (base_addr.IsValid()) {
6222 ent.load_address = base_addr.GetLoadAddress(&target);
6223 }
6224 }
6225
6226 all_image_infos_payload.PutHex64(ent.filepath_offset);
6227 all_image_infos_payload.PutRawBytes(ent.uuid, sizeof(ent.uuid));
6228 all_image_infos_payload.PutHex64(ent.load_address);
6229 all_image_infos_payload.PutHex64(ent.seg_addrs_offset);
6230 all_image_infos_payload.PutHex32(ent.segment_count);
6231
6232 if (executing_uuids.find(module_sp->GetUUID().GetAsString()) !=
6233 executing_uuids.end())
6234 all_image_infos_payload.PutHex32(1);
6235 else
6236 all_image_infos_payload.PutHex32(0);
6237
6238 current_segaddrs_offset += ent.segment_count * sizeof(segment_vmaddr);
6239 current_string_offset += module_sp->GetFileSpec().GetPath().size() + 1;
6240 }
6241
6242 // Now write the struct segment_vmaddr entries into the StringStream.
6243
6244 for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6245 if (modules_segment_vmaddrs[i].size() == 0)
6246 continue;
6247 for (struct segment_vmaddr segvm : modules_segment_vmaddrs[i]) {
6248 all_image_infos_payload.PutRawBytes(segvm.segname, sizeof(segvm.segname));
6249 all_image_infos_payload.PutHex64(segvm.vmaddr);
6250 all_image_infos_payload.PutHex64(segvm.unused);
6251 }
6252 }
6253
6254 for (size_t i = 0; i < modules_count; i++) {
6255 ModuleSP module_sp = modules.GetModuleAtIndex(i);
6256 std::string filepath = module_sp->GetFileSpec().GetPath();
6257 all_image_infos_payload.PutRawBytes(filepath.data(), filepath.size() + 1);
6258 }
6259
6260 return final_file_offset;
6261}
6262
6263// Temp struct used to combine contiguous memory regions with
6264// identical permissions.
6270
6273 Status &error) {
6274 // The FileSpec and Process are already checked in PluginManager::SaveCore.
6275 assert(options.GetOutputFile().has_value());
6276 assert(process_sp);
6277 const FileSpec outfile = options.GetOutputFile().value();
6278
6279 // MachO defaults to dirty pages
6282
6283 Target &target = process_sp->GetTarget();
6284 const ArchSpec target_arch = target.GetArchitecture();
6285 const llvm::Triple &target_triple = target_arch.GetTriple();
6286 if (target_triple.getVendor() == llvm::Triple::Apple &&
6287 (target_triple.getOS() == llvm::Triple::MacOSX ||
6288 target_triple.getOS() == llvm::Triple::IOS ||
6289 target_triple.getOS() == llvm::Triple::WatchOS ||
6290 target_triple.getOS() == llvm::Triple::TvOS ||
6291 target_triple.getOS() == llvm::Triple::BridgeOS ||
6292 target_triple.getOS() == llvm::Triple::XROS)) {
6293 bool make_core = false;
6294 switch (target_arch.GetMachine()) {
6295 case llvm::Triple::aarch64:
6296 case llvm::Triple::aarch64_32:
6297 case llvm::Triple::arm:
6298 case llvm::Triple::thumb:
6299 case llvm::Triple::x86:
6300 case llvm::Triple::x86_64:
6301 make_core = true;
6302 break;
6303 default:
6305 "unsupported core architecture: %s", target_triple.str().c_str());
6306 break;
6307 }
6308
6309 if (make_core) {
6310 CoreFileMemoryRanges core_ranges;
6311 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6312 if (error.Success()) {
6313 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
6314 const ByteOrder byte_order = target_arch.GetByteOrder();
6315 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6316 for (const auto &core_range_info : core_ranges) {
6317 // TODO: Refactor RangeDataVector to have a data iterator.
6318 const auto &core_range = core_range_info.data;
6319 uint32_t cmd_type = LC_SEGMENT_64;
6320 uint32_t segment_size = sizeof(llvm::MachO::segment_command_64);
6321 if (addr_byte_size == 4) {
6322 cmd_type = LC_SEGMENT;
6323 segment_size = sizeof(llvm::MachO::segment_command);
6324 }
6325 // Skip any ranges with no read/write/execute permissions and empty
6326 // ranges.
6327 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6328 continue;
6329 uint32_t vm_prot = 0;
6330 if (core_range.lldb_permissions & ePermissionsReadable)
6331 vm_prot |= VM_PROT_READ;
6332 if (core_range.lldb_permissions & ePermissionsWritable)
6333 vm_prot |= VM_PROT_WRITE;
6334 if (core_range.lldb_permissions & ePermissionsExecutable)
6335 vm_prot |= VM_PROT_EXECUTE;
6336 const addr_t vm_addr = core_range.range.start();
6337 const addr_t vm_size = core_range.range.size();
6338 llvm::MachO::segment_command_64 segment = {
6339 cmd_type, // uint32_t cmd;
6340 segment_size, // uint32_t cmdsize;
6341 {0}, // char segname[16];
6342 vm_addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
6343 vm_size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
6344 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
6345 vm_size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
6346 vm_prot, // uint32_t maxprot;
6347 vm_prot, // uint32_t initprot;
6348 0, // uint32_t nsects;
6349 0}; // uint32_t flags;
6350 segment_load_commands.push_back(segment);
6351 }
6352
6353 StreamString buffer(Stream::eBinary, byte_order);
6354
6355 llvm::MachO::mach_header_64 mach_header;
6356 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6357 mach_header.cputype = target_arch.GetMachOCPUType();
6358 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
6359 mach_header.filetype = MH_CORE;
6360 mach_header.ncmds = segment_load_commands.size();
6361 mach_header.flags = 0;
6362 mach_header.reserved = 0;
6363 ThreadList &thread_list = process_sp->GetThreadList();
6364 const uint32_t num_threads = thread_list.GetSize();
6365
6366 // Make an array of LC_THREAD data items. Each one contains the
6367 // contents of the LC_THREAD load command. The data doesn't contain
6368 // the load command + load command size, we will add the load command
6369 // and load command size as we emit the data.
6370 std::vector<StreamString> LC_THREAD_datas(num_threads);
6371 for (auto &LC_THREAD_data : LC_THREAD_datas) {
6372 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
6373 LC_THREAD_data.SetByteOrder(byte_order);
6374 }
6375 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6376 ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
6377 if (thread_sp) {
6378 switch (mach_header.cputype) {
6379 case llvm::MachO::CPU_TYPE_ARM64:
6380 case llvm::MachO::CPU_TYPE_ARM64_32:
6382 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6383 break;
6384
6385 case llvm::MachO::CPU_TYPE_ARM:
6387 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6388 break;
6389
6390 case llvm::MachO::CPU_TYPE_X86_64:
6392 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6393 break;
6394
6395 case llvm::MachO::CPU_TYPE_RISCV:
6397 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6398 break;
6399 }
6400 }
6401 }
6402
6403 // The size of the load command is the size of the segments...
6404 if (addr_byte_size == 8) {
6405 mach_header.sizeofcmds = segment_load_commands.size() *
6406 sizeof(llvm::MachO::segment_command_64);
6407 } else {
6408 mach_header.sizeofcmds = segment_load_commands.size() *
6409 sizeof(llvm::MachO::segment_command);
6410 }
6411
6412 // and the size of all LC_THREAD load command
6413 for (const auto &LC_THREAD_data : LC_THREAD_datas) {
6414 ++mach_header.ncmds;
6415 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6416 }
6417
6418 // Bits will be set to indicate which bits are NOT used in
6419 // addressing in this process or 0 for unknown.
6420 uint64_t address_mask = process_sp->GetCodeAddressMask();
6421 if (address_mask != LLDB_INVALID_ADDRESS_MASK) {
6422 // LC_NOTE "addrable bits"
6423 mach_header.ncmds++;
6424 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
6425 }
6426
6427 // LC_NOTE "process metadata"
6428 mach_header.ncmds++;
6429 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
6430
6431 // LC_NOTE "all image infos"
6432 mach_header.ncmds++;
6433 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
6434
6435 // Write the mach header
6436 buffer.PutHex32(mach_header.magic);
6437 buffer.PutHex32(mach_header.cputype);
6438 buffer.PutHex32(mach_header.cpusubtype);
6439 buffer.PutHex32(mach_header.filetype);
6440 buffer.PutHex32(mach_header.ncmds);
6441 buffer.PutHex32(mach_header.sizeofcmds);
6442 buffer.PutHex32(mach_header.flags);
6443 if (addr_byte_size == 8) {
6444 buffer.PutHex32(mach_header.reserved);
6445 }
6446
6447 // Skip the mach header and all load commands and align to the next
6448 // 0x1000 byte boundary
6449 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
6450
6451 file_offset = llvm::alignTo(file_offset, 16);
6452 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6453
6454 // Add "addrable bits" LC_NOTE when an address mask is available
6455 if (address_mask != LLDB_INVALID_ADDRESS_MASK) {
6456 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6457 new LCNoteEntry(byte_order));
6458 addrable_bits_lcnote_up->name = "addrable bits";
6459 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6460 int bits = std::bitset<64>(~address_mask).count();
6461 addrable_bits_lcnote_up->payload.PutHex32(4); // version
6462 addrable_bits_lcnote_up->payload.PutHex32(
6463 bits); // # of bits used for low addresses
6464 addrable_bits_lcnote_up->payload.PutHex32(
6465 bits); // # of bits used for high addresses
6466 addrable_bits_lcnote_up->payload.PutHex32(0); // reserved
6467
6468 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6469
6470 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6471 }
6472
6473 // Add "process metadata" LC_NOTE
6474 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6475 new LCNoteEntry(byte_order));
6476 thread_extrainfo_lcnote_up->name = "process metadata";
6477 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6478
6480 std::make_shared<StructuredData::Dictionary>());
6482 std::make_shared<StructuredData::Array>());
6483 for (const ThreadSP &thread_sp :
6484 process_sp->CalculateCoreFileThreadList(options)) {
6486 std::make_shared<StructuredData::Dictionary>());
6487 thread->AddIntegerItem("thread_id", thread_sp->GetID());
6488 threads->AddItem(thread);
6489 }
6490 dict->AddItem("threads", threads);
6491 StreamString strm;
6492 dict->Dump(strm, /* pretty */ false);
6493 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.GetData(),
6494 strm.GetSize());
6495
6496 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6497 file_offset = llvm::alignTo(file_offset, 16);
6498 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6499
6500 // Add "all image infos" LC_NOTE
6501 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6502 new LCNoteEntry(byte_order));
6503 all_image_infos_lcnote_up->name = "all image infos";
6504 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6505 file_offset = CreateAllImageInfosPayload(
6506 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6507 options);
6508 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6509
6510 // Add LC_NOTE load commands
6511 for (auto &lcnote : lc_notes) {
6512 // Add the LC_NOTE load command to the file.
6513 buffer.PutHex32(LC_NOTE);
6514 buffer.PutHex32(sizeof(llvm::MachO::note_command));
6515 char namebuf[16];
6516 memset(namebuf, 0, sizeof(namebuf));
6517 // This is the uncommon case where strncpy is exactly
6518 // the right one, doesn't need to be null-terminated.
6519 // LC_NOTE name field is char[16] and is not guaranteed to be
6520 // null-terminated.
6521 // coverity[buffer_size_warning]
6522 strncpy(namebuf, lcnote->name.c_str(), sizeof(namebuf));
6523 buffer.PutRawBytes(namebuf, sizeof(namebuf));
6524 buffer.PutHex64(lcnote->payload_file_offset);
6525 buffer.PutHex64(lcnote->payload.GetSize());
6526 }
6527
6528 // Align to 4096-byte page boundary for the LC_SEGMENTs.
6529 file_offset = llvm::alignTo(file_offset, 4096);
6530
6531 for (auto &segment : segment_load_commands) {
6532 segment.fileoff = file_offset;
6533 file_offset += segment.filesize;
6534 }
6535
6536 // Write out all of the LC_THREAD load commands
6537 for (const auto &LC_THREAD_data : LC_THREAD_datas) {
6538 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6539 buffer.PutHex32(LC_THREAD);
6540 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
6541 buffer.Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6542 }
6543
6544 // Write out all of the segment load commands
6545 for (const auto &segment : segment_load_commands) {
6546 buffer.PutHex32(segment.cmd);
6547 buffer.PutHex32(segment.cmdsize);
6548 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
6549 if (addr_byte_size == 8) {
6550 buffer.PutHex64(segment.vmaddr);
6551 buffer.PutHex64(segment.vmsize);
6552 buffer.PutHex64(segment.fileoff);
6553 buffer.PutHex64(segment.filesize);
6554 } else {
6555 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
6556 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
6557 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
6558 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
6559 }
6560 buffer.PutHex32(segment.maxprot);
6561 buffer.PutHex32(segment.initprot);
6562 buffer.PutHex32(segment.nsects);
6563 buffer.PutHex32(segment.flags);
6564 }
6565
6566 std::string core_file_path(outfile.GetPath());
6567 auto core_file = FileSystem::Instance().Open(
6570 if (!core_file) {
6571 error = Status::FromError(core_file.takeError());
6572 } else {
6573 // Read 1 page at a time
6574 uint8_t bytes[0x1000];
6575 // Write the mach header and load commands out to the core file
6576 size_t bytes_written = buffer.GetString().size();
6577 error =
6578 core_file.get()->Write(buffer.GetString().data(), bytes_written);
6579 if (error.Success()) {
6580
6581 for (auto &lcnote : lc_notes) {
6582 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6583 -1) {
6585 "Unable to seek to corefile pos "
6586 "to write '%s' LC_NOTE payload",
6587 lcnote->name.c_str());
6588 return false;
6589 }
6590 bytes_written = lcnote->payload.GetSize();
6591 error = core_file.get()->Write(lcnote->payload.GetData(),
6592 bytes_written);
6593 if (!error.Success())
6594 return false;
6595 }
6596
6597 // Now write the file data for all memory segments in the process
6598 for (const auto &segment : segment_load_commands) {
6599 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6601 "unable to seek to offset 0x%" PRIx64 " in '%s'",
6602 segment.fileoff, core_file_path.c_str());
6603 break;
6604 }
6605
6606 target.GetDebugger().GetAsyncOutputStream()->Printf(
6607 "Saving %" PRId64
6608 " bytes of data for memory region at 0x%" PRIx64 "\n",
6609 segment.vmsize, segment.vmaddr);
6610 addr_t bytes_left = segment.vmsize;
6611 addr_t addr = segment.vmaddr;
6613 while (bytes_left > 0 && error.Success()) {
6614 const size_t bytes_to_read =
6615 bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
6616
6617 // In a savecore setting, we don't really care about caching,
6618 // as the data is dumped and very likely never read again,
6619 // so we call ReadMemoryFromInferior to bypass it.
6620 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6621 addr, bytes, bytes_to_read, memory_read_error);
6622
6623 if (bytes_read == bytes_to_read) {
6624 size_t bytes_written = bytes_read;
6625 error = core_file.get()->Write(bytes, bytes_written);
6626 bytes_left -= bytes_read;
6627 addr += bytes_read;
6628 } else {
6629 // Some pages within regions are not readable, those should
6630 // be zero filled
6631 memset(bytes, 0, bytes_to_read);
6632 size_t bytes_written = bytes_to_read;
6633 error = core_file.get()->Write(bytes, bytes_written);
6634 bytes_left -= bytes_to_read;
6635 addr += bytes_to_read;
6636 }
6637 }
6638 }
6639 }
6640 }
6641 }
6642 }
6643 return true; // This is the right plug to handle saving core files for
6644 // this process
6645 }
6646 return false;
6647}
6648
6651 MachOCorefileAllImageInfos image_infos;
6654
6655 auto lc_notes = FindLC_NOTEByName("all image infos");
6656 for (auto lc_note : lc_notes) {
6657 offset_t payload_offset = std::get<0>(lc_note);
6658 // Read the struct all_image_infos_header.
6659 uint32_t version = m_data_nsp->GetU32(&payload_offset);
6660 if (version != 1) {
6661 return image_infos;
6662 }
6663 uint32_t imgcount = m_data_nsp->GetU32(&payload_offset);
6664 uint64_t entries_fileoff = m_data_nsp->GetU64(&payload_offset);
6665 // 'entries_size' is not used, nor is the 'unused' entry.
6666 // offset += 4; // uint32_t entries_size;
6667 // offset += 4; // uint32_t unused;
6668
6669 LLDB_LOGF(log, "LC_NOTE 'all image infos' found version %d with %d images",
6670 version, imgcount);
6671 payload_offset = entries_fileoff;
6672 for (uint32_t i = 0; i < imgcount; i++) {
6673 // Read the struct image_entry.
6674 offset_t filepath_offset = m_data_nsp->GetU64(&payload_offset);
6675 uuid_t uuid;
6676 memcpy(&uuid, m_data_nsp->GetData(&payload_offset, sizeof(uuid_t)),
6677 sizeof(uuid_t));
6678 uint64_t load_address = m_data_nsp->GetU64(&payload_offset);
6679 offset_t seg_addrs_offset = m_data_nsp->GetU64(&payload_offset);
6680 uint32_t segment_count = m_data_nsp->GetU32(&payload_offset);
6681 uint32_t currently_executing = m_data_nsp->GetU32(&payload_offset);
6682
6684 image_entry.filename =
6685 (const char *)m_data_nsp->GetCStr(&filepath_offset);
6686 image_entry.uuid = UUID(uuid, sizeof(uuid_t));
6687 image_entry.load_address = load_address;
6688 image_entry.currently_executing = currently_executing;
6689
6690 offset_t seg_vmaddrs_offset = seg_addrs_offset;
6691 for (uint32_t j = 0; j < segment_count; j++) {
6692 char segname[17];
6693 m_data_nsp->CopyData(seg_vmaddrs_offset, 16, segname);
6694 segname[16] = '\0';
6695 seg_vmaddrs_offset += 16;
6696 uint64_t vmaddr = m_data_nsp->GetU64(&seg_vmaddrs_offset);
6697 seg_vmaddrs_offset += 8; /* unused */
6698
6699 std::tuple<ConstString, addr_t> new_seg{ConstString(segname), vmaddr};
6700 image_entry.segment_load_addresses.push_back(new_seg);
6701 }
6702 LLDB_LOGF(log, " image entry: %s %s 0x%" PRIx64 " %s",
6703 image_entry.filename.c_str(),
6704 image_entry.uuid.GetAsString().c_str(),
6706 image_entry.currently_executing ? "currently executing"
6707 : "not currently executing");
6708 image_infos.all_image_infos.push_back(image_entry);
6709 }
6710 }
6711
6712 lc_notes = FindLC_NOTEByName("load binary");
6713 for (auto lc_note : lc_notes) {
6714 offset_t payload_offset = std::get<0>(lc_note);
6715 uint32_t version = m_data_nsp->GetU32(&payload_offset);
6716 if (version == 1) {
6717 uuid_t uuid;
6718 memcpy(&uuid, m_data_nsp->GetData(&payload_offset, sizeof(uuid_t)),
6719 sizeof(uuid_t));
6720 uint64_t load_address = m_data_nsp->GetU64(&payload_offset);
6721 uint64_t slide = m_data_nsp->GetU64(&payload_offset);
6722 std::string filename = m_data_nsp->GetCStr(&payload_offset);
6723
6725 image_entry.filename = filename;
6726 image_entry.uuid = UUID(uuid, sizeof(uuid_t));
6727 image_entry.load_address = load_address;
6728 image_entry.slide = slide;
6729 image_entry.currently_executing = true;
6730 image_infos.all_image_infos.push_back(image_entry);
6731 LLDB_LOGF(log,
6732 "LC_NOTE 'load binary' found, filename %s uuid %s load "
6733 "address 0x%" PRIx64 " slide 0x%" PRIx64,
6734 filename.c_str(),
6735 image_entry.uuid.IsValid()
6736 ? image_entry.uuid.GetAsString().c_str()
6737 : "00000000-0000-0000-0000-000000000000",
6738 load_address, slide);
6739 }
6740 }
6741
6742 return image_infos;
6743}
6744
6748
6749 bool found_platform_binary = false;
6750 ModuleList added_modules;
6751
6752 llvm::SmallVector<const MachOCorefileImageEntry *> pending_images;
6753 std::vector<DynamicLoader::BinarySpec> pending_specs;
6754
6755 for (MachOCorefileImageEntry &image : image_infos.all_image_infos) {
6756 // If this is a platform binary, it has been loaded (or registered with
6757 // the DynamicLoader to be loaded), we don't need to do any further
6758 // processing. We're not going to call ModulesDidLoad on this in this
6759 // method, so notify==true.
6760 //
6761 // Setting up a platform binary can replace the Target's platform and
6762 // dynamic loader, so no image is searched for until this loop has run to
6763 // the end.
6764 if (process.GetTarget()
6765 .GetDebugger()
6768 true /* notify */)) {
6769 LLDB_LOGF(log,
6770 "ObjectFileMachO::%s binary at 0x%" PRIx64
6771 " is a platform binary, has been handled by a Platform plugin.",
6772 __FUNCTION__, image.load_address);
6773 found_platform_binary = true;
6774 continue;
6775 }
6776
6777 bool value_is_offset = image.load_address == LLDB_INVALID_ADDRESS;
6778 uint64_t value = value_is_offset ? image.slide : image.load_address;
6779 if (value_is_offset && value == LLDB_INVALID_ADDRESS) {
6780 // We have neither address nor slide; so we will find the binary
6781 // by UUID and load it at slide/offset 0.
6782 value = 0;
6783 }
6784
6785 // We have either a UUID, or we have a load address which
6786 // and can try to read load commands and find a UUID.
6787 if (!image.uuid.IsValid() &&
6788 (value_is_offset || value == LLDB_INVALID_ADDRESS))
6789 continue;
6790
6792 bin_spec.name = image.filename;
6793 bin_spec.uuid = image.uuid;
6794 bin_spec.value = value;
6795 bin_spec.value_is_offset = value_is_offset;
6797 bin_spec.notify = false;
6798 // Userland Darwin binaries will have segment load addresses via
6799 // the `all image infos` LC_NOTE.
6800 bin_spec.set_address_in_target = image.segment_load_addresses.empty();
6802 !image.segment_load_addresses.empty();
6803
6804 pending_images.push_back(&image);
6805 pending_specs.push_back(std::move(bin_spec));
6806 }
6807
6808 DynamicLoader::LocateBinaries(&process, pending_specs);
6809
6810 for (auto [image, bin_spec] :
6811 llvm::zip_equal(pending_images, pending_specs)) {
6812 ModuleSP module_sp;
6813 if (llvm::Expected<ModuleSP> loaded =
6814 DynamicLoader::LoadBinaryInTarget(&process, bin_spec)) {
6815 module_sp = *loaded;
6816 } else if (bin_spec.force_symbol_search) {
6818 << llvm::toString(loaded.takeError()) << "\n";
6819 } else {
6820 // A corefile image that isn't on this machine is routine, and has
6821 // already been logged.
6822 llvm::consumeError(loaded.takeError());
6823 }
6824
6825 if (!module_sp)
6826 continue;
6827
6828 added_modules.Append(module_sp, false /* notify */);
6829
6830 // We have a list of segment load address
6831 if (image->segment_load_addresses.size() > 0) {
6832 if (log) {
6833 std::string uuidstr = image->uuid.GetAsString();
6834 log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
6835 "UUID %s with section load addresses",
6836 module_sp->GetFileSpec().GetPath().c_str(),
6837 uuidstr.c_str());
6838 }
6839 ObjectFile *objfile = module_sp->GetObjectFile();
6840 SectionList *sectlist = objfile ? objfile->GetSectionList() : nullptr;
6841 for (auto name_vmaddr_tuple : image->segment_load_addresses) {
6842 if (sectlist) {
6843 SectionSP sect_sp =
6844 sectlist->FindSectionByName(std::get<0>(name_vmaddr_tuple));
6845 if (sect_sp) {
6847 sect_sp, std::get<1>(name_vmaddr_tuple));
6848 }
6849 }
6850 }
6851 } else {
6852 if (log) {
6853 std::string uuidstr = image->uuid.GetAsString();
6854 log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
6855 "UUID %s with %s 0x%" PRIx64,
6856 module_sp->GetFileSpec().GetPath().c_str(), uuidstr.c_str(),
6857 bin_spec.value_is_offset ? "slide" : "load address",
6858 bin_spec.value);
6859 }
6860 bool changed;
6861 module_sp->SetLoadAddress(process.GetTarget(), bin_spec.value,
6862 bin_spec.value_is_offset, changed);
6863 }
6864 }
6865
6866 if (added_modules.GetSize() > 0) {
6867 process.GetTarget().ModulesDidLoad(added_modules);
6868 process.Flush();
6869 return true;
6870 }
6871 // Return true if the only binary we found was the platform binary,
6872 // and it was loaded outside the scope of this method.
6873 if (found_platform_binary)
6874 return true;
6875
6876 // No binaries.
6877 return false;
6878}
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:91
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)
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()
bool IsSharedCacheBinary() const override
Tells whether this object file is part of a shared cache.
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:710
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:375
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:465
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.
Definition ArchSpec.cpp:909
uint32_t GetMachOCPUSubType() const
Definition ArchSpec.cpp:698
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
Definition ArchSpec.h:517
uint32_t GetMachOCPUType() const
Definition ArchSpec.cpp:694
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:759
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:702
A uniqued constant string class.
Definition ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
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:234
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:36
void SetDemangledName(ConstString name)
Definition Mangled.h:161
ConstString GetDemangledName() const
Demangled name get accessor.
Definition Mangled.cpp:238
void SetMangledName(ConstString name)
Definition Mangled.h:163
void SetValue(ConstString name)
Set the string value in this object.
Definition Mangled.cpp:219
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition Mangled.cpp:297
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A collection class for Module objects.
Definition ModuleList.h:127
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:803
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:806
const lldb::addr_t m_memory_addr
Set if the object file only exists in memory.
Definition ObjectFile.h:798
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:792
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:787
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:284
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:695
lldb::ProcessWP m_process_wp
Definition ObjectFile.h:796
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:789
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:472
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:6282
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
Definition Process.cpp:3134
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:192
void SetReExportedSymbolName(ConstString name)
Definition Symbol.cpp:222
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
void SetIsWeak(bool b)
Definition Symbol.h:235
uint32_t GetFlags() const
Definition Symbol.h:203
bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
Definition Symbol.cpp:231
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:470
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 SetIsSynthetic(bool b)
Definition Symbol.h:215
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 * FindSymbolByID(lldb::user_id_t uid) const
Definition Symtab.cpp:217
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:1014
size_t GetNumSymbols() const
Definition Symtab.cpp:75
MemoryModuleLoadLevel GetMemoryModuleLoadLevel() const
Definition Target.cpp:5863
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:1979
Debugger & GetDebugger() const
Definition Target.h:1366
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1283
const ArchSpec & GetArchitecture() const
Definition Target.h:1325
bool SetSectionLoadAddress(const lldb::SectionSP &section, lldb::addr_t load_addr, bool warn_multiple=false)
Definition Target.cpp:3541
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)