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 const char *path = m_data_nsp->PeekCStr(name_offset);
2185 if (path) {
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[0] == '@')
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 unmapped_local_symbols_found = nlist_count;
2692
2693 // The normal nlist code cannot correctly size the Symbols
2694 // array, we need to allocate it here.
2695 sym = symtab.Resize(
2696 symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
2697 unmapped_local_symbols_found - m_dysymtab.nlocalsym);
2698 num_syms = symtab.GetNumSymbols();
2699
2700 lldb::offset_t nlist_data_offset = 0;
2701
2702 for (uint32_t nlist_index = 0;
2703 nlist_index < nlist_count;
2704 nlist_index++) {
2705 /////////////////////////////
2706 {
2707 std::optional<struct nlist_64> nlist_maybe =
2708 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2709 nlist_byte_size);
2710 if (!nlist_maybe)
2711 break;
2712 struct nlist_64 nlist = *nlist_maybe;
2713
2715 const char *symbol_name = string_table + nlist.n_strx;
2716
2717 if (symbol_name == NULL) {
2718 // No symbol should be NULL, even the symbols with no
2719 // string values should have an offset zero which
2720 // points to an empty C-string
2721 Debugger::ReportError(llvm::formatv(
2722 "DSC unmapped local symbol[{0}] has invalid "
2723 "string table offset {1:x} in {2}, ignoring symbol",
2724 nlist_index, nlist.n_strx,
2725 module_sp->GetFileSpec().GetPath()));
2726 continue;
2727 }
2728 if (symbol_name[0] == '\0')
2729 symbol_name = NULL;
2730
2731 const char *symbol_name_non_abi_mangled = NULL;
2732
2733 SectionSP symbol_section;
2734 bool add_nlist = true;
2735 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2736 bool demangled_is_synthesized = false;
2737 bool is_gsym = false;
2738 bool set_value = true;
2739
2740 assert(sym_idx < num_syms);
2741
2742 sym[sym_idx].SetDebug(is_debug);
2743
2744 if (is_debug) {
2745 switch (nlist.n_type) {
2746 case N_GSYM:
2747 // global symbol: name,,NO_SECT,type,0
2748 // Sometimes the N_GSYM value contains the address.
2749
2750 // FIXME: In the .o files, we have a GSYM and a debug
2751 // symbol for all the ObjC data. They
2752 // have the same address, but we want to ensure that
2753 // we always find only the real symbol, 'cause we
2754 // don't currently correctly attribute the
2755 // GSYM one to the ObjCClass/Ivar/MetaClass
2756 // symbol type. This is a temporary hack to make
2757 // sure the ObjectiveC symbols get treated correctly.
2758 // To do this right, we should coalesce all the GSYM
2759 // & global symbols that have the same address.
2760
2761 is_gsym = true;
2762 sym[sym_idx].SetExternal(true);
2763
2765 symbol_name, symbol_name_non_abi_mangled,
2766 type)) {
2767 demangled_is_synthesized = true;
2768 } else {
2769 if (nlist.n_value != 0)
2770 symbol_section = section_info.GetSection(
2771 nlist.n_sect, nlist.n_value);
2772
2773 type = eSymbolTypeData;
2774 }
2775 break;
2776
2777 case N_FNAME:
2778 // procedure name (f77 kludge): name,,NO_SECT,0,0
2779 type = eSymbolTypeCompiler;
2780 break;
2781
2782 case N_FUN:
2783 // procedure: name,,n_sect,linenumber,address
2784 if (symbol_name) {
2785 type = eSymbolTypeCode;
2786 symbol_section = section_info.GetSection(
2787 nlist.n_sect, nlist.n_value);
2788
2789 N_FUN_addr_to_sym_idx.insert(
2790 std::make_pair(nlist.n_value, sym_idx));
2791 // We use the current number of symbols in the
2792 // symbol table in lieu of using nlist_idx in case
2793 // we ever start trimming entries out
2794 N_FUN_indexes.push_back(sym_idx);
2795 } else {
2796 type = eSymbolTypeCompiler;
2797
2798 if (!N_FUN_indexes.empty()) {
2799 // Copy the size of the function into the
2800 // original
2801 // STAB entry so we don't have
2802 // to hunt for it later
2803 symtab.SymbolAtIndex(N_FUN_indexes.back())
2804 ->SetByteSize(nlist.n_value);
2805 N_FUN_indexes.pop_back();
2806 // We don't really need the end function STAB as
2807 // it contains the size which we already placed
2808 // with the original symbol, so don't add it if
2809 // we want a minimal symbol table
2810 add_nlist = false;
2811 }
2812 }
2813 break;
2814
2815 case N_STSYM:
2816 // static symbol: name,,n_sect,type,address
2817 N_STSYM_addr_to_sym_idx.insert(
2818 std::make_pair(nlist.n_value, sym_idx));
2819 symbol_section = section_info.GetSection(nlist.n_sect,
2820 nlist.n_value);
2821 if (symbol_name && symbol_name[0]) {
2823 symbol_name + 1, eSymbolTypeData);
2824 }
2825 break;
2826
2827 case N_LCSYM:
2828 // .lcomm symbol: name,,n_sect,type,address
2829 symbol_section = section_info.GetSection(nlist.n_sect,
2830 nlist.n_value);
2832 break;
2833
2834 case N_BNSYM:
2835 // We use the current number of symbols in the symbol
2836 // table in lieu of using nlist_idx in case we ever
2837 // start trimming entries out Skip these if we want
2838 // minimal symbol tables
2839 add_nlist = false;
2840 break;
2841
2842 case N_ENSYM:
2843 // Set the size of the N_BNSYM to the terminating
2844 // index of this N_ENSYM so that we can always skip
2845 // the entire symbol if we need to navigate more
2846 // quickly at the source level when parsing STABS
2847 // Skip these if we want minimal symbol tables
2848 add_nlist = false;
2849 break;
2850
2851 case N_OPT:
2852 // emitted with gcc2_compiled and in gcc source
2853 type = eSymbolTypeCompiler;
2854 break;
2855
2856 case N_RSYM:
2857 // register sym: name,,NO_SECT,type,register
2858 type = eSymbolTypeVariable;
2859 break;
2860
2861 case N_SLINE:
2862 // src line: 0,,n_sect,linenumber,address
2863 symbol_section = section_info.GetSection(nlist.n_sect,
2864 nlist.n_value);
2865 type = eSymbolTypeLineEntry;
2866 break;
2867
2868 case N_SSYM:
2869 // structure elt: name,,NO_SECT,type,struct_offset
2871 break;
2872
2873 case N_SO:
2874 // source file name
2875 type = eSymbolTypeSourceFile;
2876 if (symbol_name == NULL) {
2877 add_nlist = false;
2878 if (N_SO_index != UINT32_MAX) {
2879 // Set the size of the N_SO to the terminating
2880 // index of this N_SO so that we can always skip
2881 // the entire N_SO if we need to navigate more
2882 // quickly at the source level when parsing STABS
2883 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
2884 symbol_ptr->SetByteSize(sym_idx);
2885 symbol_ptr->SetSizeIsSibling(true);
2886 }
2887 N_NSYM_indexes.clear();
2888 N_INCL_indexes.clear();
2889 N_BRAC_indexes.clear();
2890 N_COMM_indexes.clear();
2891 N_FUN_indexes.clear();
2892 N_SO_index = UINT32_MAX;
2893 } else {
2894 // We use the current number of symbols in the
2895 // symbol table in lieu of using nlist_idx in case
2896 // we ever start trimming entries out
2897 const bool N_SO_has_full_path = symbol_name[0] == '/';
2898 if (N_SO_has_full_path) {
2899 if ((N_SO_index == sym_idx - 1) &&
2900 ((sym_idx - 1) < num_syms)) {
2901 // We have two consecutive N_SO entries where
2902 // the first contains a directory and the
2903 // second contains a full path.
2904 sym[sym_idx - 1].GetMangled().SetValue(
2905 ConstString(symbol_name));
2906 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2907 add_nlist = false;
2908 } else {
2909 // This is the first entry in a N_SO that
2910 // contains a directory or
2911 // a full path to the source file
2912 N_SO_index = sym_idx;
2913 }
2914 } else if ((N_SO_index == sym_idx - 1) &&
2915 ((sym_idx - 1) < num_syms)) {
2916 // This is usually the second N_SO entry that
2917 // contains just the filename, so here we combine
2918 // it with the first one if we are minimizing the
2919 // symbol table
2920 const char *so_path = sym[sym_idx - 1]
2921 .GetMangled()
2923 .AsCString();
2924 if (so_path && so_path[0]) {
2925 std::string full_so_path(so_path);
2926 const size_t double_slash_pos =
2927 full_so_path.find("//");
2928 if (double_slash_pos != std::string::npos) {
2929 // The linker has been generating bad N_SO
2930 // entries with doubled up paths
2931 // in the format "%s%s" where the first
2932 // string in the DW_AT_comp_dir, and the
2933 // second is the directory for the source
2934 // file so you end up with a path that looks
2935 // like "/tmp/src//tmp/src/"
2936 FileSpec so_dir(so_path);
2937 if (!FileSystem::Instance().Exists(so_dir)) {
2938 so_dir.SetFile(
2939 &full_so_path[double_slash_pos + 1],
2940 FileSpec::Style::native);
2941 if (FileSystem::Instance().Exists(so_dir)) {
2942 // Trim off the incorrect path
2943 full_so_path.erase(0, double_slash_pos + 1);
2944 }
2945 }
2946 }
2947 if (*full_so_path.rbegin() != '/')
2948 full_so_path += '/';
2949 full_so_path += symbol_name;
2950 sym[sym_idx - 1].GetMangled().SetValue(
2951 ConstString(full_so_path.c_str()));
2952 add_nlist = false;
2953 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2954 }
2955 } else {
2956 // This could be a relative path to a N_SO
2957 N_SO_index = sym_idx;
2958 }
2959 }
2960 break;
2961
2962 case N_OSO:
2963 // object file name: name,,0,0,st_mtime
2964 type = eSymbolTypeObjectFile;
2965 break;
2966
2967 case N_LSYM:
2968 // local sym: name,,NO_SECT,type,offset
2969 type = eSymbolTypeLocal;
2970 break;
2971
2972 // INCL scopes
2973 case N_BINCL:
2974 // include file beginning: name,,NO_SECT,0,sum We use
2975 // the current number of symbols in the symbol table
2976 // in lieu of using nlist_idx in case we ever start
2977 // trimming entries out
2978 N_INCL_indexes.push_back(sym_idx);
2979 type = eSymbolTypeScopeBegin;
2980 break;
2981
2982 case N_EINCL:
2983 // include file end: name,,NO_SECT,0,0
2984 // Set the size of the N_BINCL to the terminating
2985 // index of this N_EINCL so that we can always skip
2986 // the entire symbol if we need to navigate more
2987 // quickly at the source level when parsing STABS
2988 if (!N_INCL_indexes.empty()) {
2989 symbol_ptr =
2990 symtab.SymbolAtIndex(N_INCL_indexes.back());
2991 symbol_ptr->SetByteSize(sym_idx + 1);
2992 symbol_ptr->SetSizeIsSibling(true);
2993 N_INCL_indexes.pop_back();
2994 }
2995 type = eSymbolTypeScopeEnd;
2996 break;
2997
2998 case N_SOL:
2999 // #included file name: name,,n_sect,0,address
3000 type = eSymbolTypeHeaderFile;
3001
3002 // We currently don't use the header files on darwin
3003 add_nlist = false;
3004 break;
3005
3006 case N_PARAMS:
3007 // compiler parameters: name,,NO_SECT,0,0
3008 type = eSymbolTypeCompiler;
3009 break;
3010
3011 case N_VERSION:
3012 // compiler version: name,,NO_SECT,0,0
3013 type = eSymbolTypeCompiler;
3014 break;
3015
3016 case N_OLEVEL:
3017 // compiler -O level: name,,NO_SECT,0,0
3018 type = eSymbolTypeCompiler;
3019 break;
3020
3021 case N_PSYM:
3022 // parameter: name,,NO_SECT,type,offset
3023 type = eSymbolTypeVariable;
3024 break;
3025
3026 case N_ENTRY:
3027 // alternate entry: name,,n_sect,linenumber,address
3028 symbol_section = section_info.GetSection(nlist.n_sect,
3029 nlist.n_value);
3030 type = eSymbolTypeLineEntry;
3031 break;
3032
3033 // Left and Right Braces
3034 case N_LBRAC:
3035 // left bracket: 0,,NO_SECT,nesting level,address We
3036 // use the current number of symbols in the symbol
3037 // table in lieu of using nlist_idx in case we ever
3038 // start trimming entries out
3039 symbol_section = section_info.GetSection(nlist.n_sect,
3040 nlist.n_value);
3041 N_BRAC_indexes.push_back(sym_idx);
3042 type = eSymbolTypeScopeBegin;
3043 break;
3044
3045 case N_RBRAC:
3046 // right bracket: 0,,NO_SECT,nesting level,address
3047 // Set the size of the N_LBRAC to the terminating
3048 // index of this N_RBRAC so that we can always skip
3049 // the entire symbol if we need to navigate more
3050 // quickly at the source level when parsing STABS
3051 symbol_section = section_info.GetSection(nlist.n_sect,
3052 nlist.n_value);
3053 if (!N_BRAC_indexes.empty()) {
3054 symbol_ptr =
3055 symtab.SymbolAtIndex(N_BRAC_indexes.back());
3056 symbol_ptr->SetByteSize(sym_idx + 1);
3057 symbol_ptr->SetSizeIsSibling(true);
3058 N_BRAC_indexes.pop_back();
3059 }
3060 type = eSymbolTypeScopeEnd;
3061 break;
3062
3063 case N_EXCL:
3064 // deleted include file: name,,NO_SECT,0,sum
3065 type = eSymbolTypeHeaderFile;
3066 break;
3067
3068 // COMM scopes
3069 case N_BCOMM:
3070 // begin common: name,,NO_SECT,0,0
3071 // We use the current number of symbols in the symbol
3072 // table in lieu of using nlist_idx in case we ever
3073 // start trimming entries out
3074 type = eSymbolTypeScopeBegin;
3075 N_COMM_indexes.push_back(sym_idx);
3076 break;
3077
3078 case N_ECOML:
3079 // end common (local name): 0,,n_sect,0,address
3080 symbol_section = section_info.GetSection(nlist.n_sect,
3081 nlist.n_value);
3082 // Fall through
3083
3084 case N_ECOMM:
3085 // end common: name,,n_sect,0,0
3086 // Set the size of the N_BCOMM to the terminating
3087 // index of this N_ECOMM/N_ECOML so that we can
3088 // always skip the entire symbol if we need to
3089 // navigate more quickly at the source level when
3090 // parsing STABS
3091 if (!N_COMM_indexes.empty()) {
3092 symbol_ptr =
3093 symtab.SymbolAtIndex(N_COMM_indexes.back());
3094 symbol_ptr->SetByteSize(sym_idx + 1);
3095 symbol_ptr->SetSizeIsSibling(true);
3096 N_COMM_indexes.pop_back();
3097 }
3098 type = eSymbolTypeScopeEnd;
3099 break;
3100
3101 case N_LENG:
3102 // second stab entry with length information
3103 type = eSymbolTypeAdditional;
3104 break;
3105
3106 default:
3107 break;
3108 }
3109 } else {
3110 // uint8_t n_pext = N_PEXT & nlist.n_type;
3111 uint8_t n_type = N_TYPE & nlist.n_type;
3112 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3113
3114 switch (n_type) {
3115 case N_INDR: {
3116 const char *reexport_name_cstr =
3117 strtab_data.PeekCStr(nlist.n_value);
3118 if (reexport_name_cstr && reexport_name_cstr[0]) {
3119 type = eSymbolTypeReExported;
3120 ConstString reexport_name(
3121 reexport_name_cstr +
3122 ((reexport_name_cstr[0] == '_') ? 1 : 0));
3123 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3124 set_value = false;
3125 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3126 indirect_symbol_names.insert(ConstString(
3127 symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
3128 } else
3129 type = eSymbolTypeUndefined;
3130 } break;
3131
3132 case N_UNDF:
3133 if (symbol_name && symbol_name[0]) {
3134 ConstString undefined_name(
3135 symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
3136 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3137 }
3138 // Fall through
3139 case N_PBUD:
3140 type = eSymbolTypeUndefined;
3141 break;
3142
3143 case N_ABS:
3144 type = eSymbolTypeAbsolute;
3145 break;
3146
3147 case N_SECT: {
3148 symbol_section = section_info.GetSection(nlist.n_sect,
3149 nlist.n_value);
3150
3151 if (symbol_section == NULL) {
3152 // TODO: warn about this?
3153 add_nlist = false;
3154 break;
3155 }
3156
3157 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3158 type = eSymbolTypeException;
3159 } else {
3160 uint32_t section_type =
3161 symbol_section->Get() & SECTION_TYPE;
3162
3163 switch (section_type) {
3164 case S_CSTRING_LITERALS:
3165 type = eSymbolTypeData;
3166 break; // section with only literal C strings
3167 case S_4BYTE_LITERALS:
3168 type = eSymbolTypeData;
3169 break; // section with only 4 byte literals
3170 case S_8BYTE_LITERALS:
3171 type = eSymbolTypeData;
3172 break; // section with only 8 byte literals
3173 case S_LITERAL_POINTERS:
3174 type = eSymbolTypeTrampoline;
3175 break; // section with only pointers to literals
3176 case S_NON_LAZY_SYMBOL_POINTERS:
3177 type = eSymbolTypeTrampoline;
3178 break; // section with only non-lazy symbol
3179 // pointers
3180 case S_LAZY_SYMBOL_POINTERS:
3181 type = eSymbolTypeTrampoline;
3182 break; // section with only lazy symbol pointers
3183 case S_SYMBOL_STUBS:
3184 type = eSymbolTypeTrampoline;
3185 break; // section with only symbol stubs, byte
3186 // size of stub in the reserved2 field
3187 case S_MOD_INIT_FUNC_POINTERS:
3188 type = eSymbolTypeCode;
3189 break; // section with only function pointers for
3190 // initialization
3191 case S_MOD_TERM_FUNC_POINTERS:
3192 type = eSymbolTypeCode;
3193 break; // section with only function pointers for
3194 // termination
3195 case S_INTERPOSING:
3196 type = eSymbolTypeTrampoline;
3197 break; // section with only pairs of function
3198 // pointers for interposing
3199 case S_16BYTE_LITERALS:
3200 type = eSymbolTypeData;
3201 break; // section with only 16 byte literals
3202 case S_DTRACE_DOF:
3204 break;
3205 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3206 type = eSymbolTypeTrampoline;
3207 break;
3208 default:
3209 switch (symbol_section->GetType()) {
3211 type = eSymbolTypeCode;
3212 break;
3213 case eSectionTypeData:
3214 case eSectionTypeDataCString: // Inlined C string
3215 // data
3216 case eSectionTypeDataCStringPointers: // Pointers
3217 // to C
3218 // string
3219 // data
3220 case eSectionTypeDataSymbolAddress: // Address of
3221 // a symbol in
3222 // the symbol
3223 // table
3224 case eSectionTypeData4:
3225 case eSectionTypeData8:
3226 case eSectionTypeData16:
3227 type = eSymbolTypeData;
3228 break;
3229 default:
3230 break;
3231 }
3232 break;
3233 }
3234
3235 if (type == eSymbolTypeInvalid) {
3236 llvm::StringRef symbol_sect_name =
3237 symbol_section->GetName();
3238 if (symbol_section->IsDescendant(
3239 text_section_sp.get())) {
3240 if (symbol_section->IsClear(
3241 S_ATTR_PURE_INSTRUCTIONS |
3242 S_ATTR_SELF_MODIFYING_CODE |
3243 S_ATTR_SOME_INSTRUCTIONS))
3244 type = eSymbolTypeData;
3245 else
3246 type = eSymbolTypeCode;
3247 } else if (symbol_section->IsDescendant(
3248 data_section_sp.get()) ||
3249 symbol_section->IsDescendant(
3250 data_dirty_section_sp.get()) ||
3251 symbol_section->IsDescendant(
3252 data_const_section_sp.get())) {
3253 if (symbol_sect_name.starts_with("__objc")) {
3254 type = eSymbolTypeRuntime;
3255
3257 symbol_name,
3258 symbol_name_non_abi_mangled, type))
3259 demangled_is_synthesized = true;
3260 } else if (symbol_sect_name.starts_with("__gcc_except_tab")) {
3261 type = eSymbolTypeException;
3262 } else {
3263 type = eSymbolTypeData;
3264 }
3265 } else if (symbol_sect_name.starts_with("__IMPORT"))
3266 type = eSymbolTypeTrampoline;
3267 } else if (symbol_section->IsDescendant(
3268 objc_section_sp.get())) {
3269 type = eSymbolTypeRuntime;
3270 if (symbol_name && symbol_name[0] == '.') {
3271 llvm::StringRef symbol_name_ref(symbol_name);
3272 llvm::StringRef
3273 g_objc_v1_prefix_class(".objc_class_name_");
3274 if (symbol_name_ref.starts_with(
3275 g_objc_v1_prefix_class)) {
3276 symbol_name_non_abi_mangled = symbol_name;
3277 symbol_name = symbol_name +
3278 g_objc_v1_prefix_class.size();
3279 type = eSymbolTypeObjCClass;
3280 demangled_is_synthesized = true;
3281 }
3282 }
3283 }
3284 }
3285 }
3286 } break;
3287 }
3288 }
3289
3290 if (add_nlist) {
3291 uint64_t symbol_value = nlist.n_value;
3292 if (symbol_name_non_abi_mangled) {
3293 sym[sym_idx].GetMangled().SetMangledName(
3294 ConstString(symbol_name_non_abi_mangled));
3295 sym[sym_idx].GetMangled().SetDemangledName(
3296 ConstString(symbol_name));
3297 } else {
3298 if (symbol_name && symbol_name[0] == '_') {
3299 symbol_name++; // Skip the leading underscore
3300 }
3301
3302 if (symbol_name) {
3303 ConstString const_symbol_name(symbol_name);
3304 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
3305 if (is_gsym && is_debug) {
3306 const char *gsym_name =
3307 sym[sym_idx]
3308 .GetMangled()
3310 .GetCString();
3311 if (gsym_name)
3312 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3313 }
3314 }
3315 }
3316 if (symbol_section) {
3317 const addr_t section_file_addr =
3318 symbol_section->GetFileAddress();
3319 symbol_value -= section_file_addr;
3320 }
3321
3322 if (is_debug == false) {
3323 if (type == eSymbolTypeCode) {
3324 // See if we can find a N_FUN entry for any code
3325 // symbols. If we do find a match, and the name
3326 // matches, then we can merge the two into just the
3327 // function symbol to avoid duplicate entries in
3328 // the symbol table
3329 auto range =
3330 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3331 if (range.first != range.second) {
3332 bool found_it = false;
3333 for (auto pos = range.first; pos != range.second;
3334 ++pos) {
3335 if (sym[sym_idx].GetMangled().GetName(
3337 sym[pos->second].GetMangled().GetName(
3339 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3340 // We just need the flags from the linker
3341 // symbol, so put these flags
3342 // into the N_FUN flags to avoid duplicate
3343 // symbols in the symbol table
3344 sym[pos->second].SetExternal(
3345 sym[sym_idx].IsExternal());
3346 sym[pos->second].SetFlags(nlist.n_type << 16 |
3347 nlist.n_desc);
3348 if (resolver_addresses.find(nlist.n_value) !=
3349 resolver_addresses.end())
3350 sym[pos->second].SetType(eSymbolTypeResolver);
3351 sym[sym_idx].Clear();
3352 found_it = true;
3353 break;
3354 }
3355 }
3356 if (found_it)
3357 continue;
3358 } else {
3359 if (resolver_addresses.find(nlist.n_value) !=
3360 resolver_addresses.end())
3361 type = eSymbolTypeResolver;
3362 }
3363 } else if (type == eSymbolTypeData ||
3364 type == eSymbolTypeObjCClass ||
3365 type == eSymbolTypeObjCMetaClass ||
3366 type == eSymbolTypeObjCIVar) {
3367 // See if we can find a N_STSYM entry for any data
3368 // symbols. If we do find a match, and the name
3369 // matches, then we can merge the two into just the
3370 // Static symbol to avoid duplicate entries in the
3371 // symbol table
3372 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3373 nlist.n_value);
3374 if (range.first != range.second) {
3375 bool found_it = false;
3376 for (auto pos = range.first; pos != range.second;
3377 ++pos) {
3378 if (sym[sym_idx].GetMangled().GetName(
3380 sym[pos->second].GetMangled().GetName(
3382 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3383 // We just need the flags from the linker
3384 // symbol, so put these flags
3385 // into the N_STSYM flags to avoid duplicate
3386 // symbols in the symbol table
3387 sym[pos->second].SetExternal(
3388 sym[sym_idx].IsExternal());
3389 sym[pos->second].SetFlags(nlist.n_type << 16 |
3390 nlist.n_desc);
3391 sym[sym_idx].Clear();
3392 found_it = true;
3393 break;
3394 }
3395 }
3396 if (found_it)
3397 continue;
3398 } else {
3399 const char *gsym_name =
3400 sym[sym_idx]
3401 .GetMangled()
3403 .GetCString();
3404 if (gsym_name) {
3405 // Combine N_GSYM stab entries with the non
3406 // stab symbol
3407 ConstNameToSymbolIndexMap::const_iterator pos =
3408 N_GSYM_name_to_sym_idx.find(gsym_name);
3409 if (pos != N_GSYM_name_to_sym_idx.end()) {
3410 const uint32_t GSYM_sym_idx = pos->second;
3411 m_nlist_idx_to_sym_idx[nlist_idx] =
3412 GSYM_sym_idx;
3413 // Copy the address, because often the N_GSYM
3414 // address has an invalid address of zero
3415 // when the global is a common symbol
3416 sym[GSYM_sym_idx].GetAddressRef() =
3417 Address(symbol_section, symbol_value);
3418 add_symbol_addr(sym[GSYM_sym_idx]
3419 .GetAddress()
3420 .GetFileAddress());
3421 // We just need the flags from the linker
3422 // symbol, so put these flags
3423 // into the N_GSYM flags to avoid duplicate
3424 // symbols in the symbol table
3425 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 |
3426 nlist.n_desc);
3427 sym[sym_idx].Clear();
3428 continue;
3429 }
3430 }
3431 }
3432 }
3433 }
3434
3435 sym[sym_idx].SetID(nlist_idx);
3436 sym[sym_idx].SetType(type);
3437 if (set_value) {
3438 sym[sym_idx].GetAddressRef() =
3439 Address(symbol_section, symbol_value);
3440 add_symbol_addr(
3441 sym[sym_idx].GetAddress().GetFileAddress());
3442 }
3443 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
3444
3445 if (demangled_is_synthesized)
3446 sym[sym_idx].SetDemangledNameIsSynthesized(true);
3447 ++sym_idx;
3448 } else {
3449 sym[sym_idx].Clear();
3450 }
3451 }
3452 /////////////////////////////
3453 }
3454 }
3455
3456 for (const auto &pos : reexport_shlib_needs_fixup) {
3457 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3458 if (undef_pos != undefined_name_to_desc.end()) {
3459 const uint8_t dylib_ordinal =
3460 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3461 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
3462 sym[pos.first].SetReExportedSymbolSharedLibrary(
3463 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
3464 }
3465 }
3466 }
3467
3468#endif
3469 lldb::offset_t nlist_data_offset = 0;
3470
3471 if (nlist_data.GetByteSize() > 0) {
3472
3473 const uint64_t max_nsyms = nlist_data.GetByteSize() / nlist_byte_size;
3474 const uint64_t max_nindirectsyms =
3475 indirect_symbol_index_data.GetByteSize() / sizeof(uint32_t);
3476
3477 // If the sym array was not created while parsing the DSC unmapped
3478 // symbols, create it now.
3479 if (sym == nullptr) {
3480 sym = symtab.Resize(
3481 std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms) +
3482 std::min<uint64_t>(m_dysymtab.nindirectsyms, max_nindirectsyms));
3483 num_syms = symtab.GetNumSymbols();
3484 }
3485
3486 if (unmapped_local_symbols_found) {
3487 assert(m_dysymtab.ilocalsym == 0);
3488 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3489 nlist_idx = m_dysymtab.nlocalsym;
3490 } else {
3491 nlist_idx = 0;
3492 }
3493
3494 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3495 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3496 UndefinedNameToDescMap undefined_name_to_desc;
3497 SymbolIndexToName reexport_shlib_needs_fixup;
3498
3499 // Symtab parsing is a huge mess. Everything is entangled and the code
3500 // requires access to a ridiculous amount of variables. LLDB depends
3501 // heavily on the proper merging of symbols and to get that right we need
3502 // to make sure we have parsed all the debug symbols first. Therefore we
3503 // invoke the lambda twice, once to parse only the debug symbols and then
3504 // once more to parse the remaining symbols.
3505 auto ParseSymbolLambda = [&](struct nlist_64 &nlist, uint32_t nlist_idx,
3506 bool debug_only) {
3507 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3508 if (is_debug != debug_only)
3509 return true;
3510
3511 const char *symbol_name_non_abi_mangled = nullptr;
3512 const char *symbol_name = nullptr;
3513
3514 if (have_strtab_data) {
3515 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3516
3517 if (symbol_name == nullptr) {
3518 // No symbol should be NULL, even the symbols with no string values
3519 // should have an offset zero which points to an empty C-string
3520 Debugger::ReportError(llvm::formatv(
3521 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3522 "ignoring symbol",
3523 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3524 return true;
3525 }
3526 if (symbol_name[0] == '\0')
3527 symbol_name = nullptr;
3528 } else {
3529 const addr_t str_addr = strtab_addr + nlist.n_strx;
3530 Status str_error;
3531 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3532 str_error))
3533 symbol_name = memory_symbol_name.c_str();
3534 }
3535
3537 SectionSP symbol_section;
3538 bool add_nlist = true;
3539 bool is_gsym = false;
3540 bool demangled_is_synthesized = false;
3541 bool set_value = true;
3542
3543 assert(sym_idx < num_syms);
3544 sym[sym_idx].SetDebug(is_debug);
3545
3546 if (is_debug) {
3547 switch (nlist.n_type) {
3548 case N_GSYM: {
3549 // global symbol: name,,NO_SECT,type,0
3550 // Sometimes the N_GSYM value contains the address.
3551
3552 // FIXME: In the .o files, we have a GSYM and a debug symbol for all
3553 // the ObjC data. They
3554 // have the same address, but we want to ensure that we always find
3555 // only the real symbol, 'cause we don't currently correctly
3556 // attribute the GSYM one to the ObjCClass/Ivar/MetaClass symbol
3557 // type. This is a temporary hack to make sure the ObjectiveC
3558 // symbols get treated correctly. To do this right, we should
3559 // coalesce all the GSYM & global symbols that have the same
3560 // address.
3561 is_gsym = true;
3562 sym[sym_idx].SetExternal(true);
3563
3564 if (TryParseV2ObjCMetadataSymbol(symbol_name,
3565 symbol_name_non_abi_mangled, type)) {
3566 demangled_is_synthesized = true;
3567 } else {
3568 if (nlist.n_value != 0)
3569 symbol_section =
3570 section_info.GetSection(nlist.n_sect, nlist.n_value);
3571
3572 type = eSymbolTypeData;
3573 }
3574 } break;
3575
3576 case N_FNAME:
3577 // procedure name (f77 kludge): name,,NO_SECT,0,0
3578 type = eSymbolTypeCompiler;
3579 break;
3580
3581 case N_FUN:
3582 // procedure: name,,n_sect,linenumber,address
3583 if (symbol_name) {
3584 type = eSymbolTypeCode;
3585 symbol_section =
3586 section_info.GetSection(nlist.n_sect, nlist.n_value);
3587
3588 N_FUN_addr_to_sym_idx.insert(
3589 std::make_pair(nlist.n_value, sym_idx));
3590 // We use the current number of symbols in the symbol table in
3591 // lieu of using nlist_idx in case we ever start trimming entries
3592 // out
3593 N_FUN_indexes.push_back(sym_idx);
3594 } else {
3595 type = eSymbolTypeCompiler;
3596
3597 if (!N_FUN_indexes.empty()) {
3598 // Copy the size of the function into the original STAB entry
3599 // so we don't have to hunt for it later
3600 symtab.SymbolAtIndex(N_FUN_indexes.back())
3601 ->SetByteSize(nlist.n_value);
3602 N_FUN_indexes.pop_back();
3603 // We don't really need the end function STAB as it contains
3604 // the size which we already placed with the original symbol,
3605 // so don't add it if we want a minimal symbol table
3606 add_nlist = false;
3607 }
3608 }
3609 break;
3610
3611 case N_STSYM:
3612 // static symbol: name,,n_sect,type,address
3613 N_STSYM_addr_to_sym_idx.insert(
3614 std::make_pair(nlist.n_value, sym_idx));
3615 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3616 if (symbol_name && symbol_name[0]) {
3617 type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1,
3619 }
3620 break;
3621
3622 case N_LCSYM:
3623 // .lcomm symbol: name,,n_sect,type,address
3624 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3626 break;
3627
3628 case N_BNSYM:
3629 // We use the current number of symbols in the symbol table in lieu
3630 // of using nlist_idx in case we ever start trimming entries out
3631 // Skip these if we want minimal symbol tables
3632 add_nlist = false;
3633 break;
3634
3635 case N_ENSYM:
3636 // Set the size of the N_BNSYM to the terminating index of this
3637 // N_ENSYM so that we can always skip the entire symbol if we need
3638 // to navigate more quickly at the source level when parsing STABS
3639 // Skip these if we want minimal symbol tables
3640 add_nlist = false;
3641 break;
3642
3643 case N_OPT:
3644 // emitted with gcc2_compiled and in gcc source
3645 type = eSymbolTypeCompiler;
3646 break;
3647
3648 case N_RSYM:
3649 // register sym: name,,NO_SECT,type,register
3650 type = eSymbolTypeVariable;
3651 break;
3652
3653 case N_SLINE:
3654 // src line: 0,,n_sect,linenumber,address
3655 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3656 type = eSymbolTypeLineEntry;
3657 break;
3658
3659 case N_SSYM:
3660 // structure elt: name,,NO_SECT,type,struct_offset
3662 break;
3663
3664 case N_SO:
3665 // source file name
3666 type = eSymbolTypeSourceFile;
3667 if (symbol_name == nullptr) {
3668 add_nlist = false;
3669 if (N_SO_index != UINT32_MAX) {
3670 // Set the size of the N_SO to the terminating index of this
3671 // N_SO so that we can always skip the entire N_SO if we need
3672 // to navigate more quickly at the source level when parsing
3673 // STABS
3674 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
3675 symbol_ptr->SetByteSize(sym_idx);
3676 symbol_ptr->SetSizeIsSibling(true);
3677 }
3678 N_NSYM_indexes.clear();
3679 N_INCL_indexes.clear();
3680 N_BRAC_indexes.clear();
3681 N_COMM_indexes.clear();
3682 N_FUN_indexes.clear();
3683 N_SO_index = UINT32_MAX;
3684 } else {
3685 // We use the current number of symbols in the symbol table in
3686 // lieu of using nlist_idx in case we ever start trimming entries
3687 // out
3688 const bool N_SO_has_full_path = symbol_name[0] == '/';
3689 if (N_SO_has_full_path) {
3690 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3691 // We have two consecutive N_SO entries where the first
3692 // contains a directory and the second contains a full path.
3693 sym[sym_idx - 1].GetMangled().SetValue(
3694 ConstString(symbol_name));
3695 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3696 add_nlist = false;
3697 } else {
3698 // This is the first entry in a N_SO that contains a
3699 // directory or a full path to the source file
3700 N_SO_index = sym_idx;
3701 }
3702 } else if ((N_SO_index == sym_idx - 1) &&
3703 ((sym_idx - 1) < num_syms)) {
3704 // This is usually the second N_SO entry that contains just the
3705 // filename, so here we combine it with the first one if we are
3706 // minimizing the symbol table
3707 llvm::StringRef so_path = sym[sym_idx - 1]
3708 .GetMangled()
3709 .GetDemangledName()
3710 .GetStringRef();
3711 if (!so_path.empty()) {
3712 std::string full_so_path(so_path);
3713 const size_t double_slash_pos = full_so_path.find("//");
3714 if (double_slash_pos != std::string::npos) {
3715 // The linker has been generating bad N_SO entries with
3716 // doubled up paths in the format "%s%s" where the first
3717 // string in the DW_AT_comp_dir, and the second is the
3718 // directory for the source file so you end up with a path
3719 // that looks like "/tmp/src//tmp/src/"
3720 FileSpec so_dir(so_path);
3721 if (!FileSystem::Instance().Exists(so_dir)) {
3722 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
3723 FileSpec::Style::native);
3724 if (FileSystem::Instance().Exists(so_dir)) {
3725 // Trim off the incorrect path
3726 full_so_path.erase(0, double_slash_pos + 1);
3727 }
3728 }
3729 }
3730 if (*full_so_path.rbegin() != '/')
3731 full_so_path += '/';
3732 full_so_path += symbol_name;
3733 sym[sym_idx - 1].GetMangled().SetValue(
3734 ConstString(full_so_path.c_str()));
3735 add_nlist = false;
3736 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3737 }
3738 } else {
3739 // This could be a relative path to a N_SO
3740 N_SO_index = sym_idx;
3741 }
3742 }
3743 break;
3744
3745 case N_OSO:
3746 // object file name: name,,0,0,st_mtime
3747 type = eSymbolTypeObjectFile;
3748 break;
3749
3750 case N_LSYM:
3751 // local sym: name,,NO_SECT,type,offset
3752 type = eSymbolTypeLocal;
3753 break;
3754
3755 // INCL scopes
3756 case N_BINCL:
3757 // include file beginning: name,,NO_SECT,0,sum We use the current
3758 // number of symbols in the symbol table in lieu of using nlist_idx
3759 // in case we ever start trimming entries out
3760 N_INCL_indexes.push_back(sym_idx);
3761 type = eSymbolTypeScopeBegin;
3762 break;
3763
3764 case N_EINCL:
3765 // include file end: name,,NO_SECT,0,0
3766 // Set the size of the N_BINCL to the terminating index of this
3767 // N_EINCL so that we can always skip the entire symbol if we need
3768 // to navigate more quickly at the source level when parsing STABS
3769 if (!N_INCL_indexes.empty()) {
3770 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
3771 symbol_ptr->SetByteSize(sym_idx + 1);
3772 symbol_ptr->SetSizeIsSibling(true);
3773 N_INCL_indexes.pop_back();
3774 }
3775 type = eSymbolTypeScopeEnd;
3776 break;
3777
3778 case N_SOL:
3779 // #included file name: name,,n_sect,0,address
3780 type = eSymbolTypeHeaderFile;
3781
3782 // We currently don't use the header files on darwin
3783 add_nlist = false;
3784 break;
3785
3786 case N_PARAMS:
3787 // compiler parameters: name,,NO_SECT,0,0
3788 type = eSymbolTypeCompiler;
3789 break;
3790
3791 case N_VERSION:
3792 // compiler version: name,,NO_SECT,0,0
3793 type = eSymbolTypeCompiler;
3794 break;
3795
3796 case N_OLEVEL:
3797 // compiler -O level: name,,NO_SECT,0,0
3798 type = eSymbolTypeCompiler;
3799 break;
3800
3801 case N_PSYM:
3802 // parameter: name,,NO_SECT,type,offset
3803 type = eSymbolTypeVariable;
3804 break;
3805
3806 case N_ENTRY:
3807 // alternate entry: name,,n_sect,linenumber,address
3808 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3809 type = eSymbolTypeLineEntry;
3810 break;
3811
3812 // Left and Right Braces
3813 case N_LBRAC:
3814 // left bracket: 0,,NO_SECT,nesting level,address We use the
3815 // current number of symbols in the symbol table in lieu of using
3816 // nlist_idx in case we ever start trimming entries out
3817 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3818 N_BRAC_indexes.push_back(sym_idx);
3819 type = eSymbolTypeScopeBegin;
3820 break;
3821
3822 case N_RBRAC:
3823 // right bracket: 0,,NO_SECT,nesting level,address Set the size of
3824 // the N_LBRAC to the terminating index of this N_RBRAC so that we
3825 // can always skip the entire symbol if we need to navigate more
3826 // quickly at the source level when parsing STABS
3827 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3828 if (!N_BRAC_indexes.empty()) {
3829 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
3830 symbol_ptr->SetByteSize(sym_idx + 1);
3831 symbol_ptr->SetSizeIsSibling(true);
3832 N_BRAC_indexes.pop_back();
3833 }
3834 type = eSymbolTypeScopeEnd;
3835 break;
3836
3837 case N_EXCL:
3838 // deleted include file: name,,NO_SECT,0,sum
3839 type = eSymbolTypeHeaderFile;
3840 break;
3841
3842 // COMM scopes
3843 case N_BCOMM:
3844 // begin common: name,,NO_SECT,0,0
3845 // We use the current number of symbols in the symbol table in lieu
3846 // of using nlist_idx in case we ever start trimming entries out
3847 type = eSymbolTypeScopeBegin;
3848 N_COMM_indexes.push_back(sym_idx);
3849 break;
3850
3851 case N_ECOML:
3852 // end common (local name): 0,,n_sect,0,address
3853 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3854 [[fallthrough]];
3855
3856 case N_ECOMM:
3857 // end common: name,,n_sect,0,0
3858 // Set the size of the N_BCOMM to the terminating index of this
3859 // N_ECOMM/N_ECOML so that we can always skip the entire symbol if
3860 // we need to navigate more quickly at the source level when
3861 // parsing STABS
3862 if (!N_COMM_indexes.empty()) {
3863 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
3864 symbol_ptr->SetByteSize(sym_idx + 1);
3865 symbol_ptr->SetSizeIsSibling(true);
3866 N_COMM_indexes.pop_back();
3867 }
3868 type = eSymbolTypeScopeEnd;
3869 break;
3870
3871 case N_LENG:
3872 // second stab entry with length information
3873 type = eSymbolTypeAdditional;
3874 break;
3875
3876 default:
3877 break;
3878 }
3879 } else {
3880 uint8_t n_type = N_TYPE & nlist.n_type;
3881 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3882
3883 switch (n_type) {
3884 case N_INDR: {
3885 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3886 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3887 type = eSymbolTypeReExported;
3888 ConstString reexport_name(reexport_name_cstr +
3889 ((reexport_name_cstr[0] == '_') ? 1 : 0));
3890 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3891 set_value = false;
3892 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3893 indirect_symbol_names.insert(
3894 ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
3895 } else
3896 type = eSymbolTypeUndefined;
3897 } break;
3898
3899 case N_UNDF:
3900 if (symbol_name && symbol_name[0]) {
3901 ConstString undefined_name(symbol_name +
3902 ((symbol_name[0] == '_') ? 1 : 0));
3903 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3904 }
3905 [[fallthrough]];
3906
3907 case N_PBUD:
3908 type = eSymbolTypeUndefined;
3909 break;
3910
3911 case N_ABS:
3912 type = eSymbolTypeAbsolute;
3913 break;
3914
3915 case N_SECT: {
3916 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3917
3918 if (!symbol_section) {
3919 // TODO: warn about this?
3920 add_nlist = false;
3921 break;
3922 }
3923
3924 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3925 type = eSymbolTypeException;
3926 } else {
3927 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3928
3929 switch (section_type) {
3930 case S_CSTRING_LITERALS:
3931 type = eSymbolTypeData;
3932 break; // section with only literal C strings
3933 case S_4BYTE_LITERALS:
3934 type = eSymbolTypeData;
3935 break; // section with only 4 byte literals
3936 case S_8BYTE_LITERALS:
3937 type = eSymbolTypeData;
3938 break; // section with only 8 byte literals
3939 case S_LITERAL_POINTERS:
3940 type = eSymbolTypeTrampoline;
3941 break; // section with only pointers to literals
3942 case S_NON_LAZY_SYMBOL_POINTERS:
3943 type = eSymbolTypeTrampoline;
3944 break; // section with only non-lazy symbol pointers
3945 case S_LAZY_SYMBOL_POINTERS:
3946 type = eSymbolTypeTrampoline;
3947 break; // section with only lazy symbol pointers
3948 case S_SYMBOL_STUBS:
3949 type = eSymbolTypeTrampoline;
3950 break; // section with only symbol stubs, byte size of stub in
3951 // the reserved2 field
3952 case S_MOD_INIT_FUNC_POINTERS:
3953 type = eSymbolTypeCode;
3954 break; // section with only function pointers for initialization
3955 case S_MOD_TERM_FUNC_POINTERS:
3956 type = eSymbolTypeCode;
3957 break; // section with only function pointers for termination
3958 case S_INTERPOSING:
3959 type = eSymbolTypeTrampoline;
3960 break; // section with only pairs of function pointers for
3961 // interposing
3962 case S_16BYTE_LITERALS:
3963 type = eSymbolTypeData;
3964 break; // section with only 16 byte literals
3965 case S_DTRACE_DOF:
3967 break;
3968 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3969 type = eSymbolTypeTrampoline;
3970 break;
3971 default:
3972 switch (symbol_section->GetType()) {
3974 type = eSymbolTypeCode;
3975 break;
3976 case eSectionTypeData:
3977 case eSectionTypeDataCString: // Inlined C string data
3978 case eSectionTypeDataCStringPointers: // Pointers to C string
3979 // data
3980 case eSectionTypeDataSymbolAddress: // Address of a symbol in
3981 // the symbol table
3982 case eSectionTypeData4:
3983 case eSectionTypeData8:
3984 case eSectionTypeData16:
3985 type = eSymbolTypeData;
3986 break;
3987 default:
3988 break;
3989 }
3990 break;
3991 }
3992
3993 if (type == eSymbolTypeInvalid) {
3994 llvm::StringRef symbol_sect_name = symbol_section->GetName();
3995 if (symbol_section->IsDescendant(text_section_sp.get())) {
3996 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3997 S_ATTR_SELF_MODIFYING_CODE |
3998 S_ATTR_SOME_INSTRUCTIONS))
3999 type = eSymbolTypeData;
4000 else
4001 type = eSymbolTypeCode;
4002 } else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4003 symbol_section->IsDescendant(
4004 data_dirty_section_sp.get()) ||
4005 symbol_section->IsDescendant(
4006 data_const_section_sp.get())) {
4007 if (symbol_sect_name.starts_with("__objc")) {
4008 type = eSymbolTypeRuntime;
4009
4011 symbol_name, symbol_name_non_abi_mangled, type))
4012 demangled_is_synthesized = true;
4013 } else if (symbol_sect_name.starts_with("__gcc_except_tab")) {
4014 type = eSymbolTypeException;
4015 } else {
4016 type = eSymbolTypeData;
4017 }
4018 } else if (symbol_sect_name.starts_with("__IMPORT")) {
4019 type = eSymbolTypeTrampoline;
4020 } else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4021 type = eSymbolTypeRuntime;
4022 if (symbol_name && symbol_name[0] == '.') {
4023 llvm::StringRef symbol_name_ref(symbol_name);
4024 llvm::StringRef g_objc_v1_prefix_class(
4025 ".objc_class_name_");
4026 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4027 symbol_name_non_abi_mangled = symbol_name;
4028 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4029 type = eSymbolTypeObjCClass;
4030 demangled_is_synthesized = true;
4031 }
4032 }
4033 }
4034 }
4035 }
4036 } break;
4037 }
4038 }
4039
4040 if (!add_nlist) {
4041 sym[sym_idx].Clear();
4042 return true;
4043 }
4044
4045 uint64_t symbol_value = nlist.n_value;
4046
4047 if (symbol_name_non_abi_mangled) {
4048 sym[sym_idx].GetMangled().SetMangledName(
4049 ConstString(symbol_name_non_abi_mangled));
4050 sym[sym_idx].GetMangled().SetDemangledName(ConstString(symbol_name));
4051 } else {
4052
4053 if (symbol_name && symbol_name[0] == '_') {
4054 symbol_name++; // Skip the leading underscore
4055 }
4056
4057 if (symbol_name) {
4058 ConstString const_symbol_name(symbol_name);
4059 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
4060 }
4061 }
4062
4063 if (is_gsym) {
4064 const char *gsym_name = sym[sym_idx]
4065 .GetMangled()
4066 .GetName(Mangled::ePreferMangled)
4067 .GetCString();
4068 if (gsym_name)
4069 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4070 }
4071
4072 if (symbol_section) {
4073 const addr_t section_file_addr = symbol_section->GetFileAddress();
4074 symbol_value -= section_file_addr;
4075 }
4076
4077 if (!is_debug) {
4078 if (type == eSymbolTypeCode) {
4079 // See if we can find a N_FUN entry for any code symbols. If we do
4080 // find a match, and the name matches, then we can merge the two into
4081 // just the function symbol to avoid duplicate entries in the symbol
4082 // table.
4083 std::pair<ValueToSymbolIndexMap::const_iterator,
4084 ValueToSymbolIndexMap::const_iterator>
4085 range;
4086 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4087 if (range.first != range.second) {
4088 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4089 pos != range.second; ++pos) {
4090 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==
4091 sym[pos->second].GetMangled().GetName(
4093 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4094 // We just need the flags from the linker symbol, so put these
4095 // flags into the N_FUN flags to avoid duplicate symbols in the
4096 // symbol table.
4097 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4098 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4099 if (resolver_addresses.find(nlist.n_value) !=
4100 resolver_addresses.end())
4101 sym[pos->second].SetType(eSymbolTypeResolver);
4102 sym[sym_idx].Clear();
4103 return true;
4104 }
4105 }
4106 } else {
4107 if (resolver_addresses.find(nlist.n_value) !=
4108 resolver_addresses.end())
4109 type = eSymbolTypeResolver;
4110 }
4111 } else if (type == eSymbolTypeData || type == eSymbolTypeObjCClass ||
4112 type == eSymbolTypeObjCMetaClass ||
4113 type == eSymbolTypeObjCIVar) {
4114 // See if we can find a N_STSYM entry for any data symbols. If we do
4115 // find a match, and the name matches, then we can merge the two into
4116 // just the Static symbol to avoid duplicate entries in the symbol
4117 // table.
4118 std::pair<ValueToSymbolIndexMap::const_iterator,
4119 ValueToSymbolIndexMap::const_iterator>
4120 range;
4121 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4122 if (range.first != range.second) {
4123 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4124 pos != range.second; ++pos) {
4125 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==
4126 sym[pos->second].GetMangled().GetName(
4128 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4129 // We just need the flags from the linker symbol, so put these
4130 // flags into the N_STSYM flags to avoid duplicate symbols in
4131 // the symbol table.
4132 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4133 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4134 sym[sym_idx].Clear();
4135 return true;
4136 }
4137 }
4138 } else {
4139 // Combine N_GSYM stab entries with the non stab symbol.
4140 const char *gsym_name = sym[sym_idx]
4141 .GetMangled()
4142 .GetName(Mangled::ePreferMangled)
4143 .GetCString();
4144 if (gsym_name) {
4145 ConstNameToSymbolIndexMap::const_iterator pos =
4146 N_GSYM_name_to_sym_idx.find(gsym_name);
4147 if (pos != N_GSYM_name_to_sym_idx.end()) {
4148 const uint32_t GSYM_sym_idx = pos->second;
4149 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4150 // Copy the address, because often the N_GSYM address has an
4151 // invalid address of zero when the global is a common symbol.
4152 sym[GSYM_sym_idx].GetAddressRef() =
4153 Address(symbol_section, symbol_value);
4154 add_symbol_addr(
4155 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4156 // We just need the flags from the linker symbol, so put these
4157 // flags into the N_GSYM flags to avoid duplicate symbols in
4158 // the symbol table.
4159 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4160 sym[sym_idx].Clear();
4161 return true;
4162 }
4163 }
4164 }
4165 }
4166 }
4167
4168 sym[sym_idx].SetID(nlist_idx);
4169 sym[sym_idx].SetType(type);
4170 if (set_value) {
4171 sym[sym_idx].GetAddressRef() = Address(symbol_section, symbol_value);
4172 if (symbol_section)
4173 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4174 }
4175 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4176 if (nlist.n_desc & N_WEAK_REF)
4177 sym[sym_idx].SetIsWeak(true);
4178
4179 if (demangled_is_synthesized)
4180 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4181
4182 ++sym_idx;
4183 return true;
4184 };
4185
4186 // First parse all the nlists but don't process them yet. See the next
4187 // comment for an explanation why.
4188 std::vector<struct nlist_64> nlists;
4189 nlists.reserve(std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms));
4190 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4191 if (auto nlist =
4192 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4193 nlists.push_back(*nlist);
4194 else
4195 break;
4196 }
4197
4198 // Now parse all the debug symbols. This is needed to merge non-debug
4199 // symbols in the next step. Non-debug symbols are always coalesced into
4200 // the debug symbol. Doing this in one step would mean that some symbols
4201 // won't be merged.
4202 nlist_idx = 0;
4203 for (auto &nlist : nlists) {
4204 if (!ParseSymbolLambda(nlist, nlist_idx++, DebugSymbols))
4205 break;
4206 }
4207
4208 // Finally parse all the non debug symbols.
4209 nlist_idx = 0;
4210 for (auto &nlist : nlists) {
4211 if (!ParseSymbolLambda(nlist, nlist_idx++, NonDebugSymbols))
4212 break;
4213 }
4214
4215 for (const auto &pos : reexport_shlib_needs_fixup) {
4216 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4217 if (undef_pos != undefined_name_to_desc.end()) {
4218 const uint8_t dylib_ordinal =
4219 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4220 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4221 sym[pos.first].SetReExportedSymbolSharedLibrary(
4222 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4223 }
4224 }
4225 }
4226
4227 // Count how many trie symbols we'll add to the symbol table
4228 int trie_symbol_table_augment_count = 0;
4229 for (auto &e : external_sym_trie_entries) {
4230 if (!symbols_added.contains(e.entry.address))
4231 trie_symbol_table_augment_count++;
4232 }
4233
4234 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4235 num_syms = sym_idx + trie_symbol_table_augment_count;
4236 sym = symtab.Resize(num_syms);
4237 }
4238 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4239
4240 // Add symbols from the trie to the symbol table.
4241 for (auto &e : external_sym_trie_entries) {
4242 if (symbols_added.contains(e.entry.address))
4243 continue;
4244
4245 // Find the section that this trie address is in, use that to annotate
4246 // symbol type as we add the trie address and name to the symbol table.
4247 Address symbol_addr;
4248 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4249 SectionSP symbol_section(symbol_addr.GetSection());
4250 const char *symbol_name = e.entry.name.GetCString();
4251 bool demangled_is_synthesized = false;
4252 SymbolType type =
4253 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4254 data_section_sp, data_dirty_section_sp,
4255 data_const_section_sp, symbol_section);
4256
4257 sym[sym_idx].SetType(type);
4258 if (symbol_section) {
4259 sym[sym_idx].SetID(synthetic_sym_id++);
4260 sym[sym_idx].GetMangled().SetMangledName(ConstString(symbol_name));
4261 if (demangled_is_synthesized)
4262 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4263 sym[sym_idx].SetIsSynthetic(true);
4264 sym[sym_idx].SetExternal(true);
4265 sym[sym_idx].GetAddressRef() = symbol_addr;
4266 add_symbol_addr(symbol_addr.GetFileAddress());
4267 if (e.entry.flags & TRIE_SYMBOL_IS_THUMB)
4268 sym[sym_idx].SetFlags(MACHO_NLIST_ARM_SYMBOL_IS_THUMB);
4269 ++sym_idx;
4270 }
4271 }
4272 }
4273
4274 if (function_starts_count > 0) {
4275 uint32_t num_synthetic_function_symbols = 0;
4276 for (i = 0; i < function_starts_count; ++i) {
4277 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4278 ++num_synthetic_function_symbols;
4279 }
4280
4281 if (num_synthetic_function_symbols > 0) {
4282 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4283 num_syms = sym_idx + num_synthetic_function_symbols;
4284 sym = symtab.Resize(num_syms);
4285 }
4286 for (i = 0; i < function_starts_count; ++i) {
4287 const FunctionStarts::Entry *func_start_entry =
4288 function_starts.GetEntryAtIndex(i);
4289 if (!symbols_added.contains(func_start_entry->addr)) {
4290 addr_t symbol_file_addr = func_start_entry->addr;
4291 uint32_t symbol_flags = 0;
4292 if (func_start_entry->data)
4293 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
4294 Address symbol_addr;
4295 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4296 SectionSP symbol_section(symbol_addr.GetSection());
4297 if (symbol_section) {
4298 sym[sym_idx].SetID(synthetic_sym_id++);
4299 // Don't set the name for any synthetic symbols, the Symbol
4300 // object will generate one if needed when the name is accessed
4301 // via accessors.
4302 sym[sym_idx].GetMangled().SetDemangledName(ConstString());
4303 sym[sym_idx].SetType(eSymbolTypeCode);
4304 sym[sym_idx].SetIsSynthetic(true);
4305 sym[sym_idx].GetAddressRef() = symbol_addr;
4306 add_symbol_addr(symbol_addr.GetFileAddress());
4307 if (symbol_flags)
4308 sym[sym_idx].SetFlags(symbol_flags);
4309 ++sym_idx;
4310 }
4311 }
4312 }
4313 }
4314 }
4315 }
4316
4317 // Trim our symbols down to just what we ended up with after removing any
4318 // symbols.
4319 if (sym_idx < num_syms) {
4320 num_syms = sym_idx;
4321 sym = symtab.Resize(num_syms);
4322 }
4323
4324 // Now synthesize indirect symbols
4325 if (m_dysymtab.nindirectsyms != 0) {
4326 if (indirect_symbol_index_data.GetByteSize()) {
4327 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4328 m_nlist_idx_to_sym_idx.end();
4329
4330 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4331 ++sect_idx) {
4332 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4333 S_SYMBOL_STUBS) {
4334 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4335 if (symbol_stub_byte_size == 0)
4336 continue;
4337
4338 const uint32_t num_symbol_stubs =
4339 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4340
4341 if (num_symbol_stubs == 0)
4342 continue;
4343
4344 const uint32_t symbol_stub_index_offset =
4345 m_mach_sections[sect_idx].reserved1;
4346 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4347 const uint32_t symbol_stub_index =
4348 symbol_stub_index_offset + stub_idx;
4349 const lldb::addr_t symbol_stub_addr =
4350 m_mach_sections[sect_idx].addr +
4351 (stub_idx * symbol_stub_byte_size);
4352 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
4353 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4354 symbol_stub_offset, 4)) {
4355 const uint32_t stub_sym_id =
4356 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4357 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4358 continue;
4359
4360 NListIndexToSymbolIndexMap::const_iterator index_pos =
4361 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4362 Symbol *stub_symbol = nullptr;
4363 if (index_pos != end_index_pos) {
4364 // We have a remapping from the original nlist index to a
4365 // current symbol index, so just look this up by index
4366 stub_symbol = symtab.SymbolAtIndex(index_pos->second);
4367 } else {
4368 // We need to lookup a symbol using the original nlist symbol
4369 // index since this index is coming from the S_SYMBOL_STUBS
4370 stub_symbol = symtab.FindSymbolByID(stub_sym_id);
4371 }
4372
4373 if (stub_symbol) {
4374 Address so_addr(symbol_stub_addr, section_list);
4375
4376 if (stub_symbol->GetType() == eSymbolTypeUndefined) {
4377 // Change the external symbol into a trampoline that makes
4378 // sense These symbols were N_UNDF N_EXT, and are useless
4379 // to us, so we can re-use them so we don't have to make up
4380 // a synthetic symbol for no good reason.
4381 if (resolver_addresses.find(symbol_stub_addr) ==
4382 resolver_addresses.end())
4383 stub_symbol->SetType(eSymbolTypeTrampoline);
4384 else
4385 stub_symbol->SetType(eSymbolTypeResolver);
4386 stub_symbol->SetExternal(false);
4387 stub_symbol->GetAddressRef() = so_addr;
4388 stub_symbol->SetByteSize(symbol_stub_byte_size);
4389 } else {
4390 // Make a synthetic symbol to describe the trampoline stub
4391 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
4392 if (sym_idx >= num_syms) {
4393 sym = symtab.Resize(++num_syms);
4394 stub_symbol = nullptr; // this pointer no longer valid
4395 }
4396 sym[sym_idx].SetID(synthetic_sym_id++);
4397 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4398 if (resolver_addresses.find(symbol_stub_addr) ==
4399 resolver_addresses.end())
4400 sym[sym_idx].SetType(eSymbolTypeTrampoline);
4401 else
4402 sym[sym_idx].SetType(eSymbolTypeResolver);
4403 sym[sym_idx].SetIsSynthetic(true);
4404 sym[sym_idx].GetAddressRef() = so_addr;
4405 add_symbol_addr(so_addr.GetFileAddress());
4406 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4407 ++sym_idx;
4408 }
4409 } else {
4410 LLDB_LOGF(log,
4411 "warning: symbol stub referencing symbol table "
4412 "symbol %u that isn't in our minimal symbol table, "
4413 "fix this!!!",
4414 stub_sym_id);
4415 }
4416 }
4417 }
4418 }
4419 }
4420 }
4421 }
4422
4423 if (!reexport_trie_entries.empty()) {
4424 for (const auto &e : reexport_trie_entries) {
4425 if (e.entry.import_name) {
4426 // Only add indirect symbols from the Trie entries if we didn't have
4427 // a N_INDR nlist entry for this already
4428 if (indirect_symbol_names.find(e.entry.name) ==
4429 indirect_symbol_names.end()) {
4430 // Make a synthetic symbol to describe re-exported symbol.
4431 if (sym_idx >= num_syms)
4432 sym = symtab.Resize(++num_syms);
4433 sym[sym_idx].SetID(synthetic_sym_id++);
4434 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4435 sym[sym_idx].SetType(eSymbolTypeReExported);
4436 sym[sym_idx].SetIsSynthetic(true);
4437 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4438 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4439 sym[sym_idx].SetReExportedSymbolSharedLibrary(
4440 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
4441 }
4442 ++sym_idx;
4443 }
4444 }
4445 }
4446 }
4447}
4448
4450 ModuleSP module_sp(GetModule());
4451 if (module_sp) {
4452 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4453 s->Printf("%p: ", static_cast<void *>(this));
4454 s->Indent();
4455 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
4456 s->PutCString("ObjectFileMachO64");
4457 else
4458 s->PutCString("ObjectFileMachO32");
4459
4460 *s << ", file = '" << m_file;
4461 ModuleSpecList all_specs;
4462 ModuleSpec base_spec;
4464 MachHeaderSizeFromMagic(m_header.magic), base_spec,
4465 all_specs);
4466 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
4467 *s << "', triple";
4468 if (e)
4469 s->Printf("[%d]", i);
4470 *s << " = ";
4471 *s << all_specs.GetModuleSpecRefAtIndex(i)
4473 .GetTriple()
4474 .getTriple();
4475 }
4476 *s << "\n";
4477 SectionList *sections = GetSectionList();
4478 if (sections)
4479 sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
4480 UINT32_MAX);
4481
4482 if (m_symtab_up)
4483 m_symtab_up->Dump(s, nullptr, eSortOrderNone);
4484 }
4485}
4486
4487UUID ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
4488 const lldb_private::DataExtractor &data,
4489 lldb::offset_t lc_offset) {
4490 uint32_t i;
4491 llvm::MachO::uuid_command load_cmd;
4492
4493 lldb::offset_t offset = lc_offset;
4494 for (i = 0; i < header.ncmds; ++i) {
4495 const lldb::offset_t cmd_offset = offset;
4496 if (!ReadMachOCommand(data, offset, load_cmd))
4497 break;
4498
4499 if (load_cmd.cmd == LC_UUID) {
4500 const uint8_t *uuid_bytes = data.PeekData(offset, 16);
4501
4502 if (uuid_bytes) {
4503 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4504 // We pretend these object files have no UUID to prevent crashing.
4505
4506 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4507 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4508 0xbb, 0x14, 0xf0, 0x0d};
4509
4510 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4511 return UUID();
4512
4513 return UUID(uuid_bytes, 16);
4514 }
4515 return UUID();
4516 }
4517 offset = cmd_offset + load_cmd.cmdsize;
4518 }
4519 return UUID();
4520}
4521
4522static llvm::StringRef GetOSName(uint32_t cmd) {
4523 switch (cmd) {
4524 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4525 return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4526 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4527 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4528 case llvm::MachO::LC_VERSION_MIN_TVOS:
4529 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4530 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4531 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4532 default:
4533 llvm_unreachable("unexpected LC_VERSION load command");
4534 }
4535}
4536
4537namespace {
4538struct OSEnv {
4539 llvm::StringRef os_type;
4540 llvm::StringRef environment;
4541 OSEnv(uint32_t cmd) {
4542 switch (cmd) {
4543 case llvm::MachO::PLATFORM_MACOS:
4544 os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4545 return;
4546 case llvm::MachO::PLATFORM_IOS:
4547 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4548 return;
4549 case llvm::MachO::PLATFORM_TVOS:
4550 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4551 return;
4552 case llvm::MachO::PLATFORM_WATCHOS:
4553 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4554 return;
4555 case llvm::MachO::PLATFORM_BRIDGEOS:
4556 os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
4557 return;
4558 case llvm::MachO::PLATFORM_DRIVERKIT:
4559 os_type = llvm::Triple::getOSTypeName(llvm::Triple::DriverKit);
4560 return;
4561 case llvm::MachO::PLATFORM_MACCATALYST:
4562 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4563 environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);
4564 return;
4565 case llvm::MachO::PLATFORM_IOSSIMULATOR:
4566 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4567 environment =
4568 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4569 return;
4570 case llvm::MachO::PLATFORM_TVOSSIMULATOR:
4571 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4572 environment =
4573 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4574 return;
4575 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:
4576 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4577 environment =
4578 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4579 return;
4580 case llvm::MachO::PLATFORM_XROS:
4581 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4582 return;
4583 case llvm::MachO::PLATFORM_XROS_SIMULATOR:
4584 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4585 environment =
4586 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4587 return;
4588 default: {
4589 Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));
4590 LLDB_LOGF(log, "unsupported platform in LC_BUILD_VERSION");
4591 }
4592 }
4593 }
4594};
4595
4596struct MinOS {
4597 uint32_t major_version, minor_version, patch_version;
4598 MinOS(uint32_t version)
4599 : major_version(version >> 16), minor_version((version >> 8) & 0xffu),
4600 patch_version(version & 0xffu) {}
4601};
4602} // namespace
4603
4604void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header &header,
4605 const lldb_private::DataExtractor &data,
4606 lldb::offset_t lc_offset,
4607 ModuleSpec &base_spec,
4608 lldb_private::ModuleSpecList &all_specs) {
4609 auto &base_arch = base_spec.GetArchitecture();
4610 base_arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype);
4611 if (!base_arch.IsValid())
4612 return;
4613
4614 bool found_any = false;
4615 auto add_triple = [&](const llvm::Triple &triple) {
4616 auto spec = base_spec;
4617 spec.GetArchitecture().GetTriple() = triple;
4618 if (spec.GetArchitecture().IsValid()) {
4619 spec.GetUUID() = ObjectFileMachO::GetUUID(header, data, lc_offset);
4620 all_specs.Append(spec);
4621 found_any = true;
4622 }
4623 };
4624
4625 // Set OS to an unspecified unknown or a "*" so it can match any OS
4626 llvm::Triple base_triple = base_arch.GetTriple();
4627 base_triple.setOS(llvm::Triple::UnknownOS);
4628 base_triple.setOSName(llvm::StringRef());
4629
4630 if (header.filetype == MH_PRELOAD) {
4631 if (header.cputype == CPU_TYPE_ARM) {
4632 // If this is a 32-bit arm binary, and it's a standalone binary, force
4633 // the Vendor to Apple so we don't accidentally pick up the generic
4634 // armv7 ABI at runtime. Apple's armv7 ABI always uses r7 for the
4635 // frame pointer register; most other armv7 ABIs use a combination of
4636 // r7 and r11.
4637 base_triple.setVendor(llvm::Triple::Apple);
4638 } else {
4639 // Set vendor to an unspecified unknown or a "*" so it can match any
4640 // vendor This is required for correct behavior of EFI debugging on
4641 // x86_64
4642 base_triple.setVendor(llvm::Triple::UnknownVendor);
4643 base_triple.setVendorName(llvm::StringRef());
4644 }
4645 return add_triple(base_triple);
4646 }
4647
4648 llvm::MachO::load_command load_cmd;
4649
4650 // See if there is an LC_VERSION_MIN_* load command that can give
4651 // us the OS type.
4652 lldb::offset_t offset = lc_offset;
4653 for (uint32_t i = 0; i < header.ncmds; ++i) {
4654 const lldb::offset_t cmd_offset = offset;
4655 if (!ReadMachOCommand(data, offset, load_cmd))
4656 break;
4657
4658 llvm::MachO::version_min_command version_min;
4659 switch (load_cmd.cmd) {
4660 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4661 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4662 case llvm::MachO::LC_VERSION_MIN_TVOS:
4663 case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
4664 if (load_cmd.cmdsize != sizeof(version_min))
4665 break;
4666 if (data.ExtractBytes(cmd_offset, sizeof(version_min),
4667 data.GetByteOrder(), &version_min) == 0)
4668 break;
4669 MinOS min_os(version_min.version);
4670 llvm::SmallString<32> os_name;
4671 llvm::raw_svector_ostream os(os_name);
4672 os << GetOSName(load_cmd.cmd) << min_os.major_version << '.'
4673 << min_os.minor_version << '.' << min_os.patch_version;
4674
4675 auto triple = base_triple;
4676 triple.setOSName(os.str());
4677
4678 // Disambiguate legacy simulator platforms.
4679 if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
4680 (base_triple.getArch() == llvm::Triple::x86_64 ||
4681 base_triple.getArch() == llvm::Triple::x86)) {
4682 // The combination of legacy LC_VERSION_MIN load command and
4683 // x86 architecture always indicates a simulator environment.
4684 // The combination of LC_VERSION_MIN and arm architecture only
4685 // appears for native binaries. Back-deploying simulator
4686 // binaries on Apple Silicon Macs use the modern unambigous
4687 // LC_BUILD_VERSION load commands; no special handling required.
4688 triple.setEnvironment(llvm::Triple::Simulator);
4689 }
4690 add_triple(triple);
4691 break;
4692 }
4693 default:
4694 break;
4695 }
4696
4697 offset = cmd_offset + load_cmd.cmdsize;
4698 }
4699
4700 // See if there are LC_BUILD_VERSION load commands that can give
4701 // us the OS type.
4702 offset = lc_offset;
4703 for (uint32_t i = 0; i < header.ncmds; ++i) {
4704 const lldb::offset_t cmd_offset = offset;
4705 if (!ReadMachOCommand(data, offset, load_cmd))
4706 break;
4707
4708 do {
4709 if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
4710 llvm::MachO::build_version_command build_version;
4711 if (load_cmd.cmdsize < sizeof(build_version)) {
4712 // Malformed load command.
4713 break;
4714 }
4715 if (data.ExtractBytes(cmd_offset, sizeof(build_version),
4716 data.GetByteOrder(), &build_version) == 0)
4717 break;
4718 MinOS min_os(build_version.minos);
4719 OSEnv os_env(build_version.platform);
4720 llvm::SmallString<16> os_name;
4721 llvm::raw_svector_ostream os(os_name);
4722 os << os_env.os_type << min_os.major_version << '.'
4723 << min_os.minor_version << '.' << min_os.patch_version;
4724 auto triple = base_triple;
4725 triple.setOSName(os.str());
4726 os_name.clear();
4727 if (!os_env.environment.empty())
4728 triple.setEnvironmentName(os_env.environment);
4729 add_triple(triple);
4730 }
4731 } while (false);
4732 offset = cmd_offset + load_cmd.cmdsize;
4733 }
4734
4735 if (!found_any) {
4736 add_triple(base_triple);
4737 }
4738}
4739
4741 ModuleSP module_sp, const llvm::MachO::mach_header &header,
4742 const lldb_private::DataExtractor &data, lldb::offset_t lc_offset) {
4743 ModuleSpecList all_specs;
4744 ModuleSpec base_spec;
4745 GetAllArchSpecs(header, data, MachHeaderSizeFromMagic(header.magic),
4746 base_spec, all_specs);
4747
4748 // If the object file offers multiple alternative load commands,
4749 // pick the one that matches the module.
4750 if (module_sp) {
4751 const ArchSpec &module_arch = module_sp->GetArchitecture();
4752 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
4753 ArchSpec mach_arch =
4755 if (module_arch.IsCompatibleMatch(mach_arch))
4756 return mach_arch;
4757 }
4758 }
4759
4760 // Return the first arch we found.
4761 if (all_specs.GetSize() == 0)
4762 return {};
4763 return all_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();
4764}
4765
4767 ModuleSP module_sp(GetModule());
4768 if (module_sp) {
4769 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4771 return GetUUID(m_header, *m_data_nsp, offset);
4772 }
4773 return UUID();
4774}
4775
4777 ModuleSP module_sp = GetModule();
4778 if (!module_sp)
4779 return 0;
4780
4781 uint32_t count = 0;
4782 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4783 llvm::MachO::load_command load_cmd;
4785 std::vector<std::string> rpath_paths;
4786 std::vector<std::string> rpath_relative_paths;
4787 std::vector<std::string> at_exec_relative_paths;
4788 uint32_t i;
4789 for (i = 0; i < m_header.ncmds; ++i) {
4790 const uint32_t cmd_offset = offset;
4791 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
4792 break;
4793
4794 switch (load_cmd.cmd) {
4795 case LC_RPATH:
4796 case LC_LOAD_DYLIB:
4797 case LC_LOAD_WEAK_DYLIB:
4798 case LC_REEXPORT_DYLIB:
4799 case LC_LOAD_DYLINKER:
4800 case LC_LOADFVMLIB:
4801 case LC_LOAD_UPWARD_DYLIB: {
4802 uint32_t name_offset = cmd_offset + m_data_nsp->GetU32(&offset);
4803 // For LC_LOAD_DYLIB there is an alternate encoding
4804 // which adds a uint32_t `flags` field for `DYLD_USE_*`
4805 // flags. This can be detected by a timestamp field with
4806 // the `DYLIB_USE_MARKER` constant value.
4807 bool is_delayed_init = false;
4808 uint32_t use_command_marker = m_data_nsp->GetU32(&offset);
4809 if (use_command_marker == 0x1a741800 /* DYLIB_USE_MARKER */) {
4810 offset += 4; /* uint32_t current_version */
4811 offset += 4; /* uint32_t compat_version */
4812 uint32_t flags = m_data_nsp->GetU32(&offset);
4813 // If this LC_LOAD_DYLIB is marked delay-init,
4814 // don't report it as a dependent library -- it
4815 // may be loaded in the process at some point,
4816 // but will most likely not be load at launch.
4817 if (flags & 0x08 /* DYLIB_USE_DELAYED_INIT */)
4818 is_delayed_init = true;
4819 }
4820 const char *path = m_data_nsp->PeekCStr(name_offset);
4821 if (path && !is_delayed_init) {
4822 if (load_cmd.cmd == LC_RPATH)
4823 rpath_paths.push_back(path);
4824 else {
4825 if (path[0] == '@') {
4826 if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
4827 rpath_relative_paths.push_back(path + strlen("@rpath"));
4828 else if (strncmp(path, "@executable_path",
4829 strlen("@executable_path")) == 0)
4830 at_exec_relative_paths.push_back(path +
4831 strlen("@executable_path"));
4832 } else {
4833 FileSpec file_spec(path);
4834 if (files.AppendIfUnique(file_spec))
4835 count++;
4836 }
4837 }
4838 }
4839 } break;
4840
4841 default:
4842 break;
4843 }
4844 offset = cmd_offset + load_cmd.cmdsize;
4845 }
4846
4847 FileSpec this_file_spec(m_file);
4848 FileSystem::Instance().Resolve(this_file_spec);
4849
4850 if (!rpath_paths.empty()) {
4851 // Fixup all LC_RPATH values to be absolute paths.
4852 const std::string this_directory = this_file_spec.GetDirectory().str();
4853 for (auto &rpath : rpath_paths) {
4854 if (llvm::StringRef(rpath).starts_with(g_loader_path))
4855 rpath = this_directory + rpath.substr(g_loader_path.size());
4856 else if (llvm::StringRef(rpath).starts_with(g_executable_path))
4857 rpath = this_directory + rpath.substr(g_executable_path.size());
4858 }
4859
4860 for (const auto &rpath_relative_path : rpath_relative_paths) {
4861 for (const auto &rpath : rpath_paths) {
4862 std::string path = rpath;
4863 path += rpath_relative_path;
4864 // It is OK to resolve this path because we must find a file on disk
4865 // for us to accept it anyway if it is rpath relative.
4866 FileSpec file_spec(path);
4867 FileSystem::Instance().Resolve(file_spec);
4868 if (FileSystem::Instance().Exists(file_spec) &&
4869 files.AppendIfUnique(file_spec)) {
4870 count++;
4871 break;
4872 }
4873 }
4874 }
4875 }
4876
4877 // We may have @executable_paths but no RPATHS. Figure those out here.
4878 // Only do this if this object file is the executable. We have no way to
4879 // get back to the actual executable otherwise, so we won't get the right
4880 // path.
4881 if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) {
4882 FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent();
4883 for (const auto &at_exec_relative_path : at_exec_relative_paths) {
4884 FileSpec file_spec =
4885 exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
4886 if (FileSystem::Instance().Exists(file_spec) &&
4887 files.AppendIfUnique(file_spec))
4888 count++;
4889 }
4890 }
4891 return count;
4892}
4893
4895 // If the object file is not an executable it can't hold the entry point.
4896 // m_entry_point_address is initialized to an invalid address, so we can just
4897 // return that. If m_entry_point_address is valid it means we've found it
4898 // already, so return the cached value.
4899
4900 if ((!IsExecutable() && !IsDynamicLoader()) ||
4901 m_entry_point_address.IsValid()) {
4902 return m_entry_point_address;
4903 }
4904
4905 // Otherwise, look for the UnixThread or Thread command. The data for the
4906 // Thread command is given in /usr/include/mach-o.h, but it is basically:
4907 //
4908 // uint32_t flavor - this is the flavor argument you would pass to
4909 // thread_get_state
4910 // uint32_t count - this is the count of longs in the thread state data
4911 // struct XXX_thread_state state - this is the structure from
4912 // <machine/thread_status.h> corresponding to the flavor.
4913 // <repeat this trio>
4914 //
4915 // So we just keep reading the various register flavors till we find the GPR
4916 // one, then read the PC out of there.
4917 // FIXME: We will need to have a "RegisterContext data provider" class at some
4918 // point that can get all the registers
4919 // out of data in this form & attach them to a given thread. That should
4920 // underlie the MacOS X User process plugin, and we'll also need it for the
4921 // MacOS X Core File process plugin. When we have that we can also use it
4922 // here.
4923 //
4924 // For now we hard-code the offsets and flavors we need:
4925 //
4926 //
4927
4928 ModuleSP module_sp(GetModule());
4929 if (module_sp) {
4930 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4931 llvm::MachO::load_command load_cmd;
4933 uint32_t i;
4934 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
4935 bool done = false;
4936
4937 for (i = 0; i < m_header.ncmds; ++i) {
4938 const lldb::offset_t cmd_offset = offset;
4939 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
4940 break;
4941
4942 switch (load_cmd.cmd) {
4943 case LC_UNIXTHREAD:
4944 case LC_THREAD: {
4945 while (offset < cmd_offset + load_cmd.cmdsize) {
4946 uint32_t flavor = m_data_nsp->GetU32(&offset);
4947 uint32_t count = m_data_nsp->GetU32(&offset);
4948 if (count == 0) {
4949 // We've gotten off somehow, log and exit;
4950 return m_entry_point_address;
4951 }
4952
4953 switch (m_header.cputype) {
4954 case llvm::MachO::CPU_TYPE_ARM:
4955 if (flavor == 1 ||
4956 flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32
4957 // from mach/arm/thread_status.h
4958 {
4959 offset += 60; // This is the offset of pc in the GPR thread state
4960 // data structure.
4961 start_address = m_data_nsp->GetU32(&offset);
4962 done = true;
4963 }
4964 break;
4965 case llvm::MachO::CPU_TYPE_ARM64:
4966 case llvm::MachO::CPU_TYPE_ARM64_32:
4967 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
4968 {
4969 offset += 256; // This is the offset of pc in the GPR thread state
4970 // data structure.
4971 start_address = m_data_nsp->GetU64(&offset);
4972 done = true;
4973 }
4974 break;
4975 case llvm::MachO::CPU_TYPE_X86_64:
4976 if (flavor ==
4977 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
4978 {
4979 offset += 16 * 8; // This is the offset of rip in the GPR thread
4980 // state data structure.
4981 start_address = m_data_nsp->GetU64(&offset);
4982 done = true;
4983 }
4984 break;
4985 default:
4986 return m_entry_point_address;
4987 }
4988 // Haven't found the GPR flavor yet, skip over the data for this
4989 // flavor:
4990 if (done)
4991 break;
4992 offset += count * 4;
4993 }
4994 } break;
4995 case LC_MAIN: {
4996 uint64_t entryoffset = m_data_nsp->GetU64(&offset);
4997 SectionSP text_segment_sp =
4999 if (text_segment_sp) {
5000 done = true;
5001 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5002 }
5003 } break;
5004
5005 default:
5006 break;
5007 }
5008 if (done)
5009 break;
5010
5011 // Go to the next load command:
5012 offset = cmd_offset + load_cmd.cmdsize;
5013 }
5014
5015 if (start_address == LLDB_INVALID_ADDRESS && IsDynamicLoader()) {
5016 if (GetSymtab()) {
5017 const Symbol *dyld_start_sym =
5021 if (dyld_start_sym && dyld_start_sym->GetAddress().IsValid()) {
5022 start_address = dyld_start_sym->GetAddress().GetFileAddress();
5023 }
5024 }
5025 }
5026
5027 if (start_address != LLDB_INVALID_ADDRESS) {
5028 // We got the start address from the load commands, so now resolve that
5029 // address in the sections of this ObjectFile:
5030 if (!m_entry_point_address.ResolveAddressUsingFileSections(
5031 start_address, GetSectionList())) {
5032 m_entry_point_address.Clear();
5033 }
5034 } else {
5035 // We couldn't read the UnixThread load command - maybe it wasn't there.
5036 // As a fallback look for the "start" symbol in the main executable.
5037
5038 ModuleSP module_sp(GetModule());
5039
5040 if (module_sp) {
5041 SymbolContextList contexts;
5042 SymbolContext context;
5043 module_sp->FindSymbolsWithNameAndType(ConstString("start"),
5044 eSymbolTypeCode, contexts);
5045 if (contexts.GetSize()) {
5046 if (contexts.GetContextAtIndex(0, context))
5048 }
5049 }
5050 }
5051 }
5052
5053 return m_entry_point_address;
5054}
5055
5057 lldb_private::Address header_addr;
5058 SectionList *section_list = GetSectionList();
5059 if (section_list) {
5060 SectionSP text_segment_sp(
5061 section_list->FindSectionByName(GetSegmentNameTEXT()));
5062 if (text_segment_sp)
5063 header_addr = Address(text_segment_sp, /*offset=*/0);
5064 }
5065 return header_addr;
5066}
5067
5069 ModuleSP module_sp(GetModule());
5070 if (module_sp) {
5071 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5075 FileRangeArray::Entry file_range;
5076 llvm::MachO::thread_command thread_cmd;
5077 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5078 const uint32_t cmd_offset = offset;
5079 if (!ReadMachOCommand(*m_data_nsp, offset, thread_cmd))
5080 break;
5081
5082 if (thread_cmd.cmd == LC_THREAD) {
5083 file_range.SetRangeBase(offset);
5084 file_range.SetByteSize(thread_cmd.cmdsize - 8);
5085 m_thread_context_offsets.Append(file_range);
5086 }
5087 offset = cmd_offset + thread_cmd.cmdsize;
5088 }
5089 }
5090 }
5091 return m_thread_context_offsets.GetSize();
5092}
5093
5094std::vector<std::tuple<offset_t, offset_t>>
5096 std::vector<std::tuple<offset_t, offset_t>> results;
5097 ModuleSP module_sp(GetModule());
5098 if (module_sp) {
5099 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5100
5102 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5103 const uint32_t cmd_offset = offset;
5104 llvm::MachO::load_command lc = {};
5105 if (!ReadMachOCommand(*m_data_nsp, offset, lc))
5106 break;
5107 if (lc.cmd == LC_NOTE) {
5108 char data_owner[17];
5109 m_data_nsp->CopyData(offset, 16, data_owner);
5110 data_owner[16] = '\0';
5111 offset += 16;
5112
5113 if (name == data_owner) {
5114 offset_t payload_offset = m_data_nsp->GetU64_unchecked(&offset);
5115 offset_t payload_size = m_data_nsp->GetU64_unchecked(&offset);
5116 results.push_back({payload_offset, payload_size});
5117 }
5118 }
5119 offset = cmd_offset + lc.cmdsize;
5120 }
5121 }
5122 return results;
5123}
5124
5126 Log *log(
5128 ModuleSP module_sp(GetModule());
5129 if (module_sp) {
5130 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5131
5132 auto lc_notes = FindLC_NOTEByName("kern ver str");
5133 for (auto lc_note : lc_notes) {
5134 offset_t payload_offset = std::get<0>(lc_note);
5135 offset_t payload_size = std::get<1>(lc_note);
5136 uint32_t version;
5137 if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr) {
5138 if (version == 1) {
5139 uint32_t strsize = payload_size - sizeof(uint32_t);
5140 std::string result(strsize, '\0');
5141 m_data_nsp->CopyData(payload_offset, strsize, result.data());
5142 LLDB_LOGF(log, "LC_NOTE 'kern ver str' found with text '%s'",
5143 result.c_str());
5144 return result;
5145 }
5146 }
5147 }
5148
5149 // Second, make a pass over the load commands looking for an obsolete
5150 // LC_IDENT load command.
5152 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5153 const uint32_t cmd_offset = offset;
5154 llvm::MachO::ident_command ident_command;
5155 if (!ReadMachOCommand(*m_data_nsp, offset, ident_command))
5156 break;
5157 if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
5158 std::string result(ident_command.cmdsize, '\0');
5159 if (m_data_nsp->CopyData(offset, ident_command.cmdsize,
5160 result.data()) == ident_command.cmdsize) {
5161 LLDB_LOGF(log, "LC_IDENT found with text '%s'", result.c_str());
5162 return result;
5163 }
5164 }
5165 offset = cmd_offset + ident_command.cmdsize;
5166 }
5167 }
5168 return {};
5169}
5170
5172 AddressableBits addressable_bits;
5173
5175 ModuleSP module_sp(GetModule());
5176 if (module_sp) {
5177 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5178 auto lc_notes = FindLC_NOTEByName("addrable bits");
5179 for (auto lc_note : lc_notes) {
5180 offset_t payload_offset = std::get<0>(lc_note);
5181 uint32_t version;
5182 if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr) {
5183 if (version == 3) {
5184 uint32_t num_addr_bits =
5185 m_data_nsp->GetU32_unchecked(&payload_offset);
5186 addressable_bits.SetAddressableBits(num_addr_bits);
5187 LLDB_LOGF(log,
5188 "LC_NOTE 'addrable bits' v3 found, value %d "
5189 "bits",
5190 num_addr_bits);
5191 }
5192 if (version == 4) {
5193 uint32_t lo_addr_bits = m_data_nsp->GetU32_unchecked(&payload_offset);
5194 uint32_t hi_addr_bits = m_data_nsp->GetU32_unchecked(&payload_offset);
5195
5196 if (lo_addr_bits == hi_addr_bits)
5197 addressable_bits.SetAddressableBits(lo_addr_bits);
5198 else
5199 addressable_bits.SetAddressableBits(lo_addr_bits, hi_addr_bits);
5200 LLDB_LOGF(log, "LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
5201 lo_addr_bits, hi_addr_bits);
5202 }
5203 }
5204 }
5205 }
5206 return addressable_bits;
5207}
5208
5210 bool &value_is_offset,
5211 UUID &uuid,
5212 ObjectFile::BinaryType &type) {
5213 Log *log(
5215 value = LLDB_INVALID_ADDRESS;
5216 value_is_offset = false;
5217 uuid.Clear();
5218 uint32_t log2_pagesize = 0; // not currently passed up to caller
5219 uint32_t platform = 0; // not currently passed up to caller
5220 ModuleSP module_sp(GetModule());
5221 if (module_sp) {
5222 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5223
5224 auto lc_notes = FindLC_NOTEByName("main bin spec");
5225 for (auto lc_note : lc_notes) {
5226 offset_t payload_offset = std::get<0>(lc_note);
5227
5228 // struct main_bin_spec
5229 // {
5230 // uint32_t version; // currently 2
5231 // uint32_t type; // 0 == unspecified,
5232 // // 1 == kernel
5233 // // 2 == user process,
5234 // dyld mach-o binary addr
5235 // // 3 == standalone binary
5236 // // 4 == user process,
5237 // // dyld_all_image_infos addr
5238 // uint64_t address; // UINT64_MAX if address not specified
5239 // uint64_t slide; // slide, UINT64_MAX if unspecified
5240 // // 0 if no slide needs to be applied to
5241 // // file address
5242 // uuid_t uuid; // all zero's if uuid not specified
5243 // uint32_t log2_pagesize; // process page size in log base 2,
5244 // // e.g. 4k pages are 12.
5245 // // 0 for unspecified
5246 // uint32_t platform; // The Mach-O platform for this corefile.
5247 // // 0 for unspecified.
5248 // // The values are defined in
5249 // // <mach-o/loader.h>, PLATFORM_*.
5250 // } __attribute((packed));
5251
5252 // "main bin spec" (main binary specification) data payload is
5253 // formatted:
5254 // uint32_t version [currently 1]
5255 // uint32_t type [0 == unspecified, 1 == kernel,
5256 // 2 == user process, 3 == firmware ]
5257 // uint64_t address [ UINT64_MAX if address not specified ]
5258 // uuid_t uuid [ all zero's if uuid not specified ]
5259 // uint32_t log2_pagesize [ process page size in log base
5260 // 2, e.g. 4k pages are 12.
5261 // 0 for unspecified ]
5262 // uint32_t unused [ for alignment ]
5263
5264 uint32_t version;
5265 if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr &&
5266 version <= 2) {
5267 uint32_t binspec_type = 0;
5268 uuid_t raw_uuid;
5269 memset(raw_uuid, 0, sizeof(uuid_t));
5270
5271 if (!m_data_nsp->GetU32(&payload_offset, &binspec_type, 1))
5272 return false;
5273 if (!m_data_nsp->GetU64(&payload_offset, &value, 1))
5274 return false;
5275 uint64_t slide = LLDB_INVALID_ADDRESS;
5276 if (version > 1 && !m_data_nsp->GetU64(&payload_offset, &slide, 1))
5277 return false;
5278 if (value == LLDB_INVALID_ADDRESS && slide != LLDB_INVALID_ADDRESS) {
5279 value = slide;
5280 value_is_offset = true;
5281 }
5282
5283 if (m_data_nsp->CopyData(payload_offset, sizeof(uuid_t), raw_uuid) !=
5284 0) {
5285 uuid = UUID(raw_uuid, sizeof(uuid_t));
5286 // convert the "main bin spec" type into our
5287 // ObjectFile::BinaryType enum
5288 const char *typestr = "unrecognized type";
5289 type = eBinaryTypeInvalid;
5290 switch (binspec_type) {
5291 case 0:
5292 type = eBinaryTypeUnknown;
5293 typestr = "uknown";
5294 break;
5295 case 1:
5296 type = eBinaryTypeKernel;
5297 typestr = "xnu kernel";
5298 break;
5299 case 2:
5300 type = eBinaryTypeUser;
5301 typestr = "userland dyld";
5302 break;
5303 case 3:
5304 type = eBinaryTypeStandalone;
5305 typestr = "standalone";
5306 break;
5307 case 4:
5309 typestr = "userland dyld_all_image_infos";
5310 break;
5311 }
5312 LLDB_LOGF(log,
5313 "LC_NOTE 'main bin spec' found, version %d type %d "
5314 "(%s), value 0x%" PRIx64 " value-is-slide==%s uuid %s",
5315 version, type, typestr, value,
5316 value_is_offset ? "true" : "false",
5317 uuid.GetAsString().c_str());
5318 if (!m_data_nsp->GetU32(&payload_offset, &log2_pagesize, 1))
5319 return false;
5320 if (version > 1 && !m_data_nsp->GetU32(&payload_offset, &platform, 1))
5321 return false;
5322 return true;
5323 }
5324 }
5325 }
5326 }
5327 return false;
5328}
5329
5331 std::vector<lldb::tid_t> &tids) {
5332 tids.clear();
5333 ModuleSP module_sp(GetModule());
5334 if (module_sp) {
5335 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5336
5339 StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
5340 StructuredData::Array *threads;
5341 if (!dict->GetValueForKeyAsArray("threads", threads) || !threads) {
5342 LLDB_LOGF(log,
5343 "'process metadata' LC_NOTE does not have a 'threads' key");
5344 return false;
5345 }
5346 if (threads->GetSize() != GetNumThreadContexts()) {
5347 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, number of "
5348 "threads does not match number of LC_THREADS.");
5349 return false;
5350 }
5351 const size_t num_threads = threads->GetSize();
5352 for (size_t i = 0; i < num_threads; i++) {
5353 std::optional<StructuredData::Dictionary *> maybe_thread =
5354 threads->GetItemAtIndexAsDictionary(i);
5355 if (!maybe_thread) {
5356 LLDB_LOGF(log,
5357 "Unable to read 'process metadata' LC_NOTE, threads "
5358 "array does not have a dictionary at index %zu.",
5359 i);
5360 return false;
5361 }
5362 StructuredData::Dictionary *thread = *maybe_thread;
5364 if (thread->GetValueForKeyAsInteger<lldb::tid_t>("thread_id", tid))
5365 if (tid == 0)
5367 tids.push_back(tid);
5368 }
5369
5370 if (log) {
5371 StreamString logmsg;
5372 logmsg.Printf("LC_NOTE 'process metadata' found: ");
5373 dict->Dump(logmsg, /* pretty_print */ false);
5374 LLDB_LOGF(log, "%s", logmsg.GetData());
5375 }
5376 return true;
5377 }
5378 }
5379 return false;
5380}
5381
5383 ModuleSP module_sp(GetModule());
5384 if (!module_sp)
5385 return {};
5386
5388 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5389 auto lc_notes = FindLC_NOTEByName("process metadata");
5390 if (lc_notes.size() == 0)
5391 return {};
5392
5393 if (lc_notes.size() > 1)
5394 LLDB_LOGF(
5395 log,
5396 "Multiple 'process metadata' LC_NOTEs found, only using the first.");
5397
5398 auto [payload_offset, strsize] = lc_notes[0];
5399 std::string buf(strsize, '\0');
5400 if (m_data_nsp->CopyData(payload_offset, strsize, buf.data()) != strsize) {
5401 LLDB_LOGF(log,
5402 "Unable to read %" PRIu64
5403 " bytes of 'process metadata' LC_NOTE JSON contents",
5404 strsize);
5405 return {};
5406 }
5407 while (buf.back() == '\0')
5408 buf.resize(buf.size() - 1);
5410 if (!object_sp) {
5411 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
5412 "parse as valid JSON.");
5413 return {};
5414 }
5415 StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
5416 if (!dict) {
5417 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
5418 "get a dictionary.");
5419 return {};
5420 }
5421
5422 return object_sp;
5423}
5424
5427 lldb_private::Thread &thread) {
5428 lldb::RegisterContextSP reg_ctx_sp;
5429
5430 ModuleSP module_sp(GetModule());
5431 if (module_sp) {
5432 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5435
5436 const FileRangeArray::Entry *thread_context_file_range =
5437 m_thread_context_offsets.GetEntryAtIndex(idx);
5438 if (thread_context_file_range) {
5439
5440 DataExtractor data(*m_data_nsp, thread_context_file_range->GetRangeBase(),
5441 thread_context_file_range->GetByteSize());
5442
5443 switch (m_header.cputype) {
5444 case llvm::MachO::CPU_TYPE_ARM64:
5445 case llvm::MachO::CPU_TYPE_ARM64_32:
5446 reg_ctx_sp =
5447 std::make_shared<RegisterContextDarwin_arm64_Mach>(thread, data);
5448 break;
5449
5450 case llvm::MachO::CPU_TYPE_ARM:
5451 reg_ctx_sp =
5452 std::make_shared<RegisterContextDarwin_arm_Mach>(thread, data);
5453 break;
5454
5455 case llvm::MachO::CPU_TYPE_X86_64:
5456 reg_ctx_sp =
5457 std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);
5458 break;
5459
5460 case llvm::MachO::CPU_TYPE_RISCV:
5461 reg_ctx_sp =
5462 std::make_shared<RegisterContextDarwin_riscv32_Mach>(thread, data);
5463 break;
5464 }
5465 }
5466 }
5467 return reg_ctx_sp;
5468}
5469
5471 switch (m_header.filetype) {
5472 case MH_OBJECT: // 0x1u
5473 if (GetAddressByteSize() == 4) {
5474 // 32 bit kexts are just object files, but they do have a valid
5475 // UUID load command.
5476 if (GetUUID()) {
5477 // this checking for the UUID load command is not enough we could
5478 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
5479 // this is required of kexts
5480 if (m_strata == eStrataInvalid)
5482 return eTypeSharedLibrary;
5483 }
5484 }
5485 return eTypeObjectFile;
5486
5487 case MH_EXECUTE:
5488 return eTypeExecutable; // 0x2u
5489 case MH_FVMLIB:
5490 return eTypeSharedLibrary; // 0x3u
5491 case MH_CORE:
5492 return eTypeCoreFile; // 0x4u
5493 case MH_PRELOAD:
5494 return eTypeSharedLibrary; // 0x5u
5495 case MH_DYLIB:
5496 return eTypeSharedLibrary; // 0x6u
5497 case MH_DYLINKER:
5498 return eTypeDynamicLinker; // 0x7u
5499 case MH_BUNDLE:
5500 return eTypeSharedLibrary; // 0x8u
5501 case MH_DYLIB_STUB:
5502 return eTypeStubLibrary; // 0x9u
5503 case MH_DSYM:
5504 return eTypeDebugInfo; // 0xAu
5505 case MH_KEXT_BUNDLE:
5506 return eTypeSharedLibrary; // 0xBu
5507 default:
5508 break;
5509 }
5510 return eTypeUnknown;
5511}
5512
5514 switch (m_header.filetype) {
5515 case MH_OBJECT: // 0x1u
5516 {
5517 // 32 bit kexts are just object files, but they do have a valid
5518 // UUID load command.
5519 if (GetUUID()) {
5520 // this checking for the UUID load command is not enough we could
5521 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
5522 // this is required of kexts
5523 if (m_type == eTypeInvalid)
5525
5526 return eStrataKernel;
5527 }
5528 }
5529 return eStrataUnknown;
5530
5531 case MH_EXECUTE: // 0x2u
5532 // Check for the MH_DYLDLINK bit in the flags
5533 if (m_header.flags & MH_DYLDLINK) {
5534 return eStrataUser;
5535 } else {
5536 SectionList *section_list = GetSectionList();
5537 if (section_list) {
5538 if (section_list->FindSectionByName("__KLD"))
5539 return eStrataKernel;
5540 }
5541 }
5542 return eStrataRawImage;
5543
5544 case MH_FVMLIB:
5545 return eStrataUser; // 0x3u
5546 case MH_CORE:
5547 return eStrataUnknown; // 0x4u
5548 case MH_PRELOAD:
5549 return eStrataRawImage; // 0x5u
5550 case MH_DYLIB:
5551 return eStrataUser; // 0x6u
5552 case MH_DYLINKER:
5553 return eStrataUser; // 0x7u
5554 case MH_BUNDLE:
5555 return eStrataUser; // 0x8u
5556 case MH_DYLIB_STUB:
5557 return eStrataUser; // 0x9u
5558 case MH_DSYM:
5559 return eStrataUnknown; // 0xAu
5560 case MH_KEXT_BUNDLE:
5561 return eStrataKernel; // 0xBu
5562 default:
5563 break;
5564 }
5565 return eStrataUnknown;
5566}
5567
5568llvm::VersionTuple ObjectFileMachO::GetVersion() {
5569 ModuleSP module_sp(GetModule());
5570 if (module_sp) {
5571 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5572 llvm::MachO::dylib_command load_cmd;
5574 uint32_t version_cmd = 0;
5575 uint64_t version = 0;
5576 uint32_t i;
5577 for (i = 0; i < m_header.ncmds; ++i) {
5578 const lldb::offset_t cmd_offset = offset;
5579 if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
5580 break;
5581
5582 if (load_cmd.cmd == LC_ID_DYLIB) {
5583 if (version_cmd == 0) {
5584 version_cmd = load_cmd.cmd;
5585 if (m_data_nsp->GetU32(&offset, &load_cmd.dylib, 4) == nullptr)
5586 break;
5587 version = load_cmd.dylib.current_version;
5588 }
5589 break; // Break for now unless there is another more complete version
5590 // number load command in the future.
5591 }
5592 offset = cmd_offset + load_cmd.cmdsize;
5593 }
5594
5595 if (version_cmd == LC_ID_DYLIB) {
5596 unsigned major = (version & 0xFFFF0000ull) >> 16;
5597 unsigned minor = (version & 0x0000FF00ull) >> 8;
5598 unsigned subminor = (version & 0x000000FFull);
5599 return llvm::VersionTuple(major, minor, subminor);
5600 }
5601 }
5602 return llvm::VersionTuple();
5603}
5604
5606 ModuleSP module_sp(GetModule());
5607 ArchSpec arch;
5608 if (module_sp) {
5609 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5610
5611 return GetArchitecture(module_sp, m_header, *m_data_nsp,
5613 }
5614 return arch;
5615}
5616
5618 addr_t &base_addr, UUID &uuid) {
5619 uuid.Clear();
5620 base_addr = LLDB_INVALID_ADDRESS;
5621 if (process && process->GetDynamicLoader()) {
5622 DynamicLoader *dl = process->GetDynamicLoader();
5623 LazyBool using_shared_cache;
5624 LazyBool private_shared_cache;
5625 FileSpec sc_filepath;
5626 std::optional<uint64_t> size;
5627 dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,
5628 private_shared_cache, sc_filepath, size);
5629 }
5631 LLDB_LOGF(
5632 log,
5633 "inferior process shared cache has a UUID of %s, base address 0x%" PRIx64,
5634 uuid.GetAsString().c_str(), base_addr);
5635}
5636
5637// From dyld SPI header dyld_process_info.h
5638typedef void *dyld_process_info;
5640 uuid_t cacheUUID; // UUID of cache used by process
5641 uint64_t cacheBaseAddress; // load address of dyld shared cache
5642 bool noCache; // process is running without a dyld cache
5643 bool privateCache; // process is using a private copy of its dyld cache
5644};
5645
5646// #including mach/mach.h pulls in machine.h & CPU_TYPE_ARM etc conflicts with
5647// llvm enum definitions llvm::MachO::CPU_TYPE_ARM turning them into compile
5648// errors. So we need to use the actual underlying types of task_t and
5649// kern_return_t below.
5650extern "C" unsigned int /*task_t*/ mach_task_self();
5651
5653 uuid.Clear();
5654 base_addr = LLDB_INVALID_ADDRESS;
5655
5656#if defined(__APPLE__)
5657 uint8_t *(*dyld_get_all_image_infos)(void);
5658 dyld_get_all_image_infos =
5659 (uint8_t * (*)()) dlsym(RTLD_DEFAULT, "_dyld_get_all_image_infos");
5660 if (dyld_get_all_image_infos) {
5661 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5662 if (dyld_all_image_infos_address) {
5663 uint32_t *version = (uint32_t *)
5664 dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
5665 if (*version >= 13) {
5666 uuid_t *sharedCacheUUID_address = 0;
5667 int wordsize = sizeof(uint8_t *);
5668 if (wordsize == 8) {
5669 sharedCacheUUID_address =
5670 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5671 160); // sharedCacheUUID <mach-o/dyld_images.h>
5672 if (*version >= 15)
5673 base_addr =
5674 *(uint64_t
5675 *)((uint8_t *)dyld_all_image_infos_address +
5676 176); // sharedCacheBaseAddress <mach-o/dyld_images.h>
5677 } else {
5678 sharedCacheUUID_address =
5679 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5680 84); // sharedCacheUUID <mach-o/dyld_images.h>
5681 if (*version >= 15) {
5682 base_addr = 0;
5683 base_addr =
5684 *(uint32_t
5685 *)((uint8_t *)dyld_all_image_infos_address +
5686 100); // sharedCacheBaseAddress <mach-o/dyld_images.h>
5687 }
5688 }
5689 uuid = UUID(sharedCacheUUID_address, sizeof(uuid_t));
5690 }
5691 }
5692 } else {
5693 // Exists in macOS 10.12 and later, iOS 10.0 and later - dyld SPI
5694 dyld_process_info (*dyld_process_info_create)(
5695 unsigned int /* task_t */ task, uint64_t timestamp,
5696 unsigned int /*kern_return_t*/ *kernelError);
5697 void (*dyld_process_info_get_cache)(void *info, void *cacheInfo);
5698 void (*dyld_process_info_release)(dyld_process_info info);
5699
5700 dyld_process_info_create = (void *(*)(unsigned int /* task_t */, uint64_t,
5701 unsigned int /*kern_return_t*/ *))
5702 dlsym(RTLD_DEFAULT, "_dyld_process_info_create");
5703 dyld_process_info_get_cache = (void (*)(void *, void *))dlsym(
5704 RTLD_DEFAULT, "_dyld_process_info_get_cache");
5705 dyld_process_info_release =
5706 (void (*)(void *))dlsym(RTLD_DEFAULT, "_dyld_process_info_release");
5707
5708 if (dyld_process_info_create && dyld_process_info_get_cache) {
5709 unsigned int /*kern_return_t */ kern_ret;
5710 dyld_process_info process_info =
5711 dyld_process_info_create(::mach_task_self(), 0, &kern_ret);
5712 if (process_info) {
5714 memset(&sc_info, 0, sizeof(struct lldb_copy__dyld_process_cache_info));
5715 dyld_process_info_get_cache(process_info, &sc_info);
5716 if (sc_info.cacheBaseAddress != 0) {
5717 base_addr = sc_info.cacheBaseAddress;
5718 uuid = UUID(sc_info.cacheUUID, sizeof(uuid_t));
5719 }
5720 dyld_process_info_release(process_info);
5721 }
5722 }
5723 }
5725 if (log && uuid.IsValid())
5726 LLDB_LOGF(log,
5727 "lldb's in-memory shared cache has a UUID of %s base address of "
5728 "0x%" PRIx64,
5729 uuid.GetAsString().c_str(), base_addr);
5730#endif
5731}
5732
5733static llvm::VersionTuple FindMinimumVersionInfo(DataExtractor &data,
5734 lldb::offset_t offset,
5735 size_t ncmds) {
5736 for (size_t i = 0; i < ncmds; i++) {
5737 const lldb::offset_t load_cmd_offset = offset;
5738 llvm::MachO::load_command lc = {};
5739 if (!ReadMachOCommand(data, offset, lc))
5740 break;
5741
5742 uint32_t version = 0;
5743 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
5744 lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
5745 lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
5746 lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
5747 // struct version_min_command {
5748 // uint32_t cmd; // LC_VERSION_MIN_*
5749 // uint32_t cmdsize;
5750 // uint32_t version; // X.Y.Z encoded in nibbles xxxx.yy.zz
5751 // uint32_t sdk;
5752 // };
5753 // We want to read version.
5754 version = data.GetU32(&offset);
5755 } else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
5756 // struct build_version_command {
5757 // uint32_t cmd; // LC_BUILD_VERSION
5758 // uint32_t cmdsize;
5759 // uint32_t platform;
5760 // uint32_t minos; // X.Y.Z encoded in nibbles xxxx.yy.zz
5761 // uint32_t sdk;
5762 // uint32_t ntools;
5763 // };
5764 // We want to read minos.
5765 offset += sizeof(uint32_t); // Skip over platform
5766 version = data.GetU32(&offset); // Extract minos
5767 }
5768
5769 if (version) {
5770 const uint32_t xxxx = version >> 16;
5771 const uint32_t yy = (version >> 8) & 0xffu;
5772 const uint32_t zz = version & 0xffu;
5773 if (xxxx)
5774 return llvm::VersionTuple(xxxx, yy, zz);
5775 }
5776 offset = load_cmd_offset + lc.cmdsize;
5777 }
5778 return llvm::VersionTuple();
5779}
5780
5787
5794
5796 return m_header.filetype == llvm::MachO::MH_DYLINKER;
5797}
5798
5800 // Dsymutil guarantees that the .debug_aranges accelerator is complete and can
5801 // be trusted by LLDB.
5802 return m_header.filetype == llvm::MachO::MH_DSYM;
5803}
5804
5808
5810 // Find the first address of the mach header which is the first non-zero file
5811 // sized section whose file offset is zero. This is the base file address of
5812 // the mach-o file which can be subtracted from the vmaddr of the other
5813 // segments found in memory and added to the load address
5814 ModuleSP module_sp = GetModule();
5815 if (!module_sp)
5816 return nullptr;
5817 SectionList *section_list = GetSectionList();
5818 if (!section_list)
5819 return nullptr;
5820
5821 // Some binaries can have a TEXT segment with a non-zero file offset.
5822 // Binaries in the shared cache are one example. Some hand-generated
5823 // binaries may not be laid out in the normal TEXT,DATA,LC_SYMTAB order
5824 // in the file, even though they're laid out correctly in vmaddr terms.
5825 SectionSP text_segment_sp =
5826 section_list->FindSectionByName(GetSegmentNameTEXT());
5827 if (text_segment_sp.get() && SectionIsLoadable(text_segment_sp.get()))
5828 return text_segment_sp.get();
5829
5830 const size_t num_sections = section_list->GetSize();
5831 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
5832 Section *section = section_list->GetSectionAtIndex(sect_idx).get();
5833 if (section->GetFileOffset() == 0 && SectionIsLoadable(section))
5834 return section;
5835 }
5836
5837 return nullptr;
5838}
5839
5841 assert(section.GetObjectFile() == this && "Wrong object file!");
5842 SectionSP segment = section.GetParent();
5843 if (!segment)
5844 return false;
5845
5846 const bool is_data_const_got =
5847 segment->GetName() == "__DATA_CONST" && section.GetName() == "__got";
5848 const bool is_auth_const_ptr =
5849 segment->GetName() == "__AUTH_CONST" &&
5850 (section.GetName() == "__auth_got" || section.GetName() == "__auth_ptr");
5851 return is_data_const_got || is_auth_const_ptr;
5852}
5853
5855 if (!section)
5856 return false;
5857 if (section->IsThreadSpecific())
5858 return false;
5859 if (GetModule().get() != section->GetModule().get())
5860 return false;
5861 // firmware style binaries with llvm gcov segment do
5862 // not have that segment mapped into memory.
5863 if (section->GetName() == GetSegmentNameLLVM_COV()) {
5864 const Strata strata = GetStrata();
5865 if (strata == eStrataKernel || strata == eStrataRawImage)
5866 return false;
5867 }
5868 // Be careful with __LINKEDIT and __DWARF segments
5869 if (section->GetName() == GetSegmentNameLINKEDIT() ||
5870 section->GetName() == GetSegmentNameDWARF()) {
5871 // Only map __LINKEDIT and __DWARF if we have an in memory image and
5872 // this isn't a kernel binary like a kext or mach_kernel.
5873 const bool is_memory_image = (bool)m_process_wp.lock();
5874 const Strata strata = GetStrata();
5875 if (is_memory_image == false || strata == eStrataKernel)
5876 return false;
5877 }
5878 return true;
5879}
5880
5882 lldb::addr_t header_load_address, const Section *header_section,
5883 const Section *section) {
5884 ModuleSP module_sp = GetModule();
5885 if (module_sp && header_section && section &&
5886 header_load_address != LLDB_INVALID_ADDRESS) {
5887 lldb::addr_t file_addr = header_section->GetFileAddress();
5888 if (file_addr != LLDB_INVALID_ADDRESS && SectionIsLoadable(section))
5889 return section->GetFileAddress() - file_addr + header_load_address;
5890 }
5891 return LLDB_INVALID_ADDRESS;
5892}
5893
5895 bool value_is_offset) {
5897 ModuleSP module_sp = GetModule();
5898 if (!module_sp)
5899 return false;
5900
5901 SectionList *section_list = GetSectionList();
5902 if (!section_list)
5903 return false;
5904
5905 size_t num_loaded_sections = 0;
5906 const size_t num_sections = section_list->GetSize();
5907
5908 // Warn if some top-level segments map to the same address. The binary may be
5909 // malformed.
5910 const bool warn_multiple = true;
5911
5912 if (log) {
5913 StreamString logmsg;
5914 logmsg << "ObjectFileMachO::SetLoadAddress ";
5915 if (GetFileSpec())
5916 logmsg << "path='" << GetFileSpec().GetPath() << "' ";
5917 if (GetUUID()) {
5918 logmsg << "uuid=" << GetUUID().GetAsString();
5919 }
5920 LLDB_LOGF(log, "%s", logmsg.GetData());
5921 }
5922 if (value_is_offset) {
5923 // "value" is an offset to apply to each top level segment
5924 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
5925 // Iterate through the object file sections to find all of the
5926 // sections that size on disk (to avoid __PAGEZERO) and load them
5927 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
5928 if (SectionIsLoadable(section_sp.get())) {
5929 LLDB_LOG(
5930 log,
5931 "ObjectFileMachO::SetLoadAddress segment '{0}' load addr is {1:x}",
5932 section_sp->GetName(), section_sp->GetFileAddress() + value);
5933 if (target.SetSectionLoadAddress(section_sp,
5934 section_sp->GetFileAddress() + value,
5935 warn_multiple))
5936 ++num_loaded_sections;
5937 }
5938 }
5939 } else {
5940 // "value" is the new base address of the mach_header, adjust each
5941 // section accordingly
5942
5943 Section *mach_header_section = GetMachHeaderSection();
5944 if (mach_header_section) {
5945 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
5946 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
5947
5948 lldb::addr_t section_load_addr =
5950 value, mach_header_section, section_sp.get());
5951 if (section_load_addr != LLDB_INVALID_ADDRESS) {
5952 LLDB_LOG(log,
5953 "ObjectFileMachO::SetLoadAddress segment '{0}' load addr is "
5954 "{1:x}",
5955 section_sp->GetName(), section_load_addr);
5956 if (target.SetSectionLoadAddress(section_sp, section_load_addr,
5957 warn_multiple))
5958 ++num_loaded_sections;
5959 }
5960 }
5961 }
5962 }
5963 return num_loaded_sections > 0;
5964}
5965
5967 uint32_t version; // currently 1
5968 uint32_t imgcount; // number of binary images
5969 uint64_t entries_fileoff; // file offset in the corefile of where the array of
5970 // struct entry's begin.
5971 uint32_t entries_size; // size of 'struct entry'.
5972 uint32_t unused;
5973};
5974
5976 uint64_t filepath_offset; // offset in corefile to c-string of the file path,
5977 // UINT64_MAX if unavailable.
5978 uuid_t uuid; // uint8_t[16]. should be set to all zeroes if
5979 // uuid is unknown.
5980 uint64_t load_address; // UINT64_MAX if unknown.
5981 uint64_t seg_addrs_offset; // offset to the array of struct segment_vmaddr's.
5982 uint32_t segment_count; // The number of segments for this binary.
5983 uint32_t unused;
5984
5987 memset(&uuid, 0, sizeof(uuid_t));
5988 segment_count = 0;
5991 unused = 0;
5992 }
5995 memcpy(&uuid, &rhs.uuid, sizeof(uuid_t));
5999 unused = rhs.unused;
6000 }
6001};
6002
6004 char segname[16];
6005 uint64_t vmaddr;
6006 uint64_t unused;
6007
6009 memset(&segname, 0, 16);
6011 unused = 0;
6012 }
6014 memcpy(&segname, &rhs.segname, 16);
6015 vmaddr = rhs.vmaddr;
6016 unused = rhs.unused;
6017 }
6018};
6019
6020// Write the payload for the "all image infos" LC_NOTE into
6021// the supplied all_image_infos_payload, assuming that this
6022// will be written into the corefile starting at
6023// initial_file_offset.
6024//
6025// The placement of this payload is a little tricky. We're
6026// laying this out as
6027//
6028// 1. header (struct all_image_info_header)
6029// 2. Array of fixed-size (struct image_entry)'s, one
6030// per binary image present in the process.
6031// 3. Arrays of (struct segment_vmaddr)'s, a varying number
6032// for each binary image.
6033// 4. Variable length c-strings of binary image filepaths,
6034// one per binary.
6035//
6036// To compute where everything will be laid out in the
6037// payload, we need to iterate over the images and calculate
6038// how many segment_vmaddr structures each image will need,
6039// and how long each image's filepath c-string is. There
6040// are some multiple passes over the image list while calculating
6041// everything.
6042
6043static offset_t
6045 offset_t initial_file_offset,
6046 StreamString &all_image_infos_payload,
6048 Target &target = process_sp->GetTarget();
6049 ModuleList modules = target.GetImages();
6050
6051 // stack-only corefiles have no reason to include binaries that
6052 // are not executing; we're trying to make the smallest corefile
6053 // we can, so leave the rest out.
6055 modules.Clear();
6056
6057 std::set<std::string> executing_uuids;
6058 std::vector<ThreadSP> thread_list =
6059 process_sp->CalculateCoreFileThreadList(options);
6060 for (const ThreadSP &thread_sp : thread_list) {
6061 uint32_t stack_frame_count = thread_sp->GetStackFrameCount();
6062 for (uint32_t j = 0; j < stack_frame_count; j++) {
6063 StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);
6064 Address pc = stack_frame_sp->GetFrameCodeAddress();
6065 ModuleSP module_sp = pc.GetModule();
6066 if (module_sp) {
6067 UUID uuid = module_sp->GetUUID();
6068 if (uuid.IsValid()) {
6069 executing_uuids.insert(uuid.GetAsString());
6070 modules.AppendIfNeeded(module_sp);
6071 }
6072 }
6073 }
6074 }
6075 size_t modules_count = modules.GetSize();
6076
6077 struct all_image_infos_header infos;
6078 infos.version = 1;
6079 infos.imgcount = modules_count;
6080 infos.entries_size = sizeof(image_entry);
6081 infos.entries_fileoff = initial_file_offset + sizeof(all_image_infos_header);
6082 infos.unused = 0;
6083
6084 all_image_infos_payload.PutHex32(infos.version);
6085 all_image_infos_payload.PutHex32(infos.imgcount);
6086 all_image_infos_payload.PutHex64(infos.entries_fileoff);
6087 all_image_infos_payload.PutHex32(infos.entries_size);
6088 all_image_infos_payload.PutHex32(infos.unused);
6089
6090 // First create the structures for all of the segment name+vmaddr vectors
6091 // for each module, so we will know the size of them as we add the
6092 // module entries.
6093 std::vector<std::vector<segment_vmaddr>> modules_segment_vmaddrs;
6094 for (size_t i = 0; i < modules_count; i++) {
6095 ModuleSP module = modules.GetModuleAtIndex(i);
6096
6097 SectionList *sections = module->GetSectionList();
6098 size_t sections_count = sections->GetSize();
6099 std::vector<segment_vmaddr> segment_vmaddrs;
6100 for (size_t j = 0; j < sections_count; j++) {
6101 SectionSP section = sections->GetSectionAtIndex(j);
6102 if (!section->GetParent().get()) {
6103 addr_t vmaddr = section->GetLoadBaseAddress(&target);
6104 if (vmaddr == LLDB_INVALID_ADDRESS)
6105 continue;
6106 llvm::StringRef name = section->GetName();
6107 segment_vmaddr seg_vmaddr;
6108 // This is the uncommon case where strncpy is exactly
6109 // the right one, doesn't need to be nul terminated.
6110 // The segment name in a Mach-O LC_SEGMENT/LC_SEGMENT_64 is char[16] and
6111 // is not guaranteed to be nul-terminated if all 16 characters are
6112 // used.
6113 // coverity[buffer_size_warning]
6114 strncpy(seg_vmaddr.segname, name.data(),
6115 std::min(name.size(), sizeof(seg_vmaddr.segname)));
6116 seg_vmaddr.vmaddr = vmaddr;
6117 seg_vmaddr.unused = 0;
6118 segment_vmaddrs.push_back(seg_vmaddr);
6119 }
6120 }
6121 modules_segment_vmaddrs.push_back(segment_vmaddrs);
6122 }
6123
6124 offset_t size_of_vmaddr_structs = 0;
6125 for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6126 size_of_vmaddr_structs +=
6127 modules_segment_vmaddrs[i].size() * sizeof(segment_vmaddr);
6128 }
6129
6130 offset_t size_of_filepath_cstrings = 0;
6131 for (size_t i = 0; i < modules_count; i++) {
6132 ModuleSP module_sp = modules.GetModuleAtIndex(i);
6133 size_of_filepath_cstrings += module_sp->GetFileSpec().GetPath().size() + 1;
6134 }
6135
6136 // Calculate the file offsets of our "all image infos" payload in the
6137 // corefile. initial_file_offset the original value passed in to this method.
6138
6139 offset_t start_of_entries =
6140 initial_file_offset + sizeof(all_image_infos_header);
6141 offset_t start_of_seg_vmaddrs =
6142 start_of_entries + sizeof(image_entry) * modules_count;
6143 offset_t start_of_filenames = start_of_seg_vmaddrs + size_of_vmaddr_structs;
6144
6145 offset_t final_file_offset = start_of_filenames + size_of_filepath_cstrings;
6146
6147 // Now write the one-per-module 'struct image_entry' into the
6148 // StringStream; keep track of where the struct segment_vmaddr
6149 // entries for each module will end up in the corefile.
6150
6151 offset_t current_string_offset = start_of_filenames;
6152 offset_t current_segaddrs_offset = start_of_seg_vmaddrs;
6153 for (size_t i = 0; i < modules_count; i++) {
6154 ModuleSP module_sp = modules.GetModuleAtIndex(i);
6155
6156 struct image_entry ent;
6157 memcpy(&ent.uuid, module_sp->GetUUID().GetBytes().data(), sizeof(ent.uuid));
6158 if (modules_segment_vmaddrs[i].size() > 0) {
6159 ent.segment_count = modules_segment_vmaddrs[i].size();
6160 ent.seg_addrs_offset = current_segaddrs_offset;
6161 }
6162 ent.filepath_offset = current_string_offset;
6163 ObjectFile *objfile = module_sp->GetObjectFile();
6164 if (objfile) {
6165 Address base_addr(objfile->GetBaseAddress());
6166 if (base_addr.IsValid()) {
6167 ent.load_address = base_addr.GetLoadAddress(&target);
6168 }
6169 }
6170
6171 all_image_infos_payload.PutHex64(ent.filepath_offset);
6172 all_image_infos_payload.PutRawBytes(ent.uuid, sizeof(ent.uuid));
6173 all_image_infos_payload.PutHex64(ent.load_address);
6174 all_image_infos_payload.PutHex64(ent.seg_addrs_offset);
6175 all_image_infos_payload.PutHex32(ent.segment_count);
6176
6177 if (executing_uuids.find(module_sp->GetUUID().GetAsString()) !=
6178 executing_uuids.end())
6179 all_image_infos_payload.PutHex32(1);
6180 else
6181 all_image_infos_payload.PutHex32(0);
6182
6183 current_segaddrs_offset += ent.segment_count * sizeof(segment_vmaddr);
6184 current_string_offset += module_sp->GetFileSpec().GetPath().size() + 1;
6185 }
6186
6187 // Now write the struct segment_vmaddr entries into the StringStream.
6188
6189 for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6190 if (modules_segment_vmaddrs[i].size() == 0)
6191 continue;
6192 for (struct segment_vmaddr segvm : modules_segment_vmaddrs[i]) {
6193 all_image_infos_payload.PutRawBytes(segvm.segname, sizeof(segvm.segname));
6194 all_image_infos_payload.PutHex64(segvm.vmaddr);
6195 all_image_infos_payload.PutHex64(segvm.unused);
6196 }
6197 }
6198
6199 for (size_t i = 0; i < modules_count; i++) {
6200 ModuleSP module_sp = modules.GetModuleAtIndex(i);
6201 std::string filepath = module_sp->GetFileSpec().GetPath();
6202 all_image_infos_payload.PutRawBytes(filepath.data(), filepath.size() + 1);
6203 }
6204
6205 return final_file_offset;
6206}
6207
6208// Temp struct used to combine contiguous memory regions with
6209// identical permissions.
6215
6218 Status &error) {
6219 // The FileSpec and Process are already checked in PluginManager::SaveCore.
6220 assert(options.GetOutputFile().has_value());
6221 assert(process_sp);
6222 const FileSpec outfile = options.GetOutputFile().value();
6223
6224 // MachO defaults to dirty pages
6227
6228 Target &target = process_sp->GetTarget();
6229 const ArchSpec target_arch = target.GetArchitecture();
6230 const llvm::Triple &target_triple = target_arch.GetTriple();
6231 if (target_triple.getVendor() == llvm::Triple::Apple &&
6232 (target_triple.getOS() == llvm::Triple::MacOSX ||
6233 target_triple.getOS() == llvm::Triple::IOS ||
6234 target_triple.getOS() == llvm::Triple::WatchOS ||
6235 target_triple.getOS() == llvm::Triple::TvOS ||
6236 target_triple.getOS() == llvm::Triple::BridgeOS ||
6237 target_triple.getOS() == llvm::Triple::XROS)) {
6238 bool make_core = false;
6239 switch (target_arch.GetMachine()) {
6240 case llvm::Triple::aarch64:
6241 case llvm::Triple::aarch64_32:
6242 case llvm::Triple::arm:
6243 case llvm::Triple::thumb:
6244 case llvm::Triple::x86:
6245 case llvm::Triple::x86_64:
6246 make_core = true;
6247 break;
6248 default:
6250 "unsupported core architecture: %s", target_triple.str().c_str());
6251 break;
6252 }
6253
6254 if (make_core) {
6255 CoreFileMemoryRanges core_ranges;
6256 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6257 if (error.Success()) {
6258 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
6259 const ByteOrder byte_order = target_arch.GetByteOrder();
6260 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6261 for (const auto &core_range_info : core_ranges) {
6262 // TODO: Refactor RangeDataVector to have a data iterator.
6263 const auto &core_range = core_range_info.data;
6264 uint32_t cmd_type = LC_SEGMENT_64;
6265 uint32_t segment_size = sizeof(llvm::MachO::segment_command_64);
6266 if (addr_byte_size == 4) {
6267 cmd_type = LC_SEGMENT;
6268 segment_size = sizeof(llvm::MachO::segment_command);
6269 }
6270 // Skip any ranges with no read/write/execute permissions and empty
6271 // ranges.
6272 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6273 continue;
6274 uint32_t vm_prot = 0;
6275 if (core_range.lldb_permissions & ePermissionsReadable)
6276 vm_prot |= VM_PROT_READ;
6277 if (core_range.lldb_permissions & ePermissionsWritable)
6278 vm_prot |= VM_PROT_WRITE;
6279 if (core_range.lldb_permissions & ePermissionsExecutable)
6280 vm_prot |= VM_PROT_EXECUTE;
6281 const addr_t vm_addr = core_range.range.start();
6282 const addr_t vm_size = core_range.range.size();
6283 llvm::MachO::segment_command_64 segment = {
6284 cmd_type, // uint32_t cmd;
6285 segment_size, // uint32_t cmdsize;
6286 {0}, // char segname[16];
6287 vm_addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
6288 vm_size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
6289 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
6290 vm_size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
6291 vm_prot, // uint32_t maxprot;
6292 vm_prot, // uint32_t initprot;
6293 0, // uint32_t nsects;
6294 0}; // uint32_t flags;
6295 segment_load_commands.push_back(segment);
6296 }
6297
6298 StreamString buffer(Stream::eBinary, byte_order);
6299
6300 llvm::MachO::mach_header_64 mach_header;
6301 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6302 mach_header.cputype = target_arch.GetMachOCPUType();
6303 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
6304 mach_header.filetype = MH_CORE;
6305 mach_header.ncmds = segment_load_commands.size();
6306 mach_header.flags = 0;
6307 mach_header.reserved = 0;
6308 ThreadList &thread_list = process_sp->GetThreadList();
6309 const uint32_t num_threads = thread_list.GetSize();
6310
6311 // Make an array of LC_THREAD data items. Each one contains the
6312 // contents of the LC_THREAD load command. The data doesn't contain
6313 // the load command + load command size, we will add the load command
6314 // and load command size as we emit the data.
6315 std::vector<StreamString> LC_THREAD_datas(num_threads);
6316 for (auto &LC_THREAD_data : LC_THREAD_datas) {
6317 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
6318 LC_THREAD_data.SetByteOrder(byte_order);
6319 }
6320 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6321 ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
6322 if (thread_sp) {
6323 switch (mach_header.cputype) {
6324 case llvm::MachO::CPU_TYPE_ARM64:
6325 case llvm::MachO::CPU_TYPE_ARM64_32:
6327 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6328 break;
6329
6330 case llvm::MachO::CPU_TYPE_ARM:
6332 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6333 break;
6334
6335 case llvm::MachO::CPU_TYPE_X86_64:
6337 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6338 break;
6339
6340 case llvm::MachO::CPU_TYPE_RISCV:
6342 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6343 break;
6344 }
6345 }
6346 }
6347
6348 // The size of the load command is the size of the segments...
6349 if (addr_byte_size == 8) {
6350 mach_header.sizeofcmds = segment_load_commands.size() *
6351 sizeof(llvm::MachO::segment_command_64);
6352 } else {
6353 mach_header.sizeofcmds = segment_load_commands.size() *
6354 sizeof(llvm::MachO::segment_command);
6355 }
6356
6357 // and the size of all LC_THREAD load command
6358 for (const auto &LC_THREAD_data : LC_THREAD_datas) {
6359 ++mach_header.ncmds;
6360 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6361 }
6362
6363 // Bits will be set to indicate which bits are NOT used in
6364 // addressing in this process or 0 for unknown.
6365 uint64_t address_mask = process_sp->GetCodeAddressMask();
6366 if (address_mask != LLDB_INVALID_ADDRESS_MASK) {
6367 // LC_NOTE "addrable bits"
6368 mach_header.ncmds++;
6369 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
6370 }
6371
6372 // LC_NOTE "process metadata"
6373 mach_header.ncmds++;
6374 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
6375
6376 // LC_NOTE "all image infos"
6377 mach_header.ncmds++;
6378 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
6379
6380 // Write the mach header
6381 buffer.PutHex32(mach_header.magic);
6382 buffer.PutHex32(mach_header.cputype);
6383 buffer.PutHex32(mach_header.cpusubtype);
6384 buffer.PutHex32(mach_header.filetype);
6385 buffer.PutHex32(mach_header.ncmds);
6386 buffer.PutHex32(mach_header.sizeofcmds);
6387 buffer.PutHex32(mach_header.flags);
6388 if (addr_byte_size == 8) {
6389 buffer.PutHex32(mach_header.reserved);
6390 }
6391
6392 // Skip the mach header and all load commands and align to the next
6393 // 0x1000 byte boundary
6394 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
6395
6396 file_offset = llvm::alignTo(file_offset, 16);
6397 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6398
6399 // Add "addrable bits" LC_NOTE when an address mask is available
6400 if (address_mask != LLDB_INVALID_ADDRESS_MASK) {
6401 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6402 new LCNoteEntry(byte_order));
6403 addrable_bits_lcnote_up->name = "addrable bits";
6404 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6405 int bits = std::bitset<64>(~address_mask).count();
6406 addrable_bits_lcnote_up->payload.PutHex32(4); // version
6407 addrable_bits_lcnote_up->payload.PutHex32(
6408 bits); // # of bits used for low addresses
6409 addrable_bits_lcnote_up->payload.PutHex32(
6410 bits); // # of bits used for high addresses
6411 addrable_bits_lcnote_up->payload.PutHex32(0); // reserved
6412
6413 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6414
6415 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6416 }
6417
6418 // Add "process metadata" LC_NOTE
6419 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6420 new LCNoteEntry(byte_order));
6421 thread_extrainfo_lcnote_up->name = "process metadata";
6422 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6423
6425 std::make_shared<StructuredData::Dictionary>());
6427 std::make_shared<StructuredData::Array>());
6428 for (const ThreadSP &thread_sp :
6429 process_sp->CalculateCoreFileThreadList(options)) {
6431 std::make_shared<StructuredData::Dictionary>());
6432 thread->AddIntegerItem("thread_id", thread_sp->GetID());
6433 threads->AddItem(thread);
6434 }
6435 dict->AddItem("threads", threads);
6436 StreamString strm;
6437 dict->Dump(strm, /* pretty */ false);
6438 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.GetData(),
6439 strm.GetSize());
6440
6441 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6442 file_offset = llvm::alignTo(file_offset, 16);
6443 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6444
6445 // Add "all image infos" LC_NOTE
6446 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6447 new LCNoteEntry(byte_order));
6448 all_image_infos_lcnote_up->name = "all image infos";
6449 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6450 file_offset = CreateAllImageInfosPayload(
6451 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6452 options);
6453 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6454
6455 // Add LC_NOTE load commands
6456 for (auto &lcnote : lc_notes) {
6457 // Add the LC_NOTE load command to the file.
6458 buffer.PutHex32(LC_NOTE);
6459 buffer.PutHex32(sizeof(llvm::MachO::note_command));
6460 char namebuf[16];
6461 memset(namebuf, 0, sizeof(namebuf));
6462 // This is the uncommon case where strncpy is exactly
6463 // the right one, doesn't need to be nul terminated.
6464 // LC_NOTE name field is char[16] and is not guaranteed to be
6465 // nul-terminated.
6466 // coverity[buffer_size_warning]
6467 strncpy(namebuf, lcnote->name.c_str(), sizeof(namebuf));
6468 buffer.PutRawBytes(namebuf, sizeof(namebuf));
6469 buffer.PutHex64(lcnote->payload_file_offset);
6470 buffer.PutHex64(lcnote->payload.GetSize());
6471 }
6472
6473 // Align to 4096-byte page boundary for the LC_SEGMENTs.
6474 file_offset = llvm::alignTo(file_offset, 4096);
6475
6476 for (auto &segment : segment_load_commands) {
6477 segment.fileoff = file_offset;
6478 file_offset += segment.filesize;
6479 }
6480
6481 // Write out all of the LC_THREAD load commands
6482 for (const auto &LC_THREAD_data : LC_THREAD_datas) {
6483 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6484 buffer.PutHex32(LC_THREAD);
6485 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
6486 buffer.Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6487 }
6488
6489 // Write out all of the segment load commands
6490 for (const auto &segment : segment_load_commands) {
6491 buffer.PutHex32(segment.cmd);
6492 buffer.PutHex32(segment.cmdsize);
6493 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
6494 if (addr_byte_size == 8) {
6495 buffer.PutHex64(segment.vmaddr);
6496 buffer.PutHex64(segment.vmsize);
6497 buffer.PutHex64(segment.fileoff);
6498 buffer.PutHex64(segment.filesize);
6499 } else {
6500 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
6501 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
6502 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
6503 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
6504 }
6505 buffer.PutHex32(segment.maxprot);
6506 buffer.PutHex32(segment.initprot);
6507 buffer.PutHex32(segment.nsects);
6508 buffer.PutHex32(segment.flags);
6509 }
6510
6511 std::string core_file_path(outfile.GetPath());
6512 auto core_file = FileSystem::Instance().Open(
6515 if (!core_file) {
6516 error = Status::FromError(core_file.takeError());
6517 } else {
6518 // Read 1 page at a time
6519 uint8_t bytes[0x1000];
6520 // Write the mach header and load commands out to the core file
6521 size_t bytes_written = buffer.GetString().size();
6522 error =
6523 core_file.get()->Write(buffer.GetString().data(), bytes_written);
6524 if (error.Success()) {
6525
6526 for (auto &lcnote : lc_notes) {
6527 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6528 -1) {
6530 "Unable to seek to corefile pos "
6531 "to write '%s' LC_NOTE payload",
6532 lcnote->name.c_str());
6533 return false;
6534 }
6535 bytes_written = lcnote->payload.GetSize();
6536 error = core_file.get()->Write(lcnote->payload.GetData(),
6537 bytes_written);
6538 if (!error.Success())
6539 return false;
6540 }
6541
6542 // Now write the file data for all memory segments in the process
6543 for (const auto &segment : segment_load_commands) {
6544 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6546 "unable to seek to offset 0x%" PRIx64 " in '%s'",
6547 segment.fileoff, core_file_path.c_str());
6548 break;
6549 }
6550
6551 target.GetDebugger().GetAsyncOutputStream()->Printf(
6552 "Saving %" PRId64
6553 " bytes of data for memory region at 0x%" PRIx64 "\n",
6555 addr_t bytes_left = segment.vmsize;
6556 addr_t addr = segment.vmaddr;
6558 while (bytes_left > 0 && error.Success()) {
6559 const size_t bytes_to_read =
6560 bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
6561
6562 // In a savecore setting, we don't really care about caching,
6563 // as the data is dumped and very likely never read again,
6564 // so we call ReadMemoryFromInferior to bypass it.
6565 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6566 addr, bytes, bytes_to_read, memory_read_error);
6567
6568 if (bytes_read == bytes_to_read) {
6569 size_t bytes_written = bytes_read;
6570 error = core_file.get()->Write(bytes, bytes_written);
6571 bytes_left -= bytes_read;
6572 addr += bytes_read;
6573 } else {
6574 // Some pages within regions are not readable, those should
6575 // be zero filled
6576 memset(bytes, 0, bytes_to_read);
6577 size_t bytes_written = bytes_to_read;
6578 error = core_file.get()->Write(bytes, bytes_written);
6579 bytes_left -= bytes_to_read;
6580 addr += bytes_to_read;
6581 }
6582 }
6583 }
6584 }
6585 }
6586 }
6587 }
6588 return true; // This is the right plug to handle saving core files for
6589 // this process
6590 }
6591 return false;
6592}
6593
6596 MachOCorefileAllImageInfos image_infos;
6599
6600 auto lc_notes = FindLC_NOTEByName("all image infos");
6601 for (auto lc_note : lc_notes) {
6602 offset_t payload_offset = std::get<0>(lc_note);
6603 // Read the struct all_image_infos_header.
6604 uint32_t version = m_data_nsp->GetU32(&payload_offset);
6605 if (version != 1) {
6606 return image_infos;
6607 }
6608 uint32_t imgcount = m_data_nsp->GetU32(&payload_offset);
6609 uint64_t entries_fileoff = m_data_nsp->GetU64(&payload_offset);
6610 // 'entries_size' is not used, nor is the 'unused' entry.
6611 // offset += 4; // uint32_t entries_size;
6612 // offset += 4; // uint32_t unused;
6613
6614 LLDB_LOGF(log, "LC_NOTE 'all image infos' found version %d with %d images",
6615 version, imgcount);
6616 payload_offset = entries_fileoff;
6617 for (uint32_t i = 0; i < imgcount; i++) {
6618 // Read the struct image_entry.
6619 offset_t filepath_offset = m_data_nsp->GetU64(&payload_offset);
6620 uuid_t uuid;
6621 memcpy(&uuid, m_data_nsp->GetData(&payload_offset, sizeof(uuid_t)),
6622 sizeof(uuid_t));
6623 uint64_t load_address = m_data_nsp->GetU64(&payload_offset);
6624 offset_t seg_addrs_offset = m_data_nsp->GetU64(&payload_offset);
6625 uint32_t segment_count = m_data_nsp->GetU32(&payload_offset);
6626 uint32_t currently_executing = m_data_nsp->GetU32(&payload_offset);
6627
6629 image_entry.filename =
6630 (const char *)m_data_nsp->GetCStr(&filepath_offset);
6631 image_entry.uuid = UUID(uuid, sizeof(uuid_t));
6632 image_entry.load_address = load_address;
6633 image_entry.currently_executing = currently_executing;
6634
6635 offset_t seg_vmaddrs_offset = seg_addrs_offset;
6636 for (uint32_t j = 0; j < segment_count; j++) {
6637 char segname[17];
6638 m_data_nsp->CopyData(seg_vmaddrs_offset, 16, segname);
6639 segname[16] = '\0';
6640 seg_vmaddrs_offset += 16;
6641 uint64_t vmaddr = m_data_nsp->GetU64(&seg_vmaddrs_offset);
6642 seg_vmaddrs_offset += 8; /* unused */
6643
6644 std::tuple<ConstString, addr_t> new_seg{ConstString(segname), vmaddr};
6645 image_entry.segment_load_addresses.push_back(new_seg);
6646 }
6647 LLDB_LOGF(log, " image entry: %s %s 0x%" PRIx64 " %s",
6648 image_entry.filename.c_str(),
6649 image_entry.uuid.GetAsString().c_str(),
6651 image_entry.currently_executing ? "currently executing"
6652 : "not currently executing");
6653 image_infos.all_image_infos.push_back(image_entry);
6654 }
6655 }
6656
6657 lc_notes = FindLC_NOTEByName("load binary");
6658 for (auto lc_note : lc_notes) {
6659 offset_t payload_offset = std::get<0>(lc_note);
6660 uint32_t version = m_data_nsp->GetU32(&payload_offset);
6661 if (version == 1) {
6662 uuid_t uuid;
6663 memcpy(&uuid, m_data_nsp->GetData(&payload_offset, sizeof(uuid_t)),
6664 sizeof(uuid_t));
6665 uint64_t load_address = m_data_nsp->GetU64(&payload_offset);
6666 uint64_t slide = m_data_nsp->GetU64(&payload_offset);
6667 std::string filename = m_data_nsp->GetCStr(&payload_offset);
6668
6670 image_entry.filename = filename;
6671 image_entry.uuid = UUID(uuid, sizeof(uuid_t));
6672 image_entry.load_address = load_address;
6673 image_entry.slide = slide;
6674 image_entry.currently_executing = true;
6675 image_infos.all_image_infos.push_back(image_entry);
6676 LLDB_LOGF(log,
6677 "LC_NOTE 'load binary' found, filename %s uuid %s load "
6678 "address 0x%" PRIx64 " slide 0x%" PRIx64,
6679 filename.c_str(),
6680 image_entry.uuid.IsValid()
6681 ? image_entry.uuid.GetAsString().c_str()
6682 : "00000000-0000-0000-0000-000000000000",
6683 load_address, slide);
6684 }
6685 }
6686
6687 return image_infos;
6688}
6689
6693
6694 bool found_platform_binary = false;
6695 ModuleList added_modules;
6696
6697 llvm::SmallVector<const MachOCorefileImageEntry *> pending_images;
6698 std::vector<DynamicLoader::BinarySpec> pending_specs;
6699
6700 for (MachOCorefileImageEntry &image : image_infos.all_image_infos) {
6701 // If this is a platform binary, it has been loaded (or registered with
6702 // the DynamicLoader to be loaded), we don't need to do any further
6703 // processing. We're not going to call ModulesDidLoad on this in this
6704 // method, so notify==true.
6705 //
6706 // Setting up a platform binary can replace the Target's platform and
6707 // dynamic loader, so no image is searched for until this loop has run to
6708 // the end.
6709 if (process.GetTarget()
6710 .GetDebugger()
6713 true /* notify */)) {
6714 LLDB_LOGF(log,
6715 "ObjectFileMachO::%s binary at 0x%" PRIx64
6716 " is a platform binary, has been handled by a Platform plugin.",
6717 __FUNCTION__, image.load_address);
6718 found_platform_binary = true;
6719 continue;
6720 }
6721
6722 bool value_is_offset = image.load_address == LLDB_INVALID_ADDRESS;
6723 uint64_t value = value_is_offset ? image.slide : image.load_address;
6724 if (value_is_offset && value == LLDB_INVALID_ADDRESS) {
6725 // We have neither address nor slide; so we will find the binary
6726 // by UUID and load it at slide/offset 0.
6727 value = 0;
6728 }
6729
6730 // We have either a UUID, or we have a load address which
6731 // and can try to read load commands and find a UUID.
6732 if (!image.uuid.IsValid() &&
6733 (value_is_offset || value == LLDB_INVALID_ADDRESS))
6734 continue;
6735
6737 bin_spec.name = image.filename;
6738 bin_spec.uuid = image.uuid;
6739 bin_spec.value = value;
6740 bin_spec.value_is_offset = value_is_offset;
6742 bin_spec.notify = false;
6743 // Userland Darwin binaries will have segment load addresses via
6744 // the `all image infos` LC_NOTE.
6745 bin_spec.set_address_in_target = image.segment_load_addresses.empty();
6747 !image.segment_load_addresses.empty();
6748
6749 pending_images.push_back(&image);
6750 pending_specs.push_back(std::move(bin_spec));
6751 }
6752
6753 DynamicLoader::LocateBinaries(&process, pending_specs);
6754
6755 for (auto [image, bin_spec] :
6756 llvm::zip_equal(pending_images, pending_specs)) {
6757 ModuleSP module_sp;
6758 if (llvm::Expected<ModuleSP> loaded =
6759 DynamicLoader::LoadBinaryInTarget(&process, bin_spec)) {
6760 module_sp = *loaded;
6761 } else if (bin_spec.force_symbol_search) {
6763 << llvm::toString(loaded.takeError()) << "\n";
6764 } else {
6765 // A corefile image that isn't on this machine is routine, and has
6766 // already been logged.
6767 llvm::consumeError(loaded.takeError());
6768 }
6769
6770 if (!module_sp)
6771 continue;
6772
6773 added_modules.Append(module_sp, false /* notify */);
6774
6775 // We have a list of segment load address
6776 if (image->segment_load_addresses.size() > 0) {
6777 if (log) {
6778 std::string uuidstr = image->uuid.GetAsString();
6779 log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
6780 "UUID %s with section load addresses",
6781 module_sp->GetFileSpec().GetPath().c_str(),
6782 uuidstr.c_str());
6783 }
6784 ObjectFile *objfile = module_sp->GetObjectFile();
6785 SectionList *sectlist = objfile ? objfile->GetSectionList() : nullptr;
6786 for (auto name_vmaddr_tuple : image->segment_load_addresses) {
6787 if (sectlist) {
6788 SectionSP sect_sp =
6789 sectlist->FindSectionByName(std::get<0>(name_vmaddr_tuple));
6790 if (sect_sp) {
6792 sect_sp, std::get<1>(name_vmaddr_tuple));
6793 }
6794 }
6795 }
6796 } else {
6797 if (log) {
6798 std::string uuidstr = image->uuid.GetAsString();
6799 log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
6800 "UUID %s with %s 0x%" PRIx64,
6801 module_sp->GetFileSpec().GetPath().c_str(), uuidstr.c_str(),
6802 bin_spec.value_is_offset ? "slide" : "load address",
6803 bin_spec.value);
6804 }
6805 bool changed;
6806 module_sp->SetLoadAddress(process.GetTarget(), bin_spec.value,
6807 bin_spec.value_is_offset, changed);
6808 }
6809 }
6810
6811 if (added_modules.GetSize() > 0) {
6812 process.GetTarget().ModulesDidLoad(added_modules);
6813 process.Flush();
6814 return true;
6815 }
6816 // Return true if the only binary we found was the platform binary,
6817 // and it was loaded outside the scope of this method.
6818 if (found_platform_binary)
6819 return true;
6820
6821 // No binaries.
6822 return false;
6823}
unsigned char uuid_t[16]
static llvm::raw_ostream & error(Stream &strm)
void dyld_shared_cache_copy_uuid(dyld_shared_cache_t cache, uuid_t *uuid)
struct dyld_image_s * dyld_image_t
struct dyld_shared_cache_s * dyld_shared_cache_t
bool dyld_image_copy_uuid(dyld_image_t cache, uuid_t *uuid)
void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache, void(^block)(dyld_image_t image))
static const char * memory_read_error
#define lldbassert(x)
Definition LLDBAssert.h:16
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_LOGF(log,...)
Definition Log.h:389
static bool ReadMachOCommand(DataExtractor &data, lldb::offset_t &offset, T &cmd)
Read a Mach-O load-command header (cmd + cmdsize) from data at offset into cmd, advancing offset by 8...
static uint32_t MachHeaderSizeFromMagic(uint32_t magic)
static uint32_t GetSegmentPermissions(const llvm::MachO::segment_command_64 &seg_cmd)
static constexpr llvm::StringLiteral g_loader_path
static std::optional< struct nlist_64 > ParseNList(DataExtractor &nlist_data, lldb::offset_t &nlist_data_offset, size_t nlist_byte_size)
static bool ReadMachOCommand(const DataExtractor &data, lldb::offset_t &offset, T &cmd)
Read a Mach-O load-command header (cmd + cmdsize) from data at offset into cmd, advancing offset by 8...
static constexpr llvm::StringLiteral g_executable_path
static void PrintRegisterValue(RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
static lldb::SectionType GetSectionType(uint32_t flags, llvm::StringRef section_name)
static llvm::StringRef GetOSName(uint32_t cmd)
static llvm::VersionTuple FindMinimumVersionInfo(DataExtractor &data, lldb::offset_t offset, size_t ncmds)
unsigned int mach_task_self()
#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB
@ NonDebugSymbols
@ DebugSymbols
void * dyld_process_info
static uint32_t MachHeaderSizeFromMagic(uint32_t magic)
static offset_t CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp, offset_t initial_file_offset, StreamString &all_image_infos_payload, lldb_private::SaveCoreOptions &options)
static bool TryParseV2ObjCMetadataSymbol(const char *&symbol_name, const char *&symbol_name_non_abi_mangled, SymbolType &type)
static SymbolType GetSymbolType(const char *&symbol_name, bool &demangled_is_synthesized, const SectionSP &text_section_sp, const SectionSP &data_section_sp, const SectionSP &data_dirty_section_sp, const SectionSP &data_const_section_sp, const SectionSP &symbol_section)
#define LLDB_PLUGIN_DEFINE(PluginName)
#define KERN_SUCCESS
Constants returned by various RegisterContextDarwin_*** functions.
#define LLDB_SCOPED_TIMERF(...)
Definition Timer.h:86
static llvm::StringRef GetName(XcodeSDK::Type type)
Definition XcodeSDK.cpp:21
std::vector< SectionInfo > m_section_infos
SectionSP GetSection(uint8_t n_sect, addr_t file_addr)
MachSymtabSectionInfo(SectionList *section_list)
bool SectionIsLoadable(const lldb_private::Section *section)
llvm::MachO::mach_header m_header
bool m_allow_assembly_emulation_unwind_plans
std::optional< llvm::VersionTuple > m_min_os_version
lldb_private::AddressableBits GetAddressableBits() override
Some object files may have the number of bits used for addressing embedded in them,...
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override
Extract the dependent modules from an object file.
static lldb_private::ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
FileRangeArray m_thread_context_offsets
ObjectFile::Type CalculateType() override
The object file should be able to calculate its type by looking at its file header and possibly the s...
lldb_private::RangeVector< uint32_t, uint32_t, 8 > EncryptedFileRanges
static bool MagicBytesMatch(lldb::DataExtractorSP extractor_sp, lldb::addr_t offset, lldb::addr_t length)
std::vector< std::tuple< lldb::offset_t, lldb::offset_t > > FindLC_NOTEByName(std::string name)
void Dump(lldb_private::Stream *s) override
Dump a description of this object to a Stream.
bool AllowAssemblyEmulationUnwindPlans() override
Returns if the function bounds for symbols in this symbol file are likely accurate.
std::string GetIdentifierString() override
Some object files may have an identifier string embedded in them, e.g.
void ProcessSegmentCommand(const llvm::MachO::load_command &load_cmd, lldb::offset_t offset, uint32_t cmd_idx, SegmentParsingContext &context)
std::vector< llvm::MachO::section_64 > m_mach_sections
static llvm::StringRef GetSegmentNameLINKEDIT()
bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override
Sets the load address for an entire module, assuming a rigid slide of sections, if possible in the im...
void GetProcessSharedCacheUUID(lldb_private::Process *, lldb::addr_t &base_addr, lldb_private::UUID &uuid)
Intended for same-host arm device debugging where lldb needs to detect libraries in the shared cache ...
bool IsGOTSection(const lldb_private::Section &section) const override
Returns true if the section is a global offset table section.
bool GetIsDynamicLinkEditor() override
Return true if this file is a dynamic link editor (dyld)
lldb::ByteOrder GetByteOrder() const override
Gets whether endian swapping should occur when extracting data from this object file.
bool ParseHeader() override
Attempts to parse the object header.
bool IsStripped() override
Detect if this object file has been stripped of local symbols.
lldb_private::UUID GetUUID() override
Gets the UUID for this object file.
llvm::VersionTuple GetMinimumOSVersion() override
Get the minimum OS version this object file can run on.
static llvm::StringRef GetPluginDescriptionStatic()
static llvm::StringRef GetPluginNameStatic()
lldb::RegisterContextSP GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override
lldb_private::FileSpecList m_reexported_dylibs
static void GetAllArchSpecs(const llvm::MachO::mach_header &header, const lldb_private::DataExtractor &data, lldb::offset_t lc_offset, lldb_private::ModuleSpec &base_spec, lldb_private::ModuleSpecList &all_specs)
Enumerate all ArchSpecs supported by this Mach-O file.
bool GetCorefileThreadExtraInfos(std::vector< lldb::tid_t > &tids) override
Get metadata about thread ids from the corefile.
static llvm::StringRef GetSectionNameEHFrame()
bool IsDynamicLoader() const
static void Terminate()
bool IsExecutable() const override
Tells whether this object file is capable of being the main executable for a process.
lldb_private::Address GetEntryPointAddress() override
Returns the address of the Entry Point in this object file - if the object file doesn't have an entry...
lldb_private::Address m_entry_point_address
static void Initialize()
bool LoadCoreFileImages(lldb_private::Process &process) override
Load binaries listed in a corefile.
bool CanTrustAddressRanges() override
Can we trust the address ranges accelerator associated with this object file to be complete.
void SanitizeSegmentCommand(llvm::MachO::segment_command_64 &seg_cmd, uint32_t cmd_idx)
static lldb_private::ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
bool IsSharedCacheBinary() const
llvm::VersionTuple GetSDKVersion() override
Get the SDK OS version this object file was built with.
lldb_private::ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
lldb_private::Address GetBaseAddress() override
Returns base address of this object file.
size_t ParseSymtab()
static llvm::StringRef GetSectionNameLLDBNoNlist()
lldb::addr_t m_text_address
uint32_t GetAddressByteSize() const override
Gets the address size in bytes for the current object file.
static lldb_private::ModuleSpecList GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp, lldb::offset_t file_offset, lldb::offset_t length)
static llvm::StringRef GetSegmentNameDATA()
llvm::MachO::dysymtab_command m_dysymtab
bool GetCorefileMainBinaryInfo(lldb::addr_t &value, bool &value_is_offset, lldb_private::UUID &uuid, ObjectFile::BinaryType &type) override
static llvm::StringRef GetSegmentNameDATA_DIRTY()
static bool SaveCore(const lldb::ProcessSP &process_sp, lldb_private::SaveCoreOptions &options, lldb_private::Status &error)
void ProcessDysymtabCommand(const llvm::MachO::load_command &load_cmd, lldb::offset_t offset)
static llvm::StringRef GetSegmentNameLLVM_COV()
MachOCorefileAllImageInfos GetCorefileAllImageInfos()
Get the list of binary images that were present in the process when the corefile was produced.
lldb::addr_t CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const lldb_private::Section *mach_header_section, const lldb_private::Section *section)
bool m_thread_context_offsets_valid
ObjectFile::Strata CalculateStrata() override
The object file should be able to calculate the strata of the object file.
void CreateSections(lldb_private::SectionList &unified_section_list) override
static llvm::StringRef GetSegmentNameDATA_CONST()
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override
Get the address type given a file address in an object file.
lldb_private::StructuredData::ObjectSP GetCorefileProcessMetadata() override
Get process metadata from the corefile in a StructuredData dictionary.
static llvm::StringRef GetSegmentNameOBJC()
std::optional< llvm::VersionTuple > m_sdk_versions
ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
void GetLLDBSharedCacheUUID(lldb::addr_t &base_addir, lldb_private::UUID &uuid)
Intended for same-host arm device debugging where lldb will read shared cache libraries out of its ow...
llvm::VersionTuple GetVersion() override
Get the object file version numbers.
EncryptedFileRanges GetEncryptedFileRanges()
uint32_t GetNumThreadContexts() override
static llvm::StringRef GetSegmentNameDWARF()
static llvm::StringRef GetSegmentNameTEXT()
lldb::offset_t m_linkedit_original_offset
lldb_private::Section * GetMachHeaderSection()
int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
RegisterContextDarwin_arm64_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
bool SetError(int flavor, uint32_t err_idx, int err)
RegisterContextDarwin_arm64(lldb_private::Thread &thread, uint32_t concrete_frame_idx)
RegisterContextDarwin_arm_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
RegisterContextDarwin_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx)
bool SetError(int flavor, uint32_t err_idx, int err)
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
int DoWriteCSR(lldb::tid_t tid, int flavor, const CSR &csr) override
RegisterContextDarwin_riscv32_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoReadCSR(lldb::tid_t tid, int flavor, CSR &csr) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
RegisterContextDarwin_riscv32(lldb_private::Thread &thread, uint32_t concrete_frame_idx)
bool SetError(int flavor, uint32_t err_idx, int err)
RegisterContextDarwin_x86_64_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
RegisterContextDarwin_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx)
bool SetError(int flavor, uint32_t err_idx, int err)
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:303
lldb::SectionSP GetSection() const
Get const accessor for the section.
Definition Address.h:426
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:283
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:891
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:453
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:545
bool IsAlwaysThumbInstructions() const
Detect whether this architecture uses thumb code exclusively.
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
uint32_t GetMachOCPUSubType() const
Definition ArchSpec.cpp:875
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
Definition ArchSpec.h:597
uint32_t GetMachOCPUType() const
Definition ArchSpec.cpp:871
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:940
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:883
A uniqued constant string class.
Definition ConstString.h:40
const char * GetCString() const
Get the string value as a C string.
const char * AsCString(const char *value_if_empty) const
Get the string value as a C string.
void GetFunctionAddressAndSizeVector(FunctionAddressAndSizeVector &function_info)
RangeVector< lldb::addr_t, uint32_t > FunctionAddressAndSizeVector
An data extractor class.
virtual uint32_t GetU32_unchecked(lldb::offset_t *offset_ptr) const
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
bool ValidOffsetForDataOfSize(lldb::offset_t offset, lldb::offset_t length) const
Test the availability of length bytes of data from offset.
virtual const uint8_t * PeekData(lldb::offset_t offset, lldb::offset_t length) const
Peek at a bytes at offset.
virtual uint64_t GetByteSize() const
Get the number of bytes contained in this object.
uint64_t GetAddress_unchecked(lldb::offset_t *offset_ptr) const
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
virtual uint8_t GetU8_unchecked(lldb::offset_t *offset_ptr) const
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
virtual uint16_t GetU16_unchecked(lldb::offset_t *offset_ptr) const
size_t ExtractBytes(lldb::offset_t offset, lldb::offset_t length, lldb::ByteOrder dst_byte_order, void *dst) const
Extract an arbitrary number of bytes in the specified byte order.
lldb::StreamUP GetAsyncErrorStream()
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
PlatformList & GetPlatformList()
Definition Debugger.h:222
lldb::StreamUP GetAsyncOutputStream()
A plug-in interface definition class for dynamic loaders.
static void LocateBinaries(Process *process, llvm::MutableArrayRef< BinarySpec > bin_specs)
Search for a batch of binaries, without mutating the Target.
virtual bool GetSharedCacheInformation(lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache, LazyBool &private_shared_cache, lldb_private::FileSpec &shared_cache_path, std::optional< uint64_t > &size)
Get information about the shared cache for a process, if possible.
static llvm::Expected< lldb::ModuleSP > LoadBinaryInTarget(Process *process, BinarySpec &bin_spec)
Add a binary that LocateBinaries searched for to the Target, and set its load address.
A file collection class.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
void Append(const FileSpec &file)
Append a FileSpec object to the list.
size_t GetSize() const
Get the number of files in the file list.
bool AppendIfUnique(const FileSpec &file)
Append a FileSpec object if unique.
A file utility class.
Definition FileSpec.h:56
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
Definition FileSpec.cpp:425
void ClearDirectory()
Clear the directory in this object.
Definition FileSpec.cpp:373
llvm::StringRef GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:248
llvm::StringRef GetDirectory() const
Directory string const get accessor.
Definition FileSpec.h:233
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
FileSpec CopyByRemovingLastPathComponent() const
Definition FileSpec.cpp:431
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
void void Printf(const char *format,...) __attribute__((format(printf
Prefer using LLDB_LOGF whenever possible.
Definition Log.cpp:177
A class that handles mangled names.
Definition Mangled.h:34
void SetDemangledName(ConstString name)
Definition Mangled.h:160
ConstString GetDemangledName() const
Demangled name get accessor.
Definition Mangled.cpp:284
void SetMangledName(ConstString name)
Definition Mangled.h:165
void SetValue(ConstString name)
Set the string value in this object.
Definition Mangled.cpp:124
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition Mangled.cpp:369
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A collection class for Module objects.
Definition ModuleList.h:125
void Clear()
Clear the object's state.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
size_t GetSize() const
Gets the size of the module list.
void Append(const ModuleSpec &spec)
Definition ModuleSpec.h:371
ModuleSpec & GetModuleSpecRefAtIndex(size_t i)
Definition ModuleSpec.h:384
void SetObjectSize(uint64_t object_size)
Definition ModuleSpec.h:119
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
void SetObjectOffset(uint64_t object_offset)
Definition ModuleSpec.h:113
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
std::unique_ptr< lldb_private::SectionList > m_sections_up
Definition ObjectFile.h:785
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
std::unique_ptr< lldb_private::Symtab > m_symtab_up
Definition ObjectFile.h:788
const lldb::addr_t m_memory_addr
Set if the object file only exists in memory.
Definition ObjectFile.h:783
static lldb::SectionType GetDWARFSectionTypeFromName(llvm::StringRef name)
Parses the section type from a section name for DWARF sections.
Symtab * GetSymtab(bool can_create=true)
Gets the symbol table for the currently selected architecture (and object for archives).
DataExtractorNSP m_data_nsp
The data for this object file so things can be parsed lazily.
Definition ObjectFile.h:777
static lldb::WritableDataBufferSP ReadMemory(const lldb::ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
@ eTypeExecutable
A normal executable.
Definition ObjectFile.h:55
@ eTypeDebugInfo
An object file that contains only debug information.
Definition ObjectFile.h:57
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
Definition ObjectFile.h:65
@ eTypeObjectFile
An intermediate object file.
Definition ObjectFile.h:61
@ eTypeDynamicLinker
The platform's dynamic linker executable.
Definition ObjectFile.h:59
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
Definition ObjectFile.h:53
@ eTypeSharedLibrary
A shared library that can be used during execution.
Definition ObjectFile.h:63
lldb::addr_t m_file_offset
The offset in bytes into the file, or the address in memory.
Definition ObjectFile.h:772
static lldb::SymbolType GetSymbolTypeFromName(llvm::StringRef name, lldb::SymbolType symbol_type_hint=lldb::eSymbolTypeUndefined)
bool SetModulesArchitecture(const ArchSpec &new_arch)
Sets the architecture for a module.
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition ObjectFile.h:280
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
bool IsInMemory() const
Returns true if the object file exists only in memory.
Definition ObjectFile.h:691
lldb::ProcessWP m_process_wp
Definition ObjectFile.h:781
lldb::addr_t m_length
The length of this object file if it is known (can be zero if length is unknown or can't be determine...
Definition ObjectFile.h:774
BinaryType
If we have a corefile binary hint, this enum specifies the binary type which we can use to select the...
Definition ObjectFile.h:83
@ eBinaryTypeKernel
kernel binary
Definition ObjectFile.h:87
@ eBinaryTypeUser
user process binary, dyld addr
Definition ObjectFile.h:89
@ eBinaryTypeUserAllImageInfos
user process binary, dyld_all_image_infos addr
Definition ObjectFile.h:91
@ eBinaryTypeStandalone
standalone binary / firmware
Definition ObjectFile.h:93
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
Definition ObjectFile.h:468
bool LoadPlatformBinaryAndSetup(Process *process, lldb::addr_t addr, bool notify)
Detect a binary in memory that will determine which Platform and DynamicLoader should be used in this...
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
Definition Process.h:367
void Flush()
Flush all data in the process.
Definition Process.cpp:6217
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
Definition Process.cpp:3164
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1266
A Progress indicator helper class.
Definition Progress.h:60
const Entry * FindEntryThatContains(B addr) const
Definition RangeMap.h:338
const Entry * GetEntryAtIndex(size_t i) const
Definition RangeMap.h:297
void Append(const Entry &entry)
Definition RangeMap.h:179
size_t GetSize() const
Definition RangeMap.h:295
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
const void * GetBytes() const
const std::optional< lldb_private::FileSpec > GetOutputFile() const
lldb::SaveCoreStyle GetStyle() const
void SetStyle(lldb::SaveCoreStyle style)
size_t GetNumSections(uint32_t depth) const
Definition Section.cpp:544
size_t GetSize() const
Definition Section.h: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:5789
void ModulesDidLoad(ModuleList &module_list)
This call may preload module symbols, and may do so in parallel depending on the following target set...
Definition Target.cpp:1941
Debugger & GetDebugger() const
Definition Target.h:1349
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1266
const ArchSpec & GetArchitecture() const
Definition Target.h:1308
bool SetSectionLoadAddress(const lldb::SectionSP &section, lldb::addr_t load_addr, bool warn_multiple=false)
Definition Target.cpp:3506
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
Represents UUID's of various sizes.
Definition UUID.h:27
void Clear()
Definition UUID.h:62
std::string GetAsString(llvm::StringRef separator="-") const
Definition UUID.cpp:54
bool IsValid() const
Definition UUID.h:69
#define UINT64_MAX
#define LLDB_INVALID_ADDRESS_MASK
Address Mask Bits not used for addressing are set to 1 in the mask; all mask bits set is an invalid v...
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
lldb::ByteOrder InlHostByteOrder()
Definition Endian.h:25
A class that represents a running process on the host machine.
constexpr uint64_t THUMB_ADDRESS_BIT_MASK
Mask that clears the low Thumb bit from an ARM function address.
Definition MachOTrie.h:30
bool ParseTrieEntries(DataExtractor &data, const bool is_arm, lldb::addr_t text_seg_base_addr, std::set< lldb::addr_t > &resolver_addresses, std::vector< TrieEntryWithOffset > &reexports, std::vector< TrieEntryWithOffset > &ext_symbols)
Parse the Mach-O export trie (the dyld symbol trie from LC_DYLD_INFO or LC_DYLD_EXPORTS_TRIE) startin...
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
constexpr uint64_t TRIE_SYMBOL_IS_THUMB
Set on TrieEntry::flags for an ARM symbol whose address has the low Thumb bit set; the bit is strippe...
Definition MachOTrie.h:27
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition ARMUtils.h:265
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
uint64_t offset_t
Definition lldb-types.h:86
std::shared_ptr< lldb_private::Process > ProcessSP
SymbolType
Symbol types.
@ eSymbolTypeUndefined
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeReExported
@ eSymbolTypeObjCClass
@ eSymbolTypeObjectFile
@ eSymbolTypeTrampoline
@ eSymbolTypeResolver
@ eSymbolTypeSourceFile
@ eSymbolTypeException
@ eSymbolTypeVariable
@ eSymbolTypeAbsolute
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
@ eSymbolTypeHeaderFile
@ eSymbolTypeCommonBlock
@ eSymbolTypeCompiler
@ eSymbolTypeLineHeader
@ eSymbolTypeObjCIVar
@ eSymbolTypeLineEntry
@ eSymbolTypeScopeBegin
@ eSymbolTypeScopeEnd
ByteOrder
Byte ordering definitions.
uint64_t user_id_t
Definition lldb-types.h:83
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
@ eSectionTypeDWARFDebugStrOffsets
@ eSectionTypeELFDynamicSymbols
Elf SHT_DYNSYM section.
@ eSectionTypeInvalid
@ eSectionTypeDWARFDebugPubNames
@ eSectionTypeDataObjCCFStrings
Objective-C const CFString/NSString objects.
@ eSectionTypeZeroFill
@ eSectionTypeDWARFDebugLocDwo
@ eSectionTypeDWARFDebugFrame
@ eSectionTypeARMextab
@ eSectionTypeContainer
The section contains child sections.
@ eSectionTypeDWARFDebugLocLists
DWARF v5 .debug_loclists.
@ eSectionTypeDWARFDebugTypes
DWARF .debug_types section.
@ eSectionTypeDataSymbolAddress
Address of a symbol in the symbol table.
@ eSectionTypeELFDynamicLinkInfo
Elf SHT_DYNAMIC section.
@ eSectionTypeDWARFDebugMacInfo
@ eSectionTypeAbsoluteAddress
Dummy section for symbols with absolute address.
@ eSectionTypeCompactUnwind
compact unwind section in Mach-O, __TEXT,__unwind_info
@ eSectionTypeELFRelocationEntries
Elf SHT_REL or SHT_REL section.
@ eSectionTypeDWARFAppleNamespaces
@ eSectionTypeLLDBFormatters
@ eSectionTypeDWARFDebugNames
DWARF v5 .debug_names.
@ eSectionTypeDWARFDebugRngLists
DWARF v5 .debug_rnglists.
@ eSectionTypeEHFrame
@ eSectionTypeDWARFDebugStrOffsetsDwo
@ eSectionTypeDWARFDebugMacro
@ eSectionTypeDWARFAppleTypes
@ eSectionTypeWasmGlobal
@ eSectionTypeDWARFDebugInfo
@ eSectionTypeDWARFDebugTypesDwo
@ eSectionTypeDWARFDebugRanges
@ eSectionTypeDWARFDebugRngListsDwo
@ eSectionTypeLLDBTypeSummaries
@ eSectionTypeGoSymtab
@ eSectionTypeARMexidx
@ eSectionTypeDWARFDebugLine
@ eSectionTypeDWARFDebugPubTypes
@ eSectionTypeDataObjCMessageRefs
Pointer to function pointer + selector.
@ eSectionTypeDWARFDebugTuIndex
@ eSectionTypeDWARFDebugStr
@ eSectionTypeDWARFDebugLineStr
DWARF v5 .debug_line_str.
@ eSectionTypeDWARFDebugLoc
@ eSectionTypeDWARFAppleNames
@ eSectionTypeDataCStringPointers
Pointers to C string data.
@ eSectionTypeDWARFAppleObjC
@ eSectionTypeSwiftModules
@ eSectionTypeDWARFDebugCuIndex
@ eSectionTypeDWARFDebugAranges
@ eSectionTypeDWARFDebugAbbrevDwo
@ eSectionTypeDWARFGNUDebugAltLink
@ eSectionTypeDWARFDebugStrDwo
@ eSectionTypeDWARFDebugAbbrev
@ eSectionTypeDataPointers
@ eSectionTypeDWARFDebugLocListsDwo
@ eSectionTypeDWARFDebugInfoDwo
@ eSectionTypeDWARFDebugAddr
@ eSectionTypeWasmName
@ eSectionTypeDataCString
Inlined C string data.
@ eSectionTypeELFSymbolTable
Elf SHT_SYMTAB section.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
uint64_t tid_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Module > ModuleSP
The LC_DYSYMTAB's dysymtab_command has 32-bit file offsets that we will use as virtual address offset...
std::vector< MachOCorefileImageEntry > all_image_infos
A corefile may include metadata about all of the binaries that were present in the process when the c...
std::vector< std::tuple< lldb_private::ConstString, lldb::addr_t > > segment_load_addresses
lldb_private::SectionList & UnifiedList
SegmentParsingContext(EncryptedFileRanges EncryptedRanges, lldb_private::SectionList &UnifiedList)
uint32_t segment_count
uint64_t load_address
uint64_t filepath_offset
image_entry(const image_entry &rhs)
uint32_t unused
uint64_t seg_addrs_offset
uuid_t uuid
image_entry()
A binary to find and load into a Target.
lldb::addr_t value
Address where the binary should be loaded, or read out of memory.
bool allow_memory_image_last_resort
If no better binary image can be found, allow reading the binary out of memory, if possible,...
UUID uuid
UUID of the binary to be loaded.
std::string name
Name of the binary, if available.
bool force_symbol_search
Allow the search to do a possibly expensive external search for the ObjectFile and/or SymbolFile.
bool set_address_in_target
Whether the address of the binary should be set in the Target if it is added.
bool notify
Whether ModulesDidLoad should be called once the binary has been added to the Target.
bool value_is_offset
A flag indicating that value is an address, or an offset to be applied to the file addresses.
BaseType GetRangeBase() const
Definition RangeMap.h:45
SizeType GetByteSize() const
Definition RangeMap.h:87
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
Definition RangeMap.h:48
void SetByteSize(SizeType s)
Definition RangeMap.h:89
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_size
Size in bytes of the register.
segment_vmaddr(const segment_vmaddr &rhs)
size_t vmsize
uint64_t vmaddr