1 //===-- ObjectFileMachO.cpp -----------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/ScopeExit.h"
10 #include "llvm/ADT/StringRef.h"
12 #include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
13 #include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
14 #include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
15 #include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/ModuleSpec.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Core/Progress.h"
21 #include "lldb/Core/Section.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Symbol/DWARFCallFrameInfo.h"
24 #include "lldb/Symbol/LocateSymbolFile.h"
25 #include "lldb/Symbol/ObjectFile.h"
26 #include "lldb/Target/DynamicLoader.h"
27 #include "lldb/Target/MemoryRegionInfo.h"
28 #include "lldb/Target/Platform.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/SectionLoadList.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Target/Thread.h"
33 #include "lldb/Target/ThreadList.h"
34 #include "lldb/Utility/ArchSpec.h"
35 #include "lldb/Utility/DataBuffer.h"
36 #include "lldb/Utility/FileSpec.h"
37 #include "lldb/Utility/FileSpecList.h"
38 #include "lldb/Utility/LLDBLog.h"
39 #include "lldb/Utility/Log.h"
40 #include "lldb/Utility/RangeMap.h"
41 #include "lldb/Utility/RegisterValue.h"
42 #include "lldb/Utility/Status.h"
43 #include "lldb/Utility/StreamString.h"
44 #include "lldb/Utility/Timer.h"
45 #include "lldb/Utility/UUID.h"
47 #include "lldb/Host/SafeMachO.h"
49 #include "llvm/ADT/DenseSet.h"
50 #include "llvm/Support/FormatVariadic.h"
51 #include "llvm/Support/MemoryBuffer.h"
53 #include "ObjectFileMachO.h"
55 #if defined(__APPLE__)
56 #include <TargetConditionals.h>
57 // GetLLDBSharedCacheUUID() needs to call dlsym()
59 #include <mach/mach_init.h>
60 #include <mach/vm_map.h>
61 #include <lldb/Host/SafeMachO.h>
65 #include "lldb/Utility/AppleUuidCompatibility.h"
67 #include <uuid/uuid.h>
74 // Unfortunately the signpost header pulls in the system MachO header, too.
81 #ifdef CPU_TYPE_ARM64_32
82 #undef CPU_TYPE_ARM64_32
87 #ifdef CPU_TYPE_X86_64
88 #undef CPU_TYPE_X86_64
96 #ifdef LC_VERSION_MIN_MACOSX
97 #undef LC_VERSION_MIN_MACOSX
99 #ifdef LC_VERSION_MIN_IPHONEOS
100 #undef LC_VERSION_MIN_IPHONEOS
102 #ifdef LC_VERSION_MIN_TVOS
103 #undef LC_VERSION_MIN_TVOS
105 #ifdef LC_VERSION_MIN_WATCHOS
106 #undef LC_VERSION_MIN_WATCHOS
108 #ifdef LC_BUILD_VERSION
109 #undef LC_BUILD_VERSION
111 #ifdef PLATFORM_MACOS
112 #undef PLATFORM_MACOS
114 #ifdef PLATFORM_MACCATALYST
115 #undef PLATFORM_MACCATALYST
120 #ifdef PLATFORM_IOSSIMULATOR
121 #undef PLATFORM_IOSSIMULATOR
126 #ifdef PLATFORM_TVOSSIMULATOR
127 #undef PLATFORM_TVOSSIMULATOR
129 #ifdef PLATFORM_WATCHOS
130 #undef PLATFORM_WATCHOS
132 #ifdef PLATFORM_WATCHOSSIMULATOR
133 #undef PLATFORM_WATCHOSSIMULATOR
136 #define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
137 using namespace lldb
;
138 using namespace lldb_private
;
139 using namespace llvm::MachO
;
141 LLDB_PLUGIN_DEFINE(ObjectFileMachO
)
143 static void PrintRegisterValue(RegisterContext
*reg_ctx
, const char *name
,
144 const char *alt_name
, size_t reg_byte_size
,
146 const RegisterInfo
*reg_info
= reg_ctx
->GetRegisterInfoByName(name
);
147 if (reg_info
== nullptr)
148 reg_info
= reg_ctx
->GetRegisterInfoByName(alt_name
);
150 lldb_private::RegisterValue reg_value
;
151 if (reg_ctx
->ReadRegister(reg_info
, reg_value
)) {
152 if (reg_info
->byte_size
>= reg_byte_size
)
153 data
.Write(reg_value
.GetBytes(), reg_byte_size
);
155 data
.Write(reg_value
.GetBytes(), reg_info
->byte_size
);
156 for (size_t i
= 0, n
= reg_byte_size
- reg_info
->byte_size
; i
< n
; ++i
)
162 // Just write zeros if all else fails
163 for (size_t i
= 0; i
< reg_byte_size
; ++i
)
167 class RegisterContextDarwin_x86_64_Mach
: public RegisterContextDarwin_x86_64
{
169 RegisterContextDarwin_x86_64_Mach(lldb_private::Thread
&thread
,
170 const DataExtractor
&data
)
171 : RegisterContextDarwin_x86_64(thread
, 0) {
172 SetRegisterDataFrom_LC_THREAD(data
);
175 void InvalidateAllRegisters() override
{
176 // Do nothing... registers are always valid...
179 void SetRegisterDataFrom_LC_THREAD(const DataExtractor
&data
) {
180 lldb::offset_t offset
= 0;
181 SetError(GPRRegSet
, Read
, -1);
182 SetError(FPURegSet
, Read
, -1);
183 SetError(EXCRegSet
, Read
, -1);
187 int flavor
= data
.GetU32(&offset
);
192 uint32_t count
= data
.GetU32(&offset
);
195 for (i
= 0; i
< count
; ++i
)
196 (&gpr
.rax
)[i
] = data
.GetU64(&offset
);
197 SetError(GPRRegSet
, Read
, 0);
202 // TODO: fill in FPU regs....
203 // SetError (FPURegSet, Read, -1);
208 exc
.trapno
= data
.GetU32(&offset
);
209 exc
.err
= data
.GetU32(&offset
);
210 exc
.faultvaddr
= data
.GetU64(&offset
);
211 SetError(EXCRegSet
, Read
, 0);
217 // fancy flavors that encapsulate of the above flavors...
228 static bool Create_LC_THREAD(Thread
*thread
, Stream
&data
) {
229 RegisterContextSP
reg_ctx_sp(thread
->GetRegisterContext());
231 RegisterContext
*reg_ctx
= reg_ctx_sp
.get();
233 data
.PutHex32(GPRRegSet
); // Flavor
234 data
.PutHex32(GPRWordCount
);
235 PrintRegisterValue(reg_ctx
, "rax", nullptr, 8, data
);
236 PrintRegisterValue(reg_ctx
, "rbx", nullptr, 8, data
);
237 PrintRegisterValue(reg_ctx
, "rcx", nullptr, 8, data
);
238 PrintRegisterValue(reg_ctx
, "rdx", nullptr, 8, data
);
239 PrintRegisterValue(reg_ctx
, "rdi", nullptr, 8, data
);
240 PrintRegisterValue(reg_ctx
, "rsi", nullptr, 8, data
);
241 PrintRegisterValue(reg_ctx
, "rbp", nullptr, 8, data
);
242 PrintRegisterValue(reg_ctx
, "rsp", nullptr, 8, data
);
243 PrintRegisterValue(reg_ctx
, "r8", nullptr, 8, data
);
244 PrintRegisterValue(reg_ctx
, "r9", nullptr, 8, data
);
245 PrintRegisterValue(reg_ctx
, "r10", nullptr, 8, data
);
246 PrintRegisterValue(reg_ctx
, "r11", nullptr, 8, data
);
247 PrintRegisterValue(reg_ctx
, "r12", nullptr, 8, data
);
248 PrintRegisterValue(reg_ctx
, "r13", nullptr, 8, data
);
249 PrintRegisterValue(reg_ctx
, "r14", nullptr, 8, data
);
250 PrintRegisterValue(reg_ctx
, "r15", nullptr, 8, data
);
251 PrintRegisterValue(reg_ctx
, "rip", nullptr, 8, data
);
252 PrintRegisterValue(reg_ctx
, "rflags", nullptr, 8, data
);
253 PrintRegisterValue(reg_ctx
, "cs", nullptr, 8, data
);
254 PrintRegisterValue(reg_ctx
, "fs", nullptr, 8, data
);
255 PrintRegisterValue(reg_ctx
, "gs", nullptr, 8, data
);
257 // // Write out the FPU registers
258 // const size_t fpu_byte_size = sizeof(FPU);
259 // size_t bytes_written = 0;
260 // data.PutHex32 (FPURegSet);
261 // data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
262 // bytes_written += data.PutHex32(0); // uint32_t pad[0]
263 // bytes_written += data.PutHex32(0); // uint32_t pad[1]
264 // bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2,
265 // data); // uint16_t fcw; // "fctrl"
266 // bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2,
267 // data); // uint16_t fsw; // "fstat"
268 // bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1,
269 // data); // uint8_t ftw; // "ftag"
270 // bytes_written += data.PutHex8 (0); // uint8_t pad1;
271 // bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2,
272 // data); // uint16_t fop; // "fop"
273 // bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4,
274 // data); // uint32_t ip; // "fioff"
275 // bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2,
276 // data); // uint16_t cs; // "fiseg"
277 // bytes_written += data.PutHex16 (0); // uint16_t pad2;
278 // bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4,
279 // data); // uint32_t dp; // "fooff"
280 // bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2,
281 // data); // uint16_t ds; // "foseg"
282 // bytes_written += data.PutHex16 (0); // uint16_t pad3;
283 // bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4,
284 // data); // uint32_t mxcsr;
285 // bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL,
286 // 4, data);// uint32_t mxcsrmask;
287 // bytes_written += WriteRegister (reg_ctx, "stmm0", NULL,
288 // sizeof(MMSReg), data);
289 // bytes_written += WriteRegister (reg_ctx, "stmm1", NULL,
290 // sizeof(MMSReg), data);
291 // bytes_written += WriteRegister (reg_ctx, "stmm2", NULL,
292 // sizeof(MMSReg), data);
293 // bytes_written += WriteRegister (reg_ctx, "stmm3", NULL,
294 // sizeof(MMSReg), data);
295 // bytes_written += WriteRegister (reg_ctx, "stmm4", NULL,
296 // sizeof(MMSReg), data);
297 // bytes_written += WriteRegister (reg_ctx, "stmm5", NULL,
298 // sizeof(MMSReg), data);
299 // bytes_written += WriteRegister (reg_ctx, "stmm6", NULL,
300 // sizeof(MMSReg), data);
301 // bytes_written += WriteRegister (reg_ctx, "stmm7", NULL,
302 // sizeof(MMSReg), data);
303 // bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL,
304 // sizeof(XMMReg), data);
305 // bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL,
306 // sizeof(XMMReg), data);
307 // bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL,
308 // sizeof(XMMReg), data);
309 // bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL,
310 // sizeof(XMMReg), data);
311 // bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL,
312 // sizeof(XMMReg), data);
313 // bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL,
314 // sizeof(XMMReg), data);
315 // bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL,
316 // sizeof(XMMReg), data);
317 // bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL,
318 // sizeof(XMMReg), data);
319 // bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL,
320 // sizeof(XMMReg), data);
321 // bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL,
322 // sizeof(XMMReg), data);
323 // bytes_written += WriteRegister (reg_ctx, "xmm10", NULL,
324 // sizeof(XMMReg), data);
325 // bytes_written += WriteRegister (reg_ctx, "xmm11", NULL,
326 // sizeof(XMMReg), data);
327 // bytes_written += WriteRegister (reg_ctx, "xmm12", NULL,
328 // sizeof(XMMReg), data);
329 // bytes_written += WriteRegister (reg_ctx, "xmm13", NULL,
330 // sizeof(XMMReg), data);
331 // bytes_written += WriteRegister (reg_ctx, "xmm14", NULL,
332 // sizeof(XMMReg), data);
333 // bytes_written += WriteRegister (reg_ctx, "xmm15", NULL,
334 // sizeof(XMMReg), data);
336 // // Fill rest with zeros
337 // for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++
341 // Write out the EXC registers
342 data
.PutHex32(EXCRegSet
);
343 data
.PutHex32(EXCWordCount
);
344 PrintRegisterValue(reg_ctx
, "trapno", nullptr, 4, data
);
345 PrintRegisterValue(reg_ctx
, "err", nullptr, 4, data
);
346 PrintRegisterValue(reg_ctx
, "faultvaddr", nullptr, 8, data
);
353 int DoReadGPR(lldb::tid_t tid
, int flavor
, GPR
&gpr
) override
{ return 0; }
355 int DoReadFPU(lldb::tid_t tid
, int flavor
, FPU
&fpu
) override
{ return 0; }
357 int DoReadEXC(lldb::tid_t tid
, int flavor
, EXC
&exc
) override
{ return 0; }
359 int DoWriteGPR(lldb::tid_t tid
, int flavor
, const GPR
&gpr
) override
{
363 int DoWriteFPU(lldb::tid_t tid
, int flavor
, const FPU
&fpu
) override
{
367 int DoWriteEXC(lldb::tid_t tid
, int flavor
, const EXC
&exc
) override
{
372 class RegisterContextDarwin_i386_Mach
: public RegisterContextDarwin_i386
{
374 RegisterContextDarwin_i386_Mach(lldb_private::Thread
&thread
,
375 const DataExtractor
&data
)
376 : RegisterContextDarwin_i386(thread
, 0) {
377 SetRegisterDataFrom_LC_THREAD(data
);
380 void InvalidateAllRegisters() override
{
381 // Do nothing... registers are always valid...
384 void SetRegisterDataFrom_LC_THREAD(const DataExtractor
&data
) {
385 lldb::offset_t offset
= 0;
386 SetError(GPRRegSet
, Read
, -1);
387 SetError(FPURegSet
, Read
, -1);
388 SetError(EXCRegSet
, Read
, -1);
392 int flavor
= data
.GetU32(&offset
);
397 uint32_t count
= data
.GetU32(&offset
);
400 for (i
= 0; i
< count
; ++i
)
401 (&gpr
.eax
)[i
] = data
.GetU32(&offset
);
402 SetError(GPRRegSet
, Read
, 0);
407 // TODO: fill in FPU regs....
408 // SetError (FPURegSet, Read, -1);
413 exc
.trapno
= data
.GetU32(&offset
);
414 exc
.err
= data
.GetU32(&offset
);
415 exc
.faultvaddr
= data
.GetU32(&offset
);
416 SetError(EXCRegSet
, Read
, 0);
422 // fancy flavors that encapsulate of the above flavors...
433 static bool Create_LC_THREAD(Thread
*thread
, Stream
&data
) {
434 RegisterContextSP
reg_ctx_sp(thread
->GetRegisterContext());
436 RegisterContext
*reg_ctx
= reg_ctx_sp
.get();
438 data
.PutHex32(GPRRegSet
); // Flavor
439 data
.PutHex32(GPRWordCount
);
440 PrintRegisterValue(reg_ctx
, "eax", nullptr, 4, data
);
441 PrintRegisterValue(reg_ctx
, "ebx", nullptr, 4, data
);
442 PrintRegisterValue(reg_ctx
, "ecx", nullptr, 4, data
);
443 PrintRegisterValue(reg_ctx
, "edx", nullptr, 4, data
);
444 PrintRegisterValue(reg_ctx
, "edi", nullptr, 4, data
);
445 PrintRegisterValue(reg_ctx
, "esi", nullptr, 4, data
);
446 PrintRegisterValue(reg_ctx
, "ebp", nullptr, 4, data
);
447 PrintRegisterValue(reg_ctx
, "esp", nullptr, 4, data
);
448 PrintRegisterValue(reg_ctx
, "ss", nullptr, 4, data
);
449 PrintRegisterValue(reg_ctx
, "eflags", nullptr, 4, data
);
450 PrintRegisterValue(reg_ctx
, "eip", nullptr, 4, data
);
451 PrintRegisterValue(reg_ctx
, "cs", nullptr, 4, data
);
452 PrintRegisterValue(reg_ctx
, "ds", nullptr, 4, data
);
453 PrintRegisterValue(reg_ctx
, "es", nullptr, 4, data
);
454 PrintRegisterValue(reg_ctx
, "fs", nullptr, 4, data
);
455 PrintRegisterValue(reg_ctx
, "gs", nullptr, 4, data
);
457 // Write out the EXC registers
458 data
.PutHex32(EXCRegSet
);
459 data
.PutHex32(EXCWordCount
);
460 PrintRegisterValue(reg_ctx
, "trapno", nullptr, 4, data
);
461 PrintRegisterValue(reg_ctx
, "err", nullptr, 4, data
);
462 PrintRegisterValue(reg_ctx
, "faultvaddr", nullptr, 4, data
);
469 int DoReadGPR(lldb::tid_t tid
, int flavor
, GPR
&gpr
) override
{ return 0; }
471 int DoReadFPU(lldb::tid_t tid
, int flavor
, FPU
&fpu
) override
{ return 0; }
473 int DoReadEXC(lldb::tid_t tid
, int flavor
, EXC
&exc
) override
{ return 0; }
475 int DoWriteGPR(lldb::tid_t tid
, int flavor
, const GPR
&gpr
) override
{
479 int DoWriteFPU(lldb::tid_t tid
, int flavor
, const FPU
&fpu
) override
{
483 int DoWriteEXC(lldb::tid_t tid
, int flavor
, const EXC
&exc
) override
{
488 class RegisterContextDarwin_arm_Mach
: public RegisterContextDarwin_arm
{
490 RegisterContextDarwin_arm_Mach(lldb_private::Thread
&thread
,
491 const DataExtractor
&data
)
492 : RegisterContextDarwin_arm(thread
, 0) {
493 SetRegisterDataFrom_LC_THREAD(data
);
496 void InvalidateAllRegisters() override
{
497 // Do nothing... registers are always valid...
500 void SetRegisterDataFrom_LC_THREAD(const DataExtractor
&data
) {
501 lldb::offset_t offset
= 0;
502 SetError(GPRRegSet
, Read
, -1);
503 SetError(FPURegSet
, Read
, -1);
504 SetError(EXCRegSet
, Read
, -1);
508 int flavor
= data
.GetU32(&offset
);
509 uint32_t count
= data
.GetU32(&offset
);
510 lldb::offset_t next_thread_state
= offset
+ (count
* 4);
515 uint32_t gpr_buf_count
= (sizeof(gpr
.r
) / sizeof(gpr
.r
[0])) + 1;
516 if (count
== gpr_buf_count
) {
517 for (uint32_t i
= 0; i
< (count
- 1); ++i
) {
518 gpr
.r
[i
] = data
.GetU32(&offset
);
520 gpr
.cpsr
= data
.GetU32(&offset
);
522 SetError(GPRRegSet
, Read
, 0);
525 offset
= next_thread_state
;
529 uint8_t *fpu_reg_buf
= (uint8_t *)&fpu
.floats
;
530 const int fpu_reg_buf_size
= sizeof(fpu
.floats
);
531 if (data
.ExtractBytes(offset
, fpu_reg_buf_size
, eByteOrderLittle
,
532 fpu_reg_buf
) == fpu_reg_buf_size
) {
533 offset
+= fpu_reg_buf_size
;
534 fpu
.fpscr
= data
.GetU32(&offset
);
535 SetError(FPURegSet
, Read
, 0);
540 offset
= next_thread_state
;
545 exc
.exception
= data
.GetU32(&offset
);
546 exc
.fsr
= data
.GetU32(&offset
);
547 exc
.far
= data
.GetU32(&offset
);
548 SetError(EXCRegSet
, Read
, 0);
551 offset
= next_thread_state
;
554 // Unknown register set flavor, stop trying to parse.
561 static bool Create_LC_THREAD(Thread
*thread
, Stream
&data
) {
562 RegisterContextSP
reg_ctx_sp(thread
->GetRegisterContext());
564 RegisterContext
*reg_ctx
= reg_ctx_sp
.get();
566 data
.PutHex32(GPRRegSet
); // Flavor
567 data
.PutHex32(GPRWordCount
);
568 PrintRegisterValue(reg_ctx
, "r0", nullptr, 4, data
);
569 PrintRegisterValue(reg_ctx
, "r1", nullptr, 4, data
);
570 PrintRegisterValue(reg_ctx
, "r2", nullptr, 4, data
);
571 PrintRegisterValue(reg_ctx
, "r3", nullptr, 4, data
);
572 PrintRegisterValue(reg_ctx
, "r4", nullptr, 4, data
);
573 PrintRegisterValue(reg_ctx
, "r5", nullptr, 4, data
);
574 PrintRegisterValue(reg_ctx
, "r6", nullptr, 4, data
);
575 PrintRegisterValue(reg_ctx
, "r7", nullptr, 4, data
);
576 PrintRegisterValue(reg_ctx
, "r8", nullptr, 4, data
);
577 PrintRegisterValue(reg_ctx
, "r9", nullptr, 4, data
);
578 PrintRegisterValue(reg_ctx
, "r10", nullptr, 4, data
);
579 PrintRegisterValue(reg_ctx
, "r11", nullptr, 4, data
);
580 PrintRegisterValue(reg_ctx
, "r12", nullptr, 4, data
);
581 PrintRegisterValue(reg_ctx
, "sp", nullptr, 4, data
);
582 PrintRegisterValue(reg_ctx
, "lr", nullptr, 4, data
);
583 PrintRegisterValue(reg_ctx
, "pc", nullptr, 4, data
);
584 PrintRegisterValue(reg_ctx
, "cpsr", nullptr, 4, data
);
586 // Write out the EXC registers
587 // data.PutHex32 (EXCRegSet);
588 // data.PutHex32 (EXCWordCount);
589 // WriteRegister (reg_ctx, "exception", NULL, 4, data);
590 // WriteRegister (reg_ctx, "fsr", NULL, 4, data);
591 // WriteRegister (reg_ctx, "far", NULL, 4, data);
598 int DoReadGPR(lldb::tid_t tid
, int flavor
, GPR
&gpr
) override
{ return -1; }
600 int DoReadFPU(lldb::tid_t tid
, int flavor
, FPU
&fpu
) override
{ return -1; }
602 int DoReadEXC(lldb::tid_t tid
, int flavor
, EXC
&exc
) override
{ return -1; }
604 int DoReadDBG(lldb::tid_t tid
, int flavor
, DBG
&dbg
) override
{ return -1; }
606 int DoWriteGPR(lldb::tid_t tid
, int flavor
, const GPR
&gpr
) override
{
610 int DoWriteFPU(lldb::tid_t tid
, int flavor
, const FPU
&fpu
) override
{
614 int DoWriteEXC(lldb::tid_t tid
, int flavor
, const EXC
&exc
) override
{
618 int DoWriteDBG(lldb::tid_t tid
, int flavor
, const DBG
&dbg
) override
{
623 class RegisterContextDarwin_arm64_Mach
: public RegisterContextDarwin_arm64
{
625 RegisterContextDarwin_arm64_Mach(lldb_private::Thread
&thread
,
626 const DataExtractor
&data
)
627 : RegisterContextDarwin_arm64(thread
, 0) {
628 SetRegisterDataFrom_LC_THREAD(data
);
631 void InvalidateAllRegisters() override
{
632 // Do nothing... registers are always valid...
635 void SetRegisterDataFrom_LC_THREAD(const DataExtractor
&data
) {
636 lldb::offset_t offset
= 0;
637 SetError(GPRRegSet
, Read
, -1);
638 SetError(FPURegSet
, Read
, -1);
639 SetError(EXCRegSet
, Read
, -1);
642 int flavor
= data
.GetU32(&offset
);
643 uint32_t count
= data
.GetU32(&offset
);
644 lldb::offset_t next_thread_state
= offset
+ (count
* 4);
647 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1
649 if (count
>= (33 * 2) + 1) {
650 for (uint32_t i
= 0; i
< 29; ++i
)
651 gpr
.x
[i
] = data
.GetU64(&offset
);
652 gpr
.fp
= data
.GetU64(&offset
);
653 gpr
.lr
= data
.GetU64(&offset
);
654 gpr
.sp
= data
.GetU64(&offset
);
655 gpr
.pc
= data
.GetU64(&offset
);
656 gpr
.cpsr
= data
.GetU32(&offset
);
657 SetError(GPRRegSet
, Read
, 0);
659 offset
= next_thread_state
;
662 uint8_t *fpu_reg_buf
= (uint8_t *)&fpu
.v
[0];
663 const int fpu_reg_buf_size
= sizeof(fpu
);
664 if (fpu_reg_buf_size
== count
* sizeof(uint32_t) &&
665 data
.ExtractBytes(offset
, fpu_reg_buf_size
, eByteOrderLittle
,
666 fpu_reg_buf
) == fpu_reg_buf_size
) {
667 SetError(FPURegSet
, Read
, 0);
672 offset
= next_thread_state
;
676 exc
.far
= data
.GetU64(&offset
);
677 exc
.esr
= data
.GetU32(&offset
);
678 exc
.exception
= data
.GetU32(&offset
);
679 SetError(EXCRegSet
, Read
, 0);
681 offset
= next_thread_state
;
690 static bool Create_LC_THREAD(Thread
*thread
, Stream
&data
) {
691 RegisterContextSP
reg_ctx_sp(thread
->GetRegisterContext());
693 RegisterContext
*reg_ctx
= reg_ctx_sp
.get();
695 data
.PutHex32(GPRRegSet
); // Flavor
696 data
.PutHex32(GPRWordCount
);
697 PrintRegisterValue(reg_ctx
, "x0", nullptr, 8, data
);
698 PrintRegisterValue(reg_ctx
, "x1", nullptr, 8, data
);
699 PrintRegisterValue(reg_ctx
, "x2", nullptr, 8, data
);
700 PrintRegisterValue(reg_ctx
, "x3", nullptr, 8, data
);
701 PrintRegisterValue(reg_ctx
, "x4", nullptr, 8, data
);
702 PrintRegisterValue(reg_ctx
, "x5", nullptr, 8, data
);
703 PrintRegisterValue(reg_ctx
, "x6", nullptr, 8, data
);
704 PrintRegisterValue(reg_ctx
, "x7", nullptr, 8, data
);
705 PrintRegisterValue(reg_ctx
, "x8", nullptr, 8, data
);
706 PrintRegisterValue(reg_ctx
, "x9", nullptr, 8, data
);
707 PrintRegisterValue(reg_ctx
, "x10", nullptr, 8, data
);
708 PrintRegisterValue(reg_ctx
, "x11", nullptr, 8, data
);
709 PrintRegisterValue(reg_ctx
, "x12", nullptr, 8, data
);
710 PrintRegisterValue(reg_ctx
, "x13", nullptr, 8, data
);
711 PrintRegisterValue(reg_ctx
, "x14", nullptr, 8, data
);
712 PrintRegisterValue(reg_ctx
, "x15", nullptr, 8, data
);
713 PrintRegisterValue(reg_ctx
, "x16", nullptr, 8, data
);
714 PrintRegisterValue(reg_ctx
, "x17", nullptr, 8, data
);
715 PrintRegisterValue(reg_ctx
, "x18", nullptr, 8, data
);
716 PrintRegisterValue(reg_ctx
, "x19", nullptr, 8, data
);
717 PrintRegisterValue(reg_ctx
, "x20", nullptr, 8, data
);
718 PrintRegisterValue(reg_ctx
, "x21", nullptr, 8, data
);
719 PrintRegisterValue(reg_ctx
, "x22", nullptr, 8, data
);
720 PrintRegisterValue(reg_ctx
, "x23", nullptr, 8, data
);
721 PrintRegisterValue(reg_ctx
, "x24", nullptr, 8, data
);
722 PrintRegisterValue(reg_ctx
, "x25", nullptr, 8, data
);
723 PrintRegisterValue(reg_ctx
, "x26", nullptr, 8, data
);
724 PrintRegisterValue(reg_ctx
, "x27", nullptr, 8, data
);
725 PrintRegisterValue(reg_ctx
, "x28", nullptr, 8, data
);
726 PrintRegisterValue(reg_ctx
, "fp", nullptr, 8, data
);
727 PrintRegisterValue(reg_ctx
, "lr", nullptr, 8, data
);
728 PrintRegisterValue(reg_ctx
, "sp", nullptr, 8, data
);
729 PrintRegisterValue(reg_ctx
, "pc", nullptr, 8, data
);
730 PrintRegisterValue(reg_ctx
, "cpsr", nullptr, 4, data
);
731 data
.PutHex32(0); // uint32_t pad at the end
733 // Write out the EXC registers
734 data
.PutHex32(EXCRegSet
);
735 data
.PutHex32(EXCWordCount
);
736 PrintRegisterValue(reg_ctx
, "far", nullptr, 8, data
);
737 PrintRegisterValue(reg_ctx
, "esr", nullptr, 4, data
);
738 PrintRegisterValue(reg_ctx
, "exception", nullptr, 4, data
);
745 int DoReadGPR(lldb::tid_t tid
, int flavor
, GPR
&gpr
) override
{ return -1; }
747 int DoReadFPU(lldb::tid_t tid
, int flavor
, FPU
&fpu
) override
{ return -1; }
749 int DoReadEXC(lldb::tid_t tid
, int flavor
, EXC
&exc
) override
{ return -1; }
751 int DoReadDBG(lldb::tid_t tid
, int flavor
, DBG
&dbg
) override
{ return -1; }
753 int DoWriteGPR(lldb::tid_t tid
, int flavor
, const GPR
&gpr
) override
{
757 int DoWriteFPU(lldb::tid_t tid
, int flavor
, const FPU
&fpu
) override
{
761 int DoWriteEXC(lldb::tid_t tid
, int flavor
, const EXC
&exc
) override
{
765 int DoWriteDBG(lldb::tid_t tid
, int flavor
, const DBG
&dbg
) override
{
770 static uint32_t MachHeaderSizeFromMagic(uint32_t magic
) {
774 return sizeof(struct llvm::MachO::mach_header
);
778 return sizeof(struct llvm::MachO::mach_header_64
);
787 #define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
789 char ObjectFileMachO::ID
;
791 void ObjectFileMachO::Initialize() {
792 PluginManager::RegisterPlugin(
793 GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance
,
794 CreateMemoryInstance
, GetModuleSpecifications
, SaveCore
);
797 void ObjectFileMachO::Terminate() {
798 PluginManager::UnregisterPlugin(CreateInstance
);
801 ObjectFile
*ObjectFileMachO::CreateInstance(const lldb::ModuleSP
&module_sp
,
802 DataBufferSP data_sp
,
803 lldb::offset_t data_offset
,
804 const FileSpec
*file
,
805 lldb::offset_t file_offset
,
806 lldb::offset_t length
) {
808 data_sp
= MapFileData(*file
, length
, file_offset
);
814 if (!ObjectFileMachO::MagicBytesMatch(data_sp
, data_offset
, length
))
817 // Update the data to contain the entire file if it doesn't already
818 if (data_sp
->GetByteSize() < length
) {
819 data_sp
= MapFileData(*file
, length
, file_offset
);
824 auto objfile_up
= std::make_unique
<ObjectFileMachO
>(
825 module_sp
, data_sp
, data_offset
, file
, file_offset
, length
);
826 if (!objfile_up
|| !objfile_up
->ParseHeader())
829 return objfile_up
.release();
832 ObjectFile
*ObjectFileMachO::CreateMemoryInstance(
833 const lldb::ModuleSP
&module_sp
, WritableDataBufferSP data_sp
,
834 const ProcessSP
&process_sp
, lldb::addr_t header_addr
) {
835 if (ObjectFileMachO::MagicBytesMatch(data_sp
, 0, data_sp
->GetByteSize())) {
836 std::unique_ptr
<ObjectFile
> objfile_up(
837 new ObjectFileMachO(module_sp
, data_sp
, process_sp
, header_addr
));
838 if (objfile_up
.get() && objfile_up
->ParseHeader())
839 return objfile_up
.release();
844 size_t ObjectFileMachO::GetModuleSpecifications(
845 const lldb_private::FileSpec
&file
, lldb::DataBufferSP
&data_sp
,
846 lldb::offset_t data_offset
, lldb::offset_t file_offset
,
847 lldb::offset_t length
, lldb_private::ModuleSpecList
&specs
) {
848 const size_t initial_count
= specs
.GetSize();
850 if (ObjectFileMachO::MagicBytesMatch(data_sp
, 0, data_sp
->GetByteSize())) {
852 data
.SetData(data_sp
);
853 llvm::MachO::mach_header header
;
854 if (ParseHeader(data
, &data_offset
, header
)) {
855 size_t header_and_load_cmds
=
856 header
.sizeofcmds
+ MachHeaderSizeFromMagic(header
.magic
);
857 if (header_and_load_cmds
>= data_sp
->GetByteSize()) {
858 data_sp
= MapFileData(file
, header_and_load_cmds
, file_offset
);
859 data
.SetData(data_sp
);
860 data_offset
= MachHeaderSizeFromMagic(header
.magic
);
863 ModuleSpec base_spec
;
864 base_spec
.GetFileSpec() = file
;
865 base_spec
.SetObjectOffset(file_offset
);
866 base_spec
.SetObjectSize(length
);
867 GetAllArchSpecs(header
, data
, data_offset
, base_spec
, specs
);
871 return specs
.GetSize() - initial_count
;
874 ConstString
ObjectFileMachO::GetSegmentNameTEXT() {
875 static ConstString
g_segment_name_TEXT("__TEXT");
876 return g_segment_name_TEXT
;
879 ConstString
ObjectFileMachO::GetSegmentNameDATA() {
880 static ConstString
g_segment_name_DATA("__DATA");
881 return g_segment_name_DATA
;
884 ConstString
ObjectFileMachO::GetSegmentNameDATA_DIRTY() {
885 static ConstString
g_segment_name("__DATA_DIRTY");
886 return g_segment_name
;
889 ConstString
ObjectFileMachO::GetSegmentNameDATA_CONST() {
890 static ConstString
g_segment_name("__DATA_CONST");
891 return g_segment_name
;
894 ConstString
ObjectFileMachO::GetSegmentNameOBJC() {
895 static ConstString
g_segment_name_OBJC("__OBJC");
896 return g_segment_name_OBJC
;
899 ConstString
ObjectFileMachO::GetSegmentNameLINKEDIT() {
900 static ConstString
g_section_name_LINKEDIT("__LINKEDIT");
901 return g_section_name_LINKEDIT
;
904 ConstString
ObjectFileMachO::GetSegmentNameDWARF() {
905 static ConstString
g_section_name("__DWARF");
906 return g_section_name
;
909 ConstString
ObjectFileMachO::GetSectionNameEHFrame() {
910 static ConstString
g_section_name_eh_frame("__eh_frame");
911 return g_section_name_eh_frame
;
914 bool ObjectFileMachO::MagicBytesMatch(DataBufferSP data_sp
,
915 lldb::addr_t data_offset
,
916 lldb::addr_t data_length
) {
918 data
.SetData(data_sp
, data_offset
, data_length
);
919 lldb::offset_t offset
= 0;
920 uint32_t magic
= data
.GetU32(&offset
);
922 offset
+= 4; // cputype
923 offset
+= 4; // cpusubtype
924 uint32_t filetype
= data
.GetU32(&offset
);
926 // A fileset has a Mach-O header but is not an
927 // individual file and must be handled via an
928 // ObjectContainer plugin.
929 if (filetype
== llvm::MachO::MH_FILESET
)
932 return MachHeaderSizeFromMagic(magic
) != 0;
935 ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP
&module_sp
,
936 DataBufferSP data_sp
,
937 lldb::offset_t data_offset
,
938 const FileSpec
*file
,
939 lldb::offset_t file_offset
,
940 lldb::offset_t length
)
941 : ObjectFile(module_sp
, file
, file_offset
, length
, data_sp
, data_offset
),
942 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
943 m_thread_context_offsets_valid(false), m_reexported_dylibs(),
944 m_allow_assembly_emulation_unwind_plans(true) {
945 ::memset(&m_header
, 0, sizeof(m_header
));
946 ::memset(&m_dysymtab
, 0, sizeof(m_dysymtab
));
949 ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP
&module_sp
,
950 lldb::WritableDataBufferSP header_data_sp
,
951 const lldb::ProcessSP
&process_sp
,
952 lldb::addr_t header_addr
)
953 : ObjectFile(module_sp
, process_sp
, header_addr
, header_data_sp
),
954 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
955 m_thread_context_offsets_valid(false), m_reexported_dylibs(),
956 m_allow_assembly_emulation_unwind_plans(true) {
957 ::memset(&m_header
, 0, sizeof(m_header
));
958 ::memset(&m_dysymtab
, 0, sizeof(m_dysymtab
));
961 bool ObjectFileMachO::ParseHeader(DataExtractor
&data
,
962 lldb::offset_t
*data_offset_ptr
,
963 llvm::MachO::mach_header
&header
) {
964 data
.SetByteOrder(endian::InlHostByteOrder());
965 // Leave magic in the original byte order
966 header
.magic
= data
.GetU32(data_offset_ptr
);
967 bool can_parse
= false;
968 bool is_64_bit
= false;
969 switch (header
.magic
) {
971 data
.SetByteOrder(endian::InlHostByteOrder());
972 data
.SetAddressByteSize(4);
977 data
.SetByteOrder(endian::InlHostByteOrder());
978 data
.SetAddressByteSize(8);
984 data
.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
987 data
.SetAddressByteSize(4);
992 data
.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
995 data
.SetAddressByteSize(8);
1005 data
.GetU32(data_offset_ptr
, &header
.cputype
, 6);
1007 *data_offset_ptr
+= 4;
1010 memset(&header
, 0, sizeof(header
));
1015 bool ObjectFileMachO::ParseHeader() {
1016 ModuleSP
module_sp(GetModule());
1020 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
1021 bool can_parse
= false;
1022 lldb::offset_t offset
= 0;
1023 m_data
.SetByteOrder(endian::InlHostByteOrder());
1024 // Leave magic in the original byte order
1025 m_header
.magic
= m_data
.GetU32(&offset
);
1026 switch (m_header
.magic
) {
1028 m_data
.SetByteOrder(endian::InlHostByteOrder());
1029 m_data
.SetAddressByteSize(4);
1034 m_data
.SetByteOrder(endian::InlHostByteOrder());
1035 m_data
.SetAddressByteSize(8);
1040 m_data
.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
1043 m_data
.SetAddressByteSize(4);
1048 m_data
.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
1051 m_data
.SetAddressByteSize(8);
1060 m_data
.GetU32(&offset
, &m_header
.cputype
, 6);
1062 ModuleSpecList all_specs
;
1063 ModuleSpec base_spec
;
1064 GetAllArchSpecs(m_header
, m_data
, MachHeaderSizeFromMagic(m_header
.magic
),
1065 base_spec
, all_specs
);
1067 for (unsigned i
= 0, e
= all_specs
.GetSize(); i
!= e
; ++i
) {
1068 ArchSpec mach_arch
=
1069 all_specs
.GetModuleSpecRefAtIndex(i
).GetArchitecture();
1071 // Check if the module has a required architecture
1072 const ArchSpec
&module_arch
= module_sp
->GetArchitecture();
1073 if (module_arch
.IsValid() && !module_arch
.IsCompatibleMatch(mach_arch
))
1076 if (SetModulesArchitecture(mach_arch
)) {
1077 const size_t header_and_lc_size
=
1078 m_header
.sizeofcmds
+ MachHeaderSizeFromMagic(m_header
.magic
);
1079 if (m_data
.GetByteSize() < header_and_lc_size
) {
1080 DataBufferSP data_sp
;
1081 ProcessSP
process_sp(m_process_wp
.lock());
1083 data_sp
= ReadMemory(process_sp
, m_memory_addr
, header_and_lc_size
);
1085 // Read in all only the load command data from the file on disk
1086 data_sp
= MapFileData(m_file
, header_and_lc_size
, m_file_offset
);
1087 if (data_sp
->GetByteSize() != header_and_lc_size
)
1091 m_data
.SetData(data_sp
);
1099 memset(&m_header
, 0, sizeof(struct llvm::MachO::mach_header
));
1104 ByteOrder
ObjectFileMachO::GetByteOrder() const {
1105 return m_data
.GetByteOrder();
1108 bool ObjectFileMachO::IsExecutable() const {
1109 return m_header
.filetype
== MH_EXECUTE
;
1112 bool ObjectFileMachO::IsDynamicLoader() const {
1113 return m_header
.filetype
== MH_DYLINKER
;
1116 bool ObjectFileMachO::IsSharedCacheBinary() const {
1117 return m_header
.flags
& MH_DYLIB_IN_CACHE
;
1120 bool ObjectFileMachO::IsKext() const {
1121 return m_header
.filetype
== MH_KEXT_BUNDLE
;
1124 uint32_t ObjectFileMachO::GetAddressByteSize() const {
1125 return m_data
.GetAddressByteSize();
1128 AddressClass
ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr
) {
1129 Symtab
*symtab
= GetSymtab();
1131 return AddressClass::eUnknown
;
1133 Symbol
*symbol
= symtab
->FindSymbolContainingFileAddress(file_addr
);
1135 if (symbol
->ValueIsAddress()) {
1136 SectionSP
section_sp(symbol
->GetAddressRef().GetSection());
1138 const lldb::SectionType section_type
= section_sp
->GetType();
1139 switch (section_type
) {
1140 case eSectionTypeInvalid
:
1141 return AddressClass::eUnknown
;
1143 case eSectionTypeCode
:
1144 if (m_header
.cputype
== llvm::MachO::CPU_TYPE_ARM
) {
1145 // For ARM we have a bit in the n_desc field of the symbol that
1146 // tells us ARM/Thumb which is bit 0x0008.
1147 if (symbol
->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB
)
1148 return AddressClass::eCodeAlternateISA
;
1150 return AddressClass::eCode
;
1152 case eSectionTypeContainer
:
1153 return AddressClass::eUnknown
;
1155 case eSectionTypeData
:
1156 case eSectionTypeDataCString
:
1157 case eSectionTypeDataCStringPointers
:
1158 case eSectionTypeDataSymbolAddress
:
1159 case eSectionTypeData4
:
1160 case eSectionTypeData8
:
1161 case eSectionTypeData16
:
1162 case eSectionTypeDataPointers
:
1163 case eSectionTypeZeroFill
:
1164 case eSectionTypeDataObjCMessageRefs
:
1165 case eSectionTypeDataObjCCFStrings
:
1166 case eSectionTypeGoSymtab
:
1167 return AddressClass::eData
;
1169 case eSectionTypeDebug
:
1170 case eSectionTypeDWARFDebugAbbrev
:
1171 case eSectionTypeDWARFDebugAbbrevDwo
:
1172 case eSectionTypeDWARFDebugAddr
:
1173 case eSectionTypeDWARFDebugAranges
:
1174 case eSectionTypeDWARFDebugCuIndex
:
1175 case eSectionTypeDWARFDebugFrame
:
1176 case eSectionTypeDWARFDebugInfo
:
1177 case eSectionTypeDWARFDebugInfoDwo
:
1178 case eSectionTypeDWARFDebugLine
:
1179 case eSectionTypeDWARFDebugLineStr
:
1180 case eSectionTypeDWARFDebugLoc
:
1181 case eSectionTypeDWARFDebugLocDwo
:
1182 case eSectionTypeDWARFDebugLocLists
:
1183 case eSectionTypeDWARFDebugLocListsDwo
:
1184 case eSectionTypeDWARFDebugMacInfo
:
1185 case eSectionTypeDWARFDebugMacro
:
1186 case eSectionTypeDWARFDebugNames
:
1187 case eSectionTypeDWARFDebugPubNames
:
1188 case eSectionTypeDWARFDebugPubTypes
:
1189 case eSectionTypeDWARFDebugRanges
:
1190 case eSectionTypeDWARFDebugRngLists
:
1191 case eSectionTypeDWARFDebugRngListsDwo
:
1192 case eSectionTypeDWARFDebugStr
:
1193 case eSectionTypeDWARFDebugStrDwo
:
1194 case eSectionTypeDWARFDebugStrOffsets
:
1195 case eSectionTypeDWARFDebugStrOffsetsDwo
:
1196 case eSectionTypeDWARFDebugTuIndex
:
1197 case eSectionTypeDWARFDebugTypes
:
1198 case eSectionTypeDWARFDebugTypesDwo
:
1199 case eSectionTypeDWARFAppleNames
:
1200 case eSectionTypeDWARFAppleTypes
:
1201 case eSectionTypeDWARFAppleNamespaces
:
1202 case eSectionTypeDWARFAppleObjC
:
1203 case eSectionTypeDWARFGNUDebugAltLink
:
1204 case eSectionTypeCTF
:
1205 case eSectionTypeSwiftModules
:
1206 return AddressClass::eDebug
;
1208 case eSectionTypeEHFrame
:
1209 case eSectionTypeARMexidx
:
1210 case eSectionTypeARMextab
:
1211 case eSectionTypeCompactUnwind
:
1212 return AddressClass::eRuntime
;
1214 case eSectionTypeAbsoluteAddress
:
1215 case eSectionTypeELFSymbolTable
:
1216 case eSectionTypeELFDynamicSymbols
:
1217 case eSectionTypeELFRelocationEntries
:
1218 case eSectionTypeELFDynamicLinkInfo
:
1219 case eSectionTypeOther
:
1220 return AddressClass::eUnknown
;
1225 const SymbolType symbol_type
= symbol
->GetType();
1226 switch (symbol_type
) {
1227 case eSymbolTypeAny
:
1228 return AddressClass::eUnknown
;
1229 case eSymbolTypeAbsolute
:
1230 return AddressClass::eUnknown
;
1232 case eSymbolTypeCode
:
1233 case eSymbolTypeTrampoline
:
1234 case eSymbolTypeResolver
:
1235 if (m_header
.cputype
== llvm::MachO::CPU_TYPE_ARM
) {
1236 // For ARM we have a bit in the n_desc field of the symbol that tells
1237 // us ARM/Thumb which is bit 0x0008.
1238 if (symbol
->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB
)
1239 return AddressClass::eCodeAlternateISA
;
1241 return AddressClass::eCode
;
1243 case eSymbolTypeData
:
1244 return AddressClass::eData
;
1245 case eSymbolTypeRuntime
:
1246 return AddressClass::eRuntime
;
1247 case eSymbolTypeException
:
1248 return AddressClass::eRuntime
;
1249 case eSymbolTypeSourceFile
:
1250 return AddressClass::eDebug
;
1251 case eSymbolTypeHeaderFile
:
1252 return AddressClass::eDebug
;
1253 case eSymbolTypeObjectFile
:
1254 return AddressClass::eDebug
;
1255 case eSymbolTypeCommonBlock
:
1256 return AddressClass::eDebug
;
1257 case eSymbolTypeBlock
:
1258 return AddressClass::eDebug
;
1259 case eSymbolTypeLocal
:
1260 return AddressClass::eData
;
1261 case eSymbolTypeParam
:
1262 return AddressClass::eData
;
1263 case eSymbolTypeVariable
:
1264 return AddressClass::eData
;
1265 case eSymbolTypeVariableType
:
1266 return AddressClass::eDebug
;
1267 case eSymbolTypeLineEntry
:
1268 return AddressClass::eDebug
;
1269 case eSymbolTypeLineHeader
:
1270 return AddressClass::eDebug
;
1271 case eSymbolTypeScopeBegin
:
1272 return AddressClass::eDebug
;
1273 case eSymbolTypeScopeEnd
:
1274 return AddressClass::eDebug
;
1275 case eSymbolTypeAdditional
:
1276 return AddressClass::eUnknown
;
1277 case eSymbolTypeCompiler
:
1278 return AddressClass::eDebug
;
1279 case eSymbolTypeInstrumentation
:
1280 return AddressClass::eDebug
;
1281 case eSymbolTypeUndefined
:
1282 return AddressClass::eUnknown
;
1283 case eSymbolTypeObjCClass
:
1284 return AddressClass::eRuntime
;
1285 case eSymbolTypeObjCMetaClass
:
1286 return AddressClass::eRuntime
;
1287 case eSymbolTypeObjCIVar
:
1288 return AddressClass::eRuntime
;
1289 case eSymbolTypeReExported
:
1290 return AddressClass::eRuntime
;
1293 return AddressClass::eUnknown
;
1296 bool ObjectFileMachO::IsStripped() {
1297 if (m_dysymtab
.cmd
== 0) {
1298 ModuleSP
module_sp(GetModule());
1300 lldb::offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
1301 for (uint32_t i
= 0; i
< m_header
.ncmds
; ++i
) {
1302 const lldb::offset_t load_cmd_offset
= offset
;
1304 llvm::MachO::load_command lc
= {};
1305 if (m_data
.GetU32(&offset
, &lc
.cmd
, 2) == nullptr)
1307 if (lc
.cmd
== LC_DYSYMTAB
) {
1308 m_dysymtab
.cmd
= lc
.cmd
;
1309 m_dysymtab
.cmdsize
= lc
.cmdsize
;
1310 if (m_data
.GetU32(&offset
, &m_dysymtab
.ilocalsym
,
1311 (sizeof(m_dysymtab
) / sizeof(uint32_t)) - 2) ==
1313 // Clear m_dysymtab if we were unable to read all items from the
1315 ::memset(&m_dysymtab
, 0, sizeof(m_dysymtab
));
1318 offset
= load_cmd_offset
+ lc
.cmdsize
;
1323 return m_dysymtab
.nlocalsym
<= 1;
1327 ObjectFileMachO::EncryptedFileRanges
ObjectFileMachO::GetEncryptedFileRanges() {
1328 EncryptedFileRanges result
;
1329 lldb::offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
1331 llvm::MachO::encryption_info_command encryption_cmd
;
1332 for (uint32_t i
= 0; i
< m_header
.ncmds
; ++i
) {
1333 const lldb::offset_t load_cmd_offset
= offset
;
1334 if (m_data
.GetU32(&offset
, &encryption_cmd
, 2) == nullptr)
1337 // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for the
1338 // 3 fields we care about, so treat them the same.
1339 if (encryption_cmd
.cmd
== LC_ENCRYPTION_INFO
||
1340 encryption_cmd
.cmd
== LC_ENCRYPTION_INFO_64
) {
1341 if (m_data
.GetU32(&offset
, &encryption_cmd
.cryptoff
, 3)) {
1342 if (encryption_cmd
.cryptid
!= 0) {
1343 EncryptedFileRanges::Entry entry
;
1344 entry
.SetRangeBase(encryption_cmd
.cryptoff
);
1345 entry
.SetByteSize(encryption_cmd
.cryptsize
);
1346 result
.Append(entry
);
1350 offset
= load_cmd_offset
+ encryption_cmd
.cmdsize
;
1356 void ObjectFileMachO::SanitizeSegmentCommand(
1357 llvm::MachO::segment_command_64
&seg_cmd
, uint32_t cmd_idx
) {
1358 if (m_length
== 0 || seg_cmd
.filesize
== 0)
1361 if (IsSharedCacheBinary() && !IsInMemory()) {
1362 // In shared cache images, the load commands are relative to the
1363 // shared cache file, and not the specific image we are
1364 // examining. Let's fix this up so that it looks like a normal
1366 if (strncmp(seg_cmd
.segname
, GetSegmentNameTEXT().GetCString(),
1367 sizeof(seg_cmd
.segname
)) == 0)
1368 m_text_address
= seg_cmd
.vmaddr
;
1369 if (strncmp(seg_cmd
.segname
, GetSegmentNameLINKEDIT().GetCString(),
1370 sizeof(seg_cmd
.segname
)) == 0)
1371 m_linkedit_original_offset
= seg_cmd
.fileoff
;
1373 seg_cmd
.fileoff
= seg_cmd
.vmaddr
- m_text_address
;
1376 if (seg_cmd
.fileoff
> m_length
) {
1377 // We have a load command that says it extends past the end of the file.
1378 // This is likely a corrupt file. We don't have any way to return an error
1379 // condition here (this method was likely invoked from something like
1380 // ObjectFile::GetSectionList()), so we just null out the section contents,
1381 // and dump a message to stdout. The most common case here is core file
1382 // debugging with a truncated file.
1383 const char *lc_segment_name
=
1384 seg_cmd
.cmd
== LC_SEGMENT_64
? "LC_SEGMENT_64" : "LC_SEGMENT";
1385 GetModule()->ReportWarning(
1386 "load command {0} {1} has a fileoff ({2:x16}) that extends beyond "
1387 "the end of the file ({3:x16}), ignoring this section",
1388 cmd_idx
, lc_segment_name
, seg_cmd
.fileoff
, m_length
);
1390 seg_cmd
.fileoff
= 0;
1391 seg_cmd
.filesize
= 0;
1394 if (seg_cmd
.fileoff
+ seg_cmd
.filesize
> m_length
) {
1395 // We have a load command that says it extends past the end of the file.
1396 // This is likely a corrupt file. We don't have any way to return an error
1397 // condition here (this method was likely invoked from something like
1398 // ObjectFile::GetSectionList()), so we just null out the section contents,
1399 // and dump a message to stdout. The most common case here is core file
1400 // debugging with a truncated file.
1401 const char *lc_segment_name
=
1402 seg_cmd
.cmd
== LC_SEGMENT_64
? "LC_SEGMENT_64" : "LC_SEGMENT";
1403 GetModule()->ReportWarning(
1404 "load command {0} {1} has a fileoff + filesize ({2:x16}) that "
1405 "extends beyond the end of the file ({4:x16}), the segment will be "
1406 "truncated to match",
1407 cmd_idx
, lc_segment_name
, seg_cmd
.fileoff
+ seg_cmd
.filesize
, m_length
);
1409 // Truncate the length
1410 seg_cmd
.filesize
= m_length
- seg_cmd
.fileoff
;
1415 GetSegmentPermissions(const llvm::MachO::segment_command_64
&seg_cmd
) {
1416 uint32_t result
= 0;
1417 if (seg_cmd
.initprot
& VM_PROT_READ
)
1418 result
|= ePermissionsReadable
;
1419 if (seg_cmd
.initprot
& VM_PROT_WRITE
)
1420 result
|= ePermissionsWritable
;
1421 if (seg_cmd
.initprot
& VM_PROT_EXECUTE
)
1422 result
|= ePermissionsExecutable
;
1426 static lldb::SectionType
GetSectionType(uint32_t flags
,
1427 ConstString section_name
) {
1429 if (flags
& (S_ATTR_PURE_INSTRUCTIONS
| S_ATTR_SOME_INSTRUCTIONS
))
1430 return eSectionTypeCode
;
1432 uint32_t mach_sect_type
= flags
& SECTION_TYPE
;
1433 static ConstString
g_sect_name_objc_data("__objc_data");
1434 static ConstString
g_sect_name_objc_msgrefs("__objc_msgrefs");
1435 static ConstString
g_sect_name_objc_selrefs("__objc_selrefs");
1436 static ConstString
g_sect_name_objc_classrefs("__objc_classrefs");
1437 static ConstString
g_sect_name_objc_superrefs("__objc_superrefs");
1438 static ConstString
g_sect_name_objc_const("__objc_const");
1439 static ConstString
g_sect_name_objc_classlist("__objc_classlist");
1440 static ConstString
g_sect_name_cfstring("__cfstring");
1442 static ConstString
g_sect_name_dwarf_debug_abbrev("__debug_abbrev");
1443 static ConstString
g_sect_name_dwarf_debug_abbrev_dwo("__debug_abbrev.dwo");
1444 static ConstString
g_sect_name_dwarf_debug_addr("__debug_addr");
1445 static ConstString
g_sect_name_dwarf_debug_aranges("__debug_aranges");
1446 static ConstString
g_sect_name_dwarf_debug_cu_index("__debug_cu_index");
1447 static ConstString
g_sect_name_dwarf_debug_frame("__debug_frame");
1448 static ConstString
g_sect_name_dwarf_debug_info("__debug_info");
1449 static ConstString
g_sect_name_dwarf_debug_info_dwo("__debug_info.dwo");
1450 static ConstString
g_sect_name_dwarf_debug_line("__debug_line");
1451 static ConstString
g_sect_name_dwarf_debug_line_dwo("__debug_line.dwo");
1452 static ConstString
g_sect_name_dwarf_debug_line_str("__debug_line_str");
1453 static ConstString
g_sect_name_dwarf_debug_loc("__debug_loc");
1454 static ConstString
g_sect_name_dwarf_debug_loclists("__debug_loclists");
1455 static ConstString
g_sect_name_dwarf_debug_loclists_dwo("__debug_loclists.dwo");
1456 static ConstString
g_sect_name_dwarf_debug_macinfo("__debug_macinfo");
1457 static ConstString
g_sect_name_dwarf_debug_macro("__debug_macro");
1458 static ConstString
g_sect_name_dwarf_debug_macro_dwo("__debug_macro.dwo");
1459 static ConstString
g_sect_name_dwarf_debug_names("__debug_names");
1460 static ConstString
g_sect_name_dwarf_debug_pubnames("__debug_pubnames");
1461 static ConstString
g_sect_name_dwarf_debug_pubtypes("__debug_pubtypes");
1462 static ConstString
g_sect_name_dwarf_debug_ranges("__debug_ranges");
1463 static ConstString
g_sect_name_dwarf_debug_rnglists("__debug_rnglists");
1464 static ConstString
g_sect_name_dwarf_debug_str("__debug_str");
1465 static ConstString
g_sect_name_dwarf_debug_str_dwo("__debug_str.dwo");
1466 static ConstString
g_sect_name_dwarf_debug_str_offs("__debug_str_offs");
1467 static ConstString
g_sect_name_dwarf_debug_str_offs_dwo("__debug_str_offs.dwo");
1468 static ConstString
g_sect_name_dwarf_debug_tu_index("__debug_tu_index");
1469 static ConstString
g_sect_name_dwarf_debug_types("__debug_types");
1470 static ConstString
g_sect_name_dwarf_apple_names("__apple_names");
1471 static ConstString
g_sect_name_dwarf_apple_types("__apple_types");
1472 static ConstString
g_sect_name_dwarf_apple_namespaces("__apple_namespac");
1473 static ConstString
g_sect_name_dwarf_apple_objc("__apple_objc");
1474 static ConstString
g_sect_name_eh_frame("__eh_frame");
1475 static ConstString
g_sect_name_compact_unwind("__unwind_info");
1476 static ConstString
g_sect_name_text("__text");
1477 static ConstString
g_sect_name_data("__data");
1478 static ConstString
g_sect_name_go_symtab("__gosymtab");
1479 static ConstString
g_sect_name_ctf("__ctf");
1480 static ConstString
g_sect_name_swift_ast("__swift_ast");
1482 if (section_name
== g_sect_name_dwarf_debug_abbrev
)
1483 return eSectionTypeDWARFDebugAbbrev
;
1484 if (section_name
== g_sect_name_dwarf_debug_abbrev_dwo
)
1485 return eSectionTypeDWARFDebugAbbrevDwo
;
1486 if (section_name
== g_sect_name_dwarf_debug_addr
)
1487 return eSectionTypeDWARFDebugAddr
;
1488 if (section_name
== g_sect_name_dwarf_debug_aranges
)
1489 return eSectionTypeDWARFDebugAranges
;
1490 if (section_name
== g_sect_name_dwarf_debug_cu_index
)
1491 return eSectionTypeDWARFDebugCuIndex
;
1492 if (section_name
== g_sect_name_dwarf_debug_frame
)
1493 return eSectionTypeDWARFDebugFrame
;
1494 if (section_name
== g_sect_name_dwarf_debug_info
)
1495 return eSectionTypeDWARFDebugInfo
;
1496 if (section_name
== g_sect_name_dwarf_debug_info_dwo
)
1497 return eSectionTypeDWARFDebugInfoDwo
;
1498 if (section_name
== g_sect_name_dwarf_debug_line
)
1499 return eSectionTypeDWARFDebugLine
;
1500 if (section_name
== g_sect_name_dwarf_debug_line_dwo
)
1501 return eSectionTypeDWARFDebugLine
; // Same as debug_line.
1502 if (section_name
== g_sect_name_dwarf_debug_line_str
)
1503 return eSectionTypeDWARFDebugLineStr
;
1504 if (section_name
== g_sect_name_dwarf_debug_loc
)
1505 return eSectionTypeDWARFDebugLoc
;
1506 if (section_name
== g_sect_name_dwarf_debug_loclists
)
1507 return eSectionTypeDWARFDebugLocLists
;
1508 if (section_name
== g_sect_name_dwarf_debug_loclists_dwo
)
1509 return eSectionTypeDWARFDebugLocListsDwo
;
1510 if (section_name
== g_sect_name_dwarf_debug_macinfo
)
1511 return eSectionTypeDWARFDebugMacInfo
;
1512 if (section_name
== g_sect_name_dwarf_debug_macro
)
1513 return eSectionTypeDWARFDebugMacro
;
1514 if (section_name
== g_sect_name_dwarf_debug_macro_dwo
)
1515 return eSectionTypeDWARFDebugMacInfo
; // Same as debug_macro.
1516 if (section_name
== g_sect_name_dwarf_debug_names
)
1517 return eSectionTypeDWARFDebugNames
;
1518 if (section_name
== g_sect_name_dwarf_debug_pubnames
)
1519 return eSectionTypeDWARFDebugPubNames
;
1520 if (section_name
== g_sect_name_dwarf_debug_pubtypes
)
1521 return eSectionTypeDWARFDebugPubTypes
;
1522 if (section_name
== g_sect_name_dwarf_debug_ranges
)
1523 return eSectionTypeDWARFDebugRanges
;
1524 if (section_name
== g_sect_name_dwarf_debug_rnglists
)
1525 return eSectionTypeDWARFDebugRngLists
;
1526 if (section_name
== g_sect_name_dwarf_debug_str
)
1527 return eSectionTypeDWARFDebugStr
;
1528 if (section_name
== g_sect_name_dwarf_debug_str_dwo
)
1529 return eSectionTypeDWARFDebugStrDwo
;
1530 if (section_name
== g_sect_name_dwarf_debug_str_offs
)
1531 return eSectionTypeDWARFDebugStrOffsets
;
1532 if (section_name
== g_sect_name_dwarf_debug_str_offs_dwo
)
1533 return eSectionTypeDWARFDebugStrOffsetsDwo
;
1534 if (section_name
== g_sect_name_dwarf_debug_tu_index
)
1535 return eSectionTypeDWARFDebugTuIndex
;
1536 if (section_name
== g_sect_name_dwarf_debug_types
)
1537 return eSectionTypeDWARFDebugTypes
;
1538 if (section_name
== g_sect_name_dwarf_apple_names
)
1539 return eSectionTypeDWARFAppleNames
;
1540 if (section_name
== g_sect_name_dwarf_apple_types
)
1541 return eSectionTypeDWARFAppleTypes
;
1542 if (section_name
== g_sect_name_dwarf_apple_namespaces
)
1543 return eSectionTypeDWARFAppleNamespaces
;
1544 if (section_name
== g_sect_name_dwarf_apple_objc
)
1545 return eSectionTypeDWARFAppleObjC
;
1546 if (section_name
== g_sect_name_objc_selrefs
)
1547 return eSectionTypeDataCStringPointers
;
1548 if (section_name
== g_sect_name_objc_msgrefs
)
1549 return eSectionTypeDataObjCMessageRefs
;
1550 if (section_name
== g_sect_name_eh_frame
)
1551 return eSectionTypeEHFrame
;
1552 if (section_name
== g_sect_name_compact_unwind
)
1553 return eSectionTypeCompactUnwind
;
1554 if (section_name
== g_sect_name_cfstring
)
1555 return eSectionTypeDataObjCCFStrings
;
1556 if (section_name
== g_sect_name_go_symtab
)
1557 return eSectionTypeGoSymtab
;
1558 if (section_name
== g_sect_name_ctf
)
1559 return eSectionTypeCTF
;
1560 if (section_name
== g_sect_name_swift_ast
)
1561 return eSectionTypeSwiftModules
;
1562 if (section_name
== g_sect_name_objc_data
||
1563 section_name
== g_sect_name_objc_classrefs
||
1564 section_name
== g_sect_name_objc_superrefs
||
1565 section_name
== g_sect_name_objc_const
||
1566 section_name
== g_sect_name_objc_classlist
) {
1567 return eSectionTypeDataPointers
;
1570 switch (mach_sect_type
) {
1571 // TODO: categorize sections by other flags for regular sections
1573 if (section_name
== g_sect_name_text
)
1574 return eSectionTypeCode
;
1575 if (section_name
== g_sect_name_data
)
1576 return eSectionTypeData
;
1577 return eSectionTypeOther
;
1579 return eSectionTypeZeroFill
;
1580 case S_CSTRING_LITERALS
: // section with only literal C strings
1581 return eSectionTypeDataCString
;
1582 case S_4BYTE_LITERALS
: // section with only 4 byte literals
1583 return eSectionTypeData4
;
1584 case S_8BYTE_LITERALS
: // section with only 8 byte literals
1585 return eSectionTypeData8
;
1586 case S_LITERAL_POINTERS
: // section with only pointers to literals
1587 return eSectionTypeDataPointers
;
1588 case S_NON_LAZY_SYMBOL_POINTERS
: // section with only non-lazy symbol pointers
1589 return eSectionTypeDataPointers
;
1590 case S_LAZY_SYMBOL_POINTERS
: // section with only lazy symbol pointers
1591 return eSectionTypeDataPointers
;
1592 case S_SYMBOL_STUBS
: // section with only symbol stubs, byte size of stub in
1593 // the reserved2 field
1594 return eSectionTypeCode
;
1595 case S_MOD_INIT_FUNC_POINTERS
: // section with only function pointers for
1597 return eSectionTypeDataPointers
;
1598 case S_MOD_TERM_FUNC_POINTERS
: // section with only function pointers for
1600 return eSectionTypeDataPointers
;
1602 return eSectionTypeOther
;
1604 return eSectionTypeZeroFill
;
1605 case S_INTERPOSING
: // section with only pairs of function pointers for
1607 return eSectionTypeCode
;
1608 case S_16BYTE_LITERALS
: // section with only 16 byte literals
1609 return eSectionTypeData16
;
1611 return eSectionTypeDebug
;
1612 case S_LAZY_DYLIB_SYMBOL_POINTERS
:
1613 return eSectionTypeDataPointers
;
1615 return eSectionTypeOther
;
1619 struct ObjectFileMachO::SegmentParsingContext
{
1620 const EncryptedFileRanges EncryptedRanges
;
1621 lldb_private::SectionList
&UnifiedList
;
1622 uint32_t NextSegmentIdx
= 0;
1623 uint32_t NextSectionIdx
= 0;
1624 bool FileAddressesChanged
= false;
1626 SegmentParsingContext(EncryptedFileRanges EncryptedRanges
,
1627 lldb_private::SectionList
&UnifiedList
)
1628 : EncryptedRanges(std::move(EncryptedRanges
)), UnifiedList(UnifiedList
) {}
1631 void ObjectFileMachO::ProcessSegmentCommand(
1632 const llvm::MachO::load_command
&load_cmd_
, lldb::offset_t offset
,
1633 uint32_t cmd_idx
, SegmentParsingContext
&context
) {
1634 llvm::MachO::segment_command_64 load_cmd
;
1635 memcpy(&load_cmd
, &load_cmd_
, sizeof(load_cmd_
));
1637 if (!m_data
.GetU8(&offset
, (uint8_t *)load_cmd
.segname
, 16))
1640 ModuleSP module_sp
= GetModule();
1641 const bool is_core
= GetType() == eTypeCoreFile
;
1642 const bool is_dsym
= (m_header
.filetype
== MH_DSYM
);
1643 bool add_section
= true;
1644 bool add_to_unified
= true;
1645 ConstString
const_segname(
1646 load_cmd
.segname
, strnlen(load_cmd
.segname
, sizeof(load_cmd
.segname
)));
1648 SectionSP
unified_section_sp(
1649 context
.UnifiedList
.FindSectionByName(const_segname
));
1650 if (is_dsym
&& unified_section_sp
) {
1651 if (const_segname
== GetSegmentNameLINKEDIT()) {
1652 // We need to keep the __LINKEDIT segment private to this object file
1654 add_to_unified
= false;
1656 // This is the dSYM file and this section has already been created by the
1657 // object file, no need to create it.
1658 add_section
= false;
1661 load_cmd
.vmaddr
= m_data
.GetAddress(&offset
);
1662 load_cmd
.vmsize
= m_data
.GetAddress(&offset
);
1663 load_cmd
.fileoff
= m_data
.GetAddress(&offset
);
1664 load_cmd
.filesize
= m_data
.GetAddress(&offset
);
1665 if (!m_data
.GetU32(&offset
, &load_cmd
.maxprot
, 4))
1668 SanitizeSegmentCommand(load_cmd
, cmd_idx
);
1670 const uint32_t segment_permissions
= GetSegmentPermissions(load_cmd
);
1671 const bool segment_is_encrypted
=
1672 (load_cmd
.flags
& SG_PROTECTED_VERSION_1
) != 0;
1674 // Use a segment ID of the segment index shifted left by 8 so they never
1675 // conflict with any of the sections.
1676 SectionSP segment_sp
;
1677 if (add_section
&& (const_segname
|| is_core
)) {
1678 segment_sp
= std::make_shared
<Section
>(
1679 module_sp
, // Module to which this section belongs
1680 this, // Object file to which this sections belongs
1681 ++context
.NextSegmentIdx
1682 << 8, // Section ID is the 1 based segment index
1683 // shifted right by 8 bits as not to collide with any of the 256
1684 // section IDs that are possible
1685 const_segname
, // Name of this section
1686 eSectionTypeContainer
, // This section is a container of other
1688 load_cmd
.vmaddr
, // File VM address == addresses as they are
1689 // found in the object file
1690 load_cmd
.vmsize
, // VM size in bytes of this section
1691 load_cmd
.fileoff
, // Offset to the data for this section in
1693 load_cmd
.filesize
, // Size in bytes of this section as found
1695 0, // Segments have no alignment information
1696 load_cmd
.flags
); // Flags for this section
1698 segment_sp
->SetIsEncrypted(segment_is_encrypted
);
1699 m_sections_up
->AddSection(segment_sp
);
1700 segment_sp
->SetPermissions(segment_permissions
);
1702 context
.UnifiedList
.AddSection(segment_sp
);
1703 } else if (unified_section_sp
) {
1704 // If this is a dSYM and the file addresses in the dSYM differ from the
1705 // file addresses in the ObjectFile, we must use the file base address for
1706 // the Section from the dSYM for the DWARF to resolve correctly.
1707 // This only happens with binaries in the shared cache in practice;
1708 // normally a mismatch like this would give a binary & dSYM that do not
1709 // match UUIDs. When a binary is included in the shared cache, its
1710 // segments are rearranged to optimize the shared cache, so its file
1711 // addresses will differ from what the ObjectFile had originally,
1712 // and what the dSYM has.
1713 if (is_dsym
&& unified_section_sp
->GetFileAddress() != load_cmd
.vmaddr
) {
1714 Log
*log
= GetLog(LLDBLog::Symbols
);
1717 "Installing dSYM's %s segment file address over ObjectFile's "
1718 "so symbol table/debug info resolves correctly for %s",
1719 const_segname
.AsCString(),
1720 module_sp
->GetFileSpec().GetFilename().AsCString());
1723 // Make sure we've parsed the symbol table from the ObjectFile before
1724 // we go around changing its Sections.
1725 module_sp
->GetObjectFile()->GetSymtab();
1726 // eh_frame would present the same problems but we parse that on a per-
1727 // function basis as-needed so it's more difficult to remove its use of
1728 // the Sections. Realistically, the environments where this code path
1729 // will be taken will not have eh_frame sections.
1731 unified_section_sp
->SetFileAddress(load_cmd
.vmaddr
);
1733 // Notify the module that the section addresses have been changed once
1734 // we're done so any file-address caches can be updated.
1735 context
.FileAddressesChanged
= true;
1737 m_sections_up
->AddSection(unified_section_sp
);
1740 llvm::MachO::section_64 sect64
;
1741 ::memset(§64
, 0, sizeof(sect64
));
1742 // Push a section into our mach sections for the section at index zero
1743 // (NO_SECT) if we don't have any mach sections yet...
1744 if (m_mach_sections
.empty())
1745 m_mach_sections
.push_back(sect64
);
1746 uint32_t segment_sect_idx
;
1747 const lldb::user_id_t first_segment_sectID
= context
.NextSectionIdx
+ 1;
1749 const uint32_t num_u32s
= load_cmd
.cmd
== LC_SEGMENT
? 7 : 8;
1750 for (segment_sect_idx
= 0; segment_sect_idx
< load_cmd
.nsects
;
1751 ++segment_sect_idx
) {
1752 if (m_data
.GetU8(&offset
, (uint8_t *)sect64
.sectname
,
1753 sizeof(sect64
.sectname
)) == nullptr)
1755 if (m_data
.GetU8(&offset
, (uint8_t *)sect64
.segname
,
1756 sizeof(sect64
.segname
)) == nullptr)
1758 sect64
.addr
= m_data
.GetAddress(&offset
);
1759 sect64
.size
= m_data
.GetAddress(&offset
);
1761 if (m_data
.GetU32(&offset
, §64
.offset
, num_u32s
) == nullptr)
1764 if (IsSharedCacheBinary() && !IsInMemory()) {
1765 sect64
.offset
= sect64
.addr
- m_text_address
;
1768 // Keep a list of mach sections around in case we need to get at data that
1769 // isn't stored in the abstracted Sections.
1770 m_mach_sections
.push_back(sect64
);
1773 ConstString
section_name(
1774 sect64
.sectname
, strnlen(sect64
.sectname
, sizeof(sect64
.sectname
)));
1775 if (!const_segname
) {
1776 // We have a segment with no name so we need to conjure up segments
1777 // that correspond to the section's segname if there isn't already such
1778 // a section. If there is such a section, we resize the section so that
1779 // it spans all sections. We also mark these sections as fake so
1780 // address matches don't hit if they land in the gaps between the child
1782 const_segname
.SetTrimmedCStringWithLength(sect64
.segname
,
1783 sizeof(sect64
.segname
));
1784 segment_sp
= context
.UnifiedList
.FindSectionByName(const_segname
);
1785 if (segment_sp
.get()) {
1786 Section
*segment
= segment_sp
.get();
1787 // Grow the section size as needed.
1788 const lldb::addr_t sect64_min_addr
= sect64
.addr
;
1789 const lldb::addr_t sect64_max_addr
= sect64_min_addr
+ sect64
.size
;
1790 const lldb::addr_t curr_seg_byte_size
= segment
->GetByteSize();
1791 const lldb::addr_t curr_seg_min_addr
= segment
->GetFileAddress();
1792 const lldb::addr_t curr_seg_max_addr
=
1793 curr_seg_min_addr
+ curr_seg_byte_size
;
1794 if (sect64_min_addr
>= curr_seg_min_addr
) {
1795 const lldb::addr_t new_seg_byte_size
=
1796 sect64_max_addr
- curr_seg_min_addr
;
1797 // Only grow the section size if needed
1798 if (new_seg_byte_size
> curr_seg_byte_size
)
1799 segment
->SetByteSize(new_seg_byte_size
);
1801 // We need to change the base address of the segment and adjust the
1802 // child section offsets for all existing children.
1803 const lldb::addr_t slide_amount
=
1804 sect64_min_addr
- curr_seg_min_addr
;
1805 segment
->Slide(slide_amount
, false);
1806 segment
->GetChildren().Slide(-slide_amount
, false);
1807 segment
->SetByteSize(curr_seg_max_addr
- sect64_min_addr
);
1810 // Grow the section size as needed.
1811 if (sect64
.offset
) {
1812 const lldb::addr_t segment_min_file_offset
=
1813 segment
->GetFileOffset();
1814 const lldb::addr_t segment_max_file_offset
=
1815 segment_min_file_offset
+ segment
->GetFileSize();
1817 const lldb::addr_t section_min_file_offset
= sect64
.offset
;
1818 const lldb::addr_t section_max_file_offset
=
1819 section_min_file_offset
+ sect64
.size
;
1820 const lldb::addr_t new_file_offset
=
1821 std::min(section_min_file_offset
, segment_min_file_offset
);
1822 const lldb::addr_t new_file_size
=
1823 std::max(section_max_file_offset
, segment_max_file_offset
) -
1825 segment
->SetFileOffset(new_file_offset
);
1826 segment
->SetFileSize(new_file_size
);
1829 // Create a fake section for the section's named segment
1830 segment_sp
= std::make_shared
<Section
>(
1831 segment_sp
, // Parent section
1832 module_sp
, // Module to which this section belongs
1833 this, // Object file to which this section belongs
1834 ++context
.NextSegmentIdx
1835 << 8, // Section ID is the 1 based segment index
1836 // shifted right by 8 bits as not to
1837 // collide with any of the 256 section IDs
1838 // that are possible
1839 const_segname
, // Name of this section
1840 eSectionTypeContainer
, // This section is a container of
1842 sect64
.addr
, // File VM address == addresses as they are
1843 // found in the object file
1844 sect64
.size
, // VM size in bytes of this section
1845 sect64
.offset
, // Offset to the data for this section in
1847 sect64
.offset
? sect64
.size
: 0, // Size in bytes of
1849 // found in the file
1851 load_cmd
.flags
); // Flags for this section
1852 segment_sp
->SetIsFake(true);
1853 segment_sp
->SetPermissions(segment_permissions
);
1854 m_sections_up
->AddSection(segment_sp
);
1856 context
.UnifiedList
.AddSection(segment_sp
);
1857 segment_sp
->SetIsEncrypted(segment_is_encrypted
);
1860 assert(segment_sp
.get());
1862 lldb::SectionType sect_type
= GetSectionType(sect64
.flags
, section_name
);
1864 SectionSP
section_sp(new Section(
1865 segment_sp
, module_sp
, this, ++context
.NextSectionIdx
, section_name
,
1866 sect_type
, sect64
.addr
- segment_sp
->GetFileAddress(), sect64
.size
,
1867 sect64
.offset
, sect64
.offset
== 0 ? 0 : sect64
.size
, sect64
.align
,
1869 // Set the section to be encrypted to match the segment
1871 bool section_is_encrypted
= false;
1872 if (!segment_is_encrypted
&& load_cmd
.filesize
!= 0)
1873 section_is_encrypted
= context
.EncryptedRanges
.FindEntryThatContains(
1874 sect64
.offset
) != nullptr;
1876 section_sp
->SetIsEncrypted(segment_is_encrypted
|| section_is_encrypted
);
1877 section_sp
->SetPermissions(segment_permissions
);
1878 segment_sp
->GetChildren().AddSection(section_sp
);
1880 if (segment_sp
->IsFake()) {
1882 const_segname
.Clear();
1886 if (segment_sp
&& is_dsym
) {
1887 if (first_segment_sectID
<= context
.NextSectionIdx
) {
1888 lldb::user_id_t sect_uid
;
1889 for (sect_uid
= first_segment_sectID
; sect_uid
<= context
.NextSectionIdx
;
1891 SectionSP
curr_section_sp(
1892 segment_sp
->GetChildren().FindSectionByID(sect_uid
));
1893 SectionSP next_section_sp
;
1894 if (sect_uid
+ 1 <= context
.NextSectionIdx
)
1896 segment_sp
->GetChildren().FindSectionByID(sect_uid
+ 1);
1898 if (curr_section_sp
.get()) {
1899 if (curr_section_sp
->GetByteSize() == 0) {
1900 if (next_section_sp
.get() != nullptr)
1901 curr_section_sp
->SetByteSize(next_section_sp
->GetFileAddress() -
1902 curr_section_sp
->GetFileAddress());
1904 curr_section_sp
->SetByteSize(load_cmd
.vmsize
);
1912 void ObjectFileMachO::ProcessDysymtabCommand(
1913 const llvm::MachO::load_command
&load_cmd
, lldb::offset_t offset
) {
1914 m_dysymtab
.cmd
= load_cmd
.cmd
;
1915 m_dysymtab
.cmdsize
= load_cmd
.cmdsize
;
1916 m_data
.GetU32(&offset
, &m_dysymtab
.ilocalsym
,
1917 (sizeof(m_dysymtab
) / sizeof(uint32_t)) - 2);
1920 void ObjectFileMachO::CreateSections(SectionList
&unified_section_list
) {
1924 m_sections_up
= std::make_unique
<SectionList
>();
1926 lldb::offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
1927 // bool dump_sections = false;
1928 ModuleSP
module_sp(GetModule());
1930 offset
= MachHeaderSizeFromMagic(m_header
.magic
);
1932 SegmentParsingContext
context(GetEncryptedFileRanges(), unified_section_list
);
1933 llvm::MachO::load_command load_cmd
;
1934 for (uint32_t i
= 0; i
< m_header
.ncmds
; ++i
) {
1935 const lldb::offset_t load_cmd_offset
= offset
;
1936 if (m_data
.GetU32(&offset
, &load_cmd
, 2) == nullptr)
1939 if (load_cmd
.cmd
== LC_SEGMENT
|| load_cmd
.cmd
== LC_SEGMENT_64
)
1940 ProcessSegmentCommand(load_cmd
, offset
, i
, context
);
1941 else if (load_cmd
.cmd
== LC_DYSYMTAB
)
1942 ProcessDysymtabCommand(load_cmd
, offset
);
1944 offset
= load_cmd_offset
+ load_cmd
.cmdsize
;
1947 if (context
.FileAddressesChanged
&& module_sp
)
1948 module_sp
->SectionFileAddressesChanged();
1951 class MachSymtabSectionInfo
{
1953 MachSymtabSectionInfo(SectionList
*section_list
)
1954 : m_section_list(section_list
), m_section_infos() {
1955 // Get the number of sections down to a depth of 1 to include all segments
1956 // and their sections, but no other sections that may be added for debug
1958 m_section_infos
.resize(section_list
->GetNumSections(1));
1961 SectionSP
GetSection(uint8_t n_sect
, addr_t file_addr
) {
1964 if (n_sect
< m_section_infos
.size()) {
1965 if (!m_section_infos
[n_sect
].section_sp
) {
1966 SectionSP
section_sp(m_section_list
->FindSectionByID(n_sect
));
1967 m_section_infos
[n_sect
].section_sp
= section_sp
;
1969 m_section_infos
[n_sect
].vm_range
.SetBaseAddress(
1970 section_sp
->GetFileAddress());
1971 m_section_infos
[n_sect
].vm_range
.SetByteSize(
1972 section_sp
->GetByteSize());
1974 std::string filename
= "<unknown>";
1975 SectionSP
first_section_sp(m_section_list
->GetSectionAtIndex(0));
1976 if (first_section_sp
)
1977 filename
= first_section_sp
->GetObjectFile()->GetFileSpec().GetPath();
1979 Debugger::ReportError(
1980 llvm::formatv("unable to find section {0} for a symbol in "
1981 "{1}, corrupt file?",
1985 if (m_section_infos
[n_sect
].vm_range
.Contains(file_addr
)) {
1986 // Symbol is in section.
1987 return m_section_infos
[n_sect
].section_sp
;
1988 } else if (m_section_infos
[n_sect
].vm_range
.GetByteSize() == 0 &&
1989 m_section_infos
[n_sect
].vm_range
.GetBaseAddress() ==
1991 // Symbol is in section with zero size, but has the same start address
1992 // as the section. This can happen with linker symbols (symbols that
1993 // start with the letter 'l' or 'L'.
1994 return m_section_infos
[n_sect
].section_sp
;
1997 return m_section_list
->FindSectionContainingFileAddress(file_addr
);
2001 struct SectionInfo
{
2002 SectionInfo() : vm_range(), section_sp() {}
2005 SectionSP section_sp
;
2007 SectionList
*m_section_list
;
2008 std::vector
<SectionInfo
> m_section_infos
;
2011 #define TRIE_SYMBOL_IS_THUMB (1ULL << 63)
2014 printf("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
2015 static_cast<unsigned long long>(address
),
2016 static_cast<unsigned long long>(flags
),
2017 static_cast<unsigned long long>(other
), name
.GetCString());
2019 printf(" -> \"%s\"\n", import_name
.GetCString());
2024 uint64_t address
= LLDB_INVALID_ADDRESS
;
2026 0; // EXPORT_SYMBOL_FLAGS_REEXPORT, EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER,
2027 // TRIE_SYMBOL_IS_THUMB
2029 ConstString import_name
;
2032 struct TrieEntryWithOffset
{
2033 lldb::offset_t nodeOffset
;
2036 TrieEntryWithOffset(lldb::offset_t offset
) : nodeOffset(offset
), entry() {}
2038 void Dump(uint32_t idx
) const {
2039 printf("[%3u] 0x%16.16llx: ", idx
,
2040 static_cast<unsigned long long>(nodeOffset
));
2044 bool operator<(const TrieEntryWithOffset
&other
) const {
2045 return (nodeOffset
< other
.nodeOffset
);
2049 static bool ParseTrieEntries(DataExtractor
&data
, lldb::offset_t offset
,
2050 const bool is_arm
, addr_t text_seg_base_addr
,
2051 std::vector
<llvm::StringRef
> &nameSlices
,
2052 std::set
<lldb::addr_t
> &resolver_addresses
,
2053 std::vector
<TrieEntryWithOffset
> &reexports
,
2054 std::vector
<TrieEntryWithOffset
> &ext_symbols
) {
2055 if (!data
.ValidOffset(offset
))
2058 // Terminal node -- end of a branch, possibly add this to
2059 // the symbol table or resolver table.
2060 const uint64_t terminalSize
= data
.GetULEB128(&offset
);
2061 lldb::offset_t children_offset
= offset
+ terminalSize
;
2062 if (terminalSize
!= 0) {
2063 TrieEntryWithOffset
e(offset
);
2064 e
.entry
.flags
= data
.GetULEB128(&offset
);
2065 const char *import_name
= nullptr;
2066 if (e
.entry
.flags
& EXPORT_SYMBOL_FLAGS_REEXPORT
) {
2067 e
.entry
.address
= 0;
2068 e
.entry
.other
= data
.GetULEB128(&offset
); // dylib ordinal
2069 import_name
= data
.GetCStr(&offset
);
2071 e
.entry
.address
= data
.GetULEB128(&offset
);
2072 if (text_seg_base_addr
!= LLDB_INVALID_ADDRESS
)
2073 e
.entry
.address
+= text_seg_base_addr
;
2074 if (e
.entry
.flags
& EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER
) {
2075 e
.entry
.other
= data
.GetULEB128(&offset
);
2076 uint64_t resolver_addr
= e
.entry
.other
;
2077 if (text_seg_base_addr
!= LLDB_INVALID_ADDRESS
)
2078 resolver_addr
+= text_seg_base_addr
;
2080 resolver_addr
&= THUMB_ADDRESS_BIT_MASK
;
2081 resolver_addresses
.insert(resolver_addr
);
2085 bool add_this_entry
= false;
2086 if (Flags(e
.entry
.flags
).Test(EXPORT_SYMBOL_FLAGS_REEXPORT
) &&
2087 import_name
&& import_name
[0]) {
2088 // add symbols that are reexport symbols with a valid import name.
2089 add_this_entry
= true;
2090 } else if (e
.entry
.flags
== 0 &&
2091 (import_name
== nullptr || import_name
[0] == '\0')) {
2092 // add externally visible symbols, in case the nlist record has
2093 // been stripped/omitted.
2094 add_this_entry
= true;
2096 if (add_this_entry
) {
2098 if (!nameSlices
.empty()) {
2099 for (auto name_slice
: nameSlices
)
2100 name
.append(name_slice
.data(), name_slice
.size());
2102 if (name
.size() > 1) {
2103 // Skip the leading '_'
2104 e
.entry
.name
.SetCStringWithLength(name
.c_str() + 1, name
.size() - 1);
2107 // Skip the leading '_'
2108 e
.entry
.import_name
.SetCString(import_name
+ 1);
2110 if (Flags(e
.entry
.flags
).Test(EXPORT_SYMBOL_FLAGS_REEXPORT
)) {
2111 reexports
.push_back(e
);
2113 if (is_arm
&& (e
.entry
.address
& 1)) {
2114 e
.entry
.flags
|= TRIE_SYMBOL_IS_THUMB
;
2115 e
.entry
.address
&= THUMB_ADDRESS_BIT_MASK
;
2117 ext_symbols
.push_back(e
);
2122 const uint8_t childrenCount
= data
.GetU8(&children_offset
);
2123 for (uint8_t i
= 0; i
< childrenCount
; ++i
) {
2124 const char *cstr
= data
.GetCStr(&children_offset
);
2126 nameSlices
.push_back(llvm::StringRef(cstr
));
2128 return false; // Corrupt data
2129 lldb::offset_t childNodeOffset
= data
.GetULEB128(&children_offset
);
2130 if (childNodeOffset
) {
2131 if (!ParseTrieEntries(data
, childNodeOffset
, is_arm
, text_seg_base_addr
,
2132 nameSlices
, resolver_addresses
, reexports
,
2137 nameSlices
.pop_back();
2142 static SymbolType
GetSymbolType(const char *&symbol_name
,
2143 bool &demangled_is_synthesized
,
2144 const SectionSP
&text_section_sp
,
2145 const SectionSP
&data_section_sp
,
2146 const SectionSP
&data_dirty_section_sp
,
2147 const SectionSP
&data_const_section_sp
,
2148 const SectionSP
&symbol_section
) {
2149 SymbolType type
= eSymbolTypeInvalid
;
2151 const char *symbol_sect_name
= symbol_section
->GetName().AsCString();
2152 if (symbol_section
->IsDescendant(text_section_sp
.get())) {
2153 if (symbol_section
->IsClear(S_ATTR_PURE_INSTRUCTIONS
|
2154 S_ATTR_SELF_MODIFYING_CODE
|
2155 S_ATTR_SOME_INSTRUCTIONS
))
2156 type
= eSymbolTypeData
;
2158 type
= eSymbolTypeCode
;
2159 } else if (symbol_section
->IsDescendant(data_section_sp
.get()) ||
2160 symbol_section
->IsDescendant(data_dirty_section_sp
.get()) ||
2161 symbol_section
->IsDescendant(data_const_section_sp
.get())) {
2162 if (symbol_sect_name
&&
2163 ::strstr(symbol_sect_name
, "__objc") == symbol_sect_name
) {
2164 type
= eSymbolTypeRuntime
;
2167 llvm::StringRef
symbol_name_ref(symbol_name
);
2168 if (symbol_name_ref
.startswith("OBJC_")) {
2169 static const llvm::StringRef
g_objc_v2_prefix_class("OBJC_CLASS_$_");
2170 static const llvm::StringRef
g_objc_v2_prefix_metaclass(
2171 "OBJC_METACLASS_$_");
2172 static const llvm::StringRef
g_objc_v2_prefix_ivar("OBJC_IVAR_$_");
2173 if (symbol_name_ref
.startswith(g_objc_v2_prefix_class
)) {
2174 symbol_name
= symbol_name
+ g_objc_v2_prefix_class
.size();
2175 type
= eSymbolTypeObjCClass
;
2176 demangled_is_synthesized
= true;
2177 } else if (symbol_name_ref
.startswith(g_objc_v2_prefix_metaclass
)) {
2178 symbol_name
= symbol_name
+ g_objc_v2_prefix_metaclass
.size();
2179 type
= eSymbolTypeObjCMetaClass
;
2180 demangled_is_synthesized
= true;
2181 } else if (symbol_name_ref
.startswith(g_objc_v2_prefix_ivar
)) {
2182 symbol_name
= symbol_name
+ g_objc_v2_prefix_ivar
.size();
2183 type
= eSymbolTypeObjCIVar
;
2184 demangled_is_synthesized
= true;
2188 } else if (symbol_sect_name
&&
2189 ::strstr(symbol_sect_name
, "__gcc_except_tab") ==
2191 type
= eSymbolTypeException
;
2193 type
= eSymbolTypeData
;
2195 } else if (symbol_sect_name
&&
2196 ::strstr(symbol_sect_name
, "__IMPORT") == symbol_sect_name
) {
2197 type
= eSymbolTypeTrampoline
;
2202 static std::optional
<struct nlist_64
>
2203 ParseNList(DataExtractor
&nlist_data
, lldb::offset_t
&nlist_data_offset
,
2204 size_t nlist_byte_size
) {
2205 struct nlist_64 nlist
;
2206 if (!nlist_data
.ValidOffsetForDataOfSize(nlist_data_offset
, nlist_byte_size
))
2208 nlist
.n_strx
= nlist_data
.GetU32_unchecked(&nlist_data_offset
);
2209 nlist
.n_type
= nlist_data
.GetU8_unchecked(&nlist_data_offset
);
2210 nlist
.n_sect
= nlist_data
.GetU8_unchecked(&nlist_data_offset
);
2211 nlist
.n_desc
= nlist_data
.GetU16_unchecked(&nlist_data_offset
);
2212 nlist
.n_value
= nlist_data
.GetAddress_unchecked(&nlist_data_offset
);
2216 enum { DebugSymbols
= true, NonDebugSymbols
= false };
2218 void ObjectFileMachO::ParseSymtab(Symtab
&symtab
) {
2219 ModuleSP
module_sp(GetModule());
2223 Log
*log
= GetLog(LLDBLog::Symbols
);
2225 const FileSpec
&file
= m_file
? m_file
: module_sp
->GetFileSpec();
2226 const char *file_name
= file
.GetFilename().AsCString("<Unknown>");
2227 LLDB_SCOPED_TIMERF("ObjectFileMachO::ParseSymtab () module = %s", file_name
);
2228 LLDB_LOG(log
, "Parsing symbol table for {0}", file_name
);
2229 Progress
progress(llvm::formatv("Parsing symbol table for {0}", file_name
));
2231 llvm::MachO::symtab_command symtab_load_command
= {0, 0, 0, 0, 0, 0};
2232 llvm::MachO::linkedit_data_command function_starts_load_command
= {0, 0, 0, 0};
2233 llvm::MachO::linkedit_data_command exports_trie_load_command
= {0, 0, 0, 0};
2234 llvm::MachO::dyld_info_command dyld_info
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2235 llvm::MachO::dysymtab_command dysymtab
= m_dysymtab
;
2236 // The data element of type bool indicates that this entry is thumb
2238 typedef AddressDataArray
<lldb::addr_t
, bool, 100> FunctionStarts
;
2240 // Record the address of every function/data that we add to the symtab.
2241 // We add symbols to the table in the order of most information (nlist
2242 // records) to least (function starts), and avoid duplicating symbols
2244 llvm::DenseSet
<addr_t
> symbols_added
;
2246 // We are using a llvm::DenseSet for "symbols_added" so we must be sure we
2247 // do not add the tombstone or empty keys to the set.
2248 auto add_symbol_addr
= [&symbols_added
](lldb::addr_t file_addr
) {
2249 // Don't add the tombstone or empty keys.
2250 if (file_addr
== UINT64_MAX
|| file_addr
== UINT64_MAX
- 1)
2252 symbols_added
.insert(file_addr
);
2254 FunctionStarts function_starts
;
2255 lldb::offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
2257 FileSpecList dylib_files
;
2258 llvm::StringRef
g_objc_v2_prefix_class("_OBJC_CLASS_$_");
2259 llvm::StringRef
g_objc_v2_prefix_metaclass("_OBJC_METACLASS_$_");
2260 llvm::StringRef
g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
2263 for (i
= 0; i
< m_header
.ncmds
; ++i
) {
2264 const lldb::offset_t cmd_offset
= offset
;
2265 // Read in the load command and load command size
2266 llvm::MachO::load_command lc
;
2267 if (m_data
.GetU32(&offset
, &lc
, 2) == nullptr)
2269 // Watch for the symbol table load command
2272 symtab_load_command
.cmd
= lc
.cmd
;
2273 symtab_load_command
.cmdsize
= lc
.cmdsize
;
2274 // Read in the rest of the symtab load command
2275 if (m_data
.GetU32(&offset
, &symtab_load_command
.symoff
, 4) ==
2276 nullptr) // fill in symoff, nsyms, stroff, strsize fields
2281 case LC_DYLD_INFO_ONLY
:
2282 if (m_data
.GetU32(&offset
, &dyld_info
.rebase_off
, 10)) {
2283 dyld_info
.cmd
= lc
.cmd
;
2284 dyld_info
.cmdsize
= lc
.cmdsize
;
2286 memset(&dyld_info
, 0, sizeof(dyld_info
));
2291 case LC_LOAD_WEAK_DYLIB
:
2292 case LC_REEXPORT_DYLIB
:
2294 case LC_LOAD_UPWARD_DYLIB
: {
2295 uint32_t name_offset
= cmd_offset
+ m_data
.GetU32(&offset
);
2296 const char *path
= m_data
.PeekCStr(name_offset
);
2298 FileSpec
file_spec(path
);
2299 // Strip the path if there is @rpath, @executable, etc so we just use
2302 file_spec
.ClearDirectory();
2304 if (lc
.cmd
== LC_REEXPORT_DYLIB
) {
2305 m_reexported_dylibs
.AppendIfUnique(file_spec
);
2308 dylib_files
.Append(file_spec
);
2312 case LC_DYLD_EXPORTS_TRIE
:
2313 exports_trie_load_command
.cmd
= lc
.cmd
;
2314 exports_trie_load_command
.cmdsize
= lc
.cmdsize
;
2315 if (m_data
.GetU32(&offset
, &exports_trie_load_command
.dataoff
, 2) ==
2316 nullptr) // fill in offset and size fields
2317 memset(&exports_trie_load_command
, 0,
2318 sizeof(exports_trie_load_command
));
2320 case LC_FUNCTION_STARTS
:
2321 function_starts_load_command
.cmd
= lc
.cmd
;
2322 function_starts_load_command
.cmdsize
= lc
.cmdsize
;
2323 if (m_data
.GetU32(&offset
, &function_starts_load_command
.dataoff
, 2) ==
2324 nullptr) // fill in data offset and size fields
2325 memset(&function_starts_load_command
, 0,
2326 sizeof(function_starts_load_command
));
2330 const uint8_t *uuid_bytes
= m_data
.PeekData(offset
, 16);
2333 image_uuid
= UUID(uuid_bytes
, 16);
2340 offset
= cmd_offset
+ lc
.cmdsize
;
2343 if (!symtab_load_command
.cmd
)
2346 SectionList
*section_list
= GetSectionList();
2347 if (section_list
== nullptr)
2350 const uint32_t addr_byte_size
= m_data
.GetAddressByteSize();
2351 const ByteOrder byte_order
= m_data
.GetByteOrder();
2352 bool bit_width_32
= addr_byte_size
== 4;
2353 const size_t nlist_byte_size
=
2354 bit_width_32
? sizeof(struct nlist
) : sizeof(struct nlist_64
);
2356 DataExtractor
nlist_data(nullptr, 0, byte_order
, addr_byte_size
);
2357 DataExtractor
strtab_data(nullptr, 0, byte_order
, addr_byte_size
);
2358 DataExtractor
function_starts_data(nullptr, 0, byte_order
, addr_byte_size
);
2359 DataExtractor
indirect_symbol_index_data(nullptr, 0, byte_order
,
2361 DataExtractor
dyld_trie_data(nullptr, 0, byte_order
, addr_byte_size
);
2363 const addr_t nlist_data_byte_size
=
2364 symtab_load_command
.nsyms
* nlist_byte_size
;
2365 const addr_t strtab_data_byte_size
= symtab_load_command
.strsize
;
2366 addr_t strtab_addr
= LLDB_INVALID_ADDRESS
;
2368 ProcessSP
process_sp(m_process_wp
.lock());
2369 Process
*process
= process_sp
.get();
2371 uint32_t memory_module_load_level
= eMemoryModuleLoadLevelComplete
;
2372 bool is_shared_cache_image
= IsSharedCacheBinary();
2373 bool is_local_shared_cache_image
= is_shared_cache_image
&& !IsInMemory();
2374 SectionSP
linkedit_section_sp(
2375 section_list
->FindSectionByName(GetSegmentNameLINKEDIT()));
2377 if (process
&& m_header
.filetype
!= llvm::MachO::MH_OBJECT
&&
2378 !is_local_shared_cache_image
) {
2379 Target
&target
= process
->GetTarget();
2381 memory_module_load_level
= target
.GetMemoryModuleLoadLevel();
2383 // Reading mach file from memory in a process or core file...
2385 if (linkedit_section_sp
) {
2386 addr_t linkedit_load_addr
=
2387 linkedit_section_sp
->GetLoadBaseAddress(&target
);
2388 if (linkedit_load_addr
== LLDB_INVALID_ADDRESS
) {
2389 // We might be trying to access the symbol table before the
2390 // __LINKEDIT's load address has been set in the target. We can't
2391 // fail to read the symbol table, so calculate the right address
2393 linkedit_load_addr
= CalculateSectionLoadAddressForMemoryImage(
2394 m_memory_addr
, GetMachHeaderSection(), linkedit_section_sp
.get());
2397 const addr_t linkedit_file_offset
= linkedit_section_sp
->GetFileOffset();
2398 const addr_t symoff_addr
= linkedit_load_addr
+
2399 symtab_load_command
.symoff
-
2400 linkedit_file_offset
;
2401 strtab_addr
= linkedit_load_addr
+ symtab_load_command
.stroff
-
2402 linkedit_file_offset
;
2404 // Always load dyld - the dynamic linker - from memory if we didn't
2405 // find a binary anywhere else. lldb will not register
2406 // dylib/framework/bundle loads/unloads if we don't have the dyld
2407 // symbols, we force dyld to load from memory despite the user's
2408 // target.memory-module-load-level setting.
2409 if (memory_module_load_level
== eMemoryModuleLoadLevelComplete
||
2410 m_header
.filetype
== llvm::MachO::MH_DYLINKER
) {
2411 DataBufferSP
nlist_data_sp(
2412 ReadMemory(process_sp
, symoff_addr
, nlist_data_byte_size
));
2414 nlist_data
.SetData(nlist_data_sp
, 0, nlist_data_sp
->GetByteSize());
2415 if (dysymtab
.nindirectsyms
!= 0) {
2416 const addr_t indirect_syms_addr
= linkedit_load_addr
+
2417 dysymtab
.indirectsymoff
-
2418 linkedit_file_offset
;
2419 DataBufferSP
indirect_syms_data_sp(ReadMemory(
2420 process_sp
, indirect_syms_addr
, dysymtab
.nindirectsyms
* 4));
2421 if (indirect_syms_data_sp
)
2422 indirect_symbol_index_data
.SetData(
2423 indirect_syms_data_sp
, 0,
2424 indirect_syms_data_sp
->GetByteSize());
2425 // If this binary is outside the shared cache,
2426 // cache the string table.
2427 // Binaries in the shared cache all share a giant string table,
2428 // and we can't share the string tables across multiple
2429 // ObjectFileMachO's, so we'd end up re-reading this mega-strtab
2430 // for every binary in the shared cache - it would be a big perf
2431 // problem. For binaries outside the shared cache, it's faster to
2432 // read the entire strtab at once instead of piece-by-piece as we
2433 // process the nlist records.
2434 if (!is_shared_cache_image
) {
2435 DataBufferSP
strtab_data_sp(
2436 ReadMemory(process_sp
, strtab_addr
, strtab_data_byte_size
));
2437 if (strtab_data_sp
) {
2438 strtab_data
.SetData(strtab_data_sp
, 0,
2439 strtab_data_sp
->GetByteSize());
2443 if (memory_module_load_level
>= eMemoryModuleLoadLevelPartial
) {
2444 if (function_starts_load_command
.cmd
) {
2445 const addr_t func_start_addr
=
2446 linkedit_load_addr
+ function_starts_load_command
.dataoff
-
2447 linkedit_file_offset
;
2448 DataBufferSP
func_start_data_sp(
2449 ReadMemory(process_sp
, func_start_addr
,
2450 function_starts_load_command
.datasize
));
2451 if (func_start_data_sp
)
2452 function_starts_data
.SetData(func_start_data_sp
, 0,
2453 func_start_data_sp
->GetByteSize());
2459 if (is_local_shared_cache_image
) {
2460 // The load commands in shared cache images are relative to the
2461 // beginning of the shared cache, not the library image. The
2462 // data we get handed when creating the ObjectFileMachO starts
2463 // at the beginning of a specific library and spans to the end
2464 // of the cache to be able to reach the shared LINKEDIT
2465 // segments. We need to convert the load command offsets to be
2466 // relative to the beginning of our specific image.
2467 lldb::addr_t linkedit_offset
= linkedit_section_sp
->GetFileOffset();
2468 lldb::offset_t linkedit_slide
=
2469 linkedit_offset
- m_linkedit_original_offset
;
2470 symtab_load_command
.symoff
+= linkedit_slide
;
2471 symtab_load_command
.stroff
+= linkedit_slide
;
2472 dyld_info
.export_off
+= linkedit_slide
;
2473 dysymtab
.indirectsymoff
+= linkedit_slide
;
2474 function_starts_load_command
.dataoff
+= linkedit_slide
;
2475 exports_trie_load_command
.dataoff
+= linkedit_slide
;
2478 nlist_data
.SetData(m_data
, symtab_load_command
.symoff
,
2479 nlist_data_byte_size
);
2480 strtab_data
.SetData(m_data
, symtab_load_command
.stroff
,
2481 strtab_data_byte_size
);
2483 // We shouldn't have exports data from both the LC_DYLD_INFO command
2484 // AND the LC_DYLD_EXPORTS_TRIE command in the same binary:
2485 lldbassert(!((dyld_info
.export_size
> 0)
2486 && (exports_trie_load_command
.datasize
> 0)));
2487 if (dyld_info
.export_size
> 0) {
2488 dyld_trie_data
.SetData(m_data
, dyld_info
.export_off
,
2489 dyld_info
.export_size
);
2490 } else if (exports_trie_load_command
.datasize
> 0) {
2491 dyld_trie_data
.SetData(m_data
, exports_trie_load_command
.dataoff
,
2492 exports_trie_load_command
.datasize
);
2495 if (dysymtab
.nindirectsyms
!= 0) {
2496 indirect_symbol_index_data
.SetData(m_data
, dysymtab
.indirectsymoff
,
2497 dysymtab
.nindirectsyms
* 4);
2499 if (function_starts_load_command
.cmd
) {
2500 function_starts_data
.SetData(m_data
, function_starts_load_command
.dataoff
,
2501 function_starts_load_command
.datasize
);
2505 const bool have_strtab_data
= strtab_data
.GetByteSize() > 0;
2507 ConstString g_segment_name_TEXT
= GetSegmentNameTEXT();
2508 ConstString g_segment_name_DATA
= GetSegmentNameDATA();
2509 ConstString g_segment_name_DATA_DIRTY
= GetSegmentNameDATA_DIRTY();
2510 ConstString g_segment_name_DATA_CONST
= GetSegmentNameDATA_CONST();
2511 ConstString g_segment_name_OBJC
= GetSegmentNameOBJC();
2512 ConstString g_section_name_eh_frame
= GetSectionNameEHFrame();
2513 SectionSP
text_section_sp(
2514 section_list
->FindSectionByName(g_segment_name_TEXT
));
2515 SectionSP
data_section_sp(
2516 section_list
->FindSectionByName(g_segment_name_DATA
));
2517 SectionSP
data_dirty_section_sp(
2518 section_list
->FindSectionByName(g_segment_name_DATA_DIRTY
));
2519 SectionSP
data_const_section_sp(
2520 section_list
->FindSectionByName(g_segment_name_DATA_CONST
));
2521 SectionSP
objc_section_sp(
2522 section_list
->FindSectionByName(g_segment_name_OBJC
));
2523 SectionSP eh_frame_section_sp
;
2524 if (text_section_sp
.get())
2525 eh_frame_section_sp
= text_section_sp
->GetChildren().FindSectionByName(
2526 g_section_name_eh_frame
);
2528 eh_frame_section_sp
=
2529 section_list
->FindSectionByName(g_section_name_eh_frame
);
2531 const bool is_arm
= (m_header
.cputype
== llvm::MachO::CPU_TYPE_ARM
);
2532 const bool always_thumb
= GetArchitecture().IsAlwaysThumbInstructions();
2534 // lldb works best if it knows the start address of all functions in a
2535 // module. Linker symbols or debug info are normally the best source of
2536 // information for start addr / size but they may be stripped in a released
2537 // binary. Two additional sources of information exist in Mach-O binaries:
2538 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each
2539 // function's start address in the
2540 // binary, relative to the text section.
2541 // eh_frame - the eh_frame FDEs have the start addr & size of
2543 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on
2544 // all modern binaries.
2545 // Binaries built to run on older releases may need to use eh_frame
2548 if (text_section_sp
&& function_starts_data
.GetByteSize()) {
2549 FunctionStarts::Entry function_start_entry
;
2550 function_start_entry
.data
= false;
2551 lldb::offset_t function_start_offset
= 0;
2552 function_start_entry
.addr
= text_section_sp
->GetFileAddress();
2554 while ((delta
= function_starts_data
.GetULEB128(&function_start_offset
)) >
2556 // Now append the current entry
2557 function_start_entry
.addr
+= delta
;
2559 if (function_start_entry
.addr
& 1) {
2560 function_start_entry
.addr
&= THUMB_ADDRESS_BIT_MASK
;
2561 function_start_entry
.data
= true;
2562 } else if (always_thumb
) {
2563 function_start_entry
.data
= true;
2566 function_starts
.Append(function_start_entry
);
2569 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the
2570 // load command claiming an eh_frame but it doesn't actually have the
2571 // eh_frame content. And if we have a dSYM, we don't need to do any of
2572 // this fill-in-the-missing-symbols works anyway - the debug info should
2573 // give us all the functions in the module.
2574 if (text_section_sp
.get() && eh_frame_section_sp
.get() &&
2575 m_type
!= eTypeDebugInfo
) {
2576 DWARFCallFrameInfo
eh_frame(*this, eh_frame_section_sp
,
2577 DWARFCallFrameInfo::EH
);
2578 DWARFCallFrameInfo::FunctionAddressAndSizeVector functions
;
2579 eh_frame
.GetFunctionAddressAndSizeVector(functions
);
2580 addr_t text_base_addr
= text_section_sp
->GetFileAddress();
2581 size_t count
= functions
.GetSize();
2582 for (size_t i
= 0; i
< count
; ++i
) {
2583 const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry
*func
=
2584 functions
.GetEntryAtIndex(i
);
2586 FunctionStarts::Entry function_start_entry
;
2587 function_start_entry
.addr
= func
->base
- text_base_addr
;
2589 if (function_start_entry
.addr
& 1) {
2590 function_start_entry
.addr
&= THUMB_ADDRESS_BIT_MASK
;
2591 function_start_entry
.data
= true;
2592 } else if (always_thumb
) {
2593 function_start_entry
.data
= true;
2596 function_starts
.Append(function_start_entry
);
2602 const size_t function_starts_count
= function_starts
.GetSize();
2604 // For user process binaries (executables, dylibs, frameworks, bundles), if
2605 // we don't have LC_FUNCTION_STARTS/eh_frame section in this binary, we're
2606 // going to assume the binary has been stripped. Don't allow assembly
2607 // language instruction emulation because we don't know proper function
2608 // start boundaries.
2610 // For all other types of binaries (kernels, stand-alone bare board
2611 // binaries, kexts), they may not have LC_FUNCTION_STARTS / eh_frame
2612 // sections - we should not make any assumptions about them based on that.
2613 if (function_starts_count
== 0 && CalculateStrata() == eStrataUser
) {
2614 m_allow_assembly_emulation_unwind_plans
= false;
2615 Log
*unwind_or_symbol_log(GetLog(LLDBLog::Symbols
| LLDBLog::Unwind
));
2617 if (unwind_or_symbol_log
)
2618 module_sp
->LogMessage(
2619 unwind_or_symbol_log
,
2620 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2623 const user_id_t TEXT_eh_frame_sectID
= eh_frame_section_sp
.get()
2624 ? eh_frame_section_sp
->GetID()
2625 : static_cast<user_id_t
>(NO_SECT
);
2627 uint32_t N_SO_index
= UINT32_MAX
;
2629 MachSymtabSectionInfo
section_info(section_list
);
2630 std::vector
<uint32_t> N_FUN_indexes
;
2631 std::vector
<uint32_t> N_NSYM_indexes
;
2632 std::vector
<uint32_t> N_INCL_indexes
;
2633 std::vector
<uint32_t> N_BRAC_indexes
;
2634 std::vector
<uint32_t> N_COMM_indexes
;
2635 typedef std::multimap
<uint64_t, uint32_t> ValueToSymbolIndexMap
;
2636 typedef llvm::DenseMap
<uint32_t, uint32_t> NListIndexToSymbolIndexMap
;
2637 typedef llvm::DenseMap
<const char *, uint32_t> ConstNameToSymbolIndexMap
;
2638 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx
;
2639 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx
;
2640 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx
;
2641 // Any symbols that get merged into another will get an entry in this map
2643 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx
;
2644 uint32_t nlist_idx
= 0;
2645 Symbol
*symbol_ptr
= nullptr;
2647 uint32_t sym_idx
= 0;
2648 Symbol
*sym
= nullptr;
2649 size_t num_syms
= 0;
2650 std::string memory_symbol_name
;
2651 uint32_t unmapped_local_symbols_found
= 0;
2653 std::vector
<TrieEntryWithOffset
> reexport_trie_entries
;
2654 std::vector
<TrieEntryWithOffset
> external_sym_trie_entries
;
2655 std::set
<lldb::addr_t
> resolver_addresses
;
2657 const size_t dyld_trie_data_size
= dyld_trie_data
.GetByteSize();
2658 if (dyld_trie_data_size
> 0) {
2659 LLDB_LOG(log
, "Parsing {0} bytes of dyld trie data", dyld_trie_data_size
);
2660 SectionSP text_segment_sp
=
2661 GetSectionList()->FindSectionByName(GetSegmentNameTEXT());
2662 lldb::addr_t text_segment_file_addr
= LLDB_INVALID_ADDRESS
;
2663 if (text_segment_sp
)
2664 text_segment_file_addr
= text_segment_sp
->GetFileAddress();
2665 std::vector
<llvm::StringRef
> nameSlices
;
2666 ParseTrieEntries(dyld_trie_data
, 0, is_arm
, text_segment_file_addr
,
2667 nameSlices
, resolver_addresses
, reexport_trie_entries
,
2668 external_sym_trie_entries
);
2671 typedef std::set
<ConstString
> IndirectSymbols
;
2672 IndirectSymbols indirect_symbol_names
;
2674 #if TARGET_OS_IPHONE
2676 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been
2677 // optimized by moving LOCAL symbols out of the memory mapped portion of
2678 // the DSC. The symbol information has all been retained, but it isn't
2679 // available in the normal nlist data. However, there *are* duplicate
2680 // entries of *some*
2681 // LOCAL symbols in the normal nlist data. To handle this situation
2682 // correctly, we must first attempt
2683 // to parse any DSC unmapped symbol information. If we find any, we set a
2684 // flag that tells the normal nlist parser to ignore all LOCAL symbols.
2686 if (IsSharedCacheBinary()) {
2687 // Before we can start mapping the DSC, we need to make certain the
2688 // target process is actually using the cache we can find.
2690 // Next we need to determine the correct path for the dyld shared cache.
2692 ArchSpec header_arch
= GetArchitecture();
2695 UUID process_shared_cache_uuid
;
2696 addr_t process_shared_cache_base_addr
;
2699 GetProcessSharedCacheUUID(process
, process_shared_cache_base_addr
,
2700 process_shared_cache_uuid
);
2703 __block
bool found_image
= false;
2704 __block
void *nlist_buffer
= nullptr;
2705 __block
unsigned nlist_count
= 0;
2706 __block
char *string_table
= nullptr;
2707 __block vm_offset_t vm_nlist_memory
= 0;
2708 __block mach_msg_type_number_t vm_nlist_bytes_read
= 0;
2709 __block vm_offset_t vm_string_memory
= 0;
2710 __block mach_msg_type_number_t vm_string_bytes_read
= 0;
2712 auto _
= llvm::make_scope_exit(^{
2713 if (vm_nlist_memory
)
2714 vm_deallocate(mach_task_self(), vm_nlist_memory
, vm_nlist_bytes_read
);
2715 if (vm_string_memory
)
2716 vm_deallocate(mach_task_self(), vm_string_memory
, vm_string_bytes_read
);
2719 typedef llvm::DenseMap
<ConstString
, uint16_t> UndefinedNameToDescMap
;
2720 typedef llvm::DenseMap
<uint32_t, ConstString
> SymbolIndexToName
;
2721 UndefinedNameToDescMap undefined_name_to_desc
;
2722 SymbolIndexToName reexport_shlib_needs_fixup
;
2724 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache
) {
2726 dyld_shared_cache_copy_uuid(shared_cache
, &cache_uuid
);
2730 if (process_shared_cache_uuid
.IsValid() &&
2731 process_shared_cache_uuid
!= UUID::fromData(&cache_uuid
, 16))
2734 dyld_shared_cache_for_each_image(shared_cache
, ^(dyld_image_t image
) {
2735 uuid_t dsc_image_uuid
;
2739 dyld_image_copy_uuid(image
, &dsc_image_uuid
);
2740 if (image_uuid
!= UUID::fromData(dsc_image_uuid
, 16))
2745 // Compute the size of the string table. We need to ask dyld for a
2746 // new SPI to avoid this step.
2747 dyld_image_local_nlist_content_4Symbolication(
2748 image
, ^(const void *nlistStart
, uint64_t nlistCount
,
2749 const char *stringTable
) {
2750 if (!nlistStart
|| !nlistCount
)
2753 // The buffers passed here are valid only inside the block.
2754 // Use vm_read to make a cheap copy of them available for our
2755 // processing later.
2757 vm_read(mach_task_self(), (vm_address_t
)nlistStart
,
2758 nlist_byte_size
* nlistCount
, &vm_nlist_memory
,
2759 &vm_nlist_bytes_read
);
2760 if (ret
!= KERN_SUCCESS
)
2762 assert(vm_nlist_bytes_read
== nlist_byte_size
* nlistCount
);
2764 // We don't know the size of the string table. It's cheaper
2765 // to map the whole VM region than to determine the size by
2766 // parsing all the nlist entries.
2767 vm_address_t string_address
= (vm_address_t
)stringTable
;
2768 vm_size_t region_size
;
2769 mach_msg_type_number_t info_count
= VM_REGION_BASIC_INFO_COUNT_64
;
2770 vm_region_basic_info_data_t info
;
2771 memory_object_name_t object
;
2772 ret
= vm_region_64(mach_task_self(), &string_address
,
2773 ®ion_size
, VM_REGION_BASIC_INFO_64
,
2774 (vm_region_info_t
)&info
, &info_count
, &object
);
2775 if (ret
!= KERN_SUCCESS
)
2778 ret
= vm_read(mach_task_self(), (vm_address_t
)stringTable
,
2780 ((vm_address_t
)stringTable
- string_address
),
2781 &vm_string_memory
, &vm_string_bytes_read
);
2782 if (ret
!= KERN_SUCCESS
)
2785 nlist_buffer
= (void *)vm_nlist_memory
;
2786 string_table
= (char *)vm_string_memory
;
2787 nlist_count
= nlistCount
;
2792 DataExtractor
dsc_local_symbols_data(nlist_buffer
,
2793 nlist_count
* nlist_byte_size
,
2794 byte_order
, addr_byte_size
);
2795 unmapped_local_symbols_found
= nlist_count
;
2797 // The normal nlist code cannot correctly size the Symbols
2798 // array, we need to allocate it here.
2799 sym
= symtab
.Resize(
2800 symtab_load_command
.nsyms
+ m_dysymtab
.nindirectsyms
+
2801 unmapped_local_symbols_found
- m_dysymtab
.nlocalsym
);
2802 num_syms
= symtab
.GetNumSymbols();
2804 lldb::offset_t nlist_data_offset
= 0;
2806 for (uint32_t nlist_index
= 0;
2807 nlist_index
< nlist_count
;
2809 /////////////////////////////
2811 std::optional
<struct nlist_64
> nlist_maybe
=
2812 ParseNList(dsc_local_symbols_data
, nlist_data_offset
,
2816 struct nlist_64 nlist
= *nlist_maybe
;
2818 SymbolType type
= eSymbolTypeInvalid
;
2819 const char *symbol_name
= string_table
+ nlist
.n_strx
;
2821 if (symbol_name
== NULL
) {
2822 // No symbol should be NULL, even the symbols with no
2823 // string values should have an offset zero which
2824 // points to an empty C-string
2825 Debugger::ReportError(llvm::formatv(
2826 "DSC unmapped local symbol[{0}] has invalid "
2827 "string table offset {1:x} in {2}, ignoring symbol",
2828 nlist_index
, nlist
.n_strx
,
2829 module_sp
->GetFileSpec().GetPath());
2832 if (symbol_name
[0] == '\0')
2835 const char *symbol_name_non_abi_mangled
= NULL
;
2837 SectionSP symbol_section
;
2838 uint32_t symbol_byte_size
= 0;
2839 bool add_nlist
= true;
2840 bool is_debug
= ((nlist
.n_type
& N_STAB
) != 0);
2841 bool demangled_is_synthesized
= false;
2842 bool is_gsym
= false;
2843 bool set_value
= true;
2845 assert(sym_idx
< num_syms
);
2847 sym
[sym_idx
].SetDebug(is_debug
);
2850 switch (nlist
.n_type
) {
2852 // global symbol: name,,NO_SECT,type,0
2853 // Sometimes the N_GSYM value contains the address.
2855 // FIXME: In the .o files, we have a GSYM and a debug
2856 // symbol for all the ObjC data. They
2857 // have the same address, but we want to ensure that
2858 // we always find only the real symbol, 'cause we
2859 // don't currently correctly attribute the
2860 // GSYM one to the ObjCClass/Ivar/MetaClass
2861 // symbol type. This is a temporary hack to make
2862 // sure the ObjectiveC symbols get treated correctly.
2863 // To do this right, we should coalesce all the GSYM
2864 // & global symbols that have the same address.
2867 sym
[sym_idx
].SetExternal(true);
2869 if (symbol_name
&& symbol_name
[0] == '_' &&
2870 symbol_name
[1] == 'O') {
2871 llvm::StringRef
symbol_name_ref(symbol_name
);
2872 if (symbol_name_ref
.startswith(
2873 g_objc_v2_prefix_class
)) {
2874 symbol_name_non_abi_mangled
= symbol_name
+ 1;
2876 symbol_name
+ g_objc_v2_prefix_class
.size();
2877 type
= eSymbolTypeObjCClass
;
2878 demangled_is_synthesized
= true;
2880 } else if (symbol_name_ref
.startswith(
2881 g_objc_v2_prefix_metaclass
)) {
2882 symbol_name_non_abi_mangled
= symbol_name
+ 1;
2884 symbol_name
+ g_objc_v2_prefix_metaclass
.size();
2885 type
= eSymbolTypeObjCMetaClass
;
2886 demangled_is_synthesized
= true;
2887 } else if (symbol_name_ref
.startswith(
2888 g_objc_v2_prefix_ivar
)) {
2889 symbol_name_non_abi_mangled
= symbol_name
+ 1;
2891 symbol_name
+ g_objc_v2_prefix_ivar
.size();
2892 type
= eSymbolTypeObjCIVar
;
2893 demangled_is_synthesized
= true;
2896 if (nlist
.n_value
!= 0)
2897 symbol_section
= section_info
.GetSection(
2898 nlist
.n_sect
, nlist
.n_value
);
2899 type
= eSymbolTypeData
;
2904 // procedure name (f77 kludge): name,,NO_SECT,0,0
2905 type
= eSymbolTypeCompiler
;
2909 // procedure: name,,n_sect,linenumber,address
2911 type
= eSymbolTypeCode
;
2912 symbol_section
= section_info
.GetSection(
2913 nlist
.n_sect
, nlist
.n_value
);
2915 N_FUN_addr_to_sym_idx
.insert(
2916 std::make_pair(nlist
.n_value
, sym_idx
));
2917 // We use the current number of symbols in the
2918 // symbol table in lieu of using nlist_idx in case
2919 // we ever start trimming entries out
2920 N_FUN_indexes
.push_back(sym_idx
);
2922 type
= eSymbolTypeCompiler
;
2924 if (!N_FUN_indexes
.empty()) {
2925 // Copy the size of the function into the
2927 // STAB entry so we don't have
2928 // to hunt for it later
2929 symtab
.SymbolAtIndex(N_FUN_indexes
.back())
2930 ->SetByteSize(nlist
.n_value
);
2931 N_FUN_indexes
.pop_back();
2932 // We don't really need the end function STAB as
2933 // it contains the size which we already placed
2934 // with the original symbol, so don't add it if
2935 // we want a minimal symbol table
2942 // static symbol: name,,n_sect,type,address
2943 N_STSYM_addr_to_sym_idx
.insert(
2944 std::make_pair(nlist
.n_value
, sym_idx
));
2945 symbol_section
= section_info
.GetSection(nlist
.n_sect
,
2947 if (symbol_name
&& symbol_name
[0]) {
2948 type
= ObjectFile::GetSymbolTypeFromName(
2949 symbol_name
+ 1, eSymbolTypeData
);
2954 // .lcomm symbol: name,,n_sect,type,address
2955 symbol_section
= section_info
.GetSection(nlist
.n_sect
,
2957 type
= eSymbolTypeCommonBlock
;
2961 // We use the current number of symbols in the symbol
2962 // table in lieu of using nlist_idx in case we ever
2963 // start trimming entries out Skip these if we want
2964 // minimal symbol tables
2969 // Set the size of the N_BNSYM to the terminating
2970 // index of this N_ENSYM so that we can always skip
2971 // the entire symbol if we need to navigate more
2972 // quickly at the source level when parsing STABS
2973 // Skip these if we want minimal symbol tables
2978 // emitted with gcc2_compiled and in gcc source
2979 type
= eSymbolTypeCompiler
;
2983 // register sym: name,,NO_SECT,type,register
2984 type
= eSymbolTypeVariable
;
2988 // src line: 0,,n_sect,linenumber,address
2989 symbol_section
= section_info
.GetSection(nlist
.n_sect
,
2991 type
= eSymbolTypeLineEntry
;
2995 // structure elt: name,,NO_SECT,type,struct_offset
2996 type
= eSymbolTypeVariableType
;
3001 type
= eSymbolTypeSourceFile
;
3002 if (symbol_name
== NULL
) {
3004 if (N_SO_index
!= UINT32_MAX
) {
3005 // Set the size of the N_SO to the terminating
3006 // index of this N_SO so that we can always skip
3007 // the entire N_SO if we need to navigate more
3008 // quickly at the source level when parsing STABS
3009 symbol_ptr
= symtab
.SymbolAtIndex(N_SO_index
);
3010 symbol_ptr
->SetByteSize(sym_idx
);
3011 symbol_ptr
->SetSizeIsSibling(true);
3013 N_NSYM_indexes
.clear();
3014 N_INCL_indexes
.clear();
3015 N_BRAC_indexes
.clear();
3016 N_COMM_indexes
.clear();
3017 N_FUN_indexes
.clear();
3018 N_SO_index
= UINT32_MAX
;
3020 // We use the current number of symbols in the
3021 // symbol table in lieu of using nlist_idx in case
3022 // we ever start trimming entries out
3023 const bool N_SO_has_full_path
= symbol_name
[0] == '/';
3024 if (N_SO_has_full_path
) {
3025 if ((N_SO_index
== sym_idx
- 1) &&
3026 ((sym_idx
- 1) < num_syms
)) {
3027 // We have two consecutive N_SO entries where
3028 // the first contains a directory and the
3029 // second contains a full path.
3030 sym
[sym_idx
- 1].GetMangled().SetValue(
3031 ConstString(symbol_name
));
3032 m_nlist_idx_to_sym_idx
[nlist_idx
] = sym_idx
- 1;
3035 // This is the first entry in a N_SO that
3036 // contains a directory or
3037 // a full path to the source file
3038 N_SO_index
= sym_idx
;
3040 } else if ((N_SO_index
== sym_idx
- 1) &&
3041 ((sym_idx
- 1) < num_syms
)) {
3042 // This is usually the second N_SO entry that
3043 // contains just the filename, so here we combine
3044 // it with the first one if we are minimizing the
3046 const char *so_path
= sym
[sym_idx
- 1]
3050 if (so_path
&& so_path
[0]) {
3051 std::string
full_so_path(so_path
);
3052 const size_t double_slash_pos
=
3053 full_so_path
.find("//");
3054 if (double_slash_pos
!= std::string::npos
) {
3055 // The linker has been generating bad N_SO
3056 // entries with doubled up paths
3057 // in the format "%s%s" where the first
3058 // string in the DW_AT_comp_dir, and the
3059 // second is the directory for the source
3060 // file so you end up with a path that looks
3061 // like "/tmp/src//tmp/src/"
3062 FileSpec
so_dir(so_path
);
3063 if (!FileSystem::Instance().Exists(so_dir
)) {
3065 &full_so_path
[double_slash_pos
+ 1],
3066 FileSpec::Style::native
);
3067 if (FileSystem::Instance().Exists(so_dir
)) {
3068 // Trim off the incorrect path
3069 full_so_path
.erase(0, double_slash_pos
+ 1);
3073 if (*full_so_path
.rbegin() != '/')
3074 full_so_path
+= '/';
3075 full_so_path
+= symbol_name
;
3076 sym
[sym_idx
- 1].GetMangled().SetValue(
3077 ConstString(full_so_path
.c_str()));
3079 m_nlist_idx_to_sym_idx
[nlist_idx
] = sym_idx
- 1;
3082 // This could be a relative path to a N_SO
3083 N_SO_index
= sym_idx
;
3089 // object file name: name,,0,0,st_mtime
3090 type
= eSymbolTypeObjectFile
;
3094 // local sym: name,,NO_SECT,type,offset
3095 type
= eSymbolTypeLocal
;
3100 // include file beginning: name,,NO_SECT,0,sum We use
3101 // the current number of symbols in the symbol table
3102 // in lieu of using nlist_idx in case we ever start
3103 // trimming entries out
3104 N_INCL_indexes
.push_back(sym_idx
);
3105 type
= eSymbolTypeScopeBegin
;
3109 // include file end: name,,NO_SECT,0,0
3110 // Set the size of the N_BINCL to the terminating
3111 // index of this N_EINCL so that we can always skip
3112 // the entire symbol if we need to navigate more
3113 // quickly at the source level when parsing STABS
3114 if (!N_INCL_indexes
.empty()) {
3116 symtab
.SymbolAtIndex(N_INCL_indexes
.back());
3117 symbol_ptr
->SetByteSize(sym_idx
+ 1);
3118 symbol_ptr
->SetSizeIsSibling(true);
3119 N_INCL_indexes
.pop_back();
3121 type
= eSymbolTypeScopeEnd
;
3125 // #included file name: name,,n_sect,0,address
3126 type
= eSymbolTypeHeaderFile
;
3128 // We currently don't use the header files on darwin
3133 // compiler parameters: name,,NO_SECT,0,0
3134 type
= eSymbolTypeCompiler
;
3138 // compiler version: name,,NO_SECT,0,0
3139 type
= eSymbolTypeCompiler
;
3143 // compiler -O level: name,,NO_SECT,0,0
3144 type
= eSymbolTypeCompiler
;
3148 // parameter: name,,NO_SECT,type,offset
3149 type
= eSymbolTypeVariable
;
3153 // alternate entry: name,,n_sect,linenumber,address
3154 symbol_section
= section_info
.GetSection(nlist
.n_sect
,
3156 type
= eSymbolTypeLineEntry
;
3159 // Left and Right Braces
3161 // left bracket: 0,,NO_SECT,nesting level,address We
3162 // use the current number of symbols in the symbol
3163 // table in lieu of using nlist_idx in case we ever
3164 // start trimming entries out
3165 symbol_section
= section_info
.GetSection(nlist
.n_sect
,
3167 N_BRAC_indexes
.push_back(sym_idx
);
3168 type
= eSymbolTypeScopeBegin
;
3172 // right bracket: 0,,NO_SECT,nesting level,address
3173 // Set the size of the N_LBRAC to the terminating
3174 // index of this N_RBRAC so that we can always skip
3175 // the entire symbol if we need to navigate more
3176 // quickly at the source level when parsing STABS
3177 symbol_section
= section_info
.GetSection(nlist
.n_sect
,
3179 if (!N_BRAC_indexes
.empty()) {
3181 symtab
.SymbolAtIndex(N_BRAC_indexes
.back());
3182 symbol_ptr
->SetByteSize(sym_idx
+ 1);
3183 symbol_ptr
->SetSizeIsSibling(true);
3184 N_BRAC_indexes
.pop_back();
3186 type
= eSymbolTypeScopeEnd
;
3190 // deleted include file: name,,NO_SECT,0,sum
3191 type
= eSymbolTypeHeaderFile
;
3196 // begin common: name,,NO_SECT,0,0
3197 // We use the current number of symbols in the symbol
3198 // table in lieu of using nlist_idx in case we ever
3199 // start trimming entries out
3200 type
= eSymbolTypeScopeBegin
;
3201 N_COMM_indexes
.push_back(sym_idx
);
3205 // end common (local name): 0,,n_sect,0,address
3206 symbol_section
= section_info
.GetSection(nlist
.n_sect
,
3211 // end common: name,,n_sect,0,0
3212 // Set the size of the N_BCOMM to the terminating
3213 // index of this N_ECOMM/N_ECOML so that we can
3214 // always skip the entire symbol if we need to
3215 // navigate more quickly at the source level when
3217 if (!N_COMM_indexes
.empty()) {
3219 symtab
.SymbolAtIndex(N_COMM_indexes
.back());
3220 symbol_ptr
->SetByteSize(sym_idx
+ 1);
3221 symbol_ptr
->SetSizeIsSibling(true);
3222 N_COMM_indexes
.pop_back();
3224 type
= eSymbolTypeScopeEnd
;
3228 // second stab entry with length information
3229 type
= eSymbolTypeAdditional
;
3236 // uint8_t n_pext = N_PEXT & nlist.n_type;
3237 uint8_t n_type
= N_TYPE
& nlist
.n_type
;
3238 sym
[sym_idx
].SetExternal((N_EXT
& nlist
.n_type
) != 0);
3242 const char *reexport_name_cstr
=
3243 strtab_data
.PeekCStr(nlist
.n_value
);
3244 if (reexport_name_cstr
&& reexport_name_cstr
[0]) {
3245 type
= eSymbolTypeReExported
;
3246 ConstString
reexport_name(
3247 reexport_name_cstr
+
3248 ((reexport_name_cstr
[0] == '_') ? 1 : 0));
3249 sym
[sym_idx
].SetReExportedSymbolName(reexport_name
);
3251 reexport_shlib_needs_fixup
[sym_idx
] = reexport_name
;
3252 indirect_symbol_names
.insert(ConstString(
3253 symbol_name
+ ((symbol_name
[0] == '_') ? 1 : 0)));
3255 type
= eSymbolTypeUndefined
;
3259 if (symbol_name
&& symbol_name
[0]) {
3260 ConstString
undefined_name(
3261 symbol_name
+ ((symbol_name
[0] == '_') ? 1 : 0));
3262 undefined_name_to_desc
[undefined_name
] = nlist
.n_desc
;
3266 type
= eSymbolTypeUndefined
;
3270 type
= eSymbolTypeAbsolute
;
3274 symbol_section
= section_info
.GetSection(nlist
.n_sect
,
3277 if (symbol_section
== NULL
) {
3278 // TODO: warn about this?
3283 if (TEXT_eh_frame_sectID
== nlist
.n_sect
) {
3284 type
= eSymbolTypeException
;
3286 uint32_t section_type
=
3287 symbol_section
->Get() & SECTION_TYPE
;
3289 switch (section_type
) {
3290 case S_CSTRING_LITERALS
:
3291 type
= eSymbolTypeData
;
3292 break; // section with only literal C strings
3293 case S_4BYTE_LITERALS
:
3294 type
= eSymbolTypeData
;
3295 break; // section with only 4 byte literals
3296 case S_8BYTE_LITERALS
:
3297 type
= eSymbolTypeData
;
3298 break; // section with only 8 byte literals
3299 case S_LITERAL_POINTERS
:
3300 type
= eSymbolTypeTrampoline
;
3301 break; // section with only pointers to literals
3302 case S_NON_LAZY_SYMBOL_POINTERS
:
3303 type
= eSymbolTypeTrampoline
;
3304 break; // section with only non-lazy symbol
3306 case S_LAZY_SYMBOL_POINTERS
:
3307 type
= eSymbolTypeTrampoline
;
3308 break; // section with only lazy symbol pointers
3309 case S_SYMBOL_STUBS
:
3310 type
= eSymbolTypeTrampoline
;
3311 break; // section with only symbol stubs, byte
3312 // size of stub in the reserved2 field
3313 case S_MOD_INIT_FUNC_POINTERS
:
3314 type
= eSymbolTypeCode
;
3315 break; // section with only function pointers for
3317 case S_MOD_TERM_FUNC_POINTERS
:
3318 type
= eSymbolTypeCode
;
3319 break; // section with only function pointers for
3322 type
= eSymbolTypeTrampoline
;
3323 break; // section with only pairs of function
3324 // pointers for interposing
3325 case S_16BYTE_LITERALS
:
3326 type
= eSymbolTypeData
;
3327 break; // section with only 16 byte literals
3329 type
= eSymbolTypeInstrumentation
;
3331 case S_LAZY_DYLIB_SYMBOL_POINTERS
:
3332 type
= eSymbolTypeTrampoline
;
3335 switch (symbol_section
->GetType()) {
3336 case lldb::eSectionTypeCode
:
3337 type
= eSymbolTypeCode
;
3339 case eSectionTypeData
:
3340 case eSectionTypeDataCString
: // Inlined C string
3342 case eSectionTypeDataCStringPointers
: // Pointers
3346 case eSectionTypeDataSymbolAddress
: // Address of
3350 case eSectionTypeData4
:
3351 case eSectionTypeData8
:
3352 case eSectionTypeData16
:
3353 type
= eSymbolTypeData
;
3361 if (type
== eSymbolTypeInvalid
) {
3362 const char *symbol_sect_name
=
3363 symbol_section
->GetName().AsCString();
3364 if (symbol_section
->IsDescendant(
3365 text_section_sp
.get())) {
3366 if (symbol_section
->IsClear(
3367 S_ATTR_PURE_INSTRUCTIONS
|
3368 S_ATTR_SELF_MODIFYING_CODE
|
3369 S_ATTR_SOME_INSTRUCTIONS
))
3370 type
= eSymbolTypeData
;
3372 type
= eSymbolTypeCode
;
3373 } else if (symbol_section
->IsDescendant(
3374 data_section_sp
.get()) ||
3375 symbol_section
->IsDescendant(
3376 data_dirty_section_sp
.get()) ||
3377 symbol_section
->IsDescendant(
3378 data_const_section_sp
.get())) {
3379 if (symbol_sect_name
&&
3380 ::strstr(symbol_sect_name
, "__objc") ==
3382 type
= eSymbolTypeRuntime
;
3385 llvm::StringRef
symbol_name_ref(symbol_name
);
3386 if (symbol_name_ref
.startswith("_OBJC_")) {
3388 g_objc_v2_prefix_class(
3391 g_objc_v2_prefix_metaclass(
3392 "_OBJC_METACLASS_$_");
3394 g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
3395 if (symbol_name_ref
.startswith(
3396 g_objc_v2_prefix_class
)) {
3397 symbol_name_non_abi_mangled
=
3401 g_objc_v2_prefix_class
.size();
3402 type
= eSymbolTypeObjCClass
;
3403 demangled_is_synthesized
= true;
3405 symbol_name_ref
.startswith(
3406 g_objc_v2_prefix_metaclass
)) {
3407 symbol_name_non_abi_mangled
=
3411 g_objc_v2_prefix_metaclass
.size();
3412 type
= eSymbolTypeObjCMetaClass
;
3413 demangled_is_synthesized
= true;
3414 } else if (symbol_name_ref
.startswith(
3415 g_objc_v2_prefix_ivar
)) {
3416 symbol_name_non_abi_mangled
=
3420 g_objc_v2_prefix_ivar
.size();
3421 type
= eSymbolTypeObjCIVar
;
3422 demangled_is_synthesized
= true;
3426 } else if (symbol_sect_name
&&
3427 ::strstr(symbol_sect_name
,
3428 "__gcc_except_tab") ==
3430 type
= eSymbolTypeException
;
3432 type
= eSymbolTypeData
;
3434 } else if (symbol_sect_name
&&
3435 ::strstr(symbol_sect_name
, "__IMPORT") ==
3437 type
= eSymbolTypeTrampoline
;
3438 } else if (symbol_section
->IsDescendant(
3439 objc_section_sp
.get())) {
3440 type
= eSymbolTypeRuntime
;
3441 if (symbol_name
&& symbol_name
[0] == '.') {
3442 llvm::StringRef
symbol_name_ref(symbol_name
);
3444 g_objc_v1_prefix_class(".objc_class_name_");
3445 if (symbol_name_ref
.startswith(
3446 g_objc_v1_prefix_class
)) {
3447 symbol_name_non_abi_mangled
= symbol_name
;
3448 symbol_name
= symbol_name
+
3449 g_objc_v1_prefix_class
.size();
3450 type
= eSymbolTypeObjCClass
;
3451 demangled_is_synthesized
= true;
3462 uint64_t symbol_value
= nlist
.n_value
;
3463 if (symbol_name_non_abi_mangled
) {
3464 sym
[sym_idx
].GetMangled().SetMangledName(
3465 ConstString(symbol_name_non_abi_mangled
));
3466 sym
[sym_idx
].GetMangled().SetDemangledName(
3467 ConstString(symbol_name
));
3469 if (symbol_name
&& symbol_name
[0] == '_') {
3470 symbol_name
++; // Skip the leading underscore
3474 ConstString
const_symbol_name(symbol_name
);
3475 sym
[sym_idx
].GetMangled().SetValue(const_symbol_name
);
3476 if (is_gsym
&& is_debug
) {
3477 const char *gsym_name
=
3480 .GetName(Mangled::ePreferMangled
)
3483 N_GSYM_name_to_sym_idx
[gsym_name
] = sym_idx
;
3487 if (symbol_section
) {
3488 const addr_t section_file_addr
=
3489 symbol_section
->GetFileAddress();
3490 if (symbol_byte_size
== 0 &&
3491 function_starts_count
> 0) {
3492 addr_t symbol_lookup_file_addr
= nlist
.n_value
;
3493 // Do an exact address match for non-ARM addresses,
3494 // else get the closest since the symbol might be a
3495 // thumb symbol which has an address with bit zero
3497 FunctionStarts::Entry
*func_start_entry
=
3498 function_starts
.FindEntry(symbol_lookup_file_addr
,
3500 if (is_arm
&& func_start_entry
) {
3501 // Verify that the function start address is the
3502 // symbol address (ARM) or the symbol address + 1
3504 if (func_start_entry
->addr
!=
3505 symbol_lookup_file_addr
&&
3506 func_start_entry
->addr
!=
3507 (symbol_lookup_file_addr
+ 1)) {
3508 // Not the right entry, NULL it out...
3509 func_start_entry
= NULL
;
3512 if (func_start_entry
) {
3513 func_start_entry
->data
= true;
3515 addr_t symbol_file_addr
= func_start_entry
->addr
;
3516 uint32_t symbol_flags
= 0;
3518 if (symbol_file_addr
& 1)
3519 symbol_flags
= MACHO_NLIST_ARM_SYMBOL_IS_THUMB
;
3520 symbol_file_addr
&= THUMB_ADDRESS_BIT_MASK
;
3523 const FunctionStarts::Entry
*next_func_start_entry
=
3524 function_starts
.FindNextEntry(func_start_entry
);
3525 const addr_t section_end_file_addr
=
3527 symbol_section
->GetByteSize();
3528 if (next_func_start_entry
) {
3529 addr_t next_symbol_file_addr
=
3530 next_func_start_entry
->addr
;
3531 // Be sure the clear the Thumb address bit when
3532 // we calculate the size from the current and
3535 next_symbol_file_addr
&= THUMB_ADDRESS_BIT_MASK
;
3536 symbol_byte_size
= std::min
<lldb::addr_t
>(
3537 next_symbol_file_addr
- symbol_file_addr
,
3538 section_end_file_addr
- symbol_file_addr
);
3541 section_end_file_addr
- symbol_file_addr
;
3545 symbol_value
-= section_file_addr
;
3548 if (is_debug
== false) {
3549 if (type
== eSymbolTypeCode
) {
3550 // See if we can find a N_FUN entry for any code
3551 // symbols. If we do find a match, and the name
3552 // matches, then we can merge the two into just the
3553 // function symbol to avoid duplicate entries in
3556 N_FUN_addr_to_sym_idx
.equal_range(nlist
.n_value
);
3557 if (range
.first
!= range
.second
) {
3558 bool found_it
= false;
3559 for (auto pos
= range
.first
; pos
!= range
.second
;
3561 if (sym
[sym_idx
].GetMangled().GetName(
3562 Mangled::ePreferMangled
) ==
3563 sym
[pos
->second
].GetMangled().GetName(
3564 Mangled::ePreferMangled
)) {
3565 m_nlist_idx_to_sym_idx
[nlist_idx
] = pos
->second
;
3566 // We just need the flags from the linker
3567 // symbol, so put these flags
3568 // into the N_FUN flags to avoid duplicate
3569 // symbols in the symbol table
3570 sym
[pos
->second
].SetExternal(
3571 sym
[sym_idx
].IsExternal());
3572 sym
[pos
->second
].SetFlags(nlist
.n_type
<< 16 |
3574 if (resolver_addresses
.find(nlist
.n_value
) !=
3575 resolver_addresses
.end())
3576 sym
[pos
->second
].SetType(eSymbolTypeResolver
);
3577 sym
[sym_idx
].Clear();
3585 if (resolver_addresses
.find(nlist
.n_value
) !=
3586 resolver_addresses
.end())
3587 type
= eSymbolTypeResolver
;
3589 } else if (type
== eSymbolTypeData
||
3590 type
== eSymbolTypeObjCClass
||
3591 type
== eSymbolTypeObjCMetaClass
||
3592 type
== eSymbolTypeObjCIVar
) {
3593 // See if we can find a N_STSYM entry for any data
3594 // symbols. If we do find a match, and the name
3595 // matches, then we can merge the two into just the
3596 // Static symbol to avoid duplicate entries in the
3598 auto range
= N_STSYM_addr_to_sym_idx
.equal_range(
3600 if (range
.first
!= range
.second
) {
3601 bool found_it
= false;
3602 for (auto pos
= range
.first
; pos
!= range
.second
;
3604 if (sym
[sym_idx
].GetMangled().GetName(
3605 Mangled::ePreferMangled
) ==
3606 sym
[pos
->second
].GetMangled().GetName(
3607 Mangled::ePreferMangled
)) {
3608 m_nlist_idx_to_sym_idx
[nlist_idx
] = pos
->second
;
3609 // We just need the flags from the linker
3610 // symbol, so put these flags
3611 // into the N_STSYM flags to avoid duplicate
3612 // symbols in the symbol table
3613 sym
[pos
->second
].SetExternal(
3614 sym
[sym_idx
].IsExternal());
3615 sym
[pos
->second
].SetFlags(nlist
.n_type
<< 16 |
3617 sym
[sym_idx
].Clear();
3625 const char *gsym_name
=
3628 .GetName(Mangled::ePreferMangled
)
3631 // Combine N_GSYM stab entries with the non
3633 ConstNameToSymbolIndexMap::const_iterator pos
=
3634 N_GSYM_name_to_sym_idx
.find(gsym_name
);
3635 if (pos
!= N_GSYM_name_to_sym_idx
.end()) {
3636 const uint32_t GSYM_sym_idx
= pos
->second
;
3637 m_nlist_idx_to_sym_idx
[nlist_idx
] =
3639 // Copy the address, because often the N_GSYM
3640 // address has an invalid address of zero
3641 // when the global is a common symbol
3642 sym
[GSYM_sym_idx
].GetAddressRef().SetSection(
3644 sym
[GSYM_sym_idx
].GetAddressRef().SetOffset(
3646 add_symbol_addr(sym
[GSYM_sym_idx
]
3649 // We just need the flags from the linker
3650 // symbol, so put these flags
3651 // into the N_GSYM flags to avoid duplicate
3652 // symbols in the symbol table
3653 sym
[GSYM_sym_idx
].SetFlags(nlist
.n_type
<< 16 |
3655 sym
[sym_idx
].Clear();
3663 sym
[sym_idx
].SetID(nlist_idx
);
3664 sym
[sym_idx
].SetType(type
);
3666 sym
[sym_idx
].GetAddressRef().SetSection(symbol_section
);
3667 sym
[sym_idx
].GetAddressRef().SetOffset(symbol_value
);
3669 sym
[sym_idx
].GetAddress().GetFileAddress());
3671 sym
[sym_idx
].SetFlags(nlist
.n_type
<< 16 | nlist
.n_desc
);
3673 if (symbol_byte_size
> 0)
3674 sym
[sym_idx
].SetByteSize(symbol_byte_size
);
3676 if (demangled_is_synthesized
)
3677 sym
[sym_idx
].SetDemangledNameIsSynthesized(true);
3680 sym
[sym_idx
].Clear();
3683 /////////////////////////////
3687 for (const auto &pos
: reexport_shlib_needs_fixup
) {
3688 const auto undef_pos
= undefined_name_to_desc
.find(pos
.second
);
3689 if (undef_pos
!= undefined_name_to_desc
.end()) {
3690 const uint8_t dylib_ordinal
=
3691 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos
->second
);
3692 if (dylib_ordinal
> 0 && dylib_ordinal
< dylib_files
.GetSize())
3693 sym
[pos
.first
].SetReExportedSymbolSharedLibrary(
3694 dylib_files
.GetFileSpecAtIndex(dylib_ordinal
- 1));
3700 lldb::offset_t nlist_data_offset
= 0;
3702 if (nlist_data
.GetByteSize() > 0) {
3704 // If the sym array was not created while parsing the DSC unmapped
3705 // symbols, create it now.
3706 if (sym
== nullptr) {
3708 symtab
.Resize(symtab_load_command
.nsyms
+ m_dysymtab
.nindirectsyms
);
3709 num_syms
= symtab
.GetNumSymbols();
3712 if (unmapped_local_symbols_found
) {
3713 assert(m_dysymtab
.ilocalsym
== 0);
3714 nlist_data_offset
+= (m_dysymtab
.nlocalsym
* nlist_byte_size
);
3715 nlist_idx
= m_dysymtab
.nlocalsym
;
3720 typedef llvm::DenseMap
<ConstString
, uint16_t> UndefinedNameToDescMap
;
3721 typedef llvm::DenseMap
<uint32_t, ConstString
> SymbolIndexToName
;
3722 UndefinedNameToDescMap undefined_name_to_desc
;
3723 SymbolIndexToName reexport_shlib_needs_fixup
;
3725 // Symtab parsing is a huge mess. Everything is entangled and the code
3726 // requires access to a ridiculous amount of variables. LLDB depends
3727 // heavily on the proper merging of symbols and to get that right we need
3728 // to make sure we have parsed all the debug symbols first. Therefore we
3729 // invoke the lambda twice, once to parse only the debug symbols and then
3730 // once more to parse the remaining symbols.
3731 auto ParseSymbolLambda
= [&](struct nlist_64
&nlist
, uint32_t nlist_idx
,
3733 const bool is_debug
= ((nlist
.n_type
& N_STAB
) != 0);
3734 if (is_debug
!= debug_only
)
3737 const char *symbol_name_non_abi_mangled
= nullptr;
3738 const char *symbol_name
= nullptr;
3740 if (have_strtab_data
) {
3741 symbol_name
= strtab_data
.PeekCStr(nlist
.n_strx
);
3743 if (symbol_name
== nullptr) {
3744 // No symbol should be NULL, even the symbols with no string values
3745 // should have an offset zero which points to an empty C-string
3746 Debugger::ReportError(llvm::formatv(
3747 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3749 nlist_idx
, nlist
.n_strx
, module_sp
->GetFileSpec().GetPath()));
3752 if (symbol_name
[0] == '\0')
3753 symbol_name
= nullptr;
3755 const addr_t str_addr
= strtab_addr
+ nlist
.n_strx
;
3757 if (process
->ReadCStringFromMemory(str_addr
, memory_symbol_name
,
3759 symbol_name
= memory_symbol_name
.c_str();
3762 SymbolType type
= eSymbolTypeInvalid
;
3763 SectionSP symbol_section
;
3764 lldb::addr_t symbol_byte_size
= 0;
3765 bool add_nlist
= true;
3766 bool is_gsym
= false;
3767 bool demangled_is_synthesized
= false;
3768 bool set_value
= true;
3770 assert(sym_idx
< num_syms
);
3771 sym
[sym_idx
].SetDebug(is_debug
);
3774 switch (nlist
.n_type
) {
3776 // global symbol: name,,NO_SECT,type,0
3777 // Sometimes the N_GSYM value contains the address.
3779 // FIXME: In the .o files, we have a GSYM and a debug symbol for all
3780 // the ObjC data. They
3781 // have the same address, but we want to ensure that we always find
3782 // only the real symbol, 'cause we don't currently correctly
3783 // attribute the GSYM one to the ObjCClass/Ivar/MetaClass symbol
3784 // type. This is a temporary hack to make sure the ObjectiveC
3785 // symbols get treated correctly. To do this right, we should
3786 // coalesce all the GSYM & global symbols that have the same
3789 sym
[sym_idx
].SetExternal(true);
3791 if (symbol_name
&& symbol_name
[0] == '_' && symbol_name
[1] == 'O') {
3792 llvm::StringRef
symbol_name_ref(symbol_name
);
3793 if (symbol_name_ref
.startswith(g_objc_v2_prefix_class
)) {
3794 symbol_name_non_abi_mangled
= symbol_name
+ 1;
3795 symbol_name
= symbol_name
+ g_objc_v2_prefix_class
.size();
3796 type
= eSymbolTypeObjCClass
;
3797 demangled_is_synthesized
= true;
3799 } else if (symbol_name_ref
.startswith(g_objc_v2_prefix_metaclass
)) {
3800 symbol_name_non_abi_mangled
= symbol_name
+ 1;
3801 symbol_name
= symbol_name
+ g_objc_v2_prefix_metaclass
.size();
3802 type
= eSymbolTypeObjCMetaClass
;
3803 demangled_is_synthesized
= true;
3804 } else if (symbol_name_ref
.startswith(g_objc_v2_prefix_ivar
)) {
3805 symbol_name_non_abi_mangled
= symbol_name
+ 1;
3806 symbol_name
= symbol_name
+ g_objc_v2_prefix_ivar
.size();
3807 type
= eSymbolTypeObjCIVar
;
3808 demangled_is_synthesized
= true;
3811 if (nlist
.n_value
!= 0)
3813 section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
3814 type
= eSymbolTypeData
;
3819 // procedure name (f77 kludge): name,,NO_SECT,0,0
3820 type
= eSymbolTypeCompiler
;
3824 // procedure: name,,n_sect,linenumber,address
3826 type
= eSymbolTypeCode
;
3828 section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
3830 N_FUN_addr_to_sym_idx
.insert(
3831 std::make_pair(nlist
.n_value
, sym_idx
));
3832 // We use the current number of symbols in the symbol table in
3833 // lieu of using nlist_idx in case we ever start trimming entries
3835 N_FUN_indexes
.push_back(sym_idx
);
3837 type
= eSymbolTypeCompiler
;
3839 if (!N_FUN_indexes
.empty()) {
3840 // Copy the size of the function into the original STAB entry
3841 // so we don't have to hunt for it later
3842 symtab
.SymbolAtIndex(N_FUN_indexes
.back())
3843 ->SetByteSize(nlist
.n_value
);
3844 N_FUN_indexes
.pop_back();
3845 // We don't really need the end function STAB as it contains
3846 // the size which we already placed with the original symbol,
3847 // so don't add it if we want a minimal symbol table
3854 // static symbol: name,,n_sect,type,address
3855 N_STSYM_addr_to_sym_idx
.insert(
3856 std::make_pair(nlist
.n_value
, sym_idx
));
3857 symbol_section
= section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
3858 if (symbol_name
&& symbol_name
[0]) {
3859 type
= ObjectFile::GetSymbolTypeFromName(symbol_name
+ 1,
3865 // .lcomm symbol: name,,n_sect,type,address
3866 symbol_section
= section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
3867 type
= eSymbolTypeCommonBlock
;
3871 // We use the current number of symbols in the symbol table in lieu
3872 // of using nlist_idx in case we ever start trimming entries out
3873 // Skip these if we want minimal symbol tables
3878 // Set the size of the N_BNSYM to the terminating index of this
3879 // N_ENSYM so that we can always skip the entire symbol if we need
3880 // to navigate more quickly at the source level when parsing STABS
3881 // Skip these if we want minimal symbol tables
3886 // emitted with gcc2_compiled and in gcc source
3887 type
= eSymbolTypeCompiler
;
3891 // register sym: name,,NO_SECT,type,register
3892 type
= eSymbolTypeVariable
;
3896 // src line: 0,,n_sect,linenumber,address
3897 symbol_section
= section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
3898 type
= eSymbolTypeLineEntry
;
3902 // structure elt: name,,NO_SECT,type,struct_offset
3903 type
= eSymbolTypeVariableType
;
3908 type
= eSymbolTypeSourceFile
;
3909 if (symbol_name
== nullptr) {
3911 if (N_SO_index
!= UINT32_MAX
) {
3912 // Set the size of the N_SO to the terminating index of this
3913 // N_SO so that we can always skip the entire N_SO if we need
3914 // to navigate more quickly at the source level when parsing
3916 symbol_ptr
= symtab
.SymbolAtIndex(N_SO_index
);
3917 symbol_ptr
->SetByteSize(sym_idx
);
3918 symbol_ptr
->SetSizeIsSibling(true);
3920 N_NSYM_indexes
.clear();
3921 N_INCL_indexes
.clear();
3922 N_BRAC_indexes
.clear();
3923 N_COMM_indexes
.clear();
3924 N_FUN_indexes
.clear();
3925 N_SO_index
= UINT32_MAX
;
3927 // We use the current number of symbols in the symbol table in
3928 // lieu of using nlist_idx in case we ever start trimming entries
3930 const bool N_SO_has_full_path
= symbol_name
[0] == '/';
3931 if (N_SO_has_full_path
) {
3932 if ((N_SO_index
== sym_idx
- 1) && ((sym_idx
- 1) < num_syms
)) {
3933 // We have two consecutive N_SO entries where the first
3934 // contains a directory and the second contains a full path.
3935 sym
[sym_idx
- 1].GetMangled().SetValue(
3936 ConstString(symbol_name
));
3937 m_nlist_idx_to_sym_idx
[nlist_idx
] = sym_idx
- 1;
3940 // This is the first entry in a N_SO that contains a
3941 // directory or a full path to the source file
3942 N_SO_index
= sym_idx
;
3944 } else if ((N_SO_index
== sym_idx
- 1) &&
3945 ((sym_idx
- 1) < num_syms
)) {
3946 // This is usually the second N_SO entry that contains just the
3947 // filename, so here we combine it with the first one if we are
3948 // minimizing the symbol table
3949 const char *so_path
=
3950 sym
[sym_idx
- 1].GetMangled().GetDemangledName().AsCString();
3951 if (so_path
&& so_path
[0]) {
3952 std::string
full_so_path(so_path
);
3953 const size_t double_slash_pos
= full_so_path
.find("//");
3954 if (double_slash_pos
!= std::string::npos
) {
3955 // The linker has been generating bad N_SO entries with
3956 // doubled up paths in the format "%s%s" where the first
3957 // string in the DW_AT_comp_dir, and the second is the
3958 // directory for the source file so you end up with a path
3959 // that looks like "/tmp/src//tmp/src/"
3960 FileSpec
so_dir(so_path
);
3961 if (!FileSystem::Instance().Exists(so_dir
)) {
3962 so_dir
.SetFile(&full_so_path
[double_slash_pos
+ 1],
3963 FileSpec::Style::native
);
3964 if (FileSystem::Instance().Exists(so_dir
)) {
3965 // Trim off the incorrect path
3966 full_so_path
.erase(0, double_slash_pos
+ 1);
3970 if (*full_so_path
.rbegin() != '/')
3971 full_so_path
+= '/';
3972 full_so_path
+= symbol_name
;
3973 sym
[sym_idx
- 1].GetMangled().SetValue(
3974 ConstString(full_so_path
.c_str()));
3976 m_nlist_idx_to_sym_idx
[nlist_idx
] = sym_idx
- 1;
3979 // This could be a relative path to a N_SO
3980 N_SO_index
= sym_idx
;
3986 // object file name: name,,0,0,st_mtime
3987 type
= eSymbolTypeObjectFile
;
3991 // local sym: name,,NO_SECT,type,offset
3992 type
= eSymbolTypeLocal
;
3997 // include file beginning: name,,NO_SECT,0,sum We use the current
3998 // number of symbols in the symbol table in lieu of using nlist_idx
3999 // in case we ever start trimming entries out
4000 N_INCL_indexes
.push_back(sym_idx
);
4001 type
= eSymbolTypeScopeBegin
;
4005 // include file end: name,,NO_SECT,0,0
4006 // Set the size of the N_BINCL to the terminating index of this
4007 // N_EINCL so that we can always skip the entire symbol if we need
4008 // to navigate more quickly at the source level when parsing STABS
4009 if (!N_INCL_indexes
.empty()) {
4010 symbol_ptr
= symtab
.SymbolAtIndex(N_INCL_indexes
.back());
4011 symbol_ptr
->SetByteSize(sym_idx
+ 1);
4012 symbol_ptr
->SetSizeIsSibling(true);
4013 N_INCL_indexes
.pop_back();
4015 type
= eSymbolTypeScopeEnd
;
4019 // #included file name: name,,n_sect,0,address
4020 type
= eSymbolTypeHeaderFile
;
4022 // We currently don't use the header files on darwin
4027 // compiler parameters: name,,NO_SECT,0,0
4028 type
= eSymbolTypeCompiler
;
4032 // compiler version: name,,NO_SECT,0,0
4033 type
= eSymbolTypeCompiler
;
4037 // compiler -O level: name,,NO_SECT,0,0
4038 type
= eSymbolTypeCompiler
;
4042 // parameter: name,,NO_SECT,type,offset
4043 type
= eSymbolTypeVariable
;
4047 // alternate entry: name,,n_sect,linenumber,address
4048 symbol_section
= section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
4049 type
= eSymbolTypeLineEntry
;
4052 // Left and Right Braces
4054 // left bracket: 0,,NO_SECT,nesting level,address We use the
4055 // current number of symbols in the symbol table in lieu of using
4056 // nlist_idx in case we ever start trimming entries out
4057 symbol_section
= section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
4058 N_BRAC_indexes
.push_back(sym_idx
);
4059 type
= eSymbolTypeScopeBegin
;
4063 // right bracket: 0,,NO_SECT,nesting level,address Set the size of
4064 // the N_LBRAC to the terminating index of this N_RBRAC so that we
4065 // can always skip the entire symbol if we need to navigate more
4066 // quickly at the source level when parsing STABS
4067 symbol_section
= section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
4068 if (!N_BRAC_indexes
.empty()) {
4069 symbol_ptr
= symtab
.SymbolAtIndex(N_BRAC_indexes
.back());
4070 symbol_ptr
->SetByteSize(sym_idx
+ 1);
4071 symbol_ptr
->SetSizeIsSibling(true);
4072 N_BRAC_indexes
.pop_back();
4074 type
= eSymbolTypeScopeEnd
;
4078 // deleted include file: name,,NO_SECT,0,sum
4079 type
= eSymbolTypeHeaderFile
;
4084 // begin common: name,,NO_SECT,0,0
4085 // We use the current number of symbols in the symbol table in lieu
4086 // of using nlist_idx in case we ever start trimming entries out
4087 type
= eSymbolTypeScopeBegin
;
4088 N_COMM_indexes
.push_back(sym_idx
);
4092 // end common (local name): 0,,n_sect,0,address
4093 symbol_section
= section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
4097 // end common: name,,n_sect,0,0
4098 // Set the size of the N_BCOMM to the terminating index of this
4099 // N_ECOMM/N_ECOML so that we can always skip the entire symbol if
4100 // we need to navigate more quickly at the source level when
4102 if (!N_COMM_indexes
.empty()) {
4103 symbol_ptr
= symtab
.SymbolAtIndex(N_COMM_indexes
.back());
4104 symbol_ptr
->SetByteSize(sym_idx
+ 1);
4105 symbol_ptr
->SetSizeIsSibling(true);
4106 N_COMM_indexes
.pop_back();
4108 type
= eSymbolTypeScopeEnd
;
4112 // second stab entry with length information
4113 type
= eSymbolTypeAdditional
;
4120 uint8_t n_type
= N_TYPE
& nlist
.n_type
;
4121 sym
[sym_idx
].SetExternal((N_EXT
& nlist
.n_type
) != 0);
4125 const char *reexport_name_cstr
= strtab_data
.PeekCStr(nlist
.n_value
);
4126 if (reexport_name_cstr
&& reexport_name_cstr
[0] && symbol_name
) {
4127 type
= eSymbolTypeReExported
;
4128 ConstString
reexport_name(reexport_name_cstr
+
4129 ((reexport_name_cstr
[0] == '_') ? 1 : 0));
4130 sym
[sym_idx
].SetReExportedSymbolName(reexport_name
);
4132 reexport_shlib_needs_fixup
[sym_idx
] = reexport_name
;
4133 indirect_symbol_names
.insert(
4134 ConstString(symbol_name
+ ((symbol_name
[0] == '_') ? 1 : 0)));
4136 type
= eSymbolTypeUndefined
;
4140 if (symbol_name
&& symbol_name
[0]) {
4141 ConstString
undefined_name(symbol_name
+
4142 ((symbol_name
[0] == '_') ? 1 : 0));
4143 undefined_name_to_desc
[undefined_name
] = nlist
.n_desc
;
4148 type
= eSymbolTypeUndefined
;
4152 type
= eSymbolTypeAbsolute
;
4156 symbol_section
= section_info
.GetSection(nlist
.n_sect
, nlist
.n_value
);
4158 if (!symbol_section
) {
4159 // TODO: warn about this?
4164 if (TEXT_eh_frame_sectID
== nlist
.n_sect
) {
4165 type
= eSymbolTypeException
;
4167 uint32_t section_type
= symbol_section
->Get() & SECTION_TYPE
;
4169 switch (section_type
) {
4170 case S_CSTRING_LITERALS
:
4171 type
= eSymbolTypeData
;
4172 break; // section with only literal C strings
4173 case S_4BYTE_LITERALS
:
4174 type
= eSymbolTypeData
;
4175 break; // section with only 4 byte literals
4176 case S_8BYTE_LITERALS
:
4177 type
= eSymbolTypeData
;
4178 break; // section with only 8 byte literals
4179 case S_LITERAL_POINTERS
:
4180 type
= eSymbolTypeTrampoline
;
4181 break; // section with only pointers to literals
4182 case S_NON_LAZY_SYMBOL_POINTERS
:
4183 type
= eSymbolTypeTrampoline
;
4184 break; // section with only non-lazy symbol pointers
4185 case S_LAZY_SYMBOL_POINTERS
:
4186 type
= eSymbolTypeTrampoline
;
4187 break; // section with only lazy symbol pointers
4188 case S_SYMBOL_STUBS
:
4189 type
= eSymbolTypeTrampoline
;
4190 break; // section with only symbol stubs, byte size of stub in
4191 // the reserved2 field
4192 case S_MOD_INIT_FUNC_POINTERS
:
4193 type
= eSymbolTypeCode
;
4194 break; // section with only function pointers for initialization
4195 case S_MOD_TERM_FUNC_POINTERS
:
4196 type
= eSymbolTypeCode
;
4197 break; // section with only function pointers for termination
4199 type
= eSymbolTypeTrampoline
;
4200 break; // section with only pairs of function pointers for
4202 case S_16BYTE_LITERALS
:
4203 type
= eSymbolTypeData
;
4204 break; // section with only 16 byte literals
4206 type
= eSymbolTypeInstrumentation
;
4208 case S_LAZY_DYLIB_SYMBOL_POINTERS
:
4209 type
= eSymbolTypeTrampoline
;
4212 switch (symbol_section
->GetType()) {
4213 case lldb::eSectionTypeCode
:
4214 type
= eSymbolTypeCode
;
4216 case eSectionTypeData
:
4217 case eSectionTypeDataCString
: // Inlined C string data
4218 case eSectionTypeDataCStringPointers
: // Pointers to C string
4220 case eSectionTypeDataSymbolAddress
: // Address of a symbol in
4222 case eSectionTypeData4
:
4223 case eSectionTypeData8
:
4224 case eSectionTypeData16
:
4225 type
= eSymbolTypeData
;
4233 if (type
== eSymbolTypeInvalid
) {
4234 const char *symbol_sect_name
=
4235 symbol_section
->GetName().AsCString();
4236 if (symbol_section
->IsDescendant(text_section_sp
.get())) {
4237 if (symbol_section
->IsClear(S_ATTR_PURE_INSTRUCTIONS
|
4238 S_ATTR_SELF_MODIFYING_CODE
|
4239 S_ATTR_SOME_INSTRUCTIONS
))
4240 type
= eSymbolTypeData
;
4242 type
= eSymbolTypeCode
;
4243 } else if (symbol_section
->IsDescendant(data_section_sp
.get()) ||
4244 symbol_section
->IsDescendant(
4245 data_dirty_section_sp
.get()) ||
4246 symbol_section
->IsDescendant(
4247 data_const_section_sp
.get())) {
4248 if (symbol_sect_name
&&
4249 ::strstr(symbol_sect_name
, "__objc") == symbol_sect_name
) {
4250 type
= eSymbolTypeRuntime
;
4253 llvm::StringRef
symbol_name_ref(symbol_name
);
4254 if (symbol_name_ref
.startswith("_OBJC_")) {
4255 llvm::StringRef
g_objc_v2_prefix_class(
4257 llvm::StringRef
g_objc_v2_prefix_metaclass(
4258 "_OBJC_METACLASS_$_");
4259 llvm::StringRef
g_objc_v2_prefix_ivar(
4261 if (symbol_name_ref
.startswith(g_objc_v2_prefix_class
)) {
4262 symbol_name_non_abi_mangled
= symbol_name
+ 1;
4264 symbol_name
+ g_objc_v2_prefix_class
.size();
4265 type
= eSymbolTypeObjCClass
;
4266 demangled_is_synthesized
= true;
4267 } else if (symbol_name_ref
.startswith(
4268 g_objc_v2_prefix_metaclass
)) {
4269 symbol_name_non_abi_mangled
= symbol_name
+ 1;
4271 symbol_name
+ g_objc_v2_prefix_metaclass
.size();
4272 type
= eSymbolTypeObjCMetaClass
;
4273 demangled_is_synthesized
= true;
4274 } else if (symbol_name_ref
.startswith(
4275 g_objc_v2_prefix_ivar
)) {
4276 symbol_name_non_abi_mangled
= symbol_name
+ 1;
4278 symbol_name
+ g_objc_v2_prefix_ivar
.size();
4279 type
= eSymbolTypeObjCIVar
;
4280 demangled_is_synthesized
= true;
4284 } else if (symbol_sect_name
&&
4285 ::strstr(symbol_sect_name
, "__gcc_except_tab") ==
4287 type
= eSymbolTypeException
;
4289 type
= eSymbolTypeData
;
4291 } else if (symbol_sect_name
&&
4292 ::strstr(symbol_sect_name
, "__IMPORT") ==
4294 type
= eSymbolTypeTrampoline
;
4295 } else if (symbol_section
->IsDescendant(objc_section_sp
.get())) {
4296 type
= eSymbolTypeRuntime
;
4297 if (symbol_name
&& symbol_name
[0] == '.') {
4298 llvm::StringRef
symbol_name_ref(symbol_name
);
4299 llvm::StringRef
g_objc_v1_prefix_class(
4300 ".objc_class_name_");
4301 if (symbol_name_ref
.startswith(g_objc_v1_prefix_class
)) {
4302 symbol_name_non_abi_mangled
= symbol_name
;
4303 symbol_name
= symbol_name
+ g_objc_v1_prefix_class
.size();
4304 type
= eSymbolTypeObjCClass
;
4305 demangled_is_synthesized
= true;
4316 sym
[sym_idx
].Clear();
4320 uint64_t symbol_value
= nlist
.n_value
;
4322 if (symbol_name_non_abi_mangled
) {
4323 sym
[sym_idx
].GetMangled().SetMangledName(
4324 ConstString(symbol_name_non_abi_mangled
));
4325 sym
[sym_idx
].GetMangled().SetDemangledName(ConstString(symbol_name
));
4328 if (symbol_name
&& symbol_name
[0] == '_') {
4329 symbol_name
++; // Skip the leading underscore
4333 ConstString
const_symbol_name(symbol_name
);
4334 sym
[sym_idx
].GetMangled().SetValue(const_symbol_name
);
4339 const char *gsym_name
= sym
[sym_idx
]
4341 .GetName(Mangled::ePreferMangled
)
4344 N_GSYM_name_to_sym_idx
[gsym_name
] = sym_idx
;
4347 if (symbol_section
) {
4348 const addr_t section_file_addr
= symbol_section
->GetFileAddress();
4349 if (symbol_byte_size
== 0 && function_starts_count
> 0) {
4350 addr_t symbol_lookup_file_addr
= nlist
.n_value
;
4351 // Do an exact address match for non-ARM addresses, else get the
4352 // closest since the symbol might be a thumb symbol which has an
4353 // address with bit zero set.
4354 FunctionStarts::Entry
*func_start_entry
=
4355 function_starts
.FindEntry(symbol_lookup_file_addr
, !is_arm
);
4356 if (is_arm
&& func_start_entry
) {
4357 // Verify that the function start address is the symbol address
4358 // (ARM) or the symbol address + 1 (thumb).
4359 if (func_start_entry
->addr
!= symbol_lookup_file_addr
&&
4360 func_start_entry
->addr
!= (symbol_lookup_file_addr
+ 1)) {
4361 // Not the right entry, NULL it out...
4362 func_start_entry
= nullptr;
4365 if (func_start_entry
) {
4366 func_start_entry
->data
= true;
4368 addr_t symbol_file_addr
= func_start_entry
->addr
;
4370 symbol_file_addr
&= THUMB_ADDRESS_BIT_MASK
;
4372 const FunctionStarts::Entry
*next_func_start_entry
=
4373 function_starts
.FindNextEntry(func_start_entry
);
4374 const addr_t section_end_file_addr
=
4375 section_file_addr
+ symbol_section
->GetByteSize();
4376 if (next_func_start_entry
) {
4377 addr_t next_symbol_file_addr
= next_func_start_entry
->addr
;
4378 // Be sure the clear the Thumb address bit when we calculate the
4379 // size from the current and next address
4381 next_symbol_file_addr
&= THUMB_ADDRESS_BIT_MASK
;
4382 symbol_byte_size
= std::min
<lldb::addr_t
>(
4383 next_symbol_file_addr
- symbol_file_addr
,
4384 section_end_file_addr
- symbol_file_addr
);
4386 symbol_byte_size
= section_end_file_addr
- symbol_file_addr
;
4390 symbol_value
-= section_file_addr
;
4394 if (type
== eSymbolTypeCode
) {
4395 // See if we can find a N_FUN entry for any code symbols. If we do
4396 // find a match, and the name matches, then we can merge the two into
4397 // just the function symbol to avoid duplicate entries in the symbol
4399 std::pair
<ValueToSymbolIndexMap::const_iterator
,
4400 ValueToSymbolIndexMap::const_iterator
>
4402 range
= N_FUN_addr_to_sym_idx
.equal_range(nlist
.n_value
);
4403 if (range
.first
!= range
.second
) {
4404 for (ValueToSymbolIndexMap::const_iterator pos
= range
.first
;
4405 pos
!= range
.second
; ++pos
) {
4406 if (sym
[sym_idx
].GetMangled().GetName(Mangled::ePreferMangled
) ==
4407 sym
[pos
->second
].GetMangled().GetName(
4408 Mangled::ePreferMangled
)) {
4409 m_nlist_idx_to_sym_idx
[nlist_idx
] = pos
->second
;
4410 // We just need the flags from the linker symbol, so put these
4411 // flags into the N_FUN flags to avoid duplicate symbols in the
4413 sym
[pos
->second
].SetExternal(sym
[sym_idx
].IsExternal());
4414 sym
[pos
->second
].SetFlags(nlist
.n_type
<< 16 | nlist
.n_desc
);
4415 if (resolver_addresses
.find(nlist
.n_value
) !=
4416 resolver_addresses
.end())
4417 sym
[pos
->second
].SetType(eSymbolTypeResolver
);
4418 sym
[sym_idx
].Clear();
4423 if (resolver_addresses
.find(nlist
.n_value
) !=
4424 resolver_addresses
.end())
4425 type
= eSymbolTypeResolver
;
4427 } else if (type
== eSymbolTypeData
|| type
== eSymbolTypeObjCClass
||
4428 type
== eSymbolTypeObjCMetaClass
||
4429 type
== eSymbolTypeObjCIVar
) {
4430 // See if we can find a N_STSYM entry for any data symbols. If we do
4431 // find a match, and the name matches, then we can merge the two into
4432 // just the Static symbol to avoid duplicate entries in the symbol
4434 std::pair
<ValueToSymbolIndexMap::const_iterator
,
4435 ValueToSymbolIndexMap::const_iterator
>
4437 range
= N_STSYM_addr_to_sym_idx
.equal_range(nlist
.n_value
);
4438 if (range
.first
!= range
.second
) {
4439 for (ValueToSymbolIndexMap::const_iterator pos
= range
.first
;
4440 pos
!= range
.second
; ++pos
) {
4441 if (sym
[sym_idx
].GetMangled().GetName(Mangled::ePreferMangled
) ==
4442 sym
[pos
->second
].GetMangled().GetName(
4443 Mangled::ePreferMangled
)) {
4444 m_nlist_idx_to_sym_idx
[nlist_idx
] = pos
->second
;
4445 // We just need the flags from the linker symbol, so put these
4446 // flags into the N_STSYM flags to avoid duplicate symbols in
4447 // the symbol table.
4448 sym
[pos
->second
].SetExternal(sym
[sym_idx
].IsExternal());
4449 sym
[pos
->second
].SetFlags(nlist
.n_type
<< 16 | nlist
.n_desc
);
4450 sym
[sym_idx
].Clear();
4455 // Combine N_GSYM stab entries with the non stab symbol.
4456 const char *gsym_name
= sym
[sym_idx
]
4458 .GetName(Mangled::ePreferMangled
)
4461 ConstNameToSymbolIndexMap::const_iterator pos
=
4462 N_GSYM_name_to_sym_idx
.find(gsym_name
);
4463 if (pos
!= N_GSYM_name_to_sym_idx
.end()) {
4464 const uint32_t GSYM_sym_idx
= pos
->second
;
4465 m_nlist_idx_to_sym_idx
[nlist_idx
] = GSYM_sym_idx
;
4466 // Copy the address, because often the N_GSYM address has an
4467 // invalid address of zero when the global is a common symbol.
4468 sym
[GSYM_sym_idx
].GetAddressRef().SetSection(symbol_section
);
4469 sym
[GSYM_sym_idx
].GetAddressRef().SetOffset(symbol_value
);
4471 sym
[GSYM_sym_idx
].GetAddress().GetFileAddress());
4472 // We just need the flags from the linker symbol, so put these
4473 // flags into the N_GSYM flags to avoid duplicate symbols in
4474 // the symbol table.
4475 sym
[GSYM_sym_idx
].SetFlags(nlist
.n_type
<< 16 | nlist
.n_desc
);
4476 sym
[sym_idx
].Clear();
4484 sym
[sym_idx
].SetID(nlist_idx
);
4485 sym
[sym_idx
].SetType(type
);
4487 sym
[sym_idx
].GetAddressRef().SetSection(symbol_section
);
4488 sym
[sym_idx
].GetAddressRef().SetOffset(symbol_value
);
4490 add_symbol_addr(sym
[sym_idx
].GetAddress().GetFileAddress());
4492 sym
[sym_idx
].SetFlags(nlist
.n_type
<< 16 | nlist
.n_desc
);
4493 if (nlist
.n_desc
& N_WEAK_REF
)
4494 sym
[sym_idx
].SetIsWeak(true);
4496 if (symbol_byte_size
> 0)
4497 sym
[sym_idx
].SetByteSize(symbol_byte_size
);
4499 if (demangled_is_synthesized
)
4500 sym
[sym_idx
].SetDemangledNameIsSynthesized(true);
4506 // First parse all the nlists but don't process them yet. See the next
4507 // comment for an explanation why.
4508 std::vector
<struct nlist_64
> nlists
;
4509 nlists
.reserve(symtab_load_command
.nsyms
);
4510 for (; nlist_idx
< symtab_load_command
.nsyms
; ++nlist_idx
) {
4512 ParseNList(nlist_data
, nlist_data_offset
, nlist_byte_size
))
4513 nlists
.push_back(*nlist
);
4518 // Now parse all the debug symbols. This is needed to merge non-debug
4519 // symbols in the next step. Non-debug symbols are always coalesced into
4520 // the debug symbol. Doing this in one step would mean that some symbols
4523 for (auto &nlist
: nlists
) {
4524 if (!ParseSymbolLambda(nlist
, nlist_idx
++, DebugSymbols
))
4528 // Finally parse all the non debug symbols.
4530 for (auto &nlist
: nlists
) {
4531 if (!ParseSymbolLambda(nlist
, nlist_idx
++, NonDebugSymbols
))
4535 for (const auto &pos
: reexport_shlib_needs_fixup
) {
4536 const auto undef_pos
= undefined_name_to_desc
.find(pos
.second
);
4537 if (undef_pos
!= undefined_name_to_desc
.end()) {
4538 const uint8_t dylib_ordinal
=
4539 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos
->second
);
4540 if (dylib_ordinal
> 0 && dylib_ordinal
< dylib_files
.GetSize())
4541 sym
[pos
.first
].SetReExportedSymbolSharedLibrary(
4542 dylib_files
.GetFileSpecAtIndex(dylib_ordinal
- 1));
4547 // Count how many trie symbols we'll add to the symbol table
4548 int trie_symbol_table_augment_count
= 0;
4549 for (auto &e
: external_sym_trie_entries
) {
4550 if (!symbols_added
.contains(e
.entry
.address
))
4551 trie_symbol_table_augment_count
++;
4554 if (num_syms
< sym_idx
+ trie_symbol_table_augment_count
) {
4555 num_syms
= sym_idx
+ trie_symbol_table_augment_count
;
4556 sym
= symtab
.Resize(num_syms
);
4558 uint32_t synthetic_sym_id
= symtab_load_command
.nsyms
;
4560 // Add symbols from the trie to the symbol table.
4561 for (auto &e
: external_sym_trie_entries
) {
4562 if (symbols_added
.contains(e
.entry
.address
))
4565 // Find the section that this trie address is in, use that to annotate
4566 // symbol type as we add the trie address and name to the symbol table.
4567 Address symbol_addr
;
4568 if (module_sp
->ResolveFileAddress(e
.entry
.address
, symbol_addr
)) {
4569 SectionSP
symbol_section(symbol_addr
.GetSection());
4570 const char *symbol_name
= e
.entry
.name
.GetCString();
4571 bool demangled_is_synthesized
= false;
4573 GetSymbolType(symbol_name
, demangled_is_synthesized
, text_section_sp
,
4574 data_section_sp
, data_dirty_section_sp
,
4575 data_const_section_sp
, symbol_section
);
4577 sym
[sym_idx
].SetType(type
);
4578 if (symbol_section
) {
4579 sym
[sym_idx
].SetID(synthetic_sym_id
++);
4580 sym
[sym_idx
].GetMangled().SetMangledName(ConstString(symbol_name
));
4581 if (demangled_is_synthesized
)
4582 sym
[sym_idx
].SetDemangledNameIsSynthesized(true);
4583 sym
[sym_idx
].SetIsSynthetic(true);
4584 sym
[sym_idx
].SetExternal(true);
4585 sym
[sym_idx
].GetAddressRef() = symbol_addr
;
4586 add_symbol_addr(symbol_addr
.GetFileAddress());
4587 if (e
.entry
.flags
& TRIE_SYMBOL_IS_THUMB
)
4588 sym
[sym_idx
].SetFlags(MACHO_NLIST_ARM_SYMBOL_IS_THUMB
);
4594 if (function_starts_count
> 0) {
4595 uint32_t num_synthetic_function_symbols
= 0;
4596 for (i
= 0; i
< function_starts_count
; ++i
) {
4597 if (!symbols_added
.contains(function_starts
.GetEntryRef(i
).addr
))
4598 ++num_synthetic_function_symbols
;
4601 if (num_synthetic_function_symbols
> 0) {
4602 if (num_syms
< sym_idx
+ num_synthetic_function_symbols
) {
4603 num_syms
= sym_idx
+ num_synthetic_function_symbols
;
4604 sym
= symtab
.Resize(num_syms
);
4606 for (i
= 0; i
< function_starts_count
; ++i
) {
4607 const FunctionStarts::Entry
*func_start_entry
=
4608 function_starts
.GetEntryAtIndex(i
);
4609 if (!symbols_added
.contains(func_start_entry
->addr
)) {
4610 addr_t symbol_file_addr
= func_start_entry
->addr
;
4611 uint32_t symbol_flags
= 0;
4612 if (func_start_entry
->data
)
4613 symbol_flags
= MACHO_NLIST_ARM_SYMBOL_IS_THUMB
;
4614 Address symbol_addr
;
4615 if (module_sp
->ResolveFileAddress(symbol_file_addr
, symbol_addr
)) {
4616 SectionSP
symbol_section(symbol_addr
.GetSection());
4617 uint32_t symbol_byte_size
= 0;
4618 if (symbol_section
) {
4619 const addr_t section_file_addr
= symbol_section
->GetFileAddress();
4620 const FunctionStarts::Entry
*next_func_start_entry
=
4621 function_starts
.FindNextEntry(func_start_entry
);
4622 const addr_t section_end_file_addr
=
4623 section_file_addr
+ symbol_section
->GetByteSize();
4624 if (next_func_start_entry
) {
4625 addr_t next_symbol_file_addr
= next_func_start_entry
->addr
;
4627 next_symbol_file_addr
&= THUMB_ADDRESS_BIT_MASK
;
4628 symbol_byte_size
= std::min
<lldb::addr_t
>(
4629 next_symbol_file_addr
- symbol_file_addr
,
4630 section_end_file_addr
- symbol_file_addr
);
4632 symbol_byte_size
= section_end_file_addr
- symbol_file_addr
;
4634 sym
[sym_idx
].SetID(synthetic_sym_id
++);
4635 // Don't set the name for any synthetic symbols, the Symbol
4636 // object will generate one if needed when the name is accessed
4638 sym
[sym_idx
].GetMangled().SetDemangledName(ConstString());
4639 sym
[sym_idx
].SetType(eSymbolTypeCode
);
4640 sym
[sym_idx
].SetIsSynthetic(true);
4641 sym
[sym_idx
].GetAddressRef() = symbol_addr
;
4642 add_symbol_addr(symbol_addr
.GetFileAddress());
4644 sym
[sym_idx
].SetFlags(symbol_flags
);
4645 if (symbol_byte_size
)
4646 sym
[sym_idx
].SetByteSize(symbol_byte_size
);
4655 // Trim our symbols down to just what we ended up with after removing any
4657 if (sym_idx
< num_syms
) {
4659 sym
= symtab
.Resize(num_syms
);
4662 // Now synthesize indirect symbols
4663 if (m_dysymtab
.nindirectsyms
!= 0) {
4664 if (indirect_symbol_index_data
.GetByteSize()) {
4665 NListIndexToSymbolIndexMap::const_iterator end_index_pos
=
4666 m_nlist_idx_to_sym_idx
.end();
4668 for (uint32_t sect_idx
= 1; sect_idx
< m_mach_sections
.size();
4670 if ((m_mach_sections
[sect_idx
].flags
& SECTION_TYPE
) ==
4672 uint32_t symbol_stub_byte_size
= m_mach_sections
[sect_idx
].reserved2
;
4673 if (symbol_stub_byte_size
== 0)
4676 const uint32_t num_symbol_stubs
=
4677 m_mach_sections
[sect_idx
].size
/ symbol_stub_byte_size
;
4679 if (num_symbol_stubs
== 0)
4682 const uint32_t symbol_stub_index_offset
=
4683 m_mach_sections
[sect_idx
].reserved1
;
4684 for (uint32_t stub_idx
= 0; stub_idx
< num_symbol_stubs
; ++stub_idx
) {
4685 const uint32_t symbol_stub_index
=
4686 symbol_stub_index_offset
+ stub_idx
;
4687 const lldb::addr_t symbol_stub_addr
=
4688 m_mach_sections
[sect_idx
].addr
+
4689 (stub_idx
* symbol_stub_byte_size
);
4690 lldb::offset_t symbol_stub_offset
= symbol_stub_index
* 4;
4691 if (indirect_symbol_index_data
.ValidOffsetForDataOfSize(
4692 symbol_stub_offset
, 4)) {
4693 const uint32_t stub_sym_id
=
4694 indirect_symbol_index_data
.GetU32(&symbol_stub_offset
);
4695 if (stub_sym_id
& (INDIRECT_SYMBOL_ABS
| INDIRECT_SYMBOL_LOCAL
))
4698 NListIndexToSymbolIndexMap::const_iterator index_pos
=
4699 m_nlist_idx_to_sym_idx
.find(stub_sym_id
);
4700 Symbol
*stub_symbol
= nullptr;
4701 if (index_pos
!= end_index_pos
) {
4702 // We have a remapping from the original nlist index to a
4703 // current symbol index, so just look this up by index
4704 stub_symbol
= symtab
.SymbolAtIndex(index_pos
->second
);
4706 // We need to lookup a symbol using the original nlist symbol
4707 // index since this index is coming from the S_SYMBOL_STUBS
4708 stub_symbol
= symtab
.FindSymbolByID(stub_sym_id
);
4712 Address
so_addr(symbol_stub_addr
, section_list
);
4714 if (stub_symbol
->GetType() == eSymbolTypeUndefined
) {
4715 // Change the external symbol into a trampoline that makes
4716 // sense These symbols were N_UNDF N_EXT, and are useless
4717 // to us, so we can re-use them so we don't have to make up
4718 // a synthetic symbol for no good reason.
4719 if (resolver_addresses
.find(symbol_stub_addr
) ==
4720 resolver_addresses
.end())
4721 stub_symbol
->SetType(eSymbolTypeTrampoline
);
4723 stub_symbol
->SetType(eSymbolTypeResolver
);
4724 stub_symbol
->SetExternal(false);
4725 stub_symbol
->GetAddressRef() = so_addr
;
4726 stub_symbol
->SetByteSize(symbol_stub_byte_size
);
4728 // Make a synthetic symbol to describe the trampoline stub
4729 Mangled
stub_symbol_mangled_name(stub_symbol
->GetMangled());
4730 if (sym_idx
>= num_syms
) {
4731 sym
= symtab
.Resize(++num_syms
);
4732 stub_symbol
= nullptr; // this pointer no longer valid
4734 sym
[sym_idx
].SetID(synthetic_sym_id
++);
4735 sym
[sym_idx
].GetMangled() = stub_symbol_mangled_name
;
4736 if (resolver_addresses
.find(symbol_stub_addr
) ==
4737 resolver_addresses
.end())
4738 sym
[sym_idx
].SetType(eSymbolTypeTrampoline
);
4740 sym
[sym_idx
].SetType(eSymbolTypeResolver
);
4741 sym
[sym_idx
].SetIsSynthetic(true);
4742 sym
[sym_idx
].GetAddressRef() = so_addr
;
4743 add_symbol_addr(so_addr
.GetFileAddress());
4744 sym
[sym_idx
].SetByteSize(symbol_stub_byte_size
);
4749 log
->Warning("symbol stub referencing symbol table symbol "
4750 "%u that isn't in our minimal symbol table, "
4761 if (!reexport_trie_entries
.empty()) {
4762 for (const auto &e
: reexport_trie_entries
) {
4763 if (e
.entry
.import_name
) {
4764 // Only add indirect symbols from the Trie entries if we didn't have
4765 // a N_INDR nlist entry for this already
4766 if (indirect_symbol_names
.find(e
.entry
.name
) ==
4767 indirect_symbol_names
.end()) {
4768 // Make a synthetic symbol to describe re-exported symbol.
4769 if (sym_idx
>= num_syms
)
4770 sym
= symtab
.Resize(++num_syms
);
4771 sym
[sym_idx
].SetID(synthetic_sym_id
++);
4772 sym
[sym_idx
].GetMangled() = Mangled(e
.entry
.name
);
4773 sym
[sym_idx
].SetType(eSymbolTypeReExported
);
4774 sym
[sym_idx
].SetIsSynthetic(true);
4775 sym
[sym_idx
].SetReExportedSymbolName(e
.entry
.import_name
);
4776 if (e
.entry
.other
> 0 && e
.entry
.other
<= dylib_files
.GetSize()) {
4777 sym
[sym_idx
].SetReExportedSymbolSharedLibrary(
4778 dylib_files
.GetFileSpecAtIndex(e
.entry
.other
- 1));
4787 void ObjectFileMachO::Dump(Stream
*s
) {
4788 ModuleSP
module_sp(GetModule());
4790 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
4791 s
->Printf("%p: ", static_cast<void *>(this));
4793 if (m_header
.magic
== MH_MAGIC_64
|| m_header
.magic
== MH_CIGAM_64
)
4794 s
->PutCString("ObjectFileMachO64");
4796 s
->PutCString("ObjectFileMachO32");
4798 *s
<< ", file = '" << m_file
;
4799 ModuleSpecList all_specs
;
4800 ModuleSpec base_spec
;
4801 GetAllArchSpecs(m_header
, m_data
, MachHeaderSizeFromMagic(m_header
.magic
),
4802 base_spec
, all_specs
);
4803 for (unsigned i
= 0, e
= all_specs
.GetSize(); i
!= e
; ++i
) {
4806 s
->Printf("[%d]", i
);
4808 *s
<< all_specs
.GetModuleSpecRefAtIndex(i
)
4814 SectionList
*sections
= GetSectionList();
4816 sections
->Dump(s
->AsRawOstream(), s
->GetIndentLevel(), nullptr, true,
4820 m_symtab_up
->Dump(s
, nullptr, eSortOrderNone
);
4824 UUID
ObjectFileMachO::GetUUID(const llvm::MachO::mach_header
&header
,
4825 const lldb_private::DataExtractor
&data
,
4826 lldb::offset_t lc_offset
) {
4828 llvm::MachO::uuid_command load_cmd
;
4830 lldb::offset_t offset
= lc_offset
;
4831 for (i
= 0; i
< header
.ncmds
; ++i
) {
4832 const lldb::offset_t cmd_offset
= offset
;
4833 if (data
.GetU32(&offset
, &load_cmd
, 2) == nullptr)
4836 if (load_cmd
.cmd
== LC_UUID
) {
4837 const uint8_t *uuid_bytes
= data
.PeekData(offset
, 16);
4840 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4841 // We pretend these object files have no UUID to prevent crashing.
4843 const uint8_t opencl_uuid
[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4844 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4845 0xbb, 0x14, 0xf0, 0x0d};
4847 if (!memcmp(uuid_bytes
, opencl_uuid
, 16))
4850 return UUID(uuid_bytes
, 16);
4854 offset
= cmd_offset
+ load_cmd
.cmdsize
;
4859 static llvm::StringRef
GetOSName(uint32_t cmd
) {
4861 case llvm::MachO::LC_VERSION_MIN_IPHONEOS
:
4862 return llvm::Triple::getOSTypeName(llvm::Triple::IOS
);
4863 case llvm::MachO::LC_VERSION_MIN_MACOSX
:
4864 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX
);
4865 case llvm::MachO::LC_VERSION_MIN_TVOS
:
4866 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS
);
4867 case llvm::MachO::LC_VERSION_MIN_WATCHOS
:
4868 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS
);
4870 llvm_unreachable("unexpected LC_VERSION load command");
4876 llvm::StringRef os_type
;
4877 llvm::StringRef environment
;
4878 OSEnv(uint32_t cmd
) {
4880 case llvm::MachO::PLATFORM_MACOS
:
4881 os_type
= llvm::Triple::getOSTypeName(llvm::Triple::MacOSX
);
4883 case llvm::MachO::PLATFORM_IOS
:
4884 os_type
= llvm::Triple::getOSTypeName(llvm::Triple::IOS
);
4886 case llvm::MachO::PLATFORM_TVOS
:
4887 os_type
= llvm::Triple::getOSTypeName(llvm::Triple::TvOS
);
4889 case llvm::MachO::PLATFORM_WATCHOS
:
4890 os_type
= llvm::Triple::getOSTypeName(llvm::Triple::WatchOS
);
4892 // TODO: add BridgeOS & DriverKit once in llvm/lib/Support/Triple.cpp
4893 // NEED_BRIDGEOS_TRIPLE
4894 // case llvm::MachO::PLATFORM_BRIDGEOS:
4895 // os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
4897 // case llvm::MachO::PLATFORM_DRIVERKIT:
4898 // os_type = llvm::Triple::getOSTypeName(llvm::Triple::DriverKit);
4900 case llvm::MachO::PLATFORM_MACCATALYST
:
4901 os_type
= llvm::Triple::getOSTypeName(llvm::Triple::IOS
);
4902 environment
= llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI
);
4904 case llvm::MachO::PLATFORM_IOSSIMULATOR
:
4905 os_type
= llvm::Triple::getOSTypeName(llvm::Triple::IOS
);
4907 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator
);
4909 case llvm::MachO::PLATFORM_TVOSSIMULATOR
:
4910 os_type
= llvm::Triple::getOSTypeName(llvm::Triple::TvOS
);
4912 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator
);
4914 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR
:
4915 os_type
= llvm::Triple::getOSTypeName(llvm::Triple::WatchOS
);
4917 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator
);
4920 Log
*log(GetLog(LLDBLog::Symbols
| LLDBLog::Process
));
4921 LLDB_LOGF(log
, "unsupported platform in LC_BUILD_VERSION");
4928 uint32_t major_version
, minor_version
, patch_version
;
4929 MinOS(uint32_t version
)
4930 : major_version(version
>> 16), minor_version((version
>> 8) & 0xffu
),
4931 patch_version(version
& 0xffu
) {}
4935 void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header
&header
,
4936 const lldb_private::DataExtractor
&data
,
4937 lldb::offset_t lc_offset
,
4938 ModuleSpec
&base_spec
,
4939 lldb_private::ModuleSpecList
&all_specs
) {
4940 auto &base_arch
= base_spec
.GetArchitecture();
4941 base_arch
.SetArchitecture(eArchTypeMachO
, header
.cputype
, header
.cpusubtype
);
4942 if (!base_arch
.IsValid())
4945 bool found_any
= false;
4946 auto add_triple
= [&](const llvm::Triple
&triple
) {
4947 auto spec
= base_spec
;
4948 spec
.GetArchitecture().GetTriple() = triple
;
4949 if (spec
.GetArchitecture().IsValid()) {
4950 spec
.GetUUID() = ObjectFileMachO::GetUUID(header
, data
, lc_offset
);
4951 all_specs
.Append(spec
);
4956 // Set OS to an unspecified unknown or a "*" so it can match any OS
4957 llvm::Triple base_triple
= base_arch
.GetTriple();
4958 base_triple
.setOS(llvm::Triple::UnknownOS
);
4959 base_triple
.setOSName(llvm::StringRef());
4961 if (header
.filetype
== MH_PRELOAD
) {
4962 if (header
.cputype
== CPU_TYPE_ARM
) {
4963 // If this is a 32-bit arm binary, and it's a standalone binary, force
4964 // the Vendor to Apple so we don't accidentally pick up the generic
4965 // armv7 ABI at runtime. Apple's armv7 ABI always uses r7 for the
4966 // frame pointer register; most other armv7 ABIs use a combination of
4968 base_triple
.setVendor(llvm::Triple::Apple
);
4970 // Set vendor to an unspecified unknown or a "*" so it can match any
4971 // vendor This is required for correct behavior of EFI debugging on
4973 base_triple
.setVendor(llvm::Triple::UnknownVendor
);
4974 base_triple
.setVendorName(llvm::StringRef());
4976 return add_triple(base_triple
);
4979 llvm::MachO::load_command load_cmd
;
4981 // See if there is an LC_VERSION_MIN_* load command that can give
4983 lldb::offset_t offset
= lc_offset
;
4984 for (uint32_t i
= 0; i
< header
.ncmds
; ++i
) {
4985 const lldb::offset_t cmd_offset
= offset
;
4986 if (data
.GetU32(&offset
, &load_cmd
, 2) == nullptr)
4989 llvm::MachO::version_min_command version_min
;
4990 switch (load_cmd
.cmd
) {
4991 case llvm::MachO::LC_VERSION_MIN_MACOSX
:
4992 case llvm::MachO::LC_VERSION_MIN_IPHONEOS
:
4993 case llvm::MachO::LC_VERSION_MIN_TVOS
:
4994 case llvm::MachO::LC_VERSION_MIN_WATCHOS
: {
4995 if (load_cmd
.cmdsize
!= sizeof(version_min
))
4997 if (data
.ExtractBytes(cmd_offset
, sizeof(version_min
),
4998 data
.GetByteOrder(), &version_min
) == 0)
5000 MinOS
min_os(version_min
.version
);
5001 llvm::SmallString
<32> os_name
;
5002 llvm::raw_svector_ostream
os(os_name
);
5003 os
<< GetOSName(load_cmd
.cmd
) << min_os
.major_version
<< '.'
5004 << min_os
.minor_version
<< '.' << min_os
.patch_version
;
5006 auto triple
= base_triple
;
5007 triple
.setOSName(os
.str());
5009 // Disambiguate legacy simulator platforms.
5010 if (load_cmd
.cmd
!= llvm::MachO::LC_VERSION_MIN_MACOSX
&&
5011 (base_triple
.getArch() == llvm::Triple::x86_64
||
5012 base_triple
.getArch() == llvm::Triple::x86
)) {
5013 // The combination of legacy LC_VERSION_MIN load command and
5014 // x86 architecture always indicates a simulator environment.
5015 // The combination of LC_VERSION_MIN and arm architecture only
5016 // appears for native binaries. Back-deploying simulator
5017 // binaries on Apple Silicon Macs use the modern unambigous
5018 // LC_BUILD_VERSION load commands; no special handling required.
5019 triple
.setEnvironment(llvm::Triple::Simulator
);
5028 offset
= cmd_offset
+ load_cmd
.cmdsize
;
5031 // See if there are LC_BUILD_VERSION load commands that can give
5034 for (uint32_t i
= 0; i
< header
.ncmds
; ++i
) {
5035 const lldb::offset_t cmd_offset
= offset
;
5036 if (data
.GetU32(&offset
, &load_cmd
, 2) == nullptr)
5040 if (load_cmd
.cmd
== llvm::MachO::LC_BUILD_VERSION
) {
5041 llvm::MachO::build_version_command build_version
;
5042 if (load_cmd
.cmdsize
< sizeof(build_version
)) {
5043 // Malformed load command.
5046 if (data
.ExtractBytes(cmd_offset
, sizeof(build_version
),
5047 data
.GetByteOrder(), &build_version
) == 0)
5049 MinOS
min_os(build_version
.minos
);
5050 OSEnv
os_env(build_version
.platform
);
5051 llvm::SmallString
<16> os_name
;
5052 llvm::raw_svector_ostream
os(os_name
);
5053 os
<< os_env
.os_type
<< min_os
.major_version
<< '.'
5054 << min_os
.minor_version
<< '.' << min_os
.patch_version
;
5055 auto triple
= base_triple
;
5056 triple
.setOSName(os
.str());
5058 if (!os_env
.environment
.empty())
5059 triple
.setEnvironmentName(os_env
.environment
);
5063 offset
= cmd_offset
+ load_cmd
.cmdsize
;
5067 add_triple(base_triple
);
5071 ArchSpec
ObjectFileMachO::GetArchitecture(
5072 ModuleSP module_sp
, const llvm::MachO::mach_header
&header
,
5073 const lldb_private::DataExtractor
&data
, lldb::offset_t lc_offset
) {
5074 ModuleSpecList all_specs
;
5075 ModuleSpec base_spec
;
5076 GetAllArchSpecs(header
, data
, MachHeaderSizeFromMagic(header
.magic
),
5077 base_spec
, all_specs
);
5079 // If the object file offers multiple alternative load commands,
5080 // pick the one that matches the module.
5082 const ArchSpec
&module_arch
= module_sp
->GetArchitecture();
5083 for (unsigned i
= 0, e
= all_specs
.GetSize(); i
!= e
; ++i
) {
5084 ArchSpec mach_arch
=
5085 all_specs
.GetModuleSpecRefAtIndex(i
).GetArchitecture();
5086 if (module_arch
.IsCompatibleMatch(mach_arch
))
5091 // Return the first arch we found.
5092 if (all_specs
.GetSize() == 0)
5094 return all_specs
.GetModuleSpecRefAtIndex(0).GetArchitecture();
5097 UUID
ObjectFileMachO::GetUUID() {
5098 ModuleSP
module_sp(GetModule());
5100 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5101 lldb::offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
5102 return GetUUID(m_header
, m_data
, offset
);
5107 uint32_t ObjectFileMachO::GetDependentModules(FileSpecList
&files
) {
5109 ModuleSP
module_sp(GetModule());
5111 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5112 llvm::MachO::load_command load_cmd
;
5113 lldb::offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
5114 std::vector
<std::string
> rpath_paths
;
5115 std::vector
<std::string
> rpath_relative_paths
;
5116 std::vector
<std::string
> at_exec_relative_paths
;
5118 for (i
= 0; i
< m_header
.ncmds
; ++i
) {
5119 const uint32_t cmd_offset
= offset
;
5120 if (m_data
.GetU32(&offset
, &load_cmd
, 2) == nullptr)
5123 switch (load_cmd
.cmd
) {
5126 case LC_LOAD_WEAK_DYLIB
:
5127 case LC_REEXPORT_DYLIB
:
5128 case LC_LOAD_DYLINKER
:
5130 case LC_LOAD_UPWARD_DYLIB
: {
5131 uint32_t name_offset
= cmd_offset
+ m_data
.GetU32(&offset
);
5132 const char *path
= m_data
.PeekCStr(name_offset
);
5134 if (load_cmd
.cmd
== LC_RPATH
)
5135 rpath_paths
.push_back(path
);
5137 if (path
[0] == '@') {
5138 if (strncmp(path
, "@rpath", strlen("@rpath")) == 0)
5139 rpath_relative_paths
.push_back(path
+ strlen("@rpath"));
5140 else if (strncmp(path
, "@executable_path",
5141 strlen("@executable_path")) == 0)
5142 at_exec_relative_paths
.push_back(path
+
5143 strlen("@executable_path"));
5145 FileSpec
file_spec(path
);
5146 if (files
.AppendIfUnique(file_spec
))
5156 offset
= cmd_offset
+ load_cmd
.cmdsize
;
5159 FileSpec
this_file_spec(m_file
);
5160 FileSystem::Instance().Resolve(this_file_spec
);
5162 if (!rpath_paths
.empty()) {
5163 // Fixup all LC_RPATH values to be absolute paths
5164 std::string
loader_path("@loader_path");
5165 std::string
executable_path("@executable_path");
5166 for (auto &rpath
: rpath_paths
) {
5167 if (llvm::StringRef(rpath
).startswith(loader_path
)) {
5168 rpath
.erase(0, loader_path
.size());
5169 rpath
.insert(0, this_file_spec
.GetDirectory().GetCString());
5170 } else if (llvm::StringRef(rpath
).startswith(executable_path
)) {
5171 rpath
.erase(0, executable_path
.size());
5172 rpath
.insert(0, this_file_spec
.GetDirectory().GetCString());
5176 for (const auto &rpath_relative_path
: rpath_relative_paths
) {
5177 for (const auto &rpath
: rpath_paths
) {
5178 std::string path
= rpath
;
5179 path
+= rpath_relative_path
;
5180 // It is OK to resolve this path because we must find a file on disk
5181 // for us to accept it anyway if it is rpath relative.
5182 FileSpec
file_spec(path
);
5183 FileSystem::Instance().Resolve(file_spec
);
5184 if (FileSystem::Instance().Exists(file_spec
) &&
5185 files
.AppendIfUnique(file_spec
)) {
5193 // We may have @executable_paths but no RPATHS. Figure those out here.
5194 // Only do this if this object file is the executable. We have no way to
5195 // get back to the actual executable otherwise, so we won't get the right
5197 if (!at_exec_relative_paths
.empty() && CalculateType() == eTypeExecutable
) {
5198 FileSpec exec_dir
= this_file_spec
.CopyByRemovingLastPathComponent();
5199 for (const auto &at_exec_relative_path
: at_exec_relative_paths
) {
5200 FileSpec file_spec
=
5201 exec_dir
.CopyByAppendingPathComponent(at_exec_relative_path
);
5202 if (FileSystem::Instance().Exists(file_spec
) &&
5203 files
.AppendIfUnique(file_spec
))
5211 lldb_private::Address
ObjectFileMachO::GetEntryPointAddress() {
5212 // If the object file is not an executable it can't hold the entry point.
5213 // m_entry_point_address is initialized to an invalid address, so we can just
5214 // return that. If m_entry_point_address is valid it means we've found it
5215 // already, so return the cached value.
5217 if ((!IsExecutable() && !IsDynamicLoader()) ||
5218 m_entry_point_address
.IsValid()) {
5219 return m_entry_point_address
;
5222 // Otherwise, look for the UnixThread or Thread command. The data for the
5223 // Thread command is given in /usr/include/mach-o.h, but it is basically:
5225 // uint32_t flavor - this is the flavor argument you would pass to
5227 // uint32_t count - this is the count of longs in the thread state data
5228 // struct XXX_thread_state state - this is the structure from
5229 // <machine/thread_status.h> corresponding to the flavor.
5230 // <repeat this trio>
5232 // So we just keep reading the various register flavors till we find the GPR
5233 // one, then read the PC out of there.
5234 // FIXME: We will need to have a "RegisterContext data provider" class at some
5235 // point that can get all the registers
5236 // out of data in this form & attach them to a given thread. That should
5237 // underlie the MacOS X User process plugin, and we'll also need it for the
5238 // MacOS X Core File process plugin. When we have that we can also use it
5241 // For now we hard-code the offsets and flavors we need:
5245 ModuleSP
module_sp(GetModule());
5247 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5248 llvm::MachO::load_command load_cmd
;
5249 lldb::offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
5251 lldb::addr_t start_address
= LLDB_INVALID_ADDRESS
;
5254 for (i
= 0; i
< m_header
.ncmds
; ++i
) {
5255 const lldb::offset_t cmd_offset
= offset
;
5256 if (m_data
.GetU32(&offset
, &load_cmd
, 2) == nullptr)
5259 switch (load_cmd
.cmd
) {
5262 while (offset
< cmd_offset
+ load_cmd
.cmdsize
) {
5263 uint32_t flavor
= m_data
.GetU32(&offset
);
5264 uint32_t count
= m_data
.GetU32(&offset
);
5266 // We've gotten off somehow, log and exit;
5267 return m_entry_point_address
;
5270 switch (m_header
.cputype
) {
5271 case llvm::MachO::CPU_TYPE_ARM
:
5273 flavor
== 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32
5274 // from mach/arm/thread_status.h
5276 offset
+= 60; // This is the offset of pc in the GPR thread state
5278 start_address
= m_data
.GetU32(&offset
);
5282 case llvm::MachO::CPU_TYPE_ARM64
:
5283 case llvm::MachO::CPU_TYPE_ARM64_32
:
5284 if (flavor
== 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
5286 offset
+= 256; // This is the offset of pc in the GPR thread state
5288 start_address
= m_data
.GetU64(&offset
);
5292 case llvm::MachO::CPU_TYPE_I386
:
5294 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
5296 offset
+= 40; // This is the offset of eip in the GPR thread state
5298 start_address
= m_data
.GetU32(&offset
);
5302 case llvm::MachO::CPU_TYPE_X86_64
:
5304 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
5306 offset
+= 16 * 8; // This is the offset of rip in the GPR thread
5307 // state data structure.
5308 start_address
= m_data
.GetU64(&offset
);
5313 return m_entry_point_address
;
5315 // Haven't found the GPR flavor yet, skip over the data for this
5319 offset
+= count
* 4;
5323 uint64_t entryoffset
= m_data
.GetU64(&offset
);
5324 SectionSP text_segment_sp
=
5325 GetSectionList()->FindSectionByName(GetSegmentNameTEXT());
5326 if (text_segment_sp
) {
5328 start_address
= text_segment_sp
->GetFileAddress() + entryoffset
;
5338 // Go to the next load command:
5339 offset
= cmd_offset
+ load_cmd
.cmdsize
;
5342 if (start_address
== LLDB_INVALID_ADDRESS
&& IsDynamicLoader()) {
5344 Symbol
*dyld_start_sym
= GetSymtab()->FindFirstSymbolWithNameAndType(
5345 ConstString("_dyld_start"), SymbolType::eSymbolTypeCode
,
5346 Symtab::eDebugAny
, Symtab::eVisibilityAny
);
5347 if (dyld_start_sym
&& dyld_start_sym
->GetAddress().IsValid()) {
5348 start_address
= dyld_start_sym
->GetAddress().GetFileAddress();
5353 if (start_address
!= LLDB_INVALID_ADDRESS
) {
5354 // We got the start address from the load commands, so now resolve that
5355 // address in the sections of this ObjectFile:
5356 if (!m_entry_point_address
.ResolveAddressUsingFileSections(
5357 start_address
, GetSectionList())) {
5358 m_entry_point_address
.Clear();
5361 // We couldn't read the UnixThread load command - maybe it wasn't there.
5362 // As a fallback look for the "start" symbol in the main executable.
5364 ModuleSP
module_sp(GetModule());
5367 SymbolContextList contexts
;
5368 SymbolContext context
;
5369 module_sp
->FindSymbolsWithNameAndType(ConstString("start"),
5370 eSymbolTypeCode
, contexts
);
5371 if (contexts
.GetSize()) {
5372 if (contexts
.GetContextAtIndex(0, context
))
5373 m_entry_point_address
= context
.symbol
->GetAddress();
5379 return m_entry_point_address
;
5382 lldb_private::Address
ObjectFileMachO::GetBaseAddress() {
5383 lldb_private::Address header_addr
;
5384 SectionList
*section_list
= GetSectionList();
5386 SectionSP
text_segment_sp(
5387 section_list
->FindSectionByName(GetSegmentNameTEXT()));
5388 if (text_segment_sp
) {
5389 header_addr
.SetSection(text_segment_sp
);
5390 header_addr
.SetOffset(0);
5396 uint32_t ObjectFileMachO::GetNumThreadContexts() {
5397 ModuleSP
module_sp(GetModule());
5399 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5400 if (!m_thread_context_offsets_valid
) {
5401 m_thread_context_offsets_valid
= true;
5402 lldb::offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
5403 FileRangeArray::Entry file_range
;
5404 llvm::MachO::thread_command thread_cmd
;
5405 for (uint32_t i
= 0; i
< m_header
.ncmds
; ++i
) {
5406 const uint32_t cmd_offset
= offset
;
5407 if (m_data
.GetU32(&offset
, &thread_cmd
, 2) == nullptr)
5410 if (thread_cmd
.cmd
== LC_THREAD
) {
5411 file_range
.SetRangeBase(offset
);
5412 file_range
.SetByteSize(thread_cmd
.cmdsize
- 8);
5413 m_thread_context_offsets
.Append(file_range
);
5415 offset
= cmd_offset
+ thread_cmd
.cmdsize
;
5419 return m_thread_context_offsets
.GetSize();
5422 std::vector
<std::tuple
<offset_t
, offset_t
>>
5423 ObjectFileMachO::FindLC_NOTEByName(std::string name
) {
5424 std::vector
<std::tuple
<offset_t
, offset_t
>> results
;
5425 ModuleSP
module_sp(GetModule());
5427 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5429 offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
5430 for (uint32_t i
= 0; i
< m_header
.ncmds
; ++i
) {
5431 const uint32_t cmd_offset
= offset
;
5432 llvm::MachO::load_command lc
= {};
5433 if (m_data
.GetU32(&offset
, &lc
.cmd
, 2) == nullptr)
5435 if (lc
.cmd
== LC_NOTE
) {
5436 char data_owner
[17];
5437 m_data
.CopyData(offset
, 16, data_owner
);
5438 data_owner
[16] = '\0';
5441 if (name
== data_owner
) {
5442 offset_t payload_offset
= m_data
.GetU64_unchecked(&offset
);
5443 offset_t payload_size
= m_data
.GetU64_unchecked(&offset
);
5444 results
.push_back({payload_offset
, payload_size
});
5447 offset
= cmd_offset
+ lc
.cmdsize
;
5453 std::string
ObjectFileMachO::GetIdentifierString() {
5455 GetLog(LLDBLog::Symbols
| LLDBLog::Process
| LLDBLog::DynamicLoader
));
5456 ModuleSP
module_sp(GetModule());
5458 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5460 auto lc_notes
= FindLC_NOTEByName("kern ver str");
5461 for (auto lc_note
: lc_notes
) {
5462 offset_t payload_offset
= std::get
<0>(lc_note
);
5463 offset_t payload_size
= std::get
<1>(lc_note
);
5465 if (m_data
.GetU32(&payload_offset
, &version
, 1) != nullptr) {
5467 uint32_t strsize
= payload_size
- sizeof(uint32_t);
5468 std::string
result(strsize
, '\0');
5469 m_data
.CopyData(payload_offset
, strsize
, result
.data());
5470 while (result
.back() == '\0')
5471 result
.resize(result
.size() - 1);
5472 LLDB_LOGF(log
, "LC_NOTE 'kern ver str' found with text '%s'",
5479 // Second, make a pass over the load commands looking for an obsolete
5480 // LC_IDENT load command.
5481 offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
5482 for (uint32_t i
= 0; i
< m_header
.ncmds
; ++i
) {
5483 const uint32_t cmd_offset
= offset
;
5484 llvm::MachO::ident_command ident_command
;
5485 if (m_data
.GetU32(&offset
, &ident_command
, 2) == nullptr)
5487 if (ident_command
.cmd
== LC_IDENT
&& ident_command
.cmdsize
!= 0) {
5488 std::string
result(ident_command
.cmdsize
, '\0');
5489 if (m_data
.CopyData(offset
, ident_command
.cmdsize
, result
.data()) ==
5490 ident_command
.cmdsize
) {
5491 while (result
.back() == '\0')
5492 result
.resize(result
.size() - 1);
5493 LLDB_LOGF(log
, "LC_IDENT found with text '%s'", result
.c_str());
5497 offset
= cmd_offset
+ ident_command
.cmdsize
;
5503 AddressableBits
ObjectFileMachO::GetAddressableBits() {
5504 AddressableBits addressable_bits
;
5506 Log
*log(GetLog(LLDBLog::Process
));
5507 ModuleSP
module_sp(GetModule());
5509 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5510 auto lc_notes
= FindLC_NOTEByName("addrable bits");
5511 for (auto lc_note
: lc_notes
) {
5512 offset_t payload_offset
= std::get
<0>(lc_note
);
5514 if (m_data
.GetU32(&payload_offset
, &version
, 1) != nullptr) {
5516 uint32_t num_addr_bits
= m_data
.GetU32_unchecked(&payload_offset
);
5517 addressable_bits
.SetAddressableBits(num_addr_bits
);
5519 "LC_NOTE 'addrable bits' v3 found, value %d "
5524 uint32_t lo_addr_bits
= m_data
.GetU32_unchecked(&payload_offset
);
5525 uint32_t hi_addr_bits
= m_data
.GetU32_unchecked(&payload_offset
);
5527 if (lo_addr_bits
== hi_addr_bits
)
5528 addressable_bits
.SetAddressableBits(lo_addr_bits
);
5530 addressable_bits
.SetAddressableBits(lo_addr_bits
, hi_addr_bits
);
5531 LLDB_LOGF(log
, "LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
5532 lo_addr_bits
, hi_addr_bits
);
5537 return addressable_bits
;
5540 bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t
&value
,
5541 bool &value_is_offset
,
5543 ObjectFile::BinaryType
&type
) {
5545 GetLog(LLDBLog::Symbols
| LLDBLog::Process
| LLDBLog::DynamicLoader
));
5546 value
= LLDB_INVALID_ADDRESS
;
5547 value_is_offset
= false;
5549 uint32_t log2_pagesize
= 0; // not currently passed up to caller
5550 uint32_t platform
= 0; // not currently passed up to caller
5551 ModuleSP
module_sp(GetModule());
5553 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5555 auto lc_notes
= FindLC_NOTEByName("main bin spec");
5556 for (auto lc_note
: lc_notes
) {
5557 offset_t payload_offset
= std::get
<0>(lc_note
);
5559 // struct main_bin_spec
5561 // uint32_t version; // currently 2
5562 // uint32_t type; // 0 == unspecified, 1 == kernel,
5563 // // 2 == user process,
5564 // // 3 == standalone binary
5565 // uint64_t address; // UINT64_MAX if address not specified
5566 // uint64_t slide; // slide, UINT64_MAX if unspecified
5567 // // 0 if no slide needs to be applied to
5569 // uuid_t uuid; // all zero's if uuid not specified
5570 // uint32_t log2_pagesize; // process page size in log base 2,
5571 // // e.g. 4k pages are 12.
5572 // // 0 for unspecified
5573 // uint32_t platform; // The Mach-O platform for this corefile.
5574 // // 0 for unspecified.
5575 // // The values are defined in
5576 // // <mach-o/loader.h>, PLATFORM_*.
5577 // } __attribute((packed));
5579 // "main bin spec" (main binary specification) data payload is
5581 // uint32_t version [currently 1]
5582 // uint32_t type [0 == unspecified, 1 == kernel,
5583 // 2 == user process, 3 == firmware ]
5584 // uint64_t address [ UINT64_MAX if address not specified ]
5585 // uuid_t uuid [ all zero's if uuid not specified ]
5586 // uint32_t log2_pagesize [ process page size in log base
5587 // 2, e.g. 4k pages are 12.
5588 // 0 for unspecified ]
5589 // uint32_t unused [ for alignment ]
5592 if (m_data
.GetU32(&payload_offset
, &version
, 1) != nullptr &&
5594 uint32_t binspec_type
= 0;
5596 memset(raw_uuid
, 0, sizeof(uuid_t
));
5598 if (!m_data
.GetU32(&payload_offset
, &binspec_type
, 1))
5600 if (!m_data
.GetU64(&payload_offset
, &value
, 1))
5602 uint64_t slide
= LLDB_INVALID_ADDRESS
;
5603 if (version
> 1 && !m_data
.GetU64(&payload_offset
, &slide
, 1))
5605 if (value
== LLDB_INVALID_ADDRESS
&& slide
!= LLDB_INVALID_ADDRESS
) {
5607 value_is_offset
= true;
5610 if (m_data
.CopyData(payload_offset
, sizeof(uuid_t
), raw_uuid
) != 0) {
5611 uuid
= UUID(raw_uuid
, sizeof(uuid_t
));
5612 // convert the "main bin spec" type into our
5613 // ObjectFile::BinaryType enum
5614 const char *typestr
= "unrecognized type";
5615 switch (binspec_type
) {
5617 type
= eBinaryTypeUnknown
;
5621 type
= eBinaryTypeKernel
;
5622 typestr
= "xnu kernel";
5625 type
= eBinaryTypeUser
;
5626 typestr
= "userland dyld";
5629 type
= eBinaryTypeStandalone
;
5630 typestr
= "standalone";
5634 "LC_NOTE 'main bin spec' found, version %d type %d "
5635 "(%s), value 0x%" PRIx64
" value-is-slide==%s uuid %s",
5636 version
, type
, typestr
, value
,
5637 value_is_offset
? "true" : "false",
5638 uuid
.GetAsString().c_str());
5639 if (!m_data
.GetU32(&payload_offset
, &log2_pagesize
, 1))
5641 if (version
> 1 && !m_data
.GetU32(&payload_offset
, &platform
, 1))
5651 bool ObjectFileMachO::GetCorefileThreadExtraInfos(std::vector
<tid_t
> &tids
) {
5653 ModuleSP
module_sp(GetModule());
5655 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5657 Log
*log(GetLog(LLDBLog::Object
| LLDBLog::Process
| LLDBLog::Thread
));
5658 auto lc_notes
= FindLC_NOTEByName("process metadata");
5659 for (auto lc_note
: lc_notes
) {
5660 offset_t payload_offset
= std::get
<0>(lc_note
);
5661 offset_t strsize
= std::get
<1>(lc_note
);
5662 std::string
buf(strsize
, '\0');
5663 if (m_data
.CopyData(payload_offset
, strsize
, buf
.data()) != strsize
) {
5665 "Unable to read %" PRIu64
5666 " bytes of 'process metadata' LC_NOTE JSON contents",
5670 while (buf
.back() == '\0')
5671 buf
.resize(buf
.size() - 1);
5672 StructuredData::ObjectSP object_sp
= StructuredData::ParseJSON(buf
);
5673 StructuredData::Dictionary
*dict
= object_sp
->GetAsDictionary();
5675 LLDB_LOGF(log
, "Unable to read 'process metadata' LC_NOTE, did not "
5676 "get a dictionary.");
5679 StructuredData::Array
*threads
;
5680 if (!dict
->GetValueForKeyAsArray("threads", threads
) || !threads
) {
5682 "'process metadata' LC_NOTE does not have a 'threads' key");
5685 if (threads
->GetSize() != GetNumThreadContexts()) {
5686 LLDB_LOGF(log
, "Unable to read 'process metadata' LC_NOTE, number of "
5687 "threads does not match number of LC_THREADS.");
5690 const size_t num_threads
= threads
->GetSize();
5691 for (size_t i
= 0; i
< num_threads
; i
++) {
5692 StructuredData::Dictionary
*thread
;
5693 if (!threads
->GetItemAtIndexAsDictionary(i
, thread
) || !thread
) {
5695 "Unable to read 'process metadata' LC_NOTE, threads "
5696 "array does not have a dictionary at index %zu.",
5700 tid_t tid
= LLDB_INVALID_THREAD_ID
;
5701 if (thread
->GetValueForKeyAsInteger
<tid_t
>("thread_id", tid
))
5703 tid
= LLDB_INVALID_THREAD_ID
;
5704 tids
.push_back(tid
);
5708 StreamString logmsg
;
5709 logmsg
.Printf("LC_NOTE 'process metadata' found: ");
5710 dict
->Dump(logmsg
, /* pretty_print */ false);
5711 LLDB_LOGF(log
, "%s", logmsg
.GetData());
5719 lldb::RegisterContextSP
5720 ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx
,
5721 lldb_private::Thread
&thread
) {
5722 lldb::RegisterContextSP reg_ctx_sp
;
5724 ModuleSP
module_sp(GetModule());
5726 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5727 if (!m_thread_context_offsets_valid
)
5728 GetNumThreadContexts();
5730 const FileRangeArray::Entry
*thread_context_file_range
=
5731 m_thread_context_offsets
.GetEntryAtIndex(idx
);
5732 if (thread_context_file_range
) {
5734 DataExtractor
data(m_data
, thread_context_file_range
->GetRangeBase(),
5735 thread_context_file_range
->GetByteSize());
5737 switch (m_header
.cputype
) {
5738 case llvm::MachO::CPU_TYPE_ARM64
:
5739 case llvm::MachO::CPU_TYPE_ARM64_32
:
5741 std::make_shared
<RegisterContextDarwin_arm64_Mach
>(thread
, data
);
5744 case llvm::MachO::CPU_TYPE_ARM
:
5746 std::make_shared
<RegisterContextDarwin_arm_Mach
>(thread
, data
);
5749 case llvm::MachO::CPU_TYPE_I386
:
5751 std::make_shared
<RegisterContextDarwin_i386_Mach
>(thread
, data
);
5754 case llvm::MachO::CPU_TYPE_X86_64
:
5756 std::make_shared
<RegisterContextDarwin_x86_64_Mach
>(thread
, data
);
5764 ObjectFile::Type
ObjectFileMachO::CalculateType() {
5765 switch (m_header
.filetype
) {
5766 case MH_OBJECT
: // 0x1u
5767 if (GetAddressByteSize() == 4) {
5768 // 32 bit kexts are just object files, but they do have a valid
5769 // UUID load command.
5771 // this checking for the UUID load command is not enough we could
5772 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
5773 // this is required of kexts
5774 if (m_strata
== eStrataInvalid
)
5775 m_strata
= eStrataKernel
;
5776 return eTypeSharedLibrary
;
5779 return eTypeObjectFile
;
5782 return eTypeExecutable
; // 0x2u
5784 return eTypeSharedLibrary
; // 0x3u
5786 return eTypeCoreFile
; // 0x4u
5788 return eTypeSharedLibrary
; // 0x5u
5790 return eTypeSharedLibrary
; // 0x6u
5792 return eTypeDynamicLinker
; // 0x7u
5794 return eTypeSharedLibrary
; // 0x8u
5796 return eTypeStubLibrary
; // 0x9u
5798 return eTypeDebugInfo
; // 0xAu
5799 case MH_KEXT_BUNDLE
:
5800 return eTypeSharedLibrary
; // 0xBu
5804 return eTypeUnknown
;
5807 ObjectFile::Strata
ObjectFileMachO::CalculateStrata() {
5808 switch (m_header
.filetype
) {
5809 case MH_OBJECT
: // 0x1u
5811 // 32 bit kexts are just object files, but they do have a valid
5812 // UUID load command.
5814 // this checking for the UUID load command is not enough we could
5815 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
5816 // this is required of kexts
5817 if (m_type
== eTypeInvalid
)
5818 m_type
= eTypeSharedLibrary
;
5820 return eStrataKernel
;
5823 return eStrataUnknown
;
5825 case MH_EXECUTE
: // 0x2u
5826 // Check for the MH_DYLDLINK bit in the flags
5827 if (m_header
.flags
& MH_DYLDLINK
) {
5830 SectionList
*section_list
= GetSectionList();
5832 static ConstString
g_kld_section_name("__KLD");
5833 if (section_list
->FindSectionByName(g_kld_section_name
))
5834 return eStrataKernel
;
5837 return eStrataRawImage
;
5840 return eStrataUser
; // 0x3u
5842 return eStrataUnknown
; // 0x4u
5844 return eStrataRawImage
; // 0x5u
5846 return eStrataUser
; // 0x6u
5848 return eStrataUser
; // 0x7u
5850 return eStrataUser
; // 0x8u
5852 return eStrataUser
; // 0x9u
5854 return eStrataUnknown
; // 0xAu
5855 case MH_KEXT_BUNDLE
:
5856 return eStrataKernel
; // 0xBu
5860 return eStrataUnknown
;
5863 llvm::VersionTuple
ObjectFileMachO::GetVersion() {
5864 ModuleSP
module_sp(GetModule());
5866 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5867 llvm::MachO::dylib_command load_cmd
;
5868 lldb::offset_t offset
= MachHeaderSizeFromMagic(m_header
.magic
);
5869 uint32_t version_cmd
= 0;
5870 uint64_t version
= 0;
5872 for (i
= 0; i
< m_header
.ncmds
; ++i
) {
5873 const lldb::offset_t cmd_offset
= offset
;
5874 if (m_data
.GetU32(&offset
, &load_cmd
, 2) == nullptr)
5877 if (load_cmd
.cmd
== LC_ID_DYLIB
) {
5878 if (version_cmd
== 0) {
5879 version_cmd
= load_cmd
.cmd
;
5880 if (m_data
.GetU32(&offset
, &load_cmd
.dylib
, 4) == nullptr)
5882 version
= load_cmd
.dylib
.current_version
;
5884 break; // Break for now unless there is another more complete version
5885 // number load command in the future.
5887 offset
= cmd_offset
+ load_cmd
.cmdsize
;
5890 if (version_cmd
== LC_ID_DYLIB
) {
5891 unsigned major
= (version
& 0xFFFF0000ull
) >> 16;
5892 unsigned minor
= (version
& 0x0000FF00ull
) >> 8;
5893 unsigned subminor
= (version
& 0x000000FFull
);
5894 return llvm::VersionTuple(major
, minor
, subminor
);
5897 return llvm::VersionTuple();
5900 ArchSpec
ObjectFileMachO::GetArchitecture() {
5901 ModuleSP
module_sp(GetModule());
5904 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
5906 return GetArchitecture(module_sp
, m_header
, m_data
,
5907 MachHeaderSizeFromMagic(m_header
.magic
));
5912 void ObjectFileMachO::GetProcessSharedCacheUUID(Process
*process
,
5913 addr_t
&base_addr
, UUID
&uuid
) {
5915 base_addr
= LLDB_INVALID_ADDRESS
;
5916 if (process
&& process
->GetDynamicLoader()) {
5917 DynamicLoader
*dl
= process
->GetDynamicLoader();
5918 LazyBool using_shared_cache
;
5919 LazyBool private_shared_cache
;
5920 dl
->GetSharedCacheInformation(base_addr
, uuid
, using_shared_cache
,
5921 private_shared_cache
);
5923 Log
*log(GetLog(LLDBLog::Symbols
| LLDBLog::Process
));
5926 "inferior process shared cache has a UUID of %s, base address 0x%" PRIx64
,
5927 uuid
.GetAsString().c_str(), base_addr
);
5930 // From dyld SPI header dyld_process_info.h
5931 typedef void *dyld_process_info
;
5932 struct lldb_copy__dyld_process_cache_info
{
5933 uuid_t cacheUUID
; // UUID of cache used by process
5934 uint64_t cacheBaseAddress
; // load address of dyld shared cache
5935 bool noCache
; // process is running without a dyld cache
5936 bool privateCache
; // process is using a private copy of its dyld cache
5939 // #including mach/mach.h pulls in machine.h & CPU_TYPE_ARM etc conflicts with
5940 // llvm enum definitions llvm::MachO::CPU_TYPE_ARM turning them into compile
5941 // errors. So we need to use the actual underlying types of task_t and
5942 // kern_return_t below.
5943 extern "C" unsigned int /*task_t*/ mach_task_self();
5945 void ObjectFileMachO::GetLLDBSharedCacheUUID(addr_t
&base_addr
, UUID
&uuid
) {
5947 base_addr
= LLDB_INVALID_ADDRESS
;
5949 #if defined(__APPLE__)
5950 uint8_t *(*dyld_get_all_image_infos
)(void);
5951 dyld_get_all_image_infos
=
5952 (uint8_t * (*)()) dlsym(RTLD_DEFAULT
, "_dyld_get_all_image_infos");
5953 if (dyld_get_all_image_infos
) {
5954 uint8_t *dyld_all_image_infos_address
= dyld_get_all_image_infos();
5955 if (dyld_all_image_infos_address
) {
5956 uint32_t *version
= (uint32_t *)
5957 dyld_all_image_infos_address
; // version <mach-o/dyld_images.h>
5958 if (*version
>= 13) {
5959 uuid_t
*sharedCacheUUID_address
= 0;
5960 int wordsize
= sizeof(uint8_t *);
5961 if (wordsize
== 8) {
5962 sharedCacheUUID_address
=
5963 (uuid_t
*)((uint8_t *)dyld_all_image_infos_address
+
5964 160); // sharedCacheUUID <mach-o/dyld_images.h>
5968 *)((uint8_t *)dyld_all_image_infos_address
+
5969 176); // sharedCacheBaseAddress <mach-o/dyld_images.h>
5971 sharedCacheUUID_address
=
5972 (uuid_t
*)((uint8_t *)dyld_all_image_infos_address
+
5973 84); // sharedCacheUUID <mach-o/dyld_images.h>
5974 if (*version
>= 15) {
5978 *)((uint8_t *)dyld_all_image_infos_address
+
5979 100); // sharedCacheBaseAddress <mach-o/dyld_images.h>
5982 uuid
= UUID(sharedCacheUUID_address
, sizeof(uuid_t
));
5986 // Exists in macOS 10.12 and later, iOS 10.0 and later - dyld SPI
5987 dyld_process_info (*dyld_process_info_create
)(
5988 unsigned int /* task_t */ task
, uint64_t timestamp
,
5989 unsigned int /*kern_return_t*/ *kernelError
);
5990 void (*dyld_process_info_get_cache
)(void *info
, void *cacheInfo
);
5991 void (*dyld_process_info_release
)(dyld_process_info info
);
5993 dyld_process_info_create
= (void *(*)(unsigned int /* task_t */, uint64_t,
5994 unsigned int /*kern_return_t*/ *))
5995 dlsym(RTLD_DEFAULT
, "_dyld_process_info_create");
5996 dyld_process_info_get_cache
= (void (*)(void *, void *))dlsym(
5997 RTLD_DEFAULT
, "_dyld_process_info_get_cache");
5998 dyld_process_info_release
=
5999 (void (*)(void *))dlsym(RTLD_DEFAULT
, "_dyld_process_info_release");
6001 if (dyld_process_info_create
&& dyld_process_info_get_cache
) {
6002 unsigned int /*kern_return_t */ kern_ret
;
6003 dyld_process_info process_info
=
6004 dyld_process_info_create(::mach_task_self(), 0, &kern_ret
);
6006 struct lldb_copy__dyld_process_cache_info sc_info
;
6007 memset(&sc_info
, 0, sizeof(struct lldb_copy__dyld_process_cache_info
));
6008 dyld_process_info_get_cache(process_info
, &sc_info
);
6009 if (sc_info
.cacheBaseAddress
!= 0) {
6010 base_addr
= sc_info
.cacheBaseAddress
;
6011 uuid
= UUID(sc_info
.cacheUUID
, sizeof(uuid_t
));
6013 dyld_process_info_release(process_info
);
6017 Log
*log(GetLog(LLDBLog::Symbols
| LLDBLog::Process
));
6018 if (log
&& uuid
.IsValid())
6020 "lldb's in-memory shared cache has a UUID of %s base address of "
6022 uuid
.GetAsString().c_str(), base_addr
);
6026 static llvm::VersionTuple
FindMinimumVersionInfo(DataExtractor
&data
,
6027 lldb::offset_t offset
,
6029 for (size_t i
= 0; i
< ncmds
; i
++) {
6030 const lldb::offset_t load_cmd_offset
= offset
;
6031 llvm::MachO::load_command lc
= {};
6032 if (data
.GetU32(&offset
, &lc
.cmd
, 2) == nullptr)
6035 uint32_t version
= 0;
6036 if (lc
.cmd
== llvm::MachO::LC_VERSION_MIN_MACOSX
||
6037 lc
.cmd
== llvm::MachO::LC_VERSION_MIN_IPHONEOS
||
6038 lc
.cmd
== llvm::MachO::LC_VERSION_MIN_TVOS
||
6039 lc
.cmd
== llvm::MachO::LC_VERSION_MIN_WATCHOS
) {
6040 // struct version_min_command {
6041 // uint32_t cmd; // LC_VERSION_MIN_*
6042 // uint32_t cmdsize;
6043 // uint32_t version; // X.Y.Z encoded in nibbles xxxx.yy.zz
6046 // We want to read version.
6047 version
= data
.GetU32(&offset
);
6048 } else if (lc
.cmd
== llvm::MachO::LC_BUILD_VERSION
) {
6049 // struct build_version_command {
6050 // uint32_t cmd; // LC_BUILD_VERSION
6051 // uint32_t cmdsize;
6052 // uint32_t platform;
6053 // uint32_t minos; // X.Y.Z encoded in nibbles xxxx.yy.zz
6057 // We want to read minos.
6058 offset
+= sizeof(uint32_t); // Skip over platform
6059 version
= data
.GetU32(&offset
); // Extract minos
6063 const uint32_t xxxx
= version
>> 16;
6064 const uint32_t yy
= (version
>> 8) & 0xffu
;
6065 const uint32_t zz
= version
& 0xffu
;
6067 return llvm::VersionTuple(xxxx
, yy
, zz
);
6069 offset
= load_cmd_offset
+ lc
.cmdsize
;
6071 return llvm::VersionTuple();
6074 llvm::VersionTuple
ObjectFileMachO::GetMinimumOSVersion() {
6075 if (!m_min_os_version
)
6076 m_min_os_version
= FindMinimumVersionInfo(
6077 m_data
, MachHeaderSizeFromMagic(m_header
.magic
), m_header
.ncmds
);
6078 return *m_min_os_version
;
6081 llvm::VersionTuple
ObjectFileMachO::GetSDKVersion() {
6082 if (!m_sdk_versions
)
6083 m_sdk_versions
= FindMinimumVersionInfo(
6084 m_data
, MachHeaderSizeFromMagic(m_header
.magic
), m_header
.ncmds
);
6085 return *m_sdk_versions
;
6088 bool ObjectFileMachO::GetIsDynamicLinkEditor() {
6089 return m_header
.filetype
== llvm::MachO::MH_DYLINKER
;
6092 bool ObjectFileMachO::CanTrustAddressRanges() {
6093 // Dsymutil guarantees that the .debug_aranges accelerator is complete and can
6094 // be trusted by LLDB.
6095 return m_header
.filetype
== llvm::MachO::MH_DSYM
;
6098 bool ObjectFileMachO::AllowAssemblyEmulationUnwindPlans() {
6099 return m_allow_assembly_emulation_unwind_plans
;
6102 Section
*ObjectFileMachO::GetMachHeaderSection() {
6103 // Find the first address of the mach header which is the first non-zero file
6104 // sized section whose file offset is zero. This is the base file address of
6105 // the mach-o file which can be subtracted from the vmaddr of the other
6106 // segments found in memory and added to the load address
6107 ModuleSP module_sp
= GetModule();
6110 SectionList
*section_list
= GetSectionList();
6114 // Some binaries can have a TEXT segment with a non-zero file offset.
6115 // Binaries in the shared cache are one example. Some hand-generated
6116 // binaries may not be laid out in the normal TEXT,DATA,LC_SYMTAB order
6117 // in the file, even though they're laid out correctly in vmaddr terms.
6118 SectionSP text_segment_sp
=
6119 section_list
->FindSectionByName(GetSegmentNameTEXT());
6120 if (text_segment_sp
.get() && SectionIsLoadable(text_segment_sp
.get()))
6121 return text_segment_sp
.get();
6123 const size_t num_sections
= section_list
->GetSize();
6124 for (size_t sect_idx
= 0; sect_idx
< num_sections
; ++sect_idx
) {
6125 Section
*section
= section_list
->GetSectionAtIndex(sect_idx
).get();
6126 if (section
->GetFileOffset() == 0 && SectionIsLoadable(section
))
6133 bool ObjectFileMachO::SectionIsLoadable(const Section
*section
) {
6136 const bool is_dsym
= (m_header
.filetype
== MH_DSYM
);
6137 if (section
->GetFileSize() == 0 && !is_dsym
&&
6138 section
->GetName() != GetSegmentNameDATA())
6140 if (section
->IsThreadSpecific())
6142 if (GetModule().get() != section
->GetModule().get())
6144 // Be careful with __LINKEDIT and __DWARF segments
6145 if (section
->GetName() == GetSegmentNameLINKEDIT() ||
6146 section
->GetName() == GetSegmentNameDWARF()) {
6147 // Only map __LINKEDIT and __DWARF if we have an in memory image and
6148 // this isn't a kernel binary like a kext or mach_kernel.
6149 const bool is_memory_image
= (bool)m_process_wp
.lock();
6150 const Strata strata
= GetStrata();
6151 if (is_memory_image
== false || strata
== eStrataKernel
)
6157 lldb::addr_t
ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
6158 lldb::addr_t header_load_address
, const Section
*header_section
,
6159 const Section
*section
) {
6160 ModuleSP module_sp
= GetModule();
6161 if (module_sp
&& header_section
&& section
&&
6162 header_load_address
!= LLDB_INVALID_ADDRESS
) {
6163 lldb::addr_t file_addr
= header_section
->GetFileAddress();
6164 if (file_addr
!= LLDB_INVALID_ADDRESS
&& SectionIsLoadable(section
))
6165 return section
->GetFileAddress() - file_addr
+ header_load_address
;
6167 return LLDB_INVALID_ADDRESS
;
6170 bool ObjectFileMachO::SetLoadAddress(Target
&target
, lldb::addr_t value
,
6171 bool value_is_offset
) {
6172 ModuleSP module_sp
= GetModule();
6176 SectionList
*section_list
= GetSectionList();
6180 size_t num_loaded_sections
= 0;
6181 const size_t num_sections
= section_list
->GetSize();
6183 // Warn if some top-level segments map to the same address. The binary may be
6185 const bool warn_multiple
= true;
6187 if (value_is_offset
) {
6188 // "value" is an offset to apply to each top level segment
6189 for (size_t sect_idx
= 0; sect_idx
< num_sections
; ++sect_idx
) {
6190 // Iterate through the object file sections to find all of the
6191 // sections that size on disk (to avoid __PAGEZERO) and load them
6192 SectionSP
section_sp(section_list
->GetSectionAtIndex(sect_idx
));
6193 if (SectionIsLoadable(section_sp
.get()))
6194 if (target
.GetSectionLoadList().SetSectionLoadAddress(
6195 section_sp
, section_sp
->GetFileAddress() + value
,
6197 ++num_loaded_sections
;
6200 // "value" is the new base address of the mach_header, adjust each
6201 // section accordingly
6203 Section
*mach_header_section
= GetMachHeaderSection();
6204 if (mach_header_section
) {
6205 for (size_t sect_idx
= 0; sect_idx
< num_sections
; ++sect_idx
) {
6206 SectionSP
section_sp(section_list
->GetSectionAtIndex(sect_idx
));
6208 lldb::addr_t section_load_addr
=
6209 CalculateSectionLoadAddressForMemoryImage(
6210 value
, mach_header_section
, section_sp
.get());
6211 if (section_load_addr
!= LLDB_INVALID_ADDRESS
) {
6212 if (target
.GetSectionLoadList().SetSectionLoadAddress(
6213 section_sp
, section_load_addr
, warn_multiple
))
6214 ++num_loaded_sections
;
6219 return num_loaded_sections
> 0;
6222 struct all_image_infos_header
{
6223 uint32_t version
; // currently 1
6224 uint32_t imgcount
; // number of binary images
6225 uint64_t entries_fileoff
; // file offset in the corefile of where the array of
6226 // struct entry's begin.
6227 uint32_t entries_size
; // size of 'struct entry'.
6231 struct image_entry
{
6232 uint64_t filepath_offset
; // offset in corefile to c-string of the file path,
6233 // UINT64_MAX if unavailable.
6234 uuid_t uuid
; // uint8_t[16]. should be set to all zeroes if
6236 uint64_t load_address
; // UINT64_MAX if unknown.
6237 uint64_t seg_addrs_offset
; // offset to the array of struct segment_vmaddr's.
6238 uint32_t segment_count
; // The number of segments for this binary.
6242 filepath_offset
= UINT64_MAX
;
6243 memset(&uuid
, 0, sizeof(uuid_t
));
6245 load_address
= UINT64_MAX
;
6246 seg_addrs_offset
= UINT64_MAX
;
6249 image_entry(const image_entry
&rhs
) {
6250 filepath_offset
= rhs
.filepath_offset
;
6251 memcpy(&uuid
, &rhs
.uuid
, sizeof(uuid_t
));
6252 segment_count
= rhs
.segment_count
;
6253 seg_addrs_offset
= rhs
.seg_addrs_offset
;
6254 load_address
= rhs
.load_address
;
6255 unused
= rhs
.unused
;
6259 struct segment_vmaddr
{
6265 memset(&segname
, 0, 16);
6266 vmaddr
= UINT64_MAX
;
6269 segment_vmaddr(const segment_vmaddr
&rhs
) {
6270 memcpy(&segname
, &rhs
.segname
, 16);
6271 vmaddr
= rhs
.vmaddr
;
6272 unused
= rhs
.unused
;
6276 // Write the payload for the "all image infos" LC_NOTE into
6277 // the supplied all_image_infos_payload, assuming that this
6278 // will be written into the corefile starting at
6279 // initial_file_offset.
6281 // The placement of this payload is a little tricky. We're
6282 // laying this out as
6284 // 1. header (struct all_image_info_header)
6285 // 2. Array of fixed-size (struct image_entry)'s, one
6286 // per binary image present in the process.
6287 // 3. Arrays of (struct segment_vmaddr)'s, a varying number
6288 // for each binary image.
6289 // 4. Variable length c-strings of binary image filepaths,
6292 // To compute where everything will be laid out in the
6293 // payload, we need to iterate over the images and calculate
6294 // how many segment_vmaddr structures each image will need,
6295 // and how long each image's filepath c-string is. There
6296 // are some multiple passes over the image list while calculating
6299 static offset_t
CreateAllImageInfosPayload(
6300 const lldb::ProcessSP
&process_sp
, offset_t initial_file_offset
,
6301 StreamString
&all_image_infos_payload
, SaveCoreStyle core_style
) {
6302 Target
&target
= process_sp
->GetTarget();
6303 ModuleList modules
= target
.GetImages();
6305 // stack-only corefiles have no reason to include binaries that
6306 // are not executing; we're trying to make the smallest corefile
6307 // we can, so leave the rest out.
6308 if (core_style
== SaveCoreStyle::eSaveCoreStackOnly
)
6311 std::set
<std::string
> executing_uuids
;
6312 ThreadList
&thread_list(process_sp
->GetThreadList());
6313 for (uint32_t i
= 0; i
< thread_list
.GetSize(); i
++) {
6314 ThreadSP thread_sp
= thread_list
.GetThreadAtIndex(i
);
6315 uint32_t stack_frame_count
= thread_sp
->GetStackFrameCount();
6316 for (uint32_t j
= 0; j
< stack_frame_count
; j
++) {
6317 StackFrameSP stack_frame_sp
= thread_sp
->GetStackFrameAtIndex(j
);
6318 Address pc
= stack_frame_sp
->GetFrameCodeAddress();
6319 ModuleSP module_sp
= pc
.GetModule();
6321 UUID uuid
= module_sp
->GetUUID();
6322 if (uuid
.IsValid()) {
6323 executing_uuids
.insert(uuid
.GetAsString());
6324 modules
.AppendIfNeeded(module_sp
);
6329 size_t modules_count
= modules
.GetSize();
6331 struct all_image_infos_header infos
;
6333 infos
.imgcount
= modules_count
;
6334 infos
.entries_size
= sizeof(image_entry
);
6335 infos
.entries_fileoff
= initial_file_offset
+ sizeof(all_image_infos_header
);
6338 all_image_infos_payload
.PutHex32(infos
.version
);
6339 all_image_infos_payload
.PutHex32(infos
.imgcount
);
6340 all_image_infos_payload
.PutHex64(infos
.entries_fileoff
);
6341 all_image_infos_payload
.PutHex32(infos
.entries_size
);
6342 all_image_infos_payload
.PutHex32(infos
.unused
);
6344 // First create the structures for all of the segment name+vmaddr vectors
6345 // for each module, so we will know the size of them as we add the
6347 std::vector
<std::vector
<segment_vmaddr
>> modules_segment_vmaddrs
;
6348 for (size_t i
= 0; i
< modules_count
; i
++) {
6349 ModuleSP module
= modules
.GetModuleAtIndex(i
);
6351 SectionList
*sections
= module
->GetSectionList();
6352 size_t sections_count
= sections
->GetSize();
6353 std::vector
<segment_vmaddr
> segment_vmaddrs
;
6354 for (size_t j
= 0; j
< sections_count
; j
++) {
6355 SectionSP section
= sections
->GetSectionAtIndex(j
);
6356 if (!section
->GetParent().get()) {
6357 addr_t vmaddr
= section
->GetLoadBaseAddress(&target
);
6358 if (vmaddr
== LLDB_INVALID_ADDRESS
)
6360 ConstString name
= section
->GetName();
6361 segment_vmaddr seg_vmaddr
;
6362 // This is the uncommon case where strncpy is exactly
6363 // the right one, doesn't need to be nul terminated.
6364 // The segment name in a Mach-O LC_SEGMENT/LC_SEGMENT_64 is char[16] and
6365 // is not guaranteed to be nul-terminated if all 16 characters are
6367 // coverity[buffer_size_warning]
6368 strncpy(seg_vmaddr
.segname
, name
.AsCString(),
6369 sizeof(seg_vmaddr
.segname
));
6370 seg_vmaddr
.vmaddr
= vmaddr
;
6371 seg_vmaddr
.unused
= 0;
6372 segment_vmaddrs
.push_back(seg_vmaddr
);
6375 modules_segment_vmaddrs
.push_back(segment_vmaddrs
);
6378 offset_t size_of_vmaddr_structs
= 0;
6379 for (size_t i
= 0; i
< modules_segment_vmaddrs
.size(); i
++) {
6380 size_of_vmaddr_structs
+=
6381 modules_segment_vmaddrs
[i
].size() * sizeof(segment_vmaddr
);
6384 offset_t size_of_filepath_cstrings
= 0;
6385 for (size_t i
= 0; i
< modules_count
; i
++) {
6386 ModuleSP module_sp
= modules
.GetModuleAtIndex(i
);
6387 size_of_filepath_cstrings
+= module_sp
->GetFileSpec().GetPath().size() + 1;
6390 // Calculate the file offsets of our "all image infos" payload in the
6391 // corefile. initial_file_offset the original value passed in to this method.
6393 offset_t start_of_entries
=
6394 initial_file_offset
+ sizeof(all_image_infos_header
);
6395 offset_t start_of_seg_vmaddrs
=
6396 start_of_entries
+ sizeof(image_entry
) * modules_count
;
6397 offset_t start_of_filenames
= start_of_seg_vmaddrs
+ size_of_vmaddr_structs
;
6399 offset_t final_file_offset
= start_of_filenames
+ size_of_filepath_cstrings
;
6401 // Now write the one-per-module 'struct image_entry' into the
6402 // StringStream; keep track of where the struct segment_vmaddr
6403 // entries for each module will end up in the corefile.
6405 offset_t current_string_offset
= start_of_filenames
;
6406 offset_t current_segaddrs_offset
= start_of_seg_vmaddrs
;
6407 std::vector
<struct image_entry
> image_entries
;
6408 for (size_t i
= 0; i
< modules_count
; i
++) {
6409 ModuleSP module_sp
= modules
.GetModuleAtIndex(i
);
6411 struct image_entry ent
;
6412 memcpy(&ent
.uuid
, module_sp
->GetUUID().GetBytes().data(), sizeof(ent
.uuid
));
6413 if (modules_segment_vmaddrs
[i
].size() > 0) {
6414 ent
.segment_count
= modules_segment_vmaddrs
[i
].size();
6415 ent
.seg_addrs_offset
= current_segaddrs_offset
;
6417 ent
.filepath_offset
= current_string_offset
;
6418 ObjectFile
*objfile
= module_sp
->GetObjectFile();
6420 Address
base_addr(objfile
->GetBaseAddress());
6421 if (base_addr
.IsValid()) {
6422 ent
.load_address
= base_addr
.GetLoadAddress(&target
);
6426 all_image_infos_payload
.PutHex64(ent
.filepath_offset
);
6427 all_image_infos_payload
.PutRawBytes(ent
.uuid
, sizeof(ent
.uuid
));
6428 all_image_infos_payload
.PutHex64(ent
.load_address
);
6429 all_image_infos_payload
.PutHex64(ent
.seg_addrs_offset
);
6430 all_image_infos_payload
.PutHex32(ent
.segment_count
);
6432 if (executing_uuids
.find(module_sp
->GetUUID().GetAsString()) !=
6433 executing_uuids
.end())
6434 all_image_infos_payload
.PutHex32(1);
6436 all_image_infos_payload
.PutHex32(0);
6438 current_segaddrs_offset
+= ent
.segment_count
* sizeof(segment_vmaddr
);
6439 current_string_offset
+= module_sp
->GetFileSpec().GetPath().size() + 1;
6442 // Now write the struct segment_vmaddr entries into the StringStream.
6444 for (size_t i
= 0; i
< modules_segment_vmaddrs
.size(); i
++) {
6445 if (modules_segment_vmaddrs
[i
].size() == 0)
6447 for (struct segment_vmaddr segvm
: modules_segment_vmaddrs
[i
]) {
6448 all_image_infos_payload
.PutRawBytes(segvm
.segname
, sizeof(segvm
.segname
));
6449 all_image_infos_payload
.PutHex64(segvm
.vmaddr
);
6450 all_image_infos_payload
.PutHex64(segvm
.unused
);
6454 for (size_t i
= 0; i
< modules_count
; i
++) {
6455 ModuleSP module_sp
= modules
.GetModuleAtIndex(i
);
6456 std::string filepath
= module_sp
->GetFileSpec().GetPath();
6457 all_image_infos_payload
.PutRawBytes(filepath
.data(), filepath
.size() + 1);
6460 return final_file_offset
;
6463 // Temp struct used to combine contiguous memory regions with
6464 // identical permissions.
6465 struct page_object
{
6471 bool ObjectFileMachO::SaveCore(const lldb::ProcessSP
&process_sp
,
6472 const FileSpec
&outfile
,
6473 lldb::SaveCoreStyle
&core_style
, Status
&error
) {
6477 // Default on macOS is to create a dirty-memory-only corefile.
6478 if (core_style
== SaveCoreStyle::eSaveCoreUnspecified
) {
6479 core_style
= SaveCoreStyle::eSaveCoreDirtyOnly
;
6482 Target
&target
= process_sp
->GetTarget();
6483 const ArchSpec target_arch
= target
.GetArchitecture();
6484 const llvm::Triple
&target_triple
= target_arch
.GetTriple();
6485 if (target_triple
.getVendor() == llvm::Triple::Apple
&&
6486 (target_triple
.getOS() == llvm::Triple::MacOSX
||
6487 target_triple
.getOS() == llvm::Triple::IOS
||
6488 target_triple
.getOS() == llvm::Triple::WatchOS
||
6489 target_triple
.getOS() == llvm::Triple::TvOS
)) {
6490 // NEED_BRIDGEOS_TRIPLE target_triple.getOS() == llvm::Triple::BridgeOS))
6492 bool make_core
= false;
6493 switch (target_arch
.GetMachine()) {
6494 case llvm::Triple::aarch64
:
6495 case llvm::Triple::aarch64_32
:
6496 case llvm::Triple::arm
:
6497 case llvm::Triple::thumb
:
6498 case llvm::Triple::x86
:
6499 case llvm::Triple::x86_64
:
6503 error
.SetErrorStringWithFormat("unsupported core architecture: %s",
6504 target_triple
.str().c_str());
6509 std::vector
<llvm::MachO::segment_command_64
> segment_load_commands
;
6510 // uint32_t range_info_idx = 0;
6511 MemoryRegionInfo range_info
;
6512 Status range_error
= process_sp
->GetMemoryRegionInfo(0, range_info
);
6513 const uint32_t addr_byte_size
= target_arch
.GetAddressByteSize();
6514 const ByteOrder byte_order
= target_arch
.GetByteOrder();
6515 std::vector
<page_object
> pages_to_copy
;
6517 if (range_error
.Success()) {
6518 while (range_info
.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS
) {
6519 // Calculate correct protections
6521 if (range_info
.GetReadable() == MemoryRegionInfo::eYes
)
6522 prot
|= VM_PROT_READ
;
6523 if (range_info
.GetWritable() == MemoryRegionInfo::eYes
)
6524 prot
|= VM_PROT_WRITE
;
6525 if (range_info
.GetExecutable() == MemoryRegionInfo::eYes
)
6526 prot
|= VM_PROT_EXECUTE
;
6528 const addr_t addr
= range_info
.GetRange().GetRangeBase();
6529 const addr_t size
= range_info
.GetRange().GetByteSize();
6534 bool include_this_region
= true;
6535 bool dirty_pages_only
= false;
6536 if (core_style
== SaveCoreStyle::eSaveCoreStackOnly
) {
6537 dirty_pages_only
= true;
6538 if (range_info
.IsStackMemory() != MemoryRegionInfo::eYes
) {
6539 include_this_region
= false;
6542 if (core_style
== SaveCoreStyle::eSaveCoreDirtyOnly
) {
6543 dirty_pages_only
= true;
6546 if (prot
!= 0 && include_this_region
) {
6547 addr_t pagesize
= range_info
.GetPageSize();
6548 const std::optional
<std::vector
<addr_t
>> &dirty_page_list
=
6549 range_info
.GetDirtyPageList();
6550 if (dirty_pages_only
&& dirty_page_list
) {
6551 for (addr_t dirtypage
: *dirty_page_list
) {
6553 obj
.addr
= dirtypage
;
6554 obj
.size
= pagesize
;
6556 pages_to_copy
.push_back(obj
);
6563 pages_to_copy
.push_back(obj
);
6567 range_error
= process_sp
->GetMemoryRegionInfo(
6568 range_info
.GetRange().GetRangeEnd(), range_info
);
6569 if (range_error
.Fail())
6573 // Combine contiguous entries that have the same
6574 // protections so we don't have an excess of
6576 std::vector
<page_object
> combined_page_objects
;
6577 page_object last_obj
;
6578 last_obj
.addr
= LLDB_INVALID_ADDRESS
;
6580 for (page_object obj
: pages_to_copy
) {
6581 if (last_obj
.addr
== LLDB_INVALID_ADDRESS
) {
6585 if (last_obj
.addr
+ last_obj
.size
== obj
.addr
&&
6586 last_obj
.prot
== obj
.prot
) {
6587 last_obj
.size
+= obj
.size
;
6590 combined_page_objects
.push_back(last_obj
);
6593 // Add the last entry we were looking to combine
6595 if (last_obj
.addr
!= LLDB_INVALID_ADDRESS
&& last_obj
.size
!= 0)
6596 combined_page_objects
.push_back(last_obj
);
6598 for (page_object obj
: combined_page_objects
) {
6599 uint32_t cmd_type
= LC_SEGMENT_64
;
6600 uint32_t segment_size
= sizeof(llvm::MachO::segment_command_64
);
6601 if (addr_byte_size
== 4) {
6602 cmd_type
= LC_SEGMENT
;
6603 segment_size
= sizeof(llvm::MachO::segment_command
);
6605 llvm::MachO::segment_command_64 segment
= {
6606 cmd_type
, // uint32_t cmd;
6607 segment_size
, // uint32_t cmdsize;
6608 {0}, // char segname[16];
6609 obj
.addr
, // uint64_t vmaddr; // uint32_t for 32-bit
6611 obj
.size
, // uint64_t vmsize; // uint32_t for 32-bit
6613 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
6614 obj
.size
, // uint64_t filesize; // uint32_t for 32-bit
6616 obj
.prot
, // uint32_t maxprot;
6617 obj
.prot
, // uint32_t initprot;
6618 0, // uint32_t nsects;
6619 0}; // uint32_t flags;
6620 segment_load_commands
.push_back(segment
);
6623 StreamString
buffer(Stream::eBinary
, addr_byte_size
, byte_order
);
6625 llvm::MachO::mach_header_64 mach_header
;
6626 if (addr_byte_size
== 8) {
6627 mach_header
.magic
= MH_MAGIC_64
;
6629 mach_header
.magic
= MH_MAGIC
;
6631 mach_header
.cputype
= target_arch
.GetMachOCPUType();
6632 mach_header
.cpusubtype
= target_arch
.GetMachOCPUSubType();
6633 mach_header
.filetype
= MH_CORE
;
6634 mach_header
.ncmds
= segment_load_commands
.size();
6635 mach_header
.flags
= 0;
6636 mach_header
.reserved
= 0;
6637 ThreadList
&thread_list
= process_sp
->GetThreadList();
6638 const uint32_t num_threads
= thread_list
.GetSize();
6640 // Make an array of LC_THREAD data items. Each one contains the
6641 // contents of the LC_THREAD load command. The data doesn't contain
6642 // the load command + load command size, we will add the load command
6643 // and load command size as we emit the data.
6644 std::vector
<StreamString
> LC_THREAD_datas(num_threads
);
6645 for (auto &LC_THREAD_data
: LC_THREAD_datas
) {
6646 LC_THREAD_data
.GetFlags().Set(Stream::eBinary
);
6647 LC_THREAD_data
.SetAddressByteSize(addr_byte_size
);
6648 LC_THREAD_data
.SetByteOrder(byte_order
);
6650 for (uint32_t thread_idx
= 0; thread_idx
< num_threads
; ++thread_idx
) {
6651 ThreadSP
thread_sp(thread_list
.GetThreadAtIndex(thread_idx
));
6653 switch (mach_header
.cputype
) {
6654 case llvm::MachO::CPU_TYPE_ARM64
:
6655 case llvm::MachO::CPU_TYPE_ARM64_32
:
6656 RegisterContextDarwin_arm64_Mach::Create_LC_THREAD(
6657 thread_sp
.get(), LC_THREAD_datas
[thread_idx
]);
6660 case llvm::MachO::CPU_TYPE_ARM
:
6661 RegisterContextDarwin_arm_Mach::Create_LC_THREAD(
6662 thread_sp
.get(), LC_THREAD_datas
[thread_idx
]);
6665 case llvm::MachO::CPU_TYPE_I386
:
6666 RegisterContextDarwin_i386_Mach::Create_LC_THREAD(
6667 thread_sp
.get(), LC_THREAD_datas
[thread_idx
]);
6670 case llvm::MachO::CPU_TYPE_X86_64
:
6671 RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
6672 thread_sp
.get(), LC_THREAD_datas
[thread_idx
]);
6678 // The size of the load command is the size of the segments...
6679 if (addr_byte_size
== 8) {
6680 mach_header
.sizeofcmds
= segment_load_commands
.size() *
6681 sizeof(llvm::MachO::segment_command_64
);
6683 mach_header
.sizeofcmds
= segment_load_commands
.size() *
6684 sizeof(llvm::MachO::segment_command
);
6687 // and the size of all LC_THREAD load command
6688 for (const auto &LC_THREAD_data
: LC_THREAD_datas
) {
6689 ++mach_header
.ncmds
;
6690 mach_header
.sizeofcmds
+= 8 + LC_THREAD_data
.GetSize();
6693 // Bits will be set to indicate which bits are NOT used in
6694 // addressing in this process or 0 for unknown.
6695 uint64_t address_mask
= process_sp
->GetCodeAddressMask();
6696 if (address_mask
!= 0) {
6697 // LC_NOTE "addrable bits"
6698 mach_header
.ncmds
++;
6699 mach_header
.sizeofcmds
+= sizeof(llvm::MachO::note_command
);
6702 // LC_NOTE "process metadata"
6703 mach_header
.ncmds
++;
6704 mach_header
.sizeofcmds
+= sizeof(llvm::MachO::note_command
);
6706 // LC_NOTE "all image infos"
6707 mach_header
.ncmds
++;
6708 mach_header
.sizeofcmds
+= sizeof(llvm::MachO::note_command
);
6710 // Write the mach header
6711 buffer
.PutHex32(mach_header
.magic
);
6712 buffer
.PutHex32(mach_header
.cputype
);
6713 buffer
.PutHex32(mach_header
.cpusubtype
);
6714 buffer
.PutHex32(mach_header
.filetype
);
6715 buffer
.PutHex32(mach_header
.ncmds
);
6716 buffer
.PutHex32(mach_header
.sizeofcmds
);
6717 buffer
.PutHex32(mach_header
.flags
);
6718 if (addr_byte_size
== 8) {
6719 buffer
.PutHex32(mach_header
.reserved
);
6722 // Skip the mach header and all load commands and align to the next
6723 // 0x1000 byte boundary
6724 addr_t file_offset
= buffer
.GetSize() + mach_header
.sizeofcmds
;
6726 file_offset
= llvm::alignTo(file_offset
, 16);
6727 std::vector
<std::unique_ptr
<LCNoteEntry
>> lc_notes
;
6729 // Add "addrable bits" LC_NOTE when an address mask is available
6730 if (address_mask
!= 0) {
6731 std::unique_ptr
<LCNoteEntry
> addrable_bits_lcnote_up(
6732 new LCNoteEntry(addr_byte_size
, byte_order
));
6733 addrable_bits_lcnote_up
->name
= "addrable bits";
6734 addrable_bits_lcnote_up
->payload_file_offset
= file_offset
;
6735 int bits
= std::bitset
<64>(~address_mask
).count();
6736 addrable_bits_lcnote_up
->payload
.PutHex32(4); // version
6737 addrable_bits_lcnote_up
->payload
.PutHex32(
6738 bits
); // # of bits used for low addresses
6739 addrable_bits_lcnote_up
->payload
.PutHex32(
6740 bits
); // # of bits used for high addresses
6741 addrable_bits_lcnote_up
->payload
.PutHex32(0); // reserved
6743 file_offset
+= addrable_bits_lcnote_up
->payload
.GetSize();
6745 lc_notes
.push_back(std::move(addrable_bits_lcnote_up
));
6748 // Add "process metadata" LC_NOTE
6749 std::unique_ptr
<LCNoteEntry
> thread_extrainfo_lcnote_up(
6750 new LCNoteEntry(addr_byte_size
, byte_order
));
6751 thread_extrainfo_lcnote_up
->name
= "process metadata";
6752 thread_extrainfo_lcnote_up
->payload_file_offset
= file_offset
;
6754 StructuredData::DictionarySP
dict(
6755 std::make_shared
<StructuredData::Dictionary
>());
6756 StructuredData::ArraySP
threads(
6757 std::make_shared
<StructuredData::Array
>());
6758 for (uint32_t thread_idx
= 0; thread_idx
< num_threads
; ++thread_idx
) {
6759 ThreadSP
thread_sp(thread_list
.GetThreadAtIndex(thread_idx
));
6760 StructuredData::DictionarySP
thread(
6761 std::make_shared
<StructuredData::Dictionary
>());
6762 thread
->AddIntegerItem("thread_id", thread_sp
->GetID());
6763 threads
->AddItem(thread
);
6765 dict
->AddItem("threads", threads
);
6767 dict
->Dump(strm
, /* pretty */ false);
6768 thread_extrainfo_lcnote_up
->payload
.PutRawBytes(strm
.GetData(),
6771 file_offset
+= thread_extrainfo_lcnote_up
->payload
.GetSize();
6772 file_offset
= llvm::alignTo(file_offset
, 16);
6773 lc_notes
.push_back(std::move(thread_extrainfo_lcnote_up
));
6775 // Add "all image infos" LC_NOTE
6776 std::unique_ptr
<LCNoteEntry
> all_image_infos_lcnote_up(
6777 new LCNoteEntry(addr_byte_size
, byte_order
));
6778 all_image_infos_lcnote_up
->name
= "all image infos";
6779 all_image_infos_lcnote_up
->payload_file_offset
= file_offset
;
6780 file_offset
= CreateAllImageInfosPayload(
6781 process_sp
, file_offset
, all_image_infos_lcnote_up
->payload
,
6783 lc_notes
.push_back(std::move(all_image_infos_lcnote_up
));
6785 // Add LC_NOTE load commands
6786 for (auto &lcnote
: lc_notes
) {
6787 // Add the LC_NOTE load command to the file.
6788 buffer
.PutHex32(LC_NOTE
);
6789 buffer
.PutHex32(sizeof(llvm::MachO::note_command
));
6791 memset(namebuf
, 0, sizeof(namebuf
));
6792 // This is the uncommon case where strncpy is exactly
6793 // the right one, doesn't need to be nul terminated.
6794 // LC_NOTE name field is char[16] and is not guaranteed to be
6796 // coverity[buffer_size_warning]
6797 strncpy(namebuf
, lcnote
->name
.c_str(), sizeof(namebuf
));
6798 buffer
.PutRawBytes(namebuf
, sizeof(namebuf
));
6799 buffer
.PutHex64(lcnote
->payload_file_offset
);
6800 buffer
.PutHex64(lcnote
->payload
.GetSize());
6803 // Align to 4096-byte page boundary for the LC_SEGMENTs.
6804 file_offset
= llvm::alignTo(file_offset
, 4096);
6806 for (auto &segment
: segment_load_commands
) {
6807 segment
.fileoff
= file_offset
;
6808 file_offset
+= segment
.filesize
;
6811 // Write out all of the LC_THREAD load commands
6812 for (const auto &LC_THREAD_data
: LC_THREAD_datas
) {
6813 const size_t LC_THREAD_data_size
= LC_THREAD_data
.GetSize();
6814 buffer
.PutHex32(LC_THREAD
);
6815 buffer
.PutHex32(8 + LC_THREAD_data_size
); // cmd + cmdsize + data
6816 buffer
.Write(LC_THREAD_data
.GetString().data(), LC_THREAD_data_size
);
6819 // Write out all of the segment load commands
6820 for (const auto &segment
: segment_load_commands
) {
6821 buffer
.PutHex32(segment
.cmd
);
6822 buffer
.PutHex32(segment
.cmdsize
);
6823 buffer
.PutRawBytes(segment
.segname
, sizeof(segment
.segname
));
6824 if (addr_byte_size
== 8) {
6825 buffer
.PutHex64(segment
.vmaddr
);
6826 buffer
.PutHex64(segment
.vmsize
);
6827 buffer
.PutHex64(segment
.fileoff
);
6828 buffer
.PutHex64(segment
.filesize
);
6830 buffer
.PutHex32(static_cast<uint32_t>(segment
.vmaddr
));
6831 buffer
.PutHex32(static_cast<uint32_t>(segment
.vmsize
));
6832 buffer
.PutHex32(static_cast<uint32_t>(segment
.fileoff
));
6833 buffer
.PutHex32(static_cast<uint32_t>(segment
.filesize
));
6835 buffer
.PutHex32(segment
.maxprot
);
6836 buffer
.PutHex32(segment
.initprot
);
6837 buffer
.PutHex32(segment
.nsects
);
6838 buffer
.PutHex32(segment
.flags
);
6841 std::string
core_file_path(outfile
.GetPath());
6842 auto core_file
= FileSystem::Instance().Open(
6843 outfile
, File::eOpenOptionWriteOnly
| File::eOpenOptionTruncate
|
6844 File::eOpenOptionCanCreate
);
6846 error
= core_file
.takeError();
6848 // Read 1 page at a time
6849 uint8_t bytes
[0x1000];
6850 // Write the mach header and load commands out to the core file
6851 size_t bytes_written
= buffer
.GetString().size();
6853 core_file
.get()->Write(buffer
.GetString().data(), bytes_written
);
6854 if (error
.Success()) {
6856 for (auto &lcnote
: lc_notes
) {
6857 if (core_file
.get()->SeekFromStart(lcnote
->payload_file_offset
) ==
6859 error
.SetErrorStringWithFormat("Unable to seek to corefile pos "
6860 "to write '%s' LC_NOTE payload",
6861 lcnote
->name
.c_str());
6864 bytes_written
= lcnote
->payload
.GetSize();
6865 error
= core_file
.get()->Write(lcnote
->payload
.GetData(),
6867 if (!error
.Success())
6871 // Now write the file data for all memory segments in the process
6872 for (const auto &segment
: segment_load_commands
) {
6873 if (core_file
.get()->SeekFromStart(segment
.fileoff
) == -1) {
6874 error
.SetErrorStringWithFormat(
6875 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6876 segment
.fileoff
, core_file_path
.c_str());
6880 target
.GetDebugger().GetAsyncOutputStream()->Printf(
6882 " bytes of data for memory region at 0x%" PRIx64
"\n",
6883 segment
.vmsize
, segment
.vmaddr
);
6884 addr_t bytes_left
= segment
.vmsize
;
6885 addr_t addr
= segment
.vmaddr
;
6886 Status memory_read_error
;
6887 while (bytes_left
> 0 && error
.Success()) {
6888 const size_t bytes_to_read
=
6889 bytes_left
> sizeof(bytes
) ? sizeof(bytes
) : bytes_left
;
6891 // In a savecore setting, we don't really care about caching,
6892 // as the data is dumped and very likely never read again,
6893 // so we call ReadMemoryFromInferior to bypass it.
6894 const size_t bytes_read
= process_sp
->ReadMemoryFromInferior(
6895 addr
, bytes
, bytes_to_read
, memory_read_error
);
6897 if (bytes_read
== bytes_to_read
) {
6898 size_t bytes_written
= bytes_read
;
6899 error
= core_file
.get()->Write(bytes
, bytes_written
);
6900 bytes_left
-= bytes_read
;
6903 // Some pages within regions are not readable, those should
6905 memset(bytes
, 0, bytes_to_read
);
6906 size_t bytes_written
= bytes_to_read
;
6907 error
= core_file
.get()->Write(bytes
, bytes_written
);
6908 bytes_left
-= bytes_to_read
;
6909 addr
+= bytes_to_read
;
6916 error
.SetErrorString(
6917 "process doesn't support getting memory region info");
6920 return true; // This is the right plug to handle saving core files for
6926 ObjectFileMachO::MachOCorefileAllImageInfos
6927 ObjectFileMachO::GetCorefileAllImageInfos() {
6928 MachOCorefileAllImageInfos image_infos
;
6929 Log
*log(GetLog(LLDBLog::Object
| LLDBLog::Symbols
| LLDBLog::Process
|
6930 LLDBLog::DynamicLoader
));
6932 auto lc_notes
= FindLC_NOTEByName("all image infos");
6933 for (auto lc_note
: lc_notes
) {
6934 offset_t payload_offset
= std::get
<0>(lc_note
);
6935 // Read the struct all_image_infos_header.
6936 uint32_t version
= m_data
.GetU32(&payload_offset
);
6940 uint32_t imgcount
= m_data
.GetU32(&payload_offset
);
6941 uint64_t entries_fileoff
= m_data
.GetU64(&payload_offset
);
6942 // 'entries_size' is not used, nor is the 'unused' entry.
6943 // offset += 4; // uint32_t entries_size;
6944 // offset += 4; // uint32_t unused;
6946 LLDB_LOGF(log
, "LC_NOTE 'all image infos' found version %d with %d images",
6948 payload_offset
= entries_fileoff
;
6949 for (uint32_t i
= 0; i
< imgcount
; i
++) {
6950 // Read the struct image_entry.
6951 offset_t filepath_offset
= m_data
.GetU64(&payload_offset
);
6953 memcpy(&uuid
, m_data
.GetData(&payload_offset
, sizeof(uuid_t
)),
6955 uint64_t load_address
= m_data
.GetU64(&payload_offset
);
6956 offset_t seg_addrs_offset
= m_data
.GetU64(&payload_offset
);
6957 uint32_t segment_count
= m_data
.GetU32(&payload_offset
);
6958 uint32_t currently_executing
= m_data
.GetU32(&payload_offset
);
6960 MachOCorefileImageEntry image_entry
;
6961 image_entry
.filename
= (const char *)m_data
.GetCStr(&filepath_offset
);
6962 image_entry
.uuid
= UUID(uuid
, sizeof(uuid_t
));
6963 image_entry
.load_address
= load_address
;
6964 image_entry
.currently_executing
= currently_executing
;
6966 offset_t seg_vmaddrs_offset
= seg_addrs_offset
;
6967 for (uint32_t j
= 0; j
< segment_count
; j
++) {
6969 m_data
.CopyData(seg_vmaddrs_offset
, 16, segname
);
6971 seg_vmaddrs_offset
+= 16;
6972 uint64_t vmaddr
= m_data
.GetU64(&seg_vmaddrs_offset
);
6973 seg_vmaddrs_offset
+= 8; /* unused */
6975 std::tuple
<ConstString
, addr_t
> new_seg
{ConstString(segname
), vmaddr
};
6976 image_entry
.segment_load_addresses
.push_back(new_seg
);
6978 LLDB_LOGF(log
, " image entry: %s %s 0x%" PRIx64
" %s",
6979 image_entry
.filename
.c_str(),
6980 image_entry
.uuid
.GetAsString().c_str(),
6981 image_entry
.load_address
,
6982 image_entry
.currently_executing
? "currently executing"
6983 : "not currently executing");
6984 image_infos
.all_image_infos
.push_back(image_entry
);
6988 lc_notes
= FindLC_NOTEByName("load binary");
6989 for (auto lc_note
: lc_notes
) {
6990 offset_t payload_offset
= std::get
<0>(lc_note
);
6991 uint32_t version
= m_data
.GetU32(&payload_offset
);
6994 memcpy(&uuid
, m_data
.GetData(&payload_offset
, sizeof(uuid_t
)),
6996 uint64_t load_address
= m_data
.GetU64(&payload_offset
);
6997 uint64_t slide
= m_data
.GetU64(&payload_offset
);
6998 std::string filename
= m_data
.GetCStr(&payload_offset
);
7000 MachOCorefileImageEntry image_entry
;
7001 image_entry
.filename
= filename
;
7002 image_entry
.uuid
= UUID(uuid
, sizeof(uuid_t
));
7003 image_entry
.load_address
= load_address
;
7004 image_entry
.slide
= slide
;
7005 image_entry
.currently_executing
= true;
7006 image_infos
.all_image_infos
.push_back(image_entry
);
7008 "LC_NOTE 'load binary' found, filename %s uuid %s load "
7009 "address 0x%" PRIx64
" slide 0x%" PRIx64
,
7011 image_entry
.uuid
.IsValid()
7012 ? image_entry
.uuid
.GetAsString().c_str()
7013 : "00000000-0000-0000-0000-000000000000",
7014 load_address
, slide
);
7021 bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process
&process
) {
7022 MachOCorefileAllImageInfos image_infos
= GetCorefileAllImageInfos();
7023 Log
*log
= GetLog(LLDBLog::Object
| LLDBLog::DynamicLoader
);
7026 bool found_platform_binary
= false;
7027 ModuleList added_modules
;
7028 for (MachOCorefileImageEntry
&image
: image_infos
.all_image_infos
) {
7029 ModuleSP module_sp
, local_filesystem_module_sp
;
7031 // If this is a platform binary, it has been loaded (or registered with
7032 // the DynamicLoader to be loaded), we don't need to do any further
7033 // processing. We're not going to call ModulesDidLoad on this in this
7034 // method, so notify==true.
7035 if (process
.GetTarget()
7038 .LoadPlatformBinaryAndSetup(&process
, image
.load_address
,
7039 true /* notify */)) {
7041 "ObjectFileMachO::%s binary at 0x%" PRIx64
7042 " is a platform binary, has been handled by a Platform plugin.",
7043 __FUNCTION__
, image
.load_address
);
7047 bool value_is_offset
= image
.load_address
== LLDB_INVALID_ADDRESS
;
7048 uint64_t value
= value_is_offset
? image
.slide
: image
.load_address
;
7049 if (value_is_offset
&& value
== LLDB_INVALID_ADDRESS
) {
7050 // We have neither address nor slide; so we will find the binary
7051 // by UUID and load it at slide/offset 0.
7055 // We have either a UUID, or we have a load address which
7056 // and can try to read load commands and find a UUID.
7057 if (image
.uuid
.IsValid() ||
7058 (!value_is_offset
&& value
!= LLDB_INVALID_ADDRESS
)) {
7059 const bool set_load_address
= image
.segment_load_addresses
.size() == 0;
7060 const bool notify
= false;
7061 // Userland Darwin binaries will have segment load addresses via
7062 // the `all image infos` LC_NOTE.
7063 const bool allow_memory_image_last_resort
=
7064 image
.segment_load_addresses
.size();
7065 module_sp
= DynamicLoader::LoadBinaryWithUUIDAndAddress(
7066 &process
, image
.filename
, image
.uuid
, value
, value_is_offset
,
7067 image
.currently_executing
, notify
, set_load_address
,
7068 allow_memory_image_last_resort
);
7071 // We have a ModuleSP to load in the Target. Load it at the
7072 // correct address/slide and notify/load scripting resources.
7074 added_modules
.Append(module_sp
, false /* notify */);
7076 // We have a list of segment load address
7077 if (image
.segment_load_addresses
.size() > 0) {
7079 std::string uuidstr
= image
.uuid
.GetAsString();
7080 log
->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7081 "UUID %s with section load addresses",
7082 module_sp
->GetFileSpec().GetPath().c_str(),
7085 for (auto name_vmaddr_tuple
: image
.segment_load_addresses
) {
7086 SectionList
*sectlist
= module_sp
->GetObjectFile()->GetSectionList();
7089 sectlist
->FindSectionByName(std::get
<0>(name_vmaddr_tuple
));
7091 process
.GetTarget().SetSectionLoadAddress(
7092 sect_sp
, std::get
<1>(name_vmaddr_tuple
));
7098 std::string uuidstr
= image
.uuid
.GetAsString();
7099 log
->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7100 "UUID %s with %s 0x%" PRIx64
,
7101 module_sp
->GetFileSpec().GetPath().c_str(),
7103 value_is_offset
? "slide" : "load address", value
);
7106 module_sp
->SetLoadAddress(process
.GetTarget(), value
, value_is_offset
,
7111 if (added_modules
.GetSize() > 0) {
7112 process
.GetTarget().ModulesDidLoad(added_modules
);
7116 // Return true if the only binary we found was the platform binary,
7117 // and it was loaded outside the scope of this method.
7118 if (found_platform_binary
)