[llvm-readobj] Add support for MachO DataInCodeDataCommand.
[oota-llvm.git] / tools / llvm-readobj / MachODumper.cpp
1 //===-- MachODump.cpp - Object file dumping utility for llvm --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the MachO-specific dumper for llvm-readobj.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm-readobj.h"
15 #include "Error.h"
16 #include "ObjDumper.h"
17 #include "StackMapPrinter.h"
18 #include "StreamWriter.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/Object/MachO.h"
22 #include "llvm/Support/Casting.h"
23
24 using namespace llvm;
25 using namespace object;
26
27 namespace {
28
29 class MachODumper : public ObjDumper {
30 public:
31   MachODumper(const MachOObjectFile *Obj, StreamWriter& Writer)
32     : ObjDumper(Writer)
33     , Obj(Obj) { }
34
35   void printFileHeaders() override;
36   void printSections() override;
37   void printRelocations() override;
38   void printSymbols() override;
39   void printDynamicSymbols() override;
40   void printUnwindInfo() override;
41   void printStackMap() const override;
42
43   // MachO-specific.
44   void printMachODataInCode() override;
45
46 private:
47   template<class MachHeader>
48   void printFileHeaders(const MachHeader &Header);
49
50   void printSymbol(const SymbolRef &Symbol);
51
52   void printRelocation(const RelocationRef &Reloc);
53
54   void printRelocation(const MachOObjectFile *Obj, const RelocationRef &Reloc);
55
56   void printSections(const MachOObjectFile *Obj);
57
58   const MachOObjectFile *Obj;
59 };
60
61 } // namespace
62
63
64 namespace llvm {
65
66 std::error_code createMachODumper(const object::ObjectFile *Obj,
67                                   StreamWriter &Writer,
68                                   std::unique_ptr<ObjDumper> &Result) {
69   const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(Obj);
70   if (!MachOObj)
71     return readobj_error::unsupported_obj_file_format;
72
73   Result.reset(new MachODumper(MachOObj, Writer));
74   return readobj_error::success;
75 }
76
77 } // namespace llvm
78
79 static const EnumEntry<uint32_t> MachOMagics[] = {
80   { "Magic",      MachO::MH_MAGIC    },
81   { "Cigam",      MachO::MH_CIGAM    },
82   { "Magic64",    MachO::MH_MAGIC_64 },
83   { "Cigam64",    MachO::MH_CIGAM_64 },
84   { "FatMagic",   MachO::FAT_MAGIC   },
85   { "FatCigam",   MachO::FAT_CIGAM   },
86 };
87
88 static const EnumEntry<uint32_t> MachOHeaderFileTypes[] = {
89   { "Relocatable",          MachO::MH_OBJECT      },
90   { "Executable",           MachO::MH_EXECUTE     },
91   { "FixedVMLibrary",       MachO::MH_FVMLIB      },
92   { "Core",                 MachO::MH_CORE        },
93   { "PreloadedExecutable",  MachO::MH_PRELOAD     },
94   { "DynamicLibrary",       MachO::MH_DYLIB       },
95   { "DynamicLinker",        MachO::MH_DYLINKER    },
96   { "Bundle",               MachO::MH_BUNDLE      },
97   { "DynamicLibraryStub",   MachO::MH_DYLIB_STUB  },
98   { "DWARFSymbol",          MachO::MH_DSYM        },
99   { "KextBundle",           MachO::MH_KEXT_BUNDLE },
100 };
101
102 static const EnumEntry<uint32_t> MachOHeaderCpuTypes[] = {
103   { "Any"       , static_cast<uint32_t>(MachO::CPU_TYPE_ANY) },
104   { "X86"       , MachO::CPU_TYPE_X86       },
105   { "X86-64"    , MachO::CPU_TYPE_X86_64    },
106   { "Mc98000"   , MachO::CPU_TYPE_MC98000   },
107   { "Arm"       , MachO::CPU_TYPE_ARM       },
108   { "Arm64"     , MachO::CPU_TYPE_ARM64     },
109   { "Sparc"     , MachO::CPU_TYPE_SPARC     },
110   { "PowerPC"   , MachO::CPU_TYPE_POWERPC   },
111   { "PowerPC64" , MachO::CPU_TYPE_POWERPC64 },
112 };
113
114 static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesX86[] = {
115   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_I386_ALL),
116   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_386),
117   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_486),
118   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_486SX),
119   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_586),
120   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTPRO),
121   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTII_M3),
122   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTII_M5),
123   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_CELERON),
124   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_CELERON_MOBILE),
125   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3),
126   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3_M),
127   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3_XEON),
128   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_M),
129   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_4),
130   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_4_M),
131   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ITANIUM),
132   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ITANIUM_2),
133   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_XEON),
134   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_XEON_MP),
135 };
136
137 static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesX64[] = {
138   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_64_ALL),
139   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_ARCH1),
140   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_64_H),
141 };
142
143 static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesARM[] = {
144   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_ALL),
145   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V4T),
146   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V6),
147   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V5),
148   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V5TEJ),
149   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_XSCALE),
150   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7),
151   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7S),
152   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7K),
153   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V6M),
154   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7M),
155   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7EM),
156 };
157
158 static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesARM64[] = {
159   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64_ALL),
160 };
161
162 static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesSPARC[] = {
163   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_SPARC_ALL),
164 };
165
166 static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesPPC[] = {
167   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_ALL),
168   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_601),
169   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_602),
170   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603),
171   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603e),
172   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603ev),
173   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_604),
174   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_604e),
175   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_620),
176   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_750),
177   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_7400),
178   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_7450),
179   LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_970),
180 };
181
182 static const EnumEntry<uint32_t> MachOHeaderFlags[] = {
183   LLVM_READOBJ_ENUM_ENT(MachO, MH_NOUNDEFS),
184   LLVM_READOBJ_ENUM_ENT(MachO, MH_INCRLINK),
185   LLVM_READOBJ_ENUM_ENT(MachO, MH_DYLDLINK),
186   LLVM_READOBJ_ENUM_ENT(MachO, MH_BINDATLOAD),
187   LLVM_READOBJ_ENUM_ENT(MachO, MH_PREBOUND),
188   LLVM_READOBJ_ENUM_ENT(MachO, MH_SPLIT_SEGS),
189   LLVM_READOBJ_ENUM_ENT(MachO, MH_LAZY_INIT),
190   LLVM_READOBJ_ENUM_ENT(MachO, MH_TWOLEVEL),
191   LLVM_READOBJ_ENUM_ENT(MachO, MH_FORCE_FLAT),
192   LLVM_READOBJ_ENUM_ENT(MachO, MH_NOMULTIDEFS),
193   LLVM_READOBJ_ENUM_ENT(MachO, MH_NOFIXPREBINDING),
194   LLVM_READOBJ_ENUM_ENT(MachO, MH_PREBINDABLE),
195   LLVM_READOBJ_ENUM_ENT(MachO, MH_ALLMODSBOUND),
196   LLVM_READOBJ_ENUM_ENT(MachO, MH_SUBSECTIONS_VIA_SYMBOLS),
197   LLVM_READOBJ_ENUM_ENT(MachO, MH_CANONICAL),
198   LLVM_READOBJ_ENUM_ENT(MachO, MH_WEAK_DEFINES),
199   LLVM_READOBJ_ENUM_ENT(MachO, MH_BINDS_TO_WEAK),
200   LLVM_READOBJ_ENUM_ENT(MachO, MH_ALLOW_STACK_EXECUTION),
201   LLVM_READOBJ_ENUM_ENT(MachO, MH_ROOT_SAFE),
202   LLVM_READOBJ_ENUM_ENT(MachO, MH_SETUID_SAFE),
203   LLVM_READOBJ_ENUM_ENT(MachO, MH_NO_REEXPORTED_DYLIBS),
204   LLVM_READOBJ_ENUM_ENT(MachO, MH_PIE),
205   LLVM_READOBJ_ENUM_ENT(MachO, MH_DEAD_STRIPPABLE_DYLIB),
206   LLVM_READOBJ_ENUM_ENT(MachO, MH_HAS_TLV_DESCRIPTORS),
207   LLVM_READOBJ_ENUM_ENT(MachO, MH_NO_HEAP_EXECUTION),
208   LLVM_READOBJ_ENUM_ENT(MachO, MH_APP_EXTENSION_SAFE),
209 };
210
211 static const EnumEntry<unsigned> MachOSectionAttributes[] = {
212   { "LocReloc"         , 1 <<  0 /*S_ATTR_LOC_RELOC          */ },
213   { "ExtReloc"         , 1 <<  1 /*S_ATTR_EXT_RELOC          */ },
214   { "SomeInstructions" , 1 <<  2 /*S_ATTR_SOME_INSTRUCTIONS  */ },
215   { "Debug"            , 1 << 17 /*S_ATTR_DEBUG              */ },
216   { "SelfModifyingCode", 1 << 18 /*S_ATTR_SELF_MODIFYING_CODE*/ },
217   { "LiveSupport"      , 1 << 19 /*S_ATTR_LIVE_SUPPORT       */ },
218   { "NoDeadStrip"      , 1 << 20 /*S_ATTR_NO_DEAD_STRIP      */ },
219   { "StripStaticSyms"  , 1 << 21 /*S_ATTR_STRIP_STATIC_SYMS  */ },
220   { "NoTOC"            , 1 << 22 /*S_ATTR_NO_TOC             */ },
221   { "PureInstructions" , 1 << 23 /*S_ATTR_PURE_INSTRUCTIONS  */ },
222 };
223
224 static const EnumEntry<unsigned> MachOSymbolRefTypes[] = {
225   { "UndefinedNonLazy",                     0 },
226   { "ReferenceFlagUndefinedLazy",           1 },
227   { "ReferenceFlagDefined",                 2 },
228   { "ReferenceFlagPrivateDefined",          3 },
229   { "ReferenceFlagPrivateUndefinedNonLazy", 4 },
230   { "ReferenceFlagPrivateUndefinedLazy",    5 }
231 };
232
233 static const EnumEntry<unsigned> MachOSymbolFlags[] = {
234   { "ReferencedDynamically", 0x10 },
235   { "NoDeadStrip",           0x20 },
236   { "WeakRef",               0x40 },
237   { "WeakDef",               0x80 }
238 };
239
240 static const EnumEntry<unsigned> MachOSymbolTypes[] = {
241   { "Undef",           0x0 },
242   { "Abs",             0x2 },
243   { "Indirect",        0xA },
244   { "PreboundUndef",   0xC },
245   { "Section",         0xE }
246 };
247
248 namespace {
249   struct MachOSection {
250     ArrayRef<char> Name;
251     ArrayRef<char> SegmentName;
252     uint64_t Address;
253     uint64_t Size;
254     uint32_t Offset;
255     uint32_t Alignment;
256     uint32_t RelocationTableOffset;
257     uint32_t NumRelocationTableEntries;
258     uint32_t Flags;
259     uint32_t Reserved1;
260     uint32_t Reserved2;
261   };
262
263   struct MachOSymbol {
264     uint32_t StringIndex;
265     uint8_t Type;
266     uint8_t SectionIndex;
267     uint16_t Flags;
268     uint64_t Value;
269   };
270 }
271
272 static void getSection(const MachOObjectFile *Obj,
273                        DataRefImpl Sec,
274                        MachOSection &Section) {
275   if (!Obj->is64Bit()) {
276     MachO::section Sect = Obj->getSection(Sec);
277     Section.Address     = Sect.addr;
278     Section.Size        = Sect.size;
279     Section.Offset      = Sect.offset;
280     Section.Alignment   = Sect.align;
281     Section.RelocationTableOffset = Sect.reloff;
282     Section.NumRelocationTableEntries = Sect.nreloc;
283     Section.Flags       = Sect.flags;
284     Section.Reserved1   = Sect.reserved1;
285     Section.Reserved2   = Sect.reserved2;
286     return;
287   }
288   MachO::section_64 Sect = Obj->getSection64(Sec);
289   Section.Address     = Sect.addr;
290   Section.Size        = Sect.size;
291   Section.Offset      = Sect.offset;
292   Section.Alignment   = Sect.align;
293   Section.RelocationTableOffset = Sect.reloff;
294   Section.NumRelocationTableEntries = Sect.nreloc;
295   Section.Flags       = Sect.flags;
296   Section.Reserved1   = Sect.reserved1;
297   Section.Reserved2   = Sect.reserved2;
298 }
299
300
301 static void getSymbol(const MachOObjectFile *Obj,
302                       DataRefImpl DRI,
303                       MachOSymbol &Symbol) {
304   if (!Obj->is64Bit()) {
305     MachO::nlist Entry = Obj->getSymbolTableEntry(DRI);
306     Symbol.StringIndex  = Entry.n_strx;
307     Symbol.Type         = Entry.n_type;
308     Symbol.SectionIndex = Entry.n_sect;
309     Symbol.Flags        = Entry.n_desc;
310     Symbol.Value        = Entry.n_value;
311     return;
312   }
313   MachO::nlist_64 Entry = Obj->getSymbol64TableEntry(DRI);
314   Symbol.StringIndex  = Entry.n_strx;
315   Symbol.Type         = Entry.n_type;
316   Symbol.SectionIndex = Entry.n_sect;
317   Symbol.Flags        = Entry.n_desc;
318   Symbol.Value        = Entry.n_value;
319 }
320
321 void MachODumper::printFileHeaders() {
322   DictScope H(W, "MachHeader");
323   if (!Obj->is64Bit()) {
324     printFileHeaders(Obj->getHeader());
325   } else {
326     printFileHeaders(Obj->getHeader64());
327     W.printHex("Reserved", Obj->getHeader64().reserved);
328   }
329 }
330
331 template<class MachHeader>
332 void MachODumper::printFileHeaders(const MachHeader &Header) {
333   W.printEnum("Magic", Header.magic, makeArrayRef(MachOMagics));
334   W.printEnum("CpuType", Header.cputype, makeArrayRef(MachOHeaderCpuTypes));
335   uint32_t subtype = Header.cpusubtype & ~MachO::CPU_SUBTYPE_MASK;
336   switch (Header.cputype) {
337   case MachO::CPU_TYPE_X86:
338     W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX86));
339     break;
340   case MachO::CPU_TYPE_X86_64:
341     W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX64));
342     break;
343   case MachO::CPU_TYPE_ARM:
344     W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM));
345     break;
346   case MachO::CPU_TYPE_POWERPC:
347     W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesPPC));
348     break;
349   case MachO::CPU_TYPE_SPARC:
350     W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesSPARC));
351     break;
352   case MachO::CPU_TYPE_ARM64:
353     W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM64));
354     break;
355   case MachO::CPU_TYPE_POWERPC64:
356   default:
357     W.printHex("CpuSubtype", subtype);
358   }
359   W.printEnum("FileType", Header.filetype, makeArrayRef(MachOHeaderFileTypes));
360   W.printNumber("NumOfLoadCommands", Header.ncmds);
361   W.printNumber("SizeOfLoadCommands", Header.sizeofcmds);
362   W.printFlags("Flags", Header.flags, makeArrayRef(MachOHeaderFlags));
363 }
364
365 void MachODumper::printSections() {
366   return printSections(Obj);
367 }
368
369 void MachODumper::printSections(const MachOObjectFile *Obj) {
370   ListScope Group(W, "Sections");
371
372   int SectionIndex = -1;
373   for (const SectionRef &Section : Obj->sections()) {
374     ++SectionIndex;
375
376     MachOSection MOSection;
377     getSection(Obj, Section.getRawDataRefImpl(), MOSection);
378     DataRefImpl DR = Section.getRawDataRefImpl();
379
380     StringRef Name;
381     error(Section.getName(Name));
382
383     ArrayRef<char> RawName = Obj->getSectionRawName(DR);
384     StringRef SegmentName = Obj->getSectionFinalSegmentName(DR);
385     ArrayRef<char> RawSegmentName = Obj->getSectionRawFinalSegmentName(DR);
386
387     DictScope SectionD(W, "Section");
388     W.printNumber("Index", SectionIndex);
389     W.printBinary("Name", Name, RawName);
390     W.printBinary("Segment", SegmentName, RawSegmentName);
391     W.printHex("Address", MOSection.Address);
392     W.printHex("Size", MOSection.Size);
393     W.printNumber("Offset", MOSection.Offset);
394     W.printNumber("Alignment", MOSection.Alignment);
395     W.printHex("RelocationOffset", MOSection.RelocationTableOffset);
396     W.printNumber("RelocationCount", MOSection.NumRelocationTableEntries);
397     W.printEnum("Type", MOSection.Flags & 0xFF,
398                 makeArrayRef(MachOSectionAttributes));
399     W.printFlags("Attributes", MOSection.Flags >> 8,
400                  makeArrayRef(MachOSectionAttributes));
401     W.printHex("Reserved1", MOSection.Reserved1);
402     W.printHex("Reserved2", MOSection.Reserved2);
403
404     if (opts::SectionRelocations) {
405       ListScope D(W, "Relocations");
406       for (const RelocationRef &Reloc : Section.relocations())
407         printRelocation(Reloc);
408     }
409
410     if (opts::SectionSymbols) {
411       ListScope D(W, "Symbols");
412       for (const SymbolRef &Symbol : Obj->symbols()) {
413         if (!Section.containsSymbol(Symbol))
414           continue;
415
416         printSymbol(Symbol);
417       }
418     }
419
420     if (opts::SectionData) {
421       bool IsBSS = Section.isBSS();
422       if (!IsBSS) {
423         StringRef Data;
424         error(Section.getContents(Data));
425
426         W.printBinaryBlock("SectionData", Data);
427       }
428     }
429   }
430 }
431
432 void MachODumper::printRelocations() {
433   ListScope D(W, "Relocations");
434
435   std::error_code EC;
436   for (const SectionRef &Section : Obj->sections()) {
437     StringRef Name;
438     error(Section.getName(Name));
439
440     bool PrintedGroup = false;
441     for (const RelocationRef &Reloc : Section.relocations()) {
442       if (!PrintedGroup) {
443         W.startLine() << "Section " << Name << " {\n";
444         W.indent();
445         PrintedGroup = true;
446       }
447
448       printRelocation(Reloc);
449     }
450
451     if (PrintedGroup) {
452       W.unindent();
453       W.startLine() << "}\n";
454     }
455   }
456 }
457
458 void MachODumper::printRelocation(const RelocationRef &Reloc) {
459   return printRelocation(Obj, Reloc);
460 }
461
462 void MachODumper::printRelocation(const MachOObjectFile *Obj,
463                                   const RelocationRef &Reloc) {
464   uint64_t Offset = Reloc.getOffset();
465   SmallString<32> RelocName;
466   Reloc.getTypeName(RelocName);
467
468   DataRefImpl DR = Reloc.getRawDataRefImpl();
469   MachO::any_relocation_info RE = Obj->getRelocation(DR);
470   bool IsScattered = Obj->isRelocationScattered(RE);
471   bool IsExtern = !IsScattered && Obj->getPlainRelocationExternal(RE);
472
473   StringRef TargetName;
474   if (IsExtern) {
475     symbol_iterator Symbol = Reloc.getSymbol();
476     if (Symbol != Obj->symbol_end()) {
477       ErrorOr<StringRef> TargetNameOrErr = Symbol->getName();
478       error(TargetNameOrErr.getError());
479       TargetName = *TargetNameOrErr;
480     }
481   } else if (!IsScattered) {
482     section_iterator SecI = Obj->getRelocationSection(DR);
483     if (SecI != Obj->section_end()) {
484       error(SecI->getName(TargetName));
485     }
486   }
487   if (TargetName.empty())
488     TargetName = "-";
489
490   if (opts::ExpandRelocs) {
491     DictScope Group(W, "Relocation");
492     W.printHex("Offset", Offset);
493     W.printNumber("PCRel", Obj->getAnyRelocationPCRel(RE));
494     W.printNumber("Length", Obj->getAnyRelocationLength(RE));
495     W.printNumber("Type", RelocName, Obj->getAnyRelocationType(RE));
496     if (IsScattered) {
497       W.printHex("Value", Obj->getScatteredRelocationValue(RE));
498     } else {
499       const char *Kind = IsExtern ? "Symbol" : "Section";
500       W.printNumber(Kind, TargetName, Obj->getPlainRelocationSymbolNum(RE));
501     }
502   } else {
503     SmallString<32> SymbolNameOrOffset("0x");
504     if (IsScattered) {
505       // Scattered relocations don't really have an associated symbol for some
506       // reason, even if one exists in the symtab at the correct address.
507       SymbolNameOrOffset += utohexstr(Obj->getScatteredRelocationValue(RE));
508     } else {
509       SymbolNameOrOffset = TargetName;
510     }
511
512     raw_ostream& OS = W.startLine();
513     OS << W.hex(Offset)
514        << " " << Obj->getAnyRelocationPCRel(RE)
515        << " " << Obj->getAnyRelocationLength(RE);
516     if (IsScattered)
517       OS << " n/a";
518     else
519       OS << " " << Obj->getPlainRelocationExternal(RE);
520     OS << " " << RelocName
521        << " " << IsScattered
522        << " " << SymbolNameOrOffset
523        << "\n";
524   }
525 }
526
527 void MachODumper::printSymbols() {
528   ListScope Group(W, "Symbols");
529
530   for (const SymbolRef &Symbol : Obj->symbols()) {
531     printSymbol(Symbol);
532   }
533 }
534
535 void MachODumper::printDynamicSymbols() {
536   ListScope Group(W, "DynamicSymbols");
537 }
538
539 void MachODumper::printSymbol(const SymbolRef &Symbol) {
540   StringRef SymbolName;
541   if (ErrorOr<StringRef> SymbolNameOrErr = Symbol.getName())
542     SymbolName = *SymbolNameOrErr;
543
544   MachOSymbol MOSymbol;
545   getSymbol(Obj, Symbol.getRawDataRefImpl(), MOSymbol);
546
547   StringRef SectionName = "";
548   ErrorOr<section_iterator> SecIOrErr = Symbol.getSection();
549   error(SecIOrErr.getError());
550   section_iterator SecI = *SecIOrErr;
551   if (SecI != Obj->section_end())
552     error(SecI->getName(SectionName));
553
554   DictScope D(W, "Symbol");
555   W.printNumber("Name", SymbolName, MOSymbol.StringIndex);
556   if (MOSymbol.Type & MachO::N_STAB) {
557     W.printHex("Type", "SymDebugTable", MOSymbol.Type);
558   } else {
559     if (MOSymbol.Type & MachO::N_PEXT)
560       W.startLine() << "PrivateExtern\n";
561     if (MOSymbol.Type & MachO::N_EXT)
562       W.startLine() << "Extern\n";
563     W.printEnum("Type", uint8_t(MOSymbol.Type & MachO::N_TYPE),
564                 makeArrayRef(MachOSymbolTypes));
565   }
566   W.printHex("Section", SectionName, MOSymbol.SectionIndex);
567   W.printEnum("RefType", static_cast<uint16_t>(MOSymbol.Flags & 0xF),
568               makeArrayRef(MachOSymbolRefTypes));
569   W.printFlags("Flags", static_cast<uint16_t>(MOSymbol.Flags & ~0xF),
570                makeArrayRef(MachOSymbolFlags));
571   W.printHex("Value", MOSymbol.Value);
572 }
573
574 void MachODumper::printUnwindInfo() {
575   W.startLine() << "UnwindInfo not implemented.\n";
576 }
577
578 void MachODumper::printStackMap() const {
579   object::SectionRef StackMapSection;
580   for (auto Sec : Obj->sections()) {
581     StringRef Name;
582     Sec.getName(Name);
583     if (Name == "__llvm_stackmaps") {
584       StackMapSection = Sec;
585       break;
586     }
587   }
588
589   if (StackMapSection == object::SectionRef())
590     return;
591
592   StringRef StackMapContents;
593   StackMapSection.getContents(StackMapContents);
594   ArrayRef<uint8_t> StackMapContentsArray(
595       reinterpret_cast<const uint8_t*>(StackMapContents.data()),
596       StackMapContents.size());
597
598   if (Obj->isLittleEndian())
599      prettyPrintStackMap(
600                       llvm::outs(),
601                       StackMapV1Parser<support::little>(StackMapContentsArray));
602   else
603      prettyPrintStackMap(llvm::outs(),
604                          StackMapV1Parser<support::big>(StackMapContentsArray));
605 }
606
607 void MachODumper::printMachODataInCode() {
608   for (const auto &Load : Obj->load_commands()) {
609     if (Load.C.cmd  == MachO::LC_DATA_IN_CODE) {
610       MachO::linkedit_data_command LLC = Obj->getLinkeditDataLoadCommand(Load);
611       DictScope Group(W, "DataInCode");
612       W.printNumber("Data offset", LLC.dataoff);
613       W.printNumber("Data size", LLC.datasize);
614       ListScope D(W, "Data entries");
615       unsigned NumRegions = LLC.datasize / sizeof(MachO::data_in_code_entry);
616       for (unsigned i = 0; i < NumRegions; ++i) {
617         MachO::data_in_code_entry DICE = Obj->getDataInCodeTableEntry(
618                                                               LLC.dataoff, i);
619         DictScope Group(W, "Entry");
620         W.printNumber("Index", i);
621         W.printNumber("Offset", DICE.offset);
622         W.printNumber("Length", DICE.length);
623         W.printNumber("Kind", DICE.kind);
624       }
625     }
626   }
627 }