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