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