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