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-objdump.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm-objdump.h"
15 #include "llvm-c/Disassembler.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/BinaryFormat/MachO.h"
20 #include "llvm/Config/config.h"
21 #include "llvm/DebugInfo/DIContext.h"
22 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
23 #include "llvm/Demangle/Demangle.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/MC/MCInstPrinter.h"
29 #include "llvm/MC/MCInstrDesc.h"
30 #include "llvm/MC/MCInstrInfo.h"
31 #include "llvm/MC/MCRegisterInfo.h"
32 #include "llvm/MC/MCSubtargetInfo.h"
33 #include "llvm/Object/MachO.h"
34 #include "llvm/Object/MachOUniversal.h"
35 #include "llvm/Support/Casting.h"
36 #include "llvm/Support/CommandLine.h"
37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/Endian.h"
39 #include "llvm/Support/Format.h"
40 #include "llvm/Support/FormattedStream.h"
41 #include "llvm/Support/GraphWriter.h"
42 #include "llvm/Support/LEB128.h"
43 #include "llvm/Support/MemoryBuffer.h"
44 #include "llvm/Support/TargetRegistry.h"
45 #include "llvm/Support/TargetSelect.h"
46 #include "llvm/Support/ToolOutputFile.h"
47 #include "llvm/Support/raw_ostream.h"
48 #include <algorithm>
49 #include <cstring>
50 #include <system_error>
51 
52 #ifdef HAVE_LIBXAR
53 extern "C" {
54 #include <xar/xar.h>
55 }
56 #endif
57 
58 using namespace llvm;
59 using namespace object;
60 
61 static cl::opt<bool>
62     UseDbg("g",
63            cl::desc("Print line information from debug info if available"));
64 
65 static cl::opt<std::string> DSYMFile("dsym",
66                                      cl::desc("Use .dSYM file for debug info"));
67 
68 static cl::opt<bool> FullLeadingAddr("full-leading-addr",
69                                      cl::desc("Print full leading address"));
70 
71 static cl::opt<bool> NoLeadingHeaders("no-leading-headers",
72                                       cl::desc("Print no leading headers"));
73 
74 cl::opt<bool> llvm::UniversalHeaders("universal-headers",
75                                      cl::desc("Print Mach-O universal headers "
76                                               "(requires -macho)"));
77 
78 cl::opt<bool>
79     llvm::ArchiveHeaders("archive-headers",
80                          cl::desc("Print archive headers for Mach-O archives "
81                                   "(requires -macho)"));
82 
83 cl::opt<bool>
84     ArchiveMemberOffsets("archive-member-offsets",
85                          cl::desc("Print the offset to each archive member for "
86                                   "Mach-O archives (requires -macho and "
87                                   "-archive-headers)"));
88 
89 cl::opt<bool>
90     llvm::IndirectSymbols("indirect-symbols",
91                           cl::desc("Print indirect symbol table for Mach-O "
92                                    "objects (requires -macho)"));
93 
94 cl::opt<bool>
95     llvm::DataInCode("data-in-code",
96                      cl::desc("Print the data in code table for Mach-O objects "
97                               "(requires -macho)"));
98 
99 cl::opt<bool>
100     llvm::LinkOptHints("link-opt-hints",
101                        cl::desc("Print the linker optimization hints for "
102                                 "Mach-O objects (requires -macho)"));
103 
104 cl::opt<bool>
105     llvm::InfoPlist("info-plist",
106                     cl::desc("Print the info plist section as strings for "
107                              "Mach-O objects (requires -macho)"));
108 
109 cl::opt<bool>
110     llvm::DylibsUsed("dylibs-used",
111                      cl::desc("Print the shared libraries used for linked "
112                               "Mach-O files (requires -macho)"));
113 
114 cl::opt<bool>
115     llvm::DylibId("dylib-id",
116                   cl::desc("Print the shared library's id for the dylib Mach-O "
117                            "file (requires -macho)"));
118 
119 cl::opt<bool>
120     llvm::NonVerbose("non-verbose",
121                      cl::desc("Print the info for Mach-O objects in "
122                               "non-verbose or numeric form (requires -macho)"));
123 
124 cl::opt<bool>
125     llvm::ObjcMetaData("objc-meta-data",
126                        cl::desc("Print the Objective-C runtime meta data for "
127                                 "Mach-O files (requires -macho)"));
128 
129 cl::opt<std::string> llvm::DisSymName(
130     "dis-symname",
131     cl::desc("disassemble just this symbol's instructions (requires -macho)"));
132 
133 static cl::opt<bool> NoSymbolicOperands(
134     "no-symbolic-operands",
135     cl::desc("do not symbolic operands when disassembling (requires -macho)"));
136 
137 static cl::list<std::string>
138     ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
139               cl::ZeroOrMore);
140 
141 bool ArchAll = false;
142 
143 static std::string ThumbTripleName;
144 
145 static const Target *GetTarget(const MachOObjectFile *MachOObj,
146                                const char **McpuDefault,
147                                const Target **ThumbTarget) {
148   // Figure out the target triple.
149   llvm::Triple TT(TripleName);
150   if (TripleName.empty()) {
151     TT = MachOObj->getArchTriple(McpuDefault);
152     TripleName = TT.str();
153   }
154 
155   if (TT.getArch() == Triple::arm) {
156     // We've inferred a 32-bit ARM target from the object file. All MachO CPUs
157     // that support ARM are also capable of Thumb mode.
158     llvm::Triple ThumbTriple = TT;
159     std::string ThumbName = (Twine("thumb") + TT.getArchName().substr(3)).str();
160     ThumbTriple.setArchName(ThumbName);
161     ThumbTripleName = ThumbTriple.str();
162   }
163 
164   // Get the target specific parser.
165   std::string Error;
166   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
167   if (TheTarget && ThumbTripleName.empty())
168     return TheTarget;
169 
170   *ThumbTarget = TargetRegistry::lookupTarget(ThumbTripleName, Error);
171   if (*ThumbTarget)
172     return TheTarget;
173 
174   errs() << "llvm-objdump: error: unable to get target for '";
175   if (!TheTarget)
176     errs() << TripleName;
177   else
178     errs() << ThumbTripleName;
179   errs() << "', see --version and --triple.\n";
180   return nullptr;
181 }
182 
183 struct SymbolSorter {
184   bool operator()(const SymbolRef &A, const SymbolRef &B) {
185     Expected<SymbolRef::Type> ATypeOrErr = A.getType();
186     if (!ATypeOrErr)
187       report_error(A.getObject()->getFileName(), ATypeOrErr.takeError());
188     SymbolRef::Type AType = *ATypeOrErr;
189     Expected<SymbolRef::Type> BTypeOrErr = B.getType();
190     if (!BTypeOrErr)
191       report_error(B.getObject()->getFileName(), BTypeOrErr.takeError());
192     SymbolRef::Type BType = *BTypeOrErr;
193     uint64_t AAddr = (AType != SymbolRef::ST_Function) ? 0 : A.getValue();
194     uint64_t BAddr = (BType != SymbolRef::ST_Function) ? 0 : B.getValue();
195     return AAddr < BAddr;
196   }
197 };
198 
199 // Types for the storted data in code table that is built before disassembly
200 // and the predicate function to sort them.
201 typedef std::pair<uint64_t, DiceRef> DiceTableEntry;
202 typedef std::vector<DiceTableEntry> DiceTable;
203 typedef DiceTable::iterator dice_table_iterator;
204 
205 // This is used to search for a data in code table entry for the PC being
206 // disassembled.  The j parameter has the PC in j.first.  A single data in code
207 // table entry can cover many bytes for each of its Kind's.  So if the offset,
208 // aka the i.first value, of the data in code table entry plus its Length
209 // covers the PC being searched for this will return true.  If not it will
210 // return false.
211 static bool compareDiceTableEntries(const DiceTableEntry &i,
212                                     const DiceTableEntry &j) {
213   uint16_t Length;
214   i.second.getLength(Length);
215 
216   return j.first >= i.first && j.first < i.first + Length;
217 }
218 
219 static uint64_t DumpDataInCode(const uint8_t *bytes, uint64_t Length,
220                                unsigned short Kind) {
221   uint32_t Value, Size = 1;
222 
223   switch (Kind) {
224   default:
225   case MachO::DICE_KIND_DATA:
226     if (Length >= 4) {
227       if (!NoShowRawInsn)
228         dumpBytes(makeArrayRef(bytes, 4), outs());
229       Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
230       outs() << "\t.long " << Value;
231       Size = 4;
232     } else if (Length >= 2) {
233       if (!NoShowRawInsn)
234         dumpBytes(makeArrayRef(bytes, 2), outs());
235       Value = bytes[1] << 8 | bytes[0];
236       outs() << "\t.short " << Value;
237       Size = 2;
238     } else {
239       if (!NoShowRawInsn)
240         dumpBytes(makeArrayRef(bytes, 2), outs());
241       Value = bytes[0];
242       outs() << "\t.byte " << Value;
243       Size = 1;
244     }
245     if (Kind == MachO::DICE_KIND_DATA)
246       outs() << "\t@ KIND_DATA\n";
247     else
248       outs() << "\t@ data in code kind = " << Kind << "\n";
249     break;
250   case MachO::DICE_KIND_JUMP_TABLE8:
251     if (!NoShowRawInsn)
252       dumpBytes(makeArrayRef(bytes, 1), outs());
253     Value = bytes[0];
254     outs() << "\t.byte " << format("%3u", Value) << "\t@ KIND_JUMP_TABLE8\n";
255     Size = 1;
256     break;
257   case MachO::DICE_KIND_JUMP_TABLE16:
258     if (!NoShowRawInsn)
259       dumpBytes(makeArrayRef(bytes, 2), outs());
260     Value = bytes[1] << 8 | bytes[0];
261     outs() << "\t.short " << format("%5u", Value & 0xffff)
262            << "\t@ KIND_JUMP_TABLE16\n";
263     Size = 2;
264     break;
265   case MachO::DICE_KIND_JUMP_TABLE32:
266   case MachO::DICE_KIND_ABS_JUMP_TABLE32:
267     if (!NoShowRawInsn)
268       dumpBytes(makeArrayRef(bytes, 4), outs());
269     Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
270     outs() << "\t.long " << Value;
271     if (Kind == MachO::DICE_KIND_JUMP_TABLE32)
272       outs() << "\t@ KIND_JUMP_TABLE32\n";
273     else
274       outs() << "\t@ KIND_ABS_JUMP_TABLE32\n";
275     Size = 4;
276     break;
277   }
278   return Size;
279 }
280 
281 static void getSectionsAndSymbols(MachOObjectFile *MachOObj,
282                                   std::vector<SectionRef> &Sections,
283                                   std::vector<SymbolRef> &Symbols,
284                                   SmallVectorImpl<uint64_t> &FoundFns,
285                                   uint64_t &BaseSegmentAddress) {
286   for (const SymbolRef &Symbol : MachOObj->symbols()) {
287     Expected<StringRef> SymName = Symbol.getName();
288     if (!SymName)
289       report_error(MachOObj->getFileName(), SymName.takeError());
290     if (!SymName->startswith("ltmp"))
291       Symbols.push_back(Symbol);
292   }
293 
294   for (const SectionRef &Section : MachOObj->sections()) {
295     StringRef SectName;
296     Section.getName(SectName);
297     Sections.push_back(Section);
298   }
299 
300   bool BaseSegmentAddressSet = false;
301   for (const auto &Command : MachOObj->load_commands()) {
302     if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
303       // We found a function starts segment, parse the addresses for later
304       // consumption.
305       MachO::linkedit_data_command LLC =
306           MachOObj->getLinkeditDataLoadCommand(Command);
307 
308       MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
309     } else if (Command.C.cmd == MachO::LC_SEGMENT) {
310       MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command);
311       StringRef SegName = SLC.segname;
312       if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
313         BaseSegmentAddressSet = true;
314         BaseSegmentAddress = SLC.vmaddr;
315       }
316     }
317   }
318 }
319 
320 static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose,
321                                      uint32_t n, uint32_t count,
322                                      uint32_t stride, uint64_t addr) {
323   MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
324   uint32_t nindirectsyms = Dysymtab.nindirectsyms;
325   if (n > nindirectsyms)
326     outs() << " (entries start past the end of the indirect symbol "
327               "table) (reserved1 field greater than the table size)";
328   else if (n + count > nindirectsyms)
329     outs() << " (entries extends past the end of the indirect symbol "
330               "table)";
331   outs() << "\n";
332   uint32_t cputype = O->getHeader().cputype;
333   if (cputype & MachO::CPU_ARCH_ABI64)
334     outs() << "address            index";
335   else
336     outs() << "address    index";
337   if (verbose)
338     outs() << " name\n";
339   else
340     outs() << "\n";
341   for (uint32_t j = 0; j < count && n + j < nindirectsyms; j++) {
342     if (cputype & MachO::CPU_ARCH_ABI64)
343       outs() << format("0x%016" PRIx64, addr + j * stride) << " ";
344     else
345       outs() << format("0x%08" PRIx32, (uint32_t)addr + j * stride) << " ";
346     MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
347     uint32_t indirect_symbol = O->getIndirectSymbolTableEntry(Dysymtab, n + j);
348     if (indirect_symbol == MachO::INDIRECT_SYMBOL_LOCAL) {
349       outs() << "LOCAL\n";
350       continue;
351     }
352     if (indirect_symbol ==
353         (MachO::INDIRECT_SYMBOL_LOCAL | MachO::INDIRECT_SYMBOL_ABS)) {
354       outs() << "LOCAL ABSOLUTE\n";
355       continue;
356     }
357     if (indirect_symbol == MachO::INDIRECT_SYMBOL_ABS) {
358       outs() << "ABSOLUTE\n";
359       continue;
360     }
361     outs() << format("%5u ", indirect_symbol);
362     if (verbose) {
363       MachO::symtab_command Symtab = O->getSymtabLoadCommand();
364       if (indirect_symbol < Symtab.nsyms) {
365         symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol);
366         SymbolRef Symbol = *Sym;
367         Expected<StringRef> SymName = Symbol.getName();
368         if (!SymName)
369           report_error(O->getFileName(), SymName.takeError());
370         outs() << *SymName;
371       } else {
372         outs() << "?";
373       }
374     }
375     outs() << "\n";
376   }
377 }
378 
379 static void PrintIndirectSymbols(MachOObjectFile *O, bool verbose) {
380   for (const auto &Load : O->load_commands()) {
381     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
382       MachO::segment_command_64 Seg = O->getSegment64LoadCommand(Load);
383       for (unsigned J = 0; J < Seg.nsects; ++J) {
384         MachO::section_64 Sec = O->getSection64(Load, J);
385         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
386         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
387             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
388             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
389             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
390             section_type == MachO::S_SYMBOL_STUBS) {
391           uint32_t stride;
392           if (section_type == MachO::S_SYMBOL_STUBS)
393             stride = Sec.reserved2;
394           else
395             stride = 8;
396           if (stride == 0) {
397             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
398                    << Sec.sectname << ") "
399                    << "(size of stubs in reserved2 field is zero)\n";
400             continue;
401           }
402           uint32_t count = Sec.size / stride;
403           outs() << "Indirect symbols for (" << Sec.segname << ","
404                  << Sec.sectname << ") " << count << " entries";
405           uint32_t n = Sec.reserved1;
406           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
407         }
408       }
409     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
410       MachO::segment_command Seg = O->getSegmentLoadCommand(Load);
411       for (unsigned J = 0; J < Seg.nsects; ++J) {
412         MachO::section Sec = O->getSection(Load, J);
413         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
414         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
415             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
416             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
417             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
418             section_type == MachO::S_SYMBOL_STUBS) {
419           uint32_t stride;
420           if (section_type == MachO::S_SYMBOL_STUBS)
421             stride = Sec.reserved2;
422           else
423             stride = 4;
424           if (stride == 0) {
425             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
426                    << Sec.sectname << ") "
427                    << "(size of stubs in reserved2 field is zero)\n";
428             continue;
429           }
430           uint32_t count = Sec.size / stride;
431           outs() << "Indirect symbols for (" << Sec.segname << ","
432                  << Sec.sectname << ") " << count << " entries";
433           uint32_t n = Sec.reserved1;
434           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
435         }
436       }
437     }
438   }
439 }
440 
441 static void PrintDataInCodeTable(MachOObjectFile *O, bool verbose) {
442   MachO::linkedit_data_command DIC = O->getDataInCodeLoadCommand();
443   uint32_t nentries = DIC.datasize / sizeof(struct MachO::data_in_code_entry);
444   outs() << "Data in code table (" << nentries << " entries)\n";
445   outs() << "offset     length kind\n";
446   for (dice_iterator DI = O->begin_dices(), DE = O->end_dices(); DI != DE;
447        ++DI) {
448     uint32_t Offset;
449     DI->getOffset(Offset);
450     outs() << format("0x%08" PRIx32, Offset) << " ";
451     uint16_t Length;
452     DI->getLength(Length);
453     outs() << format("%6u", Length) << " ";
454     uint16_t Kind;
455     DI->getKind(Kind);
456     if (verbose) {
457       switch (Kind) {
458       case MachO::DICE_KIND_DATA:
459         outs() << "DATA";
460         break;
461       case MachO::DICE_KIND_JUMP_TABLE8:
462         outs() << "JUMP_TABLE8";
463         break;
464       case MachO::DICE_KIND_JUMP_TABLE16:
465         outs() << "JUMP_TABLE16";
466         break;
467       case MachO::DICE_KIND_JUMP_TABLE32:
468         outs() << "JUMP_TABLE32";
469         break;
470       case MachO::DICE_KIND_ABS_JUMP_TABLE32:
471         outs() << "ABS_JUMP_TABLE32";
472         break;
473       default:
474         outs() << format("0x%04" PRIx32, Kind);
475         break;
476       }
477     } else
478       outs() << format("0x%04" PRIx32, Kind);
479     outs() << "\n";
480   }
481 }
482 
483 static void PrintLinkOptHints(MachOObjectFile *O) {
484   MachO::linkedit_data_command LohLC = O->getLinkOptHintsLoadCommand();
485   const char *loh = O->getData().substr(LohLC.dataoff, 1).data();
486   uint32_t nloh = LohLC.datasize;
487   outs() << "Linker optimiztion hints (" << nloh << " total bytes)\n";
488   for (uint32_t i = 0; i < nloh;) {
489     unsigned n;
490     uint64_t identifier = decodeULEB128((const uint8_t *)(loh + i), &n);
491     i += n;
492     outs() << "    identifier " << identifier << " ";
493     if (i >= nloh)
494       return;
495     switch (identifier) {
496     case 1:
497       outs() << "AdrpAdrp\n";
498       break;
499     case 2:
500       outs() << "AdrpLdr\n";
501       break;
502     case 3:
503       outs() << "AdrpAddLdr\n";
504       break;
505     case 4:
506       outs() << "AdrpLdrGotLdr\n";
507       break;
508     case 5:
509       outs() << "AdrpAddStr\n";
510       break;
511     case 6:
512       outs() << "AdrpLdrGotStr\n";
513       break;
514     case 7:
515       outs() << "AdrpAdd\n";
516       break;
517     case 8:
518       outs() << "AdrpLdrGot\n";
519       break;
520     default:
521       outs() << "Unknown identifier value\n";
522       break;
523     }
524     uint64_t narguments = decodeULEB128((const uint8_t *)(loh + i), &n);
525     i += n;
526     outs() << "    narguments " << narguments << "\n";
527     if (i >= nloh)
528       return;
529 
530     for (uint32_t j = 0; j < narguments; j++) {
531       uint64_t value = decodeULEB128((const uint8_t *)(loh + i), &n);
532       i += n;
533       outs() << "\tvalue " << format("0x%" PRIx64, value) << "\n";
534       if (i >= nloh)
535         return;
536     }
537   }
538 }
539 
540 static void PrintDylibs(MachOObjectFile *O, bool JustId) {
541   unsigned Index = 0;
542   for (const auto &Load : O->load_commands()) {
543     if ((JustId && Load.C.cmd == MachO::LC_ID_DYLIB) ||
544         (!JustId && (Load.C.cmd == MachO::LC_ID_DYLIB ||
545                      Load.C.cmd == MachO::LC_LOAD_DYLIB ||
546                      Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
547                      Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
548                      Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
549                      Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB))) {
550       MachO::dylib_command dl = O->getDylibIDLoadCommand(Load);
551       if (dl.dylib.name < dl.cmdsize) {
552         const char *p = (const char *)(Load.Ptr) + dl.dylib.name;
553         if (JustId)
554           outs() << p << "\n";
555         else {
556           outs() << "\t" << p;
557           outs() << " (compatibility version "
558                  << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
559                  << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
560                  << (dl.dylib.compatibility_version & 0xff) << ",";
561           outs() << " current version "
562                  << ((dl.dylib.current_version >> 16) & 0xffff) << "."
563                  << ((dl.dylib.current_version >> 8) & 0xff) << "."
564                  << (dl.dylib.current_version & 0xff) << ")\n";
565         }
566       } else {
567         outs() << "\tBad offset (" << dl.dylib.name << ") for name of ";
568         if (Load.C.cmd == MachO::LC_ID_DYLIB)
569           outs() << "LC_ID_DYLIB ";
570         else if (Load.C.cmd == MachO::LC_LOAD_DYLIB)
571           outs() << "LC_LOAD_DYLIB ";
572         else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB)
573           outs() << "LC_LOAD_WEAK_DYLIB ";
574         else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB)
575           outs() << "LC_LAZY_LOAD_DYLIB ";
576         else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB)
577           outs() << "LC_REEXPORT_DYLIB ";
578         else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
579           outs() << "LC_LOAD_UPWARD_DYLIB ";
580         else
581           outs() << "LC_??? ";
582         outs() << "command " << Index++ << "\n";
583       }
584     }
585   }
586 }
587 
588 typedef DenseMap<uint64_t, StringRef> SymbolAddressMap;
589 
590 static void CreateSymbolAddressMap(MachOObjectFile *O,
591                                    SymbolAddressMap *AddrMap) {
592   // Create a map of symbol addresses to symbol names.
593   for (const SymbolRef &Symbol : O->symbols()) {
594     Expected<SymbolRef::Type> STOrErr = Symbol.getType();
595     if (!STOrErr)
596       report_error(O->getFileName(), STOrErr.takeError());
597     SymbolRef::Type ST = *STOrErr;
598     if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
599         ST == SymbolRef::ST_Other) {
600       uint64_t Address = Symbol.getValue();
601       Expected<StringRef> SymNameOrErr = Symbol.getName();
602       if (!SymNameOrErr)
603         report_error(O->getFileName(), SymNameOrErr.takeError());
604       StringRef SymName = *SymNameOrErr;
605       if (!SymName.startswith(".objc"))
606         (*AddrMap)[Address] = SymName;
607     }
608   }
609 }
610 
611 // GuessSymbolName is passed the address of what might be a symbol and a
612 // pointer to the SymbolAddressMap.  It returns the name of a symbol
613 // with that address or nullptr if no symbol is found with that address.
614 static const char *GuessSymbolName(uint64_t value, SymbolAddressMap *AddrMap) {
615   const char *SymbolName = nullptr;
616   // A DenseMap can't lookup up some values.
617   if (value != 0xffffffffffffffffULL && value != 0xfffffffffffffffeULL) {
618     StringRef name = AddrMap->lookup(value);
619     if (!name.empty())
620       SymbolName = name.data();
621   }
622   return SymbolName;
623 }
624 
625 static void DumpCstringChar(const char c) {
626   char p[2];
627   p[0] = c;
628   p[1] = '\0';
629   outs().write_escaped(p);
630 }
631 
632 static void DumpCstringSection(MachOObjectFile *O, const char *sect,
633                                uint32_t sect_size, uint64_t sect_addr,
634                                bool print_addresses) {
635   for (uint32_t i = 0; i < sect_size; i++) {
636     if (print_addresses) {
637       if (O->is64Bit())
638         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
639       else
640         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
641     }
642     for (; i < sect_size && sect[i] != '\0'; i++)
643       DumpCstringChar(sect[i]);
644     if (i < sect_size && sect[i] == '\0')
645       outs() << "\n";
646   }
647 }
648 
649 static void DumpLiteral4(uint32_t l, float f) {
650   outs() << format("0x%08" PRIx32, l);
651   if ((l & 0x7f800000) != 0x7f800000)
652     outs() << format(" (%.16e)\n", f);
653   else {
654     if (l == 0x7f800000)
655       outs() << " (+Infinity)\n";
656     else if (l == 0xff800000)
657       outs() << " (-Infinity)\n";
658     else if ((l & 0x00400000) == 0x00400000)
659       outs() << " (non-signaling Not-a-Number)\n";
660     else
661       outs() << " (signaling Not-a-Number)\n";
662   }
663 }
664 
665 static void DumpLiteral4Section(MachOObjectFile *O, const char *sect,
666                                 uint32_t sect_size, uint64_t sect_addr,
667                                 bool print_addresses) {
668   for (uint32_t i = 0; i < sect_size; i += sizeof(float)) {
669     if (print_addresses) {
670       if (O->is64Bit())
671         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
672       else
673         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
674     }
675     float f;
676     memcpy(&f, sect + i, sizeof(float));
677     if (O->isLittleEndian() != sys::IsLittleEndianHost)
678       sys::swapByteOrder(f);
679     uint32_t l;
680     memcpy(&l, sect + i, sizeof(uint32_t));
681     if (O->isLittleEndian() != sys::IsLittleEndianHost)
682       sys::swapByteOrder(l);
683     DumpLiteral4(l, f);
684   }
685 }
686 
687 static void DumpLiteral8(MachOObjectFile *O, uint32_t l0, uint32_t l1,
688                          double d) {
689   outs() << format("0x%08" PRIx32, l0) << " " << format("0x%08" PRIx32, l1);
690   uint32_t Hi, Lo;
691   Hi = (O->isLittleEndian()) ? l1 : l0;
692   Lo = (O->isLittleEndian()) ? l0 : l1;
693 
694   // Hi is the high word, so this is equivalent to if(isfinite(d))
695   if ((Hi & 0x7ff00000) != 0x7ff00000)
696     outs() << format(" (%.16e)\n", d);
697   else {
698     if (Hi == 0x7ff00000 && Lo == 0)
699       outs() << " (+Infinity)\n";
700     else if (Hi == 0xfff00000 && Lo == 0)
701       outs() << " (-Infinity)\n";
702     else if ((Hi & 0x00080000) == 0x00080000)
703       outs() << " (non-signaling Not-a-Number)\n";
704     else
705       outs() << " (signaling Not-a-Number)\n";
706   }
707 }
708 
709 static void DumpLiteral8Section(MachOObjectFile *O, const char *sect,
710                                 uint32_t sect_size, uint64_t sect_addr,
711                                 bool print_addresses) {
712   for (uint32_t i = 0; i < sect_size; i += sizeof(double)) {
713     if (print_addresses) {
714       if (O->is64Bit())
715         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
716       else
717         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
718     }
719     double d;
720     memcpy(&d, sect + i, sizeof(double));
721     if (O->isLittleEndian() != sys::IsLittleEndianHost)
722       sys::swapByteOrder(d);
723     uint32_t l0, l1;
724     memcpy(&l0, sect + i, sizeof(uint32_t));
725     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
726     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
727       sys::swapByteOrder(l0);
728       sys::swapByteOrder(l1);
729     }
730     DumpLiteral8(O, l0, l1, d);
731   }
732 }
733 
734 static void DumpLiteral16(uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3) {
735   outs() << format("0x%08" PRIx32, l0) << " ";
736   outs() << format("0x%08" PRIx32, l1) << " ";
737   outs() << format("0x%08" PRIx32, l2) << " ";
738   outs() << format("0x%08" PRIx32, l3) << "\n";
739 }
740 
741 static void DumpLiteral16Section(MachOObjectFile *O, const char *sect,
742                                  uint32_t sect_size, uint64_t sect_addr,
743                                  bool print_addresses) {
744   for (uint32_t i = 0; i < sect_size; i += 16) {
745     if (print_addresses) {
746       if (O->is64Bit())
747         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
748       else
749         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
750     }
751     uint32_t l0, l1, l2, l3;
752     memcpy(&l0, sect + i, sizeof(uint32_t));
753     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
754     memcpy(&l2, sect + i + 2 * sizeof(uint32_t), sizeof(uint32_t));
755     memcpy(&l3, sect + i + 3 * sizeof(uint32_t), sizeof(uint32_t));
756     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
757       sys::swapByteOrder(l0);
758       sys::swapByteOrder(l1);
759       sys::swapByteOrder(l2);
760       sys::swapByteOrder(l3);
761     }
762     DumpLiteral16(l0, l1, l2, l3);
763   }
764 }
765 
766 static void DumpLiteralPointerSection(MachOObjectFile *O,
767                                       const SectionRef &Section,
768                                       const char *sect, uint32_t sect_size,
769                                       uint64_t sect_addr,
770                                       bool print_addresses) {
771   // Collect the literal sections in this Mach-O file.
772   std::vector<SectionRef> LiteralSections;
773   for (const SectionRef &Section : O->sections()) {
774     DataRefImpl Ref = Section.getRawDataRefImpl();
775     uint32_t section_type;
776     if (O->is64Bit()) {
777       const MachO::section_64 Sec = O->getSection64(Ref);
778       section_type = Sec.flags & MachO::SECTION_TYPE;
779     } else {
780       const MachO::section Sec = O->getSection(Ref);
781       section_type = Sec.flags & MachO::SECTION_TYPE;
782     }
783     if (section_type == MachO::S_CSTRING_LITERALS ||
784         section_type == MachO::S_4BYTE_LITERALS ||
785         section_type == MachO::S_8BYTE_LITERALS ||
786         section_type == MachO::S_16BYTE_LITERALS)
787       LiteralSections.push_back(Section);
788   }
789 
790   // Set the size of the literal pointer.
791   uint32_t lp_size = O->is64Bit() ? 8 : 4;
792 
793   // Collect the external relocation symbols for the literal pointers.
794   std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
795   for (const RelocationRef &Reloc : Section.relocations()) {
796     DataRefImpl Rel;
797     MachO::any_relocation_info RE;
798     bool isExtern = false;
799     Rel = Reloc.getRawDataRefImpl();
800     RE = O->getRelocation(Rel);
801     isExtern = O->getPlainRelocationExternal(RE);
802     if (isExtern) {
803       uint64_t RelocOffset = Reloc.getOffset();
804       symbol_iterator RelocSym = Reloc.getSymbol();
805       Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
806     }
807   }
808   array_pod_sort(Relocs.begin(), Relocs.end());
809 
810   // Dump each literal pointer.
811   for (uint32_t i = 0; i < sect_size; i += lp_size) {
812     if (print_addresses) {
813       if (O->is64Bit())
814         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
815       else
816         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
817     }
818     uint64_t lp;
819     if (O->is64Bit()) {
820       memcpy(&lp, sect + i, sizeof(uint64_t));
821       if (O->isLittleEndian() != sys::IsLittleEndianHost)
822         sys::swapByteOrder(lp);
823     } else {
824       uint32_t li;
825       memcpy(&li, sect + i, sizeof(uint32_t));
826       if (O->isLittleEndian() != sys::IsLittleEndianHost)
827         sys::swapByteOrder(li);
828       lp = li;
829     }
830 
831     // First look for an external relocation entry for this literal pointer.
832     auto Reloc = find_if(Relocs, [&](const std::pair<uint64_t, SymbolRef> &P) {
833       return P.first == i;
834     });
835     if (Reloc != Relocs.end()) {
836       symbol_iterator RelocSym = Reloc->second;
837       Expected<StringRef> SymName = RelocSym->getName();
838       if (!SymName)
839         report_error(O->getFileName(), SymName.takeError());
840       outs() << "external relocation entry for symbol:" << *SymName << "\n";
841       continue;
842     }
843 
844     // For local references see what the section the literal pointer points to.
845     auto Sect = find_if(LiteralSections, [&](const SectionRef &R) {
846       return lp >= R.getAddress() && lp < R.getAddress() + R.getSize();
847     });
848     if (Sect == LiteralSections.end()) {
849       outs() << format("0x%" PRIx64, lp) << " (not in a literal section)\n";
850       continue;
851     }
852 
853     uint64_t SectAddress = Sect->getAddress();
854     uint64_t SectSize = Sect->getSize();
855 
856     StringRef SectName;
857     Sect->getName(SectName);
858     DataRefImpl Ref = Sect->getRawDataRefImpl();
859     StringRef SegmentName = O->getSectionFinalSegmentName(Ref);
860     outs() << SegmentName << ":" << SectName << ":";
861 
862     uint32_t section_type;
863     if (O->is64Bit()) {
864       const MachO::section_64 Sec = O->getSection64(Ref);
865       section_type = Sec.flags & MachO::SECTION_TYPE;
866     } else {
867       const MachO::section Sec = O->getSection(Ref);
868       section_type = Sec.flags & MachO::SECTION_TYPE;
869     }
870 
871     StringRef BytesStr;
872     Sect->getContents(BytesStr);
873     const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
874 
875     switch (section_type) {
876     case MachO::S_CSTRING_LITERALS:
877       for (uint64_t i = lp - SectAddress; i < SectSize && Contents[i] != '\0';
878            i++) {
879         DumpCstringChar(Contents[i]);
880       }
881       outs() << "\n";
882       break;
883     case MachO::S_4BYTE_LITERALS:
884       float f;
885       memcpy(&f, Contents + (lp - SectAddress), sizeof(float));
886       uint32_t l;
887       memcpy(&l, Contents + (lp - SectAddress), sizeof(uint32_t));
888       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
889         sys::swapByteOrder(f);
890         sys::swapByteOrder(l);
891       }
892       DumpLiteral4(l, f);
893       break;
894     case MachO::S_8BYTE_LITERALS: {
895       double d;
896       memcpy(&d, Contents + (lp - SectAddress), sizeof(double));
897       uint32_t l0, l1;
898       memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
899       memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
900              sizeof(uint32_t));
901       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
902         sys::swapByteOrder(f);
903         sys::swapByteOrder(l0);
904         sys::swapByteOrder(l1);
905       }
906       DumpLiteral8(O, l0, l1, d);
907       break;
908     }
909     case MachO::S_16BYTE_LITERALS: {
910       uint32_t l0, l1, l2, l3;
911       memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
912       memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
913              sizeof(uint32_t));
914       memcpy(&l2, Contents + (lp - SectAddress) + 2 * sizeof(uint32_t),
915              sizeof(uint32_t));
916       memcpy(&l3, Contents + (lp - SectAddress) + 3 * sizeof(uint32_t),
917              sizeof(uint32_t));
918       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
919         sys::swapByteOrder(l0);
920         sys::swapByteOrder(l1);
921         sys::swapByteOrder(l2);
922         sys::swapByteOrder(l3);
923       }
924       DumpLiteral16(l0, l1, l2, l3);
925       break;
926     }
927     }
928   }
929 }
930 
931 static void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect,
932                                        uint32_t sect_size, uint64_t sect_addr,
933                                        SymbolAddressMap *AddrMap,
934                                        bool verbose) {
935   uint32_t stride;
936   stride = (O->is64Bit()) ? sizeof(uint64_t) : sizeof(uint32_t);
937   for (uint32_t i = 0; i < sect_size; i += stride) {
938     const char *SymbolName = nullptr;
939     if (O->is64Bit()) {
940       outs() << format("0x%016" PRIx64, sect_addr + i * stride) << " ";
941       uint64_t pointer_value;
942       memcpy(&pointer_value, sect + i, stride);
943       if (O->isLittleEndian() != sys::IsLittleEndianHost)
944         sys::swapByteOrder(pointer_value);
945       outs() << format("0x%016" PRIx64, pointer_value);
946       if (verbose)
947         SymbolName = GuessSymbolName(pointer_value, AddrMap);
948     } else {
949       outs() << format("0x%08" PRIx64, sect_addr + i * stride) << " ";
950       uint32_t pointer_value;
951       memcpy(&pointer_value, sect + i, stride);
952       if (O->isLittleEndian() != sys::IsLittleEndianHost)
953         sys::swapByteOrder(pointer_value);
954       outs() << format("0x%08" PRIx32, pointer_value);
955       if (verbose)
956         SymbolName = GuessSymbolName(pointer_value, AddrMap);
957     }
958     if (SymbolName)
959       outs() << " " << SymbolName;
960     outs() << "\n";
961   }
962 }
963 
964 static void DumpRawSectionContents(MachOObjectFile *O, const char *sect,
965                                    uint32_t size, uint64_t addr) {
966   uint32_t cputype = O->getHeader().cputype;
967   if (cputype == MachO::CPU_TYPE_I386 || cputype == MachO::CPU_TYPE_X86_64) {
968     uint32_t j;
969     for (uint32_t i = 0; i < size; i += j, addr += j) {
970       if (O->is64Bit())
971         outs() << format("%016" PRIx64, addr) << "\t";
972       else
973         outs() << format("%08" PRIx64, addr) << "\t";
974       for (j = 0; j < 16 && i + j < size; j++) {
975         uint8_t byte_word = *(sect + i + j);
976         outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
977       }
978       outs() << "\n";
979     }
980   } else {
981     uint32_t j;
982     for (uint32_t i = 0; i < size; i += j, addr += j) {
983       if (O->is64Bit())
984         outs() << format("%016" PRIx64, addr) << "\t";
985       else
986         outs() << format("%08" PRIx64, addr) << "\t";
987       for (j = 0; j < 4 * sizeof(int32_t) && i + j < size;
988            j += sizeof(int32_t)) {
989         if (i + j + sizeof(int32_t) <= size) {
990           uint32_t long_word;
991           memcpy(&long_word, sect + i + j, sizeof(int32_t));
992           if (O->isLittleEndian() != sys::IsLittleEndianHost)
993             sys::swapByteOrder(long_word);
994           outs() << format("%08" PRIx32, long_word) << " ";
995         } else {
996           for (uint32_t k = 0; i + j + k < size; k++) {
997             uint8_t byte_word = *(sect + i + j + k);
998             outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
999           }
1000         }
1001       }
1002       outs() << "\n";
1003     }
1004   }
1005 }
1006 
1007 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
1008                              StringRef DisSegName, StringRef DisSectName);
1009 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,
1010                                 uint32_t size, uint32_t addr);
1011 #ifdef HAVE_LIBXAR
1012 static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
1013                                 uint32_t size, bool verbose,
1014                                 bool PrintXarHeader, bool PrintXarFileHeaders,
1015                                 std::string XarMemberName);
1016 #endif // defined(HAVE_LIBXAR)
1017 
1018 static void DumpSectionContents(StringRef Filename, MachOObjectFile *O,
1019                                 bool verbose) {
1020   SymbolAddressMap AddrMap;
1021   if (verbose)
1022     CreateSymbolAddressMap(O, &AddrMap);
1023 
1024   for (unsigned i = 0; i < FilterSections.size(); ++i) {
1025     StringRef DumpSection = FilterSections[i];
1026     std::pair<StringRef, StringRef> DumpSegSectName;
1027     DumpSegSectName = DumpSection.split(',');
1028     StringRef DumpSegName, DumpSectName;
1029     if (DumpSegSectName.second.size()) {
1030       DumpSegName = DumpSegSectName.first;
1031       DumpSectName = DumpSegSectName.second;
1032     } else {
1033       DumpSegName = "";
1034       DumpSectName = DumpSegSectName.first;
1035     }
1036     for (const SectionRef &Section : O->sections()) {
1037       StringRef SectName;
1038       Section.getName(SectName);
1039       DataRefImpl Ref = Section.getRawDataRefImpl();
1040       StringRef SegName = O->getSectionFinalSegmentName(Ref);
1041       if ((DumpSegName.empty() || SegName == DumpSegName) &&
1042           (SectName == DumpSectName)) {
1043 
1044         uint32_t section_flags;
1045         if (O->is64Bit()) {
1046           const MachO::section_64 Sec = O->getSection64(Ref);
1047           section_flags = Sec.flags;
1048 
1049         } else {
1050           const MachO::section Sec = O->getSection(Ref);
1051           section_flags = Sec.flags;
1052         }
1053         uint32_t section_type = section_flags & MachO::SECTION_TYPE;
1054 
1055         StringRef BytesStr;
1056         Section.getContents(BytesStr);
1057         const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1058         uint32_t sect_size = BytesStr.size();
1059         uint64_t sect_addr = Section.getAddress();
1060 
1061         outs() << "Contents of (" << SegName << "," << SectName
1062                << ") section\n";
1063 
1064         if (verbose) {
1065           if ((section_flags & MachO::S_ATTR_PURE_INSTRUCTIONS) ||
1066               (section_flags & MachO::S_ATTR_SOME_INSTRUCTIONS)) {
1067             DisassembleMachO(Filename, O, SegName, SectName);
1068             continue;
1069           }
1070           if (SegName == "__TEXT" && SectName == "__info_plist") {
1071             outs() << sect;
1072             continue;
1073           }
1074           if (SegName == "__OBJC" && SectName == "__protocol") {
1075             DumpProtocolSection(O, sect, sect_size, sect_addr);
1076             continue;
1077           }
1078 #ifdef HAVE_LIBXAR
1079           if (SegName == "__LLVM" && SectName == "__bundle") {
1080             DumpBitcodeSection(O, sect, sect_size, verbose, !NoSymbolicOperands,
1081                                ArchiveHeaders, "");
1082             continue;
1083           }
1084 #endif // defined(HAVE_LIBXAR)
1085           switch (section_type) {
1086           case MachO::S_REGULAR:
1087             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1088             break;
1089           case MachO::S_ZEROFILL:
1090             outs() << "zerofill section and has no contents in the file\n";
1091             break;
1092           case MachO::S_CSTRING_LITERALS:
1093             DumpCstringSection(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1094             break;
1095           case MachO::S_4BYTE_LITERALS:
1096             DumpLiteral4Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1097             break;
1098           case MachO::S_8BYTE_LITERALS:
1099             DumpLiteral8Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1100             break;
1101           case MachO::S_16BYTE_LITERALS:
1102             DumpLiteral16Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1103             break;
1104           case MachO::S_LITERAL_POINTERS:
1105             DumpLiteralPointerSection(O, Section, sect, sect_size, sect_addr,
1106                                       !NoLeadingAddr);
1107             break;
1108           case MachO::S_MOD_INIT_FUNC_POINTERS:
1109           case MachO::S_MOD_TERM_FUNC_POINTERS:
1110             DumpInitTermPointerSection(O, sect, sect_size, sect_addr, &AddrMap,
1111                                        verbose);
1112             break;
1113           default:
1114             outs() << "Unknown section type ("
1115                    << format("0x%08" PRIx32, section_type) << ")\n";
1116             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1117             break;
1118           }
1119         } else {
1120           if (section_type == MachO::S_ZEROFILL)
1121             outs() << "zerofill section and has no contents in the file\n";
1122           else
1123             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1124         }
1125       }
1126     }
1127   }
1128 }
1129 
1130 static void DumpInfoPlistSectionContents(StringRef Filename,
1131                                          MachOObjectFile *O) {
1132   for (const SectionRef &Section : O->sections()) {
1133     StringRef SectName;
1134     Section.getName(SectName);
1135     DataRefImpl Ref = Section.getRawDataRefImpl();
1136     StringRef SegName = O->getSectionFinalSegmentName(Ref);
1137     if (SegName == "__TEXT" && SectName == "__info_plist") {
1138       if (!NoLeadingHeaders)
1139         outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
1140       StringRef BytesStr;
1141       Section.getContents(BytesStr);
1142       const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1143       outs() << format("%.*s", BytesStr.size(), sect) << "\n";
1144       return;
1145     }
1146   }
1147 }
1148 
1149 // checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file
1150 // and if it is and there is a list of architecture flags is specified then
1151 // check to make sure this Mach-O file is one of those architectures or all
1152 // architectures were specified.  If not then an error is generated and this
1153 // routine returns false.  Else it returns true.
1154 static bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) {
1155   auto *MachO = dyn_cast<MachOObjectFile>(O);
1156 
1157   if (!MachO || ArchAll || ArchFlags.empty())
1158     return true;
1159 
1160   MachO::mach_header H;
1161   MachO::mach_header_64 H_64;
1162   Triple T;
1163   const char *McpuDefault, *ArchFlag;
1164   if (MachO->is64Bit()) {
1165     H_64 = MachO->MachOObjectFile::getHeader64();
1166     T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype,
1167                                        &McpuDefault, &ArchFlag);
1168   } else {
1169     H = MachO->MachOObjectFile::getHeader();
1170     T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype,
1171                                        &McpuDefault, &ArchFlag);
1172   }
1173   const std::string ArchFlagName(ArchFlag);
1174   if (none_of(ArchFlags, [&](const std::string &Name) {
1175         return Name == ArchFlagName;
1176       })) {
1177     errs() << "llvm-objdump: " + Filename + ": No architecture specified.\n";
1178     return false;
1179   }
1180   return true;
1181 }
1182 
1183 static void printObjcMetaData(MachOObjectFile *O, bool verbose);
1184 
1185 // ProcessMachO() is passed a single opened Mach-O file, which may be an
1186 // archive member and or in a slice of a universal file.  It prints the
1187 // the file name and header info and then processes it according to the
1188 // command line options.
1189 static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
1190                          StringRef ArchiveMemberName = StringRef(),
1191                          StringRef ArchitectureName = StringRef()) {
1192   // If we are doing some processing here on the Mach-O file print the header
1193   // info.  And don't print it otherwise like in the case of printing the
1194   // UniversalHeaders or ArchiveHeaders.
1195   if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind || SymbolTable ||
1196       LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints ||
1197       DylibsUsed || DylibId || ObjcMetaData || (FilterSections.size() != 0)) {
1198     if (!NoLeadingHeaders) {
1199       outs() << Name;
1200       if (!ArchiveMemberName.empty())
1201         outs() << '(' << ArchiveMemberName << ')';
1202       if (!ArchitectureName.empty())
1203         outs() << " (architecture " << ArchitectureName << ")";
1204       outs() << ":\n";
1205     }
1206   }
1207   // To use the report_error() form with an ArchiveName and FileName set
1208   // these up based on what is passed for Name and ArchiveMemberName.
1209   StringRef ArchiveName;
1210   StringRef FileName;
1211   if (!ArchiveMemberName.empty()) {
1212     ArchiveName = Name;
1213     FileName = ArchiveMemberName;
1214   } else {
1215     ArchiveName = StringRef();
1216     FileName = Name;
1217   }
1218 
1219   // If we need the symbol table to do the operation then check it here to
1220   // produce a good error message as to where the Mach-O file comes from in
1221   // the error message.
1222   if (Disassemble || IndirectSymbols || FilterSections.size() != 0 ||
1223       UnwindInfo)
1224     if (Error Err = MachOOF->checkSymbolTable())
1225       report_error(ArchiveName, FileName, std::move(Err), ArchitectureName);
1226 
1227   if (Disassemble) {
1228     if (MachOOF->getHeader().filetype == MachO::MH_KEXT_BUNDLE &&
1229         MachOOF->getHeader().cputype == MachO::CPU_TYPE_ARM64)
1230       DisassembleMachO(FileName, MachOOF, "__TEXT_EXEC", "__text");
1231     else
1232       DisassembleMachO(FileName, MachOOF, "__TEXT", "__text");
1233   }
1234   if (IndirectSymbols)
1235     PrintIndirectSymbols(MachOOF, !NonVerbose);
1236   if (DataInCode)
1237     PrintDataInCodeTable(MachOOF, !NonVerbose);
1238   if (LinkOptHints)
1239     PrintLinkOptHints(MachOOF);
1240   if (Relocations)
1241     PrintRelocations(MachOOF);
1242   if (SectionHeaders)
1243     PrintSectionHeaders(MachOOF);
1244   if (SectionContents)
1245     PrintSectionContents(MachOOF);
1246   if (FilterSections.size() != 0)
1247     DumpSectionContents(FileName, MachOOF, !NonVerbose);
1248   if (InfoPlist)
1249     DumpInfoPlistSectionContents(FileName, MachOOF);
1250   if (DylibsUsed)
1251     PrintDylibs(MachOOF, false);
1252   if (DylibId)
1253     PrintDylibs(MachOOF, true);
1254   if (SymbolTable)
1255     PrintSymbolTable(MachOOF, ArchiveName, ArchitectureName);
1256   if (UnwindInfo)
1257     printMachOUnwindInfo(MachOOF);
1258   if (PrivateHeaders) {
1259     printMachOFileHeader(MachOOF);
1260     printMachOLoadCommands(MachOOF);
1261   }
1262   if (FirstPrivateHeader)
1263     printMachOFileHeader(MachOOF);
1264   if (ObjcMetaData)
1265     printObjcMetaData(MachOOF, !NonVerbose);
1266   if (ExportsTrie)
1267     printExportsTrie(MachOOF);
1268   if (Rebase)
1269     printRebaseTable(MachOOF);
1270   if (Bind)
1271     printBindTable(MachOOF);
1272   if (LazyBind)
1273     printLazyBindTable(MachOOF);
1274   if (WeakBind)
1275     printWeakBindTable(MachOOF);
1276 
1277   if (DwarfDumpType != DIDT_Null) {
1278     std::unique_ptr<DIContext> DICtx = DWARFContext::create(*MachOOF);
1279     // Dump the complete DWARF structure.
1280     DIDumpOptions DumpOpts;
1281     DumpOpts.DumpType = DwarfDumpType;
1282     DumpOpts.DumpEH = true;
1283     DICtx->dump(outs(), DumpOpts);
1284   }
1285 }
1286 
1287 // printUnknownCPUType() helps print_fat_headers for unknown CPU's.
1288 static void printUnknownCPUType(uint32_t cputype, uint32_t cpusubtype) {
1289   outs() << "    cputype (" << cputype << ")\n";
1290   outs() << "    cpusubtype (" << cpusubtype << ")\n";
1291 }
1292 
1293 // printCPUType() helps print_fat_headers by printing the cputype and
1294 // pusubtype (symbolically for the one's it knows about).
1295 static void printCPUType(uint32_t cputype, uint32_t cpusubtype) {
1296   switch (cputype) {
1297   case MachO::CPU_TYPE_I386:
1298     switch (cpusubtype) {
1299     case MachO::CPU_SUBTYPE_I386_ALL:
1300       outs() << "    cputype CPU_TYPE_I386\n";
1301       outs() << "    cpusubtype CPU_SUBTYPE_I386_ALL\n";
1302       break;
1303     default:
1304       printUnknownCPUType(cputype, cpusubtype);
1305       break;
1306     }
1307     break;
1308   case MachO::CPU_TYPE_X86_64:
1309     switch (cpusubtype) {
1310     case MachO::CPU_SUBTYPE_X86_64_ALL:
1311       outs() << "    cputype CPU_TYPE_X86_64\n";
1312       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_ALL\n";
1313       break;
1314     case MachO::CPU_SUBTYPE_X86_64_H:
1315       outs() << "    cputype CPU_TYPE_X86_64\n";
1316       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_H\n";
1317       break;
1318     default:
1319       printUnknownCPUType(cputype, cpusubtype);
1320       break;
1321     }
1322     break;
1323   case MachO::CPU_TYPE_ARM:
1324     switch (cpusubtype) {
1325     case MachO::CPU_SUBTYPE_ARM_ALL:
1326       outs() << "    cputype CPU_TYPE_ARM\n";
1327       outs() << "    cpusubtype CPU_SUBTYPE_ARM_ALL\n";
1328       break;
1329     case MachO::CPU_SUBTYPE_ARM_V4T:
1330       outs() << "    cputype CPU_TYPE_ARM\n";
1331       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V4T\n";
1332       break;
1333     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1334       outs() << "    cputype CPU_TYPE_ARM\n";
1335       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n";
1336       break;
1337     case MachO::CPU_SUBTYPE_ARM_XSCALE:
1338       outs() << "    cputype CPU_TYPE_ARM\n";
1339       outs() << "    cpusubtype CPU_SUBTYPE_ARM_XSCALE\n";
1340       break;
1341     case MachO::CPU_SUBTYPE_ARM_V6:
1342       outs() << "    cputype CPU_TYPE_ARM\n";
1343       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6\n";
1344       break;
1345     case MachO::CPU_SUBTYPE_ARM_V6M:
1346       outs() << "    cputype CPU_TYPE_ARM\n";
1347       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6M\n";
1348       break;
1349     case MachO::CPU_SUBTYPE_ARM_V7:
1350       outs() << "    cputype CPU_TYPE_ARM\n";
1351       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7\n";
1352       break;
1353     case MachO::CPU_SUBTYPE_ARM_V7EM:
1354       outs() << "    cputype CPU_TYPE_ARM\n";
1355       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7EM\n";
1356       break;
1357     case MachO::CPU_SUBTYPE_ARM_V7K:
1358       outs() << "    cputype CPU_TYPE_ARM\n";
1359       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7K\n";
1360       break;
1361     case MachO::CPU_SUBTYPE_ARM_V7M:
1362       outs() << "    cputype CPU_TYPE_ARM\n";
1363       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7M\n";
1364       break;
1365     case MachO::CPU_SUBTYPE_ARM_V7S:
1366       outs() << "    cputype CPU_TYPE_ARM\n";
1367       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7S\n";
1368       break;
1369     default:
1370       printUnknownCPUType(cputype, cpusubtype);
1371       break;
1372     }
1373     break;
1374   case MachO::CPU_TYPE_ARM64:
1375     switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
1376     case MachO::CPU_SUBTYPE_ARM64_ALL:
1377       outs() << "    cputype CPU_TYPE_ARM64\n";
1378       outs() << "    cpusubtype CPU_SUBTYPE_ARM64_ALL\n";
1379       break;
1380     default:
1381       printUnknownCPUType(cputype, cpusubtype);
1382       break;
1383     }
1384     break;
1385   default:
1386     printUnknownCPUType(cputype, cpusubtype);
1387     break;
1388   }
1389 }
1390 
1391 static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB,
1392                                        bool verbose) {
1393   outs() << "Fat headers\n";
1394   if (verbose) {
1395     if (UB->getMagic() == MachO::FAT_MAGIC)
1396       outs() << "fat_magic FAT_MAGIC\n";
1397     else // UB->getMagic() == MachO::FAT_MAGIC_64
1398       outs() << "fat_magic FAT_MAGIC_64\n";
1399   } else
1400     outs() << "fat_magic " << format("0x%" PRIx32, MachO::FAT_MAGIC) << "\n";
1401 
1402   uint32_t nfat_arch = UB->getNumberOfObjects();
1403   StringRef Buf = UB->getData();
1404   uint64_t size = Buf.size();
1405   uint64_t big_size = sizeof(struct MachO::fat_header) +
1406                       nfat_arch * sizeof(struct MachO::fat_arch);
1407   outs() << "nfat_arch " << UB->getNumberOfObjects();
1408   if (nfat_arch == 0)
1409     outs() << " (malformed, contains zero architecture types)\n";
1410   else if (big_size > size)
1411     outs() << " (malformed, architectures past end of file)\n";
1412   else
1413     outs() << "\n";
1414 
1415   for (uint32_t i = 0; i < nfat_arch; ++i) {
1416     MachOUniversalBinary::ObjectForArch OFA(UB, i);
1417     uint32_t cputype = OFA.getCPUType();
1418     uint32_t cpusubtype = OFA.getCPUSubType();
1419     outs() << "architecture ";
1420     for (uint32_t j = 0; i != 0 && j <= i - 1; j++) {
1421       MachOUniversalBinary::ObjectForArch other_OFA(UB, j);
1422       uint32_t other_cputype = other_OFA.getCPUType();
1423       uint32_t other_cpusubtype = other_OFA.getCPUSubType();
1424       if (cputype != 0 && cpusubtype != 0 && cputype == other_cputype &&
1425           (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) ==
1426               (other_cpusubtype & ~MachO::CPU_SUBTYPE_MASK)) {
1427         outs() << "(illegal duplicate architecture) ";
1428         break;
1429       }
1430     }
1431     if (verbose) {
1432       outs() << OFA.getArchFlagName() << "\n";
1433       printCPUType(cputype, cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
1434     } else {
1435       outs() << i << "\n";
1436       outs() << "    cputype " << cputype << "\n";
1437       outs() << "    cpusubtype " << (cpusubtype & ~MachO::CPU_SUBTYPE_MASK)
1438              << "\n";
1439     }
1440     if (verbose &&
1441         (cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64)
1442       outs() << "    capabilities CPU_SUBTYPE_LIB64\n";
1443     else
1444       outs() << "    capabilities "
1445              << format("0x%" PRIx32,
1446                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24) << "\n";
1447     outs() << "    offset " << OFA.getOffset();
1448     if (OFA.getOffset() > size)
1449       outs() << " (past end of file)";
1450     if (OFA.getOffset() % (1 << OFA.getAlign()) != 0)
1451       outs() << " (not aligned on it's alignment (2^" << OFA.getAlign() << ")";
1452     outs() << "\n";
1453     outs() << "    size " << OFA.getSize();
1454     big_size = OFA.getOffset() + OFA.getSize();
1455     if (big_size > size)
1456       outs() << " (past end of file)";
1457     outs() << "\n";
1458     outs() << "    align 2^" << OFA.getAlign() << " (" << (1 << OFA.getAlign())
1459            << ")\n";
1460   }
1461 }
1462 
1463 static void printArchiveChild(StringRef Filename, const Archive::Child &C,
1464                               bool verbose, bool print_offset,
1465                               StringRef ArchitectureName = StringRef()) {
1466   if (print_offset)
1467     outs() << C.getChildOffset() << "\t";
1468   Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
1469   if (!ModeOrErr)
1470     report_error(Filename, C, ModeOrErr.takeError(), ArchitectureName);
1471   sys::fs::perms Mode = ModeOrErr.get();
1472   if (verbose) {
1473     // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
1474     // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
1475     outs() << "-";
1476     outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
1477     outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
1478     outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
1479     outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
1480     outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
1481     outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
1482     outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
1483     outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
1484     outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
1485   } else {
1486     outs() << format("0%o ", Mode);
1487   }
1488 
1489   Expected<unsigned> UIDOrErr = C.getUID();
1490   if (!UIDOrErr)
1491     report_error(Filename, C, UIDOrErr.takeError(), ArchitectureName);
1492   unsigned UID = UIDOrErr.get();
1493   outs() << format("%3d/", UID);
1494   Expected<unsigned> GIDOrErr = C.getGID();
1495   if (!GIDOrErr)
1496     report_error(Filename, C, GIDOrErr.takeError(), ArchitectureName);
1497   unsigned GID = GIDOrErr.get();
1498   outs() << format("%-3d ", GID);
1499   Expected<uint64_t> Size = C.getRawSize();
1500   if (!Size)
1501     report_error(Filename, C, Size.takeError(), ArchitectureName);
1502   outs() << format("%5" PRId64, Size.get()) << " ";
1503 
1504   StringRef RawLastModified = C.getRawLastModified();
1505   if (verbose) {
1506     unsigned Seconds;
1507     if (RawLastModified.getAsInteger(10, Seconds))
1508       outs() << "(date: \"" << RawLastModified
1509              << "\" contains non-decimal chars) ";
1510     else {
1511       // Since cime(3) returns a 26 character string of the form:
1512       // "Sun Sep 16 01:03:52 1973\n\0"
1513       // just print 24 characters.
1514       time_t t = Seconds;
1515       outs() << format("%.24s ", ctime(&t));
1516     }
1517   } else {
1518     outs() << RawLastModified << " ";
1519   }
1520 
1521   if (verbose) {
1522     Expected<StringRef> NameOrErr = C.getName();
1523     if (!NameOrErr) {
1524       consumeError(NameOrErr.takeError());
1525       Expected<StringRef> NameOrErr = C.getRawName();
1526       if (!NameOrErr)
1527         report_error(Filename, C, NameOrErr.takeError(), ArchitectureName);
1528       StringRef RawName = NameOrErr.get();
1529       outs() << RawName << "\n";
1530     } else {
1531       StringRef Name = NameOrErr.get();
1532       outs() << Name << "\n";
1533     }
1534   } else {
1535     Expected<StringRef> NameOrErr = C.getRawName();
1536     if (!NameOrErr)
1537       report_error(Filename, C, NameOrErr.takeError(), ArchitectureName);
1538     StringRef RawName = NameOrErr.get();
1539     outs() << RawName << "\n";
1540   }
1541 }
1542 
1543 static void printArchiveHeaders(StringRef Filename, Archive *A, bool verbose,
1544                                 bool print_offset,
1545                                 StringRef ArchitectureName = StringRef()) {
1546   Error Err = Error::success();
1547   ;
1548   for (const auto &C : A->children(Err, false))
1549     printArchiveChild(Filename, C, verbose, print_offset, ArchitectureName);
1550 
1551   if (Err)
1552     report_error(StringRef(), Filename, std::move(Err), ArchitectureName);
1553 }
1554 
1555 // ParseInputMachO() parses the named Mach-O file in Filename and handles the
1556 // -arch flags selecting just those slices as specified by them and also parses
1557 // archive files.  Then for each individual Mach-O file ProcessMachO() is
1558 // called to process the file based on the command line options.
1559 void llvm::ParseInputMachO(StringRef Filename) {
1560   // Check for -arch all and verifiy the -arch flags are valid.
1561   for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1562     if (ArchFlags[i] == "all") {
1563       ArchAll = true;
1564     } else {
1565       if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
1566         errs() << "llvm-objdump: Unknown architecture named '" + ArchFlags[i] +
1567                       "'for the -arch option\n";
1568         return;
1569       }
1570     }
1571   }
1572 
1573   // Attempt to open the binary.
1574   Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
1575   if (!BinaryOrErr) {
1576     if (auto E = isNotObjectErrorInvalidFileType(BinaryOrErr.takeError()))
1577       report_error(Filename, std::move(E));
1578     else
1579       outs() << Filename << ": is not an object file\n";
1580     return;
1581   }
1582   Binary &Bin = *BinaryOrErr.get().getBinary();
1583 
1584   if (Archive *A = dyn_cast<Archive>(&Bin)) {
1585     outs() << "Archive : " << Filename << "\n";
1586     if (ArchiveHeaders)
1587       printArchiveHeaders(Filename, A, !NonVerbose, ArchiveMemberOffsets);
1588 
1589     Error Err = Error::success();
1590     for (auto &C : A->children(Err)) {
1591       Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1592       if (!ChildOrErr) {
1593         if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1594           report_error(Filename, C, std::move(E));
1595         continue;
1596       }
1597       if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1598         if (!checkMachOAndArchFlags(O, Filename))
1599           return;
1600         ProcessMachO(Filename, O, O->getFileName());
1601       }
1602     }
1603     if (Err)
1604       report_error(Filename, std::move(Err));
1605     return;
1606   }
1607   if (UniversalHeaders) {
1608     if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin))
1609       printMachOUniversalHeaders(UB, !NonVerbose);
1610   }
1611   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
1612     // If we have a list of architecture flags specified dump only those.
1613     if (!ArchAll && ArchFlags.size() != 0) {
1614       // Look for a slice in the universal binary that matches each ArchFlag.
1615       bool ArchFound;
1616       for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1617         ArchFound = false;
1618         for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1619                                                    E = UB->end_objects();
1620              I != E; ++I) {
1621           if (ArchFlags[i] == I->getArchFlagName()) {
1622             ArchFound = true;
1623             Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
1624                 I->getAsObjectFile();
1625             std::string ArchitectureName = "";
1626             if (ArchFlags.size() > 1)
1627               ArchitectureName = I->getArchFlagName();
1628             if (ObjOrErr) {
1629               ObjectFile &O = *ObjOrErr.get();
1630               if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1631                 ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1632             } else if (auto E = isNotObjectErrorInvalidFileType(
1633                        ObjOrErr.takeError())) {
1634               report_error(Filename, StringRef(), std::move(E),
1635                            ArchitectureName);
1636               continue;
1637             } else if (Expected<std::unique_ptr<Archive>> AOrErr =
1638                            I->getAsArchive()) {
1639               std::unique_ptr<Archive> &A = *AOrErr;
1640               outs() << "Archive : " << Filename;
1641               if (!ArchitectureName.empty())
1642                 outs() << " (architecture " << ArchitectureName << ")";
1643               outs() << "\n";
1644               if (ArchiveHeaders)
1645                 printArchiveHeaders(Filename, A.get(), !NonVerbose,
1646                                     ArchiveMemberOffsets, ArchitectureName);
1647               Error Err = Error::success();
1648               for (auto &C : A->children(Err)) {
1649                 Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1650                 if (!ChildOrErr) {
1651                   if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1652                     report_error(Filename, C, std::move(E), ArchitectureName);
1653                   continue;
1654                 }
1655                 if (MachOObjectFile *O =
1656                         dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1657                   ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
1658               }
1659               if (Err)
1660                 report_error(Filename, std::move(Err));
1661             } else {
1662               consumeError(AOrErr.takeError());
1663               error("Mach-O universal file: " + Filename + " for " +
1664                     "architecture " + StringRef(I->getArchFlagName()) +
1665                     " is not a Mach-O file or an archive file");
1666             }
1667           }
1668         }
1669         if (!ArchFound) {
1670           errs() << "llvm-objdump: file: " + Filename + " does not contain "
1671                  << "architecture: " + ArchFlags[i] + "\n";
1672           return;
1673         }
1674       }
1675       return;
1676     }
1677     // No architecture flags were specified so if this contains a slice that
1678     // matches the host architecture dump only that.
1679     if (!ArchAll) {
1680       for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1681                                                  E = UB->end_objects();
1682            I != E; ++I) {
1683         if (MachOObjectFile::getHostArch().getArchName() ==
1684             I->getArchFlagName()) {
1685           Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1686           std::string ArchiveName;
1687           ArchiveName.clear();
1688           if (ObjOrErr) {
1689             ObjectFile &O = *ObjOrErr.get();
1690             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1691               ProcessMachO(Filename, MachOOF);
1692           } else if (auto E = isNotObjectErrorInvalidFileType(
1693                      ObjOrErr.takeError())) {
1694             report_error(Filename, std::move(E));
1695             continue;
1696           } else if (Expected<std::unique_ptr<Archive>> AOrErr =
1697                          I->getAsArchive()) {
1698             std::unique_ptr<Archive> &A = *AOrErr;
1699             outs() << "Archive : " << Filename << "\n";
1700             if (ArchiveHeaders)
1701               printArchiveHeaders(Filename, A.get(), !NonVerbose,
1702                                   ArchiveMemberOffsets);
1703             Error Err = Error::success();
1704             for (auto &C : A->children(Err)) {
1705               Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1706               if (!ChildOrErr) {
1707                 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1708                   report_error(Filename, C, std::move(E));
1709                 continue;
1710               }
1711               if (MachOObjectFile *O =
1712                       dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1713                 ProcessMachO(Filename, O, O->getFileName());
1714             }
1715             if (Err)
1716               report_error(Filename, std::move(Err));
1717           } else {
1718             consumeError(AOrErr.takeError());
1719             error("Mach-O universal file: " + Filename + " for architecture " +
1720                   StringRef(I->getArchFlagName()) +
1721                   " is not a Mach-O file or an archive file");
1722           }
1723           return;
1724         }
1725       }
1726     }
1727     // Either all architectures have been specified or none have been specified
1728     // and this does not contain the host architecture so dump all the slices.
1729     bool moreThanOneArch = UB->getNumberOfObjects() > 1;
1730     for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1731                                                E = UB->end_objects();
1732          I != E; ++I) {
1733       Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1734       std::string ArchitectureName = "";
1735       if (moreThanOneArch)
1736         ArchitectureName = I->getArchFlagName();
1737       if (ObjOrErr) {
1738         ObjectFile &Obj = *ObjOrErr.get();
1739         if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
1740           ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1741       } else if (auto E = isNotObjectErrorInvalidFileType(
1742                  ObjOrErr.takeError())) {
1743         report_error(StringRef(), Filename, std::move(E), ArchitectureName);
1744         continue;
1745       } else if (Expected<std::unique_ptr<Archive>> AOrErr =
1746                    I->getAsArchive()) {
1747         std::unique_ptr<Archive> &A = *AOrErr;
1748         outs() << "Archive : " << Filename;
1749         if (!ArchitectureName.empty())
1750           outs() << " (architecture " << ArchitectureName << ")";
1751         outs() << "\n";
1752         if (ArchiveHeaders)
1753           printArchiveHeaders(Filename, A.get(), !NonVerbose,
1754                               ArchiveMemberOffsets, ArchitectureName);
1755         Error Err = Error::success();
1756         for (auto &C : A->children(Err)) {
1757           Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1758           if (!ChildOrErr) {
1759             if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1760               report_error(Filename, C, std::move(E), ArchitectureName);
1761             continue;
1762           }
1763           if (MachOObjectFile *O =
1764                   dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1765             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
1766               ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
1767                            ArchitectureName);
1768           }
1769         }
1770         if (Err)
1771           report_error(Filename, std::move(Err));
1772       } else {
1773         consumeError(AOrErr.takeError());
1774         error("Mach-O universal file: " + Filename + " for architecture " +
1775               StringRef(I->getArchFlagName()) +
1776               " is not a Mach-O file or an archive file");
1777       }
1778     }
1779     return;
1780   }
1781   if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
1782     if (!checkMachOAndArchFlags(O, Filename))
1783       return;
1784     if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
1785       ProcessMachO(Filename, MachOOF);
1786     } else
1787       errs() << "llvm-objdump: '" << Filename << "': "
1788              << "Object is not a Mach-O file type.\n";
1789     return;
1790   }
1791   llvm_unreachable("Input object can't be invalid at this point");
1792 }
1793 
1794 // The block of info used by the Symbolizer call backs.
1795 struct DisassembleInfo {
1796   bool verbose;
1797   MachOObjectFile *O;
1798   SectionRef S;
1799   SymbolAddressMap *AddrMap;
1800   std::vector<SectionRef> *Sections;
1801   const char *class_name;
1802   const char *selector_name;
1803   char *method;
1804   char *demangled_name;
1805   uint64_t adrp_addr;
1806   uint32_t adrp_inst;
1807   std::unique_ptr<SymbolAddressMap> bindtable;
1808   uint32_t depth;
1809 };
1810 
1811 // SymbolizerGetOpInfo() is the operand information call back function.
1812 // This is called to get the symbolic information for operand(s) of an
1813 // instruction when it is being done.  This routine does this from
1814 // the relocation information, symbol table, etc. That block of information
1815 // is a pointer to the struct DisassembleInfo that was passed when the
1816 // disassembler context was created and passed to back to here when
1817 // called back by the disassembler for instruction operands that could have
1818 // relocation information. The address of the instruction containing operand is
1819 // at the Pc parameter.  The immediate value the operand has is passed in
1820 // op_info->Value and is at Offset past the start of the instruction and has a
1821 // byte Size of 1, 2 or 4. The symbolc information is returned in TagBuf is the
1822 // LLVMOpInfo1 struct defined in the header "llvm-c/Disassembler.h" as symbol
1823 // names and addends of the symbolic expression to add for the operand.  The
1824 // value of TagType is currently 1 (for the LLVMOpInfo1 struct). If symbolic
1825 // information is returned then this function returns 1 else it returns 0.
1826 static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
1827                                uint64_t Size, int TagType, void *TagBuf) {
1828   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
1829   struct LLVMOpInfo1 *op_info = (struct LLVMOpInfo1 *)TagBuf;
1830   uint64_t value = op_info->Value;
1831 
1832   // Make sure all fields returned are zero if we don't set them.
1833   memset((void *)op_info, '\0', sizeof(struct LLVMOpInfo1));
1834   op_info->Value = value;
1835 
1836   // If the TagType is not the value 1 which it code knows about or if no
1837   // verbose symbolic information is wanted then just return 0, indicating no
1838   // information is being returned.
1839   if (TagType != 1 || !info->verbose)
1840     return 0;
1841 
1842   unsigned int Arch = info->O->getArch();
1843   if (Arch == Triple::x86) {
1844     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
1845       return 0;
1846     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
1847       // TODO:
1848       // Search the external relocation entries of a fully linked image
1849       // (if any) for an entry that matches this segment offset.
1850       // uint32_t seg_offset = (Pc + Offset);
1851       return 0;
1852     }
1853     // In MH_OBJECT filetypes search the section's relocation entries (if any)
1854     // for an entry for this section offset.
1855     uint32_t sect_addr = info->S.getAddress();
1856     uint32_t sect_offset = (Pc + Offset) - sect_addr;
1857     bool reloc_found = false;
1858     DataRefImpl Rel;
1859     MachO::any_relocation_info RE;
1860     bool isExtern = false;
1861     SymbolRef Symbol;
1862     bool r_scattered = false;
1863     uint32_t r_value, pair_r_value, r_type;
1864     for (const RelocationRef &Reloc : info->S.relocations()) {
1865       uint64_t RelocOffset = Reloc.getOffset();
1866       if (RelocOffset == sect_offset) {
1867         Rel = Reloc.getRawDataRefImpl();
1868         RE = info->O->getRelocation(Rel);
1869         r_type = info->O->getAnyRelocationType(RE);
1870         r_scattered = info->O->isRelocationScattered(RE);
1871         if (r_scattered) {
1872           r_value = info->O->getScatteredRelocationValue(RE);
1873           if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
1874               r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
1875             DataRefImpl RelNext = Rel;
1876             info->O->moveRelocationNext(RelNext);
1877             MachO::any_relocation_info RENext;
1878             RENext = info->O->getRelocation(RelNext);
1879             if (info->O->isRelocationScattered(RENext))
1880               pair_r_value = info->O->getScatteredRelocationValue(RENext);
1881             else
1882               return 0;
1883           }
1884         } else {
1885           isExtern = info->O->getPlainRelocationExternal(RE);
1886           if (isExtern) {
1887             symbol_iterator RelocSym = Reloc.getSymbol();
1888             Symbol = *RelocSym;
1889           }
1890         }
1891         reloc_found = true;
1892         break;
1893       }
1894     }
1895     if (reloc_found && isExtern) {
1896       Expected<StringRef> SymName = Symbol.getName();
1897       if (!SymName)
1898         report_error(info->O->getFileName(), SymName.takeError());
1899       const char *name = SymName->data();
1900       op_info->AddSymbol.Present = 1;
1901       op_info->AddSymbol.Name = name;
1902       // For i386 extern relocation entries the value in the instruction is
1903       // the offset from the symbol, and value is already set in op_info->Value.
1904       return 1;
1905     }
1906     if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
1907                         r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
1908       const char *add = GuessSymbolName(r_value, info->AddrMap);
1909       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
1910       uint32_t offset = value - (r_value - pair_r_value);
1911       op_info->AddSymbol.Present = 1;
1912       if (add != nullptr)
1913         op_info->AddSymbol.Name = add;
1914       else
1915         op_info->AddSymbol.Value = r_value;
1916       op_info->SubtractSymbol.Present = 1;
1917       if (sub != nullptr)
1918         op_info->SubtractSymbol.Name = sub;
1919       else
1920         op_info->SubtractSymbol.Value = pair_r_value;
1921       op_info->Value = offset;
1922       return 1;
1923     }
1924     return 0;
1925   }
1926   if (Arch == Triple::x86_64) {
1927     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
1928       return 0;
1929     // For non MH_OBJECT types, like MH_KEXT_BUNDLE, Search the external
1930     // relocation entries of a linked image (if any) for an entry that matches
1931     // this segment offset.
1932     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
1933       uint64_t seg_offset = Pc + Offset;
1934       bool reloc_found = false;
1935       DataRefImpl Rel;
1936       MachO::any_relocation_info RE;
1937       bool isExtern = false;
1938       SymbolRef Symbol;
1939       for (const RelocationRef &Reloc : info->O->external_relocations()) {
1940         uint64_t RelocOffset = Reloc.getOffset();
1941         if (RelocOffset == seg_offset) {
1942           Rel = Reloc.getRawDataRefImpl();
1943           RE = info->O->getRelocation(Rel);
1944           // external relocation entries should always be external.
1945           isExtern = info->O->getPlainRelocationExternal(RE);
1946           if (isExtern) {
1947             symbol_iterator RelocSym = Reloc.getSymbol();
1948             Symbol = *RelocSym;
1949           }
1950           reloc_found = true;
1951           break;
1952         }
1953       }
1954       if (reloc_found && isExtern) {
1955         // The Value passed in will be adjusted by the Pc if the instruction
1956         // adds the Pc.  But for x86_64 external relocation entries the Value
1957         // is the offset from the external symbol.
1958         if (info->O->getAnyRelocationPCRel(RE))
1959           op_info->Value -= Pc + Offset + Size;
1960         Expected<StringRef> SymName = Symbol.getName();
1961         if (!SymName)
1962           report_error(info->O->getFileName(), SymName.takeError());
1963         const char *name = SymName->data();
1964         op_info->AddSymbol.Present = 1;
1965         op_info->AddSymbol.Name = name;
1966         return 1;
1967       }
1968       return 0;
1969     }
1970     // In MH_OBJECT filetypes search the section's relocation entries (if any)
1971     // for an entry for this section offset.
1972     uint64_t sect_addr = info->S.getAddress();
1973     uint64_t sect_offset = (Pc + Offset) - sect_addr;
1974     bool reloc_found = false;
1975     DataRefImpl Rel;
1976     MachO::any_relocation_info RE;
1977     bool isExtern = false;
1978     SymbolRef Symbol;
1979     for (const RelocationRef &Reloc : info->S.relocations()) {
1980       uint64_t RelocOffset = Reloc.getOffset();
1981       if (RelocOffset == sect_offset) {
1982         Rel = Reloc.getRawDataRefImpl();
1983         RE = info->O->getRelocation(Rel);
1984         // NOTE: Scattered relocations don't exist on x86_64.
1985         isExtern = info->O->getPlainRelocationExternal(RE);
1986         if (isExtern) {
1987           symbol_iterator RelocSym = Reloc.getSymbol();
1988           Symbol = *RelocSym;
1989         }
1990         reloc_found = true;
1991         break;
1992       }
1993     }
1994     if (reloc_found && isExtern) {
1995       // The Value passed in will be adjusted by the Pc if the instruction
1996       // adds the Pc.  But for x86_64 external relocation entries the Value
1997       // is the offset from the external symbol.
1998       if (info->O->getAnyRelocationPCRel(RE))
1999         op_info->Value -= Pc + Offset + Size;
2000       Expected<StringRef> SymName = Symbol.getName();
2001       if (!SymName)
2002         report_error(info->O->getFileName(), SymName.takeError());
2003       const char *name = SymName->data();
2004       unsigned Type = info->O->getAnyRelocationType(RE);
2005       if (Type == MachO::X86_64_RELOC_SUBTRACTOR) {
2006         DataRefImpl RelNext = Rel;
2007         info->O->moveRelocationNext(RelNext);
2008         MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
2009         unsigned TypeNext = info->O->getAnyRelocationType(RENext);
2010         bool isExternNext = info->O->getPlainRelocationExternal(RENext);
2011         unsigned SymbolNum = info->O->getPlainRelocationSymbolNum(RENext);
2012         if (TypeNext == MachO::X86_64_RELOC_UNSIGNED && isExternNext) {
2013           op_info->SubtractSymbol.Present = 1;
2014           op_info->SubtractSymbol.Name = name;
2015           symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum);
2016           Symbol = *RelocSymNext;
2017           Expected<StringRef> SymNameNext = Symbol.getName();
2018           if (!SymNameNext)
2019             report_error(info->O->getFileName(), SymNameNext.takeError());
2020           name = SymNameNext->data();
2021         }
2022       }
2023       // TODO: add the VariantKinds to op_info->VariantKind for relocation types
2024       // like: X86_64_RELOC_TLV, X86_64_RELOC_GOT_LOAD and X86_64_RELOC_GOT.
2025       op_info->AddSymbol.Present = 1;
2026       op_info->AddSymbol.Name = name;
2027       return 1;
2028     }
2029     return 0;
2030   }
2031   if (Arch == Triple::arm) {
2032     if (Offset != 0 || (Size != 4 && Size != 2))
2033       return 0;
2034     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2035       // TODO:
2036       // Search the external relocation entries of a fully linked image
2037       // (if any) for an entry that matches this segment offset.
2038       // uint32_t seg_offset = (Pc + Offset);
2039       return 0;
2040     }
2041     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2042     // for an entry for this section offset.
2043     uint32_t sect_addr = info->S.getAddress();
2044     uint32_t sect_offset = (Pc + Offset) - sect_addr;
2045     DataRefImpl Rel;
2046     MachO::any_relocation_info RE;
2047     bool isExtern = false;
2048     SymbolRef Symbol;
2049     bool r_scattered = false;
2050     uint32_t r_value, pair_r_value, r_type, r_length, other_half;
2051     auto Reloc =
2052         find_if(info->S.relocations(), [&](const RelocationRef &Reloc) {
2053           uint64_t RelocOffset = Reloc.getOffset();
2054           return RelocOffset == sect_offset;
2055         });
2056 
2057     if (Reloc == info->S.relocations().end())
2058       return 0;
2059 
2060     Rel = Reloc->getRawDataRefImpl();
2061     RE = info->O->getRelocation(Rel);
2062     r_length = info->O->getAnyRelocationLength(RE);
2063     r_scattered = info->O->isRelocationScattered(RE);
2064     if (r_scattered) {
2065       r_value = info->O->getScatteredRelocationValue(RE);
2066       r_type = info->O->getScatteredRelocationType(RE);
2067     } else {
2068       r_type = info->O->getAnyRelocationType(RE);
2069       isExtern = info->O->getPlainRelocationExternal(RE);
2070       if (isExtern) {
2071         symbol_iterator RelocSym = Reloc->getSymbol();
2072         Symbol = *RelocSym;
2073       }
2074     }
2075     if (r_type == MachO::ARM_RELOC_HALF ||
2076         r_type == MachO::ARM_RELOC_SECTDIFF ||
2077         r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
2078         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2079       DataRefImpl RelNext = Rel;
2080       info->O->moveRelocationNext(RelNext);
2081       MachO::any_relocation_info RENext;
2082       RENext = info->O->getRelocation(RelNext);
2083       other_half = info->O->getAnyRelocationAddress(RENext) & 0xffff;
2084       if (info->O->isRelocationScattered(RENext))
2085         pair_r_value = info->O->getScatteredRelocationValue(RENext);
2086     }
2087 
2088     if (isExtern) {
2089       Expected<StringRef> SymName = Symbol.getName();
2090       if (!SymName)
2091         report_error(info->O->getFileName(), SymName.takeError());
2092       const char *name = SymName->data();
2093       op_info->AddSymbol.Present = 1;
2094       op_info->AddSymbol.Name = name;
2095       switch (r_type) {
2096       case MachO::ARM_RELOC_HALF:
2097         if ((r_length & 0x1) == 1) {
2098           op_info->Value = value << 16 | other_half;
2099           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2100         } else {
2101           op_info->Value = other_half << 16 | value;
2102           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2103         }
2104         break;
2105       default:
2106         break;
2107       }
2108       return 1;
2109     }
2110     // If we have a branch that is not an external relocation entry then
2111     // return 0 so the code in tryAddingSymbolicOperand() can use the
2112     // SymbolLookUp call back with the branch target address to look up the
2113     // symbol and possibility add an annotation for a symbol stub.
2114     if (isExtern == 0 && (r_type == MachO::ARM_RELOC_BR24 ||
2115                           r_type == MachO::ARM_THUMB_RELOC_BR22))
2116       return 0;
2117 
2118     uint32_t offset = 0;
2119     if (r_type == MachO::ARM_RELOC_HALF ||
2120         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2121       if ((r_length & 0x1) == 1)
2122         value = value << 16 | other_half;
2123       else
2124         value = other_half << 16 | value;
2125     }
2126     if (r_scattered && (r_type != MachO::ARM_RELOC_HALF &&
2127                         r_type != MachO::ARM_RELOC_HALF_SECTDIFF)) {
2128       offset = value - r_value;
2129       value = r_value;
2130     }
2131 
2132     if (r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2133       if ((r_length & 0x1) == 1)
2134         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2135       else
2136         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2137       const char *add = GuessSymbolName(r_value, info->AddrMap);
2138       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
2139       int32_t offset = value - (r_value - pair_r_value);
2140       op_info->AddSymbol.Present = 1;
2141       if (add != nullptr)
2142         op_info->AddSymbol.Name = add;
2143       else
2144         op_info->AddSymbol.Value = r_value;
2145       op_info->SubtractSymbol.Present = 1;
2146       if (sub != nullptr)
2147         op_info->SubtractSymbol.Name = sub;
2148       else
2149         op_info->SubtractSymbol.Value = pair_r_value;
2150       op_info->Value = offset;
2151       return 1;
2152     }
2153 
2154     op_info->AddSymbol.Present = 1;
2155     op_info->Value = offset;
2156     if (r_type == MachO::ARM_RELOC_HALF) {
2157       if ((r_length & 0x1) == 1)
2158         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2159       else
2160         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2161     }
2162     const char *add = GuessSymbolName(value, info->AddrMap);
2163     if (add != nullptr) {
2164       op_info->AddSymbol.Name = add;
2165       return 1;
2166     }
2167     op_info->AddSymbol.Value = value;
2168     return 1;
2169   }
2170   if (Arch == Triple::aarch64) {
2171     if (Offset != 0 || Size != 4)
2172       return 0;
2173     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2174       // TODO:
2175       // Search the external relocation entries of a fully linked image
2176       // (if any) for an entry that matches this segment offset.
2177       // uint64_t seg_offset = (Pc + Offset);
2178       return 0;
2179     }
2180     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2181     // for an entry for this section offset.
2182     uint64_t sect_addr = info->S.getAddress();
2183     uint64_t sect_offset = (Pc + Offset) - sect_addr;
2184     auto Reloc =
2185         find_if(info->S.relocations(), [&](const RelocationRef &Reloc) {
2186           uint64_t RelocOffset = Reloc.getOffset();
2187           return RelocOffset == sect_offset;
2188         });
2189 
2190     if (Reloc == info->S.relocations().end())
2191       return 0;
2192 
2193     DataRefImpl Rel = Reloc->getRawDataRefImpl();
2194     MachO::any_relocation_info RE = info->O->getRelocation(Rel);
2195     uint32_t r_type = info->O->getAnyRelocationType(RE);
2196     if (r_type == MachO::ARM64_RELOC_ADDEND) {
2197       DataRefImpl RelNext = Rel;
2198       info->O->moveRelocationNext(RelNext);
2199       MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
2200       if (value == 0) {
2201         value = info->O->getPlainRelocationSymbolNum(RENext);
2202         op_info->Value = value;
2203       }
2204     }
2205     // NOTE: Scattered relocations don't exist on arm64.
2206     if (!info->O->getPlainRelocationExternal(RE))
2207       return 0;
2208     Expected<StringRef> SymName = Reloc->getSymbol()->getName();
2209     if (!SymName)
2210       report_error(info->O->getFileName(), SymName.takeError());
2211     const char *name = SymName->data();
2212     op_info->AddSymbol.Present = 1;
2213     op_info->AddSymbol.Name = name;
2214 
2215     switch (r_type) {
2216     case MachO::ARM64_RELOC_PAGE21:
2217       /* @page */
2218       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGE;
2219       break;
2220     case MachO::ARM64_RELOC_PAGEOFF12:
2221       /* @pageoff */
2222       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGEOFF;
2223       break;
2224     case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
2225       /* @gotpage */
2226       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGE;
2227       break;
2228     case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
2229       /* @gotpageoff */
2230       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF;
2231       break;
2232     case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
2233       /* @tvlppage is not implemented in llvm-mc */
2234       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVP;
2235       break;
2236     case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
2237       /* @tvlppageoff is not implemented in llvm-mc */
2238       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVOFF;
2239       break;
2240     default:
2241     case MachO::ARM64_RELOC_BRANCH26:
2242       op_info->VariantKind = LLVMDisassembler_VariantKind_None;
2243       break;
2244     }
2245     return 1;
2246   }
2247   return 0;
2248 }
2249 
2250 // GuessCstringPointer is passed the address of what might be a pointer to a
2251 // literal string in a cstring section.  If that address is in a cstring section
2252 // it returns a pointer to that string.  Else it returns nullptr.
2253 static const char *GuessCstringPointer(uint64_t ReferenceValue,
2254                                        struct DisassembleInfo *info) {
2255   for (const auto &Load : info->O->load_commands()) {
2256     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2257       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2258       for (unsigned J = 0; J < Seg.nsects; ++J) {
2259         MachO::section_64 Sec = info->O->getSection64(Load, J);
2260         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2261         if (section_type == MachO::S_CSTRING_LITERALS &&
2262             ReferenceValue >= Sec.addr &&
2263             ReferenceValue < Sec.addr + Sec.size) {
2264           uint64_t sect_offset = ReferenceValue - Sec.addr;
2265           uint64_t object_offset = Sec.offset + sect_offset;
2266           StringRef MachOContents = info->O->getData();
2267           uint64_t object_size = MachOContents.size();
2268           const char *object_addr = (const char *)MachOContents.data();
2269           if (object_offset < object_size) {
2270             const char *name = object_addr + object_offset;
2271             return name;
2272           } else {
2273             return nullptr;
2274           }
2275         }
2276       }
2277     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
2278       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
2279       for (unsigned J = 0; J < Seg.nsects; ++J) {
2280         MachO::section Sec = info->O->getSection(Load, J);
2281         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2282         if (section_type == MachO::S_CSTRING_LITERALS &&
2283             ReferenceValue >= Sec.addr &&
2284             ReferenceValue < Sec.addr + Sec.size) {
2285           uint64_t sect_offset = ReferenceValue - Sec.addr;
2286           uint64_t object_offset = Sec.offset + sect_offset;
2287           StringRef MachOContents = info->O->getData();
2288           uint64_t object_size = MachOContents.size();
2289           const char *object_addr = (const char *)MachOContents.data();
2290           if (object_offset < object_size) {
2291             const char *name = object_addr + object_offset;
2292             return name;
2293           } else {
2294             return nullptr;
2295           }
2296         }
2297       }
2298     }
2299   }
2300   return nullptr;
2301 }
2302 
2303 // GuessIndirectSymbol returns the name of the indirect symbol for the
2304 // ReferenceValue passed in or nullptr.  This is used when ReferenceValue maybe
2305 // an address of a symbol stub or a lazy or non-lazy pointer to associate the
2306 // symbol name being referenced by the stub or pointer.
2307 static const char *GuessIndirectSymbol(uint64_t ReferenceValue,
2308                                        struct DisassembleInfo *info) {
2309   MachO::dysymtab_command Dysymtab = info->O->getDysymtabLoadCommand();
2310   MachO::symtab_command Symtab = info->O->getSymtabLoadCommand();
2311   for (const auto &Load : info->O->load_commands()) {
2312     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2313       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2314       for (unsigned J = 0; J < Seg.nsects; ++J) {
2315         MachO::section_64 Sec = info->O->getSection64(Load, J);
2316         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2317         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
2318              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
2319              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
2320              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
2321              section_type == MachO::S_SYMBOL_STUBS) &&
2322             ReferenceValue >= Sec.addr &&
2323             ReferenceValue < Sec.addr + Sec.size) {
2324           uint32_t stride;
2325           if (section_type == MachO::S_SYMBOL_STUBS)
2326             stride = Sec.reserved2;
2327           else
2328             stride = 8;
2329           if (stride == 0)
2330             return nullptr;
2331           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
2332           if (index < Dysymtab.nindirectsyms) {
2333             uint32_t indirect_symbol =
2334                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
2335             if (indirect_symbol < Symtab.nsyms) {
2336               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
2337               SymbolRef Symbol = *Sym;
2338               Expected<StringRef> SymName = Symbol.getName();
2339               if (!SymName)
2340                 report_error(info->O->getFileName(), SymName.takeError());
2341               const char *name = SymName->data();
2342               return name;
2343             }
2344           }
2345         }
2346       }
2347     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
2348       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
2349       for (unsigned J = 0; J < Seg.nsects; ++J) {
2350         MachO::section Sec = info->O->getSection(Load, J);
2351         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2352         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
2353              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
2354              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
2355              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
2356              section_type == MachO::S_SYMBOL_STUBS) &&
2357             ReferenceValue >= Sec.addr &&
2358             ReferenceValue < Sec.addr + Sec.size) {
2359           uint32_t stride;
2360           if (section_type == MachO::S_SYMBOL_STUBS)
2361             stride = Sec.reserved2;
2362           else
2363             stride = 4;
2364           if (stride == 0)
2365             return nullptr;
2366           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
2367           if (index < Dysymtab.nindirectsyms) {
2368             uint32_t indirect_symbol =
2369                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
2370             if (indirect_symbol < Symtab.nsyms) {
2371               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
2372               SymbolRef Symbol = *Sym;
2373               Expected<StringRef> SymName = Symbol.getName();
2374               if (!SymName)
2375                 report_error(info->O->getFileName(), SymName.takeError());
2376               const char *name = SymName->data();
2377               return name;
2378             }
2379           }
2380         }
2381       }
2382     }
2383   }
2384   return nullptr;
2385 }
2386 
2387 // method_reference() is called passing it the ReferenceName that might be
2388 // a reference it to an Objective-C method call.  If so then it allocates and
2389 // assembles a method call string with the values last seen and saved in
2390 // the DisassembleInfo's class_name and selector_name fields.  This is saved
2391 // into the method field of the info and any previous string is free'ed.
2392 // Then the class_name field in the info is set to nullptr.  The method call
2393 // string is set into ReferenceName and ReferenceType is set to
2394 // LLVMDisassembler_ReferenceType_Out_Objc_Message.  If this not a method call
2395 // then both ReferenceType and ReferenceName are left unchanged.
2396 static void method_reference(struct DisassembleInfo *info,
2397                              uint64_t *ReferenceType,
2398                              const char **ReferenceName) {
2399   unsigned int Arch = info->O->getArch();
2400   if (*ReferenceName != nullptr) {
2401     if (strcmp(*ReferenceName, "_objc_msgSend") == 0) {
2402       if (info->selector_name != nullptr) {
2403         if (info->method != nullptr)
2404           free(info->method);
2405         if (info->class_name != nullptr) {
2406           info->method = (char *)malloc(5 + strlen(info->class_name) +
2407                                         strlen(info->selector_name));
2408           if (info->method != nullptr) {
2409             strcpy(info->method, "+[");
2410             strcat(info->method, info->class_name);
2411             strcat(info->method, " ");
2412             strcat(info->method, info->selector_name);
2413             strcat(info->method, "]");
2414             *ReferenceName = info->method;
2415             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2416           }
2417         } else {
2418           info->method = (char *)malloc(9 + strlen(info->selector_name));
2419           if (info->method != nullptr) {
2420             if (Arch == Triple::x86_64)
2421               strcpy(info->method, "-[%rdi ");
2422             else if (Arch == Triple::aarch64)
2423               strcpy(info->method, "-[x0 ");
2424             else
2425               strcpy(info->method, "-[r? ");
2426             strcat(info->method, info->selector_name);
2427             strcat(info->method, "]");
2428             *ReferenceName = info->method;
2429             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2430           }
2431         }
2432         info->class_name = nullptr;
2433       }
2434     } else if (strcmp(*ReferenceName, "_objc_msgSendSuper2") == 0) {
2435       if (info->selector_name != nullptr) {
2436         if (info->method != nullptr)
2437           free(info->method);
2438         info->method = (char *)malloc(17 + strlen(info->selector_name));
2439         if (info->method != nullptr) {
2440           if (Arch == Triple::x86_64)
2441             strcpy(info->method, "-[[%rdi super] ");
2442           else if (Arch == Triple::aarch64)
2443             strcpy(info->method, "-[[x0 super] ");
2444           else
2445             strcpy(info->method, "-[[r? super] ");
2446           strcat(info->method, info->selector_name);
2447           strcat(info->method, "]");
2448           *ReferenceName = info->method;
2449           *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2450         }
2451         info->class_name = nullptr;
2452       }
2453     }
2454   }
2455 }
2456 
2457 // GuessPointerPointer() is passed the address of what might be a pointer to
2458 // a reference to an Objective-C class, selector, message ref or cfstring.
2459 // If so the value of the pointer is returned and one of the booleans are set
2460 // to true.  If not zero is returned and all the booleans are set to false.
2461 static uint64_t GuessPointerPointer(uint64_t ReferenceValue,
2462                                     struct DisassembleInfo *info,
2463                                     bool &classref, bool &selref, bool &msgref,
2464                                     bool &cfstring) {
2465   classref = false;
2466   selref = false;
2467   msgref = false;
2468   cfstring = false;
2469   for (const auto &Load : info->O->load_commands()) {
2470     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2471       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2472       for (unsigned J = 0; J < Seg.nsects; ++J) {
2473         MachO::section_64 Sec = info->O->getSection64(Load, J);
2474         if ((strncmp(Sec.sectname, "__objc_selrefs", 16) == 0 ||
2475              strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
2476              strncmp(Sec.sectname, "__objc_superrefs", 16) == 0 ||
2477              strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 ||
2478              strncmp(Sec.sectname, "__cfstring", 16) == 0) &&
2479             ReferenceValue >= Sec.addr &&
2480             ReferenceValue < Sec.addr + Sec.size) {
2481           uint64_t sect_offset = ReferenceValue - Sec.addr;
2482           uint64_t object_offset = Sec.offset + sect_offset;
2483           StringRef MachOContents = info->O->getData();
2484           uint64_t object_size = MachOContents.size();
2485           const char *object_addr = (const char *)MachOContents.data();
2486           if (object_offset < object_size) {
2487             uint64_t pointer_value;
2488             memcpy(&pointer_value, object_addr + object_offset,
2489                    sizeof(uint64_t));
2490             if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2491               sys::swapByteOrder(pointer_value);
2492             if (strncmp(Sec.sectname, "__objc_selrefs", 16) == 0)
2493               selref = true;
2494             else if (strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
2495                      strncmp(Sec.sectname, "__objc_superrefs", 16) == 0)
2496               classref = true;
2497             else if (strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 &&
2498                      ReferenceValue + 8 < Sec.addr + Sec.size) {
2499               msgref = true;
2500               memcpy(&pointer_value, object_addr + object_offset + 8,
2501                      sizeof(uint64_t));
2502               if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2503                 sys::swapByteOrder(pointer_value);
2504             } else if (strncmp(Sec.sectname, "__cfstring", 16) == 0)
2505               cfstring = true;
2506             return pointer_value;
2507           } else {
2508             return 0;
2509           }
2510         }
2511       }
2512     }
2513     // TODO: Look for LC_SEGMENT for 32-bit Mach-O files.
2514   }
2515   return 0;
2516 }
2517 
2518 // get_pointer_64 returns a pointer to the bytes in the object file at the
2519 // Address from a section in the Mach-O file.  And indirectly returns the
2520 // offset into the section, number of bytes left in the section past the offset
2521 // and which section is was being referenced.  If the Address is not in a
2522 // section nullptr is returned.
2523 static const char *get_pointer_64(uint64_t Address, uint32_t &offset,
2524                                   uint32_t &left, SectionRef &S,
2525                                   DisassembleInfo *info,
2526                                   bool objc_only = false) {
2527   offset = 0;
2528   left = 0;
2529   S = SectionRef();
2530   for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) {
2531     uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress();
2532     uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize();
2533     if (SectSize == 0)
2534       continue;
2535     if (objc_only) {
2536       StringRef SectName;
2537       ((*(info->Sections))[SectIdx]).getName(SectName);
2538       DataRefImpl Ref = ((*(info->Sections))[SectIdx]).getRawDataRefImpl();
2539       StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
2540       if (SegName != "__OBJC" && SectName != "__cstring")
2541         continue;
2542     }
2543     if (Address >= SectAddress && Address < SectAddress + SectSize) {
2544       S = (*(info->Sections))[SectIdx];
2545       offset = Address - SectAddress;
2546       left = SectSize - offset;
2547       StringRef SectContents;
2548       ((*(info->Sections))[SectIdx]).getContents(SectContents);
2549       return SectContents.data() + offset;
2550     }
2551   }
2552   return nullptr;
2553 }
2554 
2555 static const char *get_pointer_32(uint32_t Address, uint32_t &offset,
2556                                   uint32_t &left, SectionRef &S,
2557                                   DisassembleInfo *info,
2558                                   bool objc_only = false) {
2559   return get_pointer_64(Address, offset, left, S, info, objc_only);
2560 }
2561 
2562 // get_symbol_64() returns the name of a symbol (or nullptr) and the address of
2563 // the symbol indirectly through n_value. Based on the relocation information
2564 // for the specified section offset in the specified section reference.
2565 // If no relocation information is found and a non-zero ReferenceValue for the
2566 // symbol is passed, look up that address in the info's AddrMap.
2567 static const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
2568                                  DisassembleInfo *info, uint64_t &n_value,
2569                                  uint64_t ReferenceValue = 0) {
2570   n_value = 0;
2571   if (!info->verbose)
2572     return nullptr;
2573 
2574   // See if there is an external relocation entry at the sect_offset.
2575   bool reloc_found = false;
2576   DataRefImpl Rel;
2577   MachO::any_relocation_info RE;
2578   bool isExtern = false;
2579   SymbolRef Symbol;
2580   for (const RelocationRef &Reloc : S.relocations()) {
2581     uint64_t RelocOffset = Reloc.getOffset();
2582     if (RelocOffset == sect_offset) {
2583       Rel = Reloc.getRawDataRefImpl();
2584       RE = info->O->getRelocation(Rel);
2585       if (info->O->isRelocationScattered(RE))
2586         continue;
2587       isExtern = info->O->getPlainRelocationExternal(RE);
2588       if (isExtern) {
2589         symbol_iterator RelocSym = Reloc.getSymbol();
2590         Symbol = *RelocSym;
2591       }
2592       reloc_found = true;
2593       break;
2594     }
2595   }
2596   // If there is an external relocation entry for a symbol in this section
2597   // at this section_offset then use that symbol's value for the n_value
2598   // and return its name.
2599   const char *SymbolName = nullptr;
2600   if (reloc_found && isExtern) {
2601     n_value = Symbol.getValue();
2602     Expected<StringRef> NameOrError = Symbol.getName();
2603     if (!NameOrError)
2604       report_error(info->O->getFileName(), NameOrError.takeError());
2605     StringRef Name = *NameOrError;
2606     if (!Name.empty()) {
2607       SymbolName = Name.data();
2608       return SymbolName;
2609     }
2610   }
2611 
2612   // TODO: For fully linked images, look through the external relocation
2613   // entries off the dynamic symtab command. For these the r_offset is from the
2614   // start of the first writeable segment in the Mach-O file.  So the offset
2615   // to this section from that segment is passed to this routine by the caller,
2616   // as the database_offset. Which is the difference of the section's starting
2617   // address and the first writable segment.
2618   //
2619   // NOTE: need add passing the database_offset to this routine.
2620 
2621   // We did not find an external relocation entry so look up the ReferenceValue
2622   // as an address of a symbol and if found return that symbol's name.
2623   SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
2624 
2625   return SymbolName;
2626 }
2627 
2628 static const char *get_symbol_32(uint32_t sect_offset, SectionRef S,
2629                                  DisassembleInfo *info,
2630                                  uint32_t ReferenceValue) {
2631   uint64_t n_value64;
2632   return get_symbol_64(sect_offset, S, info, n_value64, ReferenceValue);
2633 }
2634 
2635 // These are structs in the Objective-C meta data and read to produce the
2636 // comments for disassembly.  While these are part of the ABI they are no
2637 // public defintions.  So the are here not in include/llvm/BinaryFormat/MachO.h
2638 // .
2639 
2640 // The cfstring object in a 64-bit Mach-O file.
2641 struct cfstring64_t {
2642   uint64_t isa;        // class64_t * (64-bit pointer)
2643   uint64_t flags;      // flag bits
2644   uint64_t characters; // char * (64-bit pointer)
2645   uint64_t length;     // number of non-NULL characters in above
2646 };
2647 
2648 // The class object in a 64-bit Mach-O file.
2649 struct class64_t {
2650   uint64_t isa;        // class64_t * (64-bit pointer)
2651   uint64_t superclass; // class64_t * (64-bit pointer)
2652   uint64_t cache;      // Cache (64-bit pointer)
2653   uint64_t vtable;     // IMP * (64-bit pointer)
2654   uint64_t data;       // class_ro64_t * (64-bit pointer)
2655 };
2656 
2657 struct class32_t {
2658   uint32_t isa;        /* class32_t * (32-bit pointer) */
2659   uint32_t superclass; /* class32_t * (32-bit pointer) */
2660   uint32_t cache;      /* Cache (32-bit pointer) */
2661   uint32_t vtable;     /* IMP * (32-bit pointer) */
2662   uint32_t data;       /* class_ro32_t * (32-bit pointer) */
2663 };
2664 
2665 struct class_ro64_t {
2666   uint32_t flags;
2667   uint32_t instanceStart;
2668   uint32_t instanceSize;
2669   uint32_t reserved;
2670   uint64_t ivarLayout;     // const uint8_t * (64-bit pointer)
2671   uint64_t name;           // const char * (64-bit pointer)
2672   uint64_t baseMethods;    // const method_list_t * (64-bit pointer)
2673   uint64_t baseProtocols;  // const protocol_list_t * (64-bit pointer)
2674   uint64_t ivars;          // const ivar_list_t * (64-bit pointer)
2675   uint64_t weakIvarLayout; // const uint8_t * (64-bit pointer)
2676   uint64_t baseProperties; // const struct objc_property_list (64-bit pointer)
2677 };
2678 
2679 struct class_ro32_t {
2680   uint32_t flags;
2681   uint32_t instanceStart;
2682   uint32_t instanceSize;
2683   uint32_t ivarLayout;     /* const uint8_t * (32-bit pointer) */
2684   uint32_t name;           /* const char * (32-bit pointer) */
2685   uint32_t baseMethods;    /* const method_list_t * (32-bit pointer) */
2686   uint32_t baseProtocols;  /* const protocol_list_t * (32-bit pointer) */
2687   uint32_t ivars;          /* const ivar_list_t * (32-bit pointer) */
2688   uint32_t weakIvarLayout; /* const uint8_t * (32-bit pointer) */
2689   uint32_t baseProperties; /* const struct objc_property_list *
2690                                                    (32-bit pointer) */
2691 };
2692 
2693 /* Values for class_ro{64,32}_t->flags */
2694 #define RO_META (1 << 0)
2695 #define RO_ROOT (1 << 1)
2696 #define RO_HAS_CXX_STRUCTORS (1 << 2)
2697 
2698 struct method_list64_t {
2699   uint32_t entsize;
2700   uint32_t count;
2701   /* struct method64_t first;  These structures follow inline */
2702 };
2703 
2704 struct method_list32_t {
2705   uint32_t entsize;
2706   uint32_t count;
2707   /* struct method32_t first;  These structures follow inline */
2708 };
2709 
2710 struct method64_t {
2711   uint64_t name;  /* SEL (64-bit pointer) */
2712   uint64_t types; /* const char * (64-bit pointer) */
2713   uint64_t imp;   /* IMP (64-bit pointer) */
2714 };
2715 
2716 struct method32_t {
2717   uint32_t name;  /* SEL (32-bit pointer) */
2718   uint32_t types; /* const char * (32-bit pointer) */
2719   uint32_t imp;   /* IMP (32-bit pointer) */
2720 };
2721 
2722 struct protocol_list64_t {
2723   uint64_t count; /* uintptr_t (a 64-bit value) */
2724   /* struct protocol64_t * list[0];  These pointers follow inline */
2725 };
2726 
2727 struct protocol_list32_t {
2728   uint32_t count; /* uintptr_t (a 32-bit value) */
2729   /* struct protocol32_t * list[0];  These pointers follow inline */
2730 };
2731 
2732 struct protocol64_t {
2733   uint64_t isa;                     /* id * (64-bit pointer) */
2734   uint64_t name;                    /* const char * (64-bit pointer) */
2735   uint64_t protocols;               /* struct protocol_list64_t *
2736                                                     (64-bit pointer) */
2737   uint64_t instanceMethods;         /* method_list_t * (64-bit pointer) */
2738   uint64_t classMethods;            /* method_list_t * (64-bit pointer) */
2739   uint64_t optionalInstanceMethods; /* method_list_t * (64-bit pointer) */
2740   uint64_t optionalClassMethods;    /* method_list_t * (64-bit pointer) */
2741   uint64_t instanceProperties;      /* struct objc_property_list *
2742                                                        (64-bit pointer) */
2743 };
2744 
2745 struct protocol32_t {
2746   uint32_t isa;                     /* id * (32-bit pointer) */
2747   uint32_t name;                    /* const char * (32-bit pointer) */
2748   uint32_t protocols;               /* struct protocol_list_t *
2749                                                     (32-bit pointer) */
2750   uint32_t instanceMethods;         /* method_list_t * (32-bit pointer) */
2751   uint32_t classMethods;            /* method_list_t * (32-bit pointer) */
2752   uint32_t optionalInstanceMethods; /* method_list_t * (32-bit pointer) */
2753   uint32_t optionalClassMethods;    /* method_list_t * (32-bit pointer) */
2754   uint32_t instanceProperties;      /* struct objc_property_list *
2755                                                        (32-bit pointer) */
2756 };
2757 
2758 struct ivar_list64_t {
2759   uint32_t entsize;
2760   uint32_t count;
2761   /* struct ivar64_t first;  These structures follow inline */
2762 };
2763 
2764 struct ivar_list32_t {
2765   uint32_t entsize;
2766   uint32_t count;
2767   /* struct ivar32_t first;  These structures follow inline */
2768 };
2769 
2770 struct ivar64_t {
2771   uint64_t offset; /* uintptr_t * (64-bit pointer) */
2772   uint64_t name;   /* const char * (64-bit pointer) */
2773   uint64_t type;   /* const char * (64-bit pointer) */
2774   uint32_t alignment;
2775   uint32_t size;
2776 };
2777 
2778 struct ivar32_t {
2779   uint32_t offset; /* uintptr_t * (32-bit pointer) */
2780   uint32_t name;   /* const char * (32-bit pointer) */
2781   uint32_t type;   /* const char * (32-bit pointer) */
2782   uint32_t alignment;
2783   uint32_t size;
2784 };
2785 
2786 struct objc_property_list64 {
2787   uint32_t entsize;
2788   uint32_t count;
2789   /* struct objc_property64 first;  These structures follow inline */
2790 };
2791 
2792 struct objc_property_list32 {
2793   uint32_t entsize;
2794   uint32_t count;
2795   /* struct objc_property32 first;  These structures follow inline */
2796 };
2797 
2798 struct objc_property64 {
2799   uint64_t name;       /* const char * (64-bit pointer) */
2800   uint64_t attributes; /* const char * (64-bit pointer) */
2801 };
2802 
2803 struct objc_property32 {
2804   uint32_t name;       /* const char * (32-bit pointer) */
2805   uint32_t attributes; /* const char * (32-bit pointer) */
2806 };
2807 
2808 struct category64_t {
2809   uint64_t name;               /* const char * (64-bit pointer) */
2810   uint64_t cls;                /* struct class_t * (64-bit pointer) */
2811   uint64_t instanceMethods;    /* struct method_list_t * (64-bit pointer) */
2812   uint64_t classMethods;       /* struct method_list_t * (64-bit pointer) */
2813   uint64_t protocols;          /* struct protocol_list_t * (64-bit pointer) */
2814   uint64_t instanceProperties; /* struct objc_property_list *
2815                                   (64-bit pointer) */
2816 };
2817 
2818 struct category32_t {
2819   uint32_t name;               /* const char * (32-bit pointer) */
2820   uint32_t cls;                /* struct class_t * (32-bit pointer) */
2821   uint32_t instanceMethods;    /* struct method_list_t * (32-bit pointer) */
2822   uint32_t classMethods;       /* struct method_list_t * (32-bit pointer) */
2823   uint32_t protocols;          /* struct protocol_list_t * (32-bit pointer) */
2824   uint32_t instanceProperties; /* struct objc_property_list *
2825                                   (32-bit pointer) */
2826 };
2827 
2828 struct objc_image_info64 {
2829   uint32_t version;
2830   uint32_t flags;
2831 };
2832 struct objc_image_info32 {
2833   uint32_t version;
2834   uint32_t flags;
2835 };
2836 struct imageInfo_t {
2837   uint32_t version;
2838   uint32_t flags;
2839 };
2840 /* masks for objc_image_info.flags */
2841 #define OBJC_IMAGE_IS_REPLACEMENT (1 << 0)
2842 #define OBJC_IMAGE_SUPPORTS_GC (1 << 1)
2843 
2844 struct message_ref64 {
2845   uint64_t imp; /* IMP (64-bit pointer) */
2846   uint64_t sel; /* SEL (64-bit pointer) */
2847 };
2848 
2849 struct message_ref32 {
2850   uint32_t imp; /* IMP (32-bit pointer) */
2851   uint32_t sel; /* SEL (32-bit pointer) */
2852 };
2853 
2854 // Objective-C 1 (32-bit only) meta data structs.
2855 
2856 struct objc_module_t {
2857   uint32_t version;
2858   uint32_t size;
2859   uint32_t name;   /* char * (32-bit pointer) */
2860   uint32_t symtab; /* struct objc_symtab * (32-bit pointer) */
2861 };
2862 
2863 struct objc_symtab_t {
2864   uint32_t sel_ref_cnt;
2865   uint32_t refs; /* SEL * (32-bit pointer) */
2866   uint16_t cls_def_cnt;
2867   uint16_t cat_def_cnt;
2868   // uint32_t defs[1];        /* void * (32-bit pointer) variable size */
2869 };
2870 
2871 struct objc_class_t {
2872   uint32_t isa;         /* struct objc_class * (32-bit pointer) */
2873   uint32_t super_class; /* struct objc_class * (32-bit pointer) */
2874   uint32_t name;        /* const char * (32-bit pointer) */
2875   int32_t version;
2876   int32_t info;
2877   int32_t instance_size;
2878   uint32_t ivars;       /* struct objc_ivar_list * (32-bit pointer) */
2879   uint32_t methodLists; /* struct objc_method_list ** (32-bit pointer) */
2880   uint32_t cache;       /* struct objc_cache * (32-bit pointer) */
2881   uint32_t protocols;   /* struct objc_protocol_list * (32-bit pointer) */
2882 };
2883 
2884 #define CLS_GETINFO(cls, infomask) ((cls)->info & (infomask))
2885 // class is not a metaclass
2886 #define CLS_CLASS 0x1
2887 // class is a metaclass
2888 #define CLS_META 0x2
2889 
2890 struct objc_category_t {
2891   uint32_t category_name;    /* char * (32-bit pointer) */
2892   uint32_t class_name;       /* char * (32-bit pointer) */
2893   uint32_t instance_methods; /* struct objc_method_list * (32-bit pointer) */
2894   uint32_t class_methods;    /* struct objc_method_list * (32-bit pointer) */
2895   uint32_t protocols;        /* struct objc_protocol_list * (32-bit ptr) */
2896 };
2897 
2898 struct objc_ivar_t {
2899   uint32_t ivar_name; /* char * (32-bit pointer) */
2900   uint32_t ivar_type; /* char * (32-bit pointer) */
2901   int32_t ivar_offset;
2902 };
2903 
2904 struct objc_ivar_list_t {
2905   int32_t ivar_count;
2906   // struct objc_ivar_t ivar_list[1];          /* variable length structure */
2907 };
2908 
2909 struct objc_method_list_t {
2910   uint32_t obsolete; /* struct objc_method_list * (32-bit pointer) */
2911   int32_t method_count;
2912   // struct objc_method_t method_list[1];      /* variable length structure */
2913 };
2914 
2915 struct objc_method_t {
2916   uint32_t method_name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
2917   uint32_t method_types; /* char * (32-bit pointer) */
2918   uint32_t method_imp;   /* IMP, aka function pointer, (*IMP)(id, SEL, ...)
2919                             (32-bit pointer) */
2920 };
2921 
2922 struct objc_protocol_list_t {
2923   uint32_t next; /* struct objc_protocol_list * (32-bit pointer) */
2924   int32_t count;
2925   // uint32_t list[1];   /* Protocol *, aka struct objc_protocol_t *
2926   //                        (32-bit pointer) */
2927 };
2928 
2929 struct objc_protocol_t {
2930   uint32_t isa;              /* struct objc_class * (32-bit pointer) */
2931   uint32_t protocol_name;    /* char * (32-bit pointer) */
2932   uint32_t protocol_list;    /* struct objc_protocol_list * (32-bit pointer) */
2933   uint32_t instance_methods; /* struct objc_method_description_list *
2934                                 (32-bit pointer) */
2935   uint32_t class_methods;    /* struct objc_method_description_list *
2936                                 (32-bit pointer) */
2937 };
2938 
2939 struct objc_method_description_list_t {
2940   int32_t count;
2941   // struct objc_method_description_t list[1];
2942 };
2943 
2944 struct objc_method_description_t {
2945   uint32_t name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
2946   uint32_t types; /* char * (32-bit pointer) */
2947 };
2948 
2949 inline void swapStruct(struct cfstring64_t &cfs) {
2950   sys::swapByteOrder(cfs.isa);
2951   sys::swapByteOrder(cfs.flags);
2952   sys::swapByteOrder(cfs.characters);
2953   sys::swapByteOrder(cfs.length);
2954 }
2955 
2956 inline void swapStruct(struct class64_t &c) {
2957   sys::swapByteOrder(c.isa);
2958   sys::swapByteOrder(c.superclass);
2959   sys::swapByteOrder(c.cache);
2960   sys::swapByteOrder(c.vtable);
2961   sys::swapByteOrder(c.data);
2962 }
2963 
2964 inline void swapStruct(struct class32_t &c) {
2965   sys::swapByteOrder(c.isa);
2966   sys::swapByteOrder(c.superclass);
2967   sys::swapByteOrder(c.cache);
2968   sys::swapByteOrder(c.vtable);
2969   sys::swapByteOrder(c.data);
2970 }
2971 
2972 inline void swapStruct(struct class_ro64_t &cro) {
2973   sys::swapByteOrder(cro.flags);
2974   sys::swapByteOrder(cro.instanceStart);
2975   sys::swapByteOrder(cro.instanceSize);
2976   sys::swapByteOrder(cro.reserved);
2977   sys::swapByteOrder(cro.ivarLayout);
2978   sys::swapByteOrder(cro.name);
2979   sys::swapByteOrder(cro.baseMethods);
2980   sys::swapByteOrder(cro.baseProtocols);
2981   sys::swapByteOrder(cro.ivars);
2982   sys::swapByteOrder(cro.weakIvarLayout);
2983   sys::swapByteOrder(cro.baseProperties);
2984 }
2985 
2986 inline void swapStruct(struct class_ro32_t &cro) {
2987   sys::swapByteOrder(cro.flags);
2988   sys::swapByteOrder(cro.instanceStart);
2989   sys::swapByteOrder(cro.instanceSize);
2990   sys::swapByteOrder(cro.ivarLayout);
2991   sys::swapByteOrder(cro.name);
2992   sys::swapByteOrder(cro.baseMethods);
2993   sys::swapByteOrder(cro.baseProtocols);
2994   sys::swapByteOrder(cro.ivars);
2995   sys::swapByteOrder(cro.weakIvarLayout);
2996   sys::swapByteOrder(cro.baseProperties);
2997 }
2998 
2999 inline void swapStruct(struct method_list64_t &ml) {
3000   sys::swapByteOrder(ml.entsize);
3001   sys::swapByteOrder(ml.count);
3002 }
3003 
3004 inline void swapStruct(struct method_list32_t &ml) {
3005   sys::swapByteOrder(ml.entsize);
3006   sys::swapByteOrder(ml.count);
3007 }
3008 
3009 inline void swapStruct(struct method64_t &m) {
3010   sys::swapByteOrder(m.name);
3011   sys::swapByteOrder(m.types);
3012   sys::swapByteOrder(m.imp);
3013 }
3014 
3015 inline void swapStruct(struct method32_t &m) {
3016   sys::swapByteOrder(m.name);
3017   sys::swapByteOrder(m.types);
3018   sys::swapByteOrder(m.imp);
3019 }
3020 
3021 inline void swapStruct(struct protocol_list64_t &pl) {
3022   sys::swapByteOrder(pl.count);
3023 }
3024 
3025 inline void swapStruct(struct protocol_list32_t &pl) {
3026   sys::swapByteOrder(pl.count);
3027 }
3028 
3029 inline void swapStruct(struct protocol64_t &p) {
3030   sys::swapByteOrder(p.isa);
3031   sys::swapByteOrder(p.name);
3032   sys::swapByteOrder(p.protocols);
3033   sys::swapByteOrder(p.instanceMethods);
3034   sys::swapByteOrder(p.classMethods);
3035   sys::swapByteOrder(p.optionalInstanceMethods);
3036   sys::swapByteOrder(p.optionalClassMethods);
3037   sys::swapByteOrder(p.instanceProperties);
3038 }
3039 
3040 inline void swapStruct(struct protocol32_t &p) {
3041   sys::swapByteOrder(p.isa);
3042   sys::swapByteOrder(p.name);
3043   sys::swapByteOrder(p.protocols);
3044   sys::swapByteOrder(p.instanceMethods);
3045   sys::swapByteOrder(p.classMethods);
3046   sys::swapByteOrder(p.optionalInstanceMethods);
3047   sys::swapByteOrder(p.optionalClassMethods);
3048   sys::swapByteOrder(p.instanceProperties);
3049 }
3050 
3051 inline void swapStruct(struct ivar_list64_t &il) {
3052   sys::swapByteOrder(il.entsize);
3053   sys::swapByteOrder(il.count);
3054 }
3055 
3056 inline void swapStruct(struct ivar_list32_t &il) {
3057   sys::swapByteOrder(il.entsize);
3058   sys::swapByteOrder(il.count);
3059 }
3060 
3061 inline void swapStruct(struct ivar64_t &i) {
3062   sys::swapByteOrder(i.offset);
3063   sys::swapByteOrder(i.name);
3064   sys::swapByteOrder(i.type);
3065   sys::swapByteOrder(i.alignment);
3066   sys::swapByteOrder(i.size);
3067 }
3068 
3069 inline void swapStruct(struct ivar32_t &i) {
3070   sys::swapByteOrder(i.offset);
3071   sys::swapByteOrder(i.name);
3072   sys::swapByteOrder(i.type);
3073   sys::swapByteOrder(i.alignment);
3074   sys::swapByteOrder(i.size);
3075 }
3076 
3077 inline void swapStruct(struct objc_property_list64 &pl) {
3078   sys::swapByteOrder(pl.entsize);
3079   sys::swapByteOrder(pl.count);
3080 }
3081 
3082 inline void swapStruct(struct objc_property_list32 &pl) {
3083   sys::swapByteOrder(pl.entsize);
3084   sys::swapByteOrder(pl.count);
3085 }
3086 
3087 inline void swapStruct(struct objc_property64 &op) {
3088   sys::swapByteOrder(op.name);
3089   sys::swapByteOrder(op.attributes);
3090 }
3091 
3092 inline void swapStruct(struct objc_property32 &op) {
3093   sys::swapByteOrder(op.name);
3094   sys::swapByteOrder(op.attributes);
3095 }
3096 
3097 inline void swapStruct(struct category64_t &c) {
3098   sys::swapByteOrder(c.name);
3099   sys::swapByteOrder(c.cls);
3100   sys::swapByteOrder(c.instanceMethods);
3101   sys::swapByteOrder(c.classMethods);
3102   sys::swapByteOrder(c.protocols);
3103   sys::swapByteOrder(c.instanceProperties);
3104 }
3105 
3106 inline void swapStruct(struct category32_t &c) {
3107   sys::swapByteOrder(c.name);
3108   sys::swapByteOrder(c.cls);
3109   sys::swapByteOrder(c.instanceMethods);
3110   sys::swapByteOrder(c.classMethods);
3111   sys::swapByteOrder(c.protocols);
3112   sys::swapByteOrder(c.instanceProperties);
3113 }
3114 
3115 inline void swapStruct(struct objc_image_info64 &o) {
3116   sys::swapByteOrder(o.version);
3117   sys::swapByteOrder(o.flags);
3118 }
3119 
3120 inline void swapStruct(struct objc_image_info32 &o) {
3121   sys::swapByteOrder(o.version);
3122   sys::swapByteOrder(o.flags);
3123 }
3124 
3125 inline void swapStruct(struct imageInfo_t &o) {
3126   sys::swapByteOrder(o.version);
3127   sys::swapByteOrder(o.flags);
3128 }
3129 
3130 inline void swapStruct(struct message_ref64 &mr) {
3131   sys::swapByteOrder(mr.imp);
3132   sys::swapByteOrder(mr.sel);
3133 }
3134 
3135 inline void swapStruct(struct message_ref32 &mr) {
3136   sys::swapByteOrder(mr.imp);
3137   sys::swapByteOrder(mr.sel);
3138 }
3139 
3140 inline void swapStruct(struct objc_module_t &module) {
3141   sys::swapByteOrder(module.version);
3142   sys::swapByteOrder(module.size);
3143   sys::swapByteOrder(module.name);
3144   sys::swapByteOrder(module.symtab);
3145 }
3146 
3147 inline void swapStruct(struct objc_symtab_t &symtab) {
3148   sys::swapByteOrder(symtab.sel_ref_cnt);
3149   sys::swapByteOrder(symtab.refs);
3150   sys::swapByteOrder(symtab.cls_def_cnt);
3151   sys::swapByteOrder(symtab.cat_def_cnt);
3152 }
3153 
3154 inline void swapStruct(struct objc_class_t &objc_class) {
3155   sys::swapByteOrder(objc_class.isa);
3156   sys::swapByteOrder(objc_class.super_class);
3157   sys::swapByteOrder(objc_class.name);
3158   sys::swapByteOrder(objc_class.version);
3159   sys::swapByteOrder(objc_class.info);
3160   sys::swapByteOrder(objc_class.instance_size);
3161   sys::swapByteOrder(objc_class.ivars);
3162   sys::swapByteOrder(objc_class.methodLists);
3163   sys::swapByteOrder(objc_class.cache);
3164   sys::swapByteOrder(objc_class.protocols);
3165 }
3166 
3167 inline void swapStruct(struct objc_category_t &objc_category) {
3168   sys::swapByteOrder(objc_category.category_name);
3169   sys::swapByteOrder(objc_category.class_name);
3170   sys::swapByteOrder(objc_category.instance_methods);
3171   sys::swapByteOrder(objc_category.class_methods);
3172   sys::swapByteOrder(objc_category.protocols);
3173 }
3174 
3175 inline void swapStruct(struct objc_ivar_list_t &objc_ivar_list) {
3176   sys::swapByteOrder(objc_ivar_list.ivar_count);
3177 }
3178 
3179 inline void swapStruct(struct objc_ivar_t &objc_ivar) {
3180   sys::swapByteOrder(objc_ivar.ivar_name);
3181   sys::swapByteOrder(objc_ivar.ivar_type);
3182   sys::swapByteOrder(objc_ivar.ivar_offset);
3183 }
3184 
3185 inline void swapStruct(struct objc_method_list_t &method_list) {
3186   sys::swapByteOrder(method_list.obsolete);
3187   sys::swapByteOrder(method_list.method_count);
3188 }
3189 
3190 inline void swapStruct(struct objc_method_t &method) {
3191   sys::swapByteOrder(method.method_name);
3192   sys::swapByteOrder(method.method_types);
3193   sys::swapByteOrder(method.method_imp);
3194 }
3195 
3196 inline void swapStruct(struct objc_protocol_list_t &protocol_list) {
3197   sys::swapByteOrder(protocol_list.next);
3198   sys::swapByteOrder(protocol_list.count);
3199 }
3200 
3201 inline void swapStruct(struct objc_protocol_t &protocol) {
3202   sys::swapByteOrder(protocol.isa);
3203   sys::swapByteOrder(protocol.protocol_name);
3204   sys::swapByteOrder(protocol.protocol_list);
3205   sys::swapByteOrder(protocol.instance_methods);
3206   sys::swapByteOrder(protocol.class_methods);
3207 }
3208 
3209 inline void swapStruct(struct objc_method_description_list_t &mdl) {
3210   sys::swapByteOrder(mdl.count);
3211 }
3212 
3213 inline void swapStruct(struct objc_method_description_t &md) {
3214   sys::swapByteOrder(md.name);
3215   sys::swapByteOrder(md.types);
3216 }
3217 
3218 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
3219                                                  struct DisassembleInfo *info);
3220 
3221 // get_objc2_64bit_class_name() is used for disassembly and is passed a pointer
3222 // to an Objective-C class and returns the class name.  It is also passed the
3223 // address of the pointer, so when the pointer is zero as it can be in an .o
3224 // file, that is used to look for an external relocation entry with a symbol
3225 // name.
3226 static const char *get_objc2_64bit_class_name(uint64_t pointer_value,
3227                                               uint64_t ReferenceValue,
3228                                               struct DisassembleInfo *info) {
3229   const char *r;
3230   uint32_t offset, left;
3231   SectionRef S;
3232 
3233   // The pointer_value can be 0 in an object file and have a relocation
3234   // entry for the class symbol at the ReferenceValue (the address of the
3235   // pointer).
3236   if (pointer_value == 0) {
3237     r = get_pointer_64(ReferenceValue, offset, left, S, info);
3238     if (r == nullptr || left < sizeof(uint64_t))
3239       return nullptr;
3240     uint64_t n_value;
3241     const char *symbol_name = get_symbol_64(offset, S, info, n_value);
3242     if (symbol_name == nullptr)
3243       return nullptr;
3244     const char *class_name = strrchr(symbol_name, '$');
3245     if (class_name != nullptr && class_name[1] == '_' && class_name[2] != '\0')
3246       return class_name + 2;
3247     else
3248       return nullptr;
3249   }
3250 
3251   // The case were the pointer_value is non-zero and points to a class defined
3252   // in this Mach-O file.
3253   r = get_pointer_64(pointer_value, offset, left, S, info);
3254   if (r == nullptr || left < sizeof(struct class64_t))
3255     return nullptr;
3256   struct class64_t c;
3257   memcpy(&c, r, sizeof(struct class64_t));
3258   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3259     swapStruct(c);
3260   if (c.data == 0)
3261     return nullptr;
3262   r = get_pointer_64(c.data, offset, left, S, info);
3263   if (r == nullptr || left < sizeof(struct class_ro64_t))
3264     return nullptr;
3265   struct class_ro64_t cro;
3266   memcpy(&cro, r, sizeof(struct class_ro64_t));
3267   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3268     swapStruct(cro);
3269   if (cro.name == 0)
3270     return nullptr;
3271   const char *name = get_pointer_64(cro.name, offset, left, S, info);
3272   return name;
3273 }
3274 
3275 // get_objc2_64bit_cfstring_name is used for disassembly and is passed a
3276 // pointer to a cfstring and returns its name or nullptr.
3277 static const char *get_objc2_64bit_cfstring_name(uint64_t ReferenceValue,
3278                                                  struct DisassembleInfo *info) {
3279   const char *r, *name;
3280   uint32_t offset, left;
3281   SectionRef S;
3282   struct cfstring64_t cfs;
3283   uint64_t cfs_characters;
3284 
3285   r = get_pointer_64(ReferenceValue, offset, left, S, info);
3286   if (r == nullptr || left < sizeof(struct cfstring64_t))
3287     return nullptr;
3288   memcpy(&cfs, r, sizeof(struct cfstring64_t));
3289   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3290     swapStruct(cfs);
3291   if (cfs.characters == 0) {
3292     uint64_t n_value;
3293     const char *symbol_name = get_symbol_64(
3294         offset + offsetof(struct cfstring64_t, characters), S, info, n_value);
3295     if (symbol_name == nullptr)
3296       return nullptr;
3297     cfs_characters = n_value;
3298   } else
3299     cfs_characters = cfs.characters;
3300   name = get_pointer_64(cfs_characters, offset, left, S, info);
3301 
3302   return name;
3303 }
3304 
3305 // get_objc2_64bit_selref() is used for disassembly and is passed a the address
3306 // of a pointer to an Objective-C selector reference when the pointer value is
3307 // zero as in a .o file and is likely to have a external relocation entry with
3308 // who's symbol's n_value is the real pointer to the selector name.  If that is
3309 // the case the real pointer to the selector name is returned else 0 is
3310 // returned
3311 static uint64_t get_objc2_64bit_selref(uint64_t ReferenceValue,
3312                                        struct DisassembleInfo *info) {
3313   uint32_t offset, left;
3314   SectionRef S;
3315 
3316   const char *r = get_pointer_64(ReferenceValue, offset, left, S, info);
3317   if (r == nullptr || left < sizeof(uint64_t))
3318     return 0;
3319   uint64_t n_value;
3320   const char *symbol_name = get_symbol_64(offset, S, info, n_value);
3321   if (symbol_name == nullptr)
3322     return 0;
3323   return n_value;
3324 }
3325 
3326 static const SectionRef get_section(MachOObjectFile *O, const char *segname,
3327                                     const char *sectname) {
3328   for (const SectionRef &Section : O->sections()) {
3329     StringRef SectName;
3330     Section.getName(SectName);
3331     DataRefImpl Ref = Section.getRawDataRefImpl();
3332     StringRef SegName = O->getSectionFinalSegmentName(Ref);
3333     if (SegName == segname && SectName == sectname)
3334       return Section;
3335   }
3336   return SectionRef();
3337 }
3338 
3339 static void
3340 walk_pointer_list_64(const char *listname, const SectionRef S,
3341                      MachOObjectFile *O, struct DisassembleInfo *info,
3342                      void (*func)(uint64_t, struct DisassembleInfo *info)) {
3343   if (S == SectionRef())
3344     return;
3345 
3346   StringRef SectName;
3347   S.getName(SectName);
3348   DataRefImpl Ref = S.getRawDataRefImpl();
3349   StringRef SegName = O->getSectionFinalSegmentName(Ref);
3350   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
3351 
3352   StringRef BytesStr;
3353   S.getContents(BytesStr);
3354   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
3355 
3356   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint64_t)) {
3357     uint32_t left = S.getSize() - i;
3358     uint32_t size = left < sizeof(uint64_t) ? left : sizeof(uint64_t);
3359     uint64_t p = 0;
3360     memcpy(&p, Contents + i, size);
3361     if (i + sizeof(uint64_t) > S.getSize())
3362       outs() << listname << " list pointer extends past end of (" << SegName
3363              << "," << SectName << ") section\n";
3364     outs() << format("%016" PRIx64, S.getAddress() + i) << " ";
3365 
3366     if (O->isLittleEndian() != sys::IsLittleEndianHost)
3367       sys::swapByteOrder(p);
3368 
3369     uint64_t n_value = 0;
3370     const char *name = get_symbol_64(i, S, info, n_value, p);
3371     if (name == nullptr)
3372       name = get_dyld_bind_info_symbolname(S.getAddress() + i, info);
3373 
3374     if (n_value != 0) {
3375       outs() << format("0x%" PRIx64, n_value);
3376       if (p != 0)
3377         outs() << " + " << format("0x%" PRIx64, p);
3378     } else
3379       outs() << format("0x%" PRIx64, p);
3380     if (name != nullptr)
3381       outs() << " " << name;
3382     outs() << "\n";
3383 
3384     p += n_value;
3385     if (func)
3386       func(p, info);
3387   }
3388 }
3389 
3390 static void
3391 walk_pointer_list_32(const char *listname, const SectionRef S,
3392                      MachOObjectFile *O, struct DisassembleInfo *info,
3393                      void (*func)(uint32_t, struct DisassembleInfo *info)) {
3394   if (S == SectionRef())
3395     return;
3396 
3397   StringRef SectName;
3398   S.getName(SectName);
3399   DataRefImpl Ref = S.getRawDataRefImpl();
3400   StringRef SegName = O->getSectionFinalSegmentName(Ref);
3401   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
3402 
3403   StringRef BytesStr;
3404   S.getContents(BytesStr);
3405   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
3406 
3407   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint32_t)) {
3408     uint32_t left = S.getSize() - i;
3409     uint32_t size = left < sizeof(uint32_t) ? left : sizeof(uint32_t);
3410     uint32_t p = 0;
3411     memcpy(&p, Contents + i, size);
3412     if (i + sizeof(uint32_t) > S.getSize())
3413       outs() << listname << " list pointer extends past end of (" << SegName
3414              << "," << SectName << ") section\n";
3415     uint32_t Address = S.getAddress() + i;
3416     outs() << format("%08" PRIx32, Address) << " ";
3417 
3418     if (O->isLittleEndian() != sys::IsLittleEndianHost)
3419       sys::swapByteOrder(p);
3420     outs() << format("0x%" PRIx32, p);
3421 
3422     const char *name = get_symbol_32(i, S, info, p);
3423     if (name != nullptr)
3424       outs() << " " << name;
3425     outs() << "\n";
3426 
3427     if (func)
3428       func(p, info);
3429   }
3430 }
3431 
3432 static void print_layout_map(const char *layout_map, uint32_t left) {
3433   if (layout_map == nullptr)
3434     return;
3435   outs() << "                layout map: ";
3436   do {
3437     outs() << format("0x%02" PRIx32, (*layout_map) & 0xff) << " ";
3438     left--;
3439     layout_map++;
3440   } while (*layout_map != '\0' && left != 0);
3441   outs() << "\n";
3442 }
3443 
3444 static void print_layout_map64(uint64_t p, struct DisassembleInfo *info) {
3445   uint32_t offset, left;
3446   SectionRef S;
3447   const char *layout_map;
3448 
3449   if (p == 0)
3450     return;
3451   layout_map = get_pointer_64(p, offset, left, S, info);
3452   print_layout_map(layout_map, left);
3453 }
3454 
3455 static void print_layout_map32(uint32_t p, struct DisassembleInfo *info) {
3456   uint32_t offset, left;
3457   SectionRef S;
3458   const char *layout_map;
3459 
3460   if (p == 0)
3461     return;
3462   layout_map = get_pointer_32(p, offset, left, S, info);
3463   print_layout_map(layout_map, left);
3464 }
3465 
3466 static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
3467                                   const char *indent) {
3468   struct method_list64_t ml;
3469   struct method64_t m;
3470   const char *r;
3471   uint32_t offset, xoffset, left, i;
3472   SectionRef S, xS;
3473   const char *name, *sym_name;
3474   uint64_t n_value;
3475 
3476   r = get_pointer_64(p, offset, left, S, info);
3477   if (r == nullptr)
3478     return;
3479   memset(&ml, '\0', sizeof(struct method_list64_t));
3480   if (left < sizeof(struct method_list64_t)) {
3481     memcpy(&ml, r, left);
3482     outs() << "   (method_list_t entends past the end of the section)\n";
3483   } else
3484     memcpy(&ml, r, sizeof(struct method_list64_t));
3485   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3486     swapStruct(ml);
3487   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
3488   outs() << indent << "\t\t     count " << ml.count << "\n";
3489 
3490   p += sizeof(struct method_list64_t);
3491   offset += sizeof(struct method_list64_t);
3492   for (i = 0; i < ml.count; i++) {
3493     r = get_pointer_64(p, offset, left, S, info);
3494     if (r == nullptr)
3495       return;
3496     memset(&m, '\0', sizeof(struct method64_t));
3497     if (left < sizeof(struct method64_t)) {
3498       memcpy(&m, r, left);
3499       outs() << indent << "   (method_t extends past the end of the section)\n";
3500     } else
3501       memcpy(&m, r, sizeof(struct method64_t));
3502     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3503       swapStruct(m);
3504 
3505     outs() << indent << "\t\t      name ";
3506     sym_name = get_symbol_64(offset + offsetof(struct method64_t, name), S,
3507                              info, n_value, m.name);
3508     if (n_value != 0) {
3509       if (info->verbose && sym_name != nullptr)
3510         outs() << sym_name;
3511       else
3512         outs() << format("0x%" PRIx64, n_value);
3513       if (m.name != 0)
3514         outs() << " + " << format("0x%" PRIx64, m.name);
3515     } else
3516       outs() << format("0x%" PRIx64, m.name);
3517     name = get_pointer_64(m.name + n_value, xoffset, left, xS, info);
3518     if (name != nullptr)
3519       outs() << format(" %.*s", left, name);
3520     outs() << "\n";
3521 
3522     outs() << indent << "\t\t     types ";
3523     sym_name = get_symbol_64(offset + offsetof(struct method64_t, types), S,
3524                              info, n_value, m.types);
3525     if (n_value != 0) {
3526       if (info->verbose && sym_name != nullptr)
3527         outs() << sym_name;
3528       else
3529         outs() << format("0x%" PRIx64, n_value);
3530       if (m.types != 0)
3531         outs() << " + " << format("0x%" PRIx64, m.types);
3532     } else
3533       outs() << format("0x%" PRIx64, m.types);
3534     name = get_pointer_64(m.types + n_value, xoffset, left, xS, info);
3535     if (name != nullptr)
3536       outs() << format(" %.*s", left, name);
3537     outs() << "\n";
3538 
3539     outs() << indent << "\t\t       imp ";
3540     name = get_symbol_64(offset + offsetof(struct method64_t, imp), S, info,
3541                          n_value, m.imp);
3542     if (info->verbose && name == nullptr) {
3543       if (n_value != 0) {
3544         outs() << format("0x%" PRIx64, n_value) << " ";
3545         if (m.imp != 0)
3546           outs() << "+ " << format("0x%" PRIx64, m.imp) << " ";
3547       } else
3548         outs() << format("0x%" PRIx64, m.imp) << " ";
3549     }
3550     if (name != nullptr)
3551       outs() << name;
3552     outs() << "\n";
3553 
3554     p += sizeof(struct method64_t);
3555     offset += sizeof(struct method64_t);
3556   }
3557 }
3558 
3559 static void print_method_list32_t(uint64_t p, struct DisassembleInfo *info,
3560                                   const char *indent) {
3561   struct method_list32_t ml;
3562   struct method32_t m;
3563   const char *r, *name;
3564   uint32_t offset, xoffset, left, i;
3565   SectionRef S, xS;
3566 
3567   r = get_pointer_32(p, offset, left, S, info);
3568   if (r == nullptr)
3569     return;
3570   memset(&ml, '\0', sizeof(struct method_list32_t));
3571   if (left < sizeof(struct method_list32_t)) {
3572     memcpy(&ml, r, left);
3573     outs() << "   (method_list_t entends past the end of the section)\n";
3574   } else
3575     memcpy(&ml, r, sizeof(struct method_list32_t));
3576   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3577     swapStruct(ml);
3578   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
3579   outs() << indent << "\t\t     count " << ml.count << "\n";
3580 
3581   p += sizeof(struct method_list32_t);
3582   offset += sizeof(struct method_list32_t);
3583   for (i = 0; i < ml.count; i++) {
3584     r = get_pointer_32(p, offset, left, S, info);
3585     if (r == nullptr)
3586       return;
3587     memset(&m, '\0', sizeof(struct method32_t));
3588     if (left < sizeof(struct method32_t)) {
3589       memcpy(&ml, r, left);
3590       outs() << indent << "   (method_t entends past the end of the section)\n";
3591     } else
3592       memcpy(&m, r, sizeof(struct method32_t));
3593     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3594       swapStruct(m);
3595 
3596     outs() << indent << "\t\t      name " << format("0x%" PRIx32, m.name);
3597     name = get_pointer_32(m.name, xoffset, left, xS, info);
3598     if (name != nullptr)
3599       outs() << format(" %.*s", left, name);
3600     outs() << "\n";
3601 
3602     outs() << indent << "\t\t     types " << format("0x%" PRIx32, m.types);
3603     name = get_pointer_32(m.types, xoffset, left, xS, info);
3604     if (name != nullptr)
3605       outs() << format(" %.*s", left, name);
3606     outs() << "\n";
3607 
3608     outs() << indent << "\t\t       imp " << format("0x%" PRIx32, m.imp);
3609     name = get_symbol_32(offset + offsetof(struct method32_t, imp), S, info,
3610                          m.imp);
3611     if (name != nullptr)
3612       outs() << " " << name;
3613     outs() << "\n";
3614 
3615     p += sizeof(struct method32_t);
3616     offset += sizeof(struct method32_t);
3617   }
3618 }
3619 
3620 static bool print_method_list(uint32_t p, struct DisassembleInfo *info) {
3621   uint32_t offset, left, xleft;
3622   SectionRef S;
3623   struct objc_method_list_t method_list;
3624   struct objc_method_t method;
3625   const char *r, *methods, *name, *SymbolName;
3626   int32_t i;
3627 
3628   r = get_pointer_32(p, offset, left, S, info, true);
3629   if (r == nullptr)
3630     return true;
3631 
3632   outs() << "\n";
3633   if (left > sizeof(struct objc_method_list_t)) {
3634     memcpy(&method_list, r, sizeof(struct objc_method_list_t));
3635   } else {
3636     outs() << "\t\t objc_method_list extends past end of the section\n";
3637     memset(&method_list, '\0', sizeof(struct objc_method_list_t));
3638     memcpy(&method_list, r, left);
3639   }
3640   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3641     swapStruct(method_list);
3642 
3643   outs() << "\t\t         obsolete "
3644          << format("0x%08" PRIx32, method_list.obsolete) << "\n";
3645   outs() << "\t\t     method_count " << method_list.method_count << "\n";
3646 
3647   methods = r + sizeof(struct objc_method_list_t);
3648   for (i = 0; i < method_list.method_count; i++) {
3649     if ((i + 1) * sizeof(struct objc_method_t) > left) {
3650       outs() << "\t\t remaining method's extend past the of the section\n";
3651       break;
3652     }
3653     memcpy(&method, methods + i * sizeof(struct objc_method_t),
3654            sizeof(struct objc_method_t));
3655     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3656       swapStruct(method);
3657 
3658     outs() << "\t\t      method_name "
3659            << format("0x%08" PRIx32, method.method_name);
3660     if (info->verbose) {
3661       name = get_pointer_32(method.method_name, offset, xleft, S, info, true);
3662       if (name != nullptr)
3663         outs() << format(" %.*s", xleft, name);
3664       else
3665         outs() << " (not in an __OBJC section)";
3666     }
3667     outs() << "\n";
3668 
3669     outs() << "\t\t     method_types "
3670            << format("0x%08" PRIx32, method.method_types);
3671     if (info->verbose) {
3672       name = get_pointer_32(method.method_types, offset, xleft, S, info, true);
3673       if (name != nullptr)
3674         outs() << format(" %.*s", xleft, name);
3675       else
3676         outs() << " (not in an __OBJC section)";
3677     }
3678     outs() << "\n";
3679 
3680     outs() << "\t\t       method_imp "
3681            << format("0x%08" PRIx32, method.method_imp) << " ";
3682     if (info->verbose) {
3683       SymbolName = GuessSymbolName(method.method_imp, info->AddrMap);
3684       if (SymbolName != nullptr)
3685         outs() << SymbolName;
3686     }
3687     outs() << "\n";
3688   }
3689   return false;
3690 }
3691 
3692 static void print_protocol_list64_t(uint64_t p, struct DisassembleInfo *info) {
3693   struct protocol_list64_t pl;
3694   uint64_t q, n_value;
3695   struct protocol64_t pc;
3696   const char *r;
3697   uint32_t offset, xoffset, left, i;
3698   SectionRef S, xS;
3699   const char *name, *sym_name;
3700 
3701   r = get_pointer_64(p, offset, left, S, info);
3702   if (r == nullptr)
3703     return;
3704   memset(&pl, '\0', sizeof(struct protocol_list64_t));
3705   if (left < sizeof(struct protocol_list64_t)) {
3706     memcpy(&pl, r, left);
3707     outs() << "   (protocol_list_t entends past the end of the section)\n";
3708   } else
3709     memcpy(&pl, r, sizeof(struct protocol_list64_t));
3710   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3711     swapStruct(pl);
3712   outs() << "                      count " << pl.count << "\n";
3713 
3714   p += sizeof(struct protocol_list64_t);
3715   offset += sizeof(struct protocol_list64_t);
3716   for (i = 0; i < pl.count; i++) {
3717     r = get_pointer_64(p, offset, left, S, info);
3718     if (r == nullptr)
3719       return;
3720     q = 0;
3721     if (left < sizeof(uint64_t)) {
3722       memcpy(&q, r, left);
3723       outs() << "   (protocol_t * entends past the end of the section)\n";
3724     } else
3725       memcpy(&q, r, sizeof(uint64_t));
3726     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3727       sys::swapByteOrder(q);
3728 
3729     outs() << "\t\t      list[" << i << "] ";
3730     sym_name = get_symbol_64(offset, S, info, n_value, q);
3731     if (n_value != 0) {
3732       if (info->verbose && sym_name != nullptr)
3733         outs() << sym_name;
3734       else
3735         outs() << format("0x%" PRIx64, n_value);
3736       if (q != 0)
3737         outs() << " + " << format("0x%" PRIx64, q);
3738     } else
3739       outs() << format("0x%" PRIx64, q);
3740     outs() << " (struct protocol_t *)\n";
3741 
3742     r = get_pointer_64(q + n_value, offset, left, S, info);
3743     if (r == nullptr)
3744       return;
3745     memset(&pc, '\0', sizeof(struct protocol64_t));
3746     if (left < sizeof(struct protocol64_t)) {
3747       memcpy(&pc, r, left);
3748       outs() << "   (protocol_t entends past the end of the section)\n";
3749     } else
3750       memcpy(&pc, r, sizeof(struct protocol64_t));
3751     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3752       swapStruct(pc);
3753 
3754     outs() << "\t\t\t      isa " << format("0x%" PRIx64, pc.isa) << "\n";
3755 
3756     outs() << "\t\t\t     name ";
3757     sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, name), S,
3758                              info, n_value, pc.name);
3759     if (n_value != 0) {
3760       if (info->verbose && sym_name != nullptr)
3761         outs() << sym_name;
3762       else
3763         outs() << format("0x%" PRIx64, n_value);
3764       if (pc.name != 0)
3765         outs() << " + " << format("0x%" PRIx64, pc.name);
3766     } else
3767       outs() << format("0x%" PRIx64, pc.name);
3768     name = get_pointer_64(pc.name + n_value, xoffset, left, xS, info);
3769     if (name != nullptr)
3770       outs() << format(" %.*s", left, name);
3771     outs() << "\n";
3772 
3773     outs() << "\t\t\tprotocols " << format("0x%" PRIx64, pc.protocols) << "\n";
3774 
3775     outs() << "\t\t  instanceMethods ";
3776     sym_name =
3777         get_symbol_64(offset + offsetof(struct protocol64_t, instanceMethods),
3778                       S, info, n_value, pc.instanceMethods);
3779     if (n_value != 0) {
3780       if (info->verbose && sym_name != nullptr)
3781         outs() << sym_name;
3782       else
3783         outs() << format("0x%" PRIx64, n_value);
3784       if (pc.instanceMethods != 0)
3785         outs() << " + " << format("0x%" PRIx64, pc.instanceMethods);
3786     } else
3787       outs() << format("0x%" PRIx64, pc.instanceMethods);
3788     outs() << " (struct method_list_t *)\n";
3789     if (pc.instanceMethods + n_value != 0)
3790       print_method_list64_t(pc.instanceMethods + n_value, info, "\t");
3791 
3792     outs() << "\t\t     classMethods ";
3793     sym_name =
3794         get_symbol_64(offset + offsetof(struct protocol64_t, classMethods), S,
3795                       info, n_value, pc.classMethods);
3796     if (n_value != 0) {
3797       if (info->verbose && sym_name != nullptr)
3798         outs() << sym_name;
3799       else
3800         outs() << format("0x%" PRIx64, n_value);
3801       if (pc.classMethods != 0)
3802         outs() << " + " << format("0x%" PRIx64, pc.classMethods);
3803     } else
3804       outs() << format("0x%" PRIx64, pc.classMethods);
3805     outs() << " (struct method_list_t *)\n";
3806     if (pc.classMethods + n_value != 0)
3807       print_method_list64_t(pc.classMethods + n_value, info, "\t");
3808 
3809     outs() << "\t  optionalInstanceMethods "
3810            << format("0x%" PRIx64, pc.optionalInstanceMethods) << "\n";
3811     outs() << "\t     optionalClassMethods "
3812            << format("0x%" PRIx64, pc.optionalClassMethods) << "\n";
3813     outs() << "\t       instanceProperties "
3814            << format("0x%" PRIx64, pc.instanceProperties) << "\n";
3815 
3816     p += sizeof(uint64_t);
3817     offset += sizeof(uint64_t);
3818   }
3819 }
3820 
3821 static void print_protocol_list32_t(uint32_t p, struct DisassembleInfo *info) {
3822   struct protocol_list32_t pl;
3823   uint32_t q;
3824   struct protocol32_t pc;
3825   const char *r;
3826   uint32_t offset, xoffset, left, i;
3827   SectionRef S, xS;
3828   const char *name;
3829 
3830   r = get_pointer_32(p, offset, left, S, info);
3831   if (r == nullptr)
3832     return;
3833   memset(&pl, '\0', sizeof(struct protocol_list32_t));
3834   if (left < sizeof(struct protocol_list32_t)) {
3835     memcpy(&pl, r, left);
3836     outs() << "   (protocol_list_t entends past the end of the section)\n";
3837   } else
3838     memcpy(&pl, r, sizeof(struct protocol_list32_t));
3839   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3840     swapStruct(pl);
3841   outs() << "                      count " << pl.count << "\n";
3842 
3843   p += sizeof(struct protocol_list32_t);
3844   offset += sizeof(struct protocol_list32_t);
3845   for (i = 0; i < pl.count; i++) {
3846     r = get_pointer_32(p, offset, left, S, info);
3847     if (r == nullptr)
3848       return;
3849     q = 0;
3850     if (left < sizeof(uint32_t)) {
3851       memcpy(&q, r, left);
3852       outs() << "   (protocol_t * entends past the end of the section)\n";
3853     } else
3854       memcpy(&q, r, sizeof(uint32_t));
3855     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3856       sys::swapByteOrder(q);
3857     outs() << "\t\t      list[" << i << "] " << format("0x%" PRIx32, q)
3858            << " (struct protocol_t *)\n";
3859     r = get_pointer_32(q, offset, left, S, info);
3860     if (r == nullptr)
3861       return;
3862     memset(&pc, '\0', sizeof(struct protocol32_t));
3863     if (left < sizeof(struct protocol32_t)) {
3864       memcpy(&pc, r, left);
3865       outs() << "   (protocol_t entends past the end of the section)\n";
3866     } else
3867       memcpy(&pc, r, sizeof(struct protocol32_t));
3868     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3869       swapStruct(pc);
3870     outs() << "\t\t\t      isa " << format("0x%" PRIx32, pc.isa) << "\n";
3871     outs() << "\t\t\t     name " << format("0x%" PRIx32, pc.name);
3872     name = get_pointer_32(pc.name, xoffset, left, xS, info);
3873     if (name != nullptr)
3874       outs() << format(" %.*s", left, name);
3875     outs() << "\n";
3876     outs() << "\t\t\tprotocols " << format("0x%" PRIx32, pc.protocols) << "\n";
3877     outs() << "\t\t  instanceMethods "
3878            << format("0x%" PRIx32, pc.instanceMethods)
3879            << " (struct method_list_t *)\n";
3880     if (pc.instanceMethods != 0)
3881       print_method_list32_t(pc.instanceMethods, info, "\t");
3882     outs() << "\t\t     classMethods " << format("0x%" PRIx32, pc.classMethods)
3883            << " (struct method_list_t *)\n";
3884     if (pc.classMethods != 0)
3885       print_method_list32_t(pc.classMethods, info, "\t");
3886     outs() << "\t  optionalInstanceMethods "
3887            << format("0x%" PRIx32, pc.optionalInstanceMethods) << "\n";
3888     outs() << "\t     optionalClassMethods "
3889            << format("0x%" PRIx32, pc.optionalClassMethods) << "\n";
3890     outs() << "\t       instanceProperties "
3891            << format("0x%" PRIx32, pc.instanceProperties) << "\n";
3892     p += sizeof(uint32_t);
3893     offset += sizeof(uint32_t);
3894   }
3895 }
3896 
3897 static void print_indent(uint32_t indent) {
3898   for (uint32_t i = 0; i < indent;) {
3899     if (indent - i >= 8) {
3900       outs() << "\t";
3901       i += 8;
3902     } else {
3903       for (uint32_t j = i; j < indent; j++)
3904         outs() << " ";
3905       return;
3906     }
3907   }
3908 }
3909 
3910 static bool print_method_description_list(uint32_t p, uint32_t indent,
3911                                           struct DisassembleInfo *info) {
3912   uint32_t offset, left, xleft;
3913   SectionRef S;
3914   struct objc_method_description_list_t mdl;
3915   struct objc_method_description_t md;
3916   const char *r, *list, *name;
3917   int32_t i;
3918 
3919   r = get_pointer_32(p, offset, left, S, info, true);
3920   if (r == nullptr)
3921     return true;
3922 
3923   outs() << "\n";
3924   if (left > sizeof(struct objc_method_description_list_t)) {
3925     memcpy(&mdl, r, sizeof(struct objc_method_description_list_t));
3926   } else {
3927     print_indent(indent);
3928     outs() << " objc_method_description_list extends past end of the section\n";
3929     memset(&mdl, '\0', sizeof(struct objc_method_description_list_t));
3930     memcpy(&mdl, r, left);
3931   }
3932   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3933     swapStruct(mdl);
3934 
3935   print_indent(indent);
3936   outs() << "        count " << mdl.count << "\n";
3937 
3938   list = r + sizeof(struct objc_method_description_list_t);
3939   for (i = 0; i < mdl.count; i++) {
3940     if ((i + 1) * sizeof(struct objc_method_description_t) > left) {
3941       print_indent(indent);
3942       outs() << " remaining list entries extend past the of the section\n";
3943       break;
3944     }
3945     print_indent(indent);
3946     outs() << "        list[" << i << "]\n";
3947     memcpy(&md, list + i * sizeof(struct objc_method_description_t),
3948            sizeof(struct objc_method_description_t));
3949     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3950       swapStruct(md);
3951 
3952     print_indent(indent);
3953     outs() << "             name " << format("0x%08" PRIx32, md.name);
3954     if (info->verbose) {
3955       name = get_pointer_32(md.name, offset, xleft, S, info, true);
3956       if (name != nullptr)
3957         outs() << format(" %.*s", xleft, name);
3958       else
3959         outs() << " (not in an __OBJC section)";
3960     }
3961     outs() << "\n";
3962 
3963     print_indent(indent);
3964     outs() << "            types " << format("0x%08" PRIx32, md.types);
3965     if (info->verbose) {
3966       name = get_pointer_32(md.types, offset, xleft, S, info, true);
3967       if (name != nullptr)
3968         outs() << format(" %.*s", xleft, name);
3969       else
3970         outs() << " (not in an __OBJC section)";
3971     }
3972     outs() << "\n";
3973   }
3974   return false;
3975 }
3976 
3977 static bool print_protocol_list(uint32_t p, uint32_t indent,
3978                                 struct DisassembleInfo *info);
3979 
3980 static bool print_protocol(uint32_t p, uint32_t indent,
3981                            struct DisassembleInfo *info) {
3982   uint32_t offset, left;
3983   SectionRef S;
3984   struct objc_protocol_t protocol;
3985   const char *r, *name;
3986 
3987   r = get_pointer_32(p, offset, left, S, info, true);
3988   if (r == nullptr)
3989     return true;
3990 
3991   outs() << "\n";
3992   if (left >= sizeof(struct objc_protocol_t)) {
3993     memcpy(&protocol, r, sizeof(struct objc_protocol_t));
3994   } else {
3995     print_indent(indent);
3996     outs() << "            Protocol extends past end of the section\n";
3997     memset(&protocol, '\0', sizeof(struct objc_protocol_t));
3998     memcpy(&protocol, r, left);
3999   }
4000   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4001     swapStruct(protocol);
4002 
4003   print_indent(indent);
4004   outs() << "              isa " << format("0x%08" PRIx32, protocol.isa)
4005          << "\n";
4006 
4007   print_indent(indent);
4008   outs() << "    protocol_name "
4009          << format("0x%08" PRIx32, protocol.protocol_name);
4010   if (info->verbose) {
4011     name = get_pointer_32(protocol.protocol_name, offset, left, S, info, true);
4012     if (name != nullptr)
4013       outs() << format(" %.*s", left, name);
4014     else
4015       outs() << " (not in an __OBJC section)";
4016   }
4017   outs() << "\n";
4018 
4019   print_indent(indent);
4020   outs() << "    protocol_list "
4021          << format("0x%08" PRIx32, protocol.protocol_list);
4022   if (print_protocol_list(protocol.protocol_list, indent + 4, info))
4023     outs() << " (not in an __OBJC section)\n";
4024 
4025   print_indent(indent);
4026   outs() << " instance_methods "
4027          << format("0x%08" PRIx32, protocol.instance_methods);
4028   if (print_method_description_list(protocol.instance_methods, indent, info))
4029     outs() << " (not in an __OBJC section)\n";
4030 
4031   print_indent(indent);
4032   outs() << "    class_methods "
4033          << format("0x%08" PRIx32, protocol.class_methods);
4034   if (print_method_description_list(protocol.class_methods, indent, info))
4035     outs() << " (not in an __OBJC section)\n";
4036 
4037   return false;
4038 }
4039 
4040 static bool print_protocol_list(uint32_t p, uint32_t indent,
4041                                 struct DisassembleInfo *info) {
4042   uint32_t offset, left, l;
4043   SectionRef S;
4044   struct objc_protocol_list_t protocol_list;
4045   const char *r, *list;
4046   int32_t i;
4047 
4048   r = get_pointer_32(p, offset, left, S, info, true);
4049   if (r == nullptr)
4050     return true;
4051 
4052   outs() << "\n";
4053   if (left > sizeof(struct objc_protocol_list_t)) {
4054     memcpy(&protocol_list, r, sizeof(struct objc_protocol_list_t));
4055   } else {
4056     outs() << "\t\t objc_protocol_list_t extends past end of the section\n";
4057     memset(&protocol_list, '\0', sizeof(struct objc_protocol_list_t));
4058     memcpy(&protocol_list, r, left);
4059   }
4060   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4061     swapStruct(protocol_list);
4062 
4063   print_indent(indent);
4064   outs() << "         next " << format("0x%08" PRIx32, protocol_list.next)
4065          << "\n";
4066   print_indent(indent);
4067   outs() << "        count " << protocol_list.count << "\n";
4068 
4069   list = r + sizeof(struct objc_protocol_list_t);
4070   for (i = 0; i < protocol_list.count; i++) {
4071     if ((i + 1) * sizeof(uint32_t) > left) {
4072       outs() << "\t\t remaining list entries extend past the of the section\n";
4073       break;
4074     }
4075     memcpy(&l, list + i * sizeof(uint32_t), sizeof(uint32_t));
4076     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4077       sys::swapByteOrder(l);
4078 
4079     print_indent(indent);
4080     outs() << "      list[" << i << "] " << format("0x%08" PRIx32, l);
4081     if (print_protocol(l, indent, info))
4082       outs() << "(not in an __OBJC section)\n";
4083   }
4084   return false;
4085 }
4086 
4087 static void print_ivar_list64_t(uint64_t p, struct DisassembleInfo *info) {
4088   struct ivar_list64_t il;
4089   struct ivar64_t i;
4090   const char *r;
4091   uint32_t offset, xoffset, left, j;
4092   SectionRef S, xS;
4093   const char *name, *sym_name, *ivar_offset_p;
4094   uint64_t ivar_offset, n_value;
4095 
4096   r = get_pointer_64(p, offset, left, S, info);
4097   if (r == nullptr)
4098     return;
4099   memset(&il, '\0', sizeof(struct ivar_list64_t));
4100   if (left < sizeof(struct ivar_list64_t)) {
4101     memcpy(&il, r, left);
4102     outs() << "   (ivar_list_t entends past the end of the section)\n";
4103   } else
4104     memcpy(&il, r, sizeof(struct ivar_list64_t));
4105   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4106     swapStruct(il);
4107   outs() << "                    entsize " << il.entsize << "\n";
4108   outs() << "                      count " << il.count << "\n";
4109 
4110   p += sizeof(struct ivar_list64_t);
4111   offset += sizeof(struct ivar_list64_t);
4112   for (j = 0; j < il.count; j++) {
4113     r = get_pointer_64(p, offset, left, S, info);
4114     if (r == nullptr)
4115       return;
4116     memset(&i, '\0', sizeof(struct ivar64_t));
4117     if (left < sizeof(struct ivar64_t)) {
4118       memcpy(&i, r, left);
4119       outs() << "   (ivar_t entends past the end of the section)\n";
4120     } else
4121       memcpy(&i, r, sizeof(struct ivar64_t));
4122     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4123       swapStruct(i);
4124 
4125     outs() << "\t\t\t   offset ";
4126     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, offset), S,
4127                              info, n_value, i.offset);
4128     if (n_value != 0) {
4129       if (info->verbose && sym_name != nullptr)
4130         outs() << sym_name;
4131       else
4132         outs() << format("0x%" PRIx64, n_value);
4133       if (i.offset != 0)
4134         outs() << " + " << format("0x%" PRIx64, i.offset);
4135     } else
4136       outs() << format("0x%" PRIx64, i.offset);
4137     ivar_offset_p = get_pointer_64(i.offset + n_value, xoffset, left, xS, info);
4138     if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
4139       memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
4140       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4141         sys::swapByteOrder(ivar_offset);
4142       outs() << " " << ivar_offset << "\n";
4143     } else
4144       outs() << "\n";
4145 
4146     outs() << "\t\t\t     name ";
4147     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, name), S, info,
4148                              n_value, i.name);
4149     if (n_value != 0) {
4150       if (info->verbose && sym_name != nullptr)
4151         outs() << sym_name;
4152       else
4153         outs() << format("0x%" PRIx64, n_value);
4154       if (i.name != 0)
4155         outs() << " + " << format("0x%" PRIx64, i.name);
4156     } else
4157       outs() << format("0x%" PRIx64, i.name);
4158     name = get_pointer_64(i.name + n_value, xoffset, left, xS, info);
4159     if (name != nullptr)
4160       outs() << format(" %.*s", left, name);
4161     outs() << "\n";
4162 
4163     outs() << "\t\t\t     type ";
4164     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, type), S, info,
4165                              n_value, i.name);
4166     name = get_pointer_64(i.type + n_value, xoffset, left, xS, info);
4167     if (n_value != 0) {
4168       if (info->verbose && sym_name != nullptr)
4169         outs() << sym_name;
4170       else
4171         outs() << format("0x%" PRIx64, n_value);
4172       if (i.type != 0)
4173         outs() << " + " << format("0x%" PRIx64, i.type);
4174     } else
4175       outs() << format("0x%" PRIx64, i.type);
4176     if (name != nullptr)
4177       outs() << format(" %.*s", left, name);
4178     outs() << "\n";
4179 
4180     outs() << "\t\t\talignment " << i.alignment << "\n";
4181     outs() << "\t\t\t     size " << i.size << "\n";
4182 
4183     p += sizeof(struct ivar64_t);
4184     offset += sizeof(struct ivar64_t);
4185   }
4186 }
4187 
4188 static void print_ivar_list32_t(uint32_t p, struct DisassembleInfo *info) {
4189   struct ivar_list32_t il;
4190   struct ivar32_t i;
4191   const char *r;
4192   uint32_t offset, xoffset, left, j;
4193   SectionRef S, xS;
4194   const char *name, *ivar_offset_p;
4195   uint32_t ivar_offset;
4196 
4197   r = get_pointer_32(p, offset, left, S, info);
4198   if (r == nullptr)
4199     return;
4200   memset(&il, '\0', sizeof(struct ivar_list32_t));
4201   if (left < sizeof(struct ivar_list32_t)) {
4202     memcpy(&il, r, left);
4203     outs() << "   (ivar_list_t entends past the end of the section)\n";
4204   } else
4205     memcpy(&il, r, sizeof(struct ivar_list32_t));
4206   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4207     swapStruct(il);
4208   outs() << "                    entsize " << il.entsize << "\n";
4209   outs() << "                      count " << il.count << "\n";
4210 
4211   p += sizeof(struct ivar_list32_t);
4212   offset += sizeof(struct ivar_list32_t);
4213   for (j = 0; j < il.count; j++) {
4214     r = get_pointer_32(p, offset, left, S, info);
4215     if (r == nullptr)
4216       return;
4217     memset(&i, '\0', sizeof(struct ivar32_t));
4218     if (left < sizeof(struct ivar32_t)) {
4219       memcpy(&i, r, left);
4220       outs() << "   (ivar_t entends past the end of the section)\n";
4221     } else
4222       memcpy(&i, r, sizeof(struct ivar32_t));
4223     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4224       swapStruct(i);
4225 
4226     outs() << "\t\t\t   offset " << format("0x%" PRIx32, i.offset);
4227     ivar_offset_p = get_pointer_32(i.offset, xoffset, left, xS, info);
4228     if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
4229       memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
4230       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4231         sys::swapByteOrder(ivar_offset);
4232       outs() << " " << ivar_offset << "\n";
4233     } else
4234       outs() << "\n";
4235 
4236     outs() << "\t\t\t     name " << format("0x%" PRIx32, i.name);
4237     name = get_pointer_32(i.name, xoffset, left, xS, info);
4238     if (name != nullptr)
4239       outs() << format(" %.*s", left, name);
4240     outs() << "\n";
4241 
4242     outs() << "\t\t\t     type " << format("0x%" PRIx32, i.type);
4243     name = get_pointer_32(i.type, xoffset, left, xS, info);
4244     if (name != nullptr)
4245       outs() << format(" %.*s", left, name);
4246     outs() << "\n";
4247 
4248     outs() << "\t\t\talignment " << i.alignment << "\n";
4249     outs() << "\t\t\t     size " << i.size << "\n";
4250 
4251     p += sizeof(struct ivar32_t);
4252     offset += sizeof(struct ivar32_t);
4253   }
4254 }
4255 
4256 static void print_objc_property_list64(uint64_t p,
4257                                        struct DisassembleInfo *info) {
4258   struct objc_property_list64 opl;
4259   struct objc_property64 op;
4260   const char *r;
4261   uint32_t offset, xoffset, left, j;
4262   SectionRef S, xS;
4263   const char *name, *sym_name;
4264   uint64_t n_value;
4265 
4266   r = get_pointer_64(p, offset, left, S, info);
4267   if (r == nullptr)
4268     return;
4269   memset(&opl, '\0', sizeof(struct objc_property_list64));
4270   if (left < sizeof(struct objc_property_list64)) {
4271     memcpy(&opl, r, left);
4272     outs() << "   (objc_property_list entends past the end of the section)\n";
4273   } else
4274     memcpy(&opl, r, sizeof(struct objc_property_list64));
4275   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4276     swapStruct(opl);
4277   outs() << "                    entsize " << opl.entsize << "\n";
4278   outs() << "                      count " << opl.count << "\n";
4279 
4280   p += sizeof(struct objc_property_list64);
4281   offset += sizeof(struct objc_property_list64);
4282   for (j = 0; j < opl.count; j++) {
4283     r = get_pointer_64(p, offset, left, S, info);
4284     if (r == nullptr)
4285       return;
4286     memset(&op, '\0', sizeof(struct objc_property64));
4287     if (left < sizeof(struct objc_property64)) {
4288       memcpy(&op, r, left);
4289       outs() << "   (objc_property entends past the end of the section)\n";
4290     } else
4291       memcpy(&op, r, sizeof(struct objc_property64));
4292     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4293       swapStruct(op);
4294 
4295     outs() << "\t\t\t     name ";
4296     sym_name = get_symbol_64(offset + offsetof(struct objc_property64, name), S,
4297                              info, n_value, op.name);
4298     if (n_value != 0) {
4299       if (info->verbose && sym_name != nullptr)
4300         outs() << sym_name;
4301       else
4302         outs() << format("0x%" PRIx64, n_value);
4303       if (op.name != 0)
4304         outs() << " + " << format("0x%" PRIx64, op.name);
4305     } else
4306       outs() << format("0x%" PRIx64, op.name);
4307     name = get_pointer_64(op.name + n_value, xoffset, left, xS, info);
4308     if (name != nullptr)
4309       outs() << format(" %.*s", left, name);
4310     outs() << "\n";
4311 
4312     outs() << "\t\t\tattributes ";
4313     sym_name =
4314         get_symbol_64(offset + offsetof(struct objc_property64, attributes), S,
4315                       info, n_value, op.attributes);
4316     if (n_value != 0) {
4317       if (info->verbose && sym_name != nullptr)
4318         outs() << sym_name;
4319       else
4320         outs() << format("0x%" PRIx64, n_value);
4321       if (op.attributes != 0)
4322         outs() << " + " << format("0x%" PRIx64, op.attributes);
4323     } else
4324       outs() << format("0x%" PRIx64, op.attributes);
4325     name = get_pointer_64(op.attributes + n_value, xoffset, left, xS, info);
4326     if (name != nullptr)
4327       outs() << format(" %.*s", left, name);
4328     outs() << "\n";
4329 
4330     p += sizeof(struct objc_property64);
4331     offset += sizeof(struct objc_property64);
4332   }
4333 }
4334 
4335 static void print_objc_property_list32(uint32_t p,
4336                                        struct DisassembleInfo *info) {
4337   struct objc_property_list32 opl;
4338   struct objc_property32 op;
4339   const char *r;
4340   uint32_t offset, xoffset, left, j;
4341   SectionRef S, xS;
4342   const char *name;
4343 
4344   r = get_pointer_32(p, offset, left, S, info);
4345   if (r == nullptr)
4346     return;
4347   memset(&opl, '\0', sizeof(struct objc_property_list32));
4348   if (left < sizeof(struct objc_property_list32)) {
4349     memcpy(&opl, r, left);
4350     outs() << "   (objc_property_list entends past the end of the section)\n";
4351   } else
4352     memcpy(&opl, r, sizeof(struct objc_property_list32));
4353   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4354     swapStruct(opl);
4355   outs() << "                    entsize " << opl.entsize << "\n";
4356   outs() << "                      count " << opl.count << "\n";
4357 
4358   p += sizeof(struct objc_property_list32);
4359   offset += sizeof(struct objc_property_list32);
4360   for (j = 0; j < opl.count; j++) {
4361     r = get_pointer_32(p, offset, left, S, info);
4362     if (r == nullptr)
4363       return;
4364     memset(&op, '\0', sizeof(struct objc_property32));
4365     if (left < sizeof(struct objc_property32)) {
4366       memcpy(&op, r, left);
4367       outs() << "   (objc_property entends past the end of the section)\n";
4368     } else
4369       memcpy(&op, r, sizeof(struct objc_property32));
4370     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4371       swapStruct(op);
4372 
4373     outs() << "\t\t\t     name " << format("0x%" PRIx32, op.name);
4374     name = get_pointer_32(op.name, xoffset, left, xS, info);
4375     if (name != nullptr)
4376       outs() << format(" %.*s", left, name);
4377     outs() << "\n";
4378 
4379     outs() << "\t\t\tattributes " << format("0x%" PRIx32, op.attributes);
4380     name = get_pointer_32(op.attributes, xoffset, left, xS, info);
4381     if (name != nullptr)
4382       outs() << format(" %.*s", left, name);
4383     outs() << "\n";
4384 
4385     p += sizeof(struct objc_property32);
4386     offset += sizeof(struct objc_property32);
4387   }
4388 }
4389 
4390 static bool print_class_ro64_t(uint64_t p, struct DisassembleInfo *info,
4391                                bool &is_meta_class) {
4392   struct class_ro64_t cro;
4393   const char *r;
4394   uint32_t offset, xoffset, left;
4395   SectionRef S, xS;
4396   const char *name, *sym_name;
4397   uint64_t n_value;
4398 
4399   r = get_pointer_64(p, offset, left, S, info);
4400   if (r == nullptr || left < sizeof(struct class_ro64_t))
4401     return false;
4402   memcpy(&cro, r, sizeof(struct class_ro64_t));
4403   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4404     swapStruct(cro);
4405   outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
4406   if (cro.flags & RO_META)
4407     outs() << " RO_META";
4408   if (cro.flags & RO_ROOT)
4409     outs() << " RO_ROOT";
4410   if (cro.flags & RO_HAS_CXX_STRUCTORS)
4411     outs() << " RO_HAS_CXX_STRUCTORS";
4412   outs() << "\n";
4413   outs() << "            instanceStart " << cro.instanceStart << "\n";
4414   outs() << "             instanceSize " << cro.instanceSize << "\n";
4415   outs() << "                 reserved " << format("0x%" PRIx32, cro.reserved)
4416          << "\n";
4417   outs() << "               ivarLayout " << format("0x%" PRIx64, cro.ivarLayout)
4418          << "\n";
4419   print_layout_map64(cro.ivarLayout, info);
4420 
4421   outs() << "                     name ";
4422   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, name), S,
4423                            info, n_value, cro.name);
4424   if (n_value != 0) {
4425     if (info->verbose && sym_name != nullptr)
4426       outs() << sym_name;
4427     else
4428       outs() << format("0x%" PRIx64, n_value);
4429     if (cro.name != 0)
4430       outs() << " + " << format("0x%" PRIx64, cro.name);
4431   } else
4432     outs() << format("0x%" PRIx64, cro.name);
4433   name = get_pointer_64(cro.name + n_value, xoffset, left, xS, info);
4434   if (name != nullptr)
4435     outs() << format(" %.*s", left, name);
4436   outs() << "\n";
4437 
4438   outs() << "              baseMethods ";
4439   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, baseMethods),
4440                            S, info, n_value, cro.baseMethods);
4441   if (n_value != 0) {
4442     if (info->verbose && sym_name != nullptr)
4443       outs() << sym_name;
4444     else
4445       outs() << format("0x%" PRIx64, n_value);
4446     if (cro.baseMethods != 0)
4447       outs() << " + " << format("0x%" PRIx64, cro.baseMethods);
4448   } else
4449     outs() << format("0x%" PRIx64, cro.baseMethods);
4450   outs() << " (struct method_list_t *)\n";
4451   if (cro.baseMethods + n_value != 0)
4452     print_method_list64_t(cro.baseMethods + n_value, info, "");
4453 
4454   outs() << "            baseProtocols ";
4455   sym_name =
4456       get_symbol_64(offset + offsetof(struct class_ro64_t, baseProtocols), S,
4457                     info, n_value, cro.baseProtocols);
4458   if (n_value != 0) {
4459     if (info->verbose && sym_name != nullptr)
4460       outs() << sym_name;
4461     else
4462       outs() << format("0x%" PRIx64, n_value);
4463     if (cro.baseProtocols != 0)
4464       outs() << " + " << format("0x%" PRIx64, cro.baseProtocols);
4465   } else
4466     outs() << format("0x%" PRIx64, cro.baseProtocols);
4467   outs() << "\n";
4468   if (cro.baseProtocols + n_value != 0)
4469     print_protocol_list64_t(cro.baseProtocols + n_value, info);
4470 
4471   outs() << "                    ivars ";
4472   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, ivars), S,
4473                            info, n_value, cro.ivars);
4474   if (n_value != 0) {
4475     if (info->verbose && sym_name != nullptr)
4476       outs() << sym_name;
4477     else
4478       outs() << format("0x%" PRIx64, n_value);
4479     if (cro.ivars != 0)
4480       outs() << " + " << format("0x%" PRIx64, cro.ivars);
4481   } else
4482     outs() << format("0x%" PRIx64, cro.ivars);
4483   outs() << "\n";
4484   if (cro.ivars + n_value != 0)
4485     print_ivar_list64_t(cro.ivars + n_value, info);
4486 
4487   outs() << "           weakIvarLayout ";
4488   sym_name =
4489       get_symbol_64(offset + offsetof(struct class_ro64_t, weakIvarLayout), S,
4490                     info, n_value, cro.weakIvarLayout);
4491   if (n_value != 0) {
4492     if (info->verbose && sym_name != nullptr)
4493       outs() << sym_name;
4494     else
4495       outs() << format("0x%" PRIx64, n_value);
4496     if (cro.weakIvarLayout != 0)
4497       outs() << " + " << format("0x%" PRIx64, cro.weakIvarLayout);
4498   } else
4499     outs() << format("0x%" PRIx64, cro.weakIvarLayout);
4500   outs() << "\n";
4501   print_layout_map64(cro.weakIvarLayout + n_value, info);
4502 
4503   outs() << "           baseProperties ";
4504   sym_name =
4505       get_symbol_64(offset + offsetof(struct class_ro64_t, baseProperties), S,
4506                     info, n_value, cro.baseProperties);
4507   if (n_value != 0) {
4508     if (info->verbose && sym_name != nullptr)
4509       outs() << sym_name;
4510     else
4511       outs() << format("0x%" PRIx64, n_value);
4512     if (cro.baseProperties != 0)
4513       outs() << " + " << format("0x%" PRIx64, cro.baseProperties);
4514   } else
4515     outs() << format("0x%" PRIx64, cro.baseProperties);
4516   outs() << "\n";
4517   if (cro.baseProperties + n_value != 0)
4518     print_objc_property_list64(cro.baseProperties + n_value, info);
4519 
4520   is_meta_class = (cro.flags & RO_META) != 0;
4521   return true;
4522 }
4523 
4524 static bool print_class_ro32_t(uint32_t p, struct DisassembleInfo *info,
4525                                bool &is_meta_class) {
4526   struct class_ro32_t cro;
4527   const char *r;
4528   uint32_t offset, xoffset, left;
4529   SectionRef S, xS;
4530   const char *name;
4531 
4532   r = get_pointer_32(p, offset, left, S, info);
4533   if (r == nullptr)
4534     return false;
4535   memset(&cro, '\0', sizeof(struct class_ro32_t));
4536   if (left < sizeof(struct class_ro32_t)) {
4537     memcpy(&cro, r, left);
4538     outs() << "   (class_ro_t entends past the end of the section)\n";
4539   } else
4540     memcpy(&cro, r, sizeof(struct class_ro32_t));
4541   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4542     swapStruct(cro);
4543   outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
4544   if (cro.flags & RO_META)
4545     outs() << " RO_META";
4546   if (cro.flags & RO_ROOT)
4547     outs() << " RO_ROOT";
4548   if (cro.flags & RO_HAS_CXX_STRUCTORS)
4549     outs() << " RO_HAS_CXX_STRUCTORS";
4550   outs() << "\n";
4551   outs() << "            instanceStart " << cro.instanceStart << "\n";
4552   outs() << "             instanceSize " << cro.instanceSize << "\n";
4553   outs() << "               ivarLayout " << format("0x%" PRIx32, cro.ivarLayout)
4554          << "\n";
4555   print_layout_map32(cro.ivarLayout, info);
4556 
4557   outs() << "                     name " << format("0x%" PRIx32, cro.name);
4558   name = get_pointer_32(cro.name, xoffset, left, xS, info);
4559   if (name != nullptr)
4560     outs() << format(" %.*s", left, name);
4561   outs() << "\n";
4562 
4563   outs() << "              baseMethods "
4564          << format("0x%" PRIx32, cro.baseMethods)
4565          << " (struct method_list_t *)\n";
4566   if (cro.baseMethods != 0)
4567     print_method_list32_t(cro.baseMethods, info, "");
4568 
4569   outs() << "            baseProtocols "
4570          << format("0x%" PRIx32, cro.baseProtocols) << "\n";
4571   if (cro.baseProtocols != 0)
4572     print_protocol_list32_t(cro.baseProtocols, info);
4573   outs() << "                    ivars " << format("0x%" PRIx32, cro.ivars)
4574          << "\n";
4575   if (cro.ivars != 0)
4576     print_ivar_list32_t(cro.ivars, info);
4577   outs() << "           weakIvarLayout "
4578          << format("0x%" PRIx32, cro.weakIvarLayout) << "\n";
4579   print_layout_map32(cro.weakIvarLayout, info);
4580   outs() << "           baseProperties "
4581          << format("0x%" PRIx32, cro.baseProperties) << "\n";
4582   if (cro.baseProperties != 0)
4583     print_objc_property_list32(cro.baseProperties, info);
4584   is_meta_class = (cro.flags & RO_META) != 0;
4585   return true;
4586 }
4587 
4588 static void print_class64_t(uint64_t p, struct DisassembleInfo *info) {
4589   struct class64_t c;
4590   const char *r;
4591   uint32_t offset, left;
4592   SectionRef S;
4593   const char *name;
4594   uint64_t isa_n_value, n_value;
4595 
4596   r = get_pointer_64(p, offset, left, S, info);
4597   if (r == nullptr || left < sizeof(struct class64_t))
4598     return;
4599   memcpy(&c, r, sizeof(struct class64_t));
4600   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4601     swapStruct(c);
4602 
4603   outs() << "           isa " << format("0x%" PRIx64, c.isa);
4604   name = get_symbol_64(offset + offsetof(struct class64_t, isa), S, info,
4605                        isa_n_value, c.isa);
4606   if (name != nullptr)
4607     outs() << " " << name;
4608   outs() << "\n";
4609 
4610   outs() << "    superclass " << format("0x%" PRIx64, c.superclass);
4611   name = get_symbol_64(offset + offsetof(struct class64_t, superclass), S, info,
4612                        n_value, c.superclass);
4613   if (name != nullptr)
4614     outs() << " " << name;
4615   else {
4616     name = get_dyld_bind_info_symbolname(S.getAddress() +
4617              offset + offsetof(struct class64_t, superclass), info);
4618     if (name != nullptr)
4619       outs() << " " << name;
4620   }
4621   outs() << "\n";
4622 
4623   outs() << "         cache " << format("0x%" PRIx64, c.cache);
4624   name = get_symbol_64(offset + offsetof(struct class64_t, cache), S, info,
4625                        n_value, c.cache);
4626   if (name != nullptr)
4627     outs() << " " << name;
4628   outs() << "\n";
4629 
4630   outs() << "        vtable " << format("0x%" PRIx64, c.vtable);
4631   name = get_symbol_64(offset + offsetof(struct class64_t, vtable), S, info,
4632                        n_value, c.vtable);
4633   if (name != nullptr)
4634     outs() << " " << name;
4635   outs() << "\n";
4636 
4637   name = get_symbol_64(offset + offsetof(struct class64_t, data), S, info,
4638                        n_value, c.data);
4639   outs() << "          data ";
4640   if (n_value != 0) {
4641     if (info->verbose && name != nullptr)
4642       outs() << name;
4643     else
4644       outs() << format("0x%" PRIx64, n_value);
4645     if (c.data != 0)
4646       outs() << " + " << format("0x%" PRIx64, c.data);
4647   } else
4648     outs() << format("0x%" PRIx64, c.data);
4649   outs() << " (struct class_ro_t *)";
4650 
4651   // This is a Swift class if some of the low bits of the pointer are set.
4652   if ((c.data + n_value) & 0x7)
4653     outs() << " Swift class";
4654   outs() << "\n";
4655   bool is_meta_class;
4656   if (!print_class_ro64_t((c.data + n_value) & ~0x7, info, is_meta_class))
4657     return;
4658 
4659   if (!is_meta_class &&
4660       c.isa + isa_n_value != p &&
4661       c.isa + isa_n_value != 0 &&
4662       info->depth < 100) {
4663       info->depth++;
4664       outs() << "Meta Class\n";
4665       print_class64_t(c.isa + isa_n_value, info);
4666   }
4667 }
4668 
4669 static void print_class32_t(uint32_t p, struct DisassembleInfo *info) {
4670   struct class32_t c;
4671   const char *r;
4672   uint32_t offset, left;
4673   SectionRef S;
4674   const char *name;
4675 
4676   r = get_pointer_32(p, offset, left, S, info);
4677   if (r == nullptr)
4678     return;
4679   memset(&c, '\0', sizeof(struct class32_t));
4680   if (left < sizeof(struct class32_t)) {
4681     memcpy(&c, r, left);
4682     outs() << "   (class_t entends past the end of the section)\n";
4683   } else
4684     memcpy(&c, r, sizeof(struct class32_t));
4685   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4686     swapStruct(c);
4687 
4688   outs() << "           isa " << format("0x%" PRIx32, c.isa);
4689   name =
4690       get_symbol_32(offset + offsetof(struct class32_t, isa), S, info, c.isa);
4691   if (name != nullptr)
4692     outs() << " " << name;
4693   outs() << "\n";
4694 
4695   outs() << "    superclass " << format("0x%" PRIx32, c.superclass);
4696   name = get_symbol_32(offset + offsetof(struct class32_t, superclass), S, info,
4697                        c.superclass);
4698   if (name != nullptr)
4699     outs() << " " << name;
4700   outs() << "\n";
4701 
4702   outs() << "         cache " << format("0x%" PRIx32, c.cache);
4703   name = get_symbol_32(offset + offsetof(struct class32_t, cache), S, info,
4704                        c.cache);
4705   if (name != nullptr)
4706     outs() << " " << name;
4707   outs() << "\n";
4708 
4709   outs() << "        vtable " << format("0x%" PRIx32, c.vtable);
4710   name = get_symbol_32(offset + offsetof(struct class32_t, vtable), S, info,
4711                        c.vtable);
4712   if (name != nullptr)
4713     outs() << " " << name;
4714   outs() << "\n";
4715 
4716   name =
4717       get_symbol_32(offset + offsetof(struct class32_t, data), S, info, c.data);
4718   outs() << "          data " << format("0x%" PRIx32, c.data)
4719          << " (struct class_ro_t *)";
4720 
4721   // This is a Swift class if some of the low bits of the pointer are set.
4722   if (c.data & 0x3)
4723     outs() << " Swift class";
4724   outs() << "\n";
4725   bool is_meta_class;
4726   if (!print_class_ro32_t(c.data & ~0x3, info, is_meta_class))
4727     return;
4728 
4729   if (!is_meta_class) {
4730     outs() << "Meta Class\n";
4731     print_class32_t(c.isa, info);
4732   }
4733 }
4734 
4735 static void print_objc_class_t(struct objc_class_t *objc_class,
4736                                struct DisassembleInfo *info) {
4737   uint32_t offset, left, xleft;
4738   const char *name, *p, *ivar_list;
4739   SectionRef S;
4740   int32_t i;
4741   struct objc_ivar_list_t objc_ivar_list;
4742   struct objc_ivar_t ivar;
4743 
4744   outs() << "\t\t      isa " << format("0x%08" PRIx32, objc_class->isa);
4745   if (info->verbose && CLS_GETINFO(objc_class, CLS_META)) {
4746     name = get_pointer_32(objc_class->isa, offset, left, S, info, true);
4747     if (name != nullptr)
4748       outs() << format(" %.*s", left, name);
4749     else
4750       outs() << " (not in an __OBJC section)";
4751   }
4752   outs() << "\n";
4753 
4754   outs() << "\t      super_class "
4755          << format("0x%08" PRIx32, objc_class->super_class);
4756   if (info->verbose) {
4757     name = get_pointer_32(objc_class->super_class, offset, left, S, info, true);
4758     if (name != nullptr)
4759       outs() << format(" %.*s", left, name);
4760     else
4761       outs() << " (not in an __OBJC section)";
4762   }
4763   outs() << "\n";
4764 
4765   outs() << "\t\t     name " << format("0x%08" PRIx32, objc_class->name);
4766   if (info->verbose) {
4767     name = get_pointer_32(objc_class->name, offset, left, S, info, true);
4768     if (name != nullptr)
4769       outs() << format(" %.*s", left, name);
4770     else
4771       outs() << " (not in an __OBJC section)";
4772   }
4773   outs() << "\n";
4774 
4775   outs() << "\t\t  version " << format("0x%08" PRIx32, objc_class->version)
4776          << "\n";
4777 
4778   outs() << "\t\t     info " << format("0x%08" PRIx32, objc_class->info);
4779   if (info->verbose) {
4780     if (CLS_GETINFO(objc_class, CLS_CLASS))
4781       outs() << " CLS_CLASS";
4782     else if (CLS_GETINFO(objc_class, CLS_META))
4783       outs() << " CLS_META";
4784   }
4785   outs() << "\n";
4786 
4787   outs() << "\t    instance_size "
4788          << format("0x%08" PRIx32, objc_class->instance_size) << "\n";
4789 
4790   p = get_pointer_32(objc_class->ivars, offset, left, S, info, true);
4791   outs() << "\t\t    ivars " << format("0x%08" PRIx32, objc_class->ivars);
4792   if (p != nullptr) {
4793     if (left > sizeof(struct objc_ivar_list_t)) {
4794       outs() << "\n";
4795       memcpy(&objc_ivar_list, p, sizeof(struct objc_ivar_list_t));
4796     } else {
4797       outs() << " (entends past the end of the section)\n";
4798       memset(&objc_ivar_list, '\0', sizeof(struct objc_ivar_list_t));
4799       memcpy(&objc_ivar_list, p, left);
4800     }
4801     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4802       swapStruct(objc_ivar_list);
4803     outs() << "\t\t       ivar_count " << objc_ivar_list.ivar_count << "\n";
4804     ivar_list = p + sizeof(struct objc_ivar_list_t);
4805     for (i = 0; i < objc_ivar_list.ivar_count; i++) {
4806       if ((i + 1) * sizeof(struct objc_ivar_t) > left) {
4807         outs() << "\t\t remaining ivar's extend past the of the section\n";
4808         break;
4809       }
4810       memcpy(&ivar, ivar_list + i * sizeof(struct objc_ivar_t),
4811              sizeof(struct objc_ivar_t));
4812       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4813         swapStruct(ivar);
4814 
4815       outs() << "\t\t\tivar_name " << format("0x%08" PRIx32, ivar.ivar_name);
4816       if (info->verbose) {
4817         name = get_pointer_32(ivar.ivar_name, offset, xleft, S, info, true);
4818         if (name != nullptr)
4819           outs() << format(" %.*s", xleft, name);
4820         else
4821           outs() << " (not in an __OBJC section)";
4822       }
4823       outs() << "\n";
4824 
4825       outs() << "\t\t\tivar_type " << format("0x%08" PRIx32, ivar.ivar_type);
4826       if (info->verbose) {
4827         name = get_pointer_32(ivar.ivar_type, offset, xleft, S, info, true);
4828         if (name != nullptr)
4829           outs() << format(" %.*s", xleft, name);
4830         else
4831           outs() << " (not in an __OBJC section)";
4832       }
4833       outs() << "\n";
4834 
4835       outs() << "\t\t      ivar_offset "
4836              << format("0x%08" PRIx32, ivar.ivar_offset) << "\n";
4837     }
4838   } else {
4839     outs() << " (not in an __OBJC section)\n";
4840   }
4841 
4842   outs() << "\t\t  methods " << format("0x%08" PRIx32, objc_class->methodLists);
4843   if (print_method_list(objc_class->methodLists, info))
4844     outs() << " (not in an __OBJC section)\n";
4845 
4846   outs() << "\t\t    cache " << format("0x%08" PRIx32, objc_class->cache)
4847          << "\n";
4848 
4849   outs() << "\t\tprotocols " << format("0x%08" PRIx32, objc_class->protocols);
4850   if (print_protocol_list(objc_class->protocols, 16, info))
4851     outs() << " (not in an __OBJC section)\n";
4852 }
4853 
4854 static void print_objc_objc_category_t(struct objc_category_t *objc_category,
4855                                        struct DisassembleInfo *info) {
4856   uint32_t offset, left;
4857   const char *name;
4858   SectionRef S;
4859 
4860   outs() << "\t       category name "
4861          << format("0x%08" PRIx32, objc_category->category_name);
4862   if (info->verbose) {
4863     name = get_pointer_32(objc_category->category_name, offset, left, S, info,
4864                           true);
4865     if (name != nullptr)
4866       outs() << format(" %.*s", left, name);
4867     else
4868       outs() << " (not in an __OBJC section)";
4869   }
4870   outs() << "\n";
4871 
4872   outs() << "\t\t  class name "
4873          << format("0x%08" PRIx32, objc_category->class_name);
4874   if (info->verbose) {
4875     name =
4876         get_pointer_32(objc_category->class_name, offset, left, S, info, true);
4877     if (name != nullptr)
4878       outs() << format(" %.*s", left, name);
4879     else
4880       outs() << " (not in an __OBJC section)";
4881   }
4882   outs() << "\n";
4883 
4884   outs() << "\t    instance methods "
4885          << format("0x%08" PRIx32, objc_category->instance_methods);
4886   if (print_method_list(objc_category->instance_methods, info))
4887     outs() << " (not in an __OBJC section)\n";
4888 
4889   outs() << "\t       class methods "
4890          << format("0x%08" PRIx32, objc_category->class_methods);
4891   if (print_method_list(objc_category->class_methods, info))
4892     outs() << " (not in an __OBJC section)\n";
4893 }
4894 
4895 static void print_category64_t(uint64_t p, struct DisassembleInfo *info) {
4896   struct category64_t c;
4897   const char *r;
4898   uint32_t offset, xoffset, left;
4899   SectionRef S, xS;
4900   const char *name, *sym_name;
4901   uint64_t n_value;
4902 
4903   r = get_pointer_64(p, offset, left, S, info);
4904   if (r == nullptr)
4905     return;
4906   memset(&c, '\0', sizeof(struct category64_t));
4907   if (left < sizeof(struct category64_t)) {
4908     memcpy(&c, r, left);
4909     outs() << "   (category_t entends past the end of the section)\n";
4910   } else
4911     memcpy(&c, r, sizeof(struct category64_t));
4912   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4913     swapStruct(c);
4914 
4915   outs() << "              name ";
4916   sym_name = get_symbol_64(offset + offsetof(struct category64_t, name), S,
4917                            info, n_value, c.name);
4918   if (n_value != 0) {
4919     if (info->verbose && sym_name != nullptr)
4920       outs() << sym_name;
4921     else
4922       outs() << format("0x%" PRIx64, n_value);
4923     if (c.name != 0)
4924       outs() << " + " << format("0x%" PRIx64, c.name);
4925   } else
4926     outs() << format("0x%" PRIx64, c.name);
4927   name = get_pointer_64(c.name + n_value, xoffset, left, xS, info);
4928   if (name != nullptr)
4929     outs() << format(" %.*s", left, name);
4930   outs() << "\n";
4931 
4932   outs() << "               cls ";
4933   sym_name = get_symbol_64(offset + offsetof(struct category64_t, cls), S, info,
4934                            n_value, c.cls);
4935   if (n_value != 0) {
4936     if (info->verbose && sym_name != nullptr)
4937       outs() << sym_name;
4938     else
4939       outs() << format("0x%" PRIx64, n_value);
4940     if (c.cls != 0)
4941       outs() << " + " << format("0x%" PRIx64, c.cls);
4942   } else
4943     outs() << format("0x%" PRIx64, c.cls);
4944   outs() << "\n";
4945   if (c.cls + n_value != 0)
4946     print_class64_t(c.cls + n_value, info);
4947 
4948   outs() << "   instanceMethods ";
4949   sym_name =
4950       get_symbol_64(offset + offsetof(struct category64_t, instanceMethods), S,
4951                     info, n_value, c.instanceMethods);
4952   if (n_value != 0) {
4953     if (info->verbose && sym_name != nullptr)
4954       outs() << sym_name;
4955     else
4956       outs() << format("0x%" PRIx64, n_value);
4957     if (c.instanceMethods != 0)
4958       outs() << " + " << format("0x%" PRIx64, c.instanceMethods);
4959   } else
4960     outs() << format("0x%" PRIx64, c.instanceMethods);
4961   outs() << "\n";
4962   if (c.instanceMethods + n_value != 0)
4963     print_method_list64_t(c.instanceMethods + n_value, info, "");
4964 
4965   outs() << "      classMethods ";
4966   sym_name = get_symbol_64(offset + offsetof(struct category64_t, classMethods),
4967                            S, info, n_value, c.classMethods);
4968   if (n_value != 0) {
4969     if (info->verbose && sym_name != nullptr)
4970       outs() << sym_name;
4971     else
4972       outs() << format("0x%" PRIx64, n_value);
4973     if (c.classMethods != 0)
4974       outs() << " + " << format("0x%" PRIx64, c.classMethods);
4975   } else
4976     outs() << format("0x%" PRIx64, c.classMethods);
4977   outs() << "\n";
4978   if (c.classMethods + n_value != 0)
4979     print_method_list64_t(c.classMethods + n_value, info, "");
4980 
4981   outs() << "         protocols ";
4982   sym_name = get_symbol_64(offset + offsetof(struct category64_t, protocols), S,
4983                            info, n_value, c.protocols);
4984   if (n_value != 0) {
4985     if (info->verbose && sym_name != nullptr)
4986       outs() << sym_name;
4987     else
4988       outs() << format("0x%" PRIx64, n_value);
4989     if (c.protocols != 0)
4990       outs() << " + " << format("0x%" PRIx64, c.protocols);
4991   } else
4992     outs() << format("0x%" PRIx64, c.protocols);
4993   outs() << "\n";
4994   if (c.protocols + n_value != 0)
4995     print_protocol_list64_t(c.protocols + n_value, info);
4996 
4997   outs() << "instanceProperties ";
4998   sym_name =
4999       get_symbol_64(offset + offsetof(struct category64_t, instanceProperties),
5000                     S, info, n_value, c.instanceProperties);
5001   if (n_value != 0) {
5002     if (info->verbose && sym_name != nullptr)
5003       outs() << sym_name;
5004     else
5005       outs() << format("0x%" PRIx64, n_value);
5006     if (c.instanceProperties != 0)
5007       outs() << " + " << format("0x%" PRIx64, c.instanceProperties);
5008   } else
5009     outs() << format("0x%" PRIx64, c.instanceProperties);
5010   outs() << "\n";
5011   if (c.instanceProperties + n_value != 0)
5012     print_objc_property_list64(c.instanceProperties + n_value, info);
5013 }
5014 
5015 static void print_category32_t(uint32_t p, struct DisassembleInfo *info) {
5016   struct category32_t c;
5017   const char *r;
5018   uint32_t offset, left;
5019   SectionRef S, xS;
5020   const char *name;
5021 
5022   r = get_pointer_32(p, offset, left, S, info);
5023   if (r == nullptr)
5024     return;
5025   memset(&c, '\0', sizeof(struct category32_t));
5026   if (left < sizeof(struct category32_t)) {
5027     memcpy(&c, r, left);
5028     outs() << "   (category_t entends past the end of the section)\n";
5029   } else
5030     memcpy(&c, r, sizeof(struct category32_t));
5031   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5032     swapStruct(c);
5033 
5034   outs() << "              name " << format("0x%" PRIx32, c.name);
5035   name = get_symbol_32(offset + offsetof(struct category32_t, name), S, info,
5036                        c.name);
5037   if (name)
5038     outs() << " " << name;
5039   outs() << "\n";
5040 
5041   outs() << "               cls " << format("0x%" PRIx32, c.cls) << "\n";
5042   if (c.cls != 0)
5043     print_class32_t(c.cls, info);
5044   outs() << "   instanceMethods " << format("0x%" PRIx32, c.instanceMethods)
5045          << "\n";
5046   if (c.instanceMethods != 0)
5047     print_method_list32_t(c.instanceMethods, info, "");
5048   outs() << "      classMethods " << format("0x%" PRIx32, c.classMethods)
5049          << "\n";
5050   if (c.classMethods != 0)
5051     print_method_list32_t(c.classMethods, info, "");
5052   outs() << "         protocols " << format("0x%" PRIx32, c.protocols) << "\n";
5053   if (c.protocols != 0)
5054     print_protocol_list32_t(c.protocols, info);
5055   outs() << "instanceProperties " << format("0x%" PRIx32, c.instanceProperties)
5056          << "\n";
5057   if (c.instanceProperties != 0)
5058     print_objc_property_list32(c.instanceProperties, info);
5059 }
5060 
5061 static void print_message_refs64(SectionRef S, struct DisassembleInfo *info) {
5062   uint32_t i, left, offset, xoffset;
5063   uint64_t p, n_value;
5064   struct message_ref64 mr;
5065   const char *name, *sym_name;
5066   const char *r;
5067   SectionRef xS;
5068 
5069   if (S == SectionRef())
5070     return;
5071 
5072   StringRef SectName;
5073   S.getName(SectName);
5074   DataRefImpl Ref = S.getRawDataRefImpl();
5075   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5076   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5077   offset = 0;
5078   for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
5079     p = S.getAddress() + i;
5080     r = get_pointer_64(p, offset, left, S, info);
5081     if (r == nullptr)
5082       return;
5083     memset(&mr, '\0', sizeof(struct message_ref64));
5084     if (left < sizeof(struct message_ref64)) {
5085       memcpy(&mr, r, left);
5086       outs() << "   (message_ref entends past the end of the section)\n";
5087     } else
5088       memcpy(&mr, r, sizeof(struct message_ref64));
5089     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5090       swapStruct(mr);
5091 
5092     outs() << "  imp ";
5093     name = get_symbol_64(offset + offsetof(struct message_ref64, imp), S, info,
5094                          n_value, mr.imp);
5095     if (n_value != 0) {
5096       outs() << format("0x%" PRIx64, n_value) << " ";
5097       if (mr.imp != 0)
5098         outs() << "+ " << format("0x%" PRIx64, mr.imp) << " ";
5099     } else
5100       outs() << format("0x%" PRIx64, mr.imp) << " ";
5101     if (name != nullptr)
5102       outs() << " " << name;
5103     outs() << "\n";
5104 
5105     outs() << "  sel ";
5106     sym_name = get_symbol_64(offset + offsetof(struct message_ref64, sel), S,
5107                              info, n_value, mr.sel);
5108     if (n_value != 0) {
5109       if (info->verbose && sym_name != nullptr)
5110         outs() << sym_name;
5111       else
5112         outs() << format("0x%" PRIx64, n_value);
5113       if (mr.sel != 0)
5114         outs() << " + " << format("0x%" PRIx64, mr.sel);
5115     } else
5116       outs() << format("0x%" PRIx64, mr.sel);
5117     name = get_pointer_64(mr.sel + n_value, xoffset, left, xS, info);
5118     if (name != nullptr)
5119       outs() << format(" %.*s", left, name);
5120     outs() << "\n";
5121 
5122     offset += sizeof(struct message_ref64);
5123   }
5124 }
5125 
5126 static void print_message_refs32(SectionRef S, struct DisassembleInfo *info) {
5127   uint32_t i, left, offset, xoffset, p;
5128   struct message_ref32 mr;
5129   const char *name, *r;
5130   SectionRef xS;
5131 
5132   if (S == SectionRef())
5133     return;
5134 
5135   StringRef SectName;
5136   S.getName(SectName);
5137   DataRefImpl Ref = S.getRawDataRefImpl();
5138   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5139   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5140   offset = 0;
5141   for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
5142     p = S.getAddress() + i;
5143     r = get_pointer_32(p, offset, left, S, info);
5144     if (r == nullptr)
5145       return;
5146     memset(&mr, '\0', sizeof(struct message_ref32));
5147     if (left < sizeof(struct message_ref32)) {
5148       memcpy(&mr, r, left);
5149       outs() << "   (message_ref entends past the end of the section)\n";
5150     } else
5151       memcpy(&mr, r, sizeof(struct message_ref32));
5152     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5153       swapStruct(mr);
5154 
5155     outs() << "  imp " << format("0x%" PRIx32, mr.imp);
5156     name = get_symbol_32(offset + offsetof(struct message_ref32, imp), S, info,
5157                          mr.imp);
5158     if (name != nullptr)
5159       outs() << " " << name;
5160     outs() << "\n";
5161 
5162     outs() << "  sel " << format("0x%" PRIx32, mr.sel);
5163     name = get_pointer_32(mr.sel, xoffset, left, xS, info);
5164     if (name != nullptr)
5165       outs() << " " << name;
5166     outs() << "\n";
5167 
5168     offset += sizeof(struct message_ref32);
5169   }
5170 }
5171 
5172 static void print_image_info64(SectionRef S, struct DisassembleInfo *info) {
5173   uint32_t left, offset, swift_version;
5174   uint64_t p;
5175   struct objc_image_info64 o;
5176   const char *r;
5177 
5178   if (S == SectionRef())
5179     return;
5180 
5181   StringRef SectName;
5182   S.getName(SectName);
5183   DataRefImpl Ref = S.getRawDataRefImpl();
5184   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5185   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5186   p = S.getAddress();
5187   r = get_pointer_64(p, offset, left, S, info);
5188   if (r == nullptr)
5189     return;
5190   memset(&o, '\0', sizeof(struct objc_image_info64));
5191   if (left < sizeof(struct objc_image_info64)) {
5192     memcpy(&o, r, left);
5193     outs() << "   (objc_image_info entends past the end of the section)\n";
5194   } else
5195     memcpy(&o, r, sizeof(struct objc_image_info64));
5196   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5197     swapStruct(o);
5198   outs() << "  version " << o.version << "\n";
5199   outs() << "    flags " << format("0x%" PRIx32, o.flags);
5200   if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
5201     outs() << " OBJC_IMAGE_IS_REPLACEMENT";
5202   if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
5203     outs() << " OBJC_IMAGE_SUPPORTS_GC";
5204   swift_version = (o.flags >> 8) & 0xff;
5205   if (swift_version != 0) {
5206     if (swift_version == 1)
5207       outs() << " Swift 1.0";
5208     else if (swift_version == 2)
5209       outs() << " Swift 1.1";
5210     else
5211       outs() << " unknown future Swift version (" << swift_version << ")";
5212   }
5213   outs() << "\n";
5214 }
5215 
5216 static void print_image_info32(SectionRef S, struct DisassembleInfo *info) {
5217   uint32_t left, offset, swift_version, p;
5218   struct objc_image_info32 o;
5219   const char *r;
5220 
5221   if (S == SectionRef())
5222     return;
5223 
5224   StringRef SectName;
5225   S.getName(SectName);
5226   DataRefImpl Ref = S.getRawDataRefImpl();
5227   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5228   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5229   p = S.getAddress();
5230   r = get_pointer_32(p, offset, left, S, info);
5231   if (r == nullptr)
5232     return;
5233   memset(&o, '\0', sizeof(struct objc_image_info32));
5234   if (left < sizeof(struct objc_image_info32)) {
5235     memcpy(&o, r, left);
5236     outs() << "   (objc_image_info entends past the end of the section)\n";
5237   } else
5238     memcpy(&o, r, sizeof(struct objc_image_info32));
5239   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5240     swapStruct(o);
5241   outs() << "  version " << o.version << "\n";
5242   outs() << "    flags " << format("0x%" PRIx32, o.flags);
5243   if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
5244     outs() << " OBJC_IMAGE_IS_REPLACEMENT";
5245   if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
5246     outs() << " OBJC_IMAGE_SUPPORTS_GC";
5247   swift_version = (o.flags >> 8) & 0xff;
5248   if (swift_version != 0) {
5249     if (swift_version == 1)
5250       outs() << " Swift 1.0";
5251     else if (swift_version == 2)
5252       outs() << " Swift 1.1";
5253     else
5254       outs() << " unknown future Swift version (" << swift_version << ")";
5255   }
5256   outs() << "\n";
5257 }
5258 
5259 static void print_image_info(SectionRef S, struct DisassembleInfo *info) {
5260   uint32_t left, offset, p;
5261   struct imageInfo_t o;
5262   const char *r;
5263 
5264   StringRef SectName;
5265   S.getName(SectName);
5266   DataRefImpl Ref = S.getRawDataRefImpl();
5267   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5268   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5269   p = S.getAddress();
5270   r = get_pointer_32(p, offset, left, S, info);
5271   if (r == nullptr)
5272     return;
5273   memset(&o, '\0', sizeof(struct imageInfo_t));
5274   if (left < sizeof(struct imageInfo_t)) {
5275     memcpy(&o, r, left);
5276     outs() << " (imageInfo entends past the end of the section)\n";
5277   } else
5278     memcpy(&o, r, sizeof(struct imageInfo_t));
5279   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5280     swapStruct(o);
5281   outs() << "  version " << o.version << "\n";
5282   outs() << "    flags " << format("0x%" PRIx32, o.flags);
5283   if (o.flags & 0x1)
5284     outs() << "  F&C";
5285   if (o.flags & 0x2)
5286     outs() << " GC";
5287   if (o.flags & 0x4)
5288     outs() << " GC-only";
5289   else
5290     outs() << " RR";
5291   outs() << "\n";
5292 }
5293 
5294 static void printObjc2_64bit_MetaData(MachOObjectFile *O, bool verbose) {
5295   SymbolAddressMap AddrMap;
5296   if (verbose)
5297     CreateSymbolAddressMap(O, &AddrMap);
5298 
5299   std::vector<SectionRef> Sections;
5300   for (const SectionRef &Section : O->sections()) {
5301     StringRef SectName;
5302     Section.getName(SectName);
5303     Sections.push_back(Section);
5304   }
5305 
5306   struct DisassembleInfo info;
5307   // Set up the block of info used by the Symbolizer call backs.
5308   info.verbose = verbose;
5309   info.O = O;
5310   info.AddrMap = &AddrMap;
5311   info.Sections = &Sections;
5312   info.class_name = nullptr;
5313   info.selector_name = nullptr;
5314   info.method = nullptr;
5315   info.demangled_name = nullptr;
5316   info.bindtable = nullptr;
5317   info.adrp_addr = 0;
5318   info.adrp_inst = 0;
5319 
5320   info.depth = 0;
5321   SectionRef CL = get_section(O, "__OBJC2", "__class_list");
5322   if (CL == SectionRef())
5323     CL = get_section(O, "__DATA", "__objc_classlist");
5324   if (CL == SectionRef())
5325     CL = get_section(O, "__DATA_CONST", "__objc_classlist");
5326   if (CL == SectionRef())
5327     CL = get_section(O, "__DATA_DIRTY", "__objc_classlist");
5328   info.S = CL;
5329   walk_pointer_list_64("class", CL, O, &info, print_class64_t);
5330 
5331   SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
5332   if (CR == SectionRef())
5333     CR = get_section(O, "__DATA", "__objc_classrefs");
5334   if (CR == SectionRef())
5335     CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
5336   if (CR == SectionRef())
5337     CR = get_section(O, "__DATA_DIRTY", "__objc_classrefs");
5338   info.S = CR;
5339   walk_pointer_list_64("class refs", CR, O, &info, nullptr);
5340 
5341   SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
5342   if (SR == SectionRef())
5343     SR = get_section(O, "__DATA", "__objc_superrefs");
5344   if (SR == SectionRef())
5345     SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
5346   if (SR == SectionRef())
5347     SR = get_section(O, "__DATA_DIRTY", "__objc_superrefs");
5348   info.S = SR;
5349   walk_pointer_list_64("super refs", SR, O, &info, nullptr);
5350 
5351   SectionRef CA = get_section(O, "__OBJC2", "__category_list");
5352   if (CA == SectionRef())
5353     CA = get_section(O, "__DATA", "__objc_catlist");
5354   if (CA == SectionRef())
5355     CA = get_section(O, "__DATA_CONST", "__objc_catlist");
5356   if (CA == SectionRef())
5357     CA = get_section(O, "__DATA_DIRTY", "__objc_catlist");
5358   info.S = CA;
5359   walk_pointer_list_64("category", CA, O, &info, print_category64_t);
5360 
5361   SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
5362   if (PL == SectionRef())
5363     PL = get_section(O, "__DATA", "__objc_protolist");
5364   if (PL == SectionRef())
5365     PL = get_section(O, "__DATA_CONST", "__objc_protolist");
5366   if (PL == SectionRef())
5367     PL = get_section(O, "__DATA_DIRTY", "__objc_protolist");
5368   info.S = PL;
5369   walk_pointer_list_64("protocol", PL, O, &info, nullptr);
5370 
5371   SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
5372   if (MR == SectionRef())
5373     MR = get_section(O, "__DATA", "__objc_msgrefs");
5374   if (MR == SectionRef())
5375     MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
5376   if (MR == SectionRef())
5377     MR = get_section(O, "__DATA_DIRTY", "__objc_msgrefs");
5378   info.S = MR;
5379   print_message_refs64(MR, &info);
5380 
5381   SectionRef II = get_section(O, "__OBJC2", "__image_info");
5382   if (II == SectionRef())
5383     II = get_section(O, "__DATA", "__objc_imageinfo");
5384   if (II == SectionRef())
5385     II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
5386   if (II == SectionRef())
5387     II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
5388   info.S = II;
5389   print_image_info64(II, &info);
5390 }
5391 
5392 static void printObjc2_32bit_MetaData(MachOObjectFile *O, bool verbose) {
5393   SymbolAddressMap AddrMap;
5394   if (verbose)
5395     CreateSymbolAddressMap(O, &AddrMap);
5396 
5397   std::vector<SectionRef> Sections;
5398   for (const SectionRef &Section : O->sections()) {
5399     StringRef SectName;
5400     Section.getName(SectName);
5401     Sections.push_back(Section);
5402   }
5403 
5404   struct DisassembleInfo info;
5405   // Set up the block of info used by the Symbolizer call backs.
5406   info.verbose = verbose;
5407   info.O = O;
5408   info.AddrMap = &AddrMap;
5409   info.Sections = &Sections;
5410   info.class_name = nullptr;
5411   info.selector_name = nullptr;
5412   info.method = nullptr;
5413   info.demangled_name = nullptr;
5414   info.bindtable = nullptr;
5415   info.adrp_addr = 0;
5416   info.adrp_inst = 0;
5417 
5418   SectionRef CL = get_section(O, "__OBJC2", "__class_list");
5419   if (CL == SectionRef())
5420     CL = get_section(O, "__DATA", "__objc_classlist");
5421   if (CL == SectionRef())
5422     CL = get_section(O, "__DATA_CONST", "__objc_classlist");
5423   if (CL == SectionRef())
5424     CL = get_section(O, "__DATA_DIRTY", "__objc_classlist");
5425   info.S = CL;
5426   walk_pointer_list_32("class", CL, O, &info, print_class32_t);
5427 
5428   SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
5429   if (CR == SectionRef())
5430     CR = get_section(O, "__DATA", "__objc_classrefs");
5431   if (CR == SectionRef())
5432     CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
5433   if (CR == SectionRef())
5434     CR = get_section(O, "__DATA_DIRTY", "__objc_classrefs");
5435   info.S = CR;
5436   walk_pointer_list_32("class refs", CR, O, &info, nullptr);
5437 
5438   SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
5439   if (SR == SectionRef())
5440     SR = get_section(O, "__DATA", "__objc_superrefs");
5441   if (SR == SectionRef())
5442     SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
5443   if (SR == SectionRef())
5444     SR = get_section(O, "__DATA_DIRTY", "__objc_superrefs");
5445   info.S = SR;
5446   walk_pointer_list_32("super refs", SR, O, &info, nullptr);
5447 
5448   SectionRef CA = get_section(O, "__OBJC2", "__category_list");
5449   if (CA == SectionRef())
5450     CA = get_section(O, "__DATA", "__objc_catlist");
5451   if (CA == SectionRef())
5452     CA = get_section(O, "__DATA_CONST", "__objc_catlist");
5453   if (CA == SectionRef())
5454     CA = get_section(O, "__DATA_DIRTY", "__objc_catlist");
5455   info.S = CA;
5456   walk_pointer_list_32("category", CA, O, &info, print_category32_t);
5457 
5458   SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
5459   if (PL == SectionRef())
5460     PL = get_section(O, "__DATA", "__objc_protolist");
5461   if (PL == SectionRef())
5462     PL = get_section(O, "__DATA_CONST", "__objc_protolist");
5463   if (PL == SectionRef())
5464     PL = get_section(O, "__DATA_DIRTY", "__objc_protolist");
5465   info.S = PL;
5466   walk_pointer_list_32("protocol", PL, O, &info, nullptr);
5467 
5468   SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
5469   if (MR == SectionRef())
5470     MR = get_section(O, "__DATA", "__objc_msgrefs");
5471   if (MR == SectionRef())
5472     MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
5473   if (MR == SectionRef())
5474     MR = get_section(O, "__DATA_DIRTY", "__objc_msgrefs");
5475   info.S = MR;
5476   print_message_refs32(MR, &info);
5477 
5478   SectionRef II = get_section(O, "__OBJC2", "__image_info");
5479   if (II == SectionRef())
5480     II = get_section(O, "__DATA", "__objc_imageinfo");
5481   if (II == SectionRef())
5482     II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
5483   if (II == SectionRef())
5484     II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
5485   info.S = II;
5486   print_image_info32(II, &info);
5487 }
5488 
5489 static bool printObjc1_32bit_MetaData(MachOObjectFile *O, bool verbose) {
5490   uint32_t i, j, p, offset, xoffset, left, defs_left, def;
5491   const char *r, *name, *defs;
5492   struct objc_module_t module;
5493   SectionRef S, xS;
5494   struct objc_symtab_t symtab;
5495   struct objc_class_t objc_class;
5496   struct objc_category_t objc_category;
5497 
5498   outs() << "Objective-C segment\n";
5499   S = get_section(O, "__OBJC", "__module_info");
5500   if (S == SectionRef())
5501     return false;
5502 
5503   SymbolAddressMap AddrMap;
5504   if (verbose)
5505     CreateSymbolAddressMap(O, &AddrMap);
5506 
5507   std::vector<SectionRef> Sections;
5508   for (const SectionRef &Section : O->sections()) {
5509     StringRef SectName;
5510     Section.getName(SectName);
5511     Sections.push_back(Section);
5512   }
5513 
5514   struct DisassembleInfo info;
5515   // Set up the block of info used by the Symbolizer call backs.
5516   info.verbose = verbose;
5517   info.O = O;
5518   info.AddrMap = &AddrMap;
5519   info.Sections = &Sections;
5520   info.class_name = nullptr;
5521   info.selector_name = nullptr;
5522   info.method = nullptr;
5523   info.demangled_name = nullptr;
5524   info.bindtable = nullptr;
5525   info.adrp_addr = 0;
5526   info.adrp_inst = 0;
5527 
5528   for (i = 0; i < S.getSize(); i += sizeof(struct objc_module_t)) {
5529     p = S.getAddress() + i;
5530     r = get_pointer_32(p, offset, left, S, &info, true);
5531     if (r == nullptr)
5532       return true;
5533     memset(&module, '\0', sizeof(struct objc_module_t));
5534     if (left < sizeof(struct objc_module_t)) {
5535       memcpy(&module, r, left);
5536       outs() << "   (module extends past end of __module_info section)\n";
5537     } else
5538       memcpy(&module, r, sizeof(struct objc_module_t));
5539     if (O->isLittleEndian() != sys::IsLittleEndianHost)
5540       swapStruct(module);
5541 
5542     outs() << "Module " << format("0x%" PRIx32, p) << "\n";
5543     outs() << "    version " << module.version << "\n";
5544     outs() << "       size " << module.size << "\n";
5545     outs() << "       name ";
5546     name = get_pointer_32(module.name, xoffset, left, xS, &info, true);
5547     if (name != nullptr)
5548       outs() << format("%.*s", left, name);
5549     else
5550       outs() << format("0x%08" PRIx32, module.name)
5551              << "(not in an __OBJC section)";
5552     outs() << "\n";
5553 
5554     r = get_pointer_32(module.symtab, xoffset, left, xS, &info, true);
5555     if (module.symtab == 0 || r == nullptr) {
5556       outs() << "     symtab " << format("0x%08" PRIx32, module.symtab)
5557              << " (not in an __OBJC section)\n";
5558       continue;
5559     }
5560     outs() << "     symtab " << format("0x%08" PRIx32, module.symtab) << "\n";
5561     memset(&symtab, '\0', sizeof(struct objc_symtab_t));
5562     defs_left = 0;
5563     defs = nullptr;
5564     if (left < sizeof(struct objc_symtab_t)) {
5565       memcpy(&symtab, r, left);
5566       outs() << "\tsymtab extends past end of an __OBJC section)\n";
5567     } else {
5568       memcpy(&symtab, r, sizeof(struct objc_symtab_t));
5569       if (left > sizeof(struct objc_symtab_t)) {
5570         defs_left = left - sizeof(struct objc_symtab_t);
5571         defs = r + sizeof(struct objc_symtab_t);
5572       }
5573     }
5574     if (O->isLittleEndian() != sys::IsLittleEndianHost)
5575       swapStruct(symtab);
5576 
5577     outs() << "\tsel_ref_cnt " << symtab.sel_ref_cnt << "\n";
5578     r = get_pointer_32(symtab.refs, xoffset, left, xS, &info, true);
5579     outs() << "\trefs " << format("0x%08" PRIx32, symtab.refs);
5580     if (r == nullptr)
5581       outs() << " (not in an __OBJC section)";
5582     outs() << "\n";
5583     outs() << "\tcls_def_cnt " << symtab.cls_def_cnt << "\n";
5584     outs() << "\tcat_def_cnt " << symtab.cat_def_cnt << "\n";
5585     if (symtab.cls_def_cnt > 0)
5586       outs() << "\tClass Definitions\n";
5587     for (j = 0; j < symtab.cls_def_cnt; j++) {
5588       if ((j + 1) * sizeof(uint32_t) > defs_left) {
5589         outs() << "\t(remaining class defs entries entends past the end of the "
5590                << "section)\n";
5591         break;
5592       }
5593       memcpy(&def, defs + j * sizeof(uint32_t), sizeof(uint32_t));
5594       if (O->isLittleEndian() != sys::IsLittleEndianHost)
5595         sys::swapByteOrder(def);
5596 
5597       r = get_pointer_32(def, xoffset, left, xS, &info, true);
5598       outs() << "\tdefs[" << j << "] " << format("0x%08" PRIx32, def);
5599       if (r != nullptr) {
5600         if (left > sizeof(struct objc_class_t)) {
5601           outs() << "\n";
5602           memcpy(&objc_class, r, sizeof(struct objc_class_t));
5603         } else {
5604           outs() << " (entends past the end of the section)\n";
5605           memset(&objc_class, '\0', sizeof(struct objc_class_t));
5606           memcpy(&objc_class, r, left);
5607         }
5608         if (O->isLittleEndian() != sys::IsLittleEndianHost)
5609           swapStruct(objc_class);
5610         print_objc_class_t(&objc_class, &info);
5611       } else {
5612         outs() << "(not in an __OBJC section)\n";
5613       }
5614 
5615       if (CLS_GETINFO(&objc_class, CLS_CLASS)) {
5616         outs() << "\tMeta Class";
5617         r = get_pointer_32(objc_class.isa, xoffset, left, xS, &info, true);
5618         if (r != nullptr) {
5619           if (left > sizeof(struct objc_class_t)) {
5620             outs() << "\n";
5621             memcpy(&objc_class, r, sizeof(struct objc_class_t));
5622           } else {
5623             outs() << " (entends past the end of the section)\n";
5624             memset(&objc_class, '\0', sizeof(struct objc_class_t));
5625             memcpy(&objc_class, r, left);
5626           }
5627           if (O->isLittleEndian() != sys::IsLittleEndianHost)
5628             swapStruct(objc_class);
5629           print_objc_class_t(&objc_class, &info);
5630         } else {
5631           outs() << "(not in an __OBJC section)\n";
5632         }
5633       }
5634     }
5635     if (symtab.cat_def_cnt > 0)
5636       outs() << "\tCategory Definitions\n";
5637     for (j = 0; j < symtab.cat_def_cnt; j++) {
5638       if ((j + symtab.cls_def_cnt + 1) * sizeof(uint32_t) > defs_left) {
5639         outs() << "\t(remaining category defs entries entends past the end of "
5640                << "the section)\n";
5641         break;
5642       }
5643       memcpy(&def, defs + (j + symtab.cls_def_cnt) * sizeof(uint32_t),
5644              sizeof(uint32_t));
5645       if (O->isLittleEndian() != sys::IsLittleEndianHost)
5646         sys::swapByteOrder(def);
5647 
5648       r = get_pointer_32(def, xoffset, left, xS, &info, true);
5649       outs() << "\tdefs[" << j + symtab.cls_def_cnt << "] "
5650              << format("0x%08" PRIx32, def);
5651       if (r != nullptr) {
5652         if (left > sizeof(struct objc_category_t)) {
5653           outs() << "\n";
5654           memcpy(&objc_category, r, sizeof(struct objc_category_t));
5655         } else {
5656           outs() << " (entends past the end of the section)\n";
5657           memset(&objc_category, '\0', sizeof(struct objc_category_t));
5658           memcpy(&objc_category, r, left);
5659         }
5660         if (O->isLittleEndian() != sys::IsLittleEndianHost)
5661           swapStruct(objc_category);
5662         print_objc_objc_category_t(&objc_category, &info);
5663       } else {
5664         outs() << "(not in an __OBJC section)\n";
5665       }
5666     }
5667   }
5668   const SectionRef II = get_section(O, "__OBJC", "__image_info");
5669   if (II != SectionRef())
5670     print_image_info(II, &info);
5671 
5672   return true;
5673 }
5674 
5675 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,
5676                                 uint32_t size, uint32_t addr) {
5677   SymbolAddressMap AddrMap;
5678   CreateSymbolAddressMap(O, &AddrMap);
5679 
5680   std::vector<SectionRef> Sections;
5681   for (const SectionRef &Section : O->sections()) {
5682     StringRef SectName;
5683     Section.getName(SectName);
5684     Sections.push_back(Section);
5685   }
5686 
5687   struct DisassembleInfo info;
5688   // Set up the block of info used by the Symbolizer call backs.
5689   info.verbose = true;
5690   info.O = O;
5691   info.AddrMap = &AddrMap;
5692   info.Sections = &Sections;
5693   info.class_name = nullptr;
5694   info.selector_name = nullptr;
5695   info.method = nullptr;
5696   info.demangled_name = nullptr;
5697   info.bindtable = nullptr;
5698   info.adrp_addr = 0;
5699   info.adrp_inst = 0;
5700 
5701   const char *p;
5702   struct objc_protocol_t protocol;
5703   uint32_t left, paddr;
5704   for (p = sect; p < sect + size; p += sizeof(struct objc_protocol_t)) {
5705     memset(&protocol, '\0', sizeof(struct objc_protocol_t));
5706     left = size - (p - sect);
5707     if (left < sizeof(struct objc_protocol_t)) {
5708       outs() << "Protocol extends past end of __protocol section\n";
5709       memcpy(&protocol, p, left);
5710     } else
5711       memcpy(&protocol, p, sizeof(struct objc_protocol_t));
5712     if (O->isLittleEndian() != sys::IsLittleEndianHost)
5713       swapStruct(protocol);
5714     paddr = addr + (p - sect);
5715     outs() << "Protocol " << format("0x%" PRIx32, paddr);
5716     if (print_protocol(paddr, 0, &info))
5717       outs() << "(not in an __OBJC section)\n";
5718   }
5719 }
5720 
5721 #ifdef HAVE_LIBXAR
5722 inline void swapStruct(struct xar_header &xar) {
5723   sys::swapByteOrder(xar.magic);
5724   sys::swapByteOrder(xar.size);
5725   sys::swapByteOrder(xar.version);
5726   sys::swapByteOrder(xar.toc_length_compressed);
5727   sys::swapByteOrder(xar.toc_length_uncompressed);
5728   sys::swapByteOrder(xar.cksum_alg);
5729 }
5730 
5731 static void PrintModeVerbose(uint32_t mode) {
5732   switch(mode & S_IFMT){
5733   case S_IFDIR:
5734     outs() << "d";
5735     break;
5736   case S_IFCHR:
5737     outs() << "c";
5738     break;
5739   case S_IFBLK:
5740     outs() << "b";
5741     break;
5742   case S_IFREG:
5743     outs() << "-";
5744     break;
5745   case S_IFLNK:
5746     outs() << "l";
5747     break;
5748   case S_IFSOCK:
5749     outs() << "s";
5750     break;
5751   default:
5752     outs() << "?";
5753     break;
5754   }
5755 
5756   /* owner permissions */
5757   if(mode & S_IREAD)
5758     outs() << "r";
5759   else
5760     outs() << "-";
5761   if(mode & S_IWRITE)
5762     outs() << "w";
5763   else
5764     outs() << "-";
5765   if(mode & S_ISUID)
5766     outs() << "s";
5767   else if(mode & S_IEXEC)
5768     outs() << "x";
5769   else
5770     outs() << "-";
5771 
5772   /* group permissions */
5773   if(mode & (S_IREAD >> 3))
5774     outs() << "r";
5775   else
5776     outs() << "-";
5777   if(mode & (S_IWRITE >> 3))
5778     outs() << "w";
5779   else
5780     outs() << "-";
5781   if(mode & S_ISGID)
5782     outs() << "s";
5783   else if(mode & (S_IEXEC >> 3))
5784     outs() << "x";
5785   else
5786     outs() << "-";
5787 
5788   /* other permissions */
5789   if(mode & (S_IREAD >> 6))
5790     outs() << "r";
5791   else
5792     outs() << "-";
5793   if(mode & (S_IWRITE >> 6))
5794     outs() << "w";
5795   else
5796     outs() << "-";
5797   if(mode & S_ISVTX)
5798     outs() << "t";
5799   else if(mode & (S_IEXEC >> 6))
5800     outs() << "x";
5801   else
5802     outs() << "-";
5803 }
5804 
5805 static void PrintXarFilesSummary(const char *XarFilename, xar_t xar) {
5806   xar_iter_t xi;
5807   xar_file_t xf;
5808   xar_iter_t xp;
5809   const char *key, *type, *mode, *user, *group, *size, *mtime, *name, *m;
5810   char *endp;
5811   uint32_t mode_value;
5812 
5813   xi = xar_iter_new();
5814   if (!xi) {
5815     errs() << "Can't obtain an xar iterator for xar archive "
5816            << XarFilename << "\n";
5817     return;
5818   }
5819 
5820   // Go through the xar's files.
5821   for (xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)) {
5822     xp = xar_iter_new();
5823     if(!xp){
5824       errs() << "Can't obtain an xar iterator for xar archive "
5825              << XarFilename << "\n";
5826       return;
5827     }
5828     type = nullptr;
5829     mode = nullptr;
5830     user = nullptr;
5831     group = nullptr;
5832     size = nullptr;
5833     mtime = nullptr;
5834     name = nullptr;
5835     for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
5836       const char *val = nullptr;
5837       xar_prop_get(xf, key, &val);
5838 #if 0 // Useful for debugging.
5839       outs() << "key: " << key << " value: " << val << "\n";
5840 #endif
5841       if(strcmp(key, "type") == 0)
5842         type = val;
5843       if(strcmp(key, "mode") == 0)
5844         mode = val;
5845       if(strcmp(key, "user") == 0)
5846         user = val;
5847       if(strcmp(key, "group") == 0)
5848         group = val;
5849       if(strcmp(key, "data/size") == 0)
5850         size = val;
5851       if(strcmp(key, "mtime") == 0)
5852         mtime = val;
5853       if(strcmp(key, "name") == 0)
5854         name = val;
5855     }
5856     if(mode != nullptr){
5857       mode_value = strtoul(mode, &endp, 8);
5858       if(*endp != '\0')
5859         outs() << "(mode: \"" << mode << "\" contains non-octal chars) ";
5860       if(strcmp(type, "file") == 0)
5861         mode_value |= S_IFREG;
5862       PrintModeVerbose(mode_value);
5863       outs() << " ";
5864     }
5865     if(user != nullptr)
5866       outs() << format("%10s/", user);
5867     if(group != nullptr)
5868       outs() << format("%-10s ", group);
5869     if(size != nullptr)
5870       outs() << format("%7s ", size);
5871     if(mtime != nullptr){
5872       for(m = mtime; *m != 'T' && *m != '\0'; m++)
5873         outs() << *m;
5874       if(*m == 'T')
5875         m++;
5876       outs() << " ";
5877       for( ; *m != 'Z' && *m != '\0'; m++)
5878         outs() << *m;
5879       outs() << " ";
5880     }
5881     if(name != nullptr)
5882       outs() << name;
5883     outs() << "\n";
5884     xar_iter_free(xp);
5885   }
5886   xar_iter_free(xi);
5887 }
5888 
5889 static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
5890                                 uint32_t size, bool verbose,
5891                                 bool PrintXarHeader, bool PrintXarFileHeaders,
5892                                 std::string XarMemberName) {
5893   if(size < sizeof(struct xar_header)) {
5894     outs() << "size of (__LLVM,__bundle) section too small (smaller than size "
5895               "of struct xar_header)\n";
5896     return;
5897   }
5898   struct xar_header XarHeader;
5899   memcpy(&XarHeader, sect, sizeof(struct xar_header));
5900   if (sys::IsLittleEndianHost)
5901     swapStruct(XarHeader);
5902   if (PrintXarHeader) {
5903     if (!XarMemberName.empty())
5904       outs() << "In xar member " << XarMemberName << ": ";
5905     else
5906       outs() << "For (__LLVM,__bundle) section: ";
5907     outs() << "xar header\n";
5908     if (XarHeader.magic == XAR_HEADER_MAGIC)
5909       outs() << "                  magic XAR_HEADER_MAGIC\n";
5910     else
5911       outs() << "                  magic "
5912              << format_hex(XarHeader.magic, 10, true)
5913              << " (not XAR_HEADER_MAGIC)\n";
5914     outs() << "                   size " << XarHeader.size << "\n";
5915     outs() << "                version " << XarHeader.version << "\n";
5916     outs() << "  toc_length_compressed " << XarHeader.toc_length_compressed
5917            << "\n";
5918     outs() << "toc_length_uncompressed " << XarHeader.toc_length_uncompressed
5919            << "\n";
5920     outs() << "              cksum_alg ";
5921     switch (XarHeader.cksum_alg) {
5922       case XAR_CKSUM_NONE:
5923         outs() << "XAR_CKSUM_NONE\n";
5924         break;
5925       case XAR_CKSUM_SHA1:
5926         outs() << "XAR_CKSUM_SHA1\n";
5927         break;
5928       case XAR_CKSUM_MD5:
5929         outs() << "XAR_CKSUM_MD5\n";
5930         break;
5931 #ifdef XAR_CKSUM_SHA256
5932       case XAR_CKSUM_SHA256:
5933         outs() << "XAR_CKSUM_SHA256\n";
5934         break;
5935 #endif
5936 #ifdef XAR_CKSUM_SHA512
5937       case XAR_CKSUM_SHA512:
5938         outs() << "XAR_CKSUM_SHA512\n";
5939         break;
5940 #endif
5941       default:
5942         outs() << XarHeader.cksum_alg << "\n";
5943     }
5944   }
5945 
5946   SmallString<128> XarFilename;
5947   int FD;
5948   std::error_code XarEC =
5949       sys::fs::createTemporaryFile("llvm-objdump", "xar", FD, XarFilename);
5950   if (XarEC) {
5951     errs() << XarEC.message() << "\n";
5952     return;
5953   }
5954   tool_output_file XarFile(XarFilename, FD);
5955   raw_fd_ostream &XarOut = XarFile.os();
5956   StringRef XarContents(sect, size);
5957   XarOut << XarContents;
5958   XarOut.close();
5959   if (XarOut.has_error())
5960     return;
5961 
5962   xar_t xar = xar_open(XarFilename.c_str(), READ);
5963   if (!xar) {
5964     errs() << "Can't create temporary xar archive " << XarFilename << "\n";
5965     return;
5966   }
5967 
5968   SmallString<128> TocFilename;
5969   std::error_code TocEC =
5970       sys::fs::createTemporaryFile("llvm-objdump", "toc", TocFilename);
5971   if (TocEC) {
5972     errs() << TocEC.message() << "\n";
5973     return;
5974   }
5975   xar_serialize(xar, TocFilename.c_str());
5976 
5977   if (PrintXarFileHeaders) {
5978     if (!XarMemberName.empty())
5979       outs() << "In xar member " << XarMemberName << ": ";
5980     else
5981       outs() << "For (__LLVM,__bundle) section: ";
5982     outs() << "xar archive files:\n";
5983     PrintXarFilesSummary(XarFilename.c_str(), xar);
5984   }
5985 
5986   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
5987     MemoryBuffer::getFileOrSTDIN(TocFilename.c_str());
5988   if (std::error_code EC = FileOrErr.getError()) {
5989     errs() << EC.message() << "\n";
5990     return;
5991   }
5992   std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
5993 
5994   if (!XarMemberName.empty())
5995     outs() << "In xar member " << XarMemberName << ": ";
5996   else
5997     outs() << "For (__LLVM,__bundle) section: ";
5998   outs() << "xar table of contents:\n";
5999   outs() << Buffer->getBuffer() << "\n";
6000 
6001   // TODO: Go through the xar's files.
6002   xar_iter_t xi = xar_iter_new();
6003   if(!xi){
6004     errs() << "Can't obtain an xar iterator for xar archive "
6005            << XarFilename.c_str() << "\n";
6006     xar_close(xar);
6007     return;
6008   }
6009   for(xar_file_t xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)){
6010     const char *key;
6011     xar_iter_t xp;
6012     const char *member_name, *member_type, *member_size_string;
6013     size_t member_size;
6014 
6015     xp = xar_iter_new();
6016     if(!xp){
6017       errs() << "Can't obtain an xar iterator for xar archive "
6018              << XarFilename.c_str() << "\n";
6019       xar_close(xar);
6020       return;
6021     }
6022     member_name = NULL;
6023     member_type = NULL;
6024     member_size_string = NULL;
6025     for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
6026       const char *val = nullptr;
6027       xar_prop_get(xf, key, &val);
6028 #if 0 // Useful for debugging.
6029       outs() << "key: " << key << " value: " << val << "\n";
6030 #endif
6031       if (strcmp(key, "name") == 0)
6032         member_name = val;
6033       if (strcmp(key, "type") == 0)
6034         member_type = val;
6035       if (strcmp(key, "data/size") == 0)
6036         member_size_string = val;
6037     }
6038     /*
6039      * If we find a file with a name, date/size and type properties
6040      * and with the type being "file" see if that is a xar file.
6041      */
6042     if (member_name != NULL && member_type != NULL &&
6043         strcmp(member_type, "file") == 0 &&
6044         member_size_string != NULL){
6045       // Extract the file into a buffer.
6046       char *endptr;
6047       member_size = strtoul(member_size_string, &endptr, 10);
6048       if (*endptr == '\0' && member_size != 0) {
6049         char *buffer;
6050         if (xar_extract_tobuffersz(xar, xf, &buffer, &member_size) == 0) {
6051 #if 0 // Useful for debugging.
6052 	  outs() << "xar member: " << member_name << " extracted\n";
6053 #endif
6054           // Set the XarMemberName we want to see printed in the header.
6055           std::string OldXarMemberName;
6056           // If XarMemberName is already set this is nested. So
6057           // save the old name and create the nested name.
6058           if (!XarMemberName.empty()) {
6059             OldXarMemberName = XarMemberName;
6060             XarMemberName =
6061                 (Twine("[") + XarMemberName + "]" + member_name).str();
6062           } else {
6063             OldXarMemberName = "";
6064             XarMemberName = member_name;
6065           }
6066           // See if this is could be a xar file (nested).
6067           if (member_size >= sizeof(struct xar_header)) {
6068 #if 0 // Useful for debugging.
6069 	    outs() << "could be a xar file: " << member_name << "\n";
6070 #endif
6071             memcpy((char *)&XarHeader, buffer, sizeof(struct xar_header));
6072             if (sys::IsLittleEndianHost)
6073               swapStruct(XarHeader);
6074             if (XarHeader.magic == XAR_HEADER_MAGIC)
6075               DumpBitcodeSection(O, buffer, member_size, verbose,
6076                                  PrintXarHeader, PrintXarFileHeaders,
6077                                  XarMemberName);
6078           }
6079           XarMemberName = OldXarMemberName;
6080           delete buffer;
6081         }
6082       }
6083     }
6084     xar_iter_free(xp);
6085   }
6086   xar_iter_free(xi);
6087   xar_close(xar);
6088 }
6089 #endif // defined(HAVE_LIBXAR)
6090 
6091 static void printObjcMetaData(MachOObjectFile *O, bool verbose) {
6092   if (O->is64Bit())
6093     printObjc2_64bit_MetaData(O, verbose);
6094   else {
6095     MachO::mach_header H;
6096     H = O->getHeader();
6097     if (H.cputype == MachO::CPU_TYPE_ARM)
6098       printObjc2_32bit_MetaData(O, verbose);
6099     else {
6100       // This is the 32-bit non-arm cputype case.  Which is normally
6101       // the first Objective-C ABI.  But it may be the case of a
6102       // binary for the iOS simulator which is the second Objective-C
6103       // ABI.  In that case printObjc1_32bit_MetaData() will determine that
6104       // and return false.
6105       if (!printObjc1_32bit_MetaData(O, verbose))
6106         printObjc2_32bit_MetaData(O, verbose);
6107     }
6108   }
6109 }
6110 
6111 // GuessLiteralPointer returns a string which for the item in the Mach-O file
6112 // for the address passed in as ReferenceValue for printing as a comment with
6113 // the instruction and also returns the corresponding type of that item
6114 // indirectly through ReferenceType.
6115 //
6116 // If ReferenceValue is an address of literal cstring then a pointer to the
6117 // cstring is returned and ReferenceType is set to
6118 // LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr .
6119 //
6120 // If ReferenceValue is an address of an Objective-C CFString, Selector ref or
6121 // Class ref that name is returned and the ReferenceType is set accordingly.
6122 //
6123 // Lastly, literals which are Symbol address in a literal pool are looked for
6124 // and if found the symbol name is returned and ReferenceType is set to
6125 // LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr .
6126 //
6127 // If there is no item in the Mach-O file for the address passed in as
6128 // ReferenceValue nullptr is returned and ReferenceType is unchanged.
6129 static const char *GuessLiteralPointer(uint64_t ReferenceValue,
6130                                        uint64_t ReferencePC,
6131                                        uint64_t *ReferenceType,
6132                                        struct DisassembleInfo *info) {
6133   // First see if there is an external relocation entry at the ReferencePC.
6134   if (info->O->getHeader().filetype == MachO::MH_OBJECT) {
6135     uint64_t sect_addr = info->S.getAddress();
6136     uint64_t sect_offset = ReferencePC - sect_addr;
6137     bool reloc_found = false;
6138     DataRefImpl Rel;
6139     MachO::any_relocation_info RE;
6140     bool isExtern = false;
6141     SymbolRef Symbol;
6142     for (const RelocationRef &Reloc : info->S.relocations()) {
6143       uint64_t RelocOffset = Reloc.getOffset();
6144       if (RelocOffset == sect_offset) {
6145         Rel = Reloc.getRawDataRefImpl();
6146         RE = info->O->getRelocation(Rel);
6147         if (info->O->isRelocationScattered(RE))
6148           continue;
6149         isExtern = info->O->getPlainRelocationExternal(RE);
6150         if (isExtern) {
6151           symbol_iterator RelocSym = Reloc.getSymbol();
6152           Symbol = *RelocSym;
6153         }
6154         reloc_found = true;
6155         break;
6156       }
6157     }
6158     // If there is an external relocation entry for a symbol in a section
6159     // then used that symbol's value for the value of the reference.
6160     if (reloc_found && isExtern) {
6161       if (info->O->getAnyRelocationPCRel(RE)) {
6162         unsigned Type = info->O->getAnyRelocationType(RE);
6163         if (Type == MachO::X86_64_RELOC_SIGNED) {
6164           ReferenceValue = Symbol.getValue();
6165         }
6166       }
6167     }
6168   }
6169 
6170   // Look for literals such as Objective-C CFStrings refs, Selector refs,
6171   // Message refs and Class refs.
6172   bool classref, selref, msgref, cfstring;
6173   uint64_t pointer_value = GuessPointerPointer(ReferenceValue, info, classref,
6174                                                selref, msgref, cfstring);
6175   if (classref && pointer_value == 0) {
6176     // Note the ReferenceValue is a pointer into the __objc_classrefs section.
6177     // And the pointer_value in that section is typically zero as it will be
6178     // set by dyld as part of the "bind information".
6179     const char *name = get_dyld_bind_info_symbolname(ReferenceValue, info);
6180     if (name != nullptr) {
6181       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
6182       const char *class_name = strrchr(name, '$');
6183       if (class_name != nullptr && class_name[1] == '_' &&
6184           class_name[2] != '\0') {
6185         info->class_name = class_name + 2;
6186         return name;
6187       }
6188     }
6189   }
6190 
6191   if (classref) {
6192     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
6193     const char *name =
6194         get_objc2_64bit_class_name(pointer_value, ReferenceValue, info);
6195     if (name != nullptr)
6196       info->class_name = name;
6197     else
6198       name = "bad class ref";
6199     return name;
6200   }
6201 
6202   if (cfstring) {
6203     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref;
6204     const char *name = get_objc2_64bit_cfstring_name(ReferenceValue, info);
6205     return name;
6206   }
6207 
6208   if (selref && pointer_value == 0)
6209     pointer_value = get_objc2_64bit_selref(ReferenceValue, info);
6210 
6211   if (pointer_value != 0)
6212     ReferenceValue = pointer_value;
6213 
6214   const char *name = GuessCstringPointer(ReferenceValue, info);
6215   if (name) {
6216     if (pointer_value != 0 && selref) {
6217       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref;
6218       info->selector_name = name;
6219     } else if (pointer_value != 0 && msgref) {
6220       info->class_name = nullptr;
6221       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref;
6222       info->selector_name = name;
6223     } else
6224       *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr;
6225     return name;
6226   }
6227 
6228   // Lastly look for an indirect symbol with this ReferenceValue which is in
6229   // a literal pool.  If found return that symbol name.
6230   name = GuessIndirectSymbol(ReferenceValue, info);
6231   if (name) {
6232     *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr;
6233     return name;
6234   }
6235 
6236   return nullptr;
6237 }
6238 
6239 // SymbolizerSymbolLookUp is the symbol lookup function passed when creating
6240 // the Symbolizer.  It looks up the ReferenceValue using the info passed via the
6241 // pointer to the struct DisassembleInfo that was passed when MCSymbolizer
6242 // is created and returns the symbol name that matches the ReferenceValue or
6243 // nullptr if none.  The ReferenceType is passed in for the IN type of
6244 // reference the instruction is making from the values in defined in the header
6245 // "llvm-c/Disassembler.h".  On return the ReferenceType can set to a specific
6246 // Out type and the ReferenceName will also be set which is added as a comment
6247 // to the disassembled instruction.
6248 //
6249 // If the symbol name is a C++ mangled name then the demangled name is
6250 // returned through ReferenceName and ReferenceType is set to
6251 // LLVMDisassembler_ReferenceType_DeMangled_Name .
6252 //
6253 // When this is called to get a symbol name for a branch target then the
6254 // ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then
6255 // SymbolValue will be looked for in the indirect symbol table to determine if
6256 // it is an address for a symbol stub.  If so then the symbol name for that
6257 // stub is returned indirectly through ReferenceName and then ReferenceType is
6258 // set to LLVMDisassembler_ReferenceType_Out_SymbolStub.
6259 //
6260 // When this is called with an value loaded via a PC relative load then
6261 // ReferenceType will be LLVMDisassembler_ReferenceType_In_PCrel_Load then the
6262 // SymbolValue is checked to be an address of literal pointer, symbol pointer,
6263 // or an Objective-C meta data reference.  If so the output ReferenceType is
6264 // set to correspond to that as well as setting the ReferenceName.
6265 static const char *SymbolizerSymbolLookUp(void *DisInfo,
6266                                           uint64_t ReferenceValue,
6267                                           uint64_t *ReferenceType,
6268                                           uint64_t ReferencePC,
6269                                           const char **ReferenceName) {
6270   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
6271   // If no verbose symbolic information is wanted then just return nullptr.
6272   if (!info->verbose) {
6273     *ReferenceName = nullptr;
6274     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6275     return nullptr;
6276   }
6277 
6278   const char *SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
6279 
6280   if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
6281     *ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
6282     if (*ReferenceName != nullptr) {
6283       method_reference(info, ReferenceType, ReferenceName);
6284       if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message)
6285         *ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
6286     } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
6287       if (info->demangled_name != nullptr)
6288         free(info->demangled_name);
6289       int status;
6290       info->demangled_name =
6291           itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
6292       if (info->demangled_name != nullptr) {
6293         *ReferenceName = info->demangled_name;
6294         *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
6295       } else
6296         *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6297     } else
6298       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6299   } else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
6300     *ReferenceName =
6301         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
6302     if (*ReferenceName)
6303       method_reference(info, ReferenceType, ReferenceName);
6304     else
6305       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6306     // If this is arm64 and the reference is an adrp instruction save the
6307     // instruction, passed in ReferenceValue and the address of the instruction
6308     // for use later if we see and add immediate instruction.
6309   } else if (info->O->getArch() == Triple::aarch64 &&
6310              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
6311     info->adrp_inst = ReferenceValue;
6312     info->adrp_addr = ReferencePC;
6313     SymbolName = nullptr;
6314     *ReferenceName = nullptr;
6315     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6316     // If this is arm64 and reference is an add immediate instruction and we
6317     // have
6318     // seen an adrp instruction just before it and the adrp's Xd register
6319     // matches
6320     // this add's Xn register reconstruct the value being referenced and look to
6321     // see if it is a literal pointer.  Note the add immediate instruction is
6322     // passed in ReferenceValue.
6323   } else if (info->O->getArch() == Triple::aarch64 &&
6324              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
6325              ReferencePC - 4 == info->adrp_addr &&
6326              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
6327              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
6328     uint32_t addxri_inst;
6329     uint64_t adrp_imm, addxri_imm;
6330 
6331     adrp_imm =
6332         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
6333     if (info->adrp_inst & 0x0200000)
6334       adrp_imm |= 0xfffffffffc000000LL;
6335 
6336     addxri_inst = ReferenceValue;
6337     addxri_imm = (addxri_inst >> 10) & 0xfff;
6338     if (((addxri_inst >> 22) & 0x3) == 1)
6339       addxri_imm <<= 12;
6340 
6341     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
6342                      (adrp_imm << 12) + addxri_imm;
6343 
6344     *ReferenceName =
6345         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
6346     if (*ReferenceName == nullptr)
6347       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6348     // If this is arm64 and the reference is a load register instruction and we
6349     // have seen an adrp instruction just before it and the adrp's Xd register
6350     // matches this add's Xn register reconstruct the value being referenced and
6351     // look to see if it is a literal pointer.  Note the load register
6352     // instruction is passed in ReferenceValue.
6353   } else if (info->O->getArch() == Triple::aarch64 &&
6354              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXui &&
6355              ReferencePC - 4 == info->adrp_addr &&
6356              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
6357              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
6358     uint32_t ldrxui_inst;
6359     uint64_t adrp_imm, ldrxui_imm;
6360 
6361     adrp_imm =
6362         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
6363     if (info->adrp_inst & 0x0200000)
6364       adrp_imm |= 0xfffffffffc000000LL;
6365 
6366     ldrxui_inst = ReferenceValue;
6367     ldrxui_imm = (ldrxui_inst >> 10) & 0xfff;
6368 
6369     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
6370                      (adrp_imm << 12) + (ldrxui_imm << 3);
6371 
6372     *ReferenceName =
6373         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
6374     if (*ReferenceName == nullptr)
6375       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6376   }
6377   // If this arm64 and is an load register (PC-relative) instruction the
6378   // ReferenceValue is the PC plus the immediate value.
6379   else if (info->O->getArch() == Triple::aarch64 &&
6380            (*ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXl ||
6381             *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADR)) {
6382     *ReferenceName =
6383         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
6384     if (*ReferenceName == nullptr)
6385       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6386   } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
6387     if (info->demangled_name != nullptr)
6388       free(info->demangled_name);
6389     int status;
6390     info->demangled_name =
6391         itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
6392     if (info->demangled_name != nullptr) {
6393       *ReferenceName = info->demangled_name;
6394       *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
6395     }
6396   }
6397   else {
6398     *ReferenceName = nullptr;
6399     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6400   }
6401 
6402   return SymbolName;
6403 }
6404 
6405 /// \brief Emits the comments that are stored in the CommentStream.
6406 /// Each comment in the CommentStream must end with a newline.
6407 static void emitComments(raw_svector_ostream &CommentStream,
6408                          SmallString<128> &CommentsToEmit,
6409                          formatted_raw_ostream &FormattedOS,
6410                          const MCAsmInfo &MAI) {
6411   // Flush the stream before taking its content.
6412   StringRef Comments = CommentsToEmit.str();
6413   // Get the default information for printing a comment.
6414   StringRef CommentBegin = MAI.getCommentString();
6415   unsigned CommentColumn = MAI.getCommentColumn();
6416   bool IsFirst = true;
6417   while (!Comments.empty()) {
6418     if (!IsFirst)
6419       FormattedOS << '\n';
6420     // Emit a line of comments.
6421     FormattedOS.PadToColumn(CommentColumn);
6422     size_t Position = Comments.find('\n');
6423     FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
6424     // Move after the newline character.
6425     Comments = Comments.substr(Position + 1);
6426     IsFirst = false;
6427   }
6428   FormattedOS.flush();
6429 
6430   // Tell the comment stream that the vector changed underneath it.
6431   CommentsToEmit.clear();
6432 }
6433 
6434 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
6435                              StringRef DisSegName, StringRef DisSectName) {
6436   const char *McpuDefault = nullptr;
6437   const Target *ThumbTarget = nullptr;
6438   const Target *TheTarget = GetTarget(MachOOF, &McpuDefault, &ThumbTarget);
6439   if (!TheTarget) {
6440     // GetTarget prints out stuff.
6441     return;
6442   }
6443   if (MCPU.empty() && McpuDefault)
6444     MCPU = McpuDefault;
6445 
6446   std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
6447   std::unique_ptr<const MCInstrInfo> ThumbInstrInfo;
6448   if (ThumbTarget)
6449     ThumbInstrInfo.reset(ThumbTarget->createMCInstrInfo());
6450 
6451   // Package up features to be passed to target/subtarget
6452   std::string FeaturesStr;
6453   if (MAttrs.size()) {
6454     SubtargetFeatures Features;
6455     for (unsigned i = 0; i != MAttrs.size(); ++i)
6456       Features.AddFeature(MAttrs[i]);
6457     FeaturesStr = Features.getString();
6458   }
6459 
6460   // Set up disassembler.
6461   std::unique_ptr<const MCRegisterInfo> MRI(
6462       TheTarget->createMCRegInfo(TripleName));
6463   std::unique_ptr<const MCAsmInfo> AsmInfo(
6464       TheTarget->createMCAsmInfo(*MRI, TripleName));
6465   std::unique_ptr<const MCSubtargetInfo> STI(
6466       TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
6467   MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr);
6468   std::unique_ptr<MCDisassembler> DisAsm(
6469       TheTarget->createMCDisassembler(*STI, Ctx));
6470   std::unique_ptr<MCSymbolizer> Symbolizer;
6471   struct DisassembleInfo SymbolizerInfo;
6472   std::unique_ptr<MCRelocationInfo> RelInfo(
6473       TheTarget->createMCRelocationInfo(TripleName, Ctx));
6474   if (RelInfo) {
6475     Symbolizer.reset(TheTarget->createMCSymbolizer(
6476         TripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
6477         &SymbolizerInfo, &Ctx, std::move(RelInfo)));
6478     DisAsm->setSymbolizer(std::move(Symbolizer));
6479   }
6480   int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
6481   std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
6482       Triple(TripleName), AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI));
6483   // Set the display preference for hex vs. decimal immediates.
6484   IP->setPrintImmHex(PrintImmHex);
6485   // Comment stream and backing vector.
6486   SmallString<128> CommentsToEmit;
6487   raw_svector_ostream CommentStream(CommentsToEmit);
6488   // FIXME: Setting the CommentStream in the InstPrinter is problematic in that
6489   // if it is done then arm64 comments for string literals don't get printed
6490   // and some constant get printed instead and not setting it causes intel
6491   // (32-bit and 64-bit) comments printed with different spacing before the
6492   // comment causing different diffs with the 'C' disassembler library API.
6493   // IP->setCommentStream(CommentStream);
6494 
6495   if (!AsmInfo || !STI || !DisAsm || !IP) {
6496     errs() << "error: couldn't initialize disassembler for target "
6497            << TripleName << '\n';
6498     return;
6499   }
6500 
6501   // Set up separate thumb disassembler if needed.
6502   std::unique_ptr<const MCRegisterInfo> ThumbMRI;
6503   std::unique_ptr<const MCAsmInfo> ThumbAsmInfo;
6504   std::unique_ptr<const MCSubtargetInfo> ThumbSTI;
6505   std::unique_ptr<MCDisassembler> ThumbDisAsm;
6506   std::unique_ptr<MCInstPrinter> ThumbIP;
6507   std::unique_ptr<MCContext> ThumbCtx;
6508   std::unique_ptr<MCSymbolizer> ThumbSymbolizer;
6509   struct DisassembleInfo ThumbSymbolizerInfo;
6510   std::unique_ptr<MCRelocationInfo> ThumbRelInfo;
6511   if (ThumbTarget) {
6512     ThumbMRI.reset(ThumbTarget->createMCRegInfo(ThumbTripleName));
6513     ThumbAsmInfo.reset(
6514         ThumbTarget->createMCAsmInfo(*ThumbMRI, ThumbTripleName));
6515     ThumbSTI.reset(
6516         ThumbTarget->createMCSubtargetInfo(ThumbTripleName, MCPU, FeaturesStr));
6517     ThumbCtx.reset(new MCContext(ThumbAsmInfo.get(), ThumbMRI.get(), nullptr));
6518     ThumbDisAsm.reset(ThumbTarget->createMCDisassembler(*ThumbSTI, *ThumbCtx));
6519     MCContext *PtrThumbCtx = ThumbCtx.get();
6520     ThumbRelInfo.reset(
6521         ThumbTarget->createMCRelocationInfo(ThumbTripleName, *PtrThumbCtx));
6522     if (ThumbRelInfo) {
6523       ThumbSymbolizer.reset(ThumbTarget->createMCSymbolizer(
6524           ThumbTripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
6525           &ThumbSymbolizerInfo, PtrThumbCtx, std::move(ThumbRelInfo)));
6526       ThumbDisAsm->setSymbolizer(std::move(ThumbSymbolizer));
6527     }
6528     int ThumbAsmPrinterVariant = ThumbAsmInfo->getAssemblerDialect();
6529     ThumbIP.reset(ThumbTarget->createMCInstPrinter(
6530         Triple(ThumbTripleName), ThumbAsmPrinterVariant, *ThumbAsmInfo,
6531         *ThumbInstrInfo, *ThumbMRI));
6532     // Set the display preference for hex vs. decimal immediates.
6533     ThumbIP->setPrintImmHex(PrintImmHex);
6534   }
6535 
6536   if (ThumbTarget && (!ThumbAsmInfo || !ThumbSTI || !ThumbDisAsm || !ThumbIP)) {
6537     errs() << "error: couldn't initialize disassembler for target "
6538            << ThumbTripleName << '\n';
6539     return;
6540   }
6541 
6542   MachO::mach_header Header = MachOOF->getHeader();
6543 
6544   // FIXME: Using the -cfg command line option, this code used to be able to
6545   // annotate relocations with the referenced symbol's name, and if this was
6546   // inside a __[cf]string section, the data it points to. This is now replaced
6547   // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
6548   std::vector<SectionRef> Sections;
6549   std::vector<SymbolRef> Symbols;
6550   SmallVector<uint64_t, 8> FoundFns;
6551   uint64_t BaseSegmentAddress;
6552 
6553   getSectionsAndSymbols(MachOOF, Sections, Symbols, FoundFns,
6554                         BaseSegmentAddress);
6555 
6556   // Sort the symbols by address, just in case they didn't come in that way.
6557   std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());
6558 
6559   // Build a data in code table that is sorted on by the address of each entry.
6560   uint64_t BaseAddress = 0;
6561   if (Header.filetype == MachO::MH_OBJECT)
6562     BaseAddress = Sections[0].getAddress();
6563   else
6564     BaseAddress = BaseSegmentAddress;
6565   DiceTable Dices;
6566   for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
6567        DI != DE; ++DI) {
6568     uint32_t Offset;
6569     DI->getOffset(Offset);
6570     Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
6571   }
6572   array_pod_sort(Dices.begin(), Dices.end());
6573 
6574 #ifndef NDEBUG
6575   raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
6576 #else
6577   raw_ostream &DebugOut = nulls();
6578 #endif
6579 
6580   std::unique_ptr<DIContext> diContext;
6581   ObjectFile *DbgObj = MachOOF;
6582   // Try to find debug info and set up the DIContext for it.
6583   if (UseDbg) {
6584     // A separate DSym file path was specified, parse it as a macho file,
6585     // get the sections and supply it to the section name parsing machinery.
6586     if (!DSYMFile.empty()) {
6587       ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
6588           MemoryBuffer::getFileOrSTDIN(DSYMFile);
6589       if (std::error_code EC = BufOrErr.getError()) {
6590         errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n';
6591         return;
6592       }
6593       DbgObj =
6594           ObjectFile::createMachOObjectFile(BufOrErr.get()->getMemBufferRef())
6595               .get()
6596               .release();
6597     }
6598 
6599     // Setup the DIContext
6600     diContext = DWARFContext::create(*DbgObj);
6601   }
6602 
6603   if (FilterSections.size() == 0)
6604     outs() << "(" << DisSegName << "," << DisSectName << ") section\n";
6605 
6606   for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
6607     StringRef SectName;
6608     if (Sections[SectIdx].getName(SectName) || SectName != DisSectName)
6609       continue;
6610 
6611     DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
6612 
6613     StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
6614     if (SegmentName != DisSegName)
6615       continue;
6616 
6617     StringRef BytesStr;
6618     Sections[SectIdx].getContents(BytesStr);
6619     ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
6620                             BytesStr.size());
6621     uint64_t SectAddress = Sections[SectIdx].getAddress();
6622 
6623     bool symbolTableWorked = false;
6624 
6625     // Create a map of symbol addresses to symbol names for use by
6626     // the SymbolizerSymbolLookUp() routine.
6627     SymbolAddressMap AddrMap;
6628     bool DisSymNameFound = false;
6629     for (const SymbolRef &Symbol : MachOOF->symbols()) {
6630       Expected<SymbolRef::Type> STOrErr = Symbol.getType();
6631       if (!STOrErr)
6632         report_error(MachOOF->getFileName(), STOrErr.takeError());
6633       SymbolRef::Type ST = *STOrErr;
6634       if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
6635           ST == SymbolRef::ST_Other) {
6636         uint64_t Address = Symbol.getValue();
6637         Expected<StringRef> SymNameOrErr = Symbol.getName();
6638         if (!SymNameOrErr)
6639           report_error(MachOOF->getFileName(), SymNameOrErr.takeError());
6640         StringRef SymName = *SymNameOrErr;
6641         AddrMap[Address] = SymName;
6642         if (!DisSymName.empty() && DisSymName == SymName)
6643           DisSymNameFound = true;
6644       }
6645     }
6646     if (!DisSymName.empty() && !DisSymNameFound) {
6647       outs() << "Can't find -dis-symname: " << DisSymName << "\n";
6648       return;
6649     }
6650     // Set up the block of info used by the Symbolizer call backs.
6651     SymbolizerInfo.verbose = !NoSymbolicOperands;
6652     SymbolizerInfo.O = MachOOF;
6653     SymbolizerInfo.S = Sections[SectIdx];
6654     SymbolizerInfo.AddrMap = &AddrMap;
6655     SymbolizerInfo.Sections = &Sections;
6656     SymbolizerInfo.class_name = nullptr;
6657     SymbolizerInfo.selector_name = nullptr;
6658     SymbolizerInfo.method = nullptr;
6659     SymbolizerInfo.demangled_name = nullptr;
6660     SymbolizerInfo.bindtable = nullptr;
6661     SymbolizerInfo.adrp_addr = 0;
6662     SymbolizerInfo.adrp_inst = 0;
6663     // Same for the ThumbSymbolizer
6664     ThumbSymbolizerInfo.verbose = !NoSymbolicOperands;
6665     ThumbSymbolizerInfo.O = MachOOF;
6666     ThumbSymbolizerInfo.S = Sections[SectIdx];
6667     ThumbSymbolizerInfo.AddrMap = &AddrMap;
6668     ThumbSymbolizerInfo.Sections = &Sections;
6669     ThumbSymbolizerInfo.class_name = nullptr;
6670     ThumbSymbolizerInfo.selector_name = nullptr;
6671     ThumbSymbolizerInfo.method = nullptr;
6672     ThumbSymbolizerInfo.demangled_name = nullptr;
6673     ThumbSymbolizerInfo.bindtable = nullptr;
6674     ThumbSymbolizerInfo.adrp_addr = 0;
6675     ThumbSymbolizerInfo.adrp_inst = 0;
6676 
6677     unsigned int Arch = MachOOF->getArch();
6678 
6679     // Skip all symbols if this is a stubs file.
6680     if (Bytes.size() == 0)
6681       return;
6682 
6683     // If the section has symbols but no symbol at the start of the section
6684     // these are used to make sure the bytes before the first symbol are
6685     // disassembled.
6686     bool FirstSymbol = true;
6687     bool FirstSymbolAtSectionStart = true;
6688 
6689     // Disassemble symbol by symbol.
6690     for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
6691       Expected<StringRef> SymNameOrErr = Symbols[SymIdx].getName();
6692       if (!SymNameOrErr)
6693         report_error(MachOOF->getFileName(), SymNameOrErr.takeError());
6694       StringRef SymName = *SymNameOrErr;
6695 
6696       Expected<SymbolRef::Type> STOrErr = Symbols[SymIdx].getType();
6697       if (!STOrErr)
6698         report_error(MachOOF->getFileName(), STOrErr.takeError());
6699       SymbolRef::Type ST = *STOrErr;
6700       if (ST != SymbolRef::ST_Function && ST != SymbolRef::ST_Data)
6701         continue;
6702 
6703       // Make sure the symbol is defined in this section.
6704       bool containsSym = Sections[SectIdx].containsSymbol(Symbols[SymIdx]);
6705       if (!containsSym) {
6706         if (!DisSymName.empty() && DisSymName == SymName) {
6707           outs() << "-dis-symname: " << DisSymName << " not in the section\n";
6708           return;
6709         }
6710         continue;
6711       }
6712       // The __mh_execute_header is special and we need to deal with that fact
6713       // this symbol is before the start of the (__TEXT,__text) section and at the
6714       // address of the start of the __TEXT segment.  This is because this symbol
6715       // is an N_SECT symbol in the (__TEXT,__text) but its address is before the
6716       // start of the section in a standard MH_EXECUTE filetype.
6717       if (!DisSymName.empty() && DisSymName == "__mh_execute_header") {
6718         outs() << "-dis-symname: __mh_execute_header not in any section\n";
6719         return;
6720       }
6721       // When this code is trying to disassemble a symbol at a time and in the
6722       // case there is only the __mh_execute_header symbol left as in a stripped
6723       // executable, we need to deal with this by ignoring this symbol so the
6724       // whole section is disassembled and this symbol is then not displayed.
6725       if (SymName == "__mh_execute_header" || SymName == "__mh_dylib_header" ||
6726           SymName == "__mh_bundle_header" || SymName == "__mh_object_header" ||
6727           SymName == "__mh_preload_header" || SymName == "__mh_dylinker_header")
6728         continue;
6729 
6730       // If we are only disassembling one symbol see if this is that symbol.
6731       if (!DisSymName.empty() && DisSymName != SymName)
6732         continue;
6733 
6734       // Start at the address of the symbol relative to the section's address.
6735       uint64_t SectSize = Sections[SectIdx].getSize();
6736       uint64_t Start = Symbols[SymIdx].getValue();
6737       uint64_t SectionAddress = Sections[SectIdx].getAddress();
6738       Start -= SectionAddress;
6739 
6740       if (Start > SectSize) {
6741         outs() << "section data ends, " << SymName
6742                << " lies outside valid range\n";
6743         return;
6744       }
6745 
6746       // Stop disassembling either at the beginning of the next symbol or at
6747       // the end of the section.
6748       bool containsNextSym = false;
6749       uint64_t NextSym = 0;
6750       uint64_t NextSymIdx = SymIdx + 1;
6751       while (Symbols.size() > NextSymIdx) {
6752         Expected<SymbolRef::Type> STOrErr = Symbols[NextSymIdx].getType();
6753         if (!STOrErr)
6754           report_error(MachOOF->getFileName(), STOrErr.takeError());
6755         SymbolRef::Type NextSymType = *STOrErr;
6756         if (NextSymType == SymbolRef::ST_Function) {
6757           containsNextSym =
6758               Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]);
6759           NextSym = Symbols[NextSymIdx].getValue();
6760           NextSym -= SectionAddress;
6761           break;
6762         }
6763         ++NextSymIdx;
6764       }
6765 
6766       uint64_t End = containsNextSym ? std::min(NextSym, SectSize) : SectSize;
6767       uint64_t Size;
6768 
6769       symbolTableWorked = true;
6770 
6771       DataRefImpl Symb = Symbols[SymIdx].getRawDataRefImpl();
6772       bool IsThumb = MachOOF->getSymbolFlags(Symb) & SymbolRef::SF_Thumb;
6773 
6774       // We only need the dedicated Thumb target if there's a real choice
6775       // (i.e. we're not targeting M-class) and the function is Thumb.
6776       bool UseThumbTarget = IsThumb && ThumbTarget;
6777 
6778       // If we are not specifying a symbol to start disassembly with and this
6779       // is the first symbol in the section but not at the start of the section
6780       // then move the disassembly index to the start of the section and
6781       // don't print the symbol name just yet.  This is so the bytes before the
6782       // first symbol are disassembled.
6783       uint64_t SymbolStart = Start;
6784       if (DisSymName.empty() && FirstSymbol && Start != 0) {
6785         FirstSymbolAtSectionStart = false;
6786         Start = 0;
6787       }
6788       else
6789         outs() << SymName << ":\n";
6790 
6791       DILineInfo lastLine;
6792       for (uint64_t Index = Start; Index < End; Index += Size) {
6793         MCInst Inst;
6794 
6795         // If this is the first symbol in the section and it was not at the
6796         // start of the section, see if we are at its Index now and if so print
6797         // the symbol name.
6798         if (FirstSymbol && !FirstSymbolAtSectionStart && Index == SymbolStart)
6799           outs() << SymName << ":\n";
6800 
6801         uint64_t PC = SectAddress + Index;
6802         if (!NoLeadingAddr) {
6803           if (FullLeadingAddr) {
6804             if (MachOOF->is64Bit())
6805               outs() << format("%016" PRIx64, PC);
6806             else
6807               outs() << format("%08" PRIx64, PC);
6808           } else {
6809             outs() << format("%8" PRIx64 ":", PC);
6810           }
6811         }
6812         if (!NoShowRawInsn || Arch == Triple::arm)
6813           outs() << "\t";
6814 
6815         // Check the data in code table here to see if this is data not an
6816         // instruction to be disassembled.
6817         DiceTable Dice;
6818         Dice.push_back(std::make_pair(PC, DiceRef()));
6819         dice_table_iterator DTI =
6820             std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(),
6821                         compareDiceTableEntries);
6822         if (DTI != Dices.end()) {
6823           uint16_t Length;
6824           DTI->second.getLength(Length);
6825           uint16_t Kind;
6826           DTI->second.getKind(Kind);
6827           Size = DumpDataInCode(Bytes.data() + Index, Length, Kind);
6828           if ((Kind == MachO::DICE_KIND_JUMP_TABLE8) &&
6829               (PC == (DTI->first + Length - 1)) && (Length & 1))
6830             Size++;
6831           continue;
6832         }
6833 
6834         SmallVector<char, 64> AnnotationsBytes;
6835         raw_svector_ostream Annotations(AnnotationsBytes);
6836 
6837         bool gotInst;
6838         if (UseThumbTarget)
6839           gotInst = ThumbDisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
6840                                                 PC, DebugOut, Annotations);
6841         else
6842           gotInst = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index), PC,
6843                                            DebugOut, Annotations);
6844         if (gotInst) {
6845           if (!NoShowRawInsn || Arch == Triple::arm) {
6846             dumpBytes(makeArrayRef(Bytes.data() + Index, Size), outs());
6847           }
6848           formatted_raw_ostream FormattedOS(outs());
6849           StringRef AnnotationsStr = Annotations.str();
6850           if (UseThumbTarget)
6851             ThumbIP->printInst(&Inst, FormattedOS, AnnotationsStr, *ThumbSTI);
6852           else
6853             IP->printInst(&Inst, FormattedOS, AnnotationsStr, *STI);
6854           emitComments(CommentStream, CommentsToEmit, FormattedOS, *AsmInfo);
6855 
6856           // Print debug info.
6857           if (diContext) {
6858             DILineInfo dli = diContext->getLineInfoForAddress(PC);
6859             // Print valid line info if it changed.
6860             if (dli != lastLine && dli.Line != 0)
6861               outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
6862                      << dli.Column;
6863             lastLine = dli;
6864           }
6865           outs() << "\n";
6866         } else {
6867           unsigned int Arch = MachOOF->getArch();
6868           if (Arch == Triple::x86_64 || Arch == Triple::x86) {
6869             outs() << format("\t.byte 0x%02x #bad opcode\n",
6870                              *(Bytes.data() + Index) & 0xff);
6871             Size = 1; // skip exactly one illegible byte and move on.
6872           } else if (Arch == Triple::aarch64 ||
6873                      (Arch == Triple::arm && !IsThumb)) {
6874             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
6875                               (*(Bytes.data() + Index + 1) & 0xff) << 8 |
6876                               (*(Bytes.data() + Index + 2) & 0xff) << 16 |
6877                               (*(Bytes.data() + Index + 3) & 0xff) << 24;
6878             outs() << format("\t.long\t0x%08x\n", opcode);
6879             Size = 4;
6880           } else if (Arch == Triple::arm) {
6881             assert(IsThumb && "ARM mode should have been dealt with above");
6882             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
6883                               (*(Bytes.data() + Index + 1) & 0xff) << 8;
6884             outs() << format("\t.short\t0x%04x\n", opcode);
6885             Size = 2;
6886           } else{
6887             errs() << "llvm-objdump: warning: invalid instruction encoding\n";
6888             if (Size == 0)
6889               Size = 1; // skip illegible bytes
6890           }
6891         }
6892       }
6893       // Now that we are done disassembled the first symbol set the bool that
6894       // were doing this to false.
6895       FirstSymbol = false;
6896     }
6897     if (!symbolTableWorked) {
6898       // Reading the symbol table didn't work, disassemble the whole section.
6899       uint64_t SectAddress = Sections[SectIdx].getAddress();
6900       uint64_t SectSize = Sections[SectIdx].getSize();
6901       uint64_t InstSize;
6902       for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
6903         MCInst Inst;
6904 
6905         uint64_t PC = SectAddress + Index;
6906         SmallVector<char, 64> AnnotationsBytes;
6907         raw_svector_ostream Annotations(AnnotationsBytes);
6908         if (DisAsm->getInstruction(Inst, InstSize, Bytes.slice(Index), PC,
6909                                    DebugOut, Annotations)) {
6910           if (!NoLeadingAddr) {
6911             if (FullLeadingAddr) {
6912               if (MachOOF->is64Bit())
6913                 outs() << format("%016" PRIx64, PC);
6914               else
6915                 outs() << format("%08" PRIx64, PC);
6916             } else {
6917               outs() << format("%8" PRIx64 ":", PC);
6918             }
6919           }
6920           if (!NoShowRawInsn || Arch == Triple::arm) {
6921             outs() << "\t";
6922             dumpBytes(makeArrayRef(Bytes.data() + Index, InstSize), outs());
6923           }
6924           StringRef AnnotationsStr = Annotations.str();
6925           IP->printInst(&Inst, outs(), AnnotationsStr, *STI);
6926           outs() << "\n";
6927         } else {
6928           unsigned int Arch = MachOOF->getArch();
6929           if (Arch == Triple::x86_64 || Arch == Triple::x86) {
6930             outs() << format("\t.byte 0x%02x #bad opcode\n",
6931                              *(Bytes.data() + Index) & 0xff);
6932             InstSize = 1; // skip exactly one illegible byte and move on.
6933           } else {
6934             errs() << "llvm-objdump: warning: invalid instruction encoding\n";
6935             if (InstSize == 0)
6936               InstSize = 1; // skip illegible bytes
6937           }
6938         }
6939       }
6940     }
6941     // The TripleName's need to be reset if we are called again for a different
6942     // archtecture.
6943     TripleName = "";
6944     ThumbTripleName = "";
6945 
6946     if (SymbolizerInfo.method != nullptr)
6947       free(SymbolizerInfo.method);
6948     if (SymbolizerInfo.demangled_name != nullptr)
6949       free(SymbolizerInfo.demangled_name);
6950     if (ThumbSymbolizerInfo.method != nullptr)
6951       free(ThumbSymbolizerInfo.method);
6952     if (ThumbSymbolizerInfo.demangled_name != nullptr)
6953       free(ThumbSymbolizerInfo.demangled_name);
6954   }
6955 }
6956 
6957 //===----------------------------------------------------------------------===//
6958 // __compact_unwind section dumping
6959 //===----------------------------------------------------------------------===//
6960 
6961 namespace {
6962 
6963 template <typename T> static uint64_t readNext(const char *&Buf) {
6964   using llvm::support::little;
6965   using llvm::support::unaligned;
6966 
6967   uint64_t Val = support::endian::read<T, little, unaligned>(Buf);
6968   Buf += sizeof(T);
6969   return Val;
6970 }
6971 
6972 struct CompactUnwindEntry {
6973   uint32_t OffsetInSection;
6974 
6975   uint64_t FunctionAddr;
6976   uint32_t Length;
6977   uint32_t CompactEncoding;
6978   uint64_t PersonalityAddr;
6979   uint64_t LSDAAddr;
6980 
6981   RelocationRef FunctionReloc;
6982   RelocationRef PersonalityReloc;
6983   RelocationRef LSDAReloc;
6984 
6985   CompactUnwindEntry(StringRef Contents, unsigned Offset, bool Is64)
6986       : OffsetInSection(Offset) {
6987     if (Is64)
6988       read<uint64_t>(Contents.data() + Offset);
6989     else
6990       read<uint32_t>(Contents.data() + Offset);
6991   }
6992 
6993 private:
6994   template <typename UIntPtr> void read(const char *Buf) {
6995     FunctionAddr = readNext<UIntPtr>(Buf);
6996     Length = readNext<uint32_t>(Buf);
6997     CompactEncoding = readNext<uint32_t>(Buf);
6998     PersonalityAddr = readNext<UIntPtr>(Buf);
6999     LSDAAddr = readNext<UIntPtr>(Buf);
7000   }
7001 };
7002 }
7003 
7004 /// Given a relocation from __compact_unwind, consisting of the RelocationRef
7005 /// and data being relocated, determine the best base Name and Addend to use for
7006 /// display purposes.
7007 ///
7008 /// 1. An Extern relocation will directly reference a symbol (and the data is
7009 ///    then already an addend), so use that.
7010 /// 2. Otherwise the data is an offset in the object file's layout; try to find
7011 //     a symbol before it in the same section, and use the offset from there.
7012 /// 3. Finally, if all that fails, fall back to an offset from the start of the
7013 ///    referenced section.
7014 static void findUnwindRelocNameAddend(const MachOObjectFile *Obj,
7015                                       std::map<uint64_t, SymbolRef> &Symbols,
7016                                       const RelocationRef &Reloc, uint64_t Addr,
7017                                       StringRef &Name, uint64_t &Addend) {
7018   if (Reloc.getSymbol() != Obj->symbol_end()) {
7019     Expected<StringRef> NameOrErr = Reloc.getSymbol()->getName();
7020     if (!NameOrErr)
7021       report_error(Obj->getFileName(), NameOrErr.takeError());
7022     Name = *NameOrErr;
7023     Addend = Addr;
7024     return;
7025   }
7026 
7027   auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl());
7028   SectionRef RelocSection = Obj->getAnyRelocationSection(RE);
7029 
7030   uint64_t SectionAddr = RelocSection.getAddress();
7031 
7032   auto Sym = Symbols.upper_bound(Addr);
7033   if (Sym == Symbols.begin()) {
7034     // The first symbol in the object is after this reference, the best we can
7035     // do is section-relative notation.
7036     RelocSection.getName(Name);
7037     Addend = Addr - SectionAddr;
7038     return;
7039   }
7040 
7041   // Go back one so that SymbolAddress <= Addr.
7042   --Sym;
7043 
7044   auto SectOrErr = Sym->second.getSection();
7045   if (!SectOrErr)
7046     report_error(Obj->getFileName(), SectOrErr.takeError());
7047   section_iterator SymSection = *SectOrErr;
7048   if (RelocSection == *SymSection) {
7049     // There's a valid symbol in the same section before this reference.
7050     Expected<StringRef> NameOrErr = Sym->second.getName();
7051     if (!NameOrErr)
7052       report_error(Obj->getFileName(), NameOrErr.takeError());
7053     Name = *NameOrErr;
7054     Addend = Addr - Sym->first;
7055     return;
7056   }
7057 
7058   // There is a symbol before this reference, but it's in a different
7059   // section. Probably not helpful to mention it, so use the section name.
7060   RelocSection.getName(Name);
7061   Addend = Addr - SectionAddr;
7062 }
7063 
7064 static void printUnwindRelocDest(const MachOObjectFile *Obj,
7065                                  std::map<uint64_t, SymbolRef> &Symbols,
7066                                  const RelocationRef &Reloc, uint64_t Addr) {
7067   StringRef Name;
7068   uint64_t Addend;
7069 
7070   if (!Reloc.getObject())
7071     return;
7072 
7073   findUnwindRelocNameAddend(Obj, Symbols, Reloc, Addr, Name, Addend);
7074 
7075   outs() << Name;
7076   if (Addend)
7077     outs() << " + " << format("0x%" PRIx64, Addend);
7078 }
7079 
7080 static void
7081 printMachOCompactUnwindSection(const MachOObjectFile *Obj,
7082                                std::map<uint64_t, SymbolRef> &Symbols,
7083                                const SectionRef &CompactUnwind) {
7084 
7085   if (!Obj->isLittleEndian()) {
7086     outs() << "Skipping big-endian __compact_unwind section\n";
7087     return;
7088   }
7089 
7090   bool Is64 = Obj->is64Bit();
7091   uint32_t PointerSize = Is64 ? sizeof(uint64_t) : sizeof(uint32_t);
7092   uint32_t EntrySize = 3 * PointerSize + 2 * sizeof(uint32_t);
7093 
7094   StringRef Contents;
7095   CompactUnwind.getContents(Contents);
7096 
7097   SmallVector<CompactUnwindEntry, 4> CompactUnwinds;
7098 
7099   // First populate the initial raw offsets, encodings and so on from the entry.
7100   for (unsigned Offset = 0; Offset < Contents.size(); Offset += EntrySize) {
7101     CompactUnwindEntry Entry(Contents.data(), Offset, Is64);
7102     CompactUnwinds.push_back(Entry);
7103   }
7104 
7105   // Next we need to look at the relocations to find out what objects are
7106   // actually being referred to.
7107   for (const RelocationRef &Reloc : CompactUnwind.relocations()) {
7108     uint64_t RelocAddress = Reloc.getOffset();
7109 
7110     uint32_t EntryIdx = RelocAddress / EntrySize;
7111     uint32_t OffsetInEntry = RelocAddress - EntryIdx * EntrySize;
7112     CompactUnwindEntry &Entry = CompactUnwinds[EntryIdx];
7113 
7114     if (OffsetInEntry == 0)
7115       Entry.FunctionReloc = Reloc;
7116     else if (OffsetInEntry == PointerSize + 2 * sizeof(uint32_t))
7117       Entry.PersonalityReloc = Reloc;
7118     else if (OffsetInEntry == 2 * PointerSize + 2 * sizeof(uint32_t))
7119       Entry.LSDAReloc = Reloc;
7120     else {
7121       outs() << "Invalid relocation in __compact_unwind section\n";
7122       return;
7123     }
7124   }
7125 
7126   // Finally, we're ready to print the data we've gathered.
7127   outs() << "Contents of __compact_unwind section:\n";
7128   for (auto &Entry : CompactUnwinds) {
7129     outs() << "  Entry at offset "
7130            << format("0x%" PRIx32, Entry.OffsetInSection) << ":\n";
7131 
7132     // 1. Start of the region this entry applies to.
7133     outs() << "    start:                " << format("0x%" PRIx64,
7134                                                      Entry.FunctionAddr) << ' ';
7135     printUnwindRelocDest(Obj, Symbols, Entry.FunctionReloc, Entry.FunctionAddr);
7136     outs() << '\n';
7137 
7138     // 2. Length of the region this entry applies to.
7139     outs() << "    length:               " << format("0x%" PRIx32, Entry.Length)
7140            << '\n';
7141     // 3. The 32-bit compact encoding.
7142     outs() << "    compact encoding:     "
7143            << format("0x%08" PRIx32, Entry.CompactEncoding) << '\n';
7144 
7145     // 4. The personality function, if present.
7146     if (Entry.PersonalityReloc.getObject()) {
7147       outs() << "    personality function: "
7148              << format("0x%" PRIx64, Entry.PersonalityAddr) << ' ';
7149       printUnwindRelocDest(Obj, Symbols, Entry.PersonalityReloc,
7150                            Entry.PersonalityAddr);
7151       outs() << '\n';
7152     }
7153 
7154     // 5. This entry's language-specific data area.
7155     if (Entry.LSDAReloc.getObject()) {
7156       outs() << "    LSDA:                 " << format("0x%" PRIx64,
7157                                                        Entry.LSDAAddr) << ' ';
7158       printUnwindRelocDest(Obj, Symbols, Entry.LSDAReloc, Entry.LSDAAddr);
7159       outs() << '\n';
7160     }
7161   }
7162 }
7163 
7164 //===----------------------------------------------------------------------===//
7165 // __unwind_info section dumping
7166 //===----------------------------------------------------------------------===//
7167 
7168 static void printRegularSecondLevelUnwindPage(const char *PageStart) {
7169   const char *Pos = PageStart;
7170   uint32_t Kind = readNext<uint32_t>(Pos);
7171   (void)Kind;
7172   assert(Kind == 2 && "kind for a regular 2nd level index should be 2");
7173 
7174   uint16_t EntriesStart = readNext<uint16_t>(Pos);
7175   uint16_t NumEntries = readNext<uint16_t>(Pos);
7176 
7177   Pos = PageStart + EntriesStart;
7178   for (unsigned i = 0; i < NumEntries; ++i) {
7179     uint32_t FunctionOffset = readNext<uint32_t>(Pos);
7180     uint32_t Encoding = readNext<uint32_t>(Pos);
7181 
7182     outs() << "      [" << i << "]: "
7183            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
7184            << ", "
7185            << "encoding=" << format("0x%08" PRIx32, Encoding) << '\n';
7186   }
7187 }
7188 
7189 static void printCompressedSecondLevelUnwindPage(
7190     const char *PageStart, uint32_t FunctionBase,
7191     const SmallVectorImpl<uint32_t> &CommonEncodings) {
7192   const char *Pos = PageStart;
7193   uint32_t Kind = readNext<uint32_t>(Pos);
7194   (void)Kind;
7195   assert(Kind == 3 && "kind for a compressed 2nd level index should be 3");
7196 
7197   uint16_t EntriesStart = readNext<uint16_t>(Pos);
7198   uint16_t NumEntries = readNext<uint16_t>(Pos);
7199 
7200   uint16_t EncodingsStart = readNext<uint16_t>(Pos);
7201   readNext<uint16_t>(Pos);
7202   const auto *PageEncodings = reinterpret_cast<const support::ulittle32_t *>(
7203       PageStart + EncodingsStart);
7204 
7205   Pos = PageStart + EntriesStart;
7206   for (unsigned i = 0; i < NumEntries; ++i) {
7207     uint32_t Entry = readNext<uint32_t>(Pos);
7208     uint32_t FunctionOffset = FunctionBase + (Entry & 0xffffff);
7209     uint32_t EncodingIdx = Entry >> 24;
7210 
7211     uint32_t Encoding;
7212     if (EncodingIdx < CommonEncodings.size())
7213       Encoding = CommonEncodings[EncodingIdx];
7214     else
7215       Encoding = PageEncodings[EncodingIdx - CommonEncodings.size()];
7216 
7217     outs() << "      [" << i << "]: "
7218            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
7219            << ", "
7220            << "encoding[" << EncodingIdx
7221            << "]=" << format("0x%08" PRIx32, Encoding) << '\n';
7222   }
7223 }
7224 
7225 static void printMachOUnwindInfoSection(const MachOObjectFile *Obj,
7226                                         std::map<uint64_t, SymbolRef> &Symbols,
7227                                         const SectionRef &UnwindInfo) {
7228 
7229   if (!Obj->isLittleEndian()) {
7230     outs() << "Skipping big-endian __unwind_info section\n";
7231     return;
7232   }
7233 
7234   outs() << "Contents of __unwind_info section:\n";
7235 
7236   StringRef Contents;
7237   UnwindInfo.getContents(Contents);
7238   const char *Pos = Contents.data();
7239 
7240   //===----------------------------------
7241   // Section header
7242   //===----------------------------------
7243 
7244   uint32_t Version = readNext<uint32_t>(Pos);
7245   outs() << "  Version:                                   "
7246          << format("0x%" PRIx32, Version) << '\n';
7247   if (Version != 1) {
7248     outs() << "    Skipping section with unknown version\n";
7249     return;
7250   }
7251 
7252   uint32_t CommonEncodingsStart = readNext<uint32_t>(Pos);
7253   outs() << "  Common encodings array section offset:     "
7254          << format("0x%" PRIx32, CommonEncodingsStart) << '\n';
7255   uint32_t NumCommonEncodings = readNext<uint32_t>(Pos);
7256   outs() << "  Number of common encodings in array:       "
7257          << format("0x%" PRIx32, NumCommonEncodings) << '\n';
7258 
7259   uint32_t PersonalitiesStart = readNext<uint32_t>(Pos);
7260   outs() << "  Personality function array section offset: "
7261          << format("0x%" PRIx32, PersonalitiesStart) << '\n';
7262   uint32_t NumPersonalities = readNext<uint32_t>(Pos);
7263   outs() << "  Number of personality functions in array:  "
7264          << format("0x%" PRIx32, NumPersonalities) << '\n';
7265 
7266   uint32_t IndicesStart = readNext<uint32_t>(Pos);
7267   outs() << "  Index array section offset:                "
7268          << format("0x%" PRIx32, IndicesStart) << '\n';
7269   uint32_t NumIndices = readNext<uint32_t>(Pos);
7270   outs() << "  Number of indices in array:                "
7271          << format("0x%" PRIx32, NumIndices) << '\n';
7272 
7273   //===----------------------------------
7274   // A shared list of common encodings
7275   //===----------------------------------
7276 
7277   // These occupy indices in the range [0, N] whenever an encoding is referenced
7278   // from a compressed 2nd level index table. In practice the linker only
7279   // creates ~128 of these, so that indices are available to embed encodings in
7280   // the 2nd level index.
7281 
7282   SmallVector<uint32_t, 64> CommonEncodings;
7283   outs() << "  Common encodings: (count = " << NumCommonEncodings << ")\n";
7284   Pos = Contents.data() + CommonEncodingsStart;
7285   for (unsigned i = 0; i < NumCommonEncodings; ++i) {
7286     uint32_t Encoding = readNext<uint32_t>(Pos);
7287     CommonEncodings.push_back(Encoding);
7288 
7289     outs() << "    encoding[" << i << "]: " << format("0x%08" PRIx32, Encoding)
7290            << '\n';
7291   }
7292 
7293   //===----------------------------------
7294   // Personality functions used in this executable
7295   //===----------------------------------
7296 
7297   // There should be only a handful of these (one per source language,
7298   // roughly). Particularly since they only get 2 bits in the compact encoding.
7299 
7300   outs() << "  Personality functions: (count = " << NumPersonalities << ")\n";
7301   Pos = Contents.data() + PersonalitiesStart;
7302   for (unsigned i = 0; i < NumPersonalities; ++i) {
7303     uint32_t PersonalityFn = readNext<uint32_t>(Pos);
7304     outs() << "    personality[" << i + 1
7305            << "]: " << format("0x%08" PRIx32, PersonalityFn) << '\n';
7306   }
7307 
7308   //===----------------------------------
7309   // The level 1 index entries
7310   //===----------------------------------
7311 
7312   // These specify an approximate place to start searching for the more detailed
7313   // information, sorted by PC.
7314 
7315   struct IndexEntry {
7316     uint32_t FunctionOffset;
7317     uint32_t SecondLevelPageStart;
7318     uint32_t LSDAStart;
7319   };
7320 
7321   SmallVector<IndexEntry, 4> IndexEntries;
7322 
7323   outs() << "  Top level indices: (count = " << NumIndices << ")\n";
7324   Pos = Contents.data() + IndicesStart;
7325   for (unsigned i = 0; i < NumIndices; ++i) {
7326     IndexEntry Entry;
7327 
7328     Entry.FunctionOffset = readNext<uint32_t>(Pos);
7329     Entry.SecondLevelPageStart = readNext<uint32_t>(Pos);
7330     Entry.LSDAStart = readNext<uint32_t>(Pos);
7331     IndexEntries.push_back(Entry);
7332 
7333     outs() << "    [" << i << "]: "
7334            << "function offset=" << format("0x%08" PRIx32, Entry.FunctionOffset)
7335            << ", "
7336            << "2nd level page offset="
7337            << format("0x%08" PRIx32, Entry.SecondLevelPageStart) << ", "
7338            << "LSDA offset=" << format("0x%08" PRIx32, Entry.LSDAStart) << '\n';
7339   }
7340 
7341   //===----------------------------------
7342   // Next come the LSDA tables
7343   //===----------------------------------
7344 
7345   // The LSDA layout is rather implicit: it's a contiguous array of entries from
7346   // the first top-level index's LSDAOffset to the last (sentinel).
7347 
7348   outs() << "  LSDA descriptors:\n";
7349   Pos = Contents.data() + IndexEntries[0].LSDAStart;
7350   int NumLSDAs = (IndexEntries.back().LSDAStart - IndexEntries[0].LSDAStart) /
7351                  (2 * sizeof(uint32_t));
7352   for (int i = 0; i < NumLSDAs; ++i) {
7353     uint32_t FunctionOffset = readNext<uint32_t>(Pos);
7354     uint32_t LSDAOffset = readNext<uint32_t>(Pos);
7355     outs() << "    [" << i << "]: "
7356            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
7357            << ", "
7358            << "LSDA offset=" << format("0x%08" PRIx32, LSDAOffset) << '\n';
7359   }
7360 
7361   //===----------------------------------
7362   // Finally, the 2nd level indices
7363   //===----------------------------------
7364 
7365   // Generally these are 4K in size, and have 2 possible forms:
7366   //   + Regular stores up to 511 entries with disparate encodings
7367   //   + Compressed stores up to 1021 entries if few enough compact encoding
7368   //     values are used.
7369   outs() << "  Second level indices:\n";
7370   for (unsigned i = 0; i < IndexEntries.size() - 1; ++i) {
7371     // The final sentinel top-level index has no associated 2nd level page
7372     if (IndexEntries[i].SecondLevelPageStart == 0)
7373       break;
7374 
7375     outs() << "    Second level index[" << i << "]: "
7376            << "offset in section="
7377            << format("0x%08" PRIx32, IndexEntries[i].SecondLevelPageStart)
7378            << ", "
7379            << "base function offset="
7380            << format("0x%08" PRIx32, IndexEntries[i].FunctionOffset) << '\n';
7381 
7382     Pos = Contents.data() + IndexEntries[i].SecondLevelPageStart;
7383     uint32_t Kind = *reinterpret_cast<const support::ulittle32_t *>(Pos);
7384     if (Kind == 2)
7385       printRegularSecondLevelUnwindPage(Pos);
7386     else if (Kind == 3)
7387       printCompressedSecondLevelUnwindPage(Pos, IndexEntries[i].FunctionOffset,
7388                                            CommonEncodings);
7389     else
7390       outs() << "    Skipping 2nd level page with unknown kind " << Kind
7391              << '\n';
7392   }
7393 }
7394 
7395 void llvm::printMachOUnwindInfo(const MachOObjectFile *Obj) {
7396   std::map<uint64_t, SymbolRef> Symbols;
7397   for (const SymbolRef &SymRef : Obj->symbols()) {
7398     // Discard any undefined or absolute symbols. They're not going to take part
7399     // in the convenience lookup for unwind info and just take up resources.
7400     auto SectOrErr = SymRef.getSection();
7401     if (!SectOrErr) {
7402       // TODO: Actually report errors helpfully.
7403       consumeError(SectOrErr.takeError());
7404       continue;
7405     }
7406     section_iterator Section = *SectOrErr;
7407     if (Section == Obj->section_end())
7408       continue;
7409 
7410     uint64_t Addr = SymRef.getValue();
7411     Symbols.insert(std::make_pair(Addr, SymRef));
7412   }
7413 
7414   for (const SectionRef &Section : Obj->sections()) {
7415     StringRef SectName;
7416     Section.getName(SectName);
7417     if (SectName == "__compact_unwind")
7418       printMachOCompactUnwindSection(Obj, Symbols, Section);
7419     else if (SectName == "__unwind_info")
7420       printMachOUnwindInfoSection(Obj, Symbols, Section);
7421   }
7422 }
7423 
7424 static void PrintMachHeader(uint32_t magic, uint32_t cputype,
7425                             uint32_t cpusubtype, uint32_t filetype,
7426                             uint32_t ncmds, uint32_t sizeofcmds, uint32_t flags,
7427                             bool verbose) {
7428   outs() << "Mach header\n";
7429   outs() << "      magic cputype cpusubtype  caps    filetype ncmds "
7430             "sizeofcmds      flags\n";
7431   if (verbose) {
7432     if (magic == MachO::MH_MAGIC)
7433       outs() << "   MH_MAGIC";
7434     else if (magic == MachO::MH_MAGIC_64)
7435       outs() << "MH_MAGIC_64";
7436     else
7437       outs() << format(" 0x%08" PRIx32, magic);
7438     switch (cputype) {
7439     case MachO::CPU_TYPE_I386:
7440       outs() << "    I386";
7441       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7442       case MachO::CPU_SUBTYPE_I386_ALL:
7443         outs() << "        ALL";
7444         break;
7445       default:
7446         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7447         break;
7448       }
7449       break;
7450     case MachO::CPU_TYPE_X86_64:
7451       outs() << "  X86_64";
7452       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7453       case MachO::CPU_SUBTYPE_X86_64_ALL:
7454         outs() << "        ALL";
7455         break;
7456       case MachO::CPU_SUBTYPE_X86_64_H:
7457         outs() << "    Haswell";
7458         break;
7459       default:
7460         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7461         break;
7462       }
7463       break;
7464     case MachO::CPU_TYPE_ARM:
7465       outs() << "     ARM";
7466       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7467       case MachO::CPU_SUBTYPE_ARM_ALL:
7468         outs() << "        ALL";
7469         break;
7470       case MachO::CPU_SUBTYPE_ARM_V4T:
7471         outs() << "        V4T";
7472         break;
7473       case MachO::CPU_SUBTYPE_ARM_V5TEJ:
7474         outs() << "      V5TEJ";
7475         break;
7476       case MachO::CPU_SUBTYPE_ARM_XSCALE:
7477         outs() << "     XSCALE";
7478         break;
7479       case MachO::CPU_SUBTYPE_ARM_V6:
7480         outs() << "         V6";
7481         break;
7482       case MachO::CPU_SUBTYPE_ARM_V6M:
7483         outs() << "        V6M";
7484         break;
7485       case MachO::CPU_SUBTYPE_ARM_V7:
7486         outs() << "         V7";
7487         break;
7488       case MachO::CPU_SUBTYPE_ARM_V7EM:
7489         outs() << "       V7EM";
7490         break;
7491       case MachO::CPU_SUBTYPE_ARM_V7K:
7492         outs() << "        V7K";
7493         break;
7494       case MachO::CPU_SUBTYPE_ARM_V7M:
7495         outs() << "        V7M";
7496         break;
7497       case MachO::CPU_SUBTYPE_ARM_V7S:
7498         outs() << "        V7S";
7499         break;
7500       default:
7501         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7502         break;
7503       }
7504       break;
7505     case MachO::CPU_TYPE_ARM64:
7506       outs() << "   ARM64";
7507       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7508       case MachO::CPU_SUBTYPE_ARM64_ALL:
7509         outs() << "        ALL";
7510         break;
7511       default:
7512         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7513         break;
7514       }
7515       break;
7516     case MachO::CPU_TYPE_POWERPC:
7517       outs() << "     PPC";
7518       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7519       case MachO::CPU_SUBTYPE_POWERPC_ALL:
7520         outs() << "        ALL";
7521         break;
7522       default:
7523         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7524         break;
7525       }
7526       break;
7527     case MachO::CPU_TYPE_POWERPC64:
7528       outs() << "   PPC64";
7529       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7530       case MachO::CPU_SUBTYPE_POWERPC_ALL:
7531         outs() << "        ALL";
7532         break;
7533       default:
7534         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7535         break;
7536       }
7537       break;
7538     default:
7539       outs() << format(" %7d", cputype);
7540       outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7541       break;
7542     }
7543     if ((cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64) {
7544       outs() << " LIB64";
7545     } else {
7546       outs() << format("  0x%02" PRIx32,
7547                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
7548     }
7549     switch (filetype) {
7550     case MachO::MH_OBJECT:
7551       outs() << "      OBJECT";
7552       break;
7553     case MachO::MH_EXECUTE:
7554       outs() << "     EXECUTE";
7555       break;
7556     case MachO::MH_FVMLIB:
7557       outs() << "      FVMLIB";
7558       break;
7559     case MachO::MH_CORE:
7560       outs() << "        CORE";
7561       break;
7562     case MachO::MH_PRELOAD:
7563       outs() << "     PRELOAD";
7564       break;
7565     case MachO::MH_DYLIB:
7566       outs() << "       DYLIB";
7567       break;
7568     case MachO::MH_DYLIB_STUB:
7569       outs() << "  DYLIB_STUB";
7570       break;
7571     case MachO::MH_DYLINKER:
7572       outs() << "    DYLINKER";
7573       break;
7574     case MachO::MH_BUNDLE:
7575       outs() << "      BUNDLE";
7576       break;
7577     case MachO::MH_DSYM:
7578       outs() << "        DSYM";
7579       break;
7580     case MachO::MH_KEXT_BUNDLE:
7581       outs() << "  KEXTBUNDLE";
7582       break;
7583     default:
7584       outs() << format("  %10u", filetype);
7585       break;
7586     }
7587     outs() << format(" %5u", ncmds);
7588     outs() << format(" %10u", sizeofcmds);
7589     uint32_t f = flags;
7590     if (f & MachO::MH_NOUNDEFS) {
7591       outs() << "   NOUNDEFS";
7592       f &= ~MachO::MH_NOUNDEFS;
7593     }
7594     if (f & MachO::MH_INCRLINK) {
7595       outs() << " INCRLINK";
7596       f &= ~MachO::MH_INCRLINK;
7597     }
7598     if (f & MachO::MH_DYLDLINK) {
7599       outs() << " DYLDLINK";
7600       f &= ~MachO::MH_DYLDLINK;
7601     }
7602     if (f & MachO::MH_BINDATLOAD) {
7603       outs() << " BINDATLOAD";
7604       f &= ~MachO::MH_BINDATLOAD;
7605     }
7606     if (f & MachO::MH_PREBOUND) {
7607       outs() << " PREBOUND";
7608       f &= ~MachO::MH_PREBOUND;
7609     }
7610     if (f & MachO::MH_SPLIT_SEGS) {
7611       outs() << " SPLIT_SEGS";
7612       f &= ~MachO::MH_SPLIT_SEGS;
7613     }
7614     if (f & MachO::MH_LAZY_INIT) {
7615       outs() << " LAZY_INIT";
7616       f &= ~MachO::MH_LAZY_INIT;
7617     }
7618     if (f & MachO::MH_TWOLEVEL) {
7619       outs() << " TWOLEVEL";
7620       f &= ~MachO::MH_TWOLEVEL;
7621     }
7622     if (f & MachO::MH_FORCE_FLAT) {
7623       outs() << " FORCE_FLAT";
7624       f &= ~MachO::MH_FORCE_FLAT;
7625     }
7626     if (f & MachO::MH_NOMULTIDEFS) {
7627       outs() << " NOMULTIDEFS";
7628       f &= ~MachO::MH_NOMULTIDEFS;
7629     }
7630     if (f & MachO::MH_NOFIXPREBINDING) {
7631       outs() << " NOFIXPREBINDING";
7632       f &= ~MachO::MH_NOFIXPREBINDING;
7633     }
7634     if (f & MachO::MH_PREBINDABLE) {
7635       outs() << " PREBINDABLE";
7636       f &= ~MachO::MH_PREBINDABLE;
7637     }
7638     if (f & MachO::MH_ALLMODSBOUND) {
7639       outs() << " ALLMODSBOUND";
7640       f &= ~MachO::MH_ALLMODSBOUND;
7641     }
7642     if (f & MachO::MH_SUBSECTIONS_VIA_SYMBOLS) {
7643       outs() << " SUBSECTIONS_VIA_SYMBOLS";
7644       f &= ~MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
7645     }
7646     if (f & MachO::MH_CANONICAL) {
7647       outs() << " CANONICAL";
7648       f &= ~MachO::MH_CANONICAL;
7649     }
7650     if (f & MachO::MH_WEAK_DEFINES) {
7651       outs() << " WEAK_DEFINES";
7652       f &= ~MachO::MH_WEAK_DEFINES;
7653     }
7654     if (f & MachO::MH_BINDS_TO_WEAK) {
7655       outs() << " BINDS_TO_WEAK";
7656       f &= ~MachO::MH_BINDS_TO_WEAK;
7657     }
7658     if (f & MachO::MH_ALLOW_STACK_EXECUTION) {
7659       outs() << " ALLOW_STACK_EXECUTION";
7660       f &= ~MachO::MH_ALLOW_STACK_EXECUTION;
7661     }
7662     if (f & MachO::MH_DEAD_STRIPPABLE_DYLIB) {
7663       outs() << " DEAD_STRIPPABLE_DYLIB";
7664       f &= ~MachO::MH_DEAD_STRIPPABLE_DYLIB;
7665     }
7666     if (f & MachO::MH_PIE) {
7667       outs() << " PIE";
7668       f &= ~MachO::MH_PIE;
7669     }
7670     if (f & MachO::MH_NO_REEXPORTED_DYLIBS) {
7671       outs() << " NO_REEXPORTED_DYLIBS";
7672       f &= ~MachO::MH_NO_REEXPORTED_DYLIBS;
7673     }
7674     if (f & MachO::MH_HAS_TLV_DESCRIPTORS) {
7675       outs() << " MH_HAS_TLV_DESCRIPTORS";
7676       f &= ~MachO::MH_HAS_TLV_DESCRIPTORS;
7677     }
7678     if (f & MachO::MH_NO_HEAP_EXECUTION) {
7679       outs() << " MH_NO_HEAP_EXECUTION";
7680       f &= ~MachO::MH_NO_HEAP_EXECUTION;
7681     }
7682     if (f & MachO::MH_APP_EXTENSION_SAFE) {
7683       outs() << " APP_EXTENSION_SAFE";
7684       f &= ~MachO::MH_APP_EXTENSION_SAFE;
7685     }
7686     if (f & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) {
7687       outs() << " NLIST_OUTOFSYNC_WITH_DYLDINFO";
7688       f &= ~MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO;
7689     }
7690     if (f != 0 || flags == 0)
7691       outs() << format(" 0x%08" PRIx32, f);
7692   } else {
7693     outs() << format(" 0x%08" PRIx32, magic);
7694     outs() << format(" %7d", cputype);
7695     outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7696     outs() << format("  0x%02" PRIx32,
7697                      (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
7698     outs() << format("  %10u", filetype);
7699     outs() << format(" %5u", ncmds);
7700     outs() << format(" %10u", sizeofcmds);
7701     outs() << format(" 0x%08" PRIx32, flags);
7702   }
7703   outs() << "\n";
7704 }
7705 
7706 static void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize,
7707                                 StringRef SegName, uint64_t vmaddr,
7708                                 uint64_t vmsize, uint64_t fileoff,
7709                                 uint64_t filesize, uint32_t maxprot,
7710                                 uint32_t initprot, uint32_t nsects,
7711                                 uint32_t flags, uint32_t object_size,
7712                                 bool verbose) {
7713   uint64_t expected_cmdsize;
7714   if (cmd == MachO::LC_SEGMENT) {
7715     outs() << "      cmd LC_SEGMENT\n";
7716     expected_cmdsize = nsects;
7717     expected_cmdsize *= sizeof(struct MachO::section);
7718     expected_cmdsize += sizeof(struct MachO::segment_command);
7719   } else {
7720     outs() << "      cmd LC_SEGMENT_64\n";
7721     expected_cmdsize = nsects;
7722     expected_cmdsize *= sizeof(struct MachO::section_64);
7723     expected_cmdsize += sizeof(struct MachO::segment_command_64);
7724   }
7725   outs() << "  cmdsize " << cmdsize;
7726   if (cmdsize != expected_cmdsize)
7727     outs() << " Inconsistent size\n";
7728   else
7729     outs() << "\n";
7730   outs() << "  segname " << SegName << "\n";
7731   if (cmd == MachO::LC_SEGMENT_64) {
7732     outs() << "   vmaddr " << format("0x%016" PRIx64, vmaddr) << "\n";
7733     outs() << "   vmsize " << format("0x%016" PRIx64, vmsize) << "\n";
7734   } else {
7735     outs() << "   vmaddr " << format("0x%08" PRIx64, vmaddr) << "\n";
7736     outs() << "   vmsize " << format("0x%08" PRIx64, vmsize) << "\n";
7737   }
7738   outs() << "  fileoff " << fileoff;
7739   if (fileoff > object_size)
7740     outs() << " (past end of file)\n";
7741   else
7742     outs() << "\n";
7743   outs() << " filesize " << filesize;
7744   if (fileoff + filesize > object_size)
7745     outs() << " (past end of file)\n";
7746   else
7747     outs() << "\n";
7748   if (verbose) {
7749     if ((maxprot &
7750          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
7751            MachO::VM_PROT_EXECUTE)) != 0)
7752       outs() << "  maxprot ?" << format("0x%08" PRIx32, maxprot) << "\n";
7753     else {
7754       outs() << "  maxprot ";
7755       outs() << ((maxprot & MachO::VM_PROT_READ) ? "r" : "-");
7756       outs() << ((maxprot & MachO::VM_PROT_WRITE) ? "w" : "-");
7757       outs() << ((maxprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
7758     }
7759     if ((initprot &
7760          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
7761            MachO::VM_PROT_EXECUTE)) != 0)
7762       outs() << " initprot ?" << format("0x%08" PRIx32, initprot) << "\n";
7763     else {
7764       outs() << " initprot ";
7765       outs() << ((initprot & MachO::VM_PROT_READ) ? "r" : "-");
7766       outs() << ((initprot & MachO::VM_PROT_WRITE) ? "w" : "-");
7767       outs() << ((initprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
7768     }
7769   } else {
7770     outs() << "  maxprot " << format("0x%08" PRIx32, maxprot) << "\n";
7771     outs() << " initprot " << format("0x%08" PRIx32, initprot) << "\n";
7772   }
7773   outs() << "   nsects " << nsects << "\n";
7774   if (verbose) {
7775     outs() << "    flags";
7776     if (flags == 0)
7777       outs() << " (none)\n";
7778     else {
7779       if (flags & MachO::SG_HIGHVM) {
7780         outs() << " HIGHVM";
7781         flags &= ~MachO::SG_HIGHVM;
7782       }
7783       if (flags & MachO::SG_FVMLIB) {
7784         outs() << " FVMLIB";
7785         flags &= ~MachO::SG_FVMLIB;
7786       }
7787       if (flags & MachO::SG_NORELOC) {
7788         outs() << " NORELOC";
7789         flags &= ~MachO::SG_NORELOC;
7790       }
7791       if (flags & MachO::SG_PROTECTED_VERSION_1) {
7792         outs() << " PROTECTED_VERSION_1";
7793         flags &= ~MachO::SG_PROTECTED_VERSION_1;
7794       }
7795       if (flags)
7796         outs() << format(" 0x%08" PRIx32, flags) << " (unknown flags)\n";
7797       else
7798         outs() << "\n";
7799     }
7800   } else {
7801     outs() << "    flags " << format("0x%" PRIx32, flags) << "\n";
7802   }
7803 }
7804 
7805 static void PrintSection(const char *sectname, const char *segname,
7806                          uint64_t addr, uint64_t size, uint32_t offset,
7807                          uint32_t align, uint32_t reloff, uint32_t nreloc,
7808                          uint32_t flags, uint32_t reserved1, uint32_t reserved2,
7809                          uint32_t cmd, const char *sg_segname,
7810                          uint32_t filetype, uint32_t object_size,
7811                          bool verbose) {
7812   outs() << "Section\n";
7813   outs() << "  sectname " << format("%.16s\n", sectname);
7814   outs() << "   segname " << format("%.16s", segname);
7815   if (filetype != MachO::MH_OBJECT && strncmp(sg_segname, segname, 16) != 0)
7816     outs() << " (does not match segment)\n";
7817   else
7818     outs() << "\n";
7819   if (cmd == MachO::LC_SEGMENT_64) {
7820     outs() << "      addr " << format("0x%016" PRIx64, addr) << "\n";
7821     outs() << "      size " << format("0x%016" PRIx64, size);
7822   } else {
7823     outs() << "      addr " << format("0x%08" PRIx64, addr) << "\n";
7824     outs() << "      size " << format("0x%08" PRIx64, size);
7825   }
7826   if ((flags & MachO::S_ZEROFILL) != 0 && offset + size > object_size)
7827     outs() << " (past end of file)\n";
7828   else
7829     outs() << "\n";
7830   outs() << "    offset " << offset;
7831   if (offset > object_size)
7832     outs() << " (past end of file)\n";
7833   else
7834     outs() << "\n";
7835   uint32_t align_shifted = 1 << align;
7836   outs() << "     align 2^" << align << " (" << align_shifted << ")\n";
7837   outs() << "    reloff " << reloff;
7838   if (reloff > object_size)
7839     outs() << " (past end of file)\n";
7840   else
7841     outs() << "\n";
7842   outs() << "    nreloc " << nreloc;
7843   if (reloff + nreloc * sizeof(struct MachO::relocation_info) > object_size)
7844     outs() << " (past end of file)\n";
7845   else
7846     outs() << "\n";
7847   uint32_t section_type = flags & MachO::SECTION_TYPE;
7848   if (verbose) {
7849     outs() << "      type";
7850     if (section_type == MachO::S_REGULAR)
7851       outs() << " S_REGULAR\n";
7852     else if (section_type == MachO::S_ZEROFILL)
7853       outs() << " S_ZEROFILL\n";
7854     else if (section_type == MachO::S_CSTRING_LITERALS)
7855       outs() << " S_CSTRING_LITERALS\n";
7856     else if (section_type == MachO::S_4BYTE_LITERALS)
7857       outs() << " S_4BYTE_LITERALS\n";
7858     else if (section_type == MachO::S_8BYTE_LITERALS)
7859       outs() << " S_8BYTE_LITERALS\n";
7860     else if (section_type == MachO::S_16BYTE_LITERALS)
7861       outs() << " S_16BYTE_LITERALS\n";
7862     else if (section_type == MachO::S_LITERAL_POINTERS)
7863       outs() << " S_LITERAL_POINTERS\n";
7864     else if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS)
7865       outs() << " S_NON_LAZY_SYMBOL_POINTERS\n";
7866     else if (section_type == MachO::S_LAZY_SYMBOL_POINTERS)
7867       outs() << " S_LAZY_SYMBOL_POINTERS\n";
7868     else if (section_type == MachO::S_SYMBOL_STUBS)
7869       outs() << " S_SYMBOL_STUBS\n";
7870     else if (section_type == MachO::S_MOD_INIT_FUNC_POINTERS)
7871       outs() << " S_MOD_INIT_FUNC_POINTERS\n";
7872     else if (section_type == MachO::S_MOD_TERM_FUNC_POINTERS)
7873       outs() << " S_MOD_TERM_FUNC_POINTERS\n";
7874     else if (section_type == MachO::S_COALESCED)
7875       outs() << " S_COALESCED\n";
7876     else if (section_type == MachO::S_INTERPOSING)
7877       outs() << " S_INTERPOSING\n";
7878     else if (section_type == MachO::S_DTRACE_DOF)
7879       outs() << " S_DTRACE_DOF\n";
7880     else if (section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS)
7881       outs() << " S_LAZY_DYLIB_SYMBOL_POINTERS\n";
7882     else if (section_type == MachO::S_THREAD_LOCAL_REGULAR)
7883       outs() << " S_THREAD_LOCAL_REGULAR\n";
7884     else if (section_type == MachO::S_THREAD_LOCAL_ZEROFILL)
7885       outs() << " S_THREAD_LOCAL_ZEROFILL\n";
7886     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLES)
7887       outs() << " S_THREAD_LOCAL_VARIABLES\n";
7888     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
7889       outs() << " S_THREAD_LOCAL_VARIABLE_POINTERS\n";
7890     else if (section_type == MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS)
7891       outs() << " S_THREAD_LOCAL_INIT_FUNCTION_POINTERS\n";
7892     else
7893       outs() << format("0x%08" PRIx32, section_type) << "\n";
7894     outs() << "attributes";
7895     uint32_t section_attributes = flags & MachO::SECTION_ATTRIBUTES;
7896     if (section_attributes & MachO::S_ATTR_PURE_INSTRUCTIONS)
7897       outs() << " PURE_INSTRUCTIONS";
7898     if (section_attributes & MachO::S_ATTR_NO_TOC)
7899       outs() << " NO_TOC";
7900     if (section_attributes & MachO::S_ATTR_STRIP_STATIC_SYMS)
7901       outs() << " STRIP_STATIC_SYMS";
7902     if (section_attributes & MachO::S_ATTR_NO_DEAD_STRIP)
7903       outs() << " NO_DEAD_STRIP";
7904     if (section_attributes & MachO::S_ATTR_LIVE_SUPPORT)
7905       outs() << " LIVE_SUPPORT";
7906     if (section_attributes & MachO::S_ATTR_SELF_MODIFYING_CODE)
7907       outs() << " SELF_MODIFYING_CODE";
7908     if (section_attributes & MachO::S_ATTR_DEBUG)
7909       outs() << " DEBUG";
7910     if (section_attributes & MachO::S_ATTR_SOME_INSTRUCTIONS)
7911       outs() << " SOME_INSTRUCTIONS";
7912     if (section_attributes & MachO::S_ATTR_EXT_RELOC)
7913       outs() << " EXT_RELOC";
7914     if (section_attributes & MachO::S_ATTR_LOC_RELOC)
7915       outs() << " LOC_RELOC";
7916     if (section_attributes == 0)
7917       outs() << " (none)";
7918     outs() << "\n";
7919   } else
7920     outs() << "     flags " << format("0x%08" PRIx32, flags) << "\n";
7921   outs() << " reserved1 " << reserved1;
7922   if (section_type == MachO::S_SYMBOL_STUBS ||
7923       section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
7924       section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
7925       section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
7926       section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
7927     outs() << " (index into indirect symbol table)\n";
7928   else
7929     outs() << "\n";
7930   outs() << " reserved2 " << reserved2;
7931   if (section_type == MachO::S_SYMBOL_STUBS)
7932     outs() << " (size of stubs)\n";
7933   else
7934     outs() << "\n";
7935 }
7936 
7937 static void PrintSymtabLoadCommand(MachO::symtab_command st, bool Is64Bit,
7938                                    uint32_t object_size) {
7939   outs() << "     cmd LC_SYMTAB\n";
7940   outs() << " cmdsize " << st.cmdsize;
7941   if (st.cmdsize != sizeof(struct MachO::symtab_command))
7942     outs() << " Incorrect size\n";
7943   else
7944     outs() << "\n";
7945   outs() << "  symoff " << st.symoff;
7946   if (st.symoff > object_size)
7947     outs() << " (past end of file)\n";
7948   else
7949     outs() << "\n";
7950   outs() << "   nsyms " << st.nsyms;
7951   uint64_t big_size;
7952   if (Is64Bit) {
7953     big_size = st.nsyms;
7954     big_size *= sizeof(struct MachO::nlist_64);
7955     big_size += st.symoff;
7956     if (big_size > object_size)
7957       outs() << " (past end of file)\n";
7958     else
7959       outs() << "\n";
7960   } else {
7961     big_size = st.nsyms;
7962     big_size *= sizeof(struct MachO::nlist);
7963     big_size += st.symoff;
7964     if (big_size > object_size)
7965       outs() << " (past end of file)\n";
7966     else
7967       outs() << "\n";
7968   }
7969   outs() << "  stroff " << st.stroff;
7970   if (st.stroff > object_size)
7971     outs() << " (past end of file)\n";
7972   else
7973     outs() << "\n";
7974   outs() << " strsize " << st.strsize;
7975   big_size = st.stroff;
7976   big_size += st.strsize;
7977   if (big_size > object_size)
7978     outs() << " (past end of file)\n";
7979   else
7980     outs() << "\n";
7981 }
7982 
7983 static void PrintDysymtabLoadCommand(MachO::dysymtab_command dyst,
7984                                      uint32_t nsyms, uint32_t object_size,
7985                                      bool Is64Bit) {
7986   outs() << "            cmd LC_DYSYMTAB\n";
7987   outs() << "        cmdsize " << dyst.cmdsize;
7988   if (dyst.cmdsize != sizeof(struct MachO::dysymtab_command))
7989     outs() << " Incorrect size\n";
7990   else
7991     outs() << "\n";
7992   outs() << "      ilocalsym " << dyst.ilocalsym;
7993   if (dyst.ilocalsym > nsyms)
7994     outs() << " (greater than the number of symbols)\n";
7995   else
7996     outs() << "\n";
7997   outs() << "      nlocalsym " << dyst.nlocalsym;
7998   uint64_t big_size;
7999   big_size = dyst.ilocalsym;
8000   big_size += dyst.nlocalsym;
8001   if (big_size > nsyms)
8002     outs() << " (past the end of the symbol table)\n";
8003   else
8004     outs() << "\n";
8005   outs() << "     iextdefsym " << dyst.iextdefsym;
8006   if (dyst.iextdefsym > nsyms)
8007     outs() << " (greater than the number of symbols)\n";
8008   else
8009     outs() << "\n";
8010   outs() << "     nextdefsym " << dyst.nextdefsym;
8011   big_size = dyst.iextdefsym;
8012   big_size += dyst.nextdefsym;
8013   if (big_size > nsyms)
8014     outs() << " (past the end of the symbol table)\n";
8015   else
8016     outs() << "\n";
8017   outs() << "      iundefsym " << dyst.iundefsym;
8018   if (dyst.iundefsym > nsyms)
8019     outs() << " (greater than the number of symbols)\n";
8020   else
8021     outs() << "\n";
8022   outs() << "      nundefsym " << dyst.nundefsym;
8023   big_size = dyst.iundefsym;
8024   big_size += dyst.nundefsym;
8025   if (big_size > nsyms)
8026     outs() << " (past the end of the symbol table)\n";
8027   else
8028     outs() << "\n";
8029   outs() << "         tocoff " << dyst.tocoff;
8030   if (dyst.tocoff > object_size)
8031     outs() << " (past end of file)\n";
8032   else
8033     outs() << "\n";
8034   outs() << "           ntoc " << dyst.ntoc;
8035   big_size = dyst.ntoc;
8036   big_size *= sizeof(struct MachO::dylib_table_of_contents);
8037   big_size += dyst.tocoff;
8038   if (big_size > object_size)
8039     outs() << " (past end of file)\n";
8040   else
8041     outs() << "\n";
8042   outs() << "      modtaboff " << dyst.modtaboff;
8043   if (dyst.modtaboff > object_size)
8044     outs() << " (past end of file)\n";
8045   else
8046     outs() << "\n";
8047   outs() << "        nmodtab " << dyst.nmodtab;
8048   uint64_t modtabend;
8049   if (Is64Bit) {
8050     modtabend = dyst.nmodtab;
8051     modtabend *= sizeof(struct MachO::dylib_module_64);
8052     modtabend += dyst.modtaboff;
8053   } else {
8054     modtabend = dyst.nmodtab;
8055     modtabend *= sizeof(struct MachO::dylib_module);
8056     modtabend += dyst.modtaboff;
8057   }
8058   if (modtabend > object_size)
8059     outs() << " (past end of file)\n";
8060   else
8061     outs() << "\n";
8062   outs() << "   extrefsymoff " << dyst.extrefsymoff;
8063   if (dyst.extrefsymoff > object_size)
8064     outs() << " (past end of file)\n";
8065   else
8066     outs() << "\n";
8067   outs() << "    nextrefsyms " << dyst.nextrefsyms;
8068   big_size = dyst.nextrefsyms;
8069   big_size *= sizeof(struct MachO::dylib_reference);
8070   big_size += dyst.extrefsymoff;
8071   if (big_size > object_size)
8072     outs() << " (past end of file)\n";
8073   else
8074     outs() << "\n";
8075   outs() << " indirectsymoff " << dyst.indirectsymoff;
8076   if (dyst.indirectsymoff > object_size)
8077     outs() << " (past end of file)\n";
8078   else
8079     outs() << "\n";
8080   outs() << "  nindirectsyms " << dyst.nindirectsyms;
8081   big_size = dyst.nindirectsyms;
8082   big_size *= sizeof(uint32_t);
8083   big_size += dyst.indirectsymoff;
8084   if (big_size > object_size)
8085     outs() << " (past end of file)\n";
8086   else
8087     outs() << "\n";
8088   outs() << "      extreloff " << dyst.extreloff;
8089   if (dyst.extreloff > object_size)
8090     outs() << " (past end of file)\n";
8091   else
8092     outs() << "\n";
8093   outs() << "        nextrel " << dyst.nextrel;
8094   big_size = dyst.nextrel;
8095   big_size *= sizeof(struct MachO::relocation_info);
8096   big_size += dyst.extreloff;
8097   if (big_size > object_size)
8098     outs() << " (past end of file)\n";
8099   else
8100     outs() << "\n";
8101   outs() << "      locreloff " << dyst.locreloff;
8102   if (dyst.locreloff > object_size)
8103     outs() << " (past end of file)\n";
8104   else
8105     outs() << "\n";
8106   outs() << "        nlocrel " << dyst.nlocrel;
8107   big_size = dyst.nlocrel;
8108   big_size *= sizeof(struct MachO::relocation_info);
8109   big_size += dyst.locreloff;
8110   if (big_size > object_size)
8111     outs() << " (past end of file)\n";
8112   else
8113     outs() << "\n";
8114 }
8115 
8116 static void PrintDyldInfoLoadCommand(MachO::dyld_info_command dc,
8117                                      uint32_t object_size) {
8118   if (dc.cmd == MachO::LC_DYLD_INFO)
8119     outs() << "            cmd LC_DYLD_INFO\n";
8120   else
8121     outs() << "            cmd LC_DYLD_INFO_ONLY\n";
8122   outs() << "        cmdsize " << dc.cmdsize;
8123   if (dc.cmdsize != sizeof(struct MachO::dyld_info_command))
8124     outs() << " Incorrect size\n";
8125   else
8126     outs() << "\n";
8127   outs() << "     rebase_off " << dc.rebase_off;
8128   if (dc.rebase_off > object_size)
8129     outs() << " (past end of file)\n";
8130   else
8131     outs() << "\n";
8132   outs() << "    rebase_size " << dc.rebase_size;
8133   uint64_t big_size;
8134   big_size = dc.rebase_off;
8135   big_size += dc.rebase_size;
8136   if (big_size > object_size)
8137     outs() << " (past end of file)\n";
8138   else
8139     outs() << "\n";
8140   outs() << "       bind_off " << dc.bind_off;
8141   if (dc.bind_off > object_size)
8142     outs() << " (past end of file)\n";
8143   else
8144     outs() << "\n";
8145   outs() << "      bind_size " << dc.bind_size;
8146   big_size = dc.bind_off;
8147   big_size += dc.bind_size;
8148   if (big_size > object_size)
8149     outs() << " (past end of file)\n";
8150   else
8151     outs() << "\n";
8152   outs() << "  weak_bind_off " << dc.weak_bind_off;
8153   if (dc.weak_bind_off > object_size)
8154     outs() << " (past end of file)\n";
8155   else
8156     outs() << "\n";
8157   outs() << " weak_bind_size " << dc.weak_bind_size;
8158   big_size = dc.weak_bind_off;
8159   big_size += dc.weak_bind_size;
8160   if (big_size > object_size)
8161     outs() << " (past end of file)\n";
8162   else
8163     outs() << "\n";
8164   outs() << "  lazy_bind_off " << dc.lazy_bind_off;
8165   if (dc.lazy_bind_off > object_size)
8166     outs() << " (past end of file)\n";
8167   else
8168     outs() << "\n";
8169   outs() << " lazy_bind_size " << dc.lazy_bind_size;
8170   big_size = dc.lazy_bind_off;
8171   big_size += dc.lazy_bind_size;
8172   if (big_size > object_size)
8173     outs() << " (past end of file)\n";
8174   else
8175     outs() << "\n";
8176   outs() << "     export_off " << dc.export_off;
8177   if (dc.export_off > object_size)
8178     outs() << " (past end of file)\n";
8179   else
8180     outs() << "\n";
8181   outs() << "    export_size " << dc.export_size;
8182   big_size = dc.export_off;
8183   big_size += dc.export_size;
8184   if (big_size > object_size)
8185     outs() << " (past end of file)\n";
8186   else
8187     outs() << "\n";
8188 }
8189 
8190 static void PrintDyldLoadCommand(MachO::dylinker_command dyld,
8191                                  const char *Ptr) {
8192   if (dyld.cmd == MachO::LC_ID_DYLINKER)
8193     outs() << "          cmd LC_ID_DYLINKER\n";
8194   else if (dyld.cmd == MachO::LC_LOAD_DYLINKER)
8195     outs() << "          cmd LC_LOAD_DYLINKER\n";
8196   else if (dyld.cmd == MachO::LC_DYLD_ENVIRONMENT)
8197     outs() << "          cmd LC_DYLD_ENVIRONMENT\n";
8198   else
8199     outs() << "          cmd ?(" << dyld.cmd << ")\n";
8200   outs() << "      cmdsize " << dyld.cmdsize;
8201   if (dyld.cmdsize < sizeof(struct MachO::dylinker_command))
8202     outs() << " Incorrect size\n";
8203   else
8204     outs() << "\n";
8205   if (dyld.name >= dyld.cmdsize)
8206     outs() << "         name ?(bad offset " << dyld.name << ")\n";
8207   else {
8208     const char *P = (const char *)(Ptr) + dyld.name;
8209     outs() << "         name " << P << " (offset " << dyld.name << ")\n";
8210   }
8211 }
8212 
8213 static void PrintUuidLoadCommand(MachO::uuid_command uuid) {
8214   outs() << "     cmd LC_UUID\n";
8215   outs() << " cmdsize " << uuid.cmdsize;
8216   if (uuid.cmdsize != sizeof(struct MachO::uuid_command))
8217     outs() << " Incorrect size\n";
8218   else
8219     outs() << "\n";
8220   outs() << "    uuid ";
8221   for (int i = 0; i < 16; ++i) {
8222     outs() << format("%02" PRIX32, uuid.uuid[i]);
8223     if (i == 3 || i == 5 || i == 7 || i == 9)
8224       outs() << "-";
8225   }
8226   outs() << "\n";
8227 }
8228 
8229 static void PrintRpathLoadCommand(MachO::rpath_command rpath, const char *Ptr) {
8230   outs() << "          cmd LC_RPATH\n";
8231   outs() << "      cmdsize " << rpath.cmdsize;
8232   if (rpath.cmdsize < sizeof(struct MachO::rpath_command))
8233     outs() << " Incorrect size\n";
8234   else
8235     outs() << "\n";
8236   if (rpath.path >= rpath.cmdsize)
8237     outs() << "         path ?(bad offset " << rpath.path << ")\n";
8238   else {
8239     const char *P = (const char *)(Ptr) + rpath.path;
8240     outs() << "         path " << P << " (offset " << rpath.path << ")\n";
8241   }
8242 }
8243 
8244 static void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
8245   StringRef LoadCmdName;
8246   switch (vd.cmd) {
8247   case MachO::LC_VERSION_MIN_MACOSX:
8248     LoadCmdName = "LC_VERSION_MIN_MACOSX";
8249     break;
8250   case MachO::LC_VERSION_MIN_IPHONEOS:
8251     LoadCmdName = "LC_VERSION_MIN_IPHONEOS";
8252     break;
8253   case MachO::LC_VERSION_MIN_TVOS:
8254     LoadCmdName = "LC_VERSION_MIN_TVOS";
8255     break;
8256   case MachO::LC_VERSION_MIN_WATCHOS:
8257     LoadCmdName = "LC_VERSION_MIN_WATCHOS";
8258     break;
8259   default:
8260     llvm_unreachable("Unknown version min load command");
8261   }
8262 
8263   outs() << "      cmd " << LoadCmdName << '\n';
8264   outs() << "  cmdsize " << vd.cmdsize;
8265   if (vd.cmdsize != sizeof(struct MachO::version_min_command))
8266     outs() << " Incorrect size\n";
8267   else
8268     outs() << "\n";
8269   outs() << "  version "
8270          << MachOObjectFile::getVersionMinMajor(vd, false) << "."
8271          << MachOObjectFile::getVersionMinMinor(vd, false);
8272   uint32_t Update = MachOObjectFile::getVersionMinUpdate(vd, false);
8273   if (Update != 0)
8274     outs() << "." << Update;
8275   outs() << "\n";
8276   if (vd.sdk == 0)
8277     outs() << "      sdk n/a";
8278   else {
8279     outs() << "      sdk "
8280            << MachOObjectFile::getVersionMinMajor(vd, true) << "."
8281            << MachOObjectFile::getVersionMinMinor(vd, true);
8282   }
8283   Update = MachOObjectFile::getVersionMinUpdate(vd, true);
8284   if (Update != 0)
8285     outs() << "." << Update;
8286   outs() << "\n";
8287 }
8288 
8289 static void PrintNoteLoadCommand(MachO::note_command Nt) {
8290   outs() << "       cmd LC_NOTE\n";
8291   outs() << "   cmdsize " << Nt.cmdsize;
8292   if (Nt.cmdsize != sizeof(struct MachO::note_command))
8293     outs() << " Incorrect size\n";
8294   else
8295     outs() << "\n";
8296   const char *d = Nt.data_owner;
8297   outs() << "data_owner " << format("%.16s\n", d);
8298   outs() << "    offset " << Nt.offset << "\n";
8299   outs() << "      size " << Nt.size << "\n";
8300 }
8301 
8302 static void PrintBuildToolVersion(MachO::build_tool_version bv) {
8303   outs() << "      tool " << MachOObjectFile::getBuildTool(bv.tool) << "\n";
8304   outs() << "   version " << MachOObjectFile::getVersionString(bv.version)
8305          << "\n";
8306 }
8307 
8308 static void PrintBuildVersionLoadCommand(const MachOObjectFile *obj,
8309                                          MachO::build_version_command bd) {
8310   outs() << "       cmd LC_BUILD_VERSION\n";
8311   outs() << "   cmdsize " << bd.cmdsize;
8312   if (bd.cmdsize !=
8313       sizeof(struct MachO::build_version_command) +
8314           bd.ntools * sizeof(struct MachO::build_tool_version))
8315     outs() << " Incorrect size\n";
8316   else
8317     outs() << "\n";
8318   outs() << "  platform " << MachOObjectFile::getBuildPlatform(bd.platform)
8319          << "\n";
8320   if (bd.sdk)
8321     outs() << "       sdk " << MachOObjectFile::getVersionString(bd.sdk)
8322            << "\n";
8323   else
8324     outs() << "       sdk n/a\n";
8325   outs() << "     minos " << MachOObjectFile::getVersionString(bd.minos)
8326          << "\n";
8327   outs() << "    ntools " << bd.ntools << "\n";
8328   for (unsigned i = 0; i < bd.ntools; ++i) {
8329     MachO::build_tool_version bv = obj->getBuildToolVersion(i);
8330     PrintBuildToolVersion(bv);
8331   }
8332 }
8333 
8334 static void PrintSourceVersionCommand(MachO::source_version_command sd) {
8335   outs() << "      cmd LC_SOURCE_VERSION\n";
8336   outs() << "  cmdsize " << sd.cmdsize;
8337   if (sd.cmdsize != sizeof(struct MachO::source_version_command))
8338     outs() << " Incorrect size\n";
8339   else
8340     outs() << "\n";
8341   uint64_t a = (sd.version >> 40) & 0xffffff;
8342   uint64_t b = (sd.version >> 30) & 0x3ff;
8343   uint64_t c = (sd.version >> 20) & 0x3ff;
8344   uint64_t d = (sd.version >> 10) & 0x3ff;
8345   uint64_t e = sd.version & 0x3ff;
8346   outs() << "  version " << a << "." << b;
8347   if (e != 0)
8348     outs() << "." << c << "." << d << "." << e;
8349   else if (d != 0)
8350     outs() << "." << c << "." << d;
8351   else if (c != 0)
8352     outs() << "." << c;
8353   outs() << "\n";
8354 }
8355 
8356 static void PrintEntryPointCommand(MachO::entry_point_command ep) {
8357   outs() << "       cmd LC_MAIN\n";
8358   outs() << "   cmdsize " << ep.cmdsize;
8359   if (ep.cmdsize != sizeof(struct MachO::entry_point_command))
8360     outs() << " Incorrect size\n";
8361   else
8362     outs() << "\n";
8363   outs() << "  entryoff " << ep.entryoff << "\n";
8364   outs() << " stacksize " << ep.stacksize << "\n";
8365 }
8366 
8367 static void PrintEncryptionInfoCommand(MachO::encryption_info_command ec,
8368                                        uint32_t object_size) {
8369   outs() << "          cmd LC_ENCRYPTION_INFO\n";
8370   outs() << "      cmdsize " << ec.cmdsize;
8371   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command))
8372     outs() << " Incorrect size\n";
8373   else
8374     outs() << "\n";
8375   outs() << "     cryptoff " << ec.cryptoff;
8376   if (ec.cryptoff > object_size)
8377     outs() << " (past end of file)\n";
8378   else
8379     outs() << "\n";
8380   outs() << "    cryptsize " << ec.cryptsize;
8381   if (ec.cryptsize > object_size)
8382     outs() << " (past end of file)\n";
8383   else
8384     outs() << "\n";
8385   outs() << "      cryptid " << ec.cryptid << "\n";
8386 }
8387 
8388 static void PrintEncryptionInfoCommand64(MachO::encryption_info_command_64 ec,
8389                                          uint32_t object_size) {
8390   outs() << "          cmd LC_ENCRYPTION_INFO_64\n";
8391   outs() << "      cmdsize " << ec.cmdsize;
8392   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command_64))
8393     outs() << " Incorrect size\n";
8394   else
8395     outs() << "\n";
8396   outs() << "     cryptoff " << ec.cryptoff;
8397   if (ec.cryptoff > object_size)
8398     outs() << " (past end of file)\n";
8399   else
8400     outs() << "\n";
8401   outs() << "    cryptsize " << ec.cryptsize;
8402   if (ec.cryptsize > object_size)
8403     outs() << " (past end of file)\n";
8404   else
8405     outs() << "\n";
8406   outs() << "      cryptid " << ec.cryptid << "\n";
8407   outs() << "          pad " << ec.pad << "\n";
8408 }
8409 
8410 static void PrintLinkerOptionCommand(MachO::linker_option_command lo,
8411                                      const char *Ptr) {
8412   outs() << "     cmd LC_LINKER_OPTION\n";
8413   outs() << " cmdsize " << lo.cmdsize;
8414   if (lo.cmdsize < sizeof(struct MachO::linker_option_command))
8415     outs() << " Incorrect size\n";
8416   else
8417     outs() << "\n";
8418   outs() << "   count " << lo.count << "\n";
8419   const char *string = Ptr + sizeof(struct MachO::linker_option_command);
8420   uint32_t left = lo.cmdsize - sizeof(struct MachO::linker_option_command);
8421   uint32_t i = 0;
8422   while (left > 0) {
8423     while (*string == '\0' && left > 0) {
8424       string++;
8425       left--;
8426     }
8427     if (left > 0) {
8428       i++;
8429       outs() << "  string #" << i << " " << format("%.*s\n", left, string);
8430       uint32_t NullPos = StringRef(string, left).find('\0');
8431       uint32_t len = std::min(NullPos, left) + 1;
8432       string += len;
8433       left -= len;
8434     }
8435   }
8436   if (lo.count != i)
8437     outs() << "   count " << lo.count << " does not match number of strings "
8438            << i << "\n";
8439 }
8440 
8441 static void PrintSubFrameworkCommand(MachO::sub_framework_command sub,
8442                                      const char *Ptr) {
8443   outs() << "          cmd LC_SUB_FRAMEWORK\n";
8444   outs() << "      cmdsize " << sub.cmdsize;
8445   if (sub.cmdsize < sizeof(struct MachO::sub_framework_command))
8446     outs() << " Incorrect size\n";
8447   else
8448     outs() << "\n";
8449   if (sub.umbrella < sub.cmdsize) {
8450     const char *P = Ptr + sub.umbrella;
8451     outs() << "     umbrella " << P << " (offset " << sub.umbrella << ")\n";
8452   } else {
8453     outs() << "     umbrella ?(bad offset " << sub.umbrella << ")\n";
8454   }
8455 }
8456 
8457 static void PrintSubUmbrellaCommand(MachO::sub_umbrella_command sub,
8458                                     const char *Ptr) {
8459   outs() << "          cmd LC_SUB_UMBRELLA\n";
8460   outs() << "      cmdsize " << sub.cmdsize;
8461   if (sub.cmdsize < sizeof(struct MachO::sub_umbrella_command))
8462     outs() << " Incorrect size\n";
8463   else
8464     outs() << "\n";
8465   if (sub.sub_umbrella < sub.cmdsize) {
8466     const char *P = Ptr + sub.sub_umbrella;
8467     outs() << " sub_umbrella " << P << " (offset " << sub.sub_umbrella << ")\n";
8468   } else {
8469     outs() << " sub_umbrella ?(bad offset " << sub.sub_umbrella << ")\n";
8470   }
8471 }
8472 
8473 static void PrintSubLibraryCommand(MachO::sub_library_command sub,
8474                                    const char *Ptr) {
8475   outs() << "          cmd LC_SUB_LIBRARY\n";
8476   outs() << "      cmdsize " << sub.cmdsize;
8477   if (sub.cmdsize < sizeof(struct MachO::sub_library_command))
8478     outs() << " Incorrect size\n";
8479   else
8480     outs() << "\n";
8481   if (sub.sub_library < sub.cmdsize) {
8482     const char *P = Ptr + sub.sub_library;
8483     outs() << "  sub_library " << P << " (offset " << sub.sub_library << ")\n";
8484   } else {
8485     outs() << "  sub_library ?(bad offset " << sub.sub_library << ")\n";
8486   }
8487 }
8488 
8489 static void PrintSubClientCommand(MachO::sub_client_command sub,
8490                                   const char *Ptr) {
8491   outs() << "          cmd LC_SUB_CLIENT\n";
8492   outs() << "      cmdsize " << sub.cmdsize;
8493   if (sub.cmdsize < sizeof(struct MachO::sub_client_command))
8494     outs() << " Incorrect size\n";
8495   else
8496     outs() << "\n";
8497   if (sub.client < sub.cmdsize) {
8498     const char *P = Ptr + sub.client;
8499     outs() << "       client " << P << " (offset " << sub.client << ")\n";
8500   } else {
8501     outs() << "       client ?(bad offset " << sub.client << ")\n";
8502   }
8503 }
8504 
8505 static void PrintRoutinesCommand(MachO::routines_command r) {
8506   outs() << "          cmd LC_ROUTINES\n";
8507   outs() << "      cmdsize " << r.cmdsize;
8508   if (r.cmdsize != sizeof(struct MachO::routines_command))
8509     outs() << " Incorrect size\n";
8510   else
8511     outs() << "\n";
8512   outs() << " init_address " << format("0x%08" PRIx32, r.init_address) << "\n";
8513   outs() << "  init_module " << r.init_module << "\n";
8514   outs() << "    reserved1 " << r.reserved1 << "\n";
8515   outs() << "    reserved2 " << r.reserved2 << "\n";
8516   outs() << "    reserved3 " << r.reserved3 << "\n";
8517   outs() << "    reserved4 " << r.reserved4 << "\n";
8518   outs() << "    reserved5 " << r.reserved5 << "\n";
8519   outs() << "    reserved6 " << r.reserved6 << "\n";
8520 }
8521 
8522 static void PrintRoutinesCommand64(MachO::routines_command_64 r) {
8523   outs() << "          cmd LC_ROUTINES_64\n";
8524   outs() << "      cmdsize " << r.cmdsize;
8525   if (r.cmdsize != sizeof(struct MachO::routines_command_64))
8526     outs() << " Incorrect size\n";
8527   else
8528     outs() << "\n";
8529   outs() << " init_address " << format("0x%016" PRIx64, r.init_address) << "\n";
8530   outs() << "  init_module " << r.init_module << "\n";
8531   outs() << "    reserved1 " << r.reserved1 << "\n";
8532   outs() << "    reserved2 " << r.reserved2 << "\n";
8533   outs() << "    reserved3 " << r.reserved3 << "\n";
8534   outs() << "    reserved4 " << r.reserved4 << "\n";
8535   outs() << "    reserved5 " << r.reserved5 << "\n";
8536   outs() << "    reserved6 " << r.reserved6 << "\n";
8537 }
8538 
8539 static void Print_x86_thread_state32_t(MachO::x86_thread_state32_t &cpu32) {
8540   outs() << "\t    eax " << format("0x%08" PRIx32, cpu32.eax);
8541   outs() << " ebx    " << format("0x%08" PRIx32, cpu32.ebx);
8542   outs() << " ecx " << format("0x%08" PRIx32, cpu32.ecx);
8543   outs() << " edx " << format("0x%08" PRIx32, cpu32.edx) << "\n";
8544   outs() << "\t    edi " << format("0x%08" PRIx32, cpu32.edi);
8545   outs() << " esi    " << format("0x%08" PRIx32, cpu32.esi);
8546   outs() << " ebp " << format("0x%08" PRIx32, cpu32.ebp);
8547   outs() << " esp " << format("0x%08" PRIx32, cpu32.esp) << "\n";
8548   outs() << "\t    ss  " << format("0x%08" PRIx32, cpu32.ss);
8549   outs() << " eflags " << format("0x%08" PRIx32, cpu32.eflags);
8550   outs() << " eip " << format("0x%08" PRIx32, cpu32.eip);
8551   outs() << " cs  " << format("0x%08" PRIx32, cpu32.cs) << "\n";
8552   outs() << "\t    ds  " << format("0x%08" PRIx32, cpu32.ds);
8553   outs() << " es     " << format("0x%08" PRIx32, cpu32.es);
8554   outs() << " fs  " << format("0x%08" PRIx32, cpu32.fs);
8555   outs() << " gs  " << format("0x%08" PRIx32, cpu32.gs) << "\n";
8556 }
8557 
8558 static void Print_x86_thread_state64_t(MachO::x86_thread_state64_t &cpu64) {
8559   outs() << "   rax  " << format("0x%016" PRIx64, cpu64.rax);
8560   outs() << " rbx " << format("0x%016" PRIx64, cpu64.rbx);
8561   outs() << " rcx  " << format("0x%016" PRIx64, cpu64.rcx) << "\n";
8562   outs() << "   rdx  " << format("0x%016" PRIx64, cpu64.rdx);
8563   outs() << " rdi " << format("0x%016" PRIx64, cpu64.rdi);
8564   outs() << " rsi  " << format("0x%016" PRIx64, cpu64.rsi) << "\n";
8565   outs() << "   rbp  " << format("0x%016" PRIx64, cpu64.rbp);
8566   outs() << " rsp " << format("0x%016" PRIx64, cpu64.rsp);
8567   outs() << " r8   " << format("0x%016" PRIx64, cpu64.r8) << "\n";
8568   outs() << "    r9  " << format("0x%016" PRIx64, cpu64.r9);
8569   outs() << " r10 " << format("0x%016" PRIx64, cpu64.r10);
8570   outs() << " r11  " << format("0x%016" PRIx64, cpu64.r11) << "\n";
8571   outs() << "   r12  " << format("0x%016" PRIx64, cpu64.r12);
8572   outs() << " r13 " << format("0x%016" PRIx64, cpu64.r13);
8573   outs() << " r14  " << format("0x%016" PRIx64, cpu64.r14) << "\n";
8574   outs() << "   r15  " << format("0x%016" PRIx64, cpu64.r15);
8575   outs() << " rip " << format("0x%016" PRIx64, cpu64.rip) << "\n";
8576   outs() << "rflags  " << format("0x%016" PRIx64, cpu64.rflags);
8577   outs() << " cs  " << format("0x%016" PRIx64, cpu64.cs);
8578   outs() << " fs   " << format("0x%016" PRIx64, cpu64.fs) << "\n";
8579   outs() << "    gs  " << format("0x%016" PRIx64, cpu64.gs) << "\n";
8580 }
8581 
8582 static void Print_mmst_reg(MachO::mmst_reg_t &r) {
8583   uint32_t f;
8584   outs() << "\t      mmst_reg  ";
8585   for (f = 0; f < 10; f++)
8586     outs() << format("%02" PRIx32, (r.mmst_reg[f] & 0xff)) << " ";
8587   outs() << "\n";
8588   outs() << "\t      mmst_rsrv ";
8589   for (f = 0; f < 6; f++)
8590     outs() << format("%02" PRIx32, (r.mmst_rsrv[f] & 0xff)) << " ";
8591   outs() << "\n";
8592 }
8593 
8594 static void Print_xmm_reg(MachO::xmm_reg_t &r) {
8595   uint32_t f;
8596   outs() << "\t      xmm_reg ";
8597   for (f = 0; f < 16; f++)
8598     outs() << format("%02" PRIx32, (r.xmm_reg[f] & 0xff)) << " ";
8599   outs() << "\n";
8600 }
8601 
8602 static void Print_x86_float_state_t(MachO::x86_float_state64_t &fpu) {
8603   outs() << "\t    fpu_reserved[0] " << fpu.fpu_reserved[0];
8604   outs() << " fpu_reserved[1] " << fpu.fpu_reserved[1] << "\n";
8605   outs() << "\t    control: invalid " << fpu.fpu_fcw.invalid;
8606   outs() << " denorm " << fpu.fpu_fcw.denorm;
8607   outs() << " zdiv " << fpu.fpu_fcw.zdiv;
8608   outs() << " ovrfl " << fpu.fpu_fcw.ovrfl;
8609   outs() << " undfl " << fpu.fpu_fcw.undfl;
8610   outs() << " precis " << fpu.fpu_fcw.precis << "\n";
8611   outs() << "\t\t     pc ";
8612   if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_24B)
8613     outs() << "FP_PREC_24B ";
8614   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_53B)
8615     outs() << "FP_PREC_53B ";
8616   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_64B)
8617     outs() << "FP_PREC_64B ";
8618   else
8619     outs() << fpu.fpu_fcw.pc << " ";
8620   outs() << "rc ";
8621   if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_NEAR)
8622     outs() << "FP_RND_NEAR ";
8623   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_DOWN)
8624     outs() << "FP_RND_DOWN ";
8625   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_UP)
8626     outs() << "FP_RND_UP ";
8627   else if (fpu.fpu_fcw.rc == MachO::x86_FP_CHOP)
8628     outs() << "FP_CHOP ";
8629   outs() << "\n";
8630   outs() << "\t    status: invalid " << fpu.fpu_fsw.invalid;
8631   outs() << " denorm " << fpu.fpu_fsw.denorm;
8632   outs() << " zdiv " << fpu.fpu_fsw.zdiv;
8633   outs() << " ovrfl " << fpu.fpu_fsw.ovrfl;
8634   outs() << " undfl " << fpu.fpu_fsw.undfl;
8635   outs() << " precis " << fpu.fpu_fsw.precis;
8636   outs() << " stkflt " << fpu.fpu_fsw.stkflt << "\n";
8637   outs() << "\t            errsumm " << fpu.fpu_fsw.errsumm;
8638   outs() << " c0 " << fpu.fpu_fsw.c0;
8639   outs() << " c1 " << fpu.fpu_fsw.c1;
8640   outs() << " c2 " << fpu.fpu_fsw.c2;
8641   outs() << " tos " << fpu.fpu_fsw.tos;
8642   outs() << " c3 " << fpu.fpu_fsw.c3;
8643   outs() << " busy " << fpu.fpu_fsw.busy << "\n";
8644   outs() << "\t    fpu_ftw " << format("0x%02" PRIx32, fpu.fpu_ftw);
8645   outs() << " fpu_rsrv1 " << format("0x%02" PRIx32, fpu.fpu_rsrv1);
8646   outs() << " fpu_fop " << format("0x%04" PRIx32, fpu.fpu_fop);
8647   outs() << " fpu_ip " << format("0x%08" PRIx32, fpu.fpu_ip) << "\n";
8648   outs() << "\t    fpu_cs " << format("0x%04" PRIx32, fpu.fpu_cs);
8649   outs() << " fpu_rsrv2 " << format("0x%04" PRIx32, fpu.fpu_rsrv2);
8650   outs() << " fpu_dp " << format("0x%08" PRIx32, fpu.fpu_dp);
8651   outs() << " fpu_ds " << format("0x%04" PRIx32, fpu.fpu_ds) << "\n";
8652   outs() << "\t    fpu_rsrv3 " << format("0x%04" PRIx32, fpu.fpu_rsrv3);
8653   outs() << " fpu_mxcsr " << format("0x%08" PRIx32, fpu.fpu_mxcsr);
8654   outs() << " fpu_mxcsrmask " << format("0x%08" PRIx32, fpu.fpu_mxcsrmask);
8655   outs() << "\n";
8656   outs() << "\t    fpu_stmm0:\n";
8657   Print_mmst_reg(fpu.fpu_stmm0);
8658   outs() << "\t    fpu_stmm1:\n";
8659   Print_mmst_reg(fpu.fpu_stmm1);
8660   outs() << "\t    fpu_stmm2:\n";
8661   Print_mmst_reg(fpu.fpu_stmm2);
8662   outs() << "\t    fpu_stmm3:\n";
8663   Print_mmst_reg(fpu.fpu_stmm3);
8664   outs() << "\t    fpu_stmm4:\n";
8665   Print_mmst_reg(fpu.fpu_stmm4);
8666   outs() << "\t    fpu_stmm5:\n";
8667   Print_mmst_reg(fpu.fpu_stmm5);
8668   outs() << "\t    fpu_stmm6:\n";
8669   Print_mmst_reg(fpu.fpu_stmm6);
8670   outs() << "\t    fpu_stmm7:\n";
8671   Print_mmst_reg(fpu.fpu_stmm7);
8672   outs() << "\t    fpu_xmm0:\n";
8673   Print_xmm_reg(fpu.fpu_xmm0);
8674   outs() << "\t    fpu_xmm1:\n";
8675   Print_xmm_reg(fpu.fpu_xmm1);
8676   outs() << "\t    fpu_xmm2:\n";
8677   Print_xmm_reg(fpu.fpu_xmm2);
8678   outs() << "\t    fpu_xmm3:\n";
8679   Print_xmm_reg(fpu.fpu_xmm3);
8680   outs() << "\t    fpu_xmm4:\n";
8681   Print_xmm_reg(fpu.fpu_xmm4);
8682   outs() << "\t    fpu_xmm5:\n";
8683   Print_xmm_reg(fpu.fpu_xmm5);
8684   outs() << "\t    fpu_xmm6:\n";
8685   Print_xmm_reg(fpu.fpu_xmm6);
8686   outs() << "\t    fpu_xmm7:\n";
8687   Print_xmm_reg(fpu.fpu_xmm7);
8688   outs() << "\t    fpu_xmm8:\n";
8689   Print_xmm_reg(fpu.fpu_xmm8);
8690   outs() << "\t    fpu_xmm9:\n";
8691   Print_xmm_reg(fpu.fpu_xmm9);
8692   outs() << "\t    fpu_xmm10:\n";
8693   Print_xmm_reg(fpu.fpu_xmm10);
8694   outs() << "\t    fpu_xmm11:\n";
8695   Print_xmm_reg(fpu.fpu_xmm11);
8696   outs() << "\t    fpu_xmm12:\n";
8697   Print_xmm_reg(fpu.fpu_xmm12);
8698   outs() << "\t    fpu_xmm13:\n";
8699   Print_xmm_reg(fpu.fpu_xmm13);
8700   outs() << "\t    fpu_xmm14:\n";
8701   Print_xmm_reg(fpu.fpu_xmm14);
8702   outs() << "\t    fpu_xmm15:\n";
8703   Print_xmm_reg(fpu.fpu_xmm15);
8704   outs() << "\t    fpu_rsrv4:\n";
8705   for (uint32_t f = 0; f < 6; f++) {
8706     outs() << "\t            ";
8707     for (uint32_t g = 0; g < 16; g++)
8708       outs() << format("%02" PRIx32, fpu.fpu_rsrv4[f * g]) << " ";
8709     outs() << "\n";
8710   }
8711   outs() << "\t    fpu_reserved1 " << format("0x%08" PRIx32, fpu.fpu_reserved1);
8712   outs() << "\n";
8713 }
8714 
8715 static void Print_x86_exception_state_t(MachO::x86_exception_state64_t &exc64) {
8716   outs() << "\t    trapno " << format("0x%08" PRIx32, exc64.trapno);
8717   outs() << " err " << format("0x%08" PRIx32, exc64.err);
8718   outs() << " faultvaddr " << format("0x%016" PRIx64, exc64.faultvaddr) << "\n";
8719 }
8720 
8721 static void Print_arm_thread_state32_t(MachO::arm_thread_state32_t &cpu32) {
8722   outs() << "\t    r0  " << format("0x%08" PRIx32, cpu32.r[0]);
8723   outs() << " r1     "   << format("0x%08" PRIx32, cpu32.r[1]);
8724   outs() << " r2  "      << format("0x%08" PRIx32, cpu32.r[2]);
8725   outs() << " r3  "      << format("0x%08" PRIx32, cpu32.r[3]) << "\n";
8726   outs() << "\t    r4  " << format("0x%08" PRIx32, cpu32.r[4]);
8727   outs() << " r5     "   << format("0x%08" PRIx32, cpu32.r[5]);
8728   outs() << " r6  "      << format("0x%08" PRIx32, cpu32.r[6]);
8729   outs() << " r7  "      << format("0x%08" PRIx32, cpu32.r[7]) << "\n";
8730   outs() << "\t    r8  " << format("0x%08" PRIx32, cpu32.r[8]);
8731   outs() << " r9     "   << format("0x%08" PRIx32, cpu32.r[9]);
8732   outs() << " r10 "      << format("0x%08" PRIx32, cpu32.r[10]);
8733   outs() << " r11 "      << format("0x%08" PRIx32, cpu32.r[11]) << "\n";
8734   outs() << "\t    r12 " << format("0x%08" PRIx32, cpu32.r[12]);
8735   outs() << " sp     "   << format("0x%08" PRIx32, cpu32.sp);
8736   outs() << " lr  "      << format("0x%08" PRIx32, cpu32.lr);
8737   outs() << " pc  "      << format("0x%08" PRIx32, cpu32.pc) << "\n";
8738   outs() << "\t   cpsr " << format("0x%08" PRIx32, cpu32.cpsr) << "\n";
8739 }
8740 
8741 static void Print_arm_thread_state64_t(MachO::arm_thread_state64_t &cpu64) {
8742   outs() << "\t    x0  " << format("0x%016" PRIx64, cpu64.x[0]);
8743   outs() << " x1  "      << format("0x%016" PRIx64, cpu64.x[1]);
8744   outs() << " x2  "      << format("0x%016" PRIx64, cpu64.x[2]) << "\n";
8745   outs() << "\t    x3  " << format("0x%016" PRIx64, cpu64.x[3]);
8746   outs() << " x4  "      << format("0x%016" PRIx64, cpu64.x[4]);
8747   outs() << " x5  "      << format("0x%016" PRIx64, cpu64.x[5]) << "\n";
8748   outs() << "\t    x6  " << format("0x%016" PRIx64, cpu64.x[6]);
8749   outs() << " x7  "      << format("0x%016" PRIx64, cpu64.x[7]);
8750   outs() << " x8  "      << format("0x%016" PRIx64, cpu64.x[8]) << "\n";
8751   outs() << "\t    x9  " << format("0x%016" PRIx64, cpu64.x[9]);
8752   outs() << " x10 "      << format("0x%016" PRIx64, cpu64.x[10]);
8753   outs() << " x11 "      << format("0x%016" PRIx64, cpu64.x[11]) << "\n";
8754   outs() << "\t    x12 " << format("0x%016" PRIx64, cpu64.x[12]);
8755   outs() << " x13 "      << format("0x%016" PRIx64, cpu64.x[13]);
8756   outs() << " x14 "      << format("0x%016" PRIx64, cpu64.x[14]) << "\n";
8757   outs() << "\t    x15 " << format("0x%016" PRIx64, cpu64.x[15]);
8758   outs() << " x16 "      << format("0x%016" PRIx64, cpu64.x[16]);
8759   outs() << " x17 "      << format("0x%016" PRIx64, cpu64.x[17]) << "\n";
8760   outs() << "\t    x18 " << format("0x%016" PRIx64, cpu64.x[18]);
8761   outs() << " x19 "      << format("0x%016" PRIx64, cpu64.x[19]);
8762   outs() << " x20 "      << format("0x%016" PRIx64, cpu64.x[20]) << "\n";
8763   outs() << "\t    x21 " << format("0x%016" PRIx64, cpu64.x[21]);
8764   outs() << " x22 "      << format("0x%016" PRIx64, cpu64.x[22]);
8765   outs() << " x23 "      << format("0x%016" PRIx64, cpu64.x[23]) << "\n";
8766   outs() << "\t    x24 " << format("0x%016" PRIx64, cpu64.x[24]);
8767   outs() << " x25 "      << format("0x%016" PRIx64, cpu64.x[25]);
8768   outs() << " x26 "      << format("0x%016" PRIx64, cpu64.x[26]) << "\n";
8769   outs() << "\t    x27 " << format("0x%016" PRIx64, cpu64.x[27]);
8770   outs() << " x28 "      << format("0x%016" PRIx64, cpu64.x[28]);
8771   outs() << "  fp "      << format("0x%016" PRIx64, cpu64.fp) << "\n";
8772   outs() << "\t     lr " << format("0x%016" PRIx64, cpu64.lr);
8773   outs() << " sp  "      << format("0x%016" PRIx64, cpu64.sp);
8774   outs() << "  pc "      << format("0x%016" PRIx64, cpu64.pc) << "\n";
8775   outs() << "\t   cpsr " << format("0x%08"  PRIx32, cpu64.cpsr) << "\n";
8776 }
8777 
8778 static void PrintThreadCommand(MachO::thread_command t, const char *Ptr,
8779                                bool isLittleEndian, uint32_t cputype) {
8780   if (t.cmd == MachO::LC_THREAD)
8781     outs() << "        cmd LC_THREAD\n";
8782   else if (t.cmd == MachO::LC_UNIXTHREAD)
8783     outs() << "        cmd LC_UNIXTHREAD\n";
8784   else
8785     outs() << "        cmd " << t.cmd << " (unknown)\n";
8786   outs() << "    cmdsize " << t.cmdsize;
8787   if (t.cmdsize < sizeof(struct MachO::thread_command) + 2 * sizeof(uint32_t))
8788     outs() << " Incorrect size\n";
8789   else
8790     outs() << "\n";
8791 
8792   const char *begin = Ptr + sizeof(struct MachO::thread_command);
8793   const char *end = Ptr + t.cmdsize;
8794   uint32_t flavor, count, left;
8795   if (cputype == MachO::CPU_TYPE_I386) {
8796     while (begin < end) {
8797       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8798         memcpy((char *)&flavor, begin, sizeof(uint32_t));
8799         begin += sizeof(uint32_t);
8800       } else {
8801         flavor = 0;
8802         begin = end;
8803       }
8804       if (isLittleEndian != sys::IsLittleEndianHost)
8805         sys::swapByteOrder(flavor);
8806       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8807         memcpy((char *)&count, begin, sizeof(uint32_t));
8808         begin += sizeof(uint32_t);
8809       } else {
8810         count = 0;
8811         begin = end;
8812       }
8813       if (isLittleEndian != sys::IsLittleEndianHost)
8814         sys::swapByteOrder(count);
8815       if (flavor == MachO::x86_THREAD_STATE32) {
8816         outs() << "     flavor i386_THREAD_STATE\n";
8817         if (count == MachO::x86_THREAD_STATE32_COUNT)
8818           outs() << "      count i386_THREAD_STATE_COUNT\n";
8819         else
8820           outs() << "      count " << count
8821                  << " (not x86_THREAD_STATE32_COUNT)\n";
8822         MachO::x86_thread_state32_t cpu32;
8823         left = end - begin;
8824         if (left >= sizeof(MachO::x86_thread_state32_t)) {
8825           memcpy(&cpu32, begin, sizeof(MachO::x86_thread_state32_t));
8826           begin += sizeof(MachO::x86_thread_state32_t);
8827         } else {
8828           memset(&cpu32, '\0', sizeof(MachO::x86_thread_state32_t));
8829           memcpy(&cpu32, begin, left);
8830           begin += left;
8831         }
8832         if (isLittleEndian != sys::IsLittleEndianHost)
8833           swapStruct(cpu32);
8834         Print_x86_thread_state32_t(cpu32);
8835       } else if (flavor == MachO::x86_THREAD_STATE) {
8836         outs() << "     flavor x86_THREAD_STATE\n";
8837         if (count == MachO::x86_THREAD_STATE_COUNT)
8838           outs() << "      count x86_THREAD_STATE_COUNT\n";
8839         else
8840           outs() << "      count " << count
8841                  << " (not x86_THREAD_STATE_COUNT)\n";
8842         struct MachO::x86_thread_state_t ts;
8843         left = end - begin;
8844         if (left >= sizeof(MachO::x86_thread_state_t)) {
8845           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
8846           begin += sizeof(MachO::x86_thread_state_t);
8847         } else {
8848           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
8849           memcpy(&ts, begin, left);
8850           begin += left;
8851         }
8852         if (isLittleEndian != sys::IsLittleEndianHost)
8853           swapStruct(ts);
8854         if (ts.tsh.flavor == MachO::x86_THREAD_STATE32) {
8855           outs() << "\t    tsh.flavor x86_THREAD_STATE32 ";
8856           if (ts.tsh.count == MachO::x86_THREAD_STATE32_COUNT)
8857             outs() << "tsh.count x86_THREAD_STATE32_COUNT\n";
8858           else
8859             outs() << "tsh.count " << ts.tsh.count
8860                    << " (not x86_THREAD_STATE32_COUNT\n";
8861           Print_x86_thread_state32_t(ts.uts.ts32);
8862         } else {
8863           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
8864                  << ts.tsh.count << "\n";
8865         }
8866       } else {
8867         outs() << "     flavor " << flavor << " (unknown)\n";
8868         outs() << "      count " << count << "\n";
8869         outs() << "      state (unknown)\n";
8870         begin += count * sizeof(uint32_t);
8871       }
8872     }
8873   } else if (cputype == MachO::CPU_TYPE_X86_64) {
8874     while (begin < end) {
8875       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8876         memcpy((char *)&flavor, begin, sizeof(uint32_t));
8877         begin += sizeof(uint32_t);
8878       } else {
8879         flavor = 0;
8880         begin = end;
8881       }
8882       if (isLittleEndian != sys::IsLittleEndianHost)
8883         sys::swapByteOrder(flavor);
8884       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8885         memcpy((char *)&count, begin, sizeof(uint32_t));
8886         begin += sizeof(uint32_t);
8887       } else {
8888         count = 0;
8889         begin = end;
8890       }
8891       if (isLittleEndian != sys::IsLittleEndianHost)
8892         sys::swapByteOrder(count);
8893       if (flavor == MachO::x86_THREAD_STATE64) {
8894         outs() << "     flavor x86_THREAD_STATE64\n";
8895         if (count == MachO::x86_THREAD_STATE64_COUNT)
8896           outs() << "      count x86_THREAD_STATE64_COUNT\n";
8897         else
8898           outs() << "      count " << count
8899                  << " (not x86_THREAD_STATE64_COUNT)\n";
8900         MachO::x86_thread_state64_t cpu64;
8901         left = end - begin;
8902         if (left >= sizeof(MachO::x86_thread_state64_t)) {
8903           memcpy(&cpu64, begin, sizeof(MachO::x86_thread_state64_t));
8904           begin += sizeof(MachO::x86_thread_state64_t);
8905         } else {
8906           memset(&cpu64, '\0', sizeof(MachO::x86_thread_state64_t));
8907           memcpy(&cpu64, begin, left);
8908           begin += left;
8909         }
8910         if (isLittleEndian != sys::IsLittleEndianHost)
8911           swapStruct(cpu64);
8912         Print_x86_thread_state64_t(cpu64);
8913       } else if (flavor == MachO::x86_THREAD_STATE) {
8914         outs() << "     flavor x86_THREAD_STATE\n";
8915         if (count == MachO::x86_THREAD_STATE_COUNT)
8916           outs() << "      count x86_THREAD_STATE_COUNT\n";
8917         else
8918           outs() << "      count " << count
8919                  << " (not x86_THREAD_STATE_COUNT)\n";
8920         struct MachO::x86_thread_state_t ts;
8921         left = end - begin;
8922         if (left >= sizeof(MachO::x86_thread_state_t)) {
8923           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
8924           begin += sizeof(MachO::x86_thread_state_t);
8925         } else {
8926           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
8927           memcpy(&ts, begin, left);
8928           begin += left;
8929         }
8930         if (isLittleEndian != sys::IsLittleEndianHost)
8931           swapStruct(ts);
8932         if (ts.tsh.flavor == MachO::x86_THREAD_STATE64) {
8933           outs() << "\t    tsh.flavor x86_THREAD_STATE64 ";
8934           if (ts.tsh.count == MachO::x86_THREAD_STATE64_COUNT)
8935             outs() << "tsh.count x86_THREAD_STATE64_COUNT\n";
8936           else
8937             outs() << "tsh.count " << ts.tsh.count
8938                    << " (not x86_THREAD_STATE64_COUNT\n";
8939           Print_x86_thread_state64_t(ts.uts.ts64);
8940         } else {
8941           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
8942                  << ts.tsh.count << "\n";
8943         }
8944       } else if (flavor == MachO::x86_FLOAT_STATE) {
8945         outs() << "     flavor x86_FLOAT_STATE\n";
8946         if (count == MachO::x86_FLOAT_STATE_COUNT)
8947           outs() << "      count x86_FLOAT_STATE_COUNT\n";
8948         else
8949           outs() << "      count " << count << " (not x86_FLOAT_STATE_COUNT)\n";
8950         struct MachO::x86_float_state_t fs;
8951         left = end - begin;
8952         if (left >= sizeof(MachO::x86_float_state_t)) {
8953           memcpy(&fs, begin, sizeof(MachO::x86_float_state_t));
8954           begin += sizeof(MachO::x86_float_state_t);
8955         } else {
8956           memset(&fs, '\0', sizeof(MachO::x86_float_state_t));
8957           memcpy(&fs, begin, left);
8958           begin += left;
8959         }
8960         if (isLittleEndian != sys::IsLittleEndianHost)
8961           swapStruct(fs);
8962         if (fs.fsh.flavor == MachO::x86_FLOAT_STATE64) {
8963           outs() << "\t    fsh.flavor x86_FLOAT_STATE64 ";
8964           if (fs.fsh.count == MachO::x86_FLOAT_STATE64_COUNT)
8965             outs() << "fsh.count x86_FLOAT_STATE64_COUNT\n";
8966           else
8967             outs() << "fsh.count " << fs.fsh.count
8968                    << " (not x86_FLOAT_STATE64_COUNT\n";
8969           Print_x86_float_state_t(fs.ufs.fs64);
8970         } else {
8971           outs() << "\t    fsh.flavor " << fs.fsh.flavor << "  fsh.count "
8972                  << fs.fsh.count << "\n";
8973         }
8974       } else if (flavor == MachO::x86_EXCEPTION_STATE) {
8975         outs() << "     flavor x86_EXCEPTION_STATE\n";
8976         if (count == MachO::x86_EXCEPTION_STATE_COUNT)
8977           outs() << "      count x86_EXCEPTION_STATE_COUNT\n";
8978         else
8979           outs() << "      count " << count
8980                  << " (not x86_EXCEPTION_STATE_COUNT)\n";
8981         struct MachO::x86_exception_state_t es;
8982         left = end - begin;
8983         if (left >= sizeof(MachO::x86_exception_state_t)) {
8984           memcpy(&es, begin, sizeof(MachO::x86_exception_state_t));
8985           begin += sizeof(MachO::x86_exception_state_t);
8986         } else {
8987           memset(&es, '\0', sizeof(MachO::x86_exception_state_t));
8988           memcpy(&es, begin, left);
8989           begin += left;
8990         }
8991         if (isLittleEndian != sys::IsLittleEndianHost)
8992           swapStruct(es);
8993         if (es.esh.flavor == MachO::x86_EXCEPTION_STATE64) {
8994           outs() << "\t    esh.flavor x86_EXCEPTION_STATE64\n";
8995           if (es.esh.count == MachO::x86_EXCEPTION_STATE64_COUNT)
8996             outs() << "\t    esh.count x86_EXCEPTION_STATE64_COUNT\n";
8997           else
8998             outs() << "\t    esh.count " << es.esh.count
8999                    << " (not x86_EXCEPTION_STATE64_COUNT\n";
9000           Print_x86_exception_state_t(es.ues.es64);
9001         } else {
9002           outs() << "\t    esh.flavor " << es.esh.flavor << "  esh.count "
9003                  << es.esh.count << "\n";
9004         }
9005       } else {
9006         outs() << "     flavor " << flavor << " (unknown)\n";
9007         outs() << "      count " << count << "\n";
9008         outs() << "      state (unknown)\n";
9009         begin += count * sizeof(uint32_t);
9010       }
9011     }
9012   } else if (cputype == MachO::CPU_TYPE_ARM) {
9013     while (begin < end) {
9014       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9015         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9016         begin += sizeof(uint32_t);
9017       } else {
9018         flavor = 0;
9019         begin = end;
9020       }
9021       if (isLittleEndian != sys::IsLittleEndianHost)
9022         sys::swapByteOrder(flavor);
9023       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9024         memcpy((char *)&count, begin, sizeof(uint32_t));
9025         begin += sizeof(uint32_t);
9026       } else {
9027         count = 0;
9028         begin = end;
9029       }
9030       if (isLittleEndian != sys::IsLittleEndianHost)
9031         sys::swapByteOrder(count);
9032       if (flavor == MachO::ARM_THREAD_STATE) {
9033         outs() << "     flavor ARM_THREAD_STATE\n";
9034         if (count == MachO::ARM_THREAD_STATE_COUNT)
9035           outs() << "      count ARM_THREAD_STATE_COUNT\n";
9036         else
9037           outs() << "      count " << count
9038                  << " (not ARM_THREAD_STATE_COUNT)\n";
9039         MachO::arm_thread_state32_t cpu32;
9040         left = end - begin;
9041         if (left >= sizeof(MachO::arm_thread_state32_t)) {
9042           memcpy(&cpu32, begin, sizeof(MachO::arm_thread_state32_t));
9043           begin += sizeof(MachO::arm_thread_state32_t);
9044         } else {
9045           memset(&cpu32, '\0', sizeof(MachO::arm_thread_state32_t));
9046           memcpy(&cpu32, begin, left);
9047           begin += left;
9048         }
9049         if (isLittleEndian != sys::IsLittleEndianHost)
9050           swapStruct(cpu32);
9051         Print_arm_thread_state32_t(cpu32);
9052       } else {
9053         outs() << "     flavor " << flavor << " (unknown)\n";
9054         outs() << "      count " << count << "\n";
9055         outs() << "      state (unknown)\n";
9056         begin += count * sizeof(uint32_t);
9057       }
9058     }
9059   } else if (cputype == MachO::CPU_TYPE_ARM64) {
9060     while (begin < end) {
9061       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9062         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9063         begin += sizeof(uint32_t);
9064       } else {
9065         flavor = 0;
9066         begin = end;
9067       }
9068       if (isLittleEndian != sys::IsLittleEndianHost)
9069         sys::swapByteOrder(flavor);
9070       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9071         memcpy((char *)&count, begin, sizeof(uint32_t));
9072         begin += sizeof(uint32_t);
9073       } else {
9074         count = 0;
9075         begin = end;
9076       }
9077       if (isLittleEndian != sys::IsLittleEndianHost)
9078         sys::swapByteOrder(count);
9079       if (flavor == MachO::ARM_THREAD_STATE64) {
9080         outs() << "     flavor ARM_THREAD_STATE64\n";
9081         if (count == MachO::ARM_THREAD_STATE64_COUNT)
9082           outs() << "      count ARM_THREAD_STATE64_COUNT\n";
9083         else
9084           outs() << "      count " << count
9085                  << " (not ARM_THREAD_STATE64_COUNT)\n";
9086         MachO::arm_thread_state64_t cpu64;
9087         left = end - begin;
9088         if (left >= sizeof(MachO::arm_thread_state64_t)) {
9089           memcpy(&cpu64, begin, sizeof(MachO::arm_thread_state64_t));
9090           begin += sizeof(MachO::arm_thread_state64_t);
9091         } else {
9092           memset(&cpu64, '\0', sizeof(MachO::arm_thread_state64_t));
9093           memcpy(&cpu64, begin, left);
9094           begin += left;
9095         }
9096         if (isLittleEndian != sys::IsLittleEndianHost)
9097           swapStruct(cpu64);
9098         Print_arm_thread_state64_t(cpu64);
9099       } else {
9100         outs() << "     flavor " << flavor << " (unknown)\n";
9101         outs() << "      count " << count << "\n";
9102         outs() << "      state (unknown)\n";
9103         begin += count * sizeof(uint32_t);
9104       }
9105     }
9106   } else {
9107     while (begin < end) {
9108       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9109         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9110         begin += sizeof(uint32_t);
9111       } else {
9112         flavor = 0;
9113         begin = end;
9114       }
9115       if (isLittleEndian != sys::IsLittleEndianHost)
9116         sys::swapByteOrder(flavor);
9117       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9118         memcpy((char *)&count, begin, sizeof(uint32_t));
9119         begin += sizeof(uint32_t);
9120       } else {
9121         count = 0;
9122         begin = end;
9123       }
9124       if (isLittleEndian != sys::IsLittleEndianHost)
9125         sys::swapByteOrder(count);
9126       outs() << "     flavor " << flavor << "\n";
9127       outs() << "      count " << count << "\n";
9128       outs() << "      state (Unknown cputype/cpusubtype)\n";
9129       begin += count * sizeof(uint32_t);
9130     }
9131   }
9132 }
9133 
9134 static void PrintDylibCommand(MachO::dylib_command dl, const char *Ptr) {
9135   if (dl.cmd == MachO::LC_ID_DYLIB)
9136     outs() << "          cmd LC_ID_DYLIB\n";
9137   else if (dl.cmd == MachO::LC_LOAD_DYLIB)
9138     outs() << "          cmd LC_LOAD_DYLIB\n";
9139   else if (dl.cmd == MachO::LC_LOAD_WEAK_DYLIB)
9140     outs() << "          cmd LC_LOAD_WEAK_DYLIB\n";
9141   else if (dl.cmd == MachO::LC_REEXPORT_DYLIB)
9142     outs() << "          cmd LC_REEXPORT_DYLIB\n";
9143   else if (dl.cmd == MachO::LC_LAZY_LOAD_DYLIB)
9144     outs() << "          cmd LC_LAZY_LOAD_DYLIB\n";
9145   else if (dl.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
9146     outs() << "          cmd LC_LOAD_UPWARD_DYLIB\n";
9147   else
9148     outs() << "          cmd " << dl.cmd << " (unknown)\n";
9149   outs() << "      cmdsize " << dl.cmdsize;
9150   if (dl.cmdsize < sizeof(struct MachO::dylib_command))
9151     outs() << " Incorrect size\n";
9152   else
9153     outs() << "\n";
9154   if (dl.dylib.name < dl.cmdsize) {
9155     const char *P = (const char *)(Ptr) + dl.dylib.name;
9156     outs() << "         name " << P << " (offset " << dl.dylib.name << ")\n";
9157   } else {
9158     outs() << "         name ?(bad offset " << dl.dylib.name << ")\n";
9159   }
9160   outs() << "   time stamp " << dl.dylib.timestamp << " ";
9161   time_t t = dl.dylib.timestamp;
9162   outs() << ctime(&t);
9163   outs() << "      current version ";
9164   if (dl.dylib.current_version == 0xffffffff)
9165     outs() << "n/a\n";
9166   else
9167     outs() << ((dl.dylib.current_version >> 16) & 0xffff) << "."
9168            << ((dl.dylib.current_version >> 8) & 0xff) << "."
9169            << (dl.dylib.current_version & 0xff) << "\n";
9170   outs() << "compatibility version ";
9171   if (dl.dylib.compatibility_version == 0xffffffff)
9172     outs() << "n/a\n";
9173   else
9174     outs() << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
9175            << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
9176            << (dl.dylib.compatibility_version & 0xff) << "\n";
9177 }
9178 
9179 static void PrintLinkEditDataCommand(MachO::linkedit_data_command ld,
9180                                      uint32_t object_size) {
9181   if (ld.cmd == MachO::LC_CODE_SIGNATURE)
9182     outs() << "      cmd LC_CODE_SIGNATURE\n";
9183   else if (ld.cmd == MachO::LC_SEGMENT_SPLIT_INFO)
9184     outs() << "      cmd LC_SEGMENT_SPLIT_INFO\n";
9185   else if (ld.cmd == MachO::LC_FUNCTION_STARTS)
9186     outs() << "      cmd LC_FUNCTION_STARTS\n";
9187   else if (ld.cmd == MachO::LC_DATA_IN_CODE)
9188     outs() << "      cmd LC_DATA_IN_CODE\n";
9189   else if (ld.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS)
9190     outs() << "      cmd LC_DYLIB_CODE_SIGN_DRS\n";
9191   else if (ld.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT)
9192     outs() << "      cmd LC_LINKER_OPTIMIZATION_HINT\n";
9193   else
9194     outs() << "      cmd " << ld.cmd << " (?)\n";
9195   outs() << "  cmdsize " << ld.cmdsize;
9196   if (ld.cmdsize != sizeof(struct MachO::linkedit_data_command))
9197     outs() << " Incorrect size\n";
9198   else
9199     outs() << "\n";
9200   outs() << "  dataoff " << ld.dataoff;
9201   if (ld.dataoff > object_size)
9202     outs() << " (past end of file)\n";
9203   else
9204     outs() << "\n";
9205   outs() << " datasize " << ld.datasize;
9206   uint64_t big_size = ld.dataoff;
9207   big_size += ld.datasize;
9208   if (big_size > object_size)
9209     outs() << " (past end of file)\n";
9210   else
9211     outs() << "\n";
9212 }
9213 
9214 static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t filetype,
9215                               uint32_t cputype, bool verbose) {
9216   StringRef Buf = Obj->getData();
9217   unsigned Index = 0;
9218   for (const auto &Command : Obj->load_commands()) {
9219     outs() << "Load command " << Index++ << "\n";
9220     if (Command.C.cmd == MachO::LC_SEGMENT) {
9221       MachO::segment_command SLC = Obj->getSegmentLoadCommand(Command);
9222       const char *sg_segname = SLC.segname;
9223       PrintSegmentCommand(SLC.cmd, SLC.cmdsize, SLC.segname, SLC.vmaddr,
9224                           SLC.vmsize, SLC.fileoff, SLC.filesize, SLC.maxprot,
9225                           SLC.initprot, SLC.nsects, SLC.flags, Buf.size(),
9226                           verbose);
9227       for (unsigned j = 0; j < SLC.nsects; j++) {
9228         MachO::section S = Obj->getSection(Command, j);
9229         PrintSection(S.sectname, S.segname, S.addr, S.size, S.offset, S.align,
9230                      S.reloff, S.nreloc, S.flags, S.reserved1, S.reserved2,
9231                      SLC.cmd, sg_segname, filetype, Buf.size(), verbose);
9232       }
9233     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
9234       MachO::segment_command_64 SLC_64 = Obj->getSegment64LoadCommand(Command);
9235       const char *sg_segname = SLC_64.segname;
9236       PrintSegmentCommand(SLC_64.cmd, SLC_64.cmdsize, SLC_64.segname,
9237                           SLC_64.vmaddr, SLC_64.vmsize, SLC_64.fileoff,
9238                           SLC_64.filesize, SLC_64.maxprot, SLC_64.initprot,
9239                           SLC_64.nsects, SLC_64.flags, Buf.size(), verbose);
9240       for (unsigned j = 0; j < SLC_64.nsects; j++) {
9241         MachO::section_64 S_64 = Obj->getSection64(Command, j);
9242         PrintSection(S_64.sectname, S_64.segname, S_64.addr, S_64.size,
9243                      S_64.offset, S_64.align, S_64.reloff, S_64.nreloc,
9244                      S_64.flags, S_64.reserved1, S_64.reserved2, SLC_64.cmd,
9245                      sg_segname, filetype, Buf.size(), verbose);
9246       }
9247     } else if (Command.C.cmd == MachO::LC_SYMTAB) {
9248       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
9249       PrintSymtabLoadCommand(Symtab, Obj->is64Bit(), Buf.size());
9250     } else if (Command.C.cmd == MachO::LC_DYSYMTAB) {
9251       MachO::dysymtab_command Dysymtab = Obj->getDysymtabLoadCommand();
9252       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
9253       PrintDysymtabLoadCommand(Dysymtab, Symtab.nsyms, Buf.size(),
9254                                Obj->is64Bit());
9255     } else if (Command.C.cmd == MachO::LC_DYLD_INFO ||
9256                Command.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
9257       MachO::dyld_info_command DyldInfo = Obj->getDyldInfoLoadCommand(Command);
9258       PrintDyldInfoLoadCommand(DyldInfo, Buf.size());
9259     } else if (Command.C.cmd == MachO::LC_LOAD_DYLINKER ||
9260                Command.C.cmd == MachO::LC_ID_DYLINKER ||
9261                Command.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
9262       MachO::dylinker_command Dyld = Obj->getDylinkerCommand(Command);
9263       PrintDyldLoadCommand(Dyld, Command.Ptr);
9264     } else if (Command.C.cmd == MachO::LC_UUID) {
9265       MachO::uuid_command Uuid = Obj->getUuidCommand(Command);
9266       PrintUuidLoadCommand(Uuid);
9267     } else if (Command.C.cmd == MachO::LC_RPATH) {
9268       MachO::rpath_command Rpath = Obj->getRpathCommand(Command);
9269       PrintRpathLoadCommand(Rpath, Command.Ptr);
9270     } else if (Command.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
9271                Command.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS ||
9272                Command.C.cmd == MachO::LC_VERSION_MIN_TVOS ||
9273                Command.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
9274       MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
9275       PrintVersionMinLoadCommand(Vd);
9276     } else if (Command.C.cmd == MachO::LC_NOTE) {
9277       MachO::note_command Nt = Obj->getNoteLoadCommand(Command);
9278       PrintNoteLoadCommand(Nt);
9279     } else if (Command.C.cmd == MachO::LC_BUILD_VERSION) {
9280       MachO::build_version_command Bv =
9281           Obj->getBuildVersionLoadCommand(Command);
9282       PrintBuildVersionLoadCommand(Obj, Bv);
9283     } else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
9284       MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
9285       PrintSourceVersionCommand(Sd);
9286     } else if (Command.C.cmd == MachO::LC_MAIN) {
9287       MachO::entry_point_command Ep = Obj->getEntryPointCommand(Command);
9288       PrintEntryPointCommand(Ep);
9289     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO) {
9290       MachO::encryption_info_command Ei =
9291           Obj->getEncryptionInfoCommand(Command);
9292       PrintEncryptionInfoCommand(Ei, Buf.size());
9293     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
9294       MachO::encryption_info_command_64 Ei =
9295           Obj->getEncryptionInfoCommand64(Command);
9296       PrintEncryptionInfoCommand64(Ei, Buf.size());
9297     } else if (Command.C.cmd == MachO::LC_LINKER_OPTION) {
9298       MachO::linker_option_command Lo =
9299           Obj->getLinkerOptionLoadCommand(Command);
9300       PrintLinkerOptionCommand(Lo, Command.Ptr);
9301     } else if (Command.C.cmd == MachO::LC_SUB_FRAMEWORK) {
9302       MachO::sub_framework_command Sf = Obj->getSubFrameworkCommand(Command);
9303       PrintSubFrameworkCommand(Sf, Command.Ptr);
9304     } else if (Command.C.cmd == MachO::LC_SUB_UMBRELLA) {
9305       MachO::sub_umbrella_command Sf = Obj->getSubUmbrellaCommand(Command);
9306       PrintSubUmbrellaCommand(Sf, Command.Ptr);
9307     } else if (Command.C.cmd == MachO::LC_SUB_LIBRARY) {
9308       MachO::sub_library_command Sl = Obj->getSubLibraryCommand(Command);
9309       PrintSubLibraryCommand(Sl, Command.Ptr);
9310     } else if (Command.C.cmd == MachO::LC_SUB_CLIENT) {
9311       MachO::sub_client_command Sc = Obj->getSubClientCommand(Command);
9312       PrintSubClientCommand(Sc, Command.Ptr);
9313     } else if (Command.C.cmd == MachO::LC_ROUTINES) {
9314       MachO::routines_command Rc = Obj->getRoutinesCommand(Command);
9315       PrintRoutinesCommand(Rc);
9316     } else if (Command.C.cmd == MachO::LC_ROUTINES_64) {
9317       MachO::routines_command_64 Rc = Obj->getRoutinesCommand64(Command);
9318       PrintRoutinesCommand64(Rc);
9319     } else if (Command.C.cmd == MachO::LC_THREAD ||
9320                Command.C.cmd == MachO::LC_UNIXTHREAD) {
9321       MachO::thread_command Tc = Obj->getThreadCommand(Command);
9322       PrintThreadCommand(Tc, Command.Ptr, Obj->isLittleEndian(), cputype);
9323     } else if (Command.C.cmd == MachO::LC_LOAD_DYLIB ||
9324                Command.C.cmd == MachO::LC_ID_DYLIB ||
9325                Command.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
9326                Command.C.cmd == MachO::LC_REEXPORT_DYLIB ||
9327                Command.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
9328                Command.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
9329       MachO::dylib_command Dl = Obj->getDylibIDLoadCommand(Command);
9330       PrintDylibCommand(Dl, Command.Ptr);
9331     } else if (Command.C.cmd == MachO::LC_CODE_SIGNATURE ||
9332                Command.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO ||
9333                Command.C.cmd == MachO::LC_FUNCTION_STARTS ||
9334                Command.C.cmd == MachO::LC_DATA_IN_CODE ||
9335                Command.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS ||
9336                Command.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
9337       MachO::linkedit_data_command Ld =
9338           Obj->getLinkeditDataLoadCommand(Command);
9339       PrintLinkEditDataCommand(Ld, Buf.size());
9340     } else {
9341       outs() << "      cmd ?(" << format("0x%08" PRIx32, Command.C.cmd)
9342              << ")\n";
9343       outs() << "  cmdsize " << Command.C.cmdsize << "\n";
9344       // TODO: get and print the raw bytes of the load command.
9345     }
9346     // TODO: print all the other kinds of load commands.
9347   }
9348 }
9349 
9350 static void PrintMachHeader(const MachOObjectFile *Obj, bool verbose) {
9351   if (Obj->is64Bit()) {
9352     MachO::mach_header_64 H_64;
9353     H_64 = Obj->getHeader64();
9354     PrintMachHeader(H_64.magic, H_64.cputype, H_64.cpusubtype, H_64.filetype,
9355                     H_64.ncmds, H_64.sizeofcmds, H_64.flags, verbose);
9356   } else {
9357     MachO::mach_header H;
9358     H = Obj->getHeader();
9359     PrintMachHeader(H.magic, H.cputype, H.cpusubtype, H.filetype, H.ncmds,
9360                     H.sizeofcmds, H.flags, verbose);
9361   }
9362 }
9363 
9364 void llvm::printMachOFileHeader(const object::ObjectFile *Obj) {
9365   const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
9366   PrintMachHeader(file, !NonVerbose);
9367 }
9368 
9369 void llvm::printMachOLoadCommands(const object::ObjectFile *Obj) {
9370   const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
9371   uint32_t filetype = 0;
9372   uint32_t cputype = 0;
9373   if (file->is64Bit()) {
9374     MachO::mach_header_64 H_64;
9375     H_64 = file->getHeader64();
9376     filetype = H_64.filetype;
9377     cputype = H_64.cputype;
9378   } else {
9379     MachO::mach_header H;
9380     H = file->getHeader();
9381     filetype = H.filetype;
9382     cputype = H.cputype;
9383   }
9384   PrintLoadCommands(file, filetype, cputype, !NonVerbose);
9385 }
9386 
9387 //===----------------------------------------------------------------------===//
9388 // export trie dumping
9389 //===----------------------------------------------------------------------===//
9390 
9391 void llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) {
9392   uint64_t BaseSegmentAddress = 0;
9393   for (const auto &Command : Obj->load_commands()) {
9394     if (Command.C.cmd == MachO::LC_SEGMENT) {
9395       MachO::segment_command Seg = Obj->getSegmentLoadCommand(Command);
9396       if (Seg.fileoff == 0 && Seg.filesize != 0) {
9397         BaseSegmentAddress = Seg.vmaddr;
9398         break;
9399       }
9400     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
9401       MachO::segment_command_64 Seg = Obj->getSegment64LoadCommand(Command);
9402       if (Seg.fileoff == 0 && Seg.filesize != 0) {
9403         BaseSegmentAddress = Seg.vmaddr;
9404         break;
9405       }
9406     }
9407   }
9408   Error Err = Error::success();
9409   for (const llvm::object::ExportEntry &Entry : Obj->exports(Err)) {
9410     uint64_t Flags = Entry.flags();
9411     bool ReExport = (Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
9412     bool WeakDef = (Flags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
9413     bool ThreadLocal = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
9414                         MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL);
9415     bool Abs = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
9416                 MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
9417     bool Resolver = (Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
9418     if (ReExport)
9419       outs() << "[re-export] ";
9420     else
9421       outs() << format("0x%08llX  ",
9422                        Entry.address() + BaseSegmentAddress);
9423     outs() << Entry.name();
9424     if (WeakDef || ThreadLocal || Resolver || Abs) {
9425       bool NeedsComma = false;
9426       outs() << " [";
9427       if (WeakDef) {
9428         outs() << "weak_def";
9429         NeedsComma = true;
9430       }
9431       if (ThreadLocal) {
9432         if (NeedsComma)
9433           outs() << ", ";
9434         outs() << "per-thread";
9435         NeedsComma = true;
9436       }
9437       if (Abs) {
9438         if (NeedsComma)
9439           outs() << ", ";
9440         outs() << "absolute";
9441         NeedsComma = true;
9442       }
9443       if (Resolver) {
9444         if (NeedsComma)
9445           outs() << ", ";
9446         outs() << format("resolver=0x%08llX", Entry.other());
9447         NeedsComma = true;
9448       }
9449       outs() << "]";
9450     }
9451     if (ReExport) {
9452       StringRef DylibName = "unknown";
9453       int Ordinal = Entry.other() - 1;
9454       Obj->getLibraryShortNameByIndex(Ordinal, DylibName);
9455       if (Entry.otherName().empty())
9456         outs() << " (from " << DylibName << ")";
9457       else
9458         outs() << " (" << Entry.otherName() << " from " << DylibName << ")";
9459     }
9460     outs() << "\n";
9461   }
9462   if (Err)
9463     report_error(Obj->getFileName(), std::move(Err));
9464 }
9465 
9466 //===----------------------------------------------------------------------===//
9467 // rebase table dumping
9468 //===----------------------------------------------------------------------===//
9469 
9470 void llvm::printMachORebaseTable(object::MachOObjectFile *Obj) {
9471   outs() << "segment  section            address     type\n";
9472   Error Err = Error::success();
9473   for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(Err)) {
9474     StringRef SegmentName = Entry.segmentName();
9475     StringRef SectionName = Entry.sectionName();
9476     uint64_t Address = Entry.address();
9477 
9478     // Table lines look like: __DATA  __nl_symbol_ptr  0x0000F00C  pointer
9479     outs() << format("%-8s %-18s 0x%08" PRIX64 "  %s\n",
9480                      SegmentName.str().c_str(), SectionName.str().c_str(),
9481                      Address, Entry.typeName().str().c_str());
9482   }
9483   if (Err)
9484     report_error(Obj->getFileName(), std::move(Err));
9485 }
9486 
9487 static StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) {
9488   StringRef DylibName;
9489   switch (Ordinal) {
9490   case MachO::BIND_SPECIAL_DYLIB_SELF:
9491     return "this-image";
9492   case MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE:
9493     return "main-executable";
9494   case MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP:
9495     return "flat-namespace";
9496   default:
9497     if (Ordinal > 0) {
9498       std::error_code EC =
9499           Obj->getLibraryShortNameByIndex(Ordinal - 1, DylibName);
9500       if (EC)
9501         return "<<bad library ordinal>>";
9502       return DylibName;
9503     }
9504   }
9505   return "<<unknown special ordinal>>";
9506 }
9507 
9508 //===----------------------------------------------------------------------===//
9509 // bind table dumping
9510 //===----------------------------------------------------------------------===//
9511 
9512 void llvm::printMachOBindTable(object::MachOObjectFile *Obj) {
9513   // Build table of sections so names can used in final output.
9514   outs() << "segment  section            address    type       "
9515             "addend dylib            symbol\n";
9516   Error Err = Error::success();
9517   for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(Err)) {
9518     StringRef SegmentName = Entry.segmentName();
9519     StringRef SectionName = Entry.sectionName();
9520     uint64_t Address = Entry.address();
9521 
9522     // Table lines look like:
9523     //  __DATA  __got  0x00012010    pointer   0 libSystem ___stack_chk_guard
9524     StringRef Attr;
9525     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT)
9526       Attr = " (weak_import)";
9527     outs() << left_justify(SegmentName, 8) << " "
9528            << left_justify(SectionName, 18) << " "
9529            << format_hex(Address, 10, true) << " "
9530            << left_justify(Entry.typeName(), 8) << " "
9531            << format_decimal(Entry.addend(), 8) << " "
9532            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
9533            << Entry.symbolName() << Attr << "\n";
9534   }
9535   if (Err)
9536     report_error(Obj->getFileName(), std::move(Err));
9537 }
9538 
9539 //===----------------------------------------------------------------------===//
9540 // lazy bind table dumping
9541 //===----------------------------------------------------------------------===//
9542 
9543 void llvm::printMachOLazyBindTable(object::MachOObjectFile *Obj) {
9544   outs() << "segment  section            address     "
9545             "dylib            symbol\n";
9546   Error Err = Error::success();
9547   for (const llvm::object::MachOBindEntry &Entry : Obj->lazyBindTable(Err)) {
9548     StringRef SegmentName = Entry.segmentName();
9549     StringRef SectionName = Entry.sectionName();
9550     uint64_t Address = Entry.address();
9551 
9552     // Table lines look like:
9553     //  __DATA  __got  0x00012010 libSystem ___stack_chk_guard
9554     outs() << left_justify(SegmentName, 8) << " "
9555            << left_justify(SectionName, 18) << " "
9556            << format_hex(Address, 10, true) << " "
9557            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
9558            << Entry.symbolName() << "\n";
9559   }
9560   if (Err)
9561     report_error(Obj->getFileName(), std::move(Err));
9562 }
9563 
9564 //===----------------------------------------------------------------------===//
9565 // weak bind table dumping
9566 //===----------------------------------------------------------------------===//
9567 
9568 void llvm::printMachOWeakBindTable(object::MachOObjectFile *Obj) {
9569   outs() << "segment  section            address     "
9570             "type       addend   symbol\n";
9571   Error Err = Error::success();
9572   for (const llvm::object::MachOBindEntry &Entry : Obj->weakBindTable(Err)) {
9573     // Strong symbols don't have a location to update.
9574     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
9575       outs() << "                                        strong              "
9576              << Entry.symbolName() << "\n";
9577       continue;
9578     }
9579     StringRef SegmentName = Entry.segmentName();
9580     StringRef SectionName = Entry.sectionName();
9581     uint64_t Address = Entry.address();
9582 
9583     // Table lines look like:
9584     // __DATA  __data  0x00001000  pointer    0   _foo
9585     outs() << left_justify(SegmentName, 8) << " "
9586            << left_justify(SectionName, 18) << " "
9587            << format_hex(Address, 10, true) << " "
9588            << left_justify(Entry.typeName(), 8) << " "
9589            << format_decimal(Entry.addend(), 8) << "   " << Entry.symbolName()
9590            << "\n";
9591   }
9592   if (Err)
9593     report_error(Obj->getFileName(), std::move(Err));
9594 }
9595 
9596 // get_dyld_bind_info_symbolname() is used for disassembly and passed an
9597 // address, ReferenceValue, in the Mach-O file and looks in the dyld bind
9598 // information for that address. If the address is found its binding symbol
9599 // name is returned.  If not nullptr is returned.
9600 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
9601                                                  struct DisassembleInfo *info) {
9602   if (info->bindtable == nullptr) {
9603     info->bindtable = llvm::make_unique<SymbolAddressMap>();
9604     Error Err = Error::success();
9605     for (const llvm::object::MachOBindEntry &Entry : info->O->bindTable(Err)) {
9606       uint64_t Address = Entry.address();
9607       StringRef name = Entry.symbolName();
9608       if (!name.empty())
9609         (*info->bindtable)[Address] = name;
9610     }
9611     if (Err)
9612       report_error(info->O->getFileName(), std::move(Err));
9613   }
9614   auto name = info->bindtable->lookup(ReferenceValue);
9615   return !name.empty() ? name.data() : nullptr;
9616 }
9617