[Go to site: main page, start]

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