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       outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
1139       StringRef BytesStr;
1140       Section.getContents(BytesStr);
1141       const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1142       outs() << format("%.*s", BytesStr.size(), sect) << "\n";
1143       return;
1144     }
1145   }
1146 }
1147 
1148 // checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file
1149 // and if it is and there is a list of architecture flags is specified then
1150 // check to make sure this Mach-O file is one of those architectures or all
1151 // architectures were specified.  If not then an error is generated and this
1152 // routine returns false.  Else it returns true.
1153 static bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) {
1154   auto *MachO = dyn_cast<MachOObjectFile>(O);
1155 
1156   if (!MachO || ArchAll || ArchFlags.empty())
1157     return true;
1158 
1159   MachO::mach_header H;
1160   MachO::mach_header_64 H_64;
1161   Triple T;
1162   const char *McpuDefault, *ArchFlag;
1163   if (MachO->is64Bit()) {
1164     H_64 = MachO->MachOObjectFile::getHeader64();
1165     T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype,
1166                                        &McpuDefault, &ArchFlag);
1167   } else {
1168     H = MachO->MachOObjectFile::getHeader();
1169     T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype,
1170                                        &McpuDefault, &ArchFlag);
1171   }
1172   const std::string ArchFlagName(ArchFlag);
1173   if (none_of(ArchFlags, [&](const std::string &Name) {
1174         return Name == ArchFlagName;
1175       })) {
1176     errs() << "llvm-objdump: " + Filename + ": No architecture specified.\n";
1177     return false;
1178   }
1179   return true;
1180 }
1181 
1182 static void printObjcMetaData(MachOObjectFile *O, bool verbose);
1183 
1184 // ProcessMachO() is passed a single opened Mach-O file, which may be an
1185 // archive member and or in a slice of a universal file.  It prints the
1186 // the file name and header info and then processes it according to the
1187 // command line options.
1188 static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
1189                          StringRef ArchiveMemberName = StringRef(),
1190                          StringRef ArchitectureName = StringRef()) {
1191   // If we are doing some processing here on the Mach-O file print the header
1192   // info.  And don't print it otherwise like in the case of printing the
1193   // UniversalHeaders or ArchiveHeaders.
1194   if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind || SymbolTable ||
1195       LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints ||
1196       DylibsUsed || DylibId || ObjcMetaData || (FilterSections.size() != 0)) {
1197     if (!NoLeadingHeaders) {
1198       outs() << Name;
1199       if (!ArchiveMemberName.empty())
1200         outs() << '(' << ArchiveMemberName << ')';
1201       if (!ArchitectureName.empty())
1202         outs() << " (architecture " << ArchitectureName << ")";
1203       outs() << ":\n";
1204     }
1205   }
1206   // To use the report_error() form with an ArchiveName and FileName set
1207   // these up based on what is passed for Name and ArchiveMemberName.
1208   StringRef ArchiveName;
1209   StringRef FileName;
1210   if (!ArchiveMemberName.empty()) {
1211     ArchiveName = Name;
1212     FileName = ArchiveMemberName;
1213   } else {
1214     ArchiveName = StringRef();
1215     FileName = Name;
1216   }
1217 
1218   // If we need the symbol table to do the operation then check it here to
1219   // produce a good error message as to where the Mach-O file comes from in
1220   // the error message.
1221   if (Disassemble || IndirectSymbols || FilterSections.size() != 0 ||
1222       UnwindInfo)
1223     if (Error Err = MachOOF->checkSymbolTable())
1224       report_error(ArchiveName, FileName, std::move(Err), ArchitectureName);
1225 
1226   if (Disassemble)
1227     DisassembleMachO(FileName, MachOOF, "__TEXT", "__text");
1228   if (IndirectSymbols)
1229     PrintIndirectSymbols(MachOOF, !NonVerbose);
1230   if (DataInCode)
1231     PrintDataInCodeTable(MachOOF, !NonVerbose);
1232   if (LinkOptHints)
1233     PrintLinkOptHints(MachOOF);
1234   if (Relocations)
1235     PrintRelocations(MachOOF);
1236   if (SectionHeaders)
1237     PrintSectionHeaders(MachOOF);
1238   if (SectionContents)
1239     PrintSectionContents(MachOOF);
1240   if (FilterSections.size() != 0)
1241     DumpSectionContents(FileName, MachOOF, !NonVerbose);
1242   if (InfoPlist)
1243     DumpInfoPlistSectionContents(FileName, MachOOF);
1244   if (DylibsUsed)
1245     PrintDylibs(MachOOF, false);
1246   if (DylibId)
1247     PrintDylibs(MachOOF, true);
1248   if (SymbolTable)
1249     PrintSymbolTable(MachOOF, ArchiveName, ArchitectureName);
1250   if (UnwindInfo)
1251     printMachOUnwindInfo(MachOOF);
1252   if (PrivateHeaders) {
1253     printMachOFileHeader(MachOOF);
1254     printMachOLoadCommands(MachOOF);
1255   }
1256   if (FirstPrivateHeader)
1257     printMachOFileHeader(MachOOF);
1258   if (ObjcMetaData)
1259     printObjcMetaData(MachOOF, !NonVerbose);
1260   if (ExportsTrie)
1261     printExportsTrie(MachOOF);
1262   if (Rebase)
1263     printRebaseTable(MachOOF);
1264   if (Bind)
1265     printBindTable(MachOOF);
1266   if (LazyBind)
1267     printLazyBindTable(MachOOF);
1268   if (WeakBind)
1269     printWeakBindTable(MachOOF);
1270 
1271   if (DwarfDumpType != DIDT_Null) {
1272     std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*MachOOF));
1273     // Dump the complete DWARF structure.
1274     DIDumpOptions DumpOpts;
1275     DumpOpts.DumpType = DwarfDumpType;
1276     DumpOpts.DumpEH = true;
1277     DICtx->dump(outs(), DumpOpts);
1278   }
1279 }
1280 
1281 // printUnknownCPUType() helps print_fat_headers for unknown CPU's.
1282 static void printUnknownCPUType(uint32_t cputype, uint32_t cpusubtype) {
1283   outs() << "    cputype (" << cputype << ")\n";
1284   outs() << "    cpusubtype (" << cpusubtype << ")\n";
1285 }
1286 
1287 // printCPUType() helps print_fat_headers by printing the cputype and
1288 // pusubtype (symbolically for the one's it knows about).
1289 static void printCPUType(uint32_t cputype, uint32_t cpusubtype) {
1290   switch (cputype) {
1291   case MachO::CPU_TYPE_I386:
1292     switch (cpusubtype) {
1293     case MachO::CPU_SUBTYPE_I386_ALL:
1294       outs() << "    cputype CPU_TYPE_I386\n";
1295       outs() << "    cpusubtype CPU_SUBTYPE_I386_ALL\n";
1296       break;
1297     default:
1298       printUnknownCPUType(cputype, cpusubtype);
1299       break;
1300     }
1301     break;
1302   case MachO::CPU_TYPE_X86_64:
1303     switch (cpusubtype) {
1304     case MachO::CPU_SUBTYPE_X86_64_ALL:
1305       outs() << "    cputype CPU_TYPE_X86_64\n";
1306       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_ALL\n";
1307       break;
1308     case MachO::CPU_SUBTYPE_X86_64_H:
1309       outs() << "    cputype CPU_TYPE_X86_64\n";
1310       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_H\n";
1311       break;
1312     default:
1313       printUnknownCPUType(cputype, cpusubtype);
1314       break;
1315     }
1316     break;
1317   case MachO::CPU_TYPE_ARM:
1318     switch (cpusubtype) {
1319     case MachO::CPU_SUBTYPE_ARM_ALL:
1320       outs() << "    cputype CPU_TYPE_ARM\n";
1321       outs() << "    cpusubtype CPU_SUBTYPE_ARM_ALL\n";
1322       break;
1323     case MachO::CPU_SUBTYPE_ARM_V4T:
1324       outs() << "    cputype CPU_TYPE_ARM\n";
1325       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V4T\n";
1326       break;
1327     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1328       outs() << "    cputype CPU_TYPE_ARM\n";
1329       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n";
1330       break;
1331     case MachO::CPU_SUBTYPE_ARM_XSCALE:
1332       outs() << "    cputype CPU_TYPE_ARM\n";
1333       outs() << "    cpusubtype CPU_SUBTYPE_ARM_XSCALE\n";
1334       break;
1335     case MachO::CPU_SUBTYPE_ARM_V6:
1336       outs() << "    cputype CPU_TYPE_ARM\n";
1337       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6\n";
1338       break;
1339     case MachO::CPU_SUBTYPE_ARM_V6M:
1340       outs() << "    cputype CPU_TYPE_ARM\n";
1341       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6M\n";
1342       break;
1343     case MachO::CPU_SUBTYPE_ARM_V7:
1344       outs() << "    cputype CPU_TYPE_ARM\n";
1345       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7\n";
1346       break;
1347     case MachO::CPU_SUBTYPE_ARM_V7EM:
1348       outs() << "    cputype CPU_TYPE_ARM\n";
1349       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7EM\n";
1350       break;
1351     case MachO::CPU_SUBTYPE_ARM_V7K:
1352       outs() << "    cputype CPU_TYPE_ARM\n";
1353       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7K\n";
1354       break;
1355     case MachO::CPU_SUBTYPE_ARM_V7M:
1356       outs() << "    cputype CPU_TYPE_ARM\n";
1357       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7M\n";
1358       break;
1359     case MachO::CPU_SUBTYPE_ARM_V7S:
1360       outs() << "    cputype CPU_TYPE_ARM\n";
1361       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7S\n";
1362       break;
1363     default:
1364       printUnknownCPUType(cputype, cpusubtype);
1365       break;
1366     }
1367     break;
1368   case MachO::CPU_TYPE_ARM64:
1369     switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
1370     case MachO::CPU_SUBTYPE_ARM64_ALL:
1371       outs() << "    cputype CPU_TYPE_ARM64\n";
1372       outs() << "    cpusubtype CPU_SUBTYPE_ARM64_ALL\n";
1373       break;
1374     default:
1375       printUnknownCPUType(cputype, cpusubtype);
1376       break;
1377     }
1378     break;
1379   default:
1380     printUnknownCPUType(cputype, cpusubtype);
1381     break;
1382   }
1383 }
1384 
1385 static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB,
1386                                        bool verbose) {
1387   outs() << "Fat headers\n";
1388   if (verbose) {
1389     if (UB->getMagic() == MachO::FAT_MAGIC)
1390       outs() << "fat_magic FAT_MAGIC\n";
1391     else // UB->getMagic() == MachO::FAT_MAGIC_64
1392       outs() << "fat_magic FAT_MAGIC_64\n";
1393   } else
1394     outs() << "fat_magic " << format("0x%" PRIx32, MachO::FAT_MAGIC) << "\n";
1395 
1396   uint32_t nfat_arch = UB->getNumberOfObjects();
1397   StringRef Buf = UB->getData();
1398   uint64_t size = Buf.size();
1399   uint64_t big_size = sizeof(struct MachO::fat_header) +
1400                       nfat_arch * sizeof(struct MachO::fat_arch);
1401   outs() << "nfat_arch " << UB->getNumberOfObjects();
1402   if (nfat_arch == 0)
1403     outs() << " (malformed, contains zero architecture types)\n";
1404   else if (big_size > size)
1405     outs() << " (malformed, architectures past end of file)\n";
1406   else
1407     outs() << "\n";
1408 
1409   for (uint32_t i = 0; i < nfat_arch; ++i) {
1410     MachOUniversalBinary::ObjectForArch OFA(UB, i);
1411     uint32_t cputype = OFA.getCPUType();
1412     uint32_t cpusubtype = OFA.getCPUSubType();
1413     outs() << "architecture ";
1414     for (uint32_t j = 0; i != 0 && j <= i - 1; j++) {
1415       MachOUniversalBinary::ObjectForArch other_OFA(UB, j);
1416       uint32_t other_cputype = other_OFA.getCPUType();
1417       uint32_t other_cpusubtype = other_OFA.getCPUSubType();
1418       if (cputype != 0 && cpusubtype != 0 && cputype == other_cputype &&
1419           (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) ==
1420               (other_cpusubtype & ~MachO::CPU_SUBTYPE_MASK)) {
1421         outs() << "(illegal duplicate architecture) ";
1422         break;
1423       }
1424     }
1425     if (verbose) {
1426       outs() << OFA.getArchFlagName() << "\n";
1427       printCPUType(cputype, cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
1428     } else {
1429       outs() << i << "\n";
1430       outs() << "    cputype " << cputype << "\n";
1431       outs() << "    cpusubtype " << (cpusubtype & ~MachO::CPU_SUBTYPE_MASK)
1432              << "\n";
1433     }
1434     if (verbose &&
1435         (cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64)
1436       outs() << "    capabilities CPU_SUBTYPE_LIB64\n";
1437     else
1438       outs() << "    capabilities "
1439              << format("0x%" PRIx32,
1440                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24) << "\n";
1441     outs() << "    offset " << OFA.getOffset();
1442     if (OFA.getOffset() > size)
1443       outs() << " (past end of file)";
1444     if (OFA.getOffset() % (1 << OFA.getAlign()) != 0)
1445       outs() << " (not aligned on it's alignment (2^" << OFA.getAlign() << ")";
1446     outs() << "\n";
1447     outs() << "    size " << OFA.getSize();
1448     big_size = OFA.getOffset() + OFA.getSize();
1449     if (big_size > size)
1450       outs() << " (past end of file)";
1451     outs() << "\n";
1452     outs() << "    align 2^" << OFA.getAlign() << " (" << (1 << OFA.getAlign())
1453            << ")\n";
1454   }
1455 }
1456 
1457 static void printArchiveChild(StringRef Filename, const Archive::Child &C,
1458                               bool verbose, bool print_offset,
1459                               StringRef ArchitectureName = StringRef()) {
1460   if (print_offset)
1461     outs() << C.getChildOffset() << "\t";
1462   Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
1463   if (!ModeOrErr)
1464     report_error(Filename, C, ModeOrErr.takeError(), ArchitectureName);
1465   sys::fs::perms Mode = ModeOrErr.get();
1466   if (verbose) {
1467     // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
1468     // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
1469     outs() << "-";
1470     outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
1471     outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
1472     outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
1473     outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
1474     outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
1475     outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
1476     outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
1477     outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
1478     outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
1479   } else {
1480     outs() << format("0%o ", Mode);
1481   }
1482 
1483   Expected<unsigned> UIDOrErr = C.getUID();
1484   if (!UIDOrErr)
1485     report_error(Filename, C, UIDOrErr.takeError(), ArchitectureName);
1486   unsigned UID = UIDOrErr.get();
1487   outs() << format("%3d/", UID);
1488   Expected<unsigned> GIDOrErr = C.getGID();
1489   if (!GIDOrErr)
1490     report_error(Filename, C, GIDOrErr.takeError(), ArchitectureName);
1491   unsigned GID = GIDOrErr.get();
1492   outs() << format("%-3d ", GID);
1493   Expected<uint64_t> Size = C.getRawSize();
1494   if (!Size)
1495     report_error(Filename, C, Size.takeError(), ArchitectureName);
1496   outs() << format("%5" PRId64, Size.get()) << " ";
1497 
1498   StringRef RawLastModified = C.getRawLastModified();
1499   if (verbose) {
1500     unsigned Seconds;
1501     if (RawLastModified.getAsInteger(10, Seconds))
1502       outs() << "(date: \"" << RawLastModified
1503              << "\" contains non-decimal chars) ";
1504     else {
1505       // Since cime(3) returns a 26 character string of the form:
1506       // "Sun Sep 16 01:03:52 1973\n\0"
1507       // just print 24 characters.
1508       time_t t = Seconds;
1509       outs() << format("%.24s ", ctime(&t));
1510     }
1511   } else {
1512     outs() << RawLastModified << " ";
1513   }
1514 
1515   if (verbose) {
1516     Expected<StringRef> NameOrErr = C.getName();
1517     if (!NameOrErr) {
1518       consumeError(NameOrErr.takeError());
1519       Expected<StringRef> NameOrErr = C.getRawName();
1520       if (!NameOrErr)
1521         report_error(Filename, C, NameOrErr.takeError(), ArchitectureName);
1522       StringRef RawName = NameOrErr.get();
1523       outs() << RawName << "\n";
1524     } else {
1525       StringRef Name = NameOrErr.get();
1526       outs() << Name << "\n";
1527     }
1528   } else {
1529     Expected<StringRef> NameOrErr = C.getRawName();
1530     if (!NameOrErr)
1531       report_error(Filename, C, NameOrErr.takeError(), ArchitectureName);
1532     StringRef RawName = NameOrErr.get();
1533     outs() << RawName << "\n";
1534   }
1535 }
1536 
1537 static void printArchiveHeaders(StringRef Filename, Archive *A, bool verbose,
1538                                 bool print_offset,
1539                                 StringRef ArchitectureName = StringRef()) {
1540   Error Err = Error::success();
1541   ;
1542   for (const auto &C : A->children(Err, false))
1543     printArchiveChild(Filename, C, verbose, print_offset, ArchitectureName);
1544 
1545   if (Err)
1546     report_error(StringRef(), Filename, std::move(Err), ArchitectureName);
1547 }
1548 
1549 // ParseInputMachO() parses the named Mach-O file in Filename and handles the
1550 // -arch flags selecting just those slices as specified by them and also parses
1551 // archive files.  Then for each individual Mach-O file ProcessMachO() is
1552 // called to process the file based on the command line options.
1553 void llvm::ParseInputMachO(StringRef Filename) {
1554   // Check for -arch all and verifiy the -arch flags are valid.
1555   for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1556     if (ArchFlags[i] == "all") {
1557       ArchAll = true;
1558     } else {
1559       if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
1560         errs() << "llvm-objdump: Unknown architecture named '" + ArchFlags[i] +
1561                       "'for the -arch option\n";
1562         return;
1563       }
1564     }
1565   }
1566 
1567   // Attempt to open the binary.
1568   Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
1569   if (!BinaryOrErr) {
1570     if (auto E = isNotObjectErrorInvalidFileType(BinaryOrErr.takeError()))
1571       report_error(Filename, std::move(E));
1572     else
1573       outs() << Filename << ": is not an object file\n";
1574     return;
1575   }
1576   Binary &Bin = *BinaryOrErr.get().getBinary();
1577 
1578   if (Archive *A = dyn_cast<Archive>(&Bin)) {
1579     outs() << "Archive : " << Filename << "\n";
1580     if (ArchiveHeaders)
1581       printArchiveHeaders(Filename, A, !NonVerbose, ArchiveMemberOffsets);
1582 
1583     Error Err = Error::success();
1584     for (auto &C : A->children(Err)) {
1585       Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1586       if (!ChildOrErr) {
1587         if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1588           report_error(Filename, C, std::move(E));
1589         continue;
1590       }
1591       if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1592         if (!checkMachOAndArchFlags(O, Filename))
1593           return;
1594         ProcessMachO(Filename, O, O->getFileName());
1595       }
1596     }
1597     if (Err)
1598       report_error(Filename, std::move(Err));
1599     return;
1600   }
1601   if (UniversalHeaders) {
1602     if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin))
1603       printMachOUniversalHeaders(UB, !NonVerbose);
1604   }
1605   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
1606     // If we have a list of architecture flags specified dump only those.
1607     if (!ArchAll && ArchFlags.size() != 0) {
1608       // Look for a slice in the universal binary that matches each ArchFlag.
1609       bool ArchFound;
1610       for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1611         ArchFound = false;
1612         for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1613                                                    E = UB->end_objects();
1614              I != E; ++I) {
1615           if (ArchFlags[i] == I->getArchFlagName()) {
1616             ArchFound = true;
1617             Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
1618                 I->getAsObjectFile();
1619             std::string ArchitectureName = "";
1620             if (ArchFlags.size() > 1)
1621               ArchitectureName = I->getArchFlagName();
1622             if (ObjOrErr) {
1623               ObjectFile &O = *ObjOrErr.get();
1624               if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1625                 ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1626             } else if (auto E = isNotObjectErrorInvalidFileType(
1627                        ObjOrErr.takeError())) {
1628               report_error(Filename, StringRef(), std::move(E),
1629                            ArchitectureName);
1630               continue;
1631             } else if (Expected<std::unique_ptr<Archive>> AOrErr =
1632                            I->getAsArchive()) {
1633               std::unique_ptr<Archive> &A = *AOrErr;
1634               outs() << "Archive : " << Filename;
1635               if (!ArchitectureName.empty())
1636                 outs() << " (architecture " << ArchitectureName << ")";
1637               outs() << "\n";
1638               if (ArchiveHeaders)
1639                 printArchiveHeaders(Filename, A.get(), !NonVerbose,
1640                                     ArchiveMemberOffsets, ArchitectureName);
1641               Error Err = Error::success();
1642               for (auto &C : A->children(Err)) {
1643                 Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1644                 if (!ChildOrErr) {
1645                   if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1646                     report_error(Filename, C, std::move(E), ArchitectureName);
1647                   continue;
1648                 }
1649                 if (MachOObjectFile *O =
1650                         dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1651                   ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
1652               }
1653               if (Err)
1654                 report_error(Filename, std::move(Err));
1655             } else {
1656               consumeError(AOrErr.takeError());
1657               error("Mach-O universal file: " + Filename + " for " +
1658                     "architecture " + StringRef(I->getArchFlagName()) +
1659                     " is not a Mach-O file or an archive file");
1660             }
1661           }
1662         }
1663         if (!ArchFound) {
1664           errs() << "llvm-objdump: file: " + Filename + " does not contain "
1665                  << "architecture: " + ArchFlags[i] + "\n";
1666           return;
1667         }
1668       }
1669       return;
1670     }
1671     // No architecture flags were specified so if this contains a slice that
1672     // matches the host architecture dump only that.
1673     if (!ArchAll) {
1674       for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1675                                                  E = UB->end_objects();
1676            I != E; ++I) {
1677         if (MachOObjectFile::getHostArch().getArchName() ==
1678             I->getArchFlagName()) {
1679           Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1680           std::string ArchiveName;
1681           ArchiveName.clear();
1682           if (ObjOrErr) {
1683             ObjectFile &O = *ObjOrErr.get();
1684             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1685               ProcessMachO(Filename, MachOOF);
1686           } else if (auto E = isNotObjectErrorInvalidFileType(
1687                      ObjOrErr.takeError())) {
1688             report_error(Filename, std::move(E));
1689             continue;
1690           } else if (Expected<std::unique_ptr<Archive>> AOrErr =
1691                          I->getAsArchive()) {
1692             std::unique_ptr<Archive> &A = *AOrErr;
1693             outs() << "Archive : " << Filename << "\n";
1694             if (ArchiveHeaders)
1695               printArchiveHeaders(Filename, A.get(), !NonVerbose,
1696                                   ArchiveMemberOffsets);
1697             Error Err = Error::success();
1698             for (auto &C : A->children(Err)) {
1699               Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1700               if (!ChildOrErr) {
1701                 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1702                   report_error(Filename, C, std::move(E));
1703                 continue;
1704               }
1705               if (MachOObjectFile *O =
1706                       dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1707                 ProcessMachO(Filename, O, O->getFileName());
1708             }
1709             if (Err)
1710               report_error(Filename, std::move(Err));
1711           } else {
1712             consumeError(AOrErr.takeError());
1713             error("Mach-O universal file: " + Filename + " for architecture " +
1714                   StringRef(I->getArchFlagName()) +
1715                   " is not a Mach-O file or an archive file");
1716           }
1717           return;
1718         }
1719       }
1720     }
1721     // Either all architectures have been specified or none have been specified
1722     // and this does not contain the host architecture so dump all the slices.
1723     bool moreThanOneArch = UB->getNumberOfObjects() > 1;
1724     for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1725                                                E = UB->end_objects();
1726          I != E; ++I) {
1727       Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1728       std::string ArchitectureName = "";
1729       if (moreThanOneArch)
1730         ArchitectureName = I->getArchFlagName();
1731       if (ObjOrErr) {
1732         ObjectFile &Obj = *ObjOrErr.get();
1733         if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
1734           ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1735       } else if (auto E = isNotObjectErrorInvalidFileType(
1736                  ObjOrErr.takeError())) {
1737         report_error(StringRef(), Filename, std::move(E), ArchitectureName);
1738         continue;
1739       } else if (Expected<std::unique_ptr<Archive>> AOrErr =
1740                    I->getAsArchive()) {
1741         std::unique_ptr<Archive> &A = *AOrErr;
1742         outs() << "Archive : " << Filename;
1743         if (!ArchitectureName.empty())
1744           outs() << " (architecture " << ArchitectureName << ")";
1745         outs() << "\n";
1746         if (ArchiveHeaders)
1747           printArchiveHeaders(Filename, A.get(), !NonVerbose,
1748                               ArchiveMemberOffsets, ArchitectureName);
1749         Error Err = Error::success();
1750         for (auto &C : A->children(Err)) {
1751           Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1752           if (!ChildOrErr) {
1753             if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1754               report_error(Filename, C, std::move(E), ArchitectureName);
1755             continue;
1756           }
1757           if (MachOObjectFile *O =
1758                   dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1759             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
1760               ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
1761                            ArchitectureName);
1762           }
1763         }
1764         if (Err)
1765           report_error(Filename, std::move(Err));
1766       } else {
1767         consumeError(AOrErr.takeError());
1768         error("Mach-O universal file: " + Filename + " for architecture " +
1769               StringRef(I->getArchFlagName()) +
1770               " is not a Mach-O file or an archive file");
1771       }
1772     }
1773     return;
1774   }
1775   if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
1776     if (!checkMachOAndArchFlags(O, Filename))
1777       return;
1778     if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
1779       ProcessMachO(Filename, MachOOF);
1780     } else
1781       errs() << "llvm-objdump: '" << Filename << "': "
1782              << "Object is not a Mach-O file type.\n";
1783     return;
1784   }
1785   llvm_unreachable("Input object can't be invalid at this point");
1786 }
1787 
1788 // The block of info used by the Symbolizer call backs.
1789 struct DisassembleInfo {
1790   bool verbose;
1791   MachOObjectFile *O;
1792   SectionRef S;
1793   SymbolAddressMap *AddrMap;
1794   std::vector<SectionRef> *Sections;
1795   const char *class_name;
1796   const char *selector_name;
1797   char *method;
1798   char *demangled_name;
1799   uint64_t adrp_addr;
1800   uint32_t adrp_inst;
1801   std::unique_ptr<SymbolAddressMap> bindtable;
1802   uint32_t depth;
1803 };
1804 
1805 // SymbolizerGetOpInfo() is the operand information call back function.
1806 // This is called to get the symbolic information for operand(s) of an
1807 // instruction when it is being done.  This routine does this from
1808 // the relocation information, symbol table, etc. That block of information
1809 // is a pointer to the struct DisassembleInfo that was passed when the
1810 // disassembler context was created and passed to back to here when
1811 // called back by the disassembler for instruction operands that could have
1812 // relocation information. The address of the instruction containing operand is
1813 // at the Pc parameter.  The immediate value the operand has is passed in
1814 // op_info->Value and is at Offset past the start of the instruction and has a
1815 // byte Size of 1, 2 or 4. The symbolc information is returned in TagBuf is the
1816 // LLVMOpInfo1 struct defined in the header "llvm-c/Disassembler.h" as symbol
1817 // names and addends of the symbolic expression to add for the operand.  The
1818 // value of TagType is currently 1 (for the LLVMOpInfo1 struct). If symbolic
1819 // information is returned then this function returns 1 else it returns 0.
1820 static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
1821                                uint64_t Size, int TagType, void *TagBuf) {
1822   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
1823   struct LLVMOpInfo1 *op_info = (struct LLVMOpInfo1 *)TagBuf;
1824   uint64_t value = op_info->Value;
1825 
1826   // Make sure all fields returned are zero if we don't set them.
1827   memset((void *)op_info, '\0', sizeof(struct LLVMOpInfo1));
1828   op_info->Value = value;
1829 
1830   // If the TagType is not the value 1 which it code knows about or if no
1831   // verbose symbolic information is wanted then just return 0, indicating no
1832   // information is being returned.
1833   if (TagType != 1 || !info->verbose)
1834     return 0;
1835 
1836   unsigned int Arch = info->O->getArch();
1837   if (Arch == Triple::x86) {
1838     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
1839       return 0;
1840     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
1841       // TODO:
1842       // Search the external relocation entries of a fully linked image
1843       // (if any) for an entry that matches this segment offset.
1844       // uint32_t seg_offset = (Pc + Offset);
1845       return 0;
1846     }
1847     // In MH_OBJECT filetypes search the section's relocation entries (if any)
1848     // for an entry for this section offset.
1849     uint32_t sect_addr = info->S.getAddress();
1850     uint32_t sect_offset = (Pc + Offset) - sect_addr;
1851     bool reloc_found = false;
1852     DataRefImpl Rel;
1853     MachO::any_relocation_info RE;
1854     bool isExtern = false;
1855     SymbolRef Symbol;
1856     bool r_scattered = false;
1857     uint32_t r_value, pair_r_value, r_type;
1858     for (const RelocationRef &Reloc : info->S.relocations()) {
1859       uint64_t RelocOffset = Reloc.getOffset();
1860       if (RelocOffset == sect_offset) {
1861         Rel = Reloc.getRawDataRefImpl();
1862         RE = info->O->getRelocation(Rel);
1863         r_type = info->O->getAnyRelocationType(RE);
1864         r_scattered = info->O->isRelocationScattered(RE);
1865         if (r_scattered) {
1866           r_value = info->O->getScatteredRelocationValue(RE);
1867           if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
1868               r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
1869             DataRefImpl RelNext = Rel;
1870             info->O->moveRelocationNext(RelNext);
1871             MachO::any_relocation_info RENext;
1872             RENext = info->O->getRelocation(RelNext);
1873             if (info->O->isRelocationScattered(RENext))
1874               pair_r_value = info->O->getScatteredRelocationValue(RENext);
1875             else
1876               return 0;
1877           }
1878         } else {
1879           isExtern = info->O->getPlainRelocationExternal(RE);
1880           if (isExtern) {
1881             symbol_iterator RelocSym = Reloc.getSymbol();
1882             Symbol = *RelocSym;
1883           }
1884         }
1885         reloc_found = true;
1886         break;
1887       }
1888     }
1889     if (reloc_found && isExtern) {
1890       Expected<StringRef> SymName = Symbol.getName();
1891       if (!SymName)
1892         report_error(info->O->getFileName(), SymName.takeError());
1893       const char *name = SymName->data();
1894       op_info->AddSymbol.Present = 1;
1895       op_info->AddSymbol.Name = name;
1896       // For i386 extern relocation entries the value in the instruction is
1897       // the offset from the symbol, and value is already set in op_info->Value.
1898       return 1;
1899     }
1900     if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
1901                         r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
1902       const char *add = GuessSymbolName(r_value, info->AddrMap);
1903       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
1904       uint32_t offset = value - (r_value - pair_r_value);
1905       op_info->AddSymbol.Present = 1;
1906       if (add != nullptr)
1907         op_info->AddSymbol.Name = add;
1908       else
1909         op_info->AddSymbol.Value = r_value;
1910       op_info->SubtractSymbol.Present = 1;
1911       if (sub != nullptr)
1912         op_info->SubtractSymbol.Name = sub;
1913       else
1914         op_info->SubtractSymbol.Value = pair_r_value;
1915       op_info->Value = offset;
1916       return 1;
1917     }
1918     return 0;
1919   }
1920   if (Arch == Triple::x86_64) {
1921     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
1922       return 0;
1923     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
1924       // TODO:
1925       // Search the external relocation entries of a fully linked image
1926       // (if any) for an entry that matches this segment offset.
1927       // uint64_t seg_offset = (Pc + Offset);
1928       return 0;
1929     }
1930     // In MH_OBJECT filetypes search the section's relocation entries (if any)
1931     // for an entry for this section offset.
1932     uint64_t sect_addr = info->S.getAddress();
1933     uint64_t sect_offset = (Pc + Offset) - sect_addr;
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->S.relocations()) {
1940       uint64_t RelocOffset = Reloc.getOffset();
1941       if (RelocOffset == sect_offset) {
1942         Rel = Reloc.getRawDataRefImpl();
1943         RE = info->O->getRelocation(Rel);
1944         // NOTE: Scattered relocations don't exist on x86_64.
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       unsigned Type = info->O->getAnyRelocationType(RE);
1965       if (Type == MachO::X86_64_RELOC_SUBTRACTOR) {
1966         DataRefImpl RelNext = Rel;
1967         info->O->moveRelocationNext(RelNext);
1968         MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
1969         unsigned TypeNext = info->O->getAnyRelocationType(RENext);
1970         bool isExternNext = info->O->getPlainRelocationExternal(RENext);
1971         unsigned SymbolNum = info->O->getPlainRelocationSymbolNum(RENext);
1972         if (TypeNext == MachO::X86_64_RELOC_UNSIGNED && isExternNext) {
1973           op_info->SubtractSymbol.Present = 1;
1974           op_info->SubtractSymbol.Name = name;
1975           symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum);
1976           Symbol = *RelocSymNext;
1977           Expected<StringRef> SymNameNext = Symbol.getName();
1978           if (!SymNameNext)
1979             report_error(info->O->getFileName(), SymNameNext.takeError());
1980           name = SymNameNext->data();
1981         }
1982       }
1983       // TODO: add the VariantKinds to op_info->VariantKind for relocation types
1984       // like: X86_64_RELOC_TLV, X86_64_RELOC_GOT_LOAD and X86_64_RELOC_GOT.
1985       op_info->AddSymbol.Present = 1;
1986       op_info->AddSymbol.Name = name;
1987       return 1;
1988     }
1989     return 0;
1990   }
1991   if (Arch == Triple::arm) {
1992     if (Offset != 0 || (Size != 4 && Size != 2))
1993       return 0;
1994     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
1995       // TODO:
1996       // Search the external relocation entries of a fully linked image
1997       // (if any) for an entry that matches this segment offset.
1998       // uint32_t seg_offset = (Pc + Offset);
1999       return 0;
2000     }
2001     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2002     // for an entry for this section offset.
2003     uint32_t sect_addr = info->S.getAddress();
2004     uint32_t sect_offset = (Pc + Offset) - sect_addr;
2005     DataRefImpl Rel;
2006     MachO::any_relocation_info RE;
2007     bool isExtern = false;
2008     SymbolRef Symbol;
2009     bool r_scattered = false;
2010     uint32_t r_value, pair_r_value, r_type, r_length, other_half;
2011     auto Reloc =
2012         find_if(info->S.relocations(), [&](const RelocationRef &Reloc) {
2013           uint64_t RelocOffset = Reloc.getOffset();
2014           return RelocOffset == sect_offset;
2015         });
2016 
2017     if (Reloc == info->S.relocations().end())
2018       return 0;
2019 
2020     Rel = Reloc->getRawDataRefImpl();
2021     RE = info->O->getRelocation(Rel);
2022     r_length = info->O->getAnyRelocationLength(RE);
2023     r_scattered = info->O->isRelocationScattered(RE);
2024     if (r_scattered) {
2025       r_value = info->O->getScatteredRelocationValue(RE);
2026       r_type = info->O->getScatteredRelocationType(RE);
2027     } else {
2028       r_type = info->O->getAnyRelocationType(RE);
2029       isExtern = info->O->getPlainRelocationExternal(RE);
2030       if (isExtern) {
2031         symbol_iterator RelocSym = Reloc->getSymbol();
2032         Symbol = *RelocSym;
2033       }
2034     }
2035     if (r_type == MachO::ARM_RELOC_HALF ||
2036         r_type == MachO::ARM_RELOC_SECTDIFF ||
2037         r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
2038         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2039       DataRefImpl RelNext = Rel;
2040       info->O->moveRelocationNext(RelNext);
2041       MachO::any_relocation_info RENext;
2042       RENext = info->O->getRelocation(RelNext);
2043       other_half = info->O->getAnyRelocationAddress(RENext) & 0xffff;
2044       if (info->O->isRelocationScattered(RENext))
2045         pair_r_value = info->O->getScatteredRelocationValue(RENext);
2046     }
2047 
2048     if (isExtern) {
2049       Expected<StringRef> SymName = Symbol.getName();
2050       if (!SymName)
2051         report_error(info->O->getFileName(), SymName.takeError());
2052       const char *name = SymName->data();
2053       op_info->AddSymbol.Present = 1;
2054       op_info->AddSymbol.Name = name;
2055       switch (r_type) {
2056       case MachO::ARM_RELOC_HALF:
2057         if ((r_length & 0x1) == 1) {
2058           op_info->Value = value << 16 | other_half;
2059           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2060         } else {
2061           op_info->Value = other_half << 16 | value;
2062           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2063         }
2064         break;
2065       default:
2066         break;
2067       }
2068       return 1;
2069     }
2070     // If we have a branch that is not an external relocation entry then
2071     // return 0 so the code in tryAddingSymbolicOperand() can use the
2072     // SymbolLookUp call back with the branch target address to look up the
2073     // symbol and possibility add an annotation for a symbol stub.
2074     if (isExtern == 0 && (r_type == MachO::ARM_RELOC_BR24 ||
2075                           r_type == MachO::ARM_THUMB_RELOC_BR22))
2076       return 0;
2077 
2078     uint32_t offset = 0;
2079     if (r_type == MachO::ARM_RELOC_HALF ||
2080         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2081       if ((r_length & 0x1) == 1)
2082         value = value << 16 | other_half;
2083       else
2084         value = other_half << 16 | value;
2085     }
2086     if (r_scattered && (r_type != MachO::ARM_RELOC_HALF &&
2087                         r_type != MachO::ARM_RELOC_HALF_SECTDIFF)) {
2088       offset = value - r_value;
2089       value = r_value;
2090     }
2091 
2092     if (r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2093       if ((r_length & 0x1) == 1)
2094         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2095       else
2096         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2097       const char *add = GuessSymbolName(r_value, info->AddrMap);
2098       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
2099       int32_t offset = value - (r_value - pair_r_value);
2100       op_info->AddSymbol.Present = 1;
2101       if (add != nullptr)
2102         op_info->AddSymbol.Name = add;
2103       else
2104         op_info->AddSymbol.Value = r_value;
2105       op_info->SubtractSymbol.Present = 1;
2106       if (sub != nullptr)
2107         op_info->SubtractSymbol.Name = sub;
2108       else
2109         op_info->SubtractSymbol.Value = pair_r_value;
2110       op_info->Value = offset;
2111       return 1;
2112     }
2113 
2114     op_info->AddSymbol.Present = 1;
2115     op_info->Value = offset;
2116     if (r_type == MachO::ARM_RELOC_HALF) {
2117       if ((r_length & 0x1) == 1)
2118         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2119       else
2120         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2121     }
2122     const char *add = GuessSymbolName(value, info->AddrMap);
2123     if (add != nullptr) {
2124       op_info->AddSymbol.Name = add;
2125       return 1;
2126     }
2127     op_info->AddSymbol.Value = value;
2128     return 1;
2129   }
2130   if (Arch == Triple::aarch64) {
2131     if (Offset != 0 || Size != 4)
2132       return 0;
2133     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2134       // TODO:
2135       // Search the external relocation entries of a fully linked image
2136       // (if any) for an entry that matches this segment offset.
2137       // uint64_t seg_offset = (Pc + Offset);
2138       return 0;
2139     }
2140     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2141     // for an entry for this section offset.
2142     uint64_t sect_addr = info->S.getAddress();
2143     uint64_t sect_offset = (Pc + Offset) - sect_addr;
2144     auto Reloc =
2145         find_if(info->S.relocations(), [&](const RelocationRef &Reloc) {
2146           uint64_t RelocOffset = Reloc.getOffset();
2147           return RelocOffset == sect_offset;
2148         });
2149 
2150     if (Reloc == info->S.relocations().end())
2151       return 0;
2152 
2153     DataRefImpl Rel = Reloc->getRawDataRefImpl();
2154     MachO::any_relocation_info RE = info->O->getRelocation(Rel);
2155     uint32_t r_type = info->O->getAnyRelocationType(RE);
2156     if (r_type == MachO::ARM64_RELOC_ADDEND) {
2157       DataRefImpl RelNext = Rel;
2158       info->O->moveRelocationNext(RelNext);
2159       MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
2160       if (value == 0) {
2161         value = info->O->getPlainRelocationSymbolNum(RENext);
2162         op_info->Value = value;
2163       }
2164     }
2165     // NOTE: Scattered relocations don't exist on arm64.
2166     if (!info->O->getPlainRelocationExternal(RE))
2167       return 0;
2168     Expected<StringRef> SymName = Reloc->getSymbol()->getName();
2169     if (!SymName)
2170       report_error(info->O->getFileName(), SymName.takeError());
2171     const char *name = SymName->data();
2172     op_info->AddSymbol.Present = 1;
2173     op_info->AddSymbol.Name = name;
2174 
2175     switch (r_type) {
2176     case MachO::ARM64_RELOC_PAGE21:
2177       /* @page */
2178       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGE;
2179       break;
2180     case MachO::ARM64_RELOC_PAGEOFF12:
2181       /* @pageoff */
2182       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGEOFF;
2183       break;
2184     case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
2185       /* @gotpage */
2186       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGE;
2187       break;
2188     case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
2189       /* @gotpageoff */
2190       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF;
2191       break;
2192     case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
2193       /* @tvlppage is not implemented in llvm-mc */
2194       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVP;
2195       break;
2196     case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
2197       /* @tvlppageoff is not implemented in llvm-mc */
2198       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVOFF;
2199       break;
2200     default:
2201     case MachO::ARM64_RELOC_BRANCH26:
2202       op_info->VariantKind = LLVMDisassembler_VariantKind_None;
2203       break;
2204     }
2205     return 1;
2206   }
2207   return 0;
2208 }
2209 
2210 // GuessCstringPointer is passed the address of what might be a pointer to a
2211 // literal string in a cstring section.  If that address is in a cstring section
2212 // it returns a pointer to that string.  Else it returns nullptr.
2213 static const char *GuessCstringPointer(uint64_t ReferenceValue,
2214                                        struct DisassembleInfo *info) {
2215   for (const auto &Load : info->O->load_commands()) {
2216     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2217       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2218       for (unsigned J = 0; J < Seg.nsects; ++J) {
2219         MachO::section_64 Sec = info->O->getSection64(Load, J);
2220         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2221         if (section_type == MachO::S_CSTRING_LITERALS &&
2222             ReferenceValue >= Sec.addr &&
2223             ReferenceValue < Sec.addr + Sec.size) {
2224           uint64_t sect_offset = ReferenceValue - Sec.addr;
2225           uint64_t object_offset = Sec.offset + sect_offset;
2226           StringRef MachOContents = info->O->getData();
2227           uint64_t object_size = MachOContents.size();
2228           const char *object_addr = (const char *)MachOContents.data();
2229           if (object_offset < object_size) {
2230             const char *name = object_addr + object_offset;
2231             return name;
2232           } else {
2233             return nullptr;
2234           }
2235         }
2236       }
2237     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
2238       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
2239       for (unsigned J = 0; J < Seg.nsects; ++J) {
2240         MachO::section Sec = info->O->getSection(Load, J);
2241         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2242         if (section_type == MachO::S_CSTRING_LITERALS &&
2243             ReferenceValue >= Sec.addr &&
2244             ReferenceValue < Sec.addr + Sec.size) {
2245           uint64_t sect_offset = ReferenceValue - Sec.addr;
2246           uint64_t object_offset = Sec.offset + sect_offset;
2247           StringRef MachOContents = info->O->getData();
2248           uint64_t object_size = MachOContents.size();
2249           const char *object_addr = (const char *)MachOContents.data();
2250           if (object_offset < object_size) {
2251             const char *name = object_addr + object_offset;
2252             return name;
2253           } else {
2254             return nullptr;
2255           }
2256         }
2257       }
2258     }
2259   }
2260   return nullptr;
2261 }
2262 
2263 // GuessIndirectSymbol returns the name of the indirect symbol for the
2264 // ReferenceValue passed in or nullptr.  This is used when ReferenceValue maybe
2265 // an address of a symbol stub or a lazy or non-lazy pointer to associate the
2266 // symbol name being referenced by the stub or pointer.
2267 static const char *GuessIndirectSymbol(uint64_t ReferenceValue,
2268                                        struct DisassembleInfo *info) {
2269   MachO::dysymtab_command Dysymtab = info->O->getDysymtabLoadCommand();
2270   MachO::symtab_command Symtab = info->O->getSymtabLoadCommand();
2271   for (const auto &Load : info->O->load_commands()) {
2272     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2273       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2274       for (unsigned J = 0; J < Seg.nsects; ++J) {
2275         MachO::section_64 Sec = info->O->getSection64(Load, J);
2276         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2277         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
2278              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
2279              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
2280              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
2281              section_type == MachO::S_SYMBOL_STUBS) &&
2282             ReferenceValue >= Sec.addr &&
2283             ReferenceValue < Sec.addr + Sec.size) {
2284           uint32_t stride;
2285           if (section_type == MachO::S_SYMBOL_STUBS)
2286             stride = Sec.reserved2;
2287           else
2288             stride = 8;
2289           if (stride == 0)
2290             return nullptr;
2291           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
2292           if (index < Dysymtab.nindirectsyms) {
2293             uint32_t indirect_symbol =
2294                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
2295             if (indirect_symbol < Symtab.nsyms) {
2296               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
2297               SymbolRef Symbol = *Sym;
2298               Expected<StringRef> SymName = Symbol.getName();
2299               if (!SymName)
2300                 report_error(info->O->getFileName(), SymName.takeError());
2301               const char *name = SymName->data();
2302               return name;
2303             }
2304           }
2305         }
2306       }
2307     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
2308       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
2309       for (unsigned J = 0; J < Seg.nsects; ++J) {
2310         MachO::section Sec = info->O->getSection(Load, J);
2311         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2312         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
2313              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
2314              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
2315              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
2316              section_type == MachO::S_SYMBOL_STUBS) &&
2317             ReferenceValue >= Sec.addr &&
2318             ReferenceValue < Sec.addr + Sec.size) {
2319           uint32_t stride;
2320           if (section_type == MachO::S_SYMBOL_STUBS)
2321             stride = Sec.reserved2;
2322           else
2323             stride = 4;
2324           if (stride == 0)
2325             return nullptr;
2326           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
2327           if (index < Dysymtab.nindirectsyms) {
2328             uint32_t indirect_symbol =
2329                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
2330             if (indirect_symbol < Symtab.nsyms) {
2331               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
2332               SymbolRef Symbol = *Sym;
2333               Expected<StringRef> SymName = Symbol.getName();
2334               if (!SymName)
2335                 report_error(info->O->getFileName(), SymName.takeError());
2336               const char *name = SymName->data();
2337               return name;
2338             }
2339           }
2340         }
2341       }
2342     }
2343   }
2344   return nullptr;
2345 }
2346 
2347 // method_reference() is called passing it the ReferenceName that might be
2348 // a reference it to an Objective-C method call.  If so then it allocates and
2349 // assembles a method call string with the values last seen and saved in
2350 // the DisassembleInfo's class_name and selector_name fields.  This is saved
2351 // into the method field of the info and any previous string is free'ed.
2352 // Then the class_name field in the info is set to nullptr.  The method call
2353 // string is set into ReferenceName and ReferenceType is set to
2354 // LLVMDisassembler_ReferenceType_Out_Objc_Message.  If this not a method call
2355 // then both ReferenceType and ReferenceName are left unchanged.
2356 static void method_reference(struct DisassembleInfo *info,
2357                              uint64_t *ReferenceType,
2358                              const char **ReferenceName) {
2359   unsigned int Arch = info->O->getArch();
2360   if (*ReferenceName != nullptr) {
2361     if (strcmp(*ReferenceName, "_objc_msgSend") == 0) {
2362       if (info->selector_name != nullptr) {
2363         if (info->method != nullptr)
2364           free(info->method);
2365         if (info->class_name != nullptr) {
2366           info->method = (char *)malloc(5 + strlen(info->class_name) +
2367                                         strlen(info->selector_name));
2368           if (info->method != nullptr) {
2369             strcpy(info->method, "+[");
2370             strcat(info->method, info->class_name);
2371             strcat(info->method, " ");
2372             strcat(info->method, info->selector_name);
2373             strcat(info->method, "]");
2374             *ReferenceName = info->method;
2375             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2376           }
2377         } else {
2378           info->method = (char *)malloc(9 + strlen(info->selector_name));
2379           if (info->method != nullptr) {
2380             if (Arch == Triple::x86_64)
2381               strcpy(info->method, "-[%rdi ");
2382             else if (Arch == Triple::aarch64)
2383               strcpy(info->method, "-[x0 ");
2384             else
2385               strcpy(info->method, "-[r? ");
2386             strcat(info->method, info->selector_name);
2387             strcat(info->method, "]");
2388             *ReferenceName = info->method;
2389             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2390           }
2391         }
2392         info->class_name = nullptr;
2393       }
2394     } else if (strcmp(*ReferenceName, "_objc_msgSendSuper2") == 0) {
2395       if (info->selector_name != nullptr) {
2396         if (info->method != nullptr)
2397           free(info->method);
2398         info->method = (char *)malloc(17 + strlen(info->selector_name));
2399         if (info->method != nullptr) {
2400           if (Arch == Triple::x86_64)
2401             strcpy(info->method, "-[[%rdi super] ");
2402           else if (Arch == Triple::aarch64)
2403             strcpy(info->method, "-[[x0 super] ");
2404           else
2405             strcpy(info->method, "-[[r? super] ");
2406           strcat(info->method, info->selector_name);
2407           strcat(info->method, "]");
2408           *ReferenceName = info->method;
2409           *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2410         }
2411         info->class_name = nullptr;
2412       }
2413     }
2414   }
2415 }
2416 
2417 // GuessPointerPointer() is passed the address of what might be a pointer to
2418 // a reference to an Objective-C class, selector, message ref or cfstring.
2419 // If so the value of the pointer is returned and one of the booleans are set
2420 // to true.  If not zero is returned and all the booleans are set to false.
2421 static uint64_t GuessPointerPointer(uint64_t ReferenceValue,
2422                                     struct DisassembleInfo *info,
2423                                     bool &classref, bool &selref, bool &msgref,
2424                                     bool &cfstring) {
2425   classref = false;
2426   selref = false;
2427   msgref = false;
2428   cfstring = false;
2429   for (const auto &Load : info->O->load_commands()) {
2430     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2431       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2432       for (unsigned J = 0; J < Seg.nsects; ++J) {
2433         MachO::section_64 Sec = info->O->getSection64(Load, J);
2434         if ((strncmp(Sec.sectname, "__objc_selrefs", 16) == 0 ||
2435              strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
2436              strncmp(Sec.sectname, "__objc_superrefs", 16) == 0 ||
2437              strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 ||
2438              strncmp(Sec.sectname, "__cfstring", 16) == 0) &&
2439             ReferenceValue >= Sec.addr &&
2440             ReferenceValue < Sec.addr + Sec.size) {
2441           uint64_t sect_offset = ReferenceValue - Sec.addr;
2442           uint64_t object_offset = Sec.offset + sect_offset;
2443           StringRef MachOContents = info->O->getData();
2444           uint64_t object_size = MachOContents.size();
2445           const char *object_addr = (const char *)MachOContents.data();
2446           if (object_offset < object_size) {
2447             uint64_t pointer_value;
2448             memcpy(&pointer_value, object_addr + object_offset,
2449                    sizeof(uint64_t));
2450             if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2451               sys::swapByteOrder(pointer_value);
2452             if (strncmp(Sec.sectname, "__objc_selrefs", 16) == 0)
2453               selref = true;
2454             else if (strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
2455                      strncmp(Sec.sectname, "__objc_superrefs", 16) == 0)
2456               classref = true;
2457             else if (strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 &&
2458                      ReferenceValue + 8 < Sec.addr + Sec.size) {
2459               msgref = true;
2460               memcpy(&pointer_value, object_addr + object_offset + 8,
2461                      sizeof(uint64_t));
2462               if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2463                 sys::swapByteOrder(pointer_value);
2464             } else if (strncmp(Sec.sectname, "__cfstring", 16) == 0)
2465               cfstring = true;
2466             return pointer_value;
2467           } else {
2468             return 0;
2469           }
2470         }
2471       }
2472     }
2473     // TODO: Look for LC_SEGMENT for 32-bit Mach-O files.
2474   }
2475   return 0;
2476 }
2477 
2478 // get_pointer_64 returns a pointer to the bytes in the object file at the
2479 // Address from a section in the Mach-O file.  And indirectly returns the
2480 // offset into the section, number of bytes left in the section past the offset
2481 // and which section is was being referenced.  If the Address is not in a
2482 // section nullptr is returned.
2483 static const char *get_pointer_64(uint64_t Address, uint32_t &offset,
2484                                   uint32_t &left, SectionRef &S,
2485                                   DisassembleInfo *info,
2486                                   bool objc_only = false) {
2487   offset = 0;
2488   left = 0;
2489   S = SectionRef();
2490   for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) {
2491     uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress();
2492     uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize();
2493     if (SectSize == 0)
2494       continue;
2495     if (objc_only) {
2496       StringRef SectName;
2497       ((*(info->Sections))[SectIdx]).getName(SectName);
2498       DataRefImpl Ref = ((*(info->Sections))[SectIdx]).getRawDataRefImpl();
2499       StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
2500       if (SegName != "__OBJC" && SectName != "__cstring")
2501         continue;
2502     }
2503     if (Address >= SectAddress && Address < SectAddress + SectSize) {
2504       S = (*(info->Sections))[SectIdx];
2505       offset = Address - SectAddress;
2506       left = SectSize - offset;
2507       StringRef SectContents;
2508       ((*(info->Sections))[SectIdx]).getContents(SectContents);
2509       return SectContents.data() + offset;
2510     }
2511   }
2512   return nullptr;
2513 }
2514 
2515 static const char *get_pointer_32(uint32_t Address, uint32_t &offset,
2516                                   uint32_t &left, SectionRef &S,
2517                                   DisassembleInfo *info,
2518                                   bool objc_only = false) {
2519   return get_pointer_64(Address, offset, left, S, info, objc_only);
2520 }
2521 
2522 // get_symbol_64() returns the name of a symbol (or nullptr) and the address of
2523 // the symbol indirectly through n_value. Based on the relocation information
2524 // for the specified section offset in the specified section reference.
2525 // If no relocation information is found and a non-zero ReferenceValue for the
2526 // symbol is passed, look up that address in the info's AddrMap.
2527 static const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
2528                                  DisassembleInfo *info, uint64_t &n_value,
2529                                  uint64_t ReferenceValue = 0) {
2530   n_value = 0;
2531   if (!info->verbose)
2532     return nullptr;
2533 
2534   // See if there is an external relocation entry at the sect_offset.
2535   bool reloc_found = false;
2536   DataRefImpl Rel;
2537   MachO::any_relocation_info RE;
2538   bool isExtern = false;
2539   SymbolRef Symbol;
2540   for (const RelocationRef &Reloc : S.relocations()) {
2541     uint64_t RelocOffset = Reloc.getOffset();
2542     if (RelocOffset == sect_offset) {
2543       Rel = Reloc.getRawDataRefImpl();
2544       RE = info->O->getRelocation(Rel);
2545       if (info->O->isRelocationScattered(RE))
2546         continue;
2547       isExtern = info->O->getPlainRelocationExternal(RE);
2548       if (isExtern) {
2549         symbol_iterator RelocSym = Reloc.getSymbol();
2550         Symbol = *RelocSym;
2551       }
2552       reloc_found = true;
2553       break;
2554     }
2555   }
2556   // If there is an external relocation entry for a symbol in this section
2557   // at this section_offset then use that symbol's value for the n_value
2558   // and return its name.
2559   const char *SymbolName = nullptr;
2560   if (reloc_found && isExtern) {
2561     n_value = Symbol.getValue();
2562     Expected<StringRef> NameOrError = Symbol.getName();
2563     if (!NameOrError)
2564       report_error(info->O->getFileName(), NameOrError.takeError());
2565     StringRef Name = *NameOrError;
2566     if (!Name.empty()) {
2567       SymbolName = Name.data();
2568       return SymbolName;
2569     }
2570   }
2571 
2572   // TODO: For fully linked images, look through the external relocation
2573   // entries off the dynamic symtab command. For these the r_offset is from the
2574   // start of the first writeable segment in the Mach-O file.  So the offset
2575   // to this section from that segment is passed to this routine by the caller,
2576   // as the database_offset. Which is the difference of the section's starting
2577   // address and the first writable segment.
2578   //
2579   // NOTE: need add passing the database_offset to this routine.
2580 
2581   // We did not find an external relocation entry so look up the ReferenceValue
2582   // as an address of a symbol and if found return that symbol's name.
2583   SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
2584 
2585   return SymbolName;
2586 }
2587 
2588 static const char *get_symbol_32(uint32_t sect_offset, SectionRef S,
2589                                  DisassembleInfo *info,
2590                                  uint32_t ReferenceValue) {
2591   uint64_t n_value64;
2592   return get_symbol_64(sect_offset, S, info, n_value64, ReferenceValue);
2593 }
2594 
2595 // These are structs in the Objective-C meta data and read to produce the
2596 // comments for disassembly.  While these are part of the ABI they are no
2597 // public defintions.  So the are here not in include/llvm/BinaryFormat/MachO.h
2598 // .
2599 
2600 // The cfstring object in a 64-bit Mach-O file.
2601 struct cfstring64_t {
2602   uint64_t isa;        // class64_t * (64-bit pointer)
2603   uint64_t flags;      // flag bits
2604   uint64_t characters; // char * (64-bit pointer)
2605   uint64_t length;     // number of non-NULL characters in above
2606 };
2607 
2608 // The class object in a 64-bit Mach-O file.
2609 struct class64_t {
2610   uint64_t isa;        // class64_t * (64-bit pointer)
2611   uint64_t superclass; // class64_t * (64-bit pointer)
2612   uint64_t cache;      // Cache (64-bit pointer)
2613   uint64_t vtable;     // IMP * (64-bit pointer)
2614   uint64_t data;       // class_ro64_t * (64-bit pointer)
2615 };
2616 
2617 struct class32_t {
2618   uint32_t isa;        /* class32_t * (32-bit pointer) */
2619   uint32_t superclass; /* class32_t * (32-bit pointer) */
2620   uint32_t cache;      /* Cache (32-bit pointer) */
2621   uint32_t vtable;     /* IMP * (32-bit pointer) */
2622   uint32_t data;       /* class_ro32_t * (32-bit pointer) */
2623 };
2624 
2625 struct class_ro64_t {
2626   uint32_t flags;
2627   uint32_t instanceStart;
2628   uint32_t instanceSize;
2629   uint32_t reserved;
2630   uint64_t ivarLayout;     // const uint8_t * (64-bit pointer)
2631   uint64_t name;           // const char * (64-bit pointer)
2632   uint64_t baseMethods;    // const method_list_t * (64-bit pointer)
2633   uint64_t baseProtocols;  // const protocol_list_t * (64-bit pointer)
2634   uint64_t ivars;          // const ivar_list_t * (64-bit pointer)
2635   uint64_t weakIvarLayout; // const uint8_t * (64-bit pointer)
2636   uint64_t baseProperties; // const struct objc_property_list (64-bit pointer)
2637 };
2638 
2639 struct class_ro32_t {
2640   uint32_t flags;
2641   uint32_t instanceStart;
2642   uint32_t instanceSize;
2643   uint32_t ivarLayout;     /* const uint8_t * (32-bit pointer) */
2644   uint32_t name;           /* const char * (32-bit pointer) */
2645   uint32_t baseMethods;    /* const method_list_t * (32-bit pointer) */
2646   uint32_t baseProtocols;  /* const protocol_list_t * (32-bit pointer) */
2647   uint32_t ivars;          /* const ivar_list_t * (32-bit pointer) */
2648   uint32_t weakIvarLayout; /* const uint8_t * (32-bit pointer) */
2649   uint32_t baseProperties; /* const struct objc_property_list *
2650                                                    (32-bit pointer) */
2651 };
2652 
2653 /* Values for class_ro{64,32}_t->flags */
2654 #define RO_META (1 << 0)
2655 #define RO_ROOT (1 << 1)
2656 #define RO_HAS_CXX_STRUCTORS (1 << 2)
2657 
2658 struct method_list64_t {
2659   uint32_t entsize;
2660   uint32_t count;
2661   /* struct method64_t first;  These structures follow inline */
2662 };
2663 
2664 struct method_list32_t {
2665   uint32_t entsize;
2666   uint32_t count;
2667   /* struct method32_t first;  These structures follow inline */
2668 };
2669 
2670 struct method64_t {
2671   uint64_t name;  /* SEL (64-bit pointer) */
2672   uint64_t types; /* const char * (64-bit pointer) */
2673   uint64_t imp;   /* IMP (64-bit pointer) */
2674 };
2675 
2676 struct method32_t {
2677   uint32_t name;  /* SEL (32-bit pointer) */
2678   uint32_t types; /* const char * (32-bit pointer) */
2679   uint32_t imp;   /* IMP (32-bit pointer) */
2680 };
2681 
2682 struct protocol_list64_t {
2683   uint64_t count; /* uintptr_t (a 64-bit value) */
2684   /* struct protocol64_t * list[0];  These pointers follow inline */
2685 };
2686 
2687 struct protocol_list32_t {
2688   uint32_t count; /* uintptr_t (a 32-bit value) */
2689   /* struct protocol32_t * list[0];  These pointers follow inline */
2690 };
2691 
2692 struct protocol64_t {
2693   uint64_t isa;                     /* id * (64-bit pointer) */
2694   uint64_t name;                    /* const char * (64-bit pointer) */
2695   uint64_t protocols;               /* struct protocol_list64_t *
2696                                                     (64-bit pointer) */
2697   uint64_t instanceMethods;         /* method_list_t * (64-bit pointer) */
2698   uint64_t classMethods;            /* method_list_t * (64-bit pointer) */
2699   uint64_t optionalInstanceMethods; /* method_list_t * (64-bit pointer) */
2700   uint64_t optionalClassMethods;    /* method_list_t * (64-bit pointer) */
2701   uint64_t instanceProperties;      /* struct objc_property_list *
2702                                                        (64-bit pointer) */
2703 };
2704 
2705 struct protocol32_t {
2706   uint32_t isa;                     /* id * (32-bit pointer) */
2707   uint32_t name;                    /* const char * (32-bit pointer) */
2708   uint32_t protocols;               /* struct protocol_list_t *
2709                                                     (32-bit pointer) */
2710   uint32_t instanceMethods;         /* method_list_t * (32-bit pointer) */
2711   uint32_t classMethods;            /* method_list_t * (32-bit pointer) */
2712   uint32_t optionalInstanceMethods; /* method_list_t * (32-bit pointer) */
2713   uint32_t optionalClassMethods;    /* method_list_t * (32-bit pointer) */
2714   uint32_t instanceProperties;      /* struct objc_property_list *
2715                                                        (32-bit pointer) */
2716 };
2717 
2718 struct ivar_list64_t {
2719   uint32_t entsize;
2720   uint32_t count;
2721   /* struct ivar64_t first;  These structures follow inline */
2722 };
2723 
2724 struct ivar_list32_t {
2725   uint32_t entsize;
2726   uint32_t count;
2727   /* struct ivar32_t first;  These structures follow inline */
2728 };
2729 
2730 struct ivar64_t {
2731   uint64_t offset; /* uintptr_t * (64-bit pointer) */
2732   uint64_t name;   /* const char * (64-bit pointer) */
2733   uint64_t type;   /* const char * (64-bit pointer) */
2734   uint32_t alignment;
2735   uint32_t size;
2736 };
2737 
2738 struct ivar32_t {
2739   uint32_t offset; /* uintptr_t * (32-bit pointer) */
2740   uint32_t name;   /* const char * (32-bit pointer) */
2741   uint32_t type;   /* const char * (32-bit pointer) */
2742   uint32_t alignment;
2743   uint32_t size;
2744 };
2745 
2746 struct objc_property_list64 {
2747   uint32_t entsize;
2748   uint32_t count;
2749   /* struct objc_property64 first;  These structures follow inline */
2750 };
2751 
2752 struct objc_property_list32 {
2753   uint32_t entsize;
2754   uint32_t count;
2755   /* struct objc_property32 first;  These structures follow inline */
2756 };
2757 
2758 struct objc_property64 {
2759   uint64_t name;       /* const char * (64-bit pointer) */
2760   uint64_t attributes; /* const char * (64-bit pointer) */
2761 };
2762 
2763 struct objc_property32 {
2764   uint32_t name;       /* const char * (32-bit pointer) */
2765   uint32_t attributes; /* const char * (32-bit pointer) */
2766 };
2767 
2768 struct category64_t {
2769   uint64_t name;               /* const char * (64-bit pointer) */
2770   uint64_t cls;                /* struct class_t * (64-bit pointer) */
2771   uint64_t instanceMethods;    /* struct method_list_t * (64-bit pointer) */
2772   uint64_t classMethods;       /* struct method_list_t * (64-bit pointer) */
2773   uint64_t protocols;          /* struct protocol_list_t * (64-bit pointer) */
2774   uint64_t instanceProperties; /* struct objc_property_list *
2775                                   (64-bit pointer) */
2776 };
2777 
2778 struct category32_t {
2779   uint32_t name;               /* const char * (32-bit pointer) */
2780   uint32_t cls;                /* struct class_t * (32-bit pointer) */
2781   uint32_t instanceMethods;    /* struct method_list_t * (32-bit pointer) */
2782   uint32_t classMethods;       /* struct method_list_t * (32-bit pointer) */
2783   uint32_t protocols;          /* struct protocol_list_t * (32-bit pointer) */
2784   uint32_t instanceProperties; /* struct objc_property_list *
2785                                   (32-bit pointer) */
2786 };
2787 
2788 struct objc_image_info64 {
2789   uint32_t version;
2790   uint32_t flags;
2791 };
2792 struct objc_image_info32 {
2793   uint32_t version;
2794   uint32_t flags;
2795 };
2796 struct imageInfo_t {
2797   uint32_t version;
2798   uint32_t flags;
2799 };
2800 /* masks for objc_image_info.flags */
2801 #define OBJC_IMAGE_IS_REPLACEMENT (1 << 0)
2802 #define OBJC_IMAGE_SUPPORTS_GC (1 << 1)
2803 
2804 struct message_ref64 {
2805   uint64_t imp; /* IMP (64-bit pointer) */
2806   uint64_t sel; /* SEL (64-bit pointer) */
2807 };
2808 
2809 struct message_ref32 {
2810   uint32_t imp; /* IMP (32-bit pointer) */
2811   uint32_t sel; /* SEL (32-bit pointer) */
2812 };
2813 
2814 // Objective-C 1 (32-bit only) meta data structs.
2815 
2816 struct objc_module_t {
2817   uint32_t version;
2818   uint32_t size;
2819   uint32_t name;   /* char * (32-bit pointer) */
2820   uint32_t symtab; /* struct objc_symtab * (32-bit pointer) */
2821 };
2822 
2823 struct objc_symtab_t {
2824   uint32_t sel_ref_cnt;
2825   uint32_t refs; /* SEL * (32-bit pointer) */
2826   uint16_t cls_def_cnt;
2827   uint16_t cat_def_cnt;
2828   // uint32_t defs[1];        /* void * (32-bit pointer) variable size */
2829 };
2830 
2831 struct objc_class_t {
2832   uint32_t isa;         /* struct objc_class * (32-bit pointer) */
2833   uint32_t super_class; /* struct objc_class * (32-bit pointer) */
2834   uint32_t name;        /* const char * (32-bit pointer) */
2835   int32_t version;
2836   int32_t info;
2837   int32_t instance_size;
2838   uint32_t ivars;       /* struct objc_ivar_list * (32-bit pointer) */
2839   uint32_t methodLists; /* struct objc_method_list ** (32-bit pointer) */
2840   uint32_t cache;       /* struct objc_cache * (32-bit pointer) */
2841   uint32_t protocols;   /* struct objc_protocol_list * (32-bit pointer) */
2842 };
2843 
2844 #define CLS_GETINFO(cls, infomask) ((cls)->info & (infomask))
2845 // class is not a metaclass
2846 #define CLS_CLASS 0x1
2847 // class is a metaclass
2848 #define CLS_META 0x2
2849 
2850 struct objc_category_t {
2851   uint32_t category_name;    /* char * (32-bit pointer) */
2852   uint32_t class_name;       /* char * (32-bit pointer) */
2853   uint32_t instance_methods; /* struct objc_method_list * (32-bit pointer) */
2854   uint32_t class_methods;    /* struct objc_method_list * (32-bit pointer) */
2855   uint32_t protocols;        /* struct objc_protocol_list * (32-bit ptr) */
2856 };
2857 
2858 struct objc_ivar_t {
2859   uint32_t ivar_name; /* char * (32-bit pointer) */
2860   uint32_t ivar_type; /* char * (32-bit pointer) */
2861   int32_t ivar_offset;
2862 };
2863 
2864 struct objc_ivar_list_t {
2865   int32_t ivar_count;
2866   // struct objc_ivar_t ivar_list[1];          /* variable length structure */
2867 };
2868 
2869 struct objc_method_list_t {
2870   uint32_t obsolete; /* struct objc_method_list * (32-bit pointer) */
2871   int32_t method_count;
2872   // struct objc_method_t method_list[1];      /* variable length structure */
2873 };
2874 
2875 struct objc_method_t {
2876   uint32_t method_name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
2877   uint32_t method_types; /* char * (32-bit pointer) */
2878   uint32_t method_imp;   /* IMP, aka function pointer, (*IMP)(id, SEL, ...)
2879                             (32-bit pointer) */
2880 };
2881 
2882 struct objc_protocol_list_t {
2883   uint32_t next; /* struct objc_protocol_list * (32-bit pointer) */
2884   int32_t count;
2885   // uint32_t list[1];   /* Protocol *, aka struct objc_protocol_t *
2886   //                        (32-bit pointer) */
2887 };
2888 
2889 struct objc_protocol_t {
2890   uint32_t isa;              /* struct objc_class * (32-bit pointer) */
2891   uint32_t protocol_name;    /* char * (32-bit pointer) */
2892   uint32_t protocol_list;    /* struct objc_protocol_list * (32-bit pointer) */
2893   uint32_t instance_methods; /* struct objc_method_description_list *
2894                                 (32-bit pointer) */
2895   uint32_t class_methods;    /* struct objc_method_description_list *
2896                                 (32-bit pointer) */
2897 };
2898 
2899 struct objc_method_description_list_t {
2900   int32_t count;
2901   // struct objc_method_description_t list[1];
2902 };
2903 
2904 struct objc_method_description_t {
2905   uint32_t name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
2906   uint32_t types; /* char * (32-bit pointer) */
2907 };
2908 
2909 inline void swapStruct(struct cfstring64_t &cfs) {
2910   sys::swapByteOrder(cfs.isa);
2911   sys::swapByteOrder(cfs.flags);
2912   sys::swapByteOrder(cfs.characters);
2913   sys::swapByteOrder(cfs.length);
2914 }
2915 
2916 inline void swapStruct(struct class64_t &c) {
2917   sys::swapByteOrder(c.isa);
2918   sys::swapByteOrder(c.superclass);
2919   sys::swapByteOrder(c.cache);
2920   sys::swapByteOrder(c.vtable);
2921   sys::swapByteOrder(c.data);
2922 }
2923 
2924 inline void swapStruct(struct class32_t &c) {
2925   sys::swapByteOrder(c.isa);
2926   sys::swapByteOrder(c.superclass);
2927   sys::swapByteOrder(c.cache);
2928   sys::swapByteOrder(c.vtable);
2929   sys::swapByteOrder(c.data);
2930 }
2931 
2932 inline void swapStruct(struct class_ro64_t &cro) {
2933   sys::swapByteOrder(cro.flags);
2934   sys::swapByteOrder(cro.instanceStart);
2935   sys::swapByteOrder(cro.instanceSize);
2936   sys::swapByteOrder(cro.reserved);
2937   sys::swapByteOrder(cro.ivarLayout);
2938   sys::swapByteOrder(cro.name);
2939   sys::swapByteOrder(cro.baseMethods);
2940   sys::swapByteOrder(cro.baseProtocols);
2941   sys::swapByteOrder(cro.ivars);
2942   sys::swapByteOrder(cro.weakIvarLayout);
2943   sys::swapByteOrder(cro.baseProperties);
2944 }
2945 
2946 inline void swapStruct(struct class_ro32_t &cro) {
2947   sys::swapByteOrder(cro.flags);
2948   sys::swapByteOrder(cro.instanceStart);
2949   sys::swapByteOrder(cro.instanceSize);
2950   sys::swapByteOrder(cro.ivarLayout);
2951   sys::swapByteOrder(cro.name);
2952   sys::swapByteOrder(cro.baseMethods);
2953   sys::swapByteOrder(cro.baseProtocols);
2954   sys::swapByteOrder(cro.ivars);
2955   sys::swapByteOrder(cro.weakIvarLayout);
2956   sys::swapByteOrder(cro.baseProperties);
2957 }
2958 
2959 inline void swapStruct(struct method_list64_t &ml) {
2960   sys::swapByteOrder(ml.entsize);
2961   sys::swapByteOrder(ml.count);
2962 }
2963 
2964 inline void swapStruct(struct method_list32_t &ml) {
2965   sys::swapByteOrder(ml.entsize);
2966   sys::swapByteOrder(ml.count);
2967 }
2968 
2969 inline void swapStruct(struct method64_t &m) {
2970   sys::swapByteOrder(m.name);
2971   sys::swapByteOrder(m.types);
2972   sys::swapByteOrder(m.imp);
2973 }
2974 
2975 inline void swapStruct(struct method32_t &m) {
2976   sys::swapByteOrder(m.name);
2977   sys::swapByteOrder(m.types);
2978   sys::swapByteOrder(m.imp);
2979 }
2980 
2981 inline void swapStruct(struct protocol_list64_t &pl) {
2982   sys::swapByteOrder(pl.count);
2983 }
2984 
2985 inline void swapStruct(struct protocol_list32_t &pl) {
2986   sys::swapByteOrder(pl.count);
2987 }
2988 
2989 inline void swapStruct(struct protocol64_t &p) {
2990   sys::swapByteOrder(p.isa);
2991   sys::swapByteOrder(p.name);
2992   sys::swapByteOrder(p.protocols);
2993   sys::swapByteOrder(p.instanceMethods);
2994   sys::swapByteOrder(p.classMethods);
2995   sys::swapByteOrder(p.optionalInstanceMethods);
2996   sys::swapByteOrder(p.optionalClassMethods);
2997   sys::swapByteOrder(p.instanceProperties);
2998 }
2999 
3000 inline void swapStruct(struct protocol32_t &p) {
3001   sys::swapByteOrder(p.isa);
3002   sys::swapByteOrder(p.name);
3003   sys::swapByteOrder(p.protocols);
3004   sys::swapByteOrder(p.instanceMethods);
3005   sys::swapByteOrder(p.classMethods);
3006   sys::swapByteOrder(p.optionalInstanceMethods);
3007   sys::swapByteOrder(p.optionalClassMethods);
3008   sys::swapByteOrder(p.instanceProperties);
3009 }
3010 
3011 inline void swapStruct(struct ivar_list64_t &il) {
3012   sys::swapByteOrder(il.entsize);
3013   sys::swapByteOrder(il.count);
3014 }
3015 
3016 inline void swapStruct(struct ivar_list32_t &il) {
3017   sys::swapByteOrder(il.entsize);
3018   sys::swapByteOrder(il.count);
3019 }
3020 
3021 inline void swapStruct(struct ivar64_t &i) {
3022   sys::swapByteOrder(i.offset);
3023   sys::swapByteOrder(i.name);
3024   sys::swapByteOrder(i.type);
3025   sys::swapByteOrder(i.alignment);
3026   sys::swapByteOrder(i.size);
3027 }
3028 
3029 inline void swapStruct(struct ivar32_t &i) {
3030   sys::swapByteOrder(i.offset);
3031   sys::swapByteOrder(i.name);
3032   sys::swapByteOrder(i.type);
3033   sys::swapByteOrder(i.alignment);
3034   sys::swapByteOrder(i.size);
3035 }
3036 
3037 inline void swapStruct(struct objc_property_list64 &pl) {
3038   sys::swapByteOrder(pl.entsize);
3039   sys::swapByteOrder(pl.count);
3040 }
3041 
3042 inline void swapStruct(struct objc_property_list32 &pl) {
3043   sys::swapByteOrder(pl.entsize);
3044   sys::swapByteOrder(pl.count);
3045 }
3046 
3047 inline void swapStruct(struct objc_property64 &op) {
3048   sys::swapByteOrder(op.name);
3049   sys::swapByteOrder(op.attributes);
3050 }
3051 
3052 inline void swapStruct(struct objc_property32 &op) {
3053   sys::swapByteOrder(op.name);
3054   sys::swapByteOrder(op.attributes);
3055 }
3056 
3057 inline void swapStruct(struct category64_t &c) {
3058   sys::swapByteOrder(c.name);
3059   sys::swapByteOrder(c.cls);
3060   sys::swapByteOrder(c.instanceMethods);
3061   sys::swapByteOrder(c.classMethods);
3062   sys::swapByteOrder(c.protocols);
3063   sys::swapByteOrder(c.instanceProperties);
3064 }
3065 
3066 inline void swapStruct(struct category32_t &c) {
3067   sys::swapByteOrder(c.name);
3068   sys::swapByteOrder(c.cls);
3069   sys::swapByteOrder(c.instanceMethods);
3070   sys::swapByteOrder(c.classMethods);
3071   sys::swapByteOrder(c.protocols);
3072   sys::swapByteOrder(c.instanceProperties);
3073 }
3074 
3075 inline void swapStruct(struct objc_image_info64 &o) {
3076   sys::swapByteOrder(o.version);
3077   sys::swapByteOrder(o.flags);
3078 }
3079 
3080 inline void swapStruct(struct objc_image_info32 &o) {
3081   sys::swapByteOrder(o.version);
3082   sys::swapByteOrder(o.flags);
3083 }
3084 
3085 inline void swapStruct(struct imageInfo_t &o) {
3086   sys::swapByteOrder(o.version);
3087   sys::swapByteOrder(o.flags);
3088 }
3089 
3090 inline void swapStruct(struct message_ref64 &mr) {
3091   sys::swapByteOrder(mr.imp);
3092   sys::swapByteOrder(mr.sel);
3093 }
3094 
3095 inline void swapStruct(struct message_ref32 &mr) {
3096   sys::swapByteOrder(mr.imp);
3097   sys::swapByteOrder(mr.sel);
3098 }
3099 
3100 inline void swapStruct(struct objc_module_t &module) {
3101   sys::swapByteOrder(module.version);
3102   sys::swapByteOrder(module.size);
3103   sys::swapByteOrder(module.name);
3104   sys::swapByteOrder(module.symtab);
3105 }
3106 
3107 inline void swapStruct(struct objc_symtab_t &symtab) {
3108   sys::swapByteOrder(symtab.sel_ref_cnt);
3109   sys::swapByteOrder(symtab.refs);
3110   sys::swapByteOrder(symtab.cls_def_cnt);
3111   sys::swapByteOrder(symtab.cat_def_cnt);
3112 }
3113 
3114 inline void swapStruct(struct objc_class_t &objc_class) {
3115   sys::swapByteOrder(objc_class.isa);
3116   sys::swapByteOrder(objc_class.super_class);
3117   sys::swapByteOrder(objc_class.name);
3118   sys::swapByteOrder(objc_class.version);
3119   sys::swapByteOrder(objc_class.info);
3120   sys::swapByteOrder(objc_class.instance_size);
3121   sys::swapByteOrder(objc_class.ivars);
3122   sys::swapByteOrder(objc_class.methodLists);
3123   sys::swapByteOrder(objc_class.cache);
3124   sys::swapByteOrder(objc_class.protocols);
3125 }
3126 
3127 inline void swapStruct(struct objc_category_t &objc_category) {
3128   sys::swapByteOrder(objc_category.category_name);
3129   sys::swapByteOrder(objc_category.class_name);
3130   sys::swapByteOrder(objc_category.instance_methods);
3131   sys::swapByteOrder(objc_category.class_methods);
3132   sys::swapByteOrder(objc_category.protocols);
3133 }
3134 
3135 inline void swapStruct(struct objc_ivar_list_t &objc_ivar_list) {
3136   sys::swapByteOrder(objc_ivar_list.ivar_count);
3137 }
3138 
3139 inline void swapStruct(struct objc_ivar_t &objc_ivar) {
3140   sys::swapByteOrder(objc_ivar.ivar_name);
3141   sys::swapByteOrder(objc_ivar.ivar_type);
3142   sys::swapByteOrder(objc_ivar.ivar_offset);
3143 }
3144 
3145 inline void swapStruct(struct objc_method_list_t &method_list) {
3146   sys::swapByteOrder(method_list.obsolete);
3147   sys::swapByteOrder(method_list.method_count);
3148 }
3149 
3150 inline void swapStruct(struct objc_method_t &method) {
3151   sys::swapByteOrder(method.method_name);
3152   sys::swapByteOrder(method.method_types);
3153   sys::swapByteOrder(method.method_imp);
3154 }
3155 
3156 inline void swapStruct(struct objc_protocol_list_t &protocol_list) {
3157   sys::swapByteOrder(protocol_list.next);
3158   sys::swapByteOrder(protocol_list.count);
3159 }
3160 
3161 inline void swapStruct(struct objc_protocol_t &protocol) {
3162   sys::swapByteOrder(protocol.isa);
3163   sys::swapByteOrder(protocol.protocol_name);
3164   sys::swapByteOrder(protocol.protocol_list);
3165   sys::swapByteOrder(protocol.instance_methods);
3166   sys::swapByteOrder(protocol.class_methods);
3167 }
3168 
3169 inline void swapStruct(struct objc_method_description_list_t &mdl) {
3170   sys::swapByteOrder(mdl.count);
3171 }
3172 
3173 inline void swapStruct(struct objc_method_description_t &md) {
3174   sys::swapByteOrder(md.name);
3175   sys::swapByteOrder(md.types);
3176 }
3177 
3178 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
3179                                                  struct DisassembleInfo *info);
3180 
3181 // get_objc2_64bit_class_name() is used for disassembly and is passed a pointer
3182 // to an Objective-C class and returns the class name.  It is also passed the
3183 // address of the pointer, so when the pointer is zero as it can be in an .o
3184 // file, that is used to look for an external relocation entry with a symbol
3185 // name.
3186 static const char *get_objc2_64bit_class_name(uint64_t pointer_value,
3187                                               uint64_t ReferenceValue,
3188                                               struct DisassembleInfo *info) {
3189   const char *r;
3190   uint32_t offset, left;
3191   SectionRef S;
3192 
3193   // The pointer_value can be 0 in an object file and have a relocation
3194   // entry for the class symbol at the ReferenceValue (the address of the
3195   // pointer).
3196   if (pointer_value == 0) {
3197     r = get_pointer_64(ReferenceValue, offset, left, S, info);
3198     if (r == nullptr || left < sizeof(uint64_t))
3199       return nullptr;
3200     uint64_t n_value;
3201     const char *symbol_name = get_symbol_64(offset, S, info, n_value);
3202     if (symbol_name == nullptr)
3203       return nullptr;
3204     const char *class_name = strrchr(symbol_name, '$');
3205     if (class_name != nullptr && class_name[1] == '_' && class_name[2] != '\0')
3206       return class_name + 2;
3207     else
3208       return nullptr;
3209   }
3210 
3211   // The case were the pointer_value is non-zero and points to a class defined
3212   // in this Mach-O file.
3213   r = get_pointer_64(pointer_value, offset, left, S, info);
3214   if (r == nullptr || left < sizeof(struct class64_t))
3215     return nullptr;
3216   struct class64_t c;
3217   memcpy(&c, r, sizeof(struct class64_t));
3218   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3219     swapStruct(c);
3220   if (c.data == 0)
3221     return nullptr;
3222   r = get_pointer_64(c.data, offset, left, S, info);
3223   if (r == nullptr || left < sizeof(struct class_ro64_t))
3224     return nullptr;
3225   struct class_ro64_t cro;
3226   memcpy(&cro, r, sizeof(struct class_ro64_t));
3227   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3228     swapStruct(cro);
3229   if (cro.name == 0)
3230     return nullptr;
3231   const char *name = get_pointer_64(cro.name, offset, left, S, info);
3232   return name;
3233 }
3234 
3235 // get_objc2_64bit_cfstring_name is used for disassembly and is passed a
3236 // pointer to a cfstring and returns its name or nullptr.
3237 static const char *get_objc2_64bit_cfstring_name(uint64_t ReferenceValue,
3238                                                  struct DisassembleInfo *info) {
3239   const char *r, *name;
3240   uint32_t offset, left;
3241   SectionRef S;
3242   struct cfstring64_t cfs;
3243   uint64_t cfs_characters;
3244 
3245   r = get_pointer_64(ReferenceValue, offset, left, S, info);
3246   if (r == nullptr || left < sizeof(struct cfstring64_t))
3247     return nullptr;
3248   memcpy(&cfs, r, sizeof(struct cfstring64_t));
3249   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3250     swapStruct(cfs);
3251   if (cfs.characters == 0) {
3252     uint64_t n_value;
3253     const char *symbol_name = get_symbol_64(
3254         offset + offsetof(struct cfstring64_t, characters), S, info, n_value);
3255     if (symbol_name == nullptr)
3256       return nullptr;
3257     cfs_characters = n_value;
3258   } else
3259     cfs_characters = cfs.characters;
3260   name = get_pointer_64(cfs_characters, offset, left, S, info);
3261 
3262   return name;
3263 }
3264 
3265 // get_objc2_64bit_selref() is used for disassembly and is passed a the address
3266 // of a pointer to an Objective-C selector reference when the pointer value is
3267 // zero as in a .o file and is likely to have a external relocation entry with
3268 // who's symbol's n_value is the real pointer to the selector name.  If that is
3269 // the case the real pointer to the selector name is returned else 0 is
3270 // returned
3271 static uint64_t get_objc2_64bit_selref(uint64_t ReferenceValue,
3272                                        struct DisassembleInfo *info) {
3273   uint32_t offset, left;
3274   SectionRef S;
3275 
3276   const char *r = get_pointer_64(ReferenceValue, offset, left, S, info);
3277   if (r == nullptr || left < sizeof(uint64_t))
3278     return 0;
3279   uint64_t n_value;
3280   const char *symbol_name = get_symbol_64(offset, S, info, n_value);
3281   if (symbol_name == nullptr)
3282     return 0;
3283   return n_value;
3284 }
3285 
3286 static const SectionRef get_section(MachOObjectFile *O, const char *segname,
3287                                     const char *sectname) {
3288   for (const SectionRef &Section : O->sections()) {
3289     StringRef SectName;
3290     Section.getName(SectName);
3291     DataRefImpl Ref = Section.getRawDataRefImpl();
3292     StringRef SegName = O->getSectionFinalSegmentName(Ref);
3293     if (SegName == segname && SectName == sectname)
3294       return Section;
3295   }
3296   return SectionRef();
3297 }
3298 
3299 static void
3300 walk_pointer_list_64(const char *listname, const SectionRef S,
3301                      MachOObjectFile *O, struct DisassembleInfo *info,
3302                      void (*func)(uint64_t, struct DisassembleInfo *info)) {
3303   if (S == SectionRef())
3304     return;
3305 
3306   StringRef SectName;
3307   S.getName(SectName);
3308   DataRefImpl Ref = S.getRawDataRefImpl();
3309   StringRef SegName = O->getSectionFinalSegmentName(Ref);
3310   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
3311 
3312   StringRef BytesStr;
3313   S.getContents(BytesStr);
3314   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
3315 
3316   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint64_t)) {
3317     uint32_t left = S.getSize() - i;
3318     uint32_t size = left < sizeof(uint64_t) ? left : sizeof(uint64_t);
3319     uint64_t p = 0;
3320     memcpy(&p, Contents + i, size);
3321     if (i + sizeof(uint64_t) > S.getSize())
3322       outs() << listname << " list pointer extends past end of (" << SegName
3323              << "," << SectName << ") section\n";
3324     outs() << format("%016" PRIx64, S.getAddress() + i) << " ";
3325 
3326     if (O->isLittleEndian() != sys::IsLittleEndianHost)
3327       sys::swapByteOrder(p);
3328 
3329     uint64_t n_value = 0;
3330     const char *name = get_symbol_64(i, S, info, n_value, p);
3331     if (name == nullptr)
3332       name = get_dyld_bind_info_symbolname(S.getAddress() + i, info);
3333 
3334     if (n_value != 0) {
3335       outs() << format("0x%" PRIx64, n_value);
3336       if (p != 0)
3337         outs() << " + " << format("0x%" PRIx64, p);
3338     } else
3339       outs() << format("0x%" PRIx64, p);
3340     if (name != nullptr)
3341       outs() << " " << name;
3342     outs() << "\n";
3343 
3344     p += n_value;
3345     if (func)
3346       func(p, info);
3347   }
3348 }
3349 
3350 static void
3351 walk_pointer_list_32(const char *listname, const SectionRef S,
3352                      MachOObjectFile *O, struct DisassembleInfo *info,
3353                      void (*func)(uint32_t, struct DisassembleInfo *info)) {
3354   if (S == SectionRef())
3355     return;
3356 
3357   StringRef SectName;
3358   S.getName(SectName);
3359   DataRefImpl Ref = S.getRawDataRefImpl();
3360   StringRef SegName = O->getSectionFinalSegmentName(Ref);
3361   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
3362 
3363   StringRef BytesStr;
3364   S.getContents(BytesStr);
3365   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
3366 
3367   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint32_t)) {
3368     uint32_t left = S.getSize() - i;
3369     uint32_t size = left < sizeof(uint32_t) ? left : sizeof(uint32_t);
3370     uint32_t p = 0;
3371     memcpy(&p, Contents + i, size);
3372     if (i + sizeof(uint32_t) > S.getSize())
3373       outs() << listname << " list pointer extends past end of (" << SegName
3374              << "," << SectName << ") section\n";
3375     uint32_t Address = S.getAddress() + i;
3376     outs() << format("%08" PRIx32, Address) << " ";
3377 
3378     if (O->isLittleEndian() != sys::IsLittleEndianHost)
3379       sys::swapByteOrder(p);
3380     outs() << format("0x%" PRIx32, p);
3381 
3382     const char *name = get_symbol_32(i, S, info, p);
3383     if (name != nullptr)
3384       outs() << " " << name;
3385     outs() << "\n";
3386 
3387     if (func)
3388       func(p, info);
3389   }
3390 }
3391 
3392 static void print_layout_map(const char *layout_map, uint32_t left) {
3393   if (layout_map == nullptr)
3394     return;
3395   outs() << "                layout map: ";
3396   do {
3397     outs() << format("0x%02" PRIx32, (*layout_map) & 0xff) << " ";
3398     left--;
3399     layout_map++;
3400   } while (*layout_map != '\0' && left != 0);
3401   outs() << "\n";
3402 }
3403 
3404 static void print_layout_map64(uint64_t p, struct DisassembleInfo *info) {
3405   uint32_t offset, left;
3406   SectionRef S;
3407   const char *layout_map;
3408 
3409   if (p == 0)
3410     return;
3411   layout_map = get_pointer_64(p, offset, left, S, info);
3412   print_layout_map(layout_map, left);
3413 }
3414 
3415 static void print_layout_map32(uint32_t p, struct DisassembleInfo *info) {
3416   uint32_t offset, left;
3417   SectionRef S;
3418   const char *layout_map;
3419 
3420   if (p == 0)
3421     return;
3422   layout_map = get_pointer_32(p, offset, left, S, info);
3423   print_layout_map(layout_map, left);
3424 }
3425 
3426 static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
3427                                   const char *indent) {
3428   struct method_list64_t ml;
3429   struct method64_t m;
3430   const char *r;
3431   uint32_t offset, xoffset, left, i;
3432   SectionRef S, xS;
3433   const char *name, *sym_name;
3434   uint64_t n_value;
3435 
3436   r = get_pointer_64(p, offset, left, S, info);
3437   if (r == nullptr)
3438     return;
3439   memset(&ml, '\0', sizeof(struct method_list64_t));
3440   if (left < sizeof(struct method_list64_t)) {
3441     memcpy(&ml, r, left);
3442     outs() << "   (method_list_t entends past the end of the section)\n";
3443   } else
3444     memcpy(&ml, r, sizeof(struct method_list64_t));
3445   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3446     swapStruct(ml);
3447   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
3448   outs() << indent << "\t\t     count " << ml.count << "\n";
3449 
3450   p += sizeof(struct method_list64_t);
3451   offset += sizeof(struct method_list64_t);
3452   for (i = 0; i < ml.count; i++) {
3453     r = get_pointer_64(p, offset, left, S, info);
3454     if (r == nullptr)
3455       return;
3456     memset(&m, '\0', sizeof(struct method64_t));
3457     if (left < sizeof(struct method64_t)) {
3458       memcpy(&m, r, left);
3459       outs() << indent << "   (method_t extends past the end of the section)\n";
3460     } else
3461       memcpy(&m, r, sizeof(struct method64_t));
3462     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3463       swapStruct(m);
3464 
3465     outs() << indent << "\t\t      name ";
3466     sym_name = get_symbol_64(offset + offsetof(struct method64_t, name), S,
3467                              info, n_value, m.name);
3468     if (n_value != 0) {
3469       if (info->verbose && sym_name != nullptr)
3470         outs() << sym_name;
3471       else
3472         outs() << format("0x%" PRIx64, n_value);
3473       if (m.name != 0)
3474         outs() << " + " << format("0x%" PRIx64, m.name);
3475     } else
3476       outs() << format("0x%" PRIx64, m.name);
3477     name = get_pointer_64(m.name + n_value, xoffset, left, xS, info);
3478     if (name != nullptr)
3479       outs() << format(" %.*s", left, name);
3480     outs() << "\n";
3481 
3482     outs() << indent << "\t\t     types ";
3483     sym_name = get_symbol_64(offset + offsetof(struct method64_t, types), S,
3484                              info, n_value, m.types);
3485     if (n_value != 0) {
3486       if (info->verbose && sym_name != nullptr)
3487         outs() << sym_name;
3488       else
3489         outs() << format("0x%" PRIx64, n_value);
3490       if (m.types != 0)
3491         outs() << " + " << format("0x%" PRIx64, m.types);
3492     } else
3493       outs() << format("0x%" PRIx64, m.types);
3494     name = get_pointer_64(m.types + n_value, xoffset, left, xS, info);
3495     if (name != nullptr)
3496       outs() << format(" %.*s", left, name);
3497     outs() << "\n";
3498 
3499     outs() << indent << "\t\t       imp ";
3500     name = get_symbol_64(offset + offsetof(struct method64_t, imp), S, info,
3501                          n_value, m.imp);
3502     if (info->verbose && name == nullptr) {
3503       if (n_value != 0) {
3504         outs() << format("0x%" PRIx64, n_value) << " ";
3505         if (m.imp != 0)
3506           outs() << "+ " << format("0x%" PRIx64, m.imp) << " ";
3507       } else
3508         outs() << format("0x%" PRIx64, m.imp) << " ";
3509     }
3510     if (name != nullptr)
3511       outs() << name;
3512     outs() << "\n";
3513 
3514     p += sizeof(struct method64_t);
3515     offset += sizeof(struct method64_t);
3516   }
3517 }
3518 
3519 static void print_method_list32_t(uint64_t p, struct DisassembleInfo *info,
3520                                   const char *indent) {
3521   struct method_list32_t ml;
3522   struct method32_t m;
3523   const char *r, *name;
3524   uint32_t offset, xoffset, left, i;
3525   SectionRef S, xS;
3526 
3527   r = get_pointer_32(p, offset, left, S, info);
3528   if (r == nullptr)
3529     return;
3530   memset(&ml, '\0', sizeof(struct method_list32_t));
3531   if (left < sizeof(struct method_list32_t)) {
3532     memcpy(&ml, r, left);
3533     outs() << "   (method_list_t entends past the end of the section)\n";
3534   } else
3535     memcpy(&ml, r, sizeof(struct method_list32_t));
3536   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3537     swapStruct(ml);
3538   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
3539   outs() << indent << "\t\t     count " << ml.count << "\n";
3540 
3541   p += sizeof(struct method_list32_t);
3542   offset += sizeof(struct method_list32_t);
3543   for (i = 0; i < ml.count; i++) {
3544     r = get_pointer_32(p, offset, left, S, info);
3545     if (r == nullptr)
3546       return;
3547     memset(&m, '\0', sizeof(struct method32_t));
3548     if (left < sizeof(struct method32_t)) {
3549       memcpy(&ml, r, left);
3550       outs() << indent << "   (method_t entends past the end of the section)\n";
3551     } else
3552       memcpy(&m, r, sizeof(struct method32_t));
3553     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3554       swapStruct(m);
3555 
3556     outs() << indent << "\t\t      name " << format("0x%" PRIx32, m.name);
3557     name = get_pointer_32(m.name, xoffset, left, xS, info);
3558     if (name != nullptr)
3559       outs() << format(" %.*s", left, name);
3560     outs() << "\n";
3561 
3562     outs() << indent << "\t\t     types " << format("0x%" PRIx32, m.types);
3563     name = get_pointer_32(m.types, xoffset, left, xS, info);
3564     if (name != nullptr)
3565       outs() << format(" %.*s", left, name);
3566     outs() << "\n";
3567 
3568     outs() << indent << "\t\t       imp " << format("0x%" PRIx32, m.imp);
3569     name = get_symbol_32(offset + offsetof(struct method32_t, imp), S, info,
3570                          m.imp);
3571     if (name != nullptr)
3572       outs() << " " << name;
3573     outs() << "\n";
3574 
3575     p += sizeof(struct method32_t);
3576     offset += sizeof(struct method32_t);
3577   }
3578 }
3579 
3580 static bool print_method_list(uint32_t p, struct DisassembleInfo *info) {
3581   uint32_t offset, left, xleft;
3582   SectionRef S;
3583   struct objc_method_list_t method_list;
3584   struct objc_method_t method;
3585   const char *r, *methods, *name, *SymbolName;
3586   int32_t i;
3587 
3588   r = get_pointer_32(p, offset, left, S, info, true);
3589   if (r == nullptr)
3590     return true;
3591 
3592   outs() << "\n";
3593   if (left > sizeof(struct objc_method_list_t)) {
3594     memcpy(&method_list, r, sizeof(struct objc_method_list_t));
3595   } else {
3596     outs() << "\t\t objc_method_list extends past end of the section\n";
3597     memset(&method_list, '\0', sizeof(struct objc_method_list_t));
3598     memcpy(&method_list, r, left);
3599   }
3600   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3601     swapStruct(method_list);
3602 
3603   outs() << "\t\t         obsolete "
3604          << format("0x%08" PRIx32, method_list.obsolete) << "\n";
3605   outs() << "\t\t     method_count " << method_list.method_count << "\n";
3606 
3607   methods = r + sizeof(struct objc_method_list_t);
3608   for (i = 0; i < method_list.method_count; i++) {
3609     if ((i + 1) * sizeof(struct objc_method_t) > left) {
3610       outs() << "\t\t remaining method's extend past the of the section\n";
3611       break;
3612     }
3613     memcpy(&method, methods + i * sizeof(struct objc_method_t),
3614            sizeof(struct objc_method_t));
3615     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3616       swapStruct(method);
3617 
3618     outs() << "\t\t      method_name "
3619            << format("0x%08" PRIx32, method.method_name);
3620     if (info->verbose) {
3621       name = get_pointer_32(method.method_name, offset, xleft, S, info, true);
3622       if (name != nullptr)
3623         outs() << format(" %.*s", xleft, name);
3624       else
3625         outs() << " (not in an __OBJC section)";
3626     }
3627     outs() << "\n";
3628 
3629     outs() << "\t\t     method_types "
3630            << format("0x%08" PRIx32, method.method_types);
3631     if (info->verbose) {
3632       name = get_pointer_32(method.method_types, offset, xleft, S, info, true);
3633       if (name != nullptr)
3634         outs() << format(" %.*s", xleft, name);
3635       else
3636         outs() << " (not in an __OBJC section)";
3637     }
3638     outs() << "\n";
3639 
3640     outs() << "\t\t       method_imp "
3641            << format("0x%08" PRIx32, method.method_imp) << " ";
3642     if (info->verbose) {
3643       SymbolName = GuessSymbolName(method.method_imp, info->AddrMap);
3644       if (SymbolName != nullptr)
3645         outs() << SymbolName;
3646     }
3647     outs() << "\n";
3648   }
3649   return false;
3650 }
3651 
3652 static void print_protocol_list64_t(uint64_t p, struct DisassembleInfo *info) {
3653   struct protocol_list64_t pl;
3654   uint64_t q, n_value;
3655   struct protocol64_t pc;
3656   const char *r;
3657   uint32_t offset, xoffset, left, i;
3658   SectionRef S, xS;
3659   const char *name, *sym_name;
3660 
3661   r = get_pointer_64(p, offset, left, S, info);
3662   if (r == nullptr)
3663     return;
3664   memset(&pl, '\0', sizeof(struct protocol_list64_t));
3665   if (left < sizeof(struct protocol_list64_t)) {
3666     memcpy(&pl, r, left);
3667     outs() << "   (protocol_list_t entends past the end of the section)\n";
3668   } else
3669     memcpy(&pl, r, sizeof(struct protocol_list64_t));
3670   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3671     swapStruct(pl);
3672   outs() << "                      count " << pl.count << "\n";
3673 
3674   p += sizeof(struct protocol_list64_t);
3675   offset += sizeof(struct protocol_list64_t);
3676   for (i = 0; i < pl.count; i++) {
3677     r = get_pointer_64(p, offset, left, S, info);
3678     if (r == nullptr)
3679       return;
3680     q = 0;
3681     if (left < sizeof(uint64_t)) {
3682       memcpy(&q, r, left);
3683       outs() << "   (protocol_t * entends past the end of the section)\n";
3684     } else
3685       memcpy(&q, r, sizeof(uint64_t));
3686     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3687       sys::swapByteOrder(q);
3688 
3689     outs() << "\t\t      list[" << i << "] ";
3690     sym_name = get_symbol_64(offset, S, info, n_value, q);
3691     if (n_value != 0) {
3692       if (info->verbose && sym_name != nullptr)
3693         outs() << sym_name;
3694       else
3695         outs() << format("0x%" PRIx64, n_value);
3696       if (q != 0)
3697         outs() << " + " << format("0x%" PRIx64, q);
3698     } else
3699       outs() << format("0x%" PRIx64, q);
3700     outs() << " (struct protocol_t *)\n";
3701 
3702     r = get_pointer_64(q + n_value, offset, left, S, info);
3703     if (r == nullptr)
3704       return;
3705     memset(&pc, '\0', sizeof(struct protocol64_t));
3706     if (left < sizeof(struct protocol64_t)) {
3707       memcpy(&pc, r, left);
3708       outs() << "   (protocol_t entends past the end of the section)\n";
3709     } else
3710       memcpy(&pc, r, sizeof(struct protocol64_t));
3711     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3712       swapStruct(pc);
3713 
3714     outs() << "\t\t\t      isa " << format("0x%" PRIx64, pc.isa) << "\n";
3715 
3716     outs() << "\t\t\t     name ";
3717     sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, name), S,
3718                              info, n_value, pc.name);
3719     if (n_value != 0) {
3720       if (info->verbose && sym_name != nullptr)
3721         outs() << sym_name;
3722       else
3723         outs() << format("0x%" PRIx64, n_value);
3724       if (pc.name != 0)
3725         outs() << " + " << format("0x%" PRIx64, pc.name);
3726     } else
3727       outs() << format("0x%" PRIx64, pc.name);
3728     name = get_pointer_64(pc.name + n_value, xoffset, left, xS, info);
3729     if (name != nullptr)
3730       outs() << format(" %.*s", left, name);
3731     outs() << "\n";
3732 
3733     outs() << "\t\t\tprotocols " << format("0x%" PRIx64, pc.protocols) << "\n";
3734 
3735     outs() << "\t\t  instanceMethods ";
3736     sym_name =
3737         get_symbol_64(offset + offsetof(struct protocol64_t, instanceMethods),
3738                       S, info, n_value, pc.instanceMethods);
3739     if (n_value != 0) {
3740       if (info->verbose && sym_name != nullptr)
3741         outs() << sym_name;
3742       else
3743         outs() << format("0x%" PRIx64, n_value);
3744       if (pc.instanceMethods != 0)
3745         outs() << " + " << format("0x%" PRIx64, pc.instanceMethods);
3746     } else
3747       outs() << format("0x%" PRIx64, pc.instanceMethods);
3748     outs() << " (struct method_list_t *)\n";
3749     if (pc.instanceMethods + n_value != 0)
3750       print_method_list64_t(pc.instanceMethods + n_value, info, "\t");
3751 
3752     outs() << "\t\t     classMethods ";
3753     sym_name =
3754         get_symbol_64(offset + offsetof(struct protocol64_t, classMethods), S,
3755                       info, n_value, pc.classMethods);
3756     if (n_value != 0) {
3757       if (info->verbose && sym_name != nullptr)
3758         outs() << sym_name;
3759       else
3760         outs() << format("0x%" PRIx64, n_value);
3761       if (pc.classMethods != 0)
3762         outs() << " + " << format("0x%" PRIx64, pc.classMethods);
3763     } else
3764       outs() << format("0x%" PRIx64, pc.classMethods);
3765     outs() << " (struct method_list_t *)\n";
3766     if (pc.classMethods + n_value != 0)
3767       print_method_list64_t(pc.classMethods + n_value, info, "\t");
3768 
3769     outs() << "\t  optionalInstanceMethods "
3770            << format("0x%" PRIx64, pc.optionalInstanceMethods) << "\n";
3771     outs() << "\t     optionalClassMethods "
3772            << format("0x%" PRIx64, pc.optionalClassMethods) << "\n";
3773     outs() << "\t       instanceProperties "
3774            << format("0x%" PRIx64, pc.instanceProperties) << "\n";
3775 
3776     p += sizeof(uint64_t);
3777     offset += sizeof(uint64_t);
3778   }
3779 }
3780 
3781 static void print_protocol_list32_t(uint32_t p, struct DisassembleInfo *info) {
3782   struct protocol_list32_t pl;
3783   uint32_t q;
3784   struct protocol32_t pc;
3785   const char *r;
3786   uint32_t offset, xoffset, left, i;
3787   SectionRef S, xS;
3788   const char *name;
3789 
3790   r = get_pointer_32(p, offset, left, S, info);
3791   if (r == nullptr)
3792     return;
3793   memset(&pl, '\0', sizeof(struct protocol_list32_t));
3794   if (left < sizeof(struct protocol_list32_t)) {
3795     memcpy(&pl, r, left);
3796     outs() << "   (protocol_list_t entends past the end of the section)\n";
3797   } else
3798     memcpy(&pl, r, sizeof(struct protocol_list32_t));
3799   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3800     swapStruct(pl);
3801   outs() << "                      count " << pl.count << "\n";
3802 
3803   p += sizeof(struct protocol_list32_t);
3804   offset += sizeof(struct protocol_list32_t);
3805   for (i = 0; i < pl.count; i++) {
3806     r = get_pointer_32(p, offset, left, S, info);
3807     if (r == nullptr)
3808       return;
3809     q = 0;
3810     if (left < sizeof(uint32_t)) {
3811       memcpy(&q, r, left);
3812       outs() << "   (protocol_t * entends past the end of the section)\n";
3813     } else
3814       memcpy(&q, r, sizeof(uint32_t));
3815     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3816       sys::swapByteOrder(q);
3817     outs() << "\t\t      list[" << i << "] " << format("0x%" PRIx32, q)
3818            << " (struct protocol_t *)\n";
3819     r = get_pointer_32(q, offset, left, S, info);
3820     if (r == nullptr)
3821       return;
3822     memset(&pc, '\0', sizeof(struct protocol32_t));
3823     if (left < sizeof(struct protocol32_t)) {
3824       memcpy(&pc, r, left);
3825       outs() << "   (protocol_t entends past the end of the section)\n";
3826     } else
3827       memcpy(&pc, r, sizeof(struct protocol32_t));
3828     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3829       swapStruct(pc);
3830     outs() << "\t\t\t      isa " << format("0x%" PRIx32, pc.isa) << "\n";
3831     outs() << "\t\t\t     name " << format("0x%" PRIx32, pc.name);
3832     name = get_pointer_32(pc.name, xoffset, left, xS, info);
3833     if (name != nullptr)
3834       outs() << format(" %.*s", left, name);
3835     outs() << "\n";
3836     outs() << "\t\t\tprotocols " << format("0x%" PRIx32, pc.protocols) << "\n";
3837     outs() << "\t\t  instanceMethods "
3838            << format("0x%" PRIx32, pc.instanceMethods)
3839            << " (struct method_list_t *)\n";
3840     if (pc.instanceMethods != 0)
3841       print_method_list32_t(pc.instanceMethods, info, "\t");
3842     outs() << "\t\t     classMethods " << format("0x%" PRIx32, pc.classMethods)
3843            << " (struct method_list_t *)\n";
3844     if (pc.classMethods != 0)
3845       print_method_list32_t(pc.classMethods, info, "\t");
3846     outs() << "\t  optionalInstanceMethods "
3847            << format("0x%" PRIx32, pc.optionalInstanceMethods) << "\n";
3848     outs() << "\t     optionalClassMethods "
3849            << format("0x%" PRIx32, pc.optionalClassMethods) << "\n";
3850     outs() << "\t       instanceProperties "
3851            << format("0x%" PRIx32, pc.instanceProperties) << "\n";
3852     p += sizeof(uint32_t);
3853     offset += sizeof(uint32_t);
3854   }
3855 }
3856 
3857 static void print_indent(uint32_t indent) {
3858   for (uint32_t i = 0; i < indent;) {
3859     if (indent - i >= 8) {
3860       outs() << "\t";
3861       i += 8;
3862     } else {
3863       for (uint32_t j = i; j < indent; j++)
3864         outs() << " ";
3865       return;
3866     }
3867   }
3868 }
3869 
3870 static bool print_method_description_list(uint32_t p, uint32_t indent,
3871                                           struct DisassembleInfo *info) {
3872   uint32_t offset, left, xleft;
3873   SectionRef S;
3874   struct objc_method_description_list_t mdl;
3875   struct objc_method_description_t md;
3876   const char *r, *list, *name;
3877   int32_t i;
3878 
3879   r = get_pointer_32(p, offset, left, S, info, true);
3880   if (r == nullptr)
3881     return true;
3882 
3883   outs() << "\n";
3884   if (left > sizeof(struct objc_method_description_list_t)) {
3885     memcpy(&mdl, r, sizeof(struct objc_method_description_list_t));
3886   } else {
3887     print_indent(indent);
3888     outs() << " objc_method_description_list extends past end of the section\n";
3889     memset(&mdl, '\0', sizeof(struct objc_method_description_list_t));
3890     memcpy(&mdl, r, left);
3891   }
3892   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3893     swapStruct(mdl);
3894 
3895   print_indent(indent);
3896   outs() << "        count " << mdl.count << "\n";
3897 
3898   list = r + sizeof(struct objc_method_description_list_t);
3899   for (i = 0; i < mdl.count; i++) {
3900     if ((i + 1) * sizeof(struct objc_method_description_t) > left) {
3901       print_indent(indent);
3902       outs() << " remaining list entries extend past the of the section\n";
3903       break;
3904     }
3905     print_indent(indent);
3906     outs() << "        list[" << i << "]\n";
3907     memcpy(&md, list + i * sizeof(struct objc_method_description_t),
3908            sizeof(struct objc_method_description_t));
3909     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3910       swapStruct(md);
3911 
3912     print_indent(indent);
3913     outs() << "             name " << format("0x%08" PRIx32, md.name);
3914     if (info->verbose) {
3915       name = get_pointer_32(md.name, offset, xleft, S, info, true);
3916       if (name != nullptr)
3917         outs() << format(" %.*s", xleft, name);
3918       else
3919         outs() << " (not in an __OBJC section)";
3920     }
3921     outs() << "\n";
3922 
3923     print_indent(indent);
3924     outs() << "            types " << format("0x%08" PRIx32, md.types);
3925     if (info->verbose) {
3926       name = get_pointer_32(md.types, offset, xleft, S, info, true);
3927       if (name != nullptr)
3928         outs() << format(" %.*s", xleft, name);
3929       else
3930         outs() << " (not in an __OBJC section)";
3931     }
3932     outs() << "\n";
3933   }
3934   return false;
3935 }
3936 
3937 static bool print_protocol_list(uint32_t p, uint32_t indent,
3938                                 struct DisassembleInfo *info);
3939 
3940 static bool print_protocol(uint32_t p, uint32_t indent,
3941                            struct DisassembleInfo *info) {
3942   uint32_t offset, left;
3943   SectionRef S;
3944   struct objc_protocol_t protocol;
3945   const char *r, *name;
3946 
3947   r = get_pointer_32(p, offset, left, S, info, true);
3948   if (r == nullptr)
3949     return true;
3950 
3951   outs() << "\n";
3952   if (left >= sizeof(struct objc_protocol_t)) {
3953     memcpy(&protocol, r, sizeof(struct objc_protocol_t));
3954   } else {
3955     print_indent(indent);
3956     outs() << "            Protocol extends past end of the section\n";
3957     memset(&protocol, '\0', sizeof(struct objc_protocol_t));
3958     memcpy(&protocol, r, left);
3959   }
3960   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3961     swapStruct(protocol);
3962 
3963   print_indent(indent);
3964   outs() << "              isa " << format("0x%08" PRIx32, protocol.isa)
3965          << "\n";
3966 
3967   print_indent(indent);
3968   outs() << "    protocol_name "
3969          << format("0x%08" PRIx32, protocol.protocol_name);
3970   if (info->verbose) {
3971     name = get_pointer_32(protocol.protocol_name, offset, left, S, info, true);
3972     if (name != nullptr)
3973       outs() << format(" %.*s", left, name);
3974     else
3975       outs() << " (not in an __OBJC section)";
3976   }
3977   outs() << "\n";
3978 
3979   print_indent(indent);
3980   outs() << "    protocol_list "
3981          << format("0x%08" PRIx32, protocol.protocol_list);
3982   if (print_protocol_list(protocol.protocol_list, indent + 4, info))
3983     outs() << " (not in an __OBJC section)\n";
3984 
3985   print_indent(indent);
3986   outs() << " instance_methods "
3987          << format("0x%08" PRIx32, protocol.instance_methods);
3988   if (print_method_description_list(protocol.instance_methods, indent, info))
3989     outs() << " (not in an __OBJC section)\n";
3990 
3991   print_indent(indent);
3992   outs() << "    class_methods "
3993          << format("0x%08" PRIx32, protocol.class_methods);
3994   if (print_method_description_list(protocol.class_methods, indent, info))
3995     outs() << " (not in an __OBJC section)\n";
3996 
3997   return false;
3998 }
3999 
4000 static bool print_protocol_list(uint32_t p, uint32_t indent,
4001                                 struct DisassembleInfo *info) {
4002   uint32_t offset, left, l;
4003   SectionRef S;
4004   struct objc_protocol_list_t protocol_list;
4005   const char *r, *list;
4006   int32_t i;
4007 
4008   r = get_pointer_32(p, offset, left, S, info, true);
4009   if (r == nullptr)
4010     return true;
4011 
4012   outs() << "\n";
4013   if (left > sizeof(struct objc_protocol_list_t)) {
4014     memcpy(&protocol_list, r, sizeof(struct objc_protocol_list_t));
4015   } else {
4016     outs() << "\t\t objc_protocol_list_t extends past end of the section\n";
4017     memset(&protocol_list, '\0', sizeof(struct objc_protocol_list_t));
4018     memcpy(&protocol_list, r, left);
4019   }
4020   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4021     swapStruct(protocol_list);
4022 
4023   print_indent(indent);
4024   outs() << "         next " << format("0x%08" PRIx32, protocol_list.next)
4025          << "\n";
4026   print_indent(indent);
4027   outs() << "        count " << protocol_list.count << "\n";
4028 
4029   list = r + sizeof(struct objc_protocol_list_t);
4030   for (i = 0; i < protocol_list.count; i++) {
4031     if ((i + 1) * sizeof(uint32_t) > left) {
4032       outs() << "\t\t remaining list entries extend past the of the section\n";
4033       break;
4034     }
4035     memcpy(&l, list + i * sizeof(uint32_t), sizeof(uint32_t));
4036     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4037       sys::swapByteOrder(l);
4038 
4039     print_indent(indent);
4040     outs() << "      list[" << i << "] " << format("0x%08" PRIx32, l);
4041     if (print_protocol(l, indent, info))
4042       outs() << "(not in an __OBJC section)\n";
4043   }
4044   return false;
4045 }
4046 
4047 static void print_ivar_list64_t(uint64_t p, struct DisassembleInfo *info) {
4048   struct ivar_list64_t il;
4049   struct ivar64_t i;
4050   const char *r;
4051   uint32_t offset, xoffset, left, j;
4052   SectionRef S, xS;
4053   const char *name, *sym_name, *ivar_offset_p;
4054   uint64_t ivar_offset, n_value;
4055 
4056   r = get_pointer_64(p, offset, left, S, info);
4057   if (r == nullptr)
4058     return;
4059   memset(&il, '\0', sizeof(struct ivar_list64_t));
4060   if (left < sizeof(struct ivar_list64_t)) {
4061     memcpy(&il, r, left);
4062     outs() << "   (ivar_list_t entends past the end of the section)\n";
4063   } else
4064     memcpy(&il, r, sizeof(struct ivar_list64_t));
4065   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4066     swapStruct(il);
4067   outs() << "                    entsize " << il.entsize << "\n";
4068   outs() << "                      count " << il.count << "\n";
4069 
4070   p += sizeof(struct ivar_list64_t);
4071   offset += sizeof(struct ivar_list64_t);
4072   for (j = 0; j < il.count; j++) {
4073     r = get_pointer_64(p, offset, left, S, info);
4074     if (r == nullptr)
4075       return;
4076     memset(&i, '\0', sizeof(struct ivar64_t));
4077     if (left < sizeof(struct ivar64_t)) {
4078       memcpy(&i, r, left);
4079       outs() << "   (ivar_t entends past the end of the section)\n";
4080     } else
4081       memcpy(&i, r, sizeof(struct ivar64_t));
4082     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4083       swapStruct(i);
4084 
4085     outs() << "\t\t\t   offset ";
4086     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, offset), S,
4087                              info, n_value, i.offset);
4088     if (n_value != 0) {
4089       if (info->verbose && sym_name != nullptr)
4090         outs() << sym_name;
4091       else
4092         outs() << format("0x%" PRIx64, n_value);
4093       if (i.offset != 0)
4094         outs() << " + " << format("0x%" PRIx64, i.offset);
4095     } else
4096       outs() << format("0x%" PRIx64, i.offset);
4097     ivar_offset_p = get_pointer_64(i.offset + n_value, xoffset, left, xS, info);
4098     if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
4099       memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
4100       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4101         sys::swapByteOrder(ivar_offset);
4102       outs() << " " << ivar_offset << "\n";
4103     } else
4104       outs() << "\n";
4105 
4106     outs() << "\t\t\t     name ";
4107     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, name), S, info,
4108                              n_value, i.name);
4109     if (n_value != 0) {
4110       if (info->verbose && sym_name != nullptr)
4111         outs() << sym_name;
4112       else
4113         outs() << format("0x%" PRIx64, n_value);
4114       if (i.name != 0)
4115         outs() << " + " << format("0x%" PRIx64, i.name);
4116     } else
4117       outs() << format("0x%" PRIx64, i.name);
4118     name = get_pointer_64(i.name + n_value, xoffset, left, xS, info);
4119     if (name != nullptr)
4120       outs() << format(" %.*s", left, name);
4121     outs() << "\n";
4122 
4123     outs() << "\t\t\t     type ";
4124     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, type), S, info,
4125                              n_value, i.name);
4126     name = get_pointer_64(i.type + n_value, xoffset, left, xS, info);
4127     if (n_value != 0) {
4128       if (info->verbose && sym_name != nullptr)
4129         outs() << sym_name;
4130       else
4131         outs() << format("0x%" PRIx64, n_value);
4132       if (i.type != 0)
4133         outs() << " + " << format("0x%" PRIx64, i.type);
4134     } else
4135       outs() << format("0x%" PRIx64, i.type);
4136     if (name != nullptr)
4137       outs() << format(" %.*s", left, name);
4138     outs() << "\n";
4139 
4140     outs() << "\t\t\talignment " << i.alignment << "\n";
4141     outs() << "\t\t\t     size " << i.size << "\n";
4142 
4143     p += sizeof(struct ivar64_t);
4144     offset += sizeof(struct ivar64_t);
4145   }
4146 }
4147 
4148 static void print_ivar_list32_t(uint32_t p, struct DisassembleInfo *info) {
4149   struct ivar_list32_t il;
4150   struct ivar32_t i;
4151   const char *r;
4152   uint32_t offset, xoffset, left, j;
4153   SectionRef S, xS;
4154   const char *name, *ivar_offset_p;
4155   uint32_t ivar_offset;
4156 
4157   r = get_pointer_32(p, offset, left, S, info);
4158   if (r == nullptr)
4159     return;
4160   memset(&il, '\0', sizeof(struct ivar_list32_t));
4161   if (left < sizeof(struct ivar_list32_t)) {
4162     memcpy(&il, r, left);
4163     outs() << "   (ivar_list_t entends past the end of the section)\n";
4164   } else
4165     memcpy(&il, r, sizeof(struct ivar_list32_t));
4166   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4167     swapStruct(il);
4168   outs() << "                    entsize " << il.entsize << "\n";
4169   outs() << "                      count " << il.count << "\n";
4170 
4171   p += sizeof(struct ivar_list32_t);
4172   offset += sizeof(struct ivar_list32_t);
4173   for (j = 0; j < il.count; j++) {
4174     r = get_pointer_32(p, offset, left, S, info);
4175     if (r == nullptr)
4176       return;
4177     memset(&i, '\0', sizeof(struct ivar32_t));
4178     if (left < sizeof(struct ivar32_t)) {
4179       memcpy(&i, r, left);
4180       outs() << "   (ivar_t entends past the end of the section)\n";
4181     } else
4182       memcpy(&i, r, sizeof(struct ivar32_t));
4183     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4184       swapStruct(i);
4185 
4186     outs() << "\t\t\t   offset " << format("0x%" PRIx32, i.offset);
4187     ivar_offset_p = get_pointer_32(i.offset, xoffset, left, xS, info);
4188     if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
4189       memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
4190       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4191         sys::swapByteOrder(ivar_offset);
4192       outs() << " " << ivar_offset << "\n";
4193     } else
4194       outs() << "\n";
4195 
4196     outs() << "\t\t\t     name " << format("0x%" PRIx32, i.name);
4197     name = get_pointer_32(i.name, xoffset, left, xS, info);
4198     if (name != nullptr)
4199       outs() << format(" %.*s", left, name);
4200     outs() << "\n";
4201 
4202     outs() << "\t\t\t     type " << format("0x%" PRIx32, i.type);
4203     name = get_pointer_32(i.type, xoffset, left, xS, info);
4204     if (name != nullptr)
4205       outs() << format(" %.*s", left, name);
4206     outs() << "\n";
4207 
4208     outs() << "\t\t\talignment " << i.alignment << "\n";
4209     outs() << "\t\t\t     size " << i.size << "\n";
4210 
4211     p += sizeof(struct ivar32_t);
4212     offset += sizeof(struct ivar32_t);
4213   }
4214 }
4215 
4216 static void print_objc_property_list64(uint64_t p,
4217                                        struct DisassembleInfo *info) {
4218   struct objc_property_list64 opl;
4219   struct objc_property64 op;
4220   const char *r;
4221   uint32_t offset, xoffset, left, j;
4222   SectionRef S, xS;
4223   const char *name, *sym_name;
4224   uint64_t n_value;
4225 
4226   r = get_pointer_64(p, offset, left, S, info);
4227   if (r == nullptr)
4228     return;
4229   memset(&opl, '\0', sizeof(struct objc_property_list64));
4230   if (left < sizeof(struct objc_property_list64)) {
4231     memcpy(&opl, r, left);
4232     outs() << "   (objc_property_list entends past the end of the section)\n";
4233   } else
4234     memcpy(&opl, r, sizeof(struct objc_property_list64));
4235   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4236     swapStruct(opl);
4237   outs() << "                    entsize " << opl.entsize << "\n";
4238   outs() << "                      count " << opl.count << "\n";
4239 
4240   p += sizeof(struct objc_property_list64);
4241   offset += sizeof(struct objc_property_list64);
4242   for (j = 0; j < opl.count; j++) {
4243     r = get_pointer_64(p, offset, left, S, info);
4244     if (r == nullptr)
4245       return;
4246     memset(&op, '\0', sizeof(struct objc_property64));
4247     if (left < sizeof(struct objc_property64)) {
4248       memcpy(&op, r, left);
4249       outs() << "   (objc_property entends past the end of the section)\n";
4250     } else
4251       memcpy(&op, r, sizeof(struct objc_property64));
4252     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4253       swapStruct(op);
4254 
4255     outs() << "\t\t\t     name ";
4256     sym_name = get_symbol_64(offset + offsetof(struct objc_property64, name), S,
4257                              info, n_value, op.name);
4258     if (n_value != 0) {
4259       if (info->verbose && sym_name != nullptr)
4260         outs() << sym_name;
4261       else
4262         outs() << format("0x%" PRIx64, n_value);
4263       if (op.name != 0)
4264         outs() << " + " << format("0x%" PRIx64, op.name);
4265     } else
4266       outs() << format("0x%" PRIx64, op.name);
4267     name = get_pointer_64(op.name + n_value, xoffset, left, xS, info);
4268     if (name != nullptr)
4269       outs() << format(" %.*s", left, name);
4270     outs() << "\n";
4271 
4272     outs() << "\t\t\tattributes ";
4273     sym_name =
4274         get_symbol_64(offset + offsetof(struct objc_property64, attributes), S,
4275                       info, n_value, op.attributes);
4276     if (n_value != 0) {
4277       if (info->verbose && sym_name != nullptr)
4278         outs() << sym_name;
4279       else
4280         outs() << format("0x%" PRIx64, n_value);
4281       if (op.attributes != 0)
4282         outs() << " + " << format("0x%" PRIx64, op.attributes);
4283     } else
4284       outs() << format("0x%" PRIx64, op.attributes);
4285     name = get_pointer_64(op.attributes + n_value, xoffset, left, xS, info);
4286     if (name != nullptr)
4287       outs() << format(" %.*s", left, name);
4288     outs() << "\n";
4289 
4290     p += sizeof(struct objc_property64);
4291     offset += sizeof(struct objc_property64);
4292   }
4293 }
4294 
4295 static void print_objc_property_list32(uint32_t p,
4296                                        struct DisassembleInfo *info) {
4297   struct objc_property_list32 opl;
4298   struct objc_property32 op;
4299   const char *r;
4300   uint32_t offset, xoffset, left, j;
4301   SectionRef S, xS;
4302   const char *name;
4303 
4304   r = get_pointer_32(p, offset, left, S, info);
4305   if (r == nullptr)
4306     return;
4307   memset(&opl, '\0', sizeof(struct objc_property_list32));
4308   if (left < sizeof(struct objc_property_list32)) {
4309     memcpy(&opl, r, left);
4310     outs() << "   (objc_property_list entends past the end of the section)\n";
4311   } else
4312     memcpy(&opl, r, sizeof(struct objc_property_list32));
4313   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4314     swapStruct(opl);
4315   outs() << "                    entsize " << opl.entsize << "\n";
4316   outs() << "                      count " << opl.count << "\n";
4317 
4318   p += sizeof(struct objc_property_list32);
4319   offset += sizeof(struct objc_property_list32);
4320   for (j = 0; j < opl.count; j++) {
4321     r = get_pointer_32(p, offset, left, S, info);
4322     if (r == nullptr)
4323       return;
4324     memset(&op, '\0', sizeof(struct objc_property32));
4325     if (left < sizeof(struct objc_property32)) {
4326       memcpy(&op, r, left);
4327       outs() << "   (objc_property entends past the end of the section)\n";
4328     } else
4329       memcpy(&op, r, sizeof(struct objc_property32));
4330     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4331       swapStruct(op);
4332 
4333     outs() << "\t\t\t     name " << format("0x%" PRIx32, op.name);
4334     name = get_pointer_32(op.name, xoffset, left, xS, info);
4335     if (name != nullptr)
4336       outs() << format(" %.*s", left, name);
4337     outs() << "\n";
4338 
4339     outs() << "\t\t\tattributes " << format("0x%" PRIx32, op.attributes);
4340     name = get_pointer_32(op.attributes, xoffset, left, xS, info);
4341     if (name != nullptr)
4342       outs() << format(" %.*s", left, name);
4343     outs() << "\n";
4344 
4345     p += sizeof(struct objc_property32);
4346     offset += sizeof(struct objc_property32);
4347   }
4348 }
4349 
4350 static bool print_class_ro64_t(uint64_t p, struct DisassembleInfo *info,
4351                                bool &is_meta_class) {
4352   struct class_ro64_t cro;
4353   const char *r;
4354   uint32_t offset, xoffset, left;
4355   SectionRef S, xS;
4356   const char *name, *sym_name;
4357   uint64_t n_value;
4358 
4359   r = get_pointer_64(p, offset, left, S, info);
4360   if (r == nullptr || left < sizeof(struct class_ro64_t))
4361     return false;
4362   memcpy(&cro, r, sizeof(struct class_ro64_t));
4363   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4364     swapStruct(cro);
4365   outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
4366   if (cro.flags & RO_META)
4367     outs() << " RO_META";
4368   if (cro.flags & RO_ROOT)
4369     outs() << " RO_ROOT";
4370   if (cro.flags & RO_HAS_CXX_STRUCTORS)
4371     outs() << " RO_HAS_CXX_STRUCTORS";
4372   outs() << "\n";
4373   outs() << "            instanceStart " << cro.instanceStart << "\n";
4374   outs() << "             instanceSize " << cro.instanceSize << "\n";
4375   outs() << "                 reserved " << format("0x%" PRIx32, cro.reserved)
4376          << "\n";
4377   outs() << "               ivarLayout " << format("0x%" PRIx64, cro.ivarLayout)
4378          << "\n";
4379   print_layout_map64(cro.ivarLayout, info);
4380 
4381   outs() << "                     name ";
4382   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, name), S,
4383                            info, n_value, cro.name);
4384   if (n_value != 0) {
4385     if (info->verbose && sym_name != nullptr)
4386       outs() << sym_name;
4387     else
4388       outs() << format("0x%" PRIx64, n_value);
4389     if (cro.name != 0)
4390       outs() << " + " << format("0x%" PRIx64, cro.name);
4391   } else
4392     outs() << format("0x%" PRIx64, cro.name);
4393   name = get_pointer_64(cro.name + n_value, xoffset, left, xS, info);
4394   if (name != nullptr)
4395     outs() << format(" %.*s", left, name);
4396   outs() << "\n";
4397 
4398   outs() << "              baseMethods ";
4399   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, baseMethods),
4400                            S, info, n_value, cro.baseMethods);
4401   if (n_value != 0) {
4402     if (info->verbose && sym_name != nullptr)
4403       outs() << sym_name;
4404     else
4405       outs() << format("0x%" PRIx64, n_value);
4406     if (cro.baseMethods != 0)
4407       outs() << " + " << format("0x%" PRIx64, cro.baseMethods);
4408   } else
4409     outs() << format("0x%" PRIx64, cro.baseMethods);
4410   outs() << " (struct method_list_t *)\n";
4411   if (cro.baseMethods + n_value != 0)
4412     print_method_list64_t(cro.baseMethods + n_value, info, "");
4413 
4414   outs() << "            baseProtocols ";
4415   sym_name =
4416       get_symbol_64(offset + offsetof(struct class_ro64_t, baseProtocols), S,
4417                     info, n_value, cro.baseProtocols);
4418   if (n_value != 0) {
4419     if (info->verbose && sym_name != nullptr)
4420       outs() << sym_name;
4421     else
4422       outs() << format("0x%" PRIx64, n_value);
4423     if (cro.baseProtocols != 0)
4424       outs() << " + " << format("0x%" PRIx64, cro.baseProtocols);
4425   } else
4426     outs() << format("0x%" PRIx64, cro.baseProtocols);
4427   outs() << "\n";
4428   if (cro.baseProtocols + n_value != 0)
4429     print_protocol_list64_t(cro.baseProtocols + n_value, info);
4430 
4431   outs() << "                    ivars ";
4432   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, ivars), S,
4433                            info, n_value, cro.ivars);
4434   if (n_value != 0) {
4435     if (info->verbose && sym_name != nullptr)
4436       outs() << sym_name;
4437     else
4438       outs() << format("0x%" PRIx64, n_value);
4439     if (cro.ivars != 0)
4440       outs() << " + " << format("0x%" PRIx64, cro.ivars);
4441   } else
4442     outs() << format("0x%" PRIx64, cro.ivars);
4443   outs() << "\n";
4444   if (cro.ivars + n_value != 0)
4445     print_ivar_list64_t(cro.ivars + n_value, info);
4446 
4447   outs() << "           weakIvarLayout ";
4448   sym_name =
4449       get_symbol_64(offset + offsetof(struct class_ro64_t, weakIvarLayout), S,
4450                     info, n_value, cro.weakIvarLayout);
4451   if (n_value != 0) {
4452     if (info->verbose && sym_name != nullptr)
4453       outs() << sym_name;
4454     else
4455       outs() << format("0x%" PRIx64, n_value);
4456     if (cro.weakIvarLayout != 0)
4457       outs() << " + " << format("0x%" PRIx64, cro.weakIvarLayout);
4458   } else
4459     outs() << format("0x%" PRIx64, cro.weakIvarLayout);
4460   outs() << "\n";
4461   print_layout_map64(cro.weakIvarLayout + n_value, info);
4462 
4463   outs() << "           baseProperties ";
4464   sym_name =
4465       get_symbol_64(offset + offsetof(struct class_ro64_t, baseProperties), S,
4466                     info, n_value, cro.baseProperties);
4467   if (n_value != 0) {
4468     if (info->verbose && sym_name != nullptr)
4469       outs() << sym_name;
4470     else
4471       outs() << format("0x%" PRIx64, n_value);
4472     if (cro.baseProperties != 0)
4473       outs() << " + " << format("0x%" PRIx64, cro.baseProperties);
4474   } else
4475     outs() << format("0x%" PRIx64, cro.baseProperties);
4476   outs() << "\n";
4477   if (cro.baseProperties + n_value != 0)
4478     print_objc_property_list64(cro.baseProperties + n_value, info);
4479 
4480   is_meta_class = (cro.flags & RO_META) != 0;
4481   return true;
4482 }
4483 
4484 static bool print_class_ro32_t(uint32_t p, struct DisassembleInfo *info,
4485                                bool &is_meta_class) {
4486   struct class_ro32_t cro;
4487   const char *r;
4488   uint32_t offset, xoffset, left;
4489   SectionRef S, xS;
4490   const char *name;
4491 
4492   r = get_pointer_32(p, offset, left, S, info);
4493   if (r == nullptr)
4494     return false;
4495   memset(&cro, '\0', sizeof(struct class_ro32_t));
4496   if (left < sizeof(struct class_ro32_t)) {
4497     memcpy(&cro, r, left);
4498     outs() << "   (class_ro_t entends past the end of the section)\n";
4499   } else
4500     memcpy(&cro, r, sizeof(struct class_ro32_t));
4501   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4502     swapStruct(cro);
4503   outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
4504   if (cro.flags & RO_META)
4505     outs() << " RO_META";
4506   if (cro.flags & RO_ROOT)
4507     outs() << " RO_ROOT";
4508   if (cro.flags & RO_HAS_CXX_STRUCTORS)
4509     outs() << " RO_HAS_CXX_STRUCTORS";
4510   outs() << "\n";
4511   outs() << "            instanceStart " << cro.instanceStart << "\n";
4512   outs() << "             instanceSize " << cro.instanceSize << "\n";
4513   outs() << "               ivarLayout " << format("0x%" PRIx32, cro.ivarLayout)
4514          << "\n";
4515   print_layout_map32(cro.ivarLayout, info);
4516 
4517   outs() << "                     name " << format("0x%" PRIx32, cro.name);
4518   name = get_pointer_32(cro.name, xoffset, left, xS, info);
4519   if (name != nullptr)
4520     outs() << format(" %.*s", left, name);
4521   outs() << "\n";
4522 
4523   outs() << "              baseMethods "
4524          << format("0x%" PRIx32, cro.baseMethods)
4525          << " (struct method_list_t *)\n";
4526   if (cro.baseMethods != 0)
4527     print_method_list32_t(cro.baseMethods, info, "");
4528 
4529   outs() << "            baseProtocols "
4530          << format("0x%" PRIx32, cro.baseProtocols) << "\n";
4531   if (cro.baseProtocols != 0)
4532     print_protocol_list32_t(cro.baseProtocols, info);
4533   outs() << "                    ivars " << format("0x%" PRIx32, cro.ivars)
4534          << "\n";
4535   if (cro.ivars != 0)
4536     print_ivar_list32_t(cro.ivars, info);
4537   outs() << "           weakIvarLayout "
4538          << format("0x%" PRIx32, cro.weakIvarLayout) << "\n";
4539   print_layout_map32(cro.weakIvarLayout, info);
4540   outs() << "           baseProperties "
4541          << format("0x%" PRIx32, cro.baseProperties) << "\n";
4542   if (cro.baseProperties != 0)
4543     print_objc_property_list32(cro.baseProperties, info);
4544   is_meta_class = (cro.flags & RO_META) != 0;
4545   return true;
4546 }
4547 
4548 static void print_class64_t(uint64_t p, struct DisassembleInfo *info) {
4549   struct class64_t c;
4550   const char *r;
4551   uint32_t offset, left;
4552   SectionRef S;
4553   const char *name;
4554   uint64_t isa_n_value, n_value;
4555 
4556   r = get_pointer_64(p, offset, left, S, info);
4557   if (r == nullptr || left < sizeof(struct class64_t))
4558     return;
4559   memcpy(&c, r, sizeof(struct class64_t));
4560   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4561     swapStruct(c);
4562 
4563   outs() << "           isa " << format("0x%" PRIx64, c.isa);
4564   name = get_symbol_64(offset + offsetof(struct class64_t, isa), S, info,
4565                        isa_n_value, c.isa);
4566   if (name != nullptr)
4567     outs() << " " << name;
4568   outs() << "\n";
4569 
4570   outs() << "    superclass " << format("0x%" PRIx64, c.superclass);
4571   name = get_symbol_64(offset + offsetof(struct class64_t, superclass), S, info,
4572                        n_value, c.superclass);
4573   if (name != nullptr)
4574     outs() << " " << name;
4575   outs() << "\n";
4576 
4577   outs() << "         cache " << format("0x%" PRIx64, c.cache);
4578   name = get_symbol_64(offset + offsetof(struct class64_t, cache), S, info,
4579                        n_value, c.cache);
4580   if (name != nullptr)
4581     outs() << " " << name;
4582   outs() << "\n";
4583 
4584   outs() << "        vtable " << format("0x%" PRIx64, c.vtable);
4585   name = get_symbol_64(offset + offsetof(struct class64_t, vtable), S, info,
4586                        n_value, c.vtable);
4587   if (name != nullptr)
4588     outs() << " " << name;
4589   outs() << "\n";
4590 
4591   name = get_symbol_64(offset + offsetof(struct class64_t, data), S, info,
4592                        n_value, c.data);
4593   outs() << "          data ";
4594   if (n_value != 0) {
4595     if (info->verbose && name != nullptr)
4596       outs() << name;
4597     else
4598       outs() << format("0x%" PRIx64, n_value);
4599     if (c.data != 0)
4600       outs() << " + " << format("0x%" PRIx64, c.data);
4601   } else
4602     outs() << format("0x%" PRIx64, c.data);
4603   outs() << " (struct class_ro_t *)";
4604 
4605   // This is a Swift class if some of the low bits of the pointer are set.
4606   if ((c.data + n_value) & 0x7)
4607     outs() << " Swift class";
4608   outs() << "\n";
4609   bool is_meta_class;
4610   if (!print_class_ro64_t((c.data + n_value) & ~0x7, info, is_meta_class))
4611     return;
4612 
4613   if (!is_meta_class &&
4614       c.isa + isa_n_value != p &&
4615       c.isa + isa_n_value != 0 &&
4616       info->depth < 100) {
4617       info->depth++;
4618       outs() << "Meta Class\n";
4619       print_class64_t(c.isa + isa_n_value, info);
4620   }
4621 }
4622 
4623 static void print_class32_t(uint32_t p, struct DisassembleInfo *info) {
4624   struct class32_t c;
4625   const char *r;
4626   uint32_t offset, left;
4627   SectionRef S;
4628   const char *name;
4629 
4630   r = get_pointer_32(p, offset, left, S, info);
4631   if (r == nullptr)
4632     return;
4633   memset(&c, '\0', sizeof(struct class32_t));
4634   if (left < sizeof(struct class32_t)) {
4635     memcpy(&c, r, left);
4636     outs() << "   (class_t entends past the end of the section)\n";
4637   } else
4638     memcpy(&c, r, sizeof(struct class32_t));
4639   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4640     swapStruct(c);
4641 
4642   outs() << "           isa " << format("0x%" PRIx32, c.isa);
4643   name =
4644       get_symbol_32(offset + offsetof(struct class32_t, isa), S, info, c.isa);
4645   if (name != nullptr)
4646     outs() << " " << name;
4647   outs() << "\n";
4648 
4649   outs() << "    superclass " << format("0x%" PRIx32, c.superclass);
4650   name = get_symbol_32(offset + offsetof(struct class32_t, superclass), S, info,
4651                        c.superclass);
4652   if (name != nullptr)
4653     outs() << " " << name;
4654   outs() << "\n";
4655 
4656   outs() << "         cache " << format("0x%" PRIx32, c.cache);
4657   name = get_symbol_32(offset + offsetof(struct class32_t, cache), S, info,
4658                        c.cache);
4659   if (name != nullptr)
4660     outs() << " " << name;
4661   outs() << "\n";
4662 
4663   outs() << "        vtable " << format("0x%" PRIx32, c.vtable);
4664   name = get_symbol_32(offset + offsetof(struct class32_t, vtable), S, info,
4665                        c.vtable);
4666   if (name != nullptr)
4667     outs() << " " << name;
4668   outs() << "\n";
4669 
4670   name =
4671       get_symbol_32(offset + offsetof(struct class32_t, data), S, info, c.data);
4672   outs() << "          data " << format("0x%" PRIx32, c.data)
4673          << " (struct class_ro_t *)";
4674 
4675   // This is a Swift class if some of the low bits of the pointer are set.
4676   if (c.data & 0x3)
4677     outs() << " Swift class";
4678   outs() << "\n";
4679   bool is_meta_class;
4680   if (!print_class_ro32_t(c.data & ~0x3, info, is_meta_class))
4681     return;
4682 
4683   if (!is_meta_class) {
4684     outs() << "Meta Class\n";
4685     print_class32_t(c.isa, info);
4686   }
4687 }
4688 
4689 static void print_objc_class_t(struct objc_class_t *objc_class,
4690                                struct DisassembleInfo *info) {
4691   uint32_t offset, left, xleft;
4692   const char *name, *p, *ivar_list;
4693   SectionRef S;
4694   int32_t i;
4695   struct objc_ivar_list_t objc_ivar_list;
4696   struct objc_ivar_t ivar;
4697 
4698   outs() << "\t\t      isa " << format("0x%08" PRIx32, objc_class->isa);
4699   if (info->verbose && CLS_GETINFO(objc_class, CLS_META)) {
4700     name = get_pointer_32(objc_class->isa, offset, left, S, info, true);
4701     if (name != nullptr)
4702       outs() << format(" %.*s", left, name);
4703     else
4704       outs() << " (not in an __OBJC section)";
4705   }
4706   outs() << "\n";
4707 
4708   outs() << "\t      super_class "
4709          << format("0x%08" PRIx32, objc_class->super_class);
4710   if (info->verbose) {
4711     name = get_pointer_32(objc_class->super_class, offset, left, S, info, true);
4712     if (name != nullptr)
4713       outs() << format(" %.*s", left, name);
4714     else
4715       outs() << " (not in an __OBJC section)";
4716   }
4717   outs() << "\n";
4718 
4719   outs() << "\t\t     name " << format("0x%08" PRIx32, objc_class->name);
4720   if (info->verbose) {
4721     name = get_pointer_32(objc_class->name, offset, left, S, info, true);
4722     if (name != nullptr)
4723       outs() << format(" %.*s", left, name);
4724     else
4725       outs() << " (not in an __OBJC section)";
4726   }
4727   outs() << "\n";
4728 
4729   outs() << "\t\t  version " << format("0x%08" PRIx32, objc_class->version)
4730          << "\n";
4731 
4732   outs() << "\t\t     info " << format("0x%08" PRIx32, objc_class->info);
4733   if (info->verbose) {
4734     if (CLS_GETINFO(objc_class, CLS_CLASS))
4735       outs() << " CLS_CLASS";
4736     else if (CLS_GETINFO(objc_class, CLS_META))
4737       outs() << " CLS_META";
4738   }
4739   outs() << "\n";
4740 
4741   outs() << "\t    instance_size "
4742          << format("0x%08" PRIx32, objc_class->instance_size) << "\n";
4743 
4744   p = get_pointer_32(objc_class->ivars, offset, left, S, info, true);
4745   outs() << "\t\t    ivars " << format("0x%08" PRIx32, objc_class->ivars);
4746   if (p != nullptr) {
4747     if (left > sizeof(struct objc_ivar_list_t)) {
4748       outs() << "\n";
4749       memcpy(&objc_ivar_list, p, sizeof(struct objc_ivar_list_t));
4750     } else {
4751       outs() << " (entends past the end of the section)\n";
4752       memset(&objc_ivar_list, '\0', sizeof(struct objc_ivar_list_t));
4753       memcpy(&objc_ivar_list, p, left);
4754     }
4755     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4756       swapStruct(objc_ivar_list);
4757     outs() << "\t\t       ivar_count " << objc_ivar_list.ivar_count << "\n";
4758     ivar_list = p + sizeof(struct objc_ivar_list_t);
4759     for (i = 0; i < objc_ivar_list.ivar_count; i++) {
4760       if ((i + 1) * sizeof(struct objc_ivar_t) > left) {
4761         outs() << "\t\t remaining ivar's extend past the of the section\n";
4762         break;
4763       }
4764       memcpy(&ivar, ivar_list + i * sizeof(struct objc_ivar_t),
4765              sizeof(struct objc_ivar_t));
4766       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4767         swapStruct(ivar);
4768 
4769       outs() << "\t\t\tivar_name " << format("0x%08" PRIx32, ivar.ivar_name);
4770       if (info->verbose) {
4771         name = get_pointer_32(ivar.ivar_name, offset, xleft, S, info, true);
4772         if (name != nullptr)
4773           outs() << format(" %.*s", xleft, name);
4774         else
4775           outs() << " (not in an __OBJC section)";
4776       }
4777       outs() << "\n";
4778 
4779       outs() << "\t\t\tivar_type " << format("0x%08" PRIx32, ivar.ivar_type);
4780       if (info->verbose) {
4781         name = get_pointer_32(ivar.ivar_type, offset, xleft, S, info, true);
4782         if (name != nullptr)
4783           outs() << format(" %.*s", xleft, name);
4784         else
4785           outs() << " (not in an __OBJC section)";
4786       }
4787       outs() << "\n";
4788 
4789       outs() << "\t\t      ivar_offset "
4790              << format("0x%08" PRIx32, ivar.ivar_offset) << "\n";
4791     }
4792   } else {
4793     outs() << " (not in an __OBJC section)\n";
4794   }
4795 
4796   outs() << "\t\t  methods " << format("0x%08" PRIx32, objc_class->methodLists);
4797   if (print_method_list(objc_class->methodLists, info))
4798     outs() << " (not in an __OBJC section)\n";
4799 
4800   outs() << "\t\t    cache " << format("0x%08" PRIx32, objc_class->cache)
4801          << "\n";
4802 
4803   outs() << "\t\tprotocols " << format("0x%08" PRIx32, objc_class->protocols);
4804   if (print_protocol_list(objc_class->protocols, 16, info))
4805     outs() << " (not in an __OBJC section)\n";
4806 }
4807 
4808 static void print_objc_objc_category_t(struct objc_category_t *objc_category,
4809                                        struct DisassembleInfo *info) {
4810   uint32_t offset, left;
4811   const char *name;
4812   SectionRef S;
4813 
4814   outs() << "\t       category name "
4815          << format("0x%08" PRIx32, objc_category->category_name);
4816   if (info->verbose) {
4817     name = get_pointer_32(objc_category->category_name, offset, left, S, info,
4818                           true);
4819     if (name != nullptr)
4820       outs() << format(" %.*s", left, name);
4821     else
4822       outs() << " (not in an __OBJC section)";
4823   }
4824   outs() << "\n";
4825 
4826   outs() << "\t\t  class name "
4827          << format("0x%08" PRIx32, objc_category->class_name);
4828   if (info->verbose) {
4829     name =
4830         get_pointer_32(objc_category->class_name, offset, left, S, info, true);
4831     if (name != nullptr)
4832       outs() << format(" %.*s", left, name);
4833     else
4834       outs() << " (not in an __OBJC section)";
4835   }
4836   outs() << "\n";
4837 
4838   outs() << "\t    instance methods "
4839          << format("0x%08" PRIx32, objc_category->instance_methods);
4840   if (print_method_list(objc_category->instance_methods, info))
4841     outs() << " (not in an __OBJC section)\n";
4842 
4843   outs() << "\t       class methods "
4844          << format("0x%08" PRIx32, objc_category->class_methods);
4845   if (print_method_list(objc_category->class_methods, info))
4846     outs() << " (not in an __OBJC section)\n";
4847 }
4848 
4849 static void print_category64_t(uint64_t p, struct DisassembleInfo *info) {
4850   struct category64_t c;
4851   const char *r;
4852   uint32_t offset, xoffset, left;
4853   SectionRef S, xS;
4854   const char *name, *sym_name;
4855   uint64_t n_value;
4856 
4857   r = get_pointer_64(p, offset, left, S, info);
4858   if (r == nullptr)
4859     return;
4860   memset(&c, '\0', sizeof(struct category64_t));
4861   if (left < sizeof(struct category64_t)) {
4862     memcpy(&c, r, left);
4863     outs() << "   (category_t entends past the end of the section)\n";
4864   } else
4865     memcpy(&c, r, sizeof(struct category64_t));
4866   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4867     swapStruct(c);
4868 
4869   outs() << "              name ";
4870   sym_name = get_symbol_64(offset + offsetof(struct category64_t, name), S,
4871                            info, n_value, c.name);
4872   if (n_value != 0) {
4873     if (info->verbose && sym_name != nullptr)
4874       outs() << sym_name;
4875     else
4876       outs() << format("0x%" PRIx64, n_value);
4877     if (c.name != 0)
4878       outs() << " + " << format("0x%" PRIx64, c.name);
4879   } else
4880     outs() << format("0x%" PRIx64, c.name);
4881   name = get_pointer_64(c.name + n_value, xoffset, left, xS, info);
4882   if (name != nullptr)
4883     outs() << format(" %.*s", left, name);
4884   outs() << "\n";
4885 
4886   outs() << "               cls ";
4887   sym_name = get_symbol_64(offset + offsetof(struct category64_t, cls), S, info,
4888                            n_value, c.cls);
4889   if (n_value != 0) {
4890     if (info->verbose && sym_name != nullptr)
4891       outs() << sym_name;
4892     else
4893       outs() << format("0x%" PRIx64, n_value);
4894     if (c.cls != 0)
4895       outs() << " + " << format("0x%" PRIx64, c.cls);
4896   } else
4897     outs() << format("0x%" PRIx64, c.cls);
4898   outs() << "\n";
4899   if (c.cls + n_value != 0)
4900     print_class64_t(c.cls + n_value, info);
4901 
4902   outs() << "   instanceMethods ";
4903   sym_name =
4904       get_symbol_64(offset + offsetof(struct category64_t, instanceMethods), S,
4905                     info, n_value, c.instanceMethods);
4906   if (n_value != 0) {
4907     if (info->verbose && sym_name != nullptr)
4908       outs() << sym_name;
4909     else
4910       outs() << format("0x%" PRIx64, n_value);
4911     if (c.instanceMethods != 0)
4912       outs() << " + " << format("0x%" PRIx64, c.instanceMethods);
4913   } else
4914     outs() << format("0x%" PRIx64, c.instanceMethods);
4915   outs() << "\n";
4916   if (c.instanceMethods + n_value != 0)
4917     print_method_list64_t(c.instanceMethods + n_value, info, "");
4918 
4919   outs() << "      classMethods ";
4920   sym_name = get_symbol_64(offset + offsetof(struct category64_t, classMethods),
4921                            S, info, n_value, c.classMethods);
4922   if (n_value != 0) {
4923     if (info->verbose && sym_name != nullptr)
4924       outs() << sym_name;
4925     else
4926       outs() << format("0x%" PRIx64, n_value);
4927     if (c.classMethods != 0)
4928       outs() << " + " << format("0x%" PRIx64, c.classMethods);
4929   } else
4930     outs() << format("0x%" PRIx64, c.classMethods);
4931   outs() << "\n";
4932   if (c.classMethods + n_value != 0)
4933     print_method_list64_t(c.classMethods + n_value, info, "");
4934 
4935   outs() << "         protocols ";
4936   sym_name = get_symbol_64(offset + offsetof(struct category64_t, protocols), S,
4937                            info, n_value, c.protocols);
4938   if (n_value != 0) {
4939     if (info->verbose && sym_name != nullptr)
4940       outs() << sym_name;
4941     else
4942       outs() << format("0x%" PRIx64, n_value);
4943     if (c.protocols != 0)
4944       outs() << " + " << format("0x%" PRIx64, c.protocols);
4945   } else
4946     outs() << format("0x%" PRIx64, c.protocols);
4947   outs() << "\n";
4948   if (c.protocols + n_value != 0)
4949     print_protocol_list64_t(c.protocols + n_value, info);
4950 
4951   outs() << "instanceProperties ";
4952   sym_name =
4953       get_symbol_64(offset + offsetof(struct category64_t, instanceProperties),
4954                     S, info, n_value, c.instanceProperties);
4955   if (n_value != 0) {
4956     if (info->verbose && sym_name != nullptr)
4957       outs() << sym_name;
4958     else
4959       outs() << format("0x%" PRIx64, n_value);
4960     if (c.instanceProperties != 0)
4961       outs() << " + " << format("0x%" PRIx64, c.instanceProperties);
4962   } else
4963     outs() << format("0x%" PRIx64, c.instanceProperties);
4964   outs() << "\n";
4965   if (c.instanceProperties + n_value != 0)
4966     print_objc_property_list64(c.instanceProperties + n_value, info);
4967 }
4968 
4969 static void print_category32_t(uint32_t p, struct DisassembleInfo *info) {
4970   struct category32_t c;
4971   const char *r;
4972   uint32_t offset, left;
4973   SectionRef S, xS;
4974   const char *name;
4975 
4976   r = get_pointer_32(p, offset, left, S, info);
4977   if (r == nullptr)
4978     return;
4979   memset(&c, '\0', sizeof(struct category32_t));
4980   if (left < sizeof(struct category32_t)) {
4981     memcpy(&c, r, left);
4982     outs() << "   (category_t entends past the end of the section)\n";
4983   } else
4984     memcpy(&c, r, sizeof(struct category32_t));
4985   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4986     swapStruct(c);
4987 
4988   outs() << "              name " << format("0x%" PRIx32, c.name);
4989   name = get_symbol_32(offset + offsetof(struct category32_t, name), S, info,
4990                        c.name);
4991   if (name)
4992     outs() << " " << name;
4993   outs() << "\n";
4994 
4995   outs() << "               cls " << format("0x%" PRIx32, c.cls) << "\n";
4996   if (c.cls != 0)
4997     print_class32_t(c.cls, info);
4998   outs() << "   instanceMethods " << format("0x%" PRIx32, c.instanceMethods)
4999          << "\n";
5000   if (c.instanceMethods != 0)
5001     print_method_list32_t(c.instanceMethods, info, "");
5002   outs() << "      classMethods " << format("0x%" PRIx32, c.classMethods)
5003          << "\n";
5004   if (c.classMethods != 0)
5005     print_method_list32_t(c.classMethods, info, "");
5006   outs() << "         protocols " << format("0x%" PRIx32, c.protocols) << "\n";
5007   if (c.protocols != 0)
5008     print_protocol_list32_t(c.protocols, info);
5009   outs() << "instanceProperties " << format("0x%" PRIx32, c.instanceProperties)
5010          << "\n";
5011   if (c.instanceProperties != 0)
5012     print_objc_property_list32(c.instanceProperties, info);
5013 }
5014 
5015 static void print_message_refs64(SectionRef S, struct DisassembleInfo *info) {
5016   uint32_t i, left, offset, xoffset;
5017   uint64_t p, n_value;
5018   struct message_ref64 mr;
5019   const char *name, *sym_name;
5020   const char *r;
5021   SectionRef xS;
5022 
5023   if (S == SectionRef())
5024     return;
5025 
5026   StringRef SectName;
5027   S.getName(SectName);
5028   DataRefImpl Ref = S.getRawDataRefImpl();
5029   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5030   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5031   offset = 0;
5032   for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
5033     p = S.getAddress() + i;
5034     r = get_pointer_64(p, offset, left, S, info);
5035     if (r == nullptr)
5036       return;
5037     memset(&mr, '\0', sizeof(struct message_ref64));
5038     if (left < sizeof(struct message_ref64)) {
5039       memcpy(&mr, r, left);
5040       outs() << "   (message_ref entends past the end of the section)\n";
5041     } else
5042       memcpy(&mr, r, sizeof(struct message_ref64));
5043     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5044       swapStruct(mr);
5045 
5046     outs() << "  imp ";
5047     name = get_symbol_64(offset + offsetof(struct message_ref64, imp), S, info,
5048                          n_value, mr.imp);
5049     if (n_value != 0) {
5050       outs() << format("0x%" PRIx64, n_value) << " ";
5051       if (mr.imp != 0)
5052         outs() << "+ " << format("0x%" PRIx64, mr.imp) << " ";
5053     } else
5054       outs() << format("0x%" PRIx64, mr.imp) << " ";
5055     if (name != nullptr)
5056       outs() << " " << name;
5057     outs() << "\n";
5058 
5059     outs() << "  sel ";
5060     sym_name = get_symbol_64(offset + offsetof(struct message_ref64, sel), S,
5061                              info, n_value, mr.sel);
5062     if (n_value != 0) {
5063       if (info->verbose && sym_name != nullptr)
5064         outs() << sym_name;
5065       else
5066         outs() << format("0x%" PRIx64, n_value);
5067       if (mr.sel != 0)
5068         outs() << " + " << format("0x%" PRIx64, mr.sel);
5069     } else
5070       outs() << format("0x%" PRIx64, mr.sel);
5071     name = get_pointer_64(mr.sel + n_value, xoffset, left, xS, info);
5072     if (name != nullptr)
5073       outs() << format(" %.*s", left, name);
5074     outs() << "\n";
5075 
5076     offset += sizeof(struct message_ref64);
5077   }
5078 }
5079 
5080 static void print_message_refs32(SectionRef S, struct DisassembleInfo *info) {
5081   uint32_t i, left, offset, xoffset, p;
5082   struct message_ref32 mr;
5083   const char *name, *r;
5084   SectionRef xS;
5085 
5086   if (S == SectionRef())
5087     return;
5088 
5089   StringRef SectName;
5090   S.getName(SectName);
5091   DataRefImpl Ref = S.getRawDataRefImpl();
5092   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5093   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5094   offset = 0;
5095   for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
5096     p = S.getAddress() + i;
5097     r = get_pointer_32(p, offset, left, S, info);
5098     if (r == nullptr)
5099       return;
5100     memset(&mr, '\0', sizeof(struct message_ref32));
5101     if (left < sizeof(struct message_ref32)) {
5102       memcpy(&mr, r, left);
5103       outs() << "   (message_ref entends past the end of the section)\n";
5104     } else
5105       memcpy(&mr, r, sizeof(struct message_ref32));
5106     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5107       swapStruct(mr);
5108 
5109     outs() << "  imp " << format("0x%" PRIx32, mr.imp);
5110     name = get_symbol_32(offset + offsetof(struct message_ref32, imp), S, info,
5111                          mr.imp);
5112     if (name != nullptr)
5113       outs() << " " << name;
5114     outs() << "\n";
5115 
5116     outs() << "  sel " << format("0x%" PRIx32, mr.sel);
5117     name = get_pointer_32(mr.sel, xoffset, left, xS, info);
5118     if (name != nullptr)
5119       outs() << " " << name;
5120     outs() << "\n";
5121 
5122     offset += sizeof(struct message_ref32);
5123   }
5124 }
5125 
5126 static void print_image_info64(SectionRef S, struct DisassembleInfo *info) {
5127   uint32_t left, offset, swift_version;
5128   uint64_t p;
5129   struct objc_image_info64 o;
5130   const char *r;
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   p = S.getAddress();
5141   r = get_pointer_64(p, offset, left, S, info);
5142   if (r == nullptr)
5143     return;
5144   memset(&o, '\0', sizeof(struct objc_image_info64));
5145   if (left < sizeof(struct objc_image_info64)) {
5146     memcpy(&o, r, left);
5147     outs() << "   (objc_image_info entends past the end of the section)\n";
5148   } else
5149     memcpy(&o, r, sizeof(struct objc_image_info64));
5150   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5151     swapStruct(o);
5152   outs() << "  version " << o.version << "\n";
5153   outs() << "    flags " << format("0x%" PRIx32, o.flags);
5154   if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
5155     outs() << " OBJC_IMAGE_IS_REPLACEMENT";
5156   if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
5157     outs() << " OBJC_IMAGE_SUPPORTS_GC";
5158   swift_version = (o.flags >> 8) & 0xff;
5159   if (swift_version != 0) {
5160     if (swift_version == 1)
5161       outs() << " Swift 1.0";
5162     else if (swift_version == 2)
5163       outs() << " Swift 1.1";
5164     else
5165       outs() << " unknown future Swift version (" << swift_version << ")";
5166   }
5167   outs() << "\n";
5168 }
5169 
5170 static void print_image_info32(SectionRef S, struct DisassembleInfo *info) {
5171   uint32_t left, offset, swift_version, p;
5172   struct objc_image_info32 o;
5173   const char *r;
5174 
5175   if (S == SectionRef())
5176     return;
5177 
5178   StringRef SectName;
5179   S.getName(SectName);
5180   DataRefImpl Ref = S.getRawDataRefImpl();
5181   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5182   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5183   p = S.getAddress();
5184   r = get_pointer_32(p, offset, left, S, info);
5185   if (r == nullptr)
5186     return;
5187   memset(&o, '\0', sizeof(struct objc_image_info32));
5188   if (left < sizeof(struct objc_image_info32)) {
5189     memcpy(&o, r, left);
5190     outs() << "   (objc_image_info entends past the end of the section)\n";
5191   } else
5192     memcpy(&o, r, sizeof(struct objc_image_info32));
5193   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5194     swapStruct(o);
5195   outs() << "  version " << o.version << "\n";
5196   outs() << "    flags " << format("0x%" PRIx32, o.flags);
5197   if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
5198     outs() << " OBJC_IMAGE_IS_REPLACEMENT";
5199   if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
5200     outs() << " OBJC_IMAGE_SUPPORTS_GC";
5201   swift_version = (o.flags >> 8) & 0xff;
5202   if (swift_version != 0) {
5203     if (swift_version == 1)
5204       outs() << " Swift 1.0";
5205     else if (swift_version == 2)
5206       outs() << " Swift 1.1";
5207     else
5208       outs() << " unknown future Swift version (" << swift_version << ")";
5209   }
5210   outs() << "\n";
5211 }
5212 
5213 static void print_image_info(SectionRef S, struct DisassembleInfo *info) {
5214   uint32_t left, offset, p;
5215   struct imageInfo_t o;
5216   const char *r;
5217 
5218   StringRef SectName;
5219   S.getName(SectName);
5220   DataRefImpl Ref = S.getRawDataRefImpl();
5221   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5222   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5223   p = S.getAddress();
5224   r = get_pointer_32(p, offset, left, S, info);
5225   if (r == nullptr)
5226     return;
5227   memset(&o, '\0', sizeof(struct imageInfo_t));
5228   if (left < sizeof(struct imageInfo_t)) {
5229     memcpy(&o, r, left);
5230     outs() << " (imageInfo entends past the end of the section)\n";
5231   } else
5232     memcpy(&o, r, sizeof(struct imageInfo_t));
5233   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5234     swapStruct(o);
5235   outs() << "  version " << o.version << "\n";
5236   outs() << "    flags " << format("0x%" PRIx32, o.flags);
5237   if (o.flags & 0x1)
5238     outs() << "  F&C";
5239   if (o.flags & 0x2)
5240     outs() << " GC";
5241   if (o.flags & 0x4)
5242     outs() << " GC-only";
5243   else
5244     outs() << " RR";
5245   outs() << "\n";
5246 }
5247 
5248 static void printObjc2_64bit_MetaData(MachOObjectFile *O, bool verbose) {
5249   SymbolAddressMap AddrMap;
5250   if (verbose)
5251     CreateSymbolAddressMap(O, &AddrMap);
5252 
5253   std::vector<SectionRef> Sections;
5254   for (const SectionRef &Section : O->sections()) {
5255     StringRef SectName;
5256     Section.getName(SectName);
5257     Sections.push_back(Section);
5258   }
5259 
5260   struct DisassembleInfo info;
5261   // Set up the block of info used by the Symbolizer call backs.
5262   info.verbose = verbose;
5263   info.O = O;
5264   info.AddrMap = &AddrMap;
5265   info.Sections = &Sections;
5266   info.class_name = nullptr;
5267   info.selector_name = nullptr;
5268   info.method = nullptr;
5269   info.demangled_name = nullptr;
5270   info.bindtable = nullptr;
5271   info.adrp_addr = 0;
5272   info.adrp_inst = 0;
5273 
5274   info.depth = 0;
5275   SectionRef CL = get_section(O, "__OBJC2", "__class_list");
5276   if (CL == SectionRef())
5277     CL = get_section(O, "__DATA", "__objc_classlist");
5278   if (CL == SectionRef())
5279     CL = get_section(O, "__DATA_CONST", "__objc_classlist");
5280   if (CL == SectionRef())
5281     CL = get_section(O, "__DATA_DIRTY", "__objc_classlist");
5282   info.S = CL;
5283   walk_pointer_list_64("class", CL, O, &info, print_class64_t);
5284 
5285   SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
5286   if (CR == SectionRef())
5287     CR = get_section(O, "__DATA", "__objc_classrefs");
5288   if (CR == SectionRef())
5289     CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
5290   if (CR == SectionRef())
5291     CR = get_section(O, "__DATA_DIRTY", "__objc_classrefs");
5292   info.S = CR;
5293   walk_pointer_list_64("class refs", CR, O, &info, nullptr);
5294 
5295   SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
5296   if (SR == SectionRef())
5297     SR = get_section(O, "__DATA", "__objc_superrefs");
5298   if (SR == SectionRef())
5299     SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
5300   if (SR == SectionRef())
5301     SR = get_section(O, "__DATA_DIRTY", "__objc_superrefs");
5302   info.S = SR;
5303   walk_pointer_list_64("super refs", SR, O, &info, nullptr);
5304 
5305   SectionRef CA = get_section(O, "__OBJC2", "__category_list");
5306   if (CA == SectionRef())
5307     CA = get_section(O, "__DATA", "__objc_catlist");
5308   if (CA == SectionRef())
5309     CA = get_section(O, "__DATA_CONST", "__objc_catlist");
5310   if (CA == SectionRef())
5311     CA = get_section(O, "__DATA_DIRTY", "__objc_catlist");
5312   info.S = CA;
5313   walk_pointer_list_64("category", CA, O, &info, print_category64_t);
5314 
5315   SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
5316   if (PL == SectionRef())
5317     PL = get_section(O, "__DATA", "__objc_protolist");
5318   if (PL == SectionRef())
5319     PL = get_section(O, "__DATA_CONST", "__objc_protolist");
5320   if (PL == SectionRef())
5321     PL = get_section(O, "__DATA_DIRTY", "__objc_protolist");
5322   info.S = PL;
5323   walk_pointer_list_64("protocol", PL, O, &info, nullptr);
5324 
5325   SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
5326   if (MR == SectionRef())
5327     MR = get_section(O, "__DATA", "__objc_msgrefs");
5328   if (MR == SectionRef())
5329     MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
5330   if (MR == SectionRef())
5331     MR = get_section(O, "__DATA_DIRTY", "__objc_msgrefs");
5332   info.S = MR;
5333   print_message_refs64(MR, &info);
5334 
5335   SectionRef II = get_section(O, "__OBJC2", "__image_info");
5336   if (II == SectionRef())
5337     II = get_section(O, "__DATA", "__objc_imageinfo");
5338   if (II == SectionRef())
5339     II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
5340   if (II == SectionRef())
5341     II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
5342   info.S = II;
5343   print_image_info64(II, &info);
5344 }
5345 
5346 static void printObjc2_32bit_MetaData(MachOObjectFile *O, bool verbose) {
5347   SymbolAddressMap AddrMap;
5348   if (verbose)
5349     CreateSymbolAddressMap(O, &AddrMap);
5350 
5351   std::vector<SectionRef> Sections;
5352   for (const SectionRef &Section : O->sections()) {
5353     StringRef SectName;
5354     Section.getName(SectName);
5355     Sections.push_back(Section);
5356   }
5357 
5358   struct DisassembleInfo info;
5359   // Set up the block of info used by the Symbolizer call backs.
5360   info.verbose = verbose;
5361   info.O = O;
5362   info.AddrMap = &AddrMap;
5363   info.Sections = &Sections;
5364   info.class_name = nullptr;
5365   info.selector_name = nullptr;
5366   info.method = nullptr;
5367   info.demangled_name = nullptr;
5368   info.bindtable = nullptr;
5369   info.adrp_addr = 0;
5370   info.adrp_inst = 0;
5371 
5372   SectionRef CL = get_section(O, "__OBJC2", "__class_list");
5373   if (CL == SectionRef())
5374     CL = get_section(O, "__DATA", "__objc_classlist");
5375   if (CL == SectionRef())
5376     CL = get_section(O, "__DATA_CONST", "__objc_classlist");
5377   if (CL == SectionRef())
5378     CL = get_section(O, "__DATA_DIRTY", "__objc_classlist");
5379   info.S = CL;
5380   walk_pointer_list_32("class", CL, O, &info, print_class32_t);
5381 
5382   SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
5383   if (CR == SectionRef())
5384     CR = get_section(O, "__DATA", "__objc_classrefs");
5385   if (CR == SectionRef())
5386     CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
5387   if (CR == SectionRef())
5388     CR = get_section(O, "__DATA_DIRTY", "__objc_classrefs");
5389   info.S = CR;
5390   walk_pointer_list_32("class refs", CR, O, &info, nullptr);
5391 
5392   SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
5393   if (SR == SectionRef())
5394     SR = get_section(O, "__DATA", "__objc_superrefs");
5395   if (SR == SectionRef())
5396     SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
5397   if (SR == SectionRef())
5398     SR = get_section(O, "__DATA_DIRTY", "__objc_superrefs");
5399   info.S = SR;
5400   walk_pointer_list_32("super refs", SR, O, &info, nullptr);
5401 
5402   SectionRef CA = get_section(O, "__OBJC2", "__category_list");
5403   if (CA == SectionRef())
5404     CA = get_section(O, "__DATA", "__objc_catlist");
5405   if (CA == SectionRef())
5406     CA = get_section(O, "__DATA_CONST", "__objc_catlist");
5407   if (CA == SectionRef())
5408     CA = get_section(O, "__DATA_DIRTY", "__objc_catlist");
5409   info.S = CA;
5410   walk_pointer_list_32("category", CA, O, &info, print_category32_t);
5411 
5412   SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
5413   if (PL == SectionRef())
5414     PL = get_section(O, "__DATA", "__objc_protolist");
5415   if (PL == SectionRef())
5416     PL = get_section(O, "__DATA_CONST", "__objc_protolist");
5417   if (PL == SectionRef())
5418     PL = get_section(O, "__DATA_DIRTY", "__objc_protolist");
5419   info.S = PL;
5420   walk_pointer_list_32("protocol", PL, O, &info, nullptr);
5421 
5422   SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
5423   if (MR == SectionRef())
5424     MR = get_section(O, "__DATA", "__objc_msgrefs");
5425   if (MR == SectionRef())
5426     MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
5427   if (MR == SectionRef())
5428     MR = get_section(O, "__DATA_DIRTY", "__objc_msgrefs");
5429   info.S = MR;
5430   print_message_refs32(MR, &info);
5431 
5432   SectionRef II = get_section(O, "__OBJC2", "__image_info");
5433   if (II == SectionRef())
5434     II = get_section(O, "__DATA", "__objc_imageinfo");
5435   if (II == SectionRef())
5436     II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
5437   if (II == SectionRef())
5438     II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
5439   info.S = II;
5440   print_image_info32(II, &info);
5441 }
5442 
5443 static bool printObjc1_32bit_MetaData(MachOObjectFile *O, bool verbose) {
5444   uint32_t i, j, p, offset, xoffset, left, defs_left, def;
5445   const char *r, *name, *defs;
5446   struct objc_module_t module;
5447   SectionRef S, xS;
5448   struct objc_symtab_t symtab;
5449   struct objc_class_t objc_class;
5450   struct objc_category_t objc_category;
5451 
5452   outs() << "Objective-C segment\n";
5453   S = get_section(O, "__OBJC", "__module_info");
5454   if (S == SectionRef())
5455     return false;
5456 
5457   SymbolAddressMap AddrMap;
5458   if (verbose)
5459     CreateSymbolAddressMap(O, &AddrMap);
5460 
5461   std::vector<SectionRef> Sections;
5462   for (const SectionRef &Section : O->sections()) {
5463     StringRef SectName;
5464     Section.getName(SectName);
5465     Sections.push_back(Section);
5466   }
5467 
5468   struct DisassembleInfo info;
5469   // Set up the block of info used by the Symbolizer call backs.
5470   info.verbose = verbose;
5471   info.O = O;
5472   info.AddrMap = &AddrMap;
5473   info.Sections = &Sections;
5474   info.class_name = nullptr;
5475   info.selector_name = nullptr;
5476   info.method = nullptr;
5477   info.demangled_name = nullptr;
5478   info.bindtable = nullptr;
5479   info.adrp_addr = 0;
5480   info.adrp_inst = 0;
5481 
5482   for (i = 0; i < S.getSize(); i += sizeof(struct objc_module_t)) {
5483     p = S.getAddress() + i;
5484     r = get_pointer_32(p, offset, left, S, &info, true);
5485     if (r == nullptr)
5486       return true;
5487     memset(&module, '\0', sizeof(struct objc_module_t));
5488     if (left < sizeof(struct objc_module_t)) {
5489       memcpy(&module, r, left);
5490       outs() << "   (module extends past end of __module_info section)\n";
5491     } else
5492       memcpy(&module, r, sizeof(struct objc_module_t));
5493     if (O->isLittleEndian() != sys::IsLittleEndianHost)
5494       swapStruct(module);
5495 
5496     outs() << "Module " << format("0x%" PRIx32, p) << "\n";
5497     outs() << "    version " << module.version << "\n";
5498     outs() << "       size " << module.size << "\n";
5499     outs() << "       name ";
5500     name = get_pointer_32(module.name, xoffset, left, xS, &info, true);
5501     if (name != nullptr)
5502       outs() << format("%.*s", left, name);
5503     else
5504       outs() << format("0x%08" PRIx32, module.name)
5505              << "(not in an __OBJC section)";
5506     outs() << "\n";
5507 
5508     r = get_pointer_32(module.symtab, xoffset, left, xS, &info, true);
5509     if (module.symtab == 0 || r == nullptr) {
5510       outs() << "     symtab " << format("0x%08" PRIx32, module.symtab)
5511              << " (not in an __OBJC section)\n";
5512       continue;
5513     }
5514     outs() << "     symtab " << format("0x%08" PRIx32, module.symtab) << "\n";
5515     memset(&symtab, '\0', sizeof(struct objc_symtab_t));
5516     defs_left = 0;
5517     defs = nullptr;
5518     if (left < sizeof(struct objc_symtab_t)) {
5519       memcpy(&symtab, r, left);
5520       outs() << "\tsymtab extends past end of an __OBJC section)\n";
5521     } else {
5522       memcpy(&symtab, r, sizeof(struct objc_symtab_t));
5523       if (left > sizeof(struct objc_symtab_t)) {
5524         defs_left = left - sizeof(struct objc_symtab_t);
5525         defs = r + sizeof(struct objc_symtab_t);
5526       }
5527     }
5528     if (O->isLittleEndian() != sys::IsLittleEndianHost)
5529       swapStruct(symtab);
5530 
5531     outs() << "\tsel_ref_cnt " << symtab.sel_ref_cnt << "\n";
5532     r = get_pointer_32(symtab.refs, xoffset, left, xS, &info, true);
5533     outs() << "\trefs " << format("0x%08" PRIx32, symtab.refs);
5534     if (r == nullptr)
5535       outs() << " (not in an __OBJC section)";
5536     outs() << "\n";
5537     outs() << "\tcls_def_cnt " << symtab.cls_def_cnt << "\n";
5538     outs() << "\tcat_def_cnt " << symtab.cat_def_cnt << "\n";
5539     if (symtab.cls_def_cnt > 0)
5540       outs() << "\tClass Definitions\n";
5541     for (j = 0; j < symtab.cls_def_cnt; j++) {
5542       if ((j + 1) * sizeof(uint32_t) > defs_left) {
5543         outs() << "\t(remaining class defs entries entends past the end of the "
5544                << "section)\n";
5545         break;
5546       }
5547       memcpy(&def, defs + j * sizeof(uint32_t), sizeof(uint32_t));
5548       if (O->isLittleEndian() != sys::IsLittleEndianHost)
5549         sys::swapByteOrder(def);
5550 
5551       r = get_pointer_32(def, xoffset, left, xS, &info, true);
5552       outs() << "\tdefs[" << j << "] " << format("0x%08" PRIx32, def);
5553       if (r != nullptr) {
5554         if (left > sizeof(struct objc_class_t)) {
5555           outs() << "\n";
5556           memcpy(&objc_class, r, sizeof(struct objc_class_t));
5557         } else {
5558           outs() << " (entends past the end of the section)\n";
5559           memset(&objc_class, '\0', sizeof(struct objc_class_t));
5560           memcpy(&objc_class, r, left);
5561         }
5562         if (O->isLittleEndian() != sys::IsLittleEndianHost)
5563           swapStruct(objc_class);
5564         print_objc_class_t(&objc_class, &info);
5565       } else {
5566         outs() << "(not in an __OBJC section)\n";
5567       }
5568 
5569       if (CLS_GETINFO(&objc_class, CLS_CLASS)) {
5570         outs() << "\tMeta Class";
5571         r = get_pointer_32(objc_class.isa, xoffset, left, xS, &info, true);
5572         if (r != nullptr) {
5573           if (left > sizeof(struct objc_class_t)) {
5574             outs() << "\n";
5575             memcpy(&objc_class, r, sizeof(struct objc_class_t));
5576           } else {
5577             outs() << " (entends past the end of the section)\n";
5578             memset(&objc_class, '\0', sizeof(struct objc_class_t));
5579             memcpy(&objc_class, r, left);
5580           }
5581           if (O->isLittleEndian() != sys::IsLittleEndianHost)
5582             swapStruct(objc_class);
5583           print_objc_class_t(&objc_class, &info);
5584         } else {
5585           outs() << "(not in an __OBJC section)\n";
5586         }
5587       }
5588     }
5589     if (symtab.cat_def_cnt > 0)
5590       outs() << "\tCategory Definitions\n";
5591     for (j = 0; j < symtab.cat_def_cnt; j++) {
5592       if ((j + symtab.cls_def_cnt + 1) * sizeof(uint32_t) > defs_left) {
5593         outs() << "\t(remaining category defs entries entends past the end of "
5594                << "the section)\n";
5595         break;
5596       }
5597       memcpy(&def, defs + (j + symtab.cls_def_cnt) * sizeof(uint32_t),
5598              sizeof(uint32_t));
5599       if (O->isLittleEndian() != sys::IsLittleEndianHost)
5600         sys::swapByteOrder(def);
5601 
5602       r = get_pointer_32(def, xoffset, left, xS, &info, true);
5603       outs() << "\tdefs[" << j + symtab.cls_def_cnt << "] "
5604              << format("0x%08" PRIx32, def);
5605       if (r != nullptr) {
5606         if (left > sizeof(struct objc_category_t)) {
5607           outs() << "\n";
5608           memcpy(&objc_category, r, sizeof(struct objc_category_t));
5609         } else {
5610           outs() << " (entends past the end of the section)\n";
5611           memset(&objc_category, '\0', sizeof(struct objc_category_t));
5612           memcpy(&objc_category, r, left);
5613         }
5614         if (O->isLittleEndian() != sys::IsLittleEndianHost)
5615           swapStruct(objc_category);
5616         print_objc_objc_category_t(&objc_category, &info);
5617       } else {
5618         outs() << "(not in an __OBJC section)\n";
5619       }
5620     }
5621   }
5622   const SectionRef II = get_section(O, "__OBJC", "__image_info");
5623   if (II != SectionRef())
5624     print_image_info(II, &info);
5625 
5626   return true;
5627 }
5628 
5629 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,
5630                                 uint32_t size, uint32_t addr) {
5631   SymbolAddressMap AddrMap;
5632   CreateSymbolAddressMap(O, &AddrMap);
5633 
5634   std::vector<SectionRef> Sections;
5635   for (const SectionRef &Section : O->sections()) {
5636     StringRef SectName;
5637     Section.getName(SectName);
5638     Sections.push_back(Section);
5639   }
5640 
5641   struct DisassembleInfo info;
5642   // Set up the block of info used by the Symbolizer call backs.
5643   info.verbose = true;
5644   info.O = O;
5645   info.AddrMap = &AddrMap;
5646   info.Sections = &Sections;
5647   info.class_name = nullptr;
5648   info.selector_name = nullptr;
5649   info.method = nullptr;
5650   info.demangled_name = nullptr;
5651   info.bindtable = nullptr;
5652   info.adrp_addr = 0;
5653   info.adrp_inst = 0;
5654 
5655   const char *p;
5656   struct objc_protocol_t protocol;
5657   uint32_t left, paddr;
5658   for (p = sect; p < sect + size; p += sizeof(struct objc_protocol_t)) {
5659     memset(&protocol, '\0', sizeof(struct objc_protocol_t));
5660     left = size - (p - sect);
5661     if (left < sizeof(struct objc_protocol_t)) {
5662       outs() << "Protocol extends past end of __protocol section\n";
5663       memcpy(&protocol, p, left);
5664     } else
5665       memcpy(&protocol, p, sizeof(struct objc_protocol_t));
5666     if (O->isLittleEndian() != sys::IsLittleEndianHost)
5667       swapStruct(protocol);
5668     paddr = addr + (p - sect);
5669     outs() << "Protocol " << format("0x%" PRIx32, paddr);
5670     if (print_protocol(paddr, 0, &info))
5671       outs() << "(not in an __OBJC section)\n";
5672   }
5673 }
5674 
5675 #ifdef HAVE_LIBXAR
5676 inline void swapStruct(struct xar_header &xar) {
5677   sys::swapByteOrder(xar.magic);
5678   sys::swapByteOrder(xar.size);
5679   sys::swapByteOrder(xar.version);
5680   sys::swapByteOrder(xar.toc_length_compressed);
5681   sys::swapByteOrder(xar.toc_length_uncompressed);
5682   sys::swapByteOrder(xar.cksum_alg);
5683 }
5684 
5685 static void PrintModeVerbose(uint32_t mode) {
5686   switch(mode & S_IFMT){
5687   case S_IFDIR:
5688     outs() << "d";
5689     break;
5690   case S_IFCHR:
5691     outs() << "c";
5692     break;
5693   case S_IFBLK:
5694     outs() << "b";
5695     break;
5696   case S_IFREG:
5697     outs() << "-";
5698     break;
5699   case S_IFLNK:
5700     outs() << "l";
5701     break;
5702   case S_IFSOCK:
5703     outs() << "s";
5704     break;
5705   default:
5706     outs() << "?";
5707     break;
5708   }
5709 
5710   /* owner permissions */
5711   if(mode & S_IREAD)
5712     outs() << "r";
5713   else
5714     outs() << "-";
5715   if(mode & S_IWRITE)
5716     outs() << "w";
5717   else
5718     outs() << "-";
5719   if(mode & S_ISUID)
5720     outs() << "s";
5721   else if(mode & S_IEXEC)
5722     outs() << "x";
5723   else
5724     outs() << "-";
5725 
5726   /* group permissions */
5727   if(mode & (S_IREAD >> 3))
5728     outs() << "r";
5729   else
5730     outs() << "-";
5731   if(mode & (S_IWRITE >> 3))
5732     outs() << "w";
5733   else
5734     outs() << "-";
5735   if(mode & S_ISGID)
5736     outs() << "s";
5737   else if(mode & (S_IEXEC >> 3))
5738     outs() << "x";
5739   else
5740     outs() << "-";
5741 
5742   /* other permissions */
5743   if(mode & (S_IREAD >> 6))
5744     outs() << "r";
5745   else
5746     outs() << "-";
5747   if(mode & (S_IWRITE >> 6))
5748     outs() << "w";
5749   else
5750     outs() << "-";
5751   if(mode & S_ISVTX)
5752     outs() << "t";
5753   else if(mode & (S_IEXEC >> 6))
5754     outs() << "x";
5755   else
5756     outs() << "-";
5757 }
5758 
5759 static void PrintXarFilesSummary(const char *XarFilename, xar_t xar) {
5760   xar_iter_t xi;
5761   xar_file_t xf;
5762   xar_iter_t xp;
5763   const char *key, *type, *mode, *user, *group, *size, *mtime, *name, *m;
5764   char *endp;
5765   uint32_t mode_value;
5766 
5767   xi = xar_iter_new();
5768   if (!xi) {
5769     errs() << "Can't obtain an xar iterator for xar archive "
5770            << XarFilename << "\n";
5771     return;
5772   }
5773 
5774   // Go through the xar's files.
5775   for (xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)) {
5776     xp = xar_iter_new();
5777     if(!xp){
5778       errs() << "Can't obtain an xar iterator for xar archive "
5779              << XarFilename << "\n";
5780       return;
5781     }
5782     type = nullptr;
5783     mode = nullptr;
5784     user = nullptr;
5785     group = nullptr;
5786     size = nullptr;
5787     mtime = nullptr;
5788     name = nullptr;
5789     for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
5790       const char *val = nullptr;
5791       xar_prop_get(xf, key, &val);
5792 #if 0 // Useful for debugging.
5793       outs() << "key: " << key << " value: " << val << "\n";
5794 #endif
5795       if(strcmp(key, "type") == 0)
5796         type = val;
5797       if(strcmp(key, "mode") == 0)
5798         mode = val;
5799       if(strcmp(key, "user") == 0)
5800         user = val;
5801       if(strcmp(key, "group") == 0)
5802         group = val;
5803       if(strcmp(key, "data/size") == 0)
5804         size = val;
5805       if(strcmp(key, "mtime") == 0)
5806         mtime = val;
5807       if(strcmp(key, "name") == 0)
5808         name = val;
5809     }
5810     if(mode != nullptr){
5811       mode_value = strtoul(mode, &endp, 8);
5812       if(*endp != '\0')
5813         outs() << "(mode: \"" << mode << "\" contains non-octal chars) ";
5814       if(strcmp(type, "file") == 0)
5815         mode_value |= S_IFREG;
5816       PrintModeVerbose(mode_value);
5817       outs() << " ";
5818     }
5819     if(user != nullptr)
5820       outs() << format("%10s/", user);
5821     if(group != nullptr)
5822       outs() << format("%-10s ", group);
5823     if(size != nullptr)
5824       outs() << format("%7s ", size);
5825     if(mtime != nullptr){
5826       for(m = mtime; *m != 'T' && *m != '\0'; m++)
5827         outs() << *m;
5828       if(*m == 'T')
5829         m++;
5830       outs() << " ";
5831       for( ; *m != 'Z' && *m != '\0'; m++)
5832         outs() << *m;
5833       outs() << " ";
5834     }
5835     if(name != nullptr)
5836       outs() << name;
5837     outs() << "\n";
5838   }
5839 }
5840 
5841 static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
5842                                 uint32_t size, bool verbose,
5843                                 bool PrintXarHeader, bool PrintXarFileHeaders,
5844                                 std::string XarMemberName) {
5845   if(size < sizeof(struct xar_header)) {
5846     outs() << "size of (__LLVM,__bundle) section too small (smaller than size "
5847               "of struct xar_header)\n";
5848     return;
5849   }
5850   struct xar_header XarHeader;
5851   memcpy(&XarHeader, sect, sizeof(struct xar_header));
5852   if (sys::IsLittleEndianHost)
5853     swapStruct(XarHeader);
5854   if (PrintXarHeader) {
5855     if (!XarMemberName.empty())
5856       outs() << "In xar member " << XarMemberName << ": ";
5857     else
5858       outs() << "For (__LLVM,__bundle) section: ";
5859     outs() << "xar header\n";
5860     if (XarHeader.magic == XAR_HEADER_MAGIC)
5861       outs() << "                  magic XAR_HEADER_MAGIC\n";
5862     else
5863       outs() << "                  magic "
5864              << format_hex(XarHeader.magic, 10, true)
5865              << " (not XAR_HEADER_MAGIC)\n";
5866     outs() << "                   size " << XarHeader.size << "\n";
5867     outs() << "                version " << XarHeader.version << "\n";
5868     outs() << "  toc_length_compressed " << XarHeader.toc_length_compressed
5869            << "\n";
5870     outs() << "toc_length_uncompressed " << XarHeader.toc_length_uncompressed
5871            << "\n";
5872     outs() << "              cksum_alg ";
5873     switch (XarHeader.cksum_alg) {
5874       case XAR_CKSUM_NONE:
5875         outs() << "XAR_CKSUM_NONE\n";
5876         break;
5877       case XAR_CKSUM_SHA1:
5878         outs() << "XAR_CKSUM_SHA1\n";
5879         break;
5880       case XAR_CKSUM_MD5:
5881         outs() << "XAR_CKSUM_MD5\n";
5882         break;
5883 #ifdef XAR_CKSUM_SHA256
5884       case XAR_CKSUM_SHA256:
5885         outs() << "XAR_CKSUM_SHA256\n";
5886         break;
5887 #endif
5888 #ifdef XAR_CKSUM_SHA512
5889       case XAR_CKSUM_SHA512:
5890         outs() << "XAR_CKSUM_SHA512\n";
5891         break;
5892 #endif
5893       default:
5894         outs() << XarHeader.cksum_alg << "\n";
5895     }
5896   }
5897 
5898   SmallString<128> XarFilename;
5899   int FD;
5900   std::error_code XarEC =
5901       sys::fs::createTemporaryFile("llvm-objdump", "xar", FD, XarFilename);
5902   if (XarEC) {
5903     errs() << XarEC.message() << "\n";
5904     return;
5905   }
5906   tool_output_file XarFile(XarFilename, FD);
5907   raw_fd_ostream &XarOut = XarFile.os();
5908   StringRef XarContents(sect, size);
5909   XarOut << XarContents;
5910   XarOut.close();
5911   if (XarOut.has_error())
5912     return;
5913 
5914   xar_t xar = xar_open(XarFilename.c_str(), READ);
5915   if (!xar) {
5916     errs() << "Can't create temporary xar archive " << XarFilename << "\n";
5917     return;
5918   }
5919 
5920   SmallString<128> TocFilename;
5921   std::error_code TocEC =
5922       sys::fs::createTemporaryFile("llvm-objdump", "toc", TocFilename);
5923   if (TocEC) {
5924     errs() << TocEC.message() << "\n";
5925     return;
5926   }
5927   xar_serialize(xar, TocFilename.c_str());
5928 
5929   if (PrintXarFileHeaders) {
5930     if (!XarMemberName.empty())
5931       outs() << "In xar member " << XarMemberName << ": ";
5932     else
5933       outs() << "For (__LLVM,__bundle) section: ";
5934     outs() << "xar archive files:\n";
5935     PrintXarFilesSummary(XarFilename.c_str(), xar);
5936   }
5937 
5938   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
5939     MemoryBuffer::getFileOrSTDIN(TocFilename.c_str());
5940   if (std::error_code EC = FileOrErr.getError()) {
5941     errs() << EC.message() << "\n";
5942     return;
5943   }
5944   std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
5945 
5946   if (!XarMemberName.empty())
5947     outs() << "In xar member " << XarMemberName << ": ";
5948   else
5949     outs() << "For (__LLVM,__bundle) section: ";
5950   outs() << "xar table of contents:\n";
5951   outs() << Buffer->getBuffer() << "\n";
5952 
5953   // TODO: Go through the xar's files.
5954   xar_iter_t xi = xar_iter_new();
5955   if(!xi){
5956     errs() << "Can't obtain an xar iterator for xar archive "
5957            << XarFilename.c_str() << "\n";
5958     xar_close(xar);
5959     return;
5960   }
5961   for(xar_file_t xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)){
5962     const char *key;
5963     xar_iter_t xp;
5964     const char *member_name, *member_type, *member_size_string;
5965     size_t member_size;
5966 
5967     xp = xar_iter_new();
5968     if(!xp){
5969       errs() << "Can't obtain an xar iterator for xar archive "
5970 	     << XarFilename.c_str() << "\n";
5971       xar_close(xar);
5972       return;
5973     }
5974     member_name = NULL;
5975     member_type = NULL;
5976     member_size_string = NULL;
5977     for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
5978       const char *val = nullptr;
5979       xar_prop_get(xf, key, &val);
5980 #if 0 // Useful for debugging.
5981       outs() << "key: " << key << " value: " << val << "\n";
5982 #endif
5983       if(strcmp(key, "name") == 0)
5984 	member_name = val;
5985       if(strcmp(key, "type") == 0)
5986 	member_type = val;
5987       if(strcmp(key, "data/size") == 0)
5988 	member_size_string = val;
5989     }
5990     /*
5991      * If we find a file with a name, date/size and type properties
5992      * and with the type being "file" see if that is a xar file.
5993      */
5994     if (member_name != NULL && member_type != NULL &&
5995         strcmp(member_type, "file") == 0 &&
5996         member_size_string != NULL){
5997       // Extract the file into a buffer.
5998       char *endptr;
5999       member_size = strtoul(member_size_string, &endptr, 10);
6000       if (*endptr == '\0' && member_size != 0) {
6001 	char *buffer = (char *) ::operator new (member_size);
6002 	if (xar_extract_tobuffersz(xar, xf, &buffer, &member_size) == 0) {
6003 #if 0 // Useful for debugging.
6004 	  outs() << "xar member: " << member_name << " extracted\n";
6005 #endif
6006           // Set the XarMemberName we want to see printed in the header.
6007 	  std::string OldXarMemberName;
6008 	  // If XarMemberName is already set this is nested. So
6009 	  // save the old name and create the nested name.
6010 	  if (!XarMemberName.empty()) {
6011 	    OldXarMemberName = XarMemberName;
6012             XarMemberName =
6013              (Twine("[") + XarMemberName + "]" + member_name).str();
6014 	  } else {
6015 	    OldXarMemberName = "";
6016 	    XarMemberName = member_name;
6017 	  }
6018 	  // See if this is could be a xar file (nested).
6019 	  if (member_size >= sizeof(struct xar_header)) {
6020 #if 0 // Useful for debugging.
6021 	    outs() << "could be a xar file: " << member_name << "\n";
6022 #endif
6023 	    memcpy((char *)&XarHeader, buffer, sizeof(struct xar_header));
6024             if (sys::IsLittleEndianHost)
6025 	      swapStruct(XarHeader);
6026 	    if(XarHeader.magic == XAR_HEADER_MAGIC)
6027 	      DumpBitcodeSection(O, buffer, member_size, verbose,
6028                                  PrintXarHeader, PrintXarFileHeaders,
6029 		                 XarMemberName);
6030 	  }
6031 	  XarMemberName = OldXarMemberName;
6032 	}
6033         delete buffer;
6034       }
6035     }
6036     xar_iter_free(xp);
6037   }
6038   xar_close(xar);
6039 }
6040 #endif // defined(HAVE_LIBXAR)
6041 
6042 static void printObjcMetaData(MachOObjectFile *O, bool verbose) {
6043   if (O->is64Bit())
6044     printObjc2_64bit_MetaData(O, verbose);
6045   else {
6046     MachO::mach_header H;
6047     H = O->getHeader();
6048     if (H.cputype == MachO::CPU_TYPE_ARM)
6049       printObjc2_32bit_MetaData(O, verbose);
6050     else {
6051       // This is the 32-bit non-arm cputype case.  Which is normally
6052       // the first Objective-C ABI.  But it may be the case of a
6053       // binary for the iOS simulator which is the second Objective-C
6054       // ABI.  In that case printObjc1_32bit_MetaData() will determine that
6055       // and return false.
6056       if (!printObjc1_32bit_MetaData(O, verbose))
6057         printObjc2_32bit_MetaData(O, verbose);
6058     }
6059   }
6060 }
6061 
6062 // GuessLiteralPointer returns a string which for the item in the Mach-O file
6063 // for the address passed in as ReferenceValue for printing as a comment with
6064 // the instruction and also returns the corresponding type of that item
6065 // indirectly through ReferenceType.
6066 //
6067 // If ReferenceValue is an address of literal cstring then a pointer to the
6068 // cstring is returned and ReferenceType is set to
6069 // LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr .
6070 //
6071 // If ReferenceValue is an address of an Objective-C CFString, Selector ref or
6072 // Class ref that name is returned and the ReferenceType is set accordingly.
6073 //
6074 // Lastly, literals which are Symbol address in a literal pool are looked for
6075 // and if found the symbol name is returned and ReferenceType is set to
6076 // LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr .
6077 //
6078 // If there is no item in the Mach-O file for the address passed in as
6079 // ReferenceValue nullptr is returned and ReferenceType is unchanged.
6080 static const char *GuessLiteralPointer(uint64_t ReferenceValue,
6081                                        uint64_t ReferencePC,
6082                                        uint64_t *ReferenceType,
6083                                        struct DisassembleInfo *info) {
6084   // First see if there is an external relocation entry at the ReferencePC.
6085   if (info->O->getHeader().filetype == MachO::MH_OBJECT) {
6086     uint64_t sect_addr = info->S.getAddress();
6087     uint64_t sect_offset = ReferencePC - sect_addr;
6088     bool reloc_found = false;
6089     DataRefImpl Rel;
6090     MachO::any_relocation_info RE;
6091     bool isExtern = false;
6092     SymbolRef Symbol;
6093     for (const RelocationRef &Reloc : info->S.relocations()) {
6094       uint64_t RelocOffset = Reloc.getOffset();
6095       if (RelocOffset == sect_offset) {
6096         Rel = Reloc.getRawDataRefImpl();
6097         RE = info->O->getRelocation(Rel);
6098         if (info->O->isRelocationScattered(RE))
6099           continue;
6100         isExtern = info->O->getPlainRelocationExternal(RE);
6101         if (isExtern) {
6102           symbol_iterator RelocSym = Reloc.getSymbol();
6103           Symbol = *RelocSym;
6104         }
6105         reloc_found = true;
6106         break;
6107       }
6108     }
6109     // If there is an external relocation entry for a symbol in a section
6110     // then used that symbol's value for the value of the reference.
6111     if (reloc_found && isExtern) {
6112       if (info->O->getAnyRelocationPCRel(RE)) {
6113         unsigned Type = info->O->getAnyRelocationType(RE);
6114         if (Type == MachO::X86_64_RELOC_SIGNED) {
6115           ReferenceValue = Symbol.getValue();
6116         }
6117       }
6118     }
6119   }
6120 
6121   // Look for literals such as Objective-C CFStrings refs, Selector refs,
6122   // Message refs and Class refs.
6123   bool classref, selref, msgref, cfstring;
6124   uint64_t pointer_value = GuessPointerPointer(ReferenceValue, info, classref,
6125                                                selref, msgref, cfstring);
6126   if (classref && pointer_value == 0) {
6127     // Note the ReferenceValue is a pointer into the __objc_classrefs section.
6128     // And the pointer_value in that section is typically zero as it will be
6129     // set by dyld as part of the "bind information".
6130     const char *name = get_dyld_bind_info_symbolname(ReferenceValue, info);
6131     if (name != nullptr) {
6132       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
6133       const char *class_name = strrchr(name, '$');
6134       if (class_name != nullptr && class_name[1] == '_' &&
6135           class_name[2] != '\0') {
6136         info->class_name = class_name + 2;
6137         return name;
6138       }
6139     }
6140   }
6141 
6142   if (classref) {
6143     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
6144     const char *name =
6145         get_objc2_64bit_class_name(pointer_value, ReferenceValue, info);
6146     if (name != nullptr)
6147       info->class_name = name;
6148     else
6149       name = "bad class ref";
6150     return name;
6151   }
6152 
6153   if (cfstring) {
6154     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref;
6155     const char *name = get_objc2_64bit_cfstring_name(ReferenceValue, info);
6156     return name;
6157   }
6158 
6159   if (selref && pointer_value == 0)
6160     pointer_value = get_objc2_64bit_selref(ReferenceValue, info);
6161 
6162   if (pointer_value != 0)
6163     ReferenceValue = pointer_value;
6164 
6165   const char *name = GuessCstringPointer(ReferenceValue, info);
6166   if (name) {
6167     if (pointer_value != 0 && selref) {
6168       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref;
6169       info->selector_name = name;
6170     } else if (pointer_value != 0 && msgref) {
6171       info->class_name = nullptr;
6172       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref;
6173       info->selector_name = name;
6174     } else
6175       *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr;
6176     return name;
6177   }
6178 
6179   // Lastly look for an indirect symbol with this ReferenceValue which is in
6180   // a literal pool.  If found return that symbol name.
6181   name = GuessIndirectSymbol(ReferenceValue, info);
6182   if (name) {
6183     *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr;
6184     return name;
6185   }
6186 
6187   return nullptr;
6188 }
6189 
6190 // SymbolizerSymbolLookUp is the symbol lookup function passed when creating
6191 // the Symbolizer.  It looks up the ReferenceValue using the info passed via the
6192 // pointer to the struct DisassembleInfo that was passed when MCSymbolizer
6193 // is created and returns the symbol name that matches the ReferenceValue or
6194 // nullptr if none.  The ReferenceType is passed in for the IN type of
6195 // reference the instruction is making from the values in defined in the header
6196 // "llvm-c/Disassembler.h".  On return the ReferenceType can set to a specific
6197 // Out type and the ReferenceName will also be set which is added as a comment
6198 // to the disassembled instruction.
6199 //
6200 // If the symbol name is a C++ mangled name then the demangled name is
6201 // returned through ReferenceName and ReferenceType is set to
6202 // LLVMDisassembler_ReferenceType_DeMangled_Name .
6203 //
6204 // When this is called to get a symbol name for a branch target then the
6205 // ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then
6206 // SymbolValue will be looked for in the indirect symbol table to determine if
6207 // it is an address for a symbol stub.  If so then the symbol name for that
6208 // stub is returned indirectly through ReferenceName and then ReferenceType is
6209 // set to LLVMDisassembler_ReferenceType_Out_SymbolStub.
6210 //
6211 // When this is called with an value loaded via a PC relative load then
6212 // ReferenceType will be LLVMDisassembler_ReferenceType_In_PCrel_Load then the
6213 // SymbolValue is checked to be an address of literal pointer, symbol pointer,
6214 // or an Objective-C meta data reference.  If so the output ReferenceType is
6215 // set to correspond to that as well as setting the ReferenceName.
6216 static const char *SymbolizerSymbolLookUp(void *DisInfo,
6217                                           uint64_t ReferenceValue,
6218                                           uint64_t *ReferenceType,
6219                                           uint64_t ReferencePC,
6220                                           const char **ReferenceName) {
6221   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
6222   // If no verbose symbolic information is wanted then just return nullptr.
6223   if (!info->verbose) {
6224     *ReferenceName = nullptr;
6225     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6226     return nullptr;
6227   }
6228 
6229   const char *SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
6230 
6231   if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
6232     *ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
6233     if (*ReferenceName != nullptr) {
6234       method_reference(info, ReferenceType, ReferenceName);
6235       if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message)
6236         *ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
6237     } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
6238       if (info->demangled_name != nullptr)
6239         free(info->demangled_name);
6240       int status;
6241       info->demangled_name =
6242           itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
6243       if (info->demangled_name != nullptr) {
6244         *ReferenceName = info->demangled_name;
6245         *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
6246       } else
6247         *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6248     } else
6249       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6250   } else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
6251     *ReferenceName =
6252         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
6253     if (*ReferenceName)
6254       method_reference(info, ReferenceType, ReferenceName);
6255     else
6256       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6257     // If this is arm64 and the reference is an adrp instruction save the
6258     // instruction, passed in ReferenceValue and the address of the instruction
6259     // for use later if we see and add immediate instruction.
6260   } else if (info->O->getArch() == Triple::aarch64 &&
6261              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
6262     info->adrp_inst = ReferenceValue;
6263     info->adrp_addr = ReferencePC;
6264     SymbolName = nullptr;
6265     *ReferenceName = nullptr;
6266     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6267     // If this is arm64 and reference is an add immediate instruction and we
6268     // have
6269     // seen an adrp instruction just before it and the adrp's Xd register
6270     // matches
6271     // this add's Xn register reconstruct the value being referenced and look to
6272     // see if it is a literal pointer.  Note the add immediate instruction is
6273     // passed in ReferenceValue.
6274   } else if (info->O->getArch() == Triple::aarch64 &&
6275              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
6276              ReferencePC - 4 == info->adrp_addr &&
6277              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
6278              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
6279     uint32_t addxri_inst;
6280     uint64_t adrp_imm, addxri_imm;
6281 
6282     adrp_imm =
6283         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
6284     if (info->adrp_inst & 0x0200000)
6285       adrp_imm |= 0xfffffffffc000000LL;
6286 
6287     addxri_inst = ReferenceValue;
6288     addxri_imm = (addxri_inst >> 10) & 0xfff;
6289     if (((addxri_inst >> 22) & 0x3) == 1)
6290       addxri_imm <<= 12;
6291 
6292     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
6293                      (adrp_imm << 12) + addxri_imm;
6294 
6295     *ReferenceName =
6296         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
6297     if (*ReferenceName == nullptr)
6298       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6299     // If this is arm64 and the reference is a load register instruction and we
6300     // have seen an adrp instruction just before it and the adrp's Xd register
6301     // matches this add's Xn register reconstruct the value being referenced and
6302     // look to see if it is a literal pointer.  Note the load register
6303     // instruction is passed in ReferenceValue.
6304   } else if (info->O->getArch() == Triple::aarch64 &&
6305              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXui &&
6306              ReferencePC - 4 == info->adrp_addr &&
6307              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
6308              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
6309     uint32_t ldrxui_inst;
6310     uint64_t adrp_imm, ldrxui_imm;
6311 
6312     adrp_imm =
6313         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
6314     if (info->adrp_inst & 0x0200000)
6315       adrp_imm |= 0xfffffffffc000000LL;
6316 
6317     ldrxui_inst = ReferenceValue;
6318     ldrxui_imm = (ldrxui_inst >> 10) & 0xfff;
6319 
6320     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
6321                      (adrp_imm << 12) + (ldrxui_imm << 3);
6322 
6323     *ReferenceName =
6324         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
6325     if (*ReferenceName == nullptr)
6326       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6327   }
6328   // If this arm64 and is an load register (PC-relative) instruction the
6329   // ReferenceValue is the PC plus the immediate value.
6330   else if (info->O->getArch() == Triple::aarch64 &&
6331            (*ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXl ||
6332             *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADR)) {
6333     *ReferenceName =
6334         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
6335     if (*ReferenceName == nullptr)
6336       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6337   } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
6338     if (info->demangled_name != nullptr)
6339       free(info->demangled_name);
6340     int status;
6341     info->demangled_name =
6342         itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
6343     if (info->demangled_name != nullptr) {
6344       *ReferenceName = info->demangled_name;
6345       *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
6346     }
6347   }
6348   else {
6349     *ReferenceName = nullptr;
6350     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
6351   }
6352 
6353   return SymbolName;
6354 }
6355 
6356 /// \brief Emits the comments that are stored in the CommentStream.
6357 /// Each comment in the CommentStream must end with a newline.
6358 static void emitComments(raw_svector_ostream &CommentStream,
6359                          SmallString<128> &CommentsToEmit,
6360                          formatted_raw_ostream &FormattedOS,
6361                          const MCAsmInfo &MAI) {
6362   // Flush the stream before taking its content.
6363   StringRef Comments = CommentsToEmit.str();
6364   // Get the default information for printing a comment.
6365   StringRef CommentBegin = MAI.getCommentString();
6366   unsigned CommentColumn = MAI.getCommentColumn();
6367   bool IsFirst = true;
6368   while (!Comments.empty()) {
6369     if (!IsFirst)
6370       FormattedOS << '\n';
6371     // Emit a line of comments.
6372     FormattedOS.PadToColumn(CommentColumn);
6373     size_t Position = Comments.find('\n');
6374     FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
6375     // Move after the newline character.
6376     Comments = Comments.substr(Position + 1);
6377     IsFirst = false;
6378   }
6379   FormattedOS.flush();
6380 
6381   // Tell the comment stream that the vector changed underneath it.
6382   CommentsToEmit.clear();
6383 }
6384 
6385 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
6386                              StringRef DisSegName, StringRef DisSectName) {
6387   const char *McpuDefault = nullptr;
6388   const Target *ThumbTarget = nullptr;
6389   const Target *TheTarget = GetTarget(MachOOF, &McpuDefault, &ThumbTarget);
6390   if (!TheTarget) {
6391     // GetTarget prints out stuff.
6392     return;
6393   }
6394   if (MCPU.empty() && McpuDefault)
6395     MCPU = McpuDefault;
6396 
6397   std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
6398   std::unique_ptr<const MCInstrInfo> ThumbInstrInfo;
6399   if (ThumbTarget)
6400     ThumbInstrInfo.reset(ThumbTarget->createMCInstrInfo());
6401 
6402   // Package up features to be passed to target/subtarget
6403   std::string FeaturesStr;
6404   if (MAttrs.size()) {
6405     SubtargetFeatures Features;
6406     for (unsigned i = 0; i != MAttrs.size(); ++i)
6407       Features.AddFeature(MAttrs[i]);
6408     FeaturesStr = Features.getString();
6409   }
6410 
6411   // Set up disassembler.
6412   std::unique_ptr<const MCRegisterInfo> MRI(
6413       TheTarget->createMCRegInfo(TripleName));
6414   std::unique_ptr<const MCAsmInfo> AsmInfo(
6415       TheTarget->createMCAsmInfo(*MRI, TripleName));
6416   std::unique_ptr<const MCSubtargetInfo> STI(
6417       TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
6418   MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr);
6419   std::unique_ptr<MCDisassembler> DisAsm(
6420       TheTarget->createMCDisassembler(*STI, Ctx));
6421   std::unique_ptr<MCSymbolizer> Symbolizer;
6422   struct DisassembleInfo SymbolizerInfo;
6423   std::unique_ptr<MCRelocationInfo> RelInfo(
6424       TheTarget->createMCRelocationInfo(TripleName, Ctx));
6425   if (RelInfo) {
6426     Symbolizer.reset(TheTarget->createMCSymbolizer(
6427         TripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
6428         &SymbolizerInfo, &Ctx, std::move(RelInfo)));
6429     DisAsm->setSymbolizer(std::move(Symbolizer));
6430   }
6431   int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
6432   std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
6433       Triple(TripleName), AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI));
6434   // Set the display preference for hex vs. decimal immediates.
6435   IP->setPrintImmHex(PrintImmHex);
6436   // Comment stream and backing vector.
6437   SmallString<128> CommentsToEmit;
6438   raw_svector_ostream CommentStream(CommentsToEmit);
6439   // FIXME: Setting the CommentStream in the InstPrinter is problematic in that
6440   // if it is done then arm64 comments for string literals don't get printed
6441   // and some constant get printed instead and not setting it causes intel
6442   // (32-bit and 64-bit) comments printed with different spacing before the
6443   // comment causing different diffs with the 'C' disassembler library API.
6444   // IP->setCommentStream(CommentStream);
6445 
6446   if (!AsmInfo || !STI || !DisAsm || !IP) {
6447     errs() << "error: couldn't initialize disassembler for target "
6448            << TripleName << '\n';
6449     return;
6450   }
6451 
6452   // Set up separate thumb disassembler if needed.
6453   std::unique_ptr<const MCRegisterInfo> ThumbMRI;
6454   std::unique_ptr<const MCAsmInfo> ThumbAsmInfo;
6455   std::unique_ptr<const MCSubtargetInfo> ThumbSTI;
6456   std::unique_ptr<MCDisassembler> ThumbDisAsm;
6457   std::unique_ptr<MCInstPrinter> ThumbIP;
6458   std::unique_ptr<MCContext> ThumbCtx;
6459   std::unique_ptr<MCSymbolizer> ThumbSymbolizer;
6460   struct DisassembleInfo ThumbSymbolizerInfo;
6461   std::unique_ptr<MCRelocationInfo> ThumbRelInfo;
6462   if (ThumbTarget) {
6463     ThumbMRI.reset(ThumbTarget->createMCRegInfo(ThumbTripleName));
6464     ThumbAsmInfo.reset(
6465         ThumbTarget->createMCAsmInfo(*ThumbMRI, ThumbTripleName));
6466     ThumbSTI.reset(
6467         ThumbTarget->createMCSubtargetInfo(ThumbTripleName, MCPU, FeaturesStr));
6468     ThumbCtx.reset(new MCContext(ThumbAsmInfo.get(), ThumbMRI.get(), nullptr));
6469     ThumbDisAsm.reset(ThumbTarget->createMCDisassembler(*ThumbSTI, *ThumbCtx));
6470     MCContext *PtrThumbCtx = ThumbCtx.get();
6471     ThumbRelInfo.reset(
6472         ThumbTarget->createMCRelocationInfo(ThumbTripleName, *PtrThumbCtx));
6473     if (ThumbRelInfo) {
6474       ThumbSymbolizer.reset(ThumbTarget->createMCSymbolizer(
6475           ThumbTripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
6476           &ThumbSymbolizerInfo, PtrThumbCtx, std::move(ThumbRelInfo)));
6477       ThumbDisAsm->setSymbolizer(std::move(ThumbSymbolizer));
6478     }
6479     int ThumbAsmPrinterVariant = ThumbAsmInfo->getAssemblerDialect();
6480     ThumbIP.reset(ThumbTarget->createMCInstPrinter(
6481         Triple(ThumbTripleName), ThumbAsmPrinterVariant, *ThumbAsmInfo,
6482         *ThumbInstrInfo, *ThumbMRI));
6483     // Set the display preference for hex vs. decimal immediates.
6484     ThumbIP->setPrintImmHex(PrintImmHex);
6485   }
6486 
6487   if (ThumbTarget && (!ThumbAsmInfo || !ThumbSTI || !ThumbDisAsm || !ThumbIP)) {
6488     errs() << "error: couldn't initialize disassembler for target "
6489            << ThumbTripleName << '\n';
6490     return;
6491   }
6492 
6493   MachO::mach_header Header = MachOOF->getHeader();
6494 
6495   // FIXME: Using the -cfg command line option, this code used to be able to
6496   // annotate relocations with the referenced symbol's name, and if this was
6497   // inside a __[cf]string section, the data it points to. This is now replaced
6498   // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
6499   std::vector<SectionRef> Sections;
6500   std::vector<SymbolRef> Symbols;
6501   SmallVector<uint64_t, 8> FoundFns;
6502   uint64_t BaseSegmentAddress;
6503 
6504   getSectionsAndSymbols(MachOOF, Sections, Symbols, FoundFns,
6505                         BaseSegmentAddress);
6506 
6507   // Sort the symbols by address, just in case they didn't come in that way.
6508   std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());
6509 
6510   // Build a data in code table that is sorted on by the address of each entry.
6511   uint64_t BaseAddress = 0;
6512   if (Header.filetype == MachO::MH_OBJECT)
6513     BaseAddress = Sections[0].getAddress();
6514   else
6515     BaseAddress = BaseSegmentAddress;
6516   DiceTable Dices;
6517   for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
6518        DI != DE; ++DI) {
6519     uint32_t Offset;
6520     DI->getOffset(Offset);
6521     Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
6522   }
6523   array_pod_sort(Dices.begin(), Dices.end());
6524 
6525 #ifndef NDEBUG
6526   raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
6527 #else
6528   raw_ostream &DebugOut = nulls();
6529 #endif
6530 
6531   std::unique_ptr<DIContext> diContext;
6532   ObjectFile *DbgObj = MachOOF;
6533   // Try to find debug info and set up the DIContext for it.
6534   if (UseDbg) {
6535     // A separate DSym file path was specified, parse it as a macho file,
6536     // get the sections and supply it to the section name parsing machinery.
6537     if (!DSYMFile.empty()) {
6538       ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
6539           MemoryBuffer::getFileOrSTDIN(DSYMFile);
6540       if (std::error_code EC = BufOrErr.getError()) {
6541         errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n';
6542         return;
6543       }
6544       DbgObj =
6545           ObjectFile::createMachOObjectFile(BufOrErr.get()->getMemBufferRef())
6546               .get()
6547               .release();
6548     }
6549 
6550     // Setup the DIContext
6551     diContext.reset(new DWARFContextInMemory(*DbgObj));
6552   }
6553 
6554   if (FilterSections.size() == 0)
6555     outs() << "(" << DisSegName << "," << DisSectName << ") section\n";
6556 
6557   for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
6558     StringRef SectName;
6559     if (Sections[SectIdx].getName(SectName) || SectName != DisSectName)
6560       continue;
6561 
6562     DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
6563 
6564     StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
6565     if (SegmentName != DisSegName)
6566       continue;
6567 
6568     StringRef BytesStr;
6569     Sections[SectIdx].getContents(BytesStr);
6570     ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
6571                             BytesStr.size());
6572     uint64_t SectAddress = Sections[SectIdx].getAddress();
6573 
6574     bool symbolTableWorked = false;
6575 
6576     // Create a map of symbol addresses to symbol names for use by
6577     // the SymbolizerSymbolLookUp() routine.
6578     SymbolAddressMap AddrMap;
6579     bool DisSymNameFound = false;
6580     for (const SymbolRef &Symbol : MachOOF->symbols()) {
6581       Expected<SymbolRef::Type> STOrErr = Symbol.getType();
6582       if (!STOrErr)
6583         report_error(MachOOF->getFileName(), STOrErr.takeError());
6584       SymbolRef::Type ST = *STOrErr;
6585       if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
6586           ST == SymbolRef::ST_Other) {
6587         uint64_t Address = Symbol.getValue();
6588         Expected<StringRef> SymNameOrErr = Symbol.getName();
6589         if (!SymNameOrErr)
6590           report_error(MachOOF->getFileName(), SymNameOrErr.takeError());
6591         StringRef SymName = *SymNameOrErr;
6592         AddrMap[Address] = SymName;
6593         if (!DisSymName.empty() && DisSymName == SymName)
6594           DisSymNameFound = true;
6595       }
6596     }
6597     if (!DisSymName.empty() && !DisSymNameFound) {
6598       outs() << "Can't find -dis-symname: " << DisSymName << "\n";
6599       return;
6600     }
6601     // Set up the block of info used by the Symbolizer call backs.
6602     SymbolizerInfo.verbose = !NoSymbolicOperands;
6603     SymbolizerInfo.O = MachOOF;
6604     SymbolizerInfo.S = Sections[SectIdx];
6605     SymbolizerInfo.AddrMap = &AddrMap;
6606     SymbolizerInfo.Sections = &Sections;
6607     SymbolizerInfo.class_name = nullptr;
6608     SymbolizerInfo.selector_name = nullptr;
6609     SymbolizerInfo.method = nullptr;
6610     SymbolizerInfo.demangled_name = nullptr;
6611     SymbolizerInfo.bindtable = nullptr;
6612     SymbolizerInfo.adrp_addr = 0;
6613     SymbolizerInfo.adrp_inst = 0;
6614     // Same for the ThumbSymbolizer
6615     ThumbSymbolizerInfo.verbose = !NoSymbolicOperands;
6616     ThumbSymbolizerInfo.O = MachOOF;
6617     ThumbSymbolizerInfo.S = Sections[SectIdx];
6618     ThumbSymbolizerInfo.AddrMap = &AddrMap;
6619     ThumbSymbolizerInfo.Sections = &Sections;
6620     ThumbSymbolizerInfo.class_name = nullptr;
6621     ThumbSymbolizerInfo.selector_name = nullptr;
6622     ThumbSymbolizerInfo.method = nullptr;
6623     ThumbSymbolizerInfo.demangled_name = nullptr;
6624     ThumbSymbolizerInfo.bindtable = nullptr;
6625     ThumbSymbolizerInfo.adrp_addr = 0;
6626     ThumbSymbolizerInfo.adrp_inst = 0;
6627 
6628     unsigned int Arch = MachOOF->getArch();
6629 
6630     // Skip all symbols if this is a stubs file.
6631     if (Bytes.size() == 0)
6632       return;
6633 
6634     // If the section has symbols but no symbol at the start of the section
6635     // these are used to make sure the bytes before the first symbol are
6636     // disassembled.
6637     bool FirstSymbol = true;
6638     bool FirstSymbolAtSectionStart = true;
6639 
6640     // Disassemble symbol by symbol.
6641     for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
6642       Expected<StringRef> SymNameOrErr = Symbols[SymIdx].getName();
6643       if (!SymNameOrErr)
6644         report_error(MachOOF->getFileName(), SymNameOrErr.takeError());
6645       StringRef SymName = *SymNameOrErr;
6646 
6647       Expected<SymbolRef::Type> STOrErr = Symbols[SymIdx].getType();
6648       if (!STOrErr)
6649         report_error(MachOOF->getFileName(), STOrErr.takeError());
6650       SymbolRef::Type ST = *STOrErr;
6651       if (ST != SymbolRef::ST_Function && ST != SymbolRef::ST_Data)
6652         continue;
6653 
6654       // Make sure the symbol is defined in this section.
6655       bool containsSym = Sections[SectIdx].containsSymbol(Symbols[SymIdx]);
6656       if (!containsSym) {
6657         if (!DisSymName.empty() && DisSymName == SymName) {
6658           outs() << "-dis-symname: " << DisSymName << " not in the section\n";
6659           return;
6660 	}
6661         continue;
6662       }
6663       // The __mh_execute_header is special and we need to deal with that fact
6664       // this symbol is before the start of the (__TEXT,__text) section and at the
6665       // address of the start of the __TEXT segment.  This is because this symbol
6666       // is an N_SECT symbol in the (__TEXT,__text) but its address is before the
6667       // start of the section in a standard MH_EXECUTE filetype.
6668       if (!DisSymName.empty() && DisSymName == "__mh_execute_header") {
6669         outs() << "-dis-symname: __mh_execute_header not in any section\n";
6670         return;
6671       }
6672       // When this code is trying to disassemble a symbol at a time and in the
6673       // case there is only the __mh_execute_header symbol left as in a stripped
6674       // executable, we need to deal with this by ignoring this symbol so the
6675       // whole section is disassembled and this symbol is then not displayed.
6676       if (SymName == "__mh_execute_header" || SymName == "__mh_dylib_header" ||
6677           SymName == "__mh_bundle_header" || SymName == "__mh_object_header" ||
6678           SymName == "__mh_preload_header" || SymName == "__mh_dylinker_header")
6679         continue;
6680 
6681       // If we are only disassembling one symbol see if this is that symbol.
6682       if (!DisSymName.empty() && DisSymName != SymName)
6683         continue;
6684 
6685       // Start at the address of the symbol relative to the section's address.
6686       uint64_t SectSize = Sections[SectIdx].getSize();
6687       uint64_t Start = Symbols[SymIdx].getValue();
6688       uint64_t SectionAddress = Sections[SectIdx].getAddress();
6689       Start -= SectionAddress;
6690 
6691       if (Start > SectSize) {
6692         outs() << "section data ends, " << SymName
6693                << " lies outside valid range\n";
6694         return;
6695       }
6696 
6697       // Stop disassembling either at the beginning of the next symbol or at
6698       // the end of the section.
6699       bool containsNextSym = false;
6700       uint64_t NextSym = 0;
6701       uint64_t NextSymIdx = SymIdx + 1;
6702       while (Symbols.size() > NextSymIdx) {
6703         Expected<SymbolRef::Type> STOrErr = Symbols[NextSymIdx].getType();
6704         if (!STOrErr)
6705           report_error(MachOOF->getFileName(), STOrErr.takeError());
6706         SymbolRef::Type NextSymType = *STOrErr;
6707         if (NextSymType == SymbolRef::ST_Function) {
6708           containsNextSym =
6709               Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]);
6710           NextSym = Symbols[NextSymIdx].getValue();
6711           NextSym -= SectionAddress;
6712           break;
6713         }
6714         ++NextSymIdx;
6715       }
6716 
6717       uint64_t End = containsNextSym ? std::min(NextSym, SectSize) : SectSize;
6718       uint64_t Size;
6719 
6720       symbolTableWorked = true;
6721 
6722       DataRefImpl Symb = Symbols[SymIdx].getRawDataRefImpl();
6723       bool IsThumb = MachOOF->getSymbolFlags(Symb) & SymbolRef::SF_Thumb;
6724 
6725       // We only need the dedicated Thumb target if there's a real choice
6726       // (i.e. we're not targeting M-class) and the function is Thumb.
6727       bool UseThumbTarget = IsThumb && ThumbTarget;
6728 
6729       // If we are not specifying a symbol to start disassembly with and this
6730       // is the first symbol in the section but not at the start of the section
6731       // then move the disassembly index to the start of the section and
6732       // don't print the symbol name just yet.  This is so the bytes before the
6733       // first symbol are disassembled.
6734       uint64_t SymbolStart = Start;
6735       if (DisSymName.empty() && FirstSymbol && Start != 0) {
6736         FirstSymbolAtSectionStart = false;
6737         Start = 0;
6738       }
6739       else
6740         outs() << SymName << ":\n";
6741 
6742       DILineInfo lastLine;
6743       for (uint64_t Index = Start; Index < End; Index += Size) {
6744         MCInst Inst;
6745 
6746         // If this is the first symbol in the section and it was not at the
6747         // start of the section, see if we are at its Index now and if so print
6748         // the symbol name.
6749         if (FirstSymbol && !FirstSymbolAtSectionStart && Index == SymbolStart)
6750           outs() << SymName << ":\n";
6751 
6752         uint64_t PC = SectAddress + Index;
6753         if (!NoLeadingAddr) {
6754           if (FullLeadingAddr) {
6755             if (MachOOF->is64Bit())
6756               outs() << format("%016" PRIx64, PC);
6757             else
6758               outs() << format("%08" PRIx64, PC);
6759           } else {
6760             outs() << format("%8" PRIx64 ":", PC);
6761           }
6762         }
6763         if (!NoShowRawInsn || Arch == Triple::arm)
6764           outs() << "\t";
6765 
6766         // Check the data in code table here to see if this is data not an
6767         // instruction to be disassembled.
6768         DiceTable Dice;
6769         Dice.push_back(std::make_pair(PC, DiceRef()));
6770         dice_table_iterator DTI =
6771             std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(),
6772                         compareDiceTableEntries);
6773         if (DTI != Dices.end()) {
6774           uint16_t Length;
6775           DTI->second.getLength(Length);
6776           uint16_t Kind;
6777           DTI->second.getKind(Kind);
6778           Size = DumpDataInCode(Bytes.data() + Index, Length, Kind);
6779           if ((Kind == MachO::DICE_KIND_JUMP_TABLE8) &&
6780               (PC == (DTI->first + Length - 1)) && (Length & 1))
6781             Size++;
6782           continue;
6783         }
6784 
6785         SmallVector<char, 64> AnnotationsBytes;
6786         raw_svector_ostream Annotations(AnnotationsBytes);
6787 
6788         bool gotInst;
6789         if (UseThumbTarget)
6790           gotInst = ThumbDisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
6791                                                 PC, DebugOut, Annotations);
6792         else
6793           gotInst = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index), PC,
6794                                            DebugOut, Annotations);
6795         if (gotInst) {
6796           if (!NoShowRawInsn || Arch == Triple::arm) {
6797             dumpBytes(makeArrayRef(Bytes.data() + Index, Size), outs());
6798           }
6799           formatted_raw_ostream FormattedOS(outs());
6800           StringRef AnnotationsStr = Annotations.str();
6801           if (UseThumbTarget)
6802             ThumbIP->printInst(&Inst, FormattedOS, AnnotationsStr, *ThumbSTI);
6803           else
6804             IP->printInst(&Inst, FormattedOS, AnnotationsStr, *STI);
6805           emitComments(CommentStream, CommentsToEmit, FormattedOS, *AsmInfo);
6806 
6807           // Print debug info.
6808           if (diContext) {
6809             DILineInfo dli = diContext->getLineInfoForAddress(PC);
6810             // Print valid line info if it changed.
6811             if (dli != lastLine && dli.Line != 0)
6812               outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
6813                      << dli.Column;
6814             lastLine = dli;
6815           }
6816           outs() << "\n";
6817         } else {
6818           unsigned int Arch = MachOOF->getArch();
6819           if (Arch == Triple::x86_64 || Arch == Triple::x86) {
6820             outs() << format("\t.byte 0x%02x #bad opcode\n",
6821                              *(Bytes.data() + Index) & 0xff);
6822             Size = 1; // skip exactly one illegible byte and move on.
6823           } else if (Arch == Triple::aarch64 ||
6824                      (Arch == Triple::arm && !IsThumb)) {
6825             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
6826                               (*(Bytes.data() + Index + 1) & 0xff) << 8 |
6827                               (*(Bytes.data() + Index + 2) & 0xff) << 16 |
6828                               (*(Bytes.data() + Index + 3) & 0xff) << 24;
6829             outs() << format("\t.long\t0x%08x\n", opcode);
6830             Size = 4;
6831           } else if (Arch == Triple::arm) {
6832             assert(IsThumb && "ARM mode should have been dealt with above");
6833             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
6834                               (*(Bytes.data() + Index + 1) & 0xff) << 8;
6835             outs() << format("\t.short\t0x%04x\n", opcode);
6836             Size = 2;
6837           } else{
6838             errs() << "llvm-objdump: warning: invalid instruction encoding\n";
6839             if (Size == 0)
6840               Size = 1; // skip illegible bytes
6841           }
6842         }
6843       }
6844       // Now that we are done disassembled the first symbol set the bool that
6845       // were doing this to false.
6846       FirstSymbol = false;
6847     }
6848     if (!symbolTableWorked) {
6849       // Reading the symbol table didn't work, disassemble the whole section.
6850       uint64_t SectAddress = Sections[SectIdx].getAddress();
6851       uint64_t SectSize = Sections[SectIdx].getSize();
6852       uint64_t InstSize;
6853       for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
6854         MCInst Inst;
6855 
6856         uint64_t PC = SectAddress + Index;
6857         SmallVector<char, 64> AnnotationsBytes;
6858         raw_svector_ostream Annotations(AnnotationsBytes);
6859         if (DisAsm->getInstruction(Inst, InstSize, Bytes.slice(Index), PC,
6860                                    DebugOut, Annotations)) {
6861           if (!NoLeadingAddr) {
6862             if (FullLeadingAddr) {
6863               if (MachOOF->is64Bit())
6864                 outs() << format("%016" PRIx64, PC);
6865               else
6866                 outs() << format("%08" PRIx64, PC);
6867             } else {
6868               outs() << format("%8" PRIx64 ":", PC);
6869             }
6870           }
6871           if (!NoShowRawInsn || Arch == Triple::arm) {
6872             outs() << "\t";
6873             dumpBytes(makeArrayRef(Bytes.data() + Index, InstSize), outs());
6874           }
6875           StringRef AnnotationsStr = Annotations.str();
6876           IP->printInst(&Inst, outs(), AnnotationsStr, *STI);
6877           outs() << "\n";
6878         } else {
6879           unsigned int Arch = MachOOF->getArch();
6880           if (Arch == Triple::x86_64 || Arch == Triple::x86) {
6881             outs() << format("\t.byte 0x%02x #bad opcode\n",
6882                              *(Bytes.data() + Index) & 0xff);
6883             InstSize = 1; // skip exactly one illegible byte and move on.
6884           } else {
6885             errs() << "llvm-objdump: warning: invalid instruction encoding\n";
6886             if (InstSize == 0)
6887               InstSize = 1; // skip illegible bytes
6888           }
6889         }
6890       }
6891     }
6892     // The TripleName's need to be reset if we are called again for a different
6893     // archtecture.
6894     TripleName = "";
6895     ThumbTripleName = "";
6896 
6897     if (SymbolizerInfo.method != nullptr)
6898       free(SymbolizerInfo.method);
6899     if (SymbolizerInfo.demangled_name != nullptr)
6900       free(SymbolizerInfo.demangled_name);
6901     if (ThumbSymbolizerInfo.method != nullptr)
6902       free(ThumbSymbolizerInfo.method);
6903     if (ThumbSymbolizerInfo.demangled_name != nullptr)
6904       free(ThumbSymbolizerInfo.demangled_name);
6905   }
6906 }
6907 
6908 //===----------------------------------------------------------------------===//
6909 // __compact_unwind section dumping
6910 //===----------------------------------------------------------------------===//
6911 
6912 namespace {
6913 
6914 template <typename T> static uint64_t readNext(const char *&Buf) {
6915   using llvm::support::little;
6916   using llvm::support::unaligned;
6917 
6918   uint64_t Val = support::endian::read<T, little, unaligned>(Buf);
6919   Buf += sizeof(T);
6920   return Val;
6921 }
6922 
6923 struct CompactUnwindEntry {
6924   uint32_t OffsetInSection;
6925 
6926   uint64_t FunctionAddr;
6927   uint32_t Length;
6928   uint32_t CompactEncoding;
6929   uint64_t PersonalityAddr;
6930   uint64_t LSDAAddr;
6931 
6932   RelocationRef FunctionReloc;
6933   RelocationRef PersonalityReloc;
6934   RelocationRef LSDAReloc;
6935 
6936   CompactUnwindEntry(StringRef Contents, unsigned Offset, bool Is64)
6937       : OffsetInSection(Offset) {
6938     if (Is64)
6939       read<uint64_t>(Contents.data() + Offset);
6940     else
6941       read<uint32_t>(Contents.data() + Offset);
6942   }
6943 
6944 private:
6945   template <typename UIntPtr> void read(const char *Buf) {
6946     FunctionAddr = readNext<UIntPtr>(Buf);
6947     Length = readNext<uint32_t>(Buf);
6948     CompactEncoding = readNext<uint32_t>(Buf);
6949     PersonalityAddr = readNext<UIntPtr>(Buf);
6950     LSDAAddr = readNext<UIntPtr>(Buf);
6951   }
6952 };
6953 }
6954 
6955 /// Given a relocation from __compact_unwind, consisting of the RelocationRef
6956 /// and data being relocated, determine the best base Name and Addend to use for
6957 /// display purposes.
6958 ///
6959 /// 1. An Extern relocation will directly reference a symbol (and the data is
6960 ///    then already an addend), so use that.
6961 /// 2. Otherwise the data is an offset in the object file's layout; try to find
6962 //     a symbol before it in the same section, and use the offset from there.
6963 /// 3. Finally, if all that fails, fall back to an offset from the start of the
6964 ///    referenced section.
6965 static void findUnwindRelocNameAddend(const MachOObjectFile *Obj,
6966                                       std::map<uint64_t, SymbolRef> &Symbols,
6967                                       const RelocationRef &Reloc, uint64_t Addr,
6968                                       StringRef &Name, uint64_t &Addend) {
6969   if (Reloc.getSymbol() != Obj->symbol_end()) {
6970     Expected<StringRef> NameOrErr = Reloc.getSymbol()->getName();
6971     if (!NameOrErr)
6972       report_error(Obj->getFileName(), NameOrErr.takeError());
6973     Name = *NameOrErr;
6974     Addend = Addr;
6975     return;
6976   }
6977 
6978   auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl());
6979   SectionRef RelocSection = Obj->getAnyRelocationSection(RE);
6980 
6981   uint64_t SectionAddr = RelocSection.getAddress();
6982 
6983   auto Sym = Symbols.upper_bound(Addr);
6984   if (Sym == Symbols.begin()) {
6985     // The first symbol in the object is after this reference, the best we can
6986     // do is section-relative notation.
6987     RelocSection.getName(Name);
6988     Addend = Addr - SectionAddr;
6989     return;
6990   }
6991 
6992   // Go back one so that SymbolAddress <= Addr.
6993   --Sym;
6994 
6995   auto SectOrErr = Sym->second.getSection();
6996   if (!SectOrErr)
6997     report_error(Obj->getFileName(), SectOrErr.takeError());
6998   section_iterator SymSection = *SectOrErr;
6999   if (RelocSection == *SymSection) {
7000     // There's a valid symbol in the same section before this reference.
7001     Expected<StringRef> NameOrErr = Sym->second.getName();
7002     if (!NameOrErr)
7003       report_error(Obj->getFileName(), NameOrErr.takeError());
7004     Name = *NameOrErr;
7005     Addend = Addr - Sym->first;
7006     return;
7007   }
7008 
7009   // There is a symbol before this reference, but it's in a different
7010   // section. Probably not helpful to mention it, so use the section name.
7011   RelocSection.getName(Name);
7012   Addend = Addr - SectionAddr;
7013 }
7014 
7015 static void printUnwindRelocDest(const MachOObjectFile *Obj,
7016                                  std::map<uint64_t, SymbolRef> &Symbols,
7017                                  const RelocationRef &Reloc, uint64_t Addr) {
7018   StringRef Name;
7019   uint64_t Addend;
7020 
7021   if (!Reloc.getObject())
7022     return;
7023 
7024   findUnwindRelocNameAddend(Obj, Symbols, Reloc, Addr, Name, Addend);
7025 
7026   outs() << Name;
7027   if (Addend)
7028     outs() << " + " << format("0x%" PRIx64, Addend);
7029 }
7030 
7031 static void
7032 printMachOCompactUnwindSection(const MachOObjectFile *Obj,
7033                                std::map<uint64_t, SymbolRef> &Symbols,
7034                                const SectionRef &CompactUnwind) {
7035 
7036   if (!Obj->isLittleEndian()) {
7037     outs() << "Skipping big-endian __compact_unwind section\n";
7038     return;
7039   }
7040 
7041   bool Is64 = Obj->is64Bit();
7042   uint32_t PointerSize = Is64 ? sizeof(uint64_t) : sizeof(uint32_t);
7043   uint32_t EntrySize = 3 * PointerSize + 2 * sizeof(uint32_t);
7044 
7045   StringRef Contents;
7046   CompactUnwind.getContents(Contents);
7047 
7048   SmallVector<CompactUnwindEntry, 4> CompactUnwinds;
7049 
7050   // First populate the initial raw offsets, encodings and so on from the entry.
7051   for (unsigned Offset = 0; Offset < Contents.size(); Offset += EntrySize) {
7052     CompactUnwindEntry Entry(Contents.data(), Offset, Is64);
7053     CompactUnwinds.push_back(Entry);
7054   }
7055 
7056   // Next we need to look at the relocations to find out what objects are
7057   // actually being referred to.
7058   for (const RelocationRef &Reloc : CompactUnwind.relocations()) {
7059     uint64_t RelocAddress = Reloc.getOffset();
7060 
7061     uint32_t EntryIdx = RelocAddress / EntrySize;
7062     uint32_t OffsetInEntry = RelocAddress - EntryIdx * EntrySize;
7063     CompactUnwindEntry &Entry = CompactUnwinds[EntryIdx];
7064 
7065     if (OffsetInEntry == 0)
7066       Entry.FunctionReloc = Reloc;
7067     else if (OffsetInEntry == PointerSize + 2 * sizeof(uint32_t))
7068       Entry.PersonalityReloc = Reloc;
7069     else if (OffsetInEntry == 2 * PointerSize + 2 * sizeof(uint32_t))
7070       Entry.LSDAReloc = Reloc;
7071     else {
7072       outs() << "Invalid relocation in __compact_unwind section\n";
7073       return;
7074     }
7075   }
7076 
7077   // Finally, we're ready to print the data we've gathered.
7078   outs() << "Contents of __compact_unwind section:\n";
7079   for (auto &Entry : CompactUnwinds) {
7080     outs() << "  Entry at offset "
7081            << format("0x%" PRIx32, Entry.OffsetInSection) << ":\n";
7082 
7083     // 1. Start of the region this entry applies to.
7084     outs() << "    start:                " << format("0x%" PRIx64,
7085                                                      Entry.FunctionAddr) << ' ';
7086     printUnwindRelocDest(Obj, Symbols, Entry.FunctionReloc, Entry.FunctionAddr);
7087     outs() << '\n';
7088 
7089     // 2. Length of the region this entry applies to.
7090     outs() << "    length:               " << format("0x%" PRIx32, Entry.Length)
7091            << '\n';
7092     // 3. The 32-bit compact encoding.
7093     outs() << "    compact encoding:     "
7094            << format("0x%08" PRIx32, Entry.CompactEncoding) << '\n';
7095 
7096     // 4. The personality function, if present.
7097     if (Entry.PersonalityReloc.getObject()) {
7098       outs() << "    personality function: "
7099              << format("0x%" PRIx64, Entry.PersonalityAddr) << ' ';
7100       printUnwindRelocDest(Obj, Symbols, Entry.PersonalityReloc,
7101                            Entry.PersonalityAddr);
7102       outs() << '\n';
7103     }
7104 
7105     // 5. This entry's language-specific data area.
7106     if (Entry.LSDAReloc.getObject()) {
7107       outs() << "    LSDA:                 " << format("0x%" PRIx64,
7108                                                        Entry.LSDAAddr) << ' ';
7109       printUnwindRelocDest(Obj, Symbols, Entry.LSDAReloc, Entry.LSDAAddr);
7110       outs() << '\n';
7111     }
7112   }
7113 }
7114 
7115 //===----------------------------------------------------------------------===//
7116 // __unwind_info section dumping
7117 //===----------------------------------------------------------------------===//
7118 
7119 static void printRegularSecondLevelUnwindPage(const char *PageStart) {
7120   const char *Pos = PageStart;
7121   uint32_t Kind = readNext<uint32_t>(Pos);
7122   (void)Kind;
7123   assert(Kind == 2 && "kind for a regular 2nd level index should be 2");
7124 
7125   uint16_t EntriesStart = readNext<uint16_t>(Pos);
7126   uint16_t NumEntries = readNext<uint16_t>(Pos);
7127 
7128   Pos = PageStart + EntriesStart;
7129   for (unsigned i = 0; i < NumEntries; ++i) {
7130     uint32_t FunctionOffset = readNext<uint32_t>(Pos);
7131     uint32_t Encoding = readNext<uint32_t>(Pos);
7132 
7133     outs() << "      [" << i << "]: "
7134            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
7135            << ", "
7136            << "encoding=" << format("0x%08" PRIx32, Encoding) << '\n';
7137   }
7138 }
7139 
7140 static void printCompressedSecondLevelUnwindPage(
7141     const char *PageStart, uint32_t FunctionBase,
7142     const SmallVectorImpl<uint32_t> &CommonEncodings) {
7143   const char *Pos = PageStart;
7144   uint32_t Kind = readNext<uint32_t>(Pos);
7145   (void)Kind;
7146   assert(Kind == 3 && "kind for a compressed 2nd level index should be 3");
7147 
7148   uint16_t EntriesStart = readNext<uint16_t>(Pos);
7149   uint16_t NumEntries = readNext<uint16_t>(Pos);
7150 
7151   uint16_t EncodingsStart = readNext<uint16_t>(Pos);
7152   readNext<uint16_t>(Pos);
7153   const auto *PageEncodings = reinterpret_cast<const support::ulittle32_t *>(
7154       PageStart + EncodingsStart);
7155 
7156   Pos = PageStart + EntriesStart;
7157   for (unsigned i = 0; i < NumEntries; ++i) {
7158     uint32_t Entry = readNext<uint32_t>(Pos);
7159     uint32_t FunctionOffset = FunctionBase + (Entry & 0xffffff);
7160     uint32_t EncodingIdx = Entry >> 24;
7161 
7162     uint32_t Encoding;
7163     if (EncodingIdx < CommonEncodings.size())
7164       Encoding = CommonEncodings[EncodingIdx];
7165     else
7166       Encoding = PageEncodings[EncodingIdx - CommonEncodings.size()];
7167 
7168     outs() << "      [" << i << "]: "
7169            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
7170            << ", "
7171            << "encoding[" << EncodingIdx
7172            << "]=" << format("0x%08" PRIx32, Encoding) << '\n';
7173   }
7174 }
7175 
7176 static void printMachOUnwindInfoSection(const MachOObjectFile *Obj,
7177                                         std::map<uint64_t, SymbolRef> &Symbols,
7178                                         const SectionRef &UnwindInfo) {
7179 
7180   if (!Obj->isLittleEndian()) {
7181     outs() << "Skipping big-endian __unwind_info section\n";
7182     return;
7183   }
7184 
7185   outs() << "Contents of __unwind_info section:\n";
7186 
7187   StringRef Contents;
7188   UnwindInfo.getContents(Contents);
7189   const char *Pos = Contents.data();
7190 
7191   //===----------------------------------
7192   // Section header
7193   //===----------------------------------
7194 
7195   uint32_t Version = readNext<uint32_t>(Pos);
7196   outs() << "  Version:                                   "
7197          << format("0x%" PRIx32, Version) << '\n';
7198   if (Version != 1) {
7199     outs() << "    Skipping section with unknown version\n";
7200     return;
7201   }
7202 
7203   uint32_t CommonEncodingsStart = readNext<uint32_t>(Pos);
7204   outs() << "  Common encodings array section offset:     "
7205          << format("0x%" PRIx32, CommonEncodingsStart) << '\n';
7206   uint32_t NumCommonEncodings = readNext<uint32_t>(Pos);
7207   outs() << "  Number of common encodings in array:       "
7208          << format("0x%" PRIx32, NumCommonEncodings) << '\n';
7209 
7210   uint32_t PersonalitiesStart = readNext<uint32_t>(Pos);
7211   outs() << "  Personality function array section offset: "
7212          << format("0x%" PRIx32, PersonalitiesStart) << '\n';
7213   uint32_t NumPersonalities = readNext<uint32_t>(Pos);
7214   outs() << "  Number of personality functions in array:  "
7215          << format("0x%" PRIx32, NumPersonalities) << '\n';
7216 
7217   uint32_t IndicesStart = readNext<uint32_t>(Pos);
7218   outs() << "  Index array section offset:                "
7219          << format("0x%" PRIx32, IndicesStart) << '\n';
7220   uint32_t NumIndices = readNext<uint32_t>(Pos);
7221   outs() << "  Number of indices in array:                "
7222          << format("0x%" PRIx32, NumIndices) << '\n';
7223 
7224   //===----------------------------------
7225   // A shared list of common encodings
7226   //===----------------------------------
7227 
7228   // These occupy indices in the range [0, N] whenever an encoding is referenced
7229   // from a compressed 2nd level index table. In practice the linker only
7230   // creates ~128 of these, so that indices are available to embed encodings in
7231   // the 2nd level index.
7232 
7233   SmallVector<uint32_t, 64> CommonEncodings;
7234   outs() << "  Common encodings: (count = " << NumCommonEncodings << ")\n";
7235   Pos = Contents.data() + CommonEncodingsStart;
7236   for (unsigned i = 0; i < NumCommonEncodings; ++i) {
7237     uint32_t Encoding = readNext<uint32_t>(Pos);
7238     CommonEncodings.push_back(Encoding);
7239 
7240     outs() << "    encoding[" << i << "]: " << format("0x%08" PRIx32, Encoding)
7241            << '\n';
7242   }
7243 
7244   //===----------------------------------
7245   // Personality functions used in this executable
7246   //===----------------------------------
7247 
7248   // There should be only a handful of these (one per source language,
7249   // roughly). Particularly since they only get 2 bits in the compact encoding.
7250 
7251   outs() << "  Personality functions: (count = " << NumPersonalities << ")\n";
7252   Pos = Contents.data() + PersonalitiesStart;
7253   for (unsigned i = 0; i < NumPersonalities; ++i) {
7254     uint32_t PersonalityFn = readNext<uint32_t>(Pos);
7255     outs() << "    personality[" << i + 1
7256            << "]: " << format("0x%08" PRIx32, PersonalityFn) << '\n';
7257   }
7258 
7259   //===----------------------------------
7260   // The level 1 index entries
7261   //===----------------------------------
7262 
7263   // These specify an approximate place to start searching for the more detailed
7264   // information, sorted by PC.
7265 
7266   struct IndexEntry {
7267     uint32_t FunctionOffset;
7268     uint32_t SecondLevelPageStart;
7269     uint32_t LSDAStart;
7270   };
7271 
7272   SmallVector<IndexEntry, 4> IndexEntries;
7273 
7274   outs() << "  Top level indices: (count = " << NumIndices << ")\n";
7275   Pos = Contents.data() + IndicesStart;
7276   for (unsigned i = 0; i < NumIndices; ++i) {
7277     IndexEntry Entry;
7278 
7279     Entry.FunctionOffset = readNext<uint32_t>(Pos);
7280     Entry.SecondLevelPageStart = readNext<uint32_t>(Pos);
7281     Entry.LSDAStart = readNext<uint32_t>(Pos);
7282     IndexEntries.push_back(Entry);
7283 
7284     outs() << "    [" << i << "]: "
7285            << "function offset=" << format("0x%08" PRIx32, Entry.FunctionOffset)
7286            << ", "
7287            << "2nd level page offset="
7288            << format("0x%08" PRIx32, Entry.SecondLevelPageStart) << ", "
7289            << "LSDA offset=" << format("0x%08" PRIx32, Entry.LSDAStart) << '\n';
7290   }
7291 
7292   //===----------------------------------
7293   // Next come the LSDA tables
7294   //===----------------------------------
7295 
7296   // The LSDA layout is rather implicit: it's a contiguous array of entries from
7297   // the first top-level index's LSDAOffset to the last (sentinel).
7298 
7299   outs() << "  LSDA descriptors:\n";
7300   Pos = Contents.data() + IndexEntries[0].LSDAStart;
7301   int NumLSDAs = (IndexEntries.back().LSDAStart - IndexEntries[0].LSDAStart) /
7302                  (2 * sizeof(uint32_t));
7303   for (int i = 0; i < NumLSDAs; ++i) {
7304     uint32_t FunctionOffset = readNext<uint32_t>(Pos);
7305     uint32_t LSDAOffset = readNext<uint32_t>(Pos);
7306     outs() << "    [" << i << "]: "
7307            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
7308            << ", "
7309            << "LSDA offset=" << format("0x%08" PRIx32, LSDAOffset) << '\n';
7310   }
7311 
7312   //===----------------------------------
7313   // Finally, the 2nd level indices
7314   //===----------------------------------
7315 
7316   // Generally these are 4K in size, and have 2 possible forms:
7317   //   + Regular stores up to 511 entries with disparate encodings
7318   //   + Compressed stores up to 1021 entries if few enough compact encoding
7319   //     values are used.
7320   outs() << "  Second level indices:\n";
7321   for (unsigned i = 0; i < IndexEntries.size() - 1; ++i) {
7322     // The final sentinel top-level index has no associated 2nd level page
7323     if (IndexEntries[i].SecondLevelPageStart == 0)
7324       break;
7325 
7326     outs() << "    Second level index[" << i << "]: "
7327            << "offset in section="
7328            << format("0x%08" PRIx32, IndexEntries[i].SecondLevelPageStart)
7329            << ", "
7330            << "base function offset="
7331            << format("0x%08" PRIx32, IndexEntries[i].FunctionOffset) << '\n';
7332 
7333     Pos = Contents.data() + IndexEntries[i].SecondLevelPageStart;
7334     uint32_t Kind = *reinterpret_cast<const support::ulittle32_t *>(Pos);
7335     if (Kind == 2)
7336       printRegularSecondLevelUnwindPage(Pos);
7337     else if (Kind == 3)
7338       printCompressedSecondLevelUnwindPage(Pos, IndexEntries[i].FunctionOffset,
7339                                            CommonEncodings);
7340     else
7341       outs() << "    Skipping 2nd level page with unknown kind " << Kind
7342              << '\n';
7343   }
7344 }
7345 
7346 void llvm::printMachOUnwindInfo(const MachOObjectFile *Obj) {
7347   std::map<uint64_t, SymbolRef> Symbols;
7348   for (const SymbolRef &SymRef : Obj->symbols()) {
7349     // Discard any undefined or absolute symbols. They're not going to take part
7350     // in the convenience lookup for unwind info and just take up resources.
7351     auto SectOrErr = SymRef.getSection();
7352     if (!SectOrErr) {
7353       // TODO: Actually report errors helpfully.
7354       consumeError(SectOrErr.takeError());
7355       continue;
7356     }
7357     section_iterator Section = *SectOrErr;
7358     if (Section == Obj->section_end())
7359       continue;
7360 
7361     uint64_t Addr = SymRef.getValue();
7362     Symbols.insert(std::make_pair(Addr, SymRef));
7363   }
7364 
7365   for (const SectionRef &Section : Obj->sections()) {
7366     StringRef SectName;
7367     Section.getName(SectName);
7368     if (SectName == "__compact_unwind")
7369       printMachOCompactUnwindSection(Obj, Symbols, Section);
7370     else if (SectName == "__unwind_info")
7371       printMachOUnwindInfoSection(Obj, Symbols, Section);
7372   }
7373 }
7374 
7375 static void PrintMachHeader(uint32_t magic, uint32_t cputype,
7376                             uint32_t cpusubtype, uint32_t filetype,
7377                             uint32_t ncmds, uint32_t sizeofcmds, uint32_t flags,
7378                             bool verbose) {
7379   outs() << "Mach header\n";
7380   outs() << "      magic cputype cpusubtype  caps    filetype ncmds "
7381             "sizeofcmds      flags\n";
7382   if (verbose) {
7383     if (magic == MachO::MH_MAGIC)
7384       outs() << "   MH_MAGIC";
7385     else if (magic == MachO::MH_MAGIC_64)
7386       outs() << "MH_MAGIC_64";
7387     else
7388       outs() << format(" 0x%08" PRIx32, magic);
7389     switch (cputype) {
7390     case MachO::CPU_TYPE_I386:
7391       outs() << "    I386";
7392       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7393       case MachO::CPU_SUBTYPE_I386_ALL:
7394         outs() << "        ALL";
7395         break;
7396       default:
7397         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7398         break;
7399       }
7400       break;
7401     case MachO::CPU_TYPE_X86_64:
7402       outs() << "  X86_64";
7403       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7404       case MachO::CPU_SUBTYPE_X86_64_ALL:
7405         outs() << "        ALL";
7406         break;
7407       case MachO::CPU_SUBTYPE_X86_64_H:
7408         outs() << "    Haswell";
7409         break;
7410       default:
7411         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7412         break;
7413       }
7414       break;
7415     case MachO::CPU_TYPE_ARM:
7416       outs() << "     ARM";
7417       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7418       case MachO::CPU_SUBTYPE_ARM_ALL:
7419         outs() << "        ALL";
7420         break;
7421       case MachO::CPU_SUBTYPE_ARM_V4T:
7422         outs() << "        V4T";
7423         break;
7424       case MachO::CPU_SUBTYPE_ARM_V5TEJ:
7425         outs() << "      V5TEJ";
7426         break;
7427       case MachO::CPU_SUBTYPE_ARM_XSCALE:
7428         outs() << "     XSCALE";
7429         break;
7430       case MachO::CPU_SUBTYPE_ARM_V6:
7431         outs() << "         V6";
7432         break;
7433       case MachO::CPU_SUBTYPE_ARM_V6M:
7434         outs() << "        V6M";
7435         break;
7436       case MachO::CPU_SUBTYPE_ARM_V7:
7437         outs() << "         V7";
7438         break;
7439       case MachO::CPU_SUBTYPE_ARM_V7EM:
7440         outs() << "       V7EM";
7441         break;
7442       case MachO::CPU_SUBTYPE_ARM_V7K:
7443         outs() << "        V7K";
7444         break;
7445       case MachO::CPU_SUBTYPE_ARM_V7M:
7446         outs() << "        V7M";
7447         break;
7448       case MachO::CPU_SUBTYPE_ARM_V7S:
7449         outs() << "        V7S";
7450         break;
7451       default:
7452         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7453         break;
7454       }
7455       break;
7456     case MachO::CPU_TYPE_ARM64:
7457       outs() << "   ARM64";
7458       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7459       case MachO::CPU_SUBTYPE_ARM64_ALL:
7460         outs() << "        ALL";
7461         break;
7462       default:
7463         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7464         break;
7465       }
7466       break;
7467     case MachO::CPU_TYPE_POWERPC:
7468       outs() << "     PPC";
7469       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7470       case MachO::CPU_SUBTYPE_POWERPC_ALL:
7471         outs() << "        ALL";
7472         break;
7473       default:
7474         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7475         break;
7476       }
7477       break;
7478     case MachO::CPU_TYPE_POWERPC64:
7479       outs() << "   PPC64";
7480       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7481       case MachO::CPU_SUBTYPE_POWERPC_ALL:
7482         outs() << "        ALL";
7483         break;
7484       default:
7485         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7486         break;
7487       }
7488       break;
7489     default:
7490       outs() << format(" %7d", cputype);
7491       outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7492       break;
7493     }
7494     if ((cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64) {
7495       outs() << " LIB64";
7496     } else {
7497       outs() << format("  0x%02" PRIx32,
7498                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
7499     }
7500     switch (filetype) {
7501     case MachO::MH_OBJECT:
7502       outs() << "      OBJECT";
7503       break;
7504     case MachO::MH_EXECUTE:
7505       outs() << "     EXECUTE";
7506       break;
7507     case MachO::MH_FVMLIB:
7508       outs() << "      FVMLIB";
7509       break;
7510     case MachO::MH_CORE:
7511       outs() << "        CORE";
7512       break;
7513     case MachO::MH_PRELOAD:
7514       outs() << "     PRELOAD";
7515       break;
7516     case MachO::MH_DYLIB:
7517       outs() << "       DYLIB";
7518       break;
7519     case MachO::MH_DYLIB_STUB:
7520       outs() << "  DYLIB_STUB";
7521       break;
7522     case MachO::MH_DYLINKER:
7523       outs() << "    DYLINKER";
7524       break;
7525     case MachO::MH_BUNDLE:
7526       outs() << "      BUNDLE";
7527       break;
7528     case MachO::MH_DSYM:
7529       outs() << "        DSYM";
7530       break;
7531     case MachO::MH_KEXT_BUNDLE:
7532       outs() << "  KEXTBUNDLE";
7533       break;
7534     default:
7535       outs() << format("  %10u", filetype);
7536       break;
7537     }
7538     outs() << format(" %5u", ncmds);
7539     outs() << format(" %10u", sizeofcmds);
7540     uint32_t f = flags;
7541     if (f & MachO::MH_NOUNDEFS) {
7542       outs() << "   NOUNDEFS";
7543       f &= ~MachO::MH_NOUNDEFS;
7544     }
7545     if (f & MachO::MH_INCRLINK) {
7546       outs() << " INCRLINK";
7547       f &= ~MachO::MH_INCRLINK;
7548     }
7549     if (f & MachO::MH_DYLDLINK) {
7550       outs() << " DYLDLINK";
7551       f &= ~MachO::MH_DYLDLINK;
7552     }
7553     if (f & MachO::MH_BINDATLOAD) {
7554       outs() << " BINDATLOAD";
7555       f &= ~MachO::MH_BINDATLOAD;
7556     }
7557     if (f & MachO::MH_PREBOUND) {
7558       outs() << " PREBOUND";
7559       f &= ~MachO::MH_PREBOUND;
7560     }
7561     if (f & MachO::MH_SPLIT_SEGS) {
7562       outs() << " SPLIT_SEGS";
7563       f &= ~MachO::MH_SPLIT_SEGS;
7564     }
7565     if (f & MachO::MH_LAZY_INIT) {
7566       outs() << " LAZY_INIT";
7567       f &= ~MachO::MH_LAZY_INIT;
7568     }
7569     if (f & MachO::MH_TWOLEVEL) {
7570       outs() << " TWOLEVEL";
7571       f &= ~MachO::MH_TWOLEVEL;
7572     }
7573     if (f & MachO::MH_FORCE_FLAT) {
7574       outs() << " FORCE_FLAT";
7575       f &= ~MachO::MH_FORCE_FLAT;
7576     }
7577     if (f & MachO::MH_NOMULTIDEFS) {
7578       outs() << " NOMULTIDEFS";
7579       f &= ~MachO::MH_NOMULTIDEFS;
7580     }
7581     if (f & MachO::MH_NOFIXPREBINDING) {
7582       outs() << " NOFIXPREBINDING";
7583       f &= ~MachO::MH_NOFIXPREBINDING;
7584     }
7585     if (f & MachO::MH_PREBINDABLE) {
7586       outs() << " PREBINDABLE";
7587       f &= ~MachO::MH_PREBINDABLE;
7588     }
7589     if (f & MachO::MH_ALLMODSBOUND) {
7590       outs() << " ALLMODSBOUND";
7591       f &= ~MachO::MH_ALLMODSBOUND;
7592     }
7593     if (f & MachO::MH_SUBSECTIONS_VIA_SYMBOLS) {
7594       outs() << " SUBSECTIONS_VIA_SYMBOLS";
7595       f &= ~MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
7596     }
7597     if (f & MachO::MH_CANONICAL) {
7598       outs() << " CANONICAL";
7599       f &= ~MachO::MH_CANONICAL;
7600     }
7601     if (f & MachO::MH_WEAK_DEFINES) {
7602       outs() << " WEAK_DEFINES";
7603       f &= ~MachO::MH_WEAK_DEFINES;
7604     }
7605     if (f & MachO::MH_BINDS_TO_WEAK) {
7606       outs() << " BINDS_TO_WEAK";
7607       f &= ~MachO::MH_BINDS_TO_WEAK;
7608     }
7609     if (f & MachO::MH_ALLOW_STACK_EXECUTION) {
7610       outs() << " ALLOW_STACK_EXECUTION";
7611       f &= ~MachO::MH_ALLOW_STACK_EXECUTION;
7612     }
7613     if (f & MachO::MH_DEAD_STRIPPABLE_DYLIB) {
7614       outs() << " DEAD_STRIPPABLE_DYLIB";
7615       f &= ~MachO::MH_DEAD_STRIPPABLE_DYLIB;
7616     }
7617     if (f & MachO::MH_PIE) {
7618       outs() << " PIE";
7619       f &= ~MachO::MH_PIE;
7620     }
7621     if (f & MachO::MH_NO_REEXPORTED_DYLIBS) {
7622       outs() << " NO_REEXPORTED_DYLIBS";
7623       f &= ~MachO::MH_NO_REEXPORTED_DYLIBS;
7624     }
7625     if (f & MachO::MH_HAS_TLV_DESCRIPTORS) {
7626       outs() << " MH_HAS_TLV_DESCRIPTORS";
7627       f &= ~MachO::MH_HAS_TLV_DESCRIPTORS;
7628     }
7629     if (f & MachO::MH_NO_HEAP_EXECUTION) {
7630       outs() << " MH_NO_HEAP_EXECUTION";
7631       f &= ~MachO::MH_NO_HEAP_EXECUTION;
7632     }
7633     if (f & MachO::MH_APP_EXTENSION_SAFE) {
7634       outs() << " APP_EXTENSION_SAFE";
7635       f &= ~MachO::MH_APP_EXTENSION_SAFE;
7636     }
7637     if (f != 0 || flags == 0)
7638       outs() << format(" 0x%08" PRIx32, f);
7639   } else {
7640     outs() << format(" 0x%08" PRIx32, magic);
7641     outs() << format(" %7d", cputype);
7642     outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7643     outs() << format("  0x%02" PRIx32,
7644                      (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
7645     outs() << format("  %10u", filetype);
7646     outs() << format(" %5u", ncmds);
7647     outs() << format(" %10u", sizeofcmds);
7648     outs() << format(" 0x%08" PRIx32, flags);
7649   }
7650   outs() << "\n";
7651 }
7652 
7653 static void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize,
7654                                 StringRef SegName, uint64_t vmaddr,
7655                                 uint64_t vmsize, uint64_t fileoff,
7656                                 uint64_t filesize, uint32_t maxprot,
7657                                 uint32_t initprot, uint32_t nsects,
7658                                 uint32_t flags, uint32_t object_size,
7659                                 bool verbose) {
7660   uint64_t expected_cmdsize;
7661   if (cmd == MachO::LC_SEGMENT) {
7662     outs() << "      cmd LC_SEGMENT\n";
7663     expected_cmdsize = nsects;
7664     expected_cmdsize *= sizeof(struct MachO::section);
7665     expected_cmdsize += sizeof(struct MachO::segment_command);
7666   } else {
7667     outs() << "      cmd LC_SEGMENT_64\n";
7668     expected_cmdsize = nsects;
7669     expected_cmdsize *= sizeof(struct MachO::section_64);
7670     expected_cmdsize += sizeof(struct MachO::segment_command_64);
7671   }
7672   outs() << "  cmdsize " << cmdsize;
7673   if (cmdsize != expected_cmdsize)
7674     outs() << " Inconsistent size\n";
7675   else
7676     outs() << "\n";
7677   outs() << "  segname " << SegName << "\n";
7678   if (cmd == MachO::LC_SEGMENT_64) {
7679     outs() << "   vmaddr " << format("0x%016" PRIx64, vmaddr) << "\n";
7680     outs() << "   vmsize " << format("0x%016" PRIx64, vmsize) << "\n";
7681   } else {
7682     outs() << "   vmaddr " << format("0x%08" PRIx64, vmaddr) << "\n";
7683     outs() << "   vmsize " << format("0x%08" PRIx64, vmsize) << "\n";
7684   }
7685   outs() << "  fileoff " << fileoff;
7686   if (fileoff > object_size)
7687     outs() << " (past end of file)\n";
7688   else
7689     outs() << "\n";
7690   outs() << " filesize " << filesize;
7691   if (fileoff + filesize > object_size)
7692     outs() << " (past end of file)\n";
7693   else
7694     outs() << "\n";
7695   if (verbose) {
7696     if ((maxprot &
7697          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
7698            MachO::VM_PROT_EXECUTE)) != 0)
7699       outs() << "  maxprot ?" << format("0x%08" PRIx32, maxprot) << "\n";
7700     else {
7701       outs() << "  maxprot ";
7702       outs() << ((maxprot & MachO::VM_PROT_READ) ? "r" : "-");
7703       outs() << ((maxprot & MachO::VM_PROT_WRITE) ? "w" : "-");
7704       outs() << ((maxprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
7705     }
7706     if ((initprot &
7707          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
7708            MachO::VM_PROT_EXECUTE)) != 0)
7709       outs() << " initprot ?" << format("0x%08" PRIx32, initprot) << "\n";
7710     else {
7711       outs() << " initprot ";
7712       outs() << ((initprot & MachO::VM_PROT_READ) ? "r" : "-");
7713       outs() << ((initprot & MachO::VM_PROT_WRITE) ? "w" : "-");
7714       outs() << ((initprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
7715     }
7716   } else {
7717     outs() << "  maxprot " << format("0x%08" PRIx32, maxprot) << "\n";
7718     outs() << " initprot " << format("0x%08" PRIx32, initprot) << "\n";
7719   }
7720   outs() << "   nsects " << nsects << "\n";
7721   if (verbose) {
7722     outs() << "    flags";
7723     if (flags == 0)
7724       outs() << " (none)\n";
7725     else {
7726       if (flags & MachO::SG_HIGHVM) {
7727         outs() << " HIGHVM";
7728         flags &= ~MachO::SG_HIGHVM;
7729       }
7730       if (flags & MachO::SG_FVMLIB) {
7731         outs() << " FVMLIB";
7732         flags &= ~MachO::SG_FVMLIB;
7733       }
7734       if (flags & MachO::SG_NORELOC) {
7735         outs() << " NORELOC";
7736         flags &= ~MachO::SG_NORELOC;
7737       }
7738       if (flags & MachO::SG_PROTECTED_VERSION_1) {
7739         outs() << " PROTECTED_VERSION_1";
7740         flags &= ~MachO::SG_PROTECTED_VERSION_1;
7741       }
7742       if (flags)
7743         outs() << format(" 0x%08" PRIx32, flags) << " (unknown flags)\n";
7744       else
7745         outs() << "\n";
7746     }
7747   } else {
7748     outs() << "    flags " << format("0x%" PRIx32, flags) << "\n";
7749   }
7750 }
7751 
7752 static void PrintSection(const char *sectname, const char *segname,
7753                          uint64_t addr, uint64_t size, uint32_t offset,
7754                          uint32_t align, uint32_t reloff, uint32_t nreloc,
7755                          uint32_t flags, uint32_t reserved1, uint32_t reserved2,
7756                          uint32_t cmd, const char *sg_segname,
7757                          uint32_t filetype, uint32_t object_size,
7758                          bool verbose) {
7759   outs() << "Section\n";
7760   outs() << "  sectname " << format("%.16s\n", sectname);
7761   outs() << "   segname " << format("%.16s", segname);
7762   if (filetype != MachO::MH_OBJECT && strncmp(sg_segname, segname, 16) != 0)
7763     outs() << " (does not match segment)\n";
7764   else
7765     outs() << "\n";
7766   if (cmd == MachO::LC_SEGMENT_64) {
7767     outs() << "      addr " << format("0x%016" PRIx64, addr) << "\n";
7768     outs() << "      size " << format("0x%016" PRIx64, size);
7769   } else {
7770     outs() << "      addr " << format("0x%08" PRIx64, addr) << "\n";
7771     outs() << "      size " << format("0x%08" PRIx64, size);
7772   }
7773   if ((flags & MachO::S_ZEROFILL) != 0 && offset + size > object_size)
7774     outs() << " (past end of file)\n";
7775   else
7776     outs() << "\n";
7777   outs() << "    offset " << offset;
7778   if (offset > object_size)
7779     outs() << " (past end of file)\n";
7780   else
7781     outs() << "\n";
7782   uint32_t align_shifted = 1 << align;
7783   outs() << "     align 2^" << align << " (" << align_shifted << ")\n";
7784   outs() << "    reloff " << reloff;
7785   if (reloff > object_size)
7786     outs() << " (past end of file)\n";
7787   else
7788     outs() << "\n";
7789   outs() << "    nreloc " << nreloc;
7790   if (reloff + nreloc * sizeof(struct MachO::relocation_info) > object_size)
7791     outs() << " (past end of file)\n";
7792   else
7793     outs() << "\n";
7794   uint32_t section_type = flags & MachO::SECTION_TYPE;
7795   if (verbose) {
7796     outs() << "      type";
7797     if (section_type == MachO::S_REGULAR)
7798       outs() << " S_REGULAR\n";
7799     else if (section_type == MachO::S_ZEROFILL)
7800       outs() << " S_ZEROFILL\n";
7801     else if (section_type == MachO::S_CSTRING_LITERALS)
7802       outs() << " S_CSTRING_LITERALS\n";
7803     else if (section_type == MachO::S_4BYTE_LITERALS)
7804       outs() << " S_4BYTE_LITERALS\n";
7805     else if (section_type == MachO::S_8BYTE_LITERALS)
7806       outs() << " S_8BYTE_LITERALS\n";
7807     else if (section_type == MachO::S_16BYTE_LITERALS)
7808       outs() << " S_16BYTE_LITERALS\n";
7809     else if (section_type == MachO::S_LITERAL_POINTERS)
7810       outs() << " S_LITERAL_POINTERS\n";
7811     else if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS)
7812       outs() << " S_NON_LAZY_SYMBOL_POINTERS\n";
7813     else if (section_type == MachO::S_LAZY_SYMBOL_POINTERS)
7814       outs() << " S_LAZY_SYMBOL_POINTERS\n";
7815     else if (section_type == MachO::S_SYMBOL_STUBS)
7816       outs() << " S_SYMBOL_STUBS\n";
7817     else if (section_type == MachO::S_MOD_INIT_FUNC_POINTERS)
7818       outs() << " S_MOD_INIT_FUNC_POINTERS\n";
7819     else if (section_type == MachO::S_MOD_TERM_FUNC_POINTERS)
7820       outs() << " S_MOD_TERM_FUNC_POINTERS\n";
7821     else if (section_type == MachO::S_COALESCED)
7822       outs() << " S_COALESCED\n";
7823     else if (section_type == MachO::S_INTERPOSING)
7824       outs() << " S_INTERPOSING\n";
7825     else if (section_type == MachO::S_DTRACE_DOF)
7826       outs() << " S_DTRACE_DOF\n";
7827     else if (section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS)
7828       outs() << " S_LAZY_DYLIB_SYMBOL_POINTERS\n";
7829     else if (section_type == MachO::S_THREAD_LOCAL_REGULAR)
7830       outs() << " S_THREAD_LOCAL_REGULAR\n";
7831     else if (section_type == MachO::S_THREAD_LOCAL_ZEROFILL)
7832       outs() << " S_THREAD_LOCAL_ZEROFILL\n";
7833     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLES)
7834       outs() << " S_THREAD_LOCAL_VARIABLES\n";
7835     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
7836       outs() << " S_THREAD_LOCAL_VARIABLE_POINTERS\n";
7837     else if (section_type == MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS)
7838       outs() << " S_THREAD_LOCAL_INIT_FUNCTION_POINTERS\n";
7839     else
7840       outs() << format("0x%08" PRIx32, section_type) << "\n";
7841     outs() << "attributes";
7842     uint32_t section_attributes = flags & MachO::SECTION_ATTRIBUTES;
7843     if (section_attributes & MachO::S_ATTR_PURE_INSTRUCTIONS)
7844       outs() << " PURE_INSTRUCTIONS";
7845     if (section_attributes & MachO::S_ATTR_NO_TOC)
7846       outs() << " NO_TOC";
7847     if (section_attributes & MachO::S_ATTR_STRIP_STATIC_SYMS)
7848       outs() << " STRIP_STATIC_SYMS";
7849     if (section_attributes & MachO::S_ATTR_NO_DEAD_STRIP)
7850       outs() << " NO_DEAD_STRIP";
7851     if (section_attributes & MachO::S_ATTR_LIVE_SUPPORT)
7852       outs() << " LIVE_SUPPORT";
7853     if (section_attributes & MachO::S_ATTR_SELF_MODIFYING_CODE)
7854       outs() << " SELF_MODIFYING_CODE";
7855     if (section_attributes & MachO::S_ATTR_DEBUG)
7856       outs() << " DEBUG";
7857     if (section_attributes & MachO::S_ATTR_SOME_INSTRUCTIONS)
7858       outs() << " SOME_INSTRUCTIONS";
7859     if (section_attributes & MachO::S_ATTR_EXT_RELOC)
7860       outs() << " EXT_RELOC";
7861     if (section_attributes & MachO::S_ATTR_LOC_RELOC)
7862       outs() << " LOC_RELOC";
7863     if (section_attributes == 0)
7864       outs() << " (none)";
7865     outs() << "\n";
7866   } else
7867     outs() << "     flags " << format("0x%08" PRIx32, flags) << "\n";
7868   outs() << " reserved1 " << reserved1;
7869   if (section_type == MachO::S_SYMBOL_STUBS ||
7870       section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
7871       section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
7872       section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
7873       section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
7874     outs() << " (index into indirect symbol table)\n";
7875   else
7876     outs() << "\n";
7877   outs() << " reserved2 " << reserved2;
7878   if (section_type == MachO::S_SYMBOL_STUBS)
7879     outs() << " (size of stubs)\n";
7880   else
7881     outs() << "\n";
7882 }
7883 
7884 static void PrintSymtabLoadCommand(MachO::symtab_command st, bool Is64Bit,
7885                                    uint32_t object_size) {
7886   outs() << "     cmd LC_SYMTAB\n";
7887   outs() << " cmdsize " << st.cmdsize;
7888   if (st.cmdsize != sizeof(struct MachO::symtab_command))
7889     outs() << " Incorrect size\n";
7890   else
7891     outs() << "\n";
7892   outs() << "  symoff " << st.symoff;
7893   if (st.symoff > object_size)
7894     outs() << " (past end of file)\n";
7895   else
7896     outs() << "\n";
7897   outs() << "   nsyms " << st.nsyms;
7898   uint64_t big_size;
7899   if (Is64Bit) {
7900     big_size = st.nsyms;
7901     big_size *= sizeof(struct MachO::nlist_64);
7902     big_size += st.symoff;
7903     if (big_size > object_size)
7904       outs() << " (past end of file)\n";
7905     else
7906       outs() << "\n";
7907   } else {
7908     big_size = st.nsyms;
7909     big_size *= sizeof(struct MachO::nlist);
7910     big_size += st.symoff;
7911     if (big_size > object_size)
7912       outs() << " (past end of file)\n";
7913     else
7914       outs() << "\n";
7915   }
7916   outs() << "  stroff " << st.stroff;
7917   if (st.stroff > object_size)
7918     outs() << " (past end of file)\n";
7919   else
7920     outs() << "\n";
7921   outs() << " strsize " << st.strsize;
7922   big_size = st.stroff;
7923   big_size += st.strsize;
7924   if (big_size > object_size)
7925     outs() << " (past end of file)\n";
7926   else
7927     outs() << "\n";
7928 }
7929 
7930 static void PrintDysymtabLoadCommand(MachO::dysymtab_command dyst,
7931                                      uint32_t nsyms, uint32_t object_size,
7932                                      bool Is64Bit) {
7933   outs() << "            cmd LC_DYSYMTAB\n";
7934   outs() << "        cmdsize " << dyst.cmdsize;
7935   if (dyst.cmdsize != sizeof(struct MachO::dysymtab_command))
7936     outs() << " Incorrect size\n";
7937   else
7938     outs() << "\n";
7939   outs() << "      ilocalsym " << dyst.ilocalsym;
7940   if (dyst.ilocalsym > nsyms)
7941     outs() << " (greater than the number of symbols)\n";
7942   else
7943     outs() << "\n";
7944   outs() << "      nlocalsym " << dyst.nlocalsym;
7945   uint64_t big_size;
7946   big_size = dyst.ilocalsym;
7947   big_size += dyst.nlocalsym;
7948   if (big_size > nsyms)
7949     outs() << " (past the end of the symbol table)\n";
7950   else
7951     outs() << "\n";
7952   outs() << "     iextdefsym " << dyst.iextdefsym;
7953   if (dyst.iextdefsym > nsyms)
7954     outs() << " (greater than the number of symbols)\n";
7955   else
7956     outs() << "\n";
7957   outs() << "     nextdefsym " << dyst.nextdefsym;
7958   big_size = dyst.iextdefsym;
7959   big_size += dyst.nextdefsym;
7960   if (big_size > nsyms)
7961     outs() << " (past the end of the symbol table)\n";
7962   else
7963     outs() << "\n";
7964   outs() << "      iundefsym " << dyst.iundefsym;
7965   if (dyst.iundefsym > nsyms)
7966     outs() << " (greater than the number of symbols)\n";
7967   else
7968     outs() << "\n";
7969   outs() << "      nundefsym " << dyst.nundefsym;
7970   big_size = dyst.iundefsym;
7971   big_size += dyst.nundefsym;
7972   if (big_size > nsyms)
7973     outs() << " (past the end of the symbol table)\n";
7974   else
7975     outs() << "\n";
7976   outs() << "         tocoff " << dyst.tocoff;
7977   if (dyst.tocoff > object_size)
7978     outs() << " (past end of file)\n";
7979   else
7980     outs() << "\n";
7981   outs() << "           ntoc " << dyst.ntoc;
7982   big_size = dyst.ntoc;
7983   big_size *= sizeof(struct MachO::dylib_table_of_contents);
7984   big_size += dyst.tocoff;
7985   if (big_size > object_size)
7986     outs() << " (past end of file)\n";
7987   else
7988     outs() << "\n";
7989   outs() << "      modtaboff " << dyst.modtaboff;
7990   if (dyst.modtaboff > object_size)
7991     outs() << " (past end of file)\n";
7992   else
7993     outs() << "\n";
7994   outs() << "        nmodtab " << dyst.nmodtab;
7995   uint64_t modtabend;
7996   if (Is64Bit) {
7997     modtabend = dyst.nmodtab;
7998     modtabend *= sizeof(struct MachO::dylib_module_64);
7999     modtabend += dyst.modtaboff;
8000   } else {
8001     modtabend = dyst.nmodtab;
8002     modtabend *= sizeof(struct MachO::dylib_module);
8003     modtabend += dyst.modtaboff;
8004   }
8005   if (modtabend > object_size)
8006     outs() << " (past end of file)\n";
8007   else
8008     outs() << "\n";
8009   outs() << "   extrefsymoff " << dyst.extrefsymoff;
8010   if (dyst.extrefsymoff > object_size)
8011     outs() << " (past end of file)\n";
8012   else
8013     outs() << "\n";
8014   outs() << "    nextrefsyms " << dyst.nextrefsyms;
8015   big_size = dyst.nextrefsyms;
8016   big_size *= sizeof(struct MachO::dylib_reference);
8017   big_size += dyst.extrefsymoff;
8018   if (big_size > object_size)
8019     outs() << " (past end of file)\n";
8020   else
8021     outs() << "\n";
8022   outs() << " indirectsymoff " << dyst.indirectsymoff;
8023   if (dyst.indirectsymoff > object_size)
8024     outs() << " (past end of file)\n";
8025   else
8026     outs() << "\n";
8027   outs() << "  nindirectsyms " << dyst.nindirectsyms;
8028   big_size = dyst.nindirectsyms;
8029   big_size *= sizeof(uint32_t);
8030   big_size += dyst.indirectsymoff;
8031   if (big_size > object_size)
8032     outs() << " (past end of file)\n";
8033   else
8034     outs() << "\n";
8035   outs() << "      extreloff " << dyst.extreloff;
8036   if (dyst.extreloff > object_size)
8037     outs() << " (past end of file)\n";
8038   else
8039     outs() << "\n";
8040   outs() << "        nextrel " << dyst.nextrel;
8041   big_size = dyst.nextrel;
8042   big_size *= sizeof(struct MachO::relocation_info);
8043   big_size += dyst.extreloff;
8044   if (big_size > object_size)
8045     outs() << " (past end of file)\n";
8046   else
8047     outs() << "\n";
8048   outs() << "      locreloff " << dyst.locreloff;
8049   if (dyst.locreloff > object_size)
8050     outs() << " (past end of file)\n";
8051   else
8052     outs() << "\n";
8053   outs() << "        nlocrel " << dyst.nlocrel;
8054   big_size = dyst.nlocrel;
8055   big_size *= sizeof(struct MachO::relocation_info);
8056   big_size += dyst.locreloff;
8057   if (big_size > object_size)
8058     outs() << " (past end of file)\n";
8059   else
8060     outs() << "\n";
8061 }
8062 
8063 static void PrintDyldInfoLoadCommand(MachO::dyld_info_command dc,
8064                                      uint32_t object_size) {
8065   if (dc.cmd == MachO::LC_DYLD_INFO)
8066     outs() << "            cmd LC_DYLD_INFO\n";
8067   else
8068     outs() << "            cmd LC_DYLD_INFO_ONLY\n";
8069   outs() << "        cmdsize " << dc.cmdsize;
8070   if (dc.cmdsize != sizeof(struct MachO::dyld_info_command))
8071     outs() << " Incorrect size\n";
8072   else
8073     outs() << "\n";
8074   outs() << "     rebase_off " << dc.rebase_off;
8075   if (dc.rebase_off > object_size)
8076     outs() << " (past end of file)\n";
8077   else
8078     outs() << "\n";
8079   outs() << "    rebase_size " << dc.rebase_size;
8080   uint64_t big_size;
8081   big_size = dc.rebase_off;
8082   big_size += dc.rebase_size;
8083   if (big_size > object_size)
8084     outs() << " (past end of file)\n";
8085   else
8086     outs() << "\n";
8087   outs() << "       bind_off " << dc.bind_off;
8088   if (dc.bind_off > object_size)
8089     outs() << " (past end of file)\n";
8090   else
8091     outs() << "\n";
8092   outs() << "      bind_size " << dc.bind_size;
8093   big_size = dc.bind_off;
8094   big_size += dc.bind_size;
8095   if (big_size > object_size)
8096     outs() << " (past end of file)\n";
8097   else
8098     outs() << "\n";
8099   outs() << "  weak_bind_off " << dc.weak_bind_off;
8100   if (dc.weak_bind_off > object_size)
8101     outs() << " (past end of file)\n";
8102   else
8103     outs() << "\n";
8104   outs() << " weak_bind_size " << dc.weak_bind_size;
8105   big_size = dc.weak_bind_off;
8106   big_size += dc.weak_bind_size;
8107   if (big_size > object_size)
8108     outs() << " (past end of file)\n";
8109   else
8110     outs() << "\n";
8111   outs() << "  lazy_bind_off " << dc.lazy_bind_off;
8112   if (dc.lazy_bind_off > object_size)
8113     outs() << " (past end of file)\n";
8114   else
8115     outs() << "\n";
8116   outs() << " lazy_bind_size " << dc.lazy_bind_size;
8117   big_size = dc.lazy_bind_off;
8118   big_size += dc.lazy_bind_size;
8119   if (big_size > object_size)
8120     outs() << " (past end of file)\n";
8121   else
8122     outs() << "\n";
8123   outs() << "     export_off " << dc.export_off;
8124   if (dc.export_off > object_size)
8125     outs() << " (past end of file)\n";
8126   else
8127     outs() << "\n";
8128   outs() << "    export_size " << dc.export_size;
8129   big_size = dc.export_off;
8130   big_size += dc.export_size;
8131   if (big_size > object_size)
8132     outs() << " (past end of file)\n";
8133   else
8134     outs() << "\n";
8135 }
8136 
8137 static void PrintDyldLoadCommand(MachO::dylinker_command dyld,
8138                                  const char *Ptr) {
8139   if (dyld.cmd == MachO::LC_ID_DYLINKER)
8140     outs() << "          cmd LC_ID_DYLINKER\n";
8141   else if (dyld.cmd == MachO::LC_LOAD_DYLINKER)
8142     outs() << "          cmd LC_LOAD_DYLINKER\n";
8143   else if (dyld.cmd == MachO::LC_DYLD_ENVIRONMENT)
8144     outs() << "          cmd LC_DYLD_ENVIRONMENT\n";
8145   else
8146     outs() << "          cmd ?(" << dyld.cmd << ")\n";
8147   outs() << "      cmdsize " << dyld.cmdsize;
8148   if (dyld.cmdsize < sizeof(struct MachO::dylinker_command))
8149     outs() << " Incorrect size\n";
8150   else
8151     outs() << "\n";
8152   if (dyld.name >= dyld.cmdsize)
8153     outs() << "         name ?(bad offset " << dyld.name << ")\n";
8154   else {
8155     const char *P = (const char *)(Ptr) + dyld.name;
8156     outs() << "         name " << P << " (offset " << dyld.name << ")\n";
8157   }
8158 }
8159 
8160 static void PrintUuidLoadCommand(MachO::uuid_command uuid) {
8161   outs() << "     cmd LC_UUID\n";
8162   outs() << " cmdsize " << uuid.cmdsize;
8163   if (uuid.cmdsize != sizeof(struct MachO::uuid_command))
8164     outs() << " Incorrect size\n";
8165   else
8166     outs() << "\n";
8167   outs() << "    uuid ";
8168   for (int i = 0; i < 16; ++i) {
8169     outs() << format("%02" PRIX32, uuid.uuid[i]);
8170     if (i == 3 || i == 5 || i == 7 || i == 9)
8171       outs() << "-";
8172   }
8173   outs() << "\n";
8174 }
8175 
8176 static void PrintRpathLoadCommand(MachO::rpath_command rpath, const char *Ptr) {
8177   outs() << "          cmd LC_RPATH\n";
8178   outs() << "      cmdsize " << rpath.cmdsize;
8179   if (rpath.cmdsize < sizeof(struct MachO::rpath_command))
8180     outs() << " Incorrect size\n";
8181   else
8182     outs() << "\n";
8183   if (rpath.path >= rpath.cmdsize)
8184     outs() << "         path ?(bad offset " << rpath.path << ")\n";
8185   else {
8186     const char *P = (const char *)(Ptr) + rpath.path;
8187     outs() << "         path " << P << " (offset " << rpath.path << ")\n";
8188   }
8189 }
8190 
8191 static void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
8192   StringRef LoadCmdName;
8193   switch (vd.cmd) {
8194   case MachO::LC_VERSION_MIN_MACOSX:
8195     LoadCmdName = "LC_VERSION_MIN_MACOSX";
8196     break;
8197   case MachO::LC_VERSION_MIN_IPHONEOS:
8198     LoadCmdName = "LC_VERSION_MIN_IPHONEOS";
8199     break;
8200   case MachO::LC_VERSION_MIN_TVOS:
8201     LoadCmdName = "LC_VERSION_MIN_TVOS";
8202     break;
8203   case MachO::LC_VERSION_MIN_WATCHOS:
8204     LoadCmdName = "LC_VERSION_MIN_WATCHOS";
8205     break;
8206   default:
8207     llvm_unreachable("Unknown version min load command");
8208   }
8209 
8210   outs() << "      cmd " << LoadCmdName << '\n';
8211   outs() << "  cmdsize " << vd.cmdsize;
8212   if (vd.cmdsize != sizeof(struct MachO::version_min_command))
8213     outs() << " Incorrect size\n";
8214   else
8215     outs() << "\n";
8216   outs() << "  version "
8217          << MachOObjectFile::getVersionMinMajor(vd, false) << "."
8218          << MachOObjectFile::getVersionMinMinor(vd, false);
8219   uint32_t Update = MachOObjectFile::getVersionMinUpdate(vd, false);
8220   if (Update != 0)
8221     outs() << "." << Update;
8222   outs() << "\n";
8223   if (vd.sdk == 0)
8224     outs() << "      sdk n/a";
8225   else {
8226     outs() << "      sdk "
8227            << MachOObjectFile::getVersionMinMajor(vd, true) << "."
8228            << MachOObjectFile::getVersionMinMinor(vd, true);
8229   }
8230   Update = MachOObjectFile::getVersionMinUpdate(vd, true);
8231   if (Update != 0)
8232     outs() << "." << Update;
8233   outs() << "\n";
8234 }
8235 
8236 static void PrintNoteLoadCommand(MachO::note_command Nt) {
8237   outs() << "       cmd LC_NOTE\n";
8238   outs() << "   cmdsize " << Nt.cmdsize;
8239   if (Nt.cmdsize != sizeof(struct MachO::note_command))
8240     outs() << " Incorrect size\n";
8241   else
8242     outs() << "\n";
8243   const char *d = Nt.data_owner;
8244   outs() << "data_owner " << format("%.16s\n", d);
8245   outs() << "    offset " << Nt.offset << "\n";
8246   outs() << "      size " << Nt.size << "\n";
8247 }
8248 
8249 static void PrintBuildToolVersion(MachO::build_tool_version bv) {
8250   outs() << "      tool " << MachOObjectFile::getBuildTool(bv.tool) << "\n";
8251   outs() << "   version " << MachOObjectFile::getVersionString(bv.version)
8252          << "\n";
8253 }
8254 
8255 static void PrintBuildVersionLoadCommand(const MachOObjectFile *obj,
8256                                          MachO::build_version_command bd) {
8257   outs() << "       cmd LC_BUILD_VERSION\n";
8258   outs() << "   cmdsize " << bd.cmdsize;
8259   if (bd.cmdsize !=
8260       sizeof(struct MachO::build_version_command) +
8261           bd.ntools * sizeof(struct MachO::build_tool_version))
8262     outs() << " Incorrect size\n";
8263   else
8264     outs() << "\n";
8265   outs() << "  platform " << MachOObjectFile::getBuildPlatform(bd.platform)
8266          << "\n";
8267   if (bd.sdk)
8268     outs() << "       sdk " << MachOObjectFile::getVersionString(bd.sdk)
8269            << "\n";
8270   else
8271     outs() << "       sdk n/a\n";
8272   outs() << "     minos " << MachOObjectFile::getVersionString(bd.minos)
8273          << "\n";
8274   outs() << "    ntools " << bd.ntools << "\n";
8275   for (unsigned i = 0; i < bd.ntools; ++i) {
8276     MachO::build_tool_version bv = obj->getBuildToolVersion(i);
8277     PrintBuildToolVersion(bv);
8278   }
8279 }
8280 
8281 static void PrintSourceVersionCommand(MachO::source_version_command sd) {
8282   outs() << "      cmd LC_SOURCE_VERSION\n";
8283   outs() << "  cmdsize " << sd.cmdsize;
8284   if (sd.cmdsize != sizeof(struct MachO::source_version_command))
8285     outs() << " Incorrect size\n";
8286   else
8287     outs() << "\n";
8288   uint64_t a = (sd.version >> 40) & 0xffffff;
8289   uint64_t b = (sd.version >> 30) & 0x3ff;
8290   uint64_t c = (sd.version >> 20) & 0x3ff;
8291   uint64_t d = (sd.version >> 10) & 0x3ff;
8292   uint64_t e = sd.version & 0x3ff;
8293   outs() << "  version " << a << "." << b;
8294   if (e != 0)
8295     outs() << "." << c << "." << d << "." << e;
8296   else if (d != 0)
8297     outs() << "." << c << "." << d;
8298   else if (c != 0)
8299     outs() << "." << c;
8300   outs() << "\n";
8301 }
8302 
8303 static void PrintEntryPointCommand(MachO::entry_point_command ep) {
8304   outs() << "       cmd LC_MAIN\n";
8305   outs() << "   cmdsize " << ep.cmdsize;
8306   if (ep.cmdsize != sizeof(struct MachO::entry_point_command))
8307     outs() << " Incorrect size\n";
8308   else
8309     outs() << "\n";
8310   outs() << "  entryoff " << ep.entryoff << "\n";
8311   outs() << " stacksize " << ep.stacksize << "\n";
8312 }
8313 
8314 static void PrintEncryptionInfoCommand(MachO::encryption_info_command ec,
8315                                        uint32_t object_size) {
8316   outs() << "          cmd LC_ENCRYPTION_INFO\n";
8317   outs() << "      cmdsize " << ec.cmdsize;
8318   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command))
8319     outs() << " Incorrect size\n";
8320   else
8321     outs() << "\n";
8322   outs() << "     cryptoff " << ec.cryptoff;
8323   if (ec.cryptoff > object_size)
8324     outs() << " (past end of file)\n";
8325   else
8326     outs() << "\n";
8327   outs() << "    cryptsize " << ec.cryptsize;
8328   if (ec.cryptsize > object_size)
8329     outs() << " (past end of file)\n";
8330   else
8331     outs() << "\n";
8332   outs() << "      cryptid " << ec.cryptid << "\n";
8333 }
8334 
8335 static void PrintEncryptionInfoCommand64(MachO::encryption_info_command_64 ec,
8336                                          uint32_t object_size) {
8337   outs() << "          cmd LC_ENCRYPTION_INFO_64\n";
8338   outs() << "      cmdsize " << ec.cmdsize;
8339   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command_64))
8340     outs() << " Incorrect size\n";
8341   else
8342     outs() << "\n";
8343   outs() << "     cryptoff " << ec.cryptoff;
8344   if (ec.cryptoff > object_size)
8345     outs() << " (past end of file)\n";
8346   else
8347     outs() << "\n";
8348   outs() << "    cryptsize " << ec.cryptsize;
8349   if (ec.cryptsize > object_size)
8350     outs() << " (past end of file)\n";
8351   else
8352     outs() << "\n";
8353   outs() << "      cryptid " << ec.cryptid << "\n";
8354   outs() << "          pad " << ec.pad << "\n";
8355 }
8356 
8357 static void PrintLinkerOptionCommand(MachO::linker_option_command lo,
8358                                      const char *Ptr) {
8359   outs() << "     cmd LC_LINKER_OPTION\n";
8360   outs() << " cmdsize " << lo.cmdsize;
8361   if (lo.cmdsize < sizeof(struct MachO::linker_option_command))
8362     outs() << " Incorrect size\n";
8363   else
8364     outs() << "\n";
8365   outs() << "   count " << lo.count << "\n";
8366   const char *string = Ptr + sizeof(struct MachO::linker_option_command);
8367   uint32_t left = lo.cmdsize - sizeof(struct MachO::linker_option_command);
8368   uint32_t i = 0;
8369   while (left > 0) {
8370     while (*string == '\0' && left > 0) {
8371       string++;
8372       left--;
8373     }
8374     if (left > 0) {
8375       i++;
8376       outs() << "  string #" << i << " " << format("%.*s\n", left, string);
8377       uint32_t NullPos = StringRef(string, left).find('\0');
8378       uint32_t len = std::min(NullPos, left) + 1;
8379       string += len;
8380       left -= len;
8381     }
8382   }
8383   if (lo.count != i)
8384     outs() << "   count " << lo.count << " does not match number of strings "
8385            << i << "\n";
8386 }
8387 
8388 static void PrintSubFrameworkCommand(MachO::sub_framework_command sub,
8389                                      const char *Ptr) {
8390   outs() << "          cmd LC_SUB_FRAMEWORK\n";
8391   outs() << "      cmdsize " << sub.cmdsize;
8392   if (sub.cmdsize < sizeof(struct MachO::sub_framework_command))
8393     outs() << " Incorrect size\n";
8394   else
8395     outs() << "\n";
8396   if (sub.umbrella < sub.cmdsize) {
8397     const char *P = Ptr + sub.umbrella;
8398     outs() << "     umbrella " << P << " (offset " << sub.umbrella << ")\n";
8399   } else {
8400     outs() << "     umbrella ?(bad offset " << sub.umbrella << ")\n";
8401   }
8402 }
8403 
8404 static void PrintSubUmbrellaCommand(MachO::sub_umbrella_command sub,
8405                                     const char *Ptr) {
8406   outs() << "          cmd LC_SUB_UMBRELLA\n";
8407   outs() << "      cmdsize " << sub.cmdsize;
8408   if (sub.cmdsize < sizeof(struct MachO::sub_umbrella_command))
8409     outs() << " Incorrect size\n";
8410   else
8411     outs() << "\n";
8412   if (sub.sub_umbrella < sub.cmdsize) {
8413     const char *P = Ptr + sub.sub_umbrella;
8414     outs() << " sub_umbrella " << P << " (offset " << sub.sub_umbrella << ")\n";
8415   } else {
8416     outs() << " sub_umbrella ?(bad offset " << sub.sub_umbrella << ")\n";
8417   }
8418 }
8419 
8420 static void PrintSubLibraryCommand(MachO::sub_library_command sub,
8421                                    const char *Ptr) {
8422   outs() << "          cmd LC_SUB_LIBRARY\n";
8423   outs() << "      cmdsize " << sub.cmdsize;
8424   if (sub.cmdsize < sizeof(struct MachO::sub_library_command))
8425     outs() << " Incorrect size\n";
8426   else
8427     outs() << "\n";
8428   if (sub.sub_library < sub.cmdsize) {
8429     const char *P = Ptr + sub.sub_library;
8430     outs() << "  sub_library " << P << " (offset " << sub.sub_library << ")\n";
8431   } else {
8432     outs() << "  sub_library ?(bad offset " << sub.sub_library << ")\n";
8433   }
8434 }
8435 
8436 static void PrintSubClientCommand(MachO::sub_client_command sub,
8437                                   const char *Ptr) {
8438   outs() << "          cmd LC_SUB_CLIENT\n";
8439   outs() << "      cmdsize " << sub.cmdsize;
8440   if (sub.cmdsize < sizeof(struct MachO::sub_client_command))
8441     outs() << " Incorrect size\n";
8442   else
8443     outs() << "\n";
8444   if (sub.client < sub.cmdsize) {
8445     const char *P = Ptr + sub.client;
8446     outs() << "       client " << P << " (offset " << sub.client << ")\n";
8447   } else {
8448     outs() << "       client ?(bad offset " << sub.client << ")\n";
8449   }
8450 }
8451 
8452 static void PrintRoutinesCommand(MachO::routines_command r) {
8453   outs() << "          cmd LC_ROUTINES\n";
8454   outs() << "      cmdsize " << r.cmdsize;
8455   if (r.cmdsize != sizeof(struct MachO::routines_command))
8456     outs() << " Incorrect size\n";
8457   else
8458     outs() << "\n";
8459   outs() << " init_address " << format("0x%08" PRIx32, r.init_address) << "\n";
8460   outs() << "  init_module " << r.init_module << "\n";
8461   outs() << "    reserved1 " << r.reserved1 << "\n";
8462   outs() << "    reserved2 " << r.reserved2 << "\n";
8463   outs() << "    reserved3 " << r.reserved3 << "\n";
8464   outs() << "    reserved4 " << r.reserved4 << "\n";
8465   outs() << "    reserved5 " << r.reserved5 << "\n";
8466   outs() << "    reserved6 " << r.reserved6 << "\n";
8467 }
8468 
8469 static void PrintRoutinesCommand64(MachO::routines_command_64 r) {
8470   outs() << "          cmd LC_ROUTINES_64\n";
8471   outs() << "      cmdsize " << r.cmdsize;
8472   if (r.cmdsize != sizeof(struct MachO::routines_command_64))
8473     outs() << " Incorrect size\n";
8474   else
8475     outs() << "\n";
8476   outs() << " init_address " << format("0x%016" PRIx64, r.init_address) << "\n";
8477   outs() << "  init_module " << r.init_module << "\n";
8478   outs() << "    reserved1 " << r.reserved1 << "\n";
8479   outs() << "    reserved2 " << r.reserved2 << "\n";
8480   outs() << "    reserved3 " << r.reserved3 << "\n";
8481   outs() << "    reserved4 " << r.reserved4 << "\n";
8482   outs() << "    reserved5 " << r.reserved5 << "\n";
8483   outs() << "    reserved6 " << r.reserved6 << "\n";
8484 }
8485 
8486 static void Print_x86_thread_state32_t(MachO::x86_thread_state32_t &cpu32) {
8487   outs() << "\t    eax " << format("0x%08" PRIx32, cpu32.eax);
8488   outs() << " ebx    " << format("0x%08" PRIx32, cpu32.ebx);
8489   outs() << " ecx " << format("0x%08" PRIx32, cpu32.ecx);
8490   outs() << " edx " << format("0x%08" PRIx32, cpu32.edx) << "\n";
8491   outs() << "\t    edi " << format("0x%08" PRIx32, cpu32.edi);
8492   outs() << " esi    " << format("0x%08" PRIx32, cpu32.esi);
8493   outs() << " ebp " << format("0x%08" PRIx32, cpu32.ebp);
8494   outs() << " esp " << format("0x%08" PRIx32, cpu32.esp) << "\n";
8495   outs() << "\t    ss  " << format("0x%08" PRIx32, cpu32.ss);
8496   outs() << " eflags " << format("0x%08" PRIx32, cpu32.eflags);
8497   outs() << " eip " << format("0x%08" PRIx32, cpu32.eip);
8498   outs() << " cs  " << format("0x%08" PRIx32, cpu32.cs) << "\n";
8499   outs() << "\t    ds  " << format("0x%08" PRIx32, cpu32.ds);
8500   outs() << " es     " << format("0x%08" PRIx32, cpu32.es);
8501   outs() << " fs  " << format("0x%08" PRIx32, cpu32.fs);
8502   outs() << " gs  " << format("0x%08" PRIx32, cpu32.gs) << "\n";
8503 }
8504 
8505 static void Print_x86_thread_state64_t(MachO::x86_thread_state64_t &cpu64) {
8506   outs() << "   rax  " << format("0x%016" PRIx64, cpu64.rax);
8507   outs() << " rbx " << format("0x%016" PRIx64, cpu64.rbx);
8508   outs() << " rcx  " << format("0x%016" PRIx64, cpu64.rcx) << "\n";
8509   outs() << "   rdx  " << format("0x%016" PRIx64, cpu64.rdx);
8510   outs() << " rdi " << format("0x%016" PRIx64, cpu64.rdi);
8511   outs() << " rsi  " << format("0x%016" PRIx64, cpu64.rsi) << "\n";
8512   outs() << "   rbp  " << format("0x%016" PRIx64, cpu64.rbp);
8513   outs() << " rsp " << format("0x%016" PRIx64, cpu64.rsp);
8514   outs() << " r8   " << format("0x%016" PRIx64, cpu64.r8) << "\n";
8515   outs() << "    r9  " << format("0x%016" PRIx64, cpu64.r9);
8516   outs() << " r10 " << format("0x%016" PRIx64, cpu64.r10);
8517   outs() << " r11  " << format("0x%016" PRIx64, cpu64.r11) << "\n";
8518   outs() << "   r12  " << format("0x%016" PRIx64, cpu64.r12);
8519   outs() << " r13 " << format("0x%016" PRIx64, cpu64.r13);
8520   outs() << " r14  " << format("0x%016" PRIx64, cpu64.r14) << "\n";
8521   outs() << "   r15  " << format("0x%016" PRIx64, cpu64.r15);
8522   outs() << " rip " << format("0x%016" PRIx64, cpu64.rip) << "\n";
8523   outs() << "rflags  " << format("0x%016" PRIx64, cpu64.rflags);
8524   outs() << " cs  " << format("0x%016" PRIx64, cpu64.cs);
8525   outs() << " fs   " << format("0x%016" PRIx64, cpu64.fs) << "\n";
8526   outs() << "    gs  " << format("0x%016" PRIx64, cpu64.gs) << "\n";
8527 }
8528 
8529 static void Print_mmst_reg(MachO::mmst_reg_t &r) {
8530   uint32_t f;
8531   outs() << "\t      mmst_reg  ";
8532   for (f = 0; f < 10; f++)
8533     outs() << format("%02" PRIx32, (r.mmst_reg[f] & 0xff)) << " ";
8534   outs() << "\n";
8535   outs() << "\t      mmst_rsrv ";
8536   for (f = 0; f < 6; f++)
8537     outs() << format("%02" PRIx32, (r.mmst_rsrv[f] & 0xff)) << " ";
8538   outs() << "\n";
8539 }
8540 
8541 static void Print_xmm_reg(MachO::xmm_reg_t &r) {
8542   uint32_t f;
8543   outs() << "\t      xmm_reg ";
8544   for (f = 0; f < 16; f++)
8545     outs() << format("%02" PRIx32, (r.xmm_reg[f] & 0xff)) << " ";
8546   outs() << "\n";
8547 }
8548 
8549 static void Print_x86_float_state_t(MachO::x86_float_state64_t &fpu) {
8550   outs() << "\t    fpu_reserved[0] " << fpu.fpu_reserved[0];
8551   outs() << " fpu_reserved[1] " << fpu.fpu_reserved[1] << "\n";
8552   outs() << "\t    control: invalid " << fpu.fpu_fcw.invalid;
8553   outs() << " denorm " << fpu.fpu_fcw.denorm;
8554   outs() << " zdiv " << fpu.fpu_fcw.zdiv;
8555   outs() << " ovrfl " << fpu.fpu_fcw.ovrfl;
8556   outs() << " undfl " << fpu.fpu_fcw.undfl;
8557   outs() << " precis " << fpu.fpu_fcw.precis << "\n";
8558   outs() << "\t\t     pc ";
8559   if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_24B)
8560     outs() << "FP_PREC_24B ";
8561   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_53B)
8562     outs() << "FP_PREC_53B ";
8563   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_64B)
8564     outs() << "FP_PREC_64B ";
8565   else
8566     outs() << fpu.fpu_fcw.pc << " ";
8567   outs() << "rc ";
8568   if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_NEAR)
8569     outs() << "FP_RND_NEAR ";
8570   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_DOWN)
8571     outs() << "FP_RND_DOWN ";
8572   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_UP)
8573     outs() << "FP_RND_UP ";
8574   else if (fpu.fpu_fcw.rc == MachO::x86_FP_CHOP)
8575     outs() << "FP_CHOP ";
8576   outs() << "\n";
8577   outs() << "\t    status: invalid " << fpu.fpu_fsw.invalid;
8578   outs() << " denorm " << fpu.fpu_fsw.denorm;
8579   outs() << " zdiv " << fpu.fpu_fsw.zdiv;
8580   outs() << " ovrfl " << fpu.fpu_fsw.ovrfl;
8581   outs() << " undfl " << fpu.fpu_fsw.undfl;
8582   outs() << " precis " << fpu.fpu_fsw.precis;
8583   outs() << " stkflt " << fpu.fpu_fsw.stkflt << "\n";
8584   outs() << "\t            errsumm " << fpu.fpu_fsw.errsumm;
8585   outs() << " c0 " << fpu.fpu_fsw.c0;
8586   outs() << " c1 " << fpu.fpu_fsw.c1;
8587   outs() << " c2 " << fpu.fpu_fsw.c2;
8588   outs() << " tos " << fpu.fpu_fsw.tos;
8589   outs() << " c3 " << fpu.fpu_fsw.c3;
8590   outs() << " busy " << fpu.fpu_fsw.busy << "\n";
8591   outs() << "\t    fpu_ftw " << format("0x%02" PRIx32, fpu.fpu_ftw);
8592   outs() << " fpu_rsrv1 " << format("0x%02" PRIx32, fpu.fpu_rsrv1);
8593   outs() << " fpu_fop " << format("0x%04" PRIx32, fpu.fpu_fop);
8594   outs() << " fpu_ip " << format("0x%08" PRIx32, fpu.fpu_ip) << "\n";
8595   outs() << "\t    fpu_cs " << format("0x%04" PRIx32, fpu.fpu_cs);
8596   outs() << " fpu_rsrv2 " << format("0x%04" PRIx32, fpu.fpu_rsrv2);
8597   outs() << " fpu_dp " << format("0x%08" PRIx32, fpu.fpu_dp);
8598   outs() << " fpu_ds " << format("0x%04" PRIx32, fpu.fpu_ds) << "\n";
8599   outs() << "\t    fpu_rsrv3 " << format("0x%04" PRIx32, fpu.fpu_rsrv3);
8600   outs() << " fpu_mxcsr " << format("0x%08" PRIx32, fpu.fpu_mxcsr);
8601   outs() << " fpu_mxcsrmask " << format("0x%08" PRIx32, fpu.fpu_mxcsrmask);
8602   outs() << "\n";
8603   outs() << "\t    fpu_stmm0:\n";
8604   Print_mmst_reg(fpu.fpu_stmm0);
8605   outs() << "\t    fpu_stmm1:\n";
8606   Print_mmst_reg(fpu.fpu_stmm1);
8607   outs() << "\t    fpu_stmm2:\n";
8608   Print_mmst_reg(fpu.fpu_stmm2);
8609   outs() << "\t    fpu_stmm3:\n";
8610   Print_mmst_reg(fpu.fpu_stmm3);
8611   outs() << "\t    fpu_stmm4:\n";
8612   Print_mmst_reg(fpu.fpu_stmm4);
8613   outs() << "\t    fpu_stmm5:\n";
8614   Print_mmst_reg(fpu.fpu_stmm5);
8615   outs() << "\t    fpu_stmm6:\n";
8616   Print_mmst_reg(fpu.fpu_stmm6);
8617   outs() << "\t    fpu_stmm7:\n";
8618   Print_mmst_reg(fpu.fpu_stmm7);
8619   outs() << "\t    fpu_xmm0:\n";
8620   Print_xmm_reg(fpu.fpu_xmm0);
8621   outs() << "\t    fpu_xmm1:\n";
8622   Print_xmm_reg(fpu.fpu_xmm1);
8623   outs() << "\t    fpu_xmm2:\n";
8624   Print_xmm_reg(fpu.fpu_xmm2);
8625   outs() << "\t    fpu_xmm3:\n";
8626   Print_xmm_reg(fpu.fpu_xmm3);
8627   outs() << "\t    fpu_xmm4:\n";
8628   Print_xmm_reg(fpu.fpu_xmm4);
8629   outs() << "\t    fpu_xmm5:\n";
8630   Print_xmm_reg(fpu.fpu_xmm5);
8631   outs() << "\t    fpu_xmm6:\n";
8632   Print_xmm_reg(fpu.fpu_xmm6);
8633   outs() << "\t    fpu_xmm7:\n";
8634   Print_xmm_reg(fpu.fpu_xmm7);
8635   outs() << "\t    fpu_xmm8:\n";
8636   Print_xmm_reg(fpu.fpu_xmm8);
8637   outs() << "\t    fpu_xmm9:\n";
8638   Print_xmm_reg(fpu.fpu_xmm9);
8639   outs() << "\t    fpu_xmm10:\n";
8640   Print_xmm_reg(fpu.fpu_xmm10);
8641   outs() << "\t    fpu_xmm11:\n";
8642   Print_xmm_reg(fpu.fpu_xmm11);
8643   outs() << "\t    fpu_xmm12:\n";
8644   Print_xmm_reg(fpu.fpu_xmm12);
8645   outs() << "\t    fpu_xmm13:\n";
8646   Print_xmm_reg(fpu.fpu_xmm13);
8647   outs() << "\t    fpu_xmm14:\n";
8648   Print_xmm_reg(fpu.fpu_xmm14);
8649   outs() << "\t    fpu_xmm15:\n";
8650   Print_xmm_reg(fpu.fpu_xmm15);
8651   outs() << "\t    fpu_rsrv4:\n";
8652   for (uint32_t f = 0; f < 6; f++) {
8653     outs() << "\t            ";
8654     for (uint32_t g = 0; g < 16; g++)
8655       outs() << format("%02" PRIx32, fpu.fpu_rsrv4[f * g]) << " ";
8656     outs() << "\n";
8657   }
8658   outs() << "\t    fpu_reserved1 " << format("0x%08" PRIx32, fpu.fpu_reserved1);
8659   outs() << "\n";
8660 }
8661 
8662 static void Print_x86_exception_state_t(MachO::x86_exception_state64_t &exc64) {
8663   outs() << "\t    trapno " << format("0x%08" PRIx32, exc64.trapno);
8664   outs() << " err " << format("0x%08" PRIx32, exc64.err);
8665   outs() << " faultvaddr " << format("0x%016" PRIx64, exc64.faultvaddr) << "\n";
8666 }
8667 
8668 static void Print_arm_thread_state32_t(MachO::arm_thread_state32_t &cpu32) {
8669   outs() << "\t    r0  " << format("0x%08" PRIx32, cpu32.r[0]);
8670   outs() << " r1     "   << format("0x%08" PRIx32, cpu32.r[1]);
8671   outs() << " r2  "      << format("0x%08" PRIx32, cpu32.r[2]);
8672   outs() << " r3  "      << format("0x%08" PRIx32, cpu32.r[3]) << "\n";
8673   outs() << "\t    r4  " << format("0x%08" PRIx32, cpu32.r[4]);
8674   outs() << " r5     "   << format("0x%08" PRIx32, cpu32.r[5]);
8675   outs() << " r6  "      << format("0x%08" PRIx32, cpu32.r[6]);
8676   outs() << " r7  "      << format("0x%08" PRIx32, cpu32.r[7]) << "\n";
8677   outs() << "\t    r8  " << format("0x%08" PRIx32, cpu32.r[8]);
8678   outs() << " r9     "   << format("0x%08" PRIx32, cpu32.r[9]);
8679   outs() << " r10 "      << format("0x%08" PRIx32, cpu32.r[10]);
8680   outs() << " r11 "      << format("0x%08" PRIx32, cpu32.r[11]) << "\n";
8681   outs() << "\t    r12 " << format("0x%08" PRIx32, cpu32.r[12]);
8682   outs() << " sp     "   << format("0x%08" PRIx32, cpu32.sp);
8683   outs() << " lr  "      << format("0x%08" PRIx32, cpu32.lr);
8684   outs() << " pc  "      << format("0x%08" PRIx32, cpu32.pc) << "\n";
8685   outs() << "\t   cpsr " << format("0x%08" PRIx32, cpu32.cpsr) << "\n";
8686 }
8687 
8688 static void Print_arm_thread_state64_t(MachO::arm_thread_state64_t &cpu64) {
8689   outs() << "\t    x0  " << format("0x%016" PRIx64, cpu64.x[0]);
8690   outs() << " x1  "      << format("0x%016" PRIx64, cpu64.x[1]);
8691   outs() << " x2  "      << format("0x%016" PRIx64, cpu64.x[2]) << "\n";
8692   outs() << "\t    x3  " << format("0x%016" PRIx64, cpu64.x[3]);
8693   outs() << " x4  "      << format("0x%016" PRIx64, cpu64.x[4]);
8694   outs() << " x5  "      << format("0x%016" PRIx64, cpu64.x[5]) << "\n";
8695   outs() << "\t    x6  " << format("0x%016" PRIx64, cpu64.x[6]);
8696   outs() << " x7  "      << format("0x%016" PRIx64, cpu64.x[7]);
8697   outs() << " x8  "      << format("0x%016" PRIx64, cpu64.x[8]) << "\n";
8698   outs() << "\t    x9  " << format("0x%016" PRIx64, cpu64.x[9]);
8699   outs() << " x10 "      << format("0x%016" PRIx64, cpu64.x[10]);
8700   outs() << " x11 "      << format("0x%016" PRIx64, cpu64.x[11]) << "\n";
8701   outs() << "\t    x12 " << format("0x%016" PRIx64, cpu64.x[12]);
8702   outs() << " x13 "      << format("0x%016" PRIx64, cpu64.x[13]);
8703   outs() << " x14 "      << format("0x%016" PRIx64, cpu64.x[14]) << "\n";
8704   outs() << "\t    x15 " << format("0x%016" PRIx64, cpu64.x[15]);
8705   outs() << " x16 "      << format("0x%016" PRIx64, cpu64.x[16]);
8706   outs() << " x17 "      << format("0x%016" PRIx64, cpu64.x[17]) << "\n";
8707   outs() << "\t    x18 " << format("0x%016" PRIx64, cpu64.x[18]);
8708   outs() << " x19 "      << format("0x%016" PRIx64, cpu64.x[19]);
8709   outs() << " x20 "      << format("0x%016" PRIx64, cpu64.x[20]) << "\n";
8710   outs() << "\t    x21 " << format("0x%016" PRIx64, cpu64.x[21]);
8711   outs() << " x22 "      << format("0x%016" PRIx64, cpu64.x[22]);
8712   outs() << " x23 "      << format("0x%016" PRIx64, cpu64.x[23]) << "\n";
8713   outs() << "\t    x24 " << format("0x%016" PRIx64, cpu64.x[24]);
8714   outs() << " x25 "      << format("0x%016" PRIx64, cpu64.x[25]);
8715   outs() << " x26 "      << format("0x%016" PRIx64, cpu64.x[26]) << "\n";
8716   outs() << "\t    x27 " << format("0x%016" PRIx64, cpu64.x[27]);
8717   outs() << " x28 "      << format("0x%016" PRIx64, cpu64.x[28]);
8718   outs() << "  fp "      << format("0x%016" PRIx64, cpu64.fp) << "\n";
8719   outs() << "\t     lr " << format("0x%016" PRIx64, cpu64.lr);
8720   outs() << " sp  "      << format("0x%016" PRIx64, cpu64.sp);
8721   outs() << "  pc "      << format("0x%016" PRIx64, cpu64.pc) << "\n";
8722   outs() << "\t   cpsr " << format("0x%08"  PRIx32, cpu64.cpsr) << "\n";
8723 }
8724 
8725 static void PrintThreadCommand(MachO::thread_command t, const char *Ptr,
8726                                bool isLittleEndian, uint32_t cputype) {
8727   if (t.cmd == MachO::LC_THREAD)
8728     outs() << "        cmd LC_THREAD\n";
8729   else if (t.cmd == MachO::LC_UNIXTHREAD)
8730     outs() << "        cmd LC_UNIXTHREAD\n";
8731   else
8732     outs() << "        cmd " << t.cmd << " (unknown)\n";
8733   outs() << "    cmdsize " << t.cmdsize;
8734   if (t.cmdsize < sizeof(struct MachO::thread_command) + 2 * sizeof(uint32_t))
8735     outs() << " Incorrect size\n";
8736   else
8737     outs() << "\n";
8738 
8739   const char *begin = Ptr + sizeof(struct MachO::thread_command);
8740   const char *end = Ptr + t.cmdsize;
8741   uint32_t flavor, count, left;
8742   if (cputype == MachO::CPU_TYPE_I386) {
8743     while (begin < end) {
8744       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8745         memcpy((char *)&flavor, begin, sizeof(uint32_t));
8746         begin += sizeof(uint32_t);
8747       } else {
8748         flavor = 0;
8749         begin = end;
8750       }
8751       if (isLittleEndian != sys::IsLittleEndianHost)
8752         sys::swapByteOrder(flavor);
8753       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8754         memcpy((char *)&count, begin, sizeof(uint32_t));
8755         begin += sizeof(uint32_t);
8756       } else {
8757         count = 0;
8758         begin = end;
8759       }
8760       if (isLittleEndian != sys::IsLittleEndianHost)
8761         sys::swapByteOrder(count);
8762       if (flavor == MachO::x86_THREAD_STATE32) {
8763         outs() << "     flavor i386_THREAD_STATE\n";
8764         if (count == MachO::x86_THREAD_STATE32_COUNT)
8765           outs() << "      count i386_THREAD_STATE_COUNT\n";
8766         else
8767           outs() << "      count " << count
8768                  << " (not x86_THREAD_STATE32_COUNT)\n";
8769         MachO::x86_thread_state32_t cpu32;
8770         left = end - begin;
8771         if (left >= sizeof(MachO::x86_thread_state32_t)) {
8772           memcpy(&cpu32, begin, sizeof(MachO::x86_thread_state32_t));
8773           begin += sizeof(MachO::x86_thread_state32_t);
8774         } else {
8775           memset(&cpu32, '\0', sizeof(MachO::x86_thread_state32_t));
8776           memcpy(&cpu32, begin, left);
8777           begin += left;
8778         }
8779         if (isLittleEndian != sys::IsLittleEndianHost)
8780           swapStruct(cpu32);
8781         Print_x86_thread_state32_t(cpu32);
8782       } else if (flavor == MachO::x86_THREAD_STATE) {
8783         outs() << "     flavor x86_THREAD_STATE\n";
8784         if (count == MachO::x86_THREAD_STATE_COUNT)
8785           outs() << "      count x86_THREAD_STATE_COUNT\n";
8786         else
8787           outs() << "      count " << count
8788                  << " (not x86_THREAD_STATE_COUNT)\n";
8789         struct MachO::x86_thread_state_t ts;
8790         left = end - begin;
8791         if (left >= sizeof(MachO::x86_thread_state_t)) {
8792           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
8793           begin += sizeof(MachO::x86_thread_state_t);
8794         } else {
8795           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
8796           memcpy(&ts, begin, left);
8797           begin += left;
8798         }
8799         if (isLittleEndian != sys::IsLittleEndianHost)
8800           swapStruct(ts);
8801         if (ts.tsh.flavor == MachO::x86_THREAD_STATE32) {
8802           outs() << "\t    tsh.flavor x86_THREAD_STATE32 ";
8803           if (ts.tsh.count == MachO::x86_THREAD_STATE32_COUNT)
8804             outs() << "tsh.count x86_THREAD_STATE32_COUNT\n";
8805           else
8806             outs() << "tsh.count " << ts.tsh.count
8807                    << " (not x86_THREAD_STATE32_COUNT\n";
8808           Print_x86_thread_state32_t(ts.uts.ts32);
8809         } else {
8810           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
8811                  << ts.tsh.count << "\n";
8812         }
8813       } else {
8814         outs() << "     flavor " << flavor << " (unknown)\n";
8815         outs() << "      count " << count << "\n";
8816         outs() << "      state (unknown)\n";
8817         begin += count * sizeof(uint32_t);
8818       }
8819     }
8820   } else if (cputype == MachO::CPU_TYPE_X86_64) {
8821     while (begin < end) {
8822       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8823         memcpy((char *)&flavor, begin, sizeof(uint32_t));
8824         begin += sizeof(uint32_t);
8825       } else {
8826         flavor = 0;
8827         begin = end;
8828       }
8829       if (isLittleEndian != sys::IsLittleEndianHost)
8830         sys::swapByteOrder(flavor);
8831       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8832         memcpy((char *)&count, begin, sizeof(uint32_t));
8833         begin += sizeof(uint32_t);
8834       } else {
8835         count = 0;
8836         begin = end;
8837       }
8838       if (isLittleEndian != sys::IsLittleEndianHost)
8839         sys::swapByteOrder(count);
8840       if (flavor == MachO::x86_THREAD_STATE64) {
8841         outs() << "     flavor x86_THREAD_STATE64\n";
8842         if (count == MachO::x86_THREAD_STATE64_COUNT)
8843           outs() << "      count x86_THREAD_STATE64_COUNT\n";
8844         else
8845           outs() << "      count " << count
8846                  << " (not x86_THREAD_STATE64_COUNT)\n";
8847         MachO::x86_thread_state64_t cpu64;
8848         left = end - begin;
8849         if (left >= sizeof(MachO::x86_thread_state64_t)) {
8850           memcpy(&cpu64, begin, sizeof(MachO::x86_thread_state64_t));
8851           begin += sizeof(MachO::x86_thread_state64_t);
8852         } else {
8853           memset(&cpu64, '\0', sizeof(MachO::x86_thread_state64_t));
8854           memcpy(&cpu64, begin, left);
8855           begin += left;
8856         }
8857         if (isLittleEndian != sys::IsLittleEndianHost)
8858           swapStruct(cpu64);
8859         Print_x86_thread_state64_t(cpu64);
8860       } else if (flavor == MachO::x86_THREAD_STATE) {
8861         outs() << "     flavor x86_THREAD_STATE\n";
8862         if (count == MachO::x86_THREAD_STATE_COUNT)
8863           outs() << "      count x86_THREAD_STATE_COUNT\n";
8864         else
8865           outs() << "      count " << count
8866                  << " (not x86_THREAD_STATE_COUNT)\n";
8867         struct MachO::x86_thread_state_t ts;
8868         left = end - begin;
8869         if (left >= sizeof(MachO::x86_thread_state_t)) {
8870           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
8871           begin += sizeof(MachO::x86_thread_state_t);
8872         } else {
8873           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
8874           memcpy(&ts, begin, left);
8875           begin += left;
8876         }
8877         if (isLittleEndian != sys::IsLittleEndianHost)
8878           swapStruct(ts);
8879         if (ts.tsh.flavor == MachO::x86_THREAD_STATE64) {
8880           outs() << "\t    tsh.flavor x86_THREAD_STATE64 ";
8881           if (ts.tsh.count == MachO::x86_THREAD_STATE64_COUNT)
8882             outs() << "tsh.count x86_THREAD_STATE64_COUNT\n";
8883           else
8884             outs() << "tsh.count " << ts.tsh.count
8885                    << " (not x86_THREAD_STATE64_COUNT\n";
8886           Print_x86_thread_state64_t(ts.uts.ts64);
8887         } else {
8888           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
8889                  << ts.tsh.count << "\n";
8890         }
8891       } else if (flavor == MachO::x86_FLOAT_STATE) {
8892         outs() << "     flavor x86_FLOAT_STATE\n";
8893         if (count == MachO::x86_FLOAT_STATE_COUNT)
8894           outs() << "      count x86_FLOAT_STATE_COUNT\n";
8895         else
8896           outs() << "      count " << count << " (not x86_FLOAT_STATE_COUNT)\n";
8897         struct MachO::x86_float_state_t fs;
8898         left = end - begin;
8899         if (left >= sizeof(MachO::x86_float_state_t)) {
8900           memcpy(&fs, begin, sizeof(MachO::x86_float_state_t));
8901           begin += sizeof(MachO::x86_float_state_t);
8902         } else {
8903           memset(&fs, '\0', sizeof(MachO::x86_float_state_t));
8904           memcpy(&fs, begin, left);
8905           begin += left;
8906         }
8907         if (isLittleEndian != sys::IsLittleEndianHost)
8908           swapStruct(fs);
8909         if (fs.fsh.flavor == MachO::x86_FLOAT_STATE64) {
8910           outs() << "\t    fsh.flavor x86_FLOAT_STATE64 ";
8911           if (fs.fsh.count == MachO::x86_FLOAT_STATE64_COUNT)
8912             outs() << "fsh.count x86_FLOAT_STATE64_COUNT\n";
8913           else
8914             outs() << "fsh.count " << fs.fsh.count
8915                    << " (not x86_FLOAT_STATE64_COUNT\n";
8916           Print_x86_float_state_t(fs.ufs.fs64);
8917         } else {
8918           outs() << "\t    fsh.flavor " << fs.fsh.flavor << "  fsh.count "
8919                  << fs.fsh.count << "\n";
8920         }
8921       } else if (flavor == MachO::x86_EXCEPTION_STATE) {
8922         outs() << "     flavor x86_EXCEPTION_STATE\n";
8923         if (count == MachO::x86_EXCEPTION_STATE_COUNT)
8924           outs() << "      count x86_EXCEPTION_STATE_COUNT\n";
8925         else
8926           outs() << "      count " << count
8927                  << " (not x86_EXCEPTION_STATE_COUNT)\n";
8928         struct MachO::x86_exception_state_t es;
8929         left = end - begin;
8930         if (left >= sizeof(MachO::x86_exception_state_t)) {
8931           memcpy(&es, begin, sizeof(MachO::x86_exception_state_t));
8932           begin += sizeof(MachO::x86_exception_state_t);
8933         } else {
8934           memset(&es, '\0', sizeof(MachO::x86_exception_state_t));
8935           memcpy(&es, begin, left);
8936           begin += left;
8937         }
8938         if (isLittleEndian != sys::IsLittleEndianHost)
8939           swapStruct(es);
8940         if (es.esh.flavor == MachO::x86_EXCEPTION_STATE64) {
8941           outs() << "\t    esh.flavor x86_EXCEPTION_STATE64\n";
8942           if (es.esh.count == MachO::x86_EXCEPTION_STATE64_COUNT)
8943             outs() << "\t    esh.count x86_EXCEPTION_STATE64_COUNT\n";
8944           else
8945             outs() << "\t    esh.count " << es.esh.count
8946                    << " (not x86_EXCEPTION_STATE64_COUNT\n";
8947           Print_x86_exception_state_t(es.ues.es64);
8948         } else {
8949           outs() << "\t    esh.flavor " << es.esh.flavor << "  esh.count "
8950                  << es.esh.count << "\n";
8951         }
8952       } else {
8953         outs() << "     flavor " << flavor << " (unknown)\n";
8954         outs() << "      count " << count << "\n";
8955         outs() << "      state (unknown)\n";
8956         begin += count * sizeof(uint32_t);
8957       }
8958     }
8959   } else if (cputype == MachO::CPU_TYPE_ARM) {
8960     while (begin < end) {
8961       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8962         memcpy((char *)&flavor, begin, sizeof(uint32_t));
8963         begin += sizeof(uint32_t);
8964       } else {
8965         flavor = 0;
8966         begin = end;
8967       }
8968       if (isLittleEndian != sys::IsLittleEndianHost)
8969         sys::swapByteOrder(flavor);
8970       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8971         memcpy((char *)&count, begin, sizeof(uint32_t));
8972         begin += sizeof(uint32_t);
8973       } else {
8974         count = 0;
8975         begin = end;
8976       }
8977       if (isLittleEndian != sys::IsLittleEndianHost)
8978         sys::swapByteOrder(count);
8979       if (flavor == MachO::ARM_THREAD_STATE) {
8980         outs() << "     flavor ARM_THREAD_STATE\n";
8981         if (count == MachO::ARM_THREAD_STATE_COUNT)
8982           outs() << "      count ARM_THREAD_STATE_COUNT\n";
8983         else
8984           outs() << "      count " << count
8985                  << " (not ARM_THREAD_STATE_COUNT)\n";
8986         MachO::arm_thread_state32_t cpu32;
8987         left = end - begin;
8988         if (left >= sizeof(MachO::arm_thread_state32_t)) {
8989           memcpy(&cpu32, begin, sizeof(MachO::arm_thread_state32_t));
8990           begin += sizeof(MachO::arm_thread_state32_t);
8991         } else {
8992           memset(&cpu32, '\0', sizeof(MachO::arm_thread_state32_t));
8993           memcpy(&cpu32, begin, left);
8994           begin += left;
8995         }
8996         if (isLittleEndian != sys::IsLittleEndianHost)
8997           swapStruct(cpu32);
8998         Print_arm_thread_state32_t(cpu32);
8999       } else {
9000         outs() << "     flavor " << flavor << " (unknown)\n";
9001         outs() << "      count " << count << "\n";
9002         outs() << "      state (unknown)\n";
9003         begin += count * sizeof(uint32_t);
9004       }
9005     }
9006   } else if (cputype == MachO::CPU_TYPE_ARM64) {
9007     while (begin < end) {
9008       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9009         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9010         begin += sizeof(uint32_t);
9011       } else {
9012         flavor = 0;
9013         begin = end;
9014       }
9015       if (isLittleEndian != sys::IsLittleEndianHost)
9016         sys::swapByteOrder(flavor);
9017       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9018         memcpy((char *)&count, begin, sizeof(uint32_t));
9019         begin += sizeof(uint32_t);
9020       } else {
9021         count = 0;
9022         begin = end;
9023       }
9024       if (isLittleEndian != sys::IsLittleEndianHost)
9025         sys::swapByteOrder(count);
9026       if (flavor == MachO::ARM_THREAD_STATE64) {
9027         outs() << "     flavor ARM_THREAD_STATE64\n";
9028         if (count == MachO::ARM_THREAD_STATE64_COUNT)
9029           outs() << "      count ARM_THREAD_STATE64_COUNT\n";
9030         else
9031           outs() << "      count " << count
9032                  << " (not ARM_THREAD_STATE64_COUNT)\n";
9033         MachO::arm_thread_state64_t cpu64;
9034         left = end - begin;
9035         if (left >= sizeof(MachO::arm_thread_state64_t)) {
9036           memcpy(&cpu64, begin, sizeof(MachO::arm_thread_state64_t));
9037           begin += sizeof(MachO::arm_thread_state64_t);
9038         } else {
9039           memset(&cpu64, '\0', sizeof(MachO::arm_thread_state64_t));
9040           memcpy(&cpu64, begin, left);
9041           begin += left;
9042         }
9043         if (isLittleEndian != sys::IsLittleEndianHost)
9044           swapStruct(cpu64);
9045         Print_arm_thread_state64_t(cpu64);
9046       } else {
9047         outs() << "     flavor " << flavor << " (unknown)\n";
9048         outs() << "      count " << count << "\n";
9049         outs() << "      state (unknown)\n";
9050         begin += count * sizeof(uint32_t);
9051       }
9052     }
9053   } else {
9054     while (begin < end) {
9055       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9056         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9057         begin += sizeof(uint32_t);
9058       } else {
9059         flavor = 0;
9060         begin = end;
9061       }
9062       if (isLittleEndian != sys::IsLittleEndianHost)
9063         sys::swapByteOrder(flavor);
9064       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9065         memcpy((char *)&count, begin, sizeof(uint32_t));
9066         begin += sizeof(uint32_t);
9067       } else {
9068         count = 0;
9069         begin = end;
9070       }
9071       if (isLittleEndian != sys::IsLittleEndianHost)
9072         sys::swapByteOrder(count);
9073       outs() << "     flavor " << flavor << "\n";
9074       outs() << "      count " << count << "\n";
9075       outs() << "      state (Unknown cputype/cpusubtype)\n";
9076       begin += count * sizeof(uint32_t);
9077     }
9078   }
9079 }
9080 
9081 static void PrintDylibCommand(MachO::dylib_command dl, const char *Ptr) {
9082   if (dl.cmd == MachO::LC_ID_DYLIB)
9083     outs() << "          cmd LC_ID_DYLIB\n";
9084   else if (dl.cmd == MachO::LC_LOAD_DYLIB)
9085     outs() << "          cmd LC_LOAD_DYLIB\n";
9086   else if (dl.cmd == MachO::LC_LOAD_WEAK_DYLIB)
9087     outs() << "          cmd LC_LOAD_WEAK_DYLIB\n";
9088   else if (dl.cmd == MachO::LC_REEXPORT_DYLIB)
9089     outs() << "          cmd LC_REEXPORT_DYLIB\n";
9090   else if (dl.cmd == MachO::LC_LAZY_LOAD_DYLIB)
9091     outs() << "          cmd LC_LAZY_LOAD_DYLIB\n";
9092   else if (dl.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
9093     outs() << "          cmd LC_LOAD_UPWARD_DYLIB\n";
9094   else
9095     outs() << "          cmd " << dl.cmd << " (unknown)\n";
9096   outs() << "      cmdsize " << dl.cmdsize;
9097   if (dl.cmdsize < sizeof(struct MachO::dylib_command))
9098     outs() << " Incorrect size\n";
9099   else
9100     outs() << "\n";
9101   if (dl.dylib.name < dl.cmdsize) {
9102     const char *P = (const char *)(Ptr) + dl.dylib.name;
9103     outs() << "         name " << P << " (offset " << dl.dylib.name << ")\n";
9104   } else {
9105     outs() << "         name ?(bad offset " << dl.dylib.name << ")\n";
9106   }
9107   outs() << "   time stamp " << dl.dylib.timestamp << " ";
9108   time_t t = dl.dylib.timestamp;
9109   outs() << ctime(&t);
9110   outs() << "      current version ";
9111   if (dl.dylib.current_version == 0xffffffff)
9112     outs() << "n/a\n";
9113   else
9114     outs() << ((dl.dylib.current_version >> 16) & 0xffff) << "."
9115            << ((dl.dylib.current_version >> 8) & 0xff) << "."
9116            << (dl.dylib.current_version & 0xff) << "\n";
9117   outs() << "compatibility version ";
9118   if (dl.dylib.compatibility_version == 0xffffffff)
9119     outs() << "n/a\n";
9120   else
9121     outs() << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
9122            << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
9123            << (dl.dylib.compatibility_version & 0xff) << "\n";
9124 }
9125 
9126 static void PrintLinkEditDataCommand(MachO::linkedit_data_command ld,
9127                                      uint32_t object_size) {
9128   if (ld.cmd == MachO::LC_CODE_SIGNATURE)
9129     outs() << "      cmd LC_CODE_SIGNATURE\n";
9130   else if (ld.cmd == MachO::LC_SEGMENT_SPLIT_INFO)
9131     outs() << "      cmd LC_SEGMENT_SPLIT_INFO\n";
9132   else if (ld.cmd == MachO::LC_FUNCTION_STARTS)
9133     outs() << "      cmd LC_FUNCTION_STARTS\n";
9134   else if (ld.cmd == MachO::LC_DATA_IN_CODE)
9135     outs() << "      cmd LC_DATA_IN_CODE\n";
9136   else if (ld.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS)
9137     outs() << "      cmd LC_DYLIB_CODE_SIGN_DRS\n";
9138   else if (ld.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT)
9139     outs() << "      cmd LC_LINKER_OPTIMIZATION_HINT\n";
9140   else
9141     outs() << "      cmd " << ld.cmd << " (?)\n";
9142   outs() << "  cmdsize " << ld.cmdsize;
9143   if (ld.cmdsize != sizeof(struct MachO::linkedit_data_command))
9144     outs() << " Incorrect size\n";
9145   else
9146     outs() << "\n";
9147   outs() << "  dataoff " << ld.dataoff;
9148   if (ld.dataoff > object_size)
9149     outs() << " (past end of file)\n";
9150   else
9151     outs() << "\n";
9152   outs() << " datasize " << ld.datasize;
9153   uint64_t big_size = ld.dataoff;
9154   big_size += ld.datasize;
9155   if (big_size > object_size)
9156     outs() << " (past end of file)\n";
9157   else
9158     outs() << "\n";
9159 }
9160 
9161 static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t filetype,
9162                               uint32_t cputype, bool verbose) {
9163   StringRef Buf = Obj->getData();
9164   unsigned Index = 0;
9165   for (const auto &Command : Obj->load_commands()) {
9166     outs() << "Load command " << Index++ << "\n";
9167     if (Command.C.cmd == MachO::LC_SEGMENT) {
9168       MachO::segment_command SLC = Obj->getSegmentLoadCommand(Command);
9169       const char *sg_segname = SLC.segname;
9170       PrintSegmentCommand(SLC.cmd, SLC.cmdsize, SLC.segname, SLC.vmaddr,
9171                           SLC.vmsize, SLC.fileoff, SLC.filesize, SLC.maxprot,
9172                           SLC.initprot, SLC.nsects, SLC.flags, Buf.size(),
9173                           verbose);
9174       for (unsigned j = 0; j < SLC.nsects; j++) {
9175         MachO::section S = Obj->getSection(Command, j);
9176         PrintSection(S.sectname, S.segname, S.addr, S.size, S.offset, S.align,
9177                      S.reloff, S.nreloc, S.flags, S.reserved1, S.reserved2,
9178                      SLC.cmd, sg_segname, filetype, Buf.size(), verbose);
9179       }
9180     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
9181       MachO::segment_command_64 SLC_64 = Obj->getSegment64LoadCommand(Command);
9182       const char *sg_segname = SLC_64.segname;
9183       PrintSegmentCommand(SLC_64.cmd, SLC_64.cmdsize, SLC_64.segname,
9184                           SLC_64.vmaddr, SLC_64.vmsize, SLC_64.fileoff,
9185                           SLC_64.filesize, SLC_64.maxprot, SLC_64.initprot,
9186                           SLC_64.nsects, SLC_64.flags, Buf.size(), verbose);
9187       for (unsigned j = 0; j < SLC_64.nsects; j++) {
9188         MachO::section_64 S_64 = Obj->getSection64(Command, j);
9189         PrintSection(S_64.sectname, S_64.segname, S_64.addr, S_64.size,
9190                      S_64.offset, S_64.align, S_64.reloff, S_64.nreloc,
9191                      S_64.flags, S_64.reserved1, S_64.reserved2, SLC_64.cmd,
9192                      sg_segname, filetype, Buf.size(), verbose);
9193       }
9194     } else if (Command.C.cmd == MachO::LC_SYMTAB) {
9195       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
9196       PrintSymtabLoadCommand(Symtab, Obj->is64Bit(), Buf.size());
9197     } else if (Command.C.cmd == MachO::LC_DYSYMTAB) {
9198       MachO::dysymtab_command Dysymtab = Obj->getDysymtabLoadCommand();
9199       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
9200       PrintDysymtabLoadCommand(Dysymtab, Symtab.nsyms, Buf.size(),
9201                                Obj->is64Bit());
9202     } else if (Command.C.cmd == MachO::LC_DYLD_INFO ||
9203                Command.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
9204       MachO::dyld_info_command DyldInfo = Obj->getDyldInfoLoadCommand(Command);
9205       PrintDyldInfoLoadCommand(DyldInfo, Buf.size());
9206     } else if (Command.C.cmd == MachO::LC_LOAD_DYLINKER ||
9207                Command.C.cmd == MachO::LC_ID_DYLINKER ||
9208                Command.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
9209       MachO::dylinker_command Dyld = Obj->getDylinkerCommand(Command);
9210       PrintDyldLoadCommand(Dyld, Command.Ptr);
9211     } else if (Command.C.cmd == MachO::LC_UUID) {
9212       MachO::uuid_command Uuid = Obj->getUuidCommand(Command);
9213       PrintUuidLoadCommand(Uuid);
9214     } else if (Command.C.cmd == MachO::LC_RPATH) {
9215       MachO::rpath_command Rpath = Obj->getRpathCommand(Command);
9216       PrintRpathLoadCommand(Rpath, Command.Ptr);
9217     } else if (Command.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
9218                Command.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS ||
9219                Command.C.cmd == MachO::LC_VERSION_MIN_TVOS ||
9220                Command.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
9221       MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
9222       PrintVersionMinLoadCommand(Vd);
9223     } else if (Command.C.cmd == MachO::LC_NOTE) {
9224       MachO::note_command Nt = Obj->getNoteLoadCommand(Command);
9225       PrintNoteLoadCommand(Nt);
9226     } else if (Command.C.cmd == MachO::LC_BUILD_VERSION) {
9227       MachO::build_version_command Bv =
9228           Obj->getBuildVersionLoadCommand(Command);
9229       PrintBuildVersionLoadCommand(Obj, Bv);
9230     } else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
9231       MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
9232       PrintSourceVersionCommand(Sd);
9233     } else if (Command.C.cmd == MachO::LC_MAIN) {
9234       MachO::entry_point_command Ep = Obj->getEntryPointCommand(Command);
9235       PrintEntryPointCommand(Ep);
9236     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO) {
9237       MachO::encryption_info_command Ei =
9238           Obj->getEncryptionInfoCommand(Command);
9239       PrintEncryptionInfoCommand(Ei, Buf.size());
9240     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
9241       MachO::encryption_info_command_64 Ei =
9242           Obj->getEncryptionInfoCommand64(Command);
9243       PrintEncryptionInfoCommand64(Ei, Buf.size());
9244     } else if (Command.C.cmd == MachO::LC_LINKER_OPTION) {
9245       MachO::linker_option_command Lo =
9246           Obj->getLinkerOptionLoadCommand(Command);
9247       PrintLinkerOptionCommand(Lo, Command.Ptr);
9248     } else if (Command.C.cmd == MachO::LC_SUB_FRAMEWORK) {
9249       MachO::sub_framework_command Sf = Obj->getSubFrameworkCommand(Command);
9250       PrintSubFrameworkCommand(Sf, Command.Ptr);
9251     } else if (Command.C.cmd == MachO::LC_SUB_UMBRELLA) {
9252       MachO::sub_umbrella_command Sf = Obj->getSubUmbrellaCommand(Command);
9253       PrintSubUmbrellaCommand(Sf, Command.Ptr);
9254     } else if (Command.C.cmd == MachO::LC_SUB_LIBRARY) {
9255       MachO::sub_library_command Sl = Obj->getSubLibraryCommand(Command);
9256       PrintSubLibraryCommand(Sl, Command.Ptr);
9257     } else if (Command.C.cmd == MachO::LC_SUB_CLIENT) {
9258       MachO::sub_client_command Sc = Obj->getSubClientCommand(Command);
9259       PrintSubClientCommand(Sc, Command.Ptr);
9260     } else if (Command.C.cmd == MachO::LC_ROUTINES) {
9261       MachO::routines_command Rc = Obj->getRoutinesCommand(Command);
9262       PrintRoutinesCommand(Rc);
9263     } else if (Command.C.cmd == MachO::LC_ROUTINES_64) {
9264       MachO::routines_command_64 Rc = Obj->getRoutinesCommand64(Command);
9265       PrintRoutinesCommand64(Rc);
9266     } else if (Command.C.cmd == MachO::LC_THREAD ||
9267                Command.C.cmd == MachO::LC_UNIXTHREAD) {
9268       MachO::thread_command Tc = Obj->getThreadCommand(Command);
9269       PrintThreadCommand(Tc, Command.Ptr, Obj->isLittleEndian(), cputype);
9270     } else if (Command.C.cmd == MachO::LC_LOAD_DYLIB ||
9271                Command.C.cmd == MachO::LC_ID_DYLIB ||
9272                Command.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
9273                Command.C.cmd == MachO::LC_REEXPORT_DYLIB ||
9274                Command.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
9275                Command.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
9276       MachO::dylib_command Dl = Obj->getDylibIDLoadCommand(Command);
9277       PrintDylibCommand(Dl, Command.Ptr);
9278     } else if (Command.C.cmd == MachO::LC_CODE_SIGNATURE ||
9279                Command.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO ||
9280                Command.C.cmd == MachO::LC_FUNCTION_STARTS ||
9281                Command.C.cmd == MachO::LC_DATA_IN_CODE ||
9282                Command.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS ||
9283                Command.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
9284       MachO::linkedit_data_command Ld =
9285           Obj->getLinkeditDataLoadCommand(Command);
9286       PrintLinkEditDataCommand(Ld, Buf.size());
9287     } else {
9288       outs() << "      cmd ?(" << format("0x%08" PRIx32, Command.C.cmd)
9289              << ")\n";
9290       outs() << "  cmdsize " << Command.C.cmdsize << "\n";
9291       // TODO: get and print the raw bytes of the load command.
9292     }
9293     // TODO: print all the other kinds of load commands.
9294   }
9295 }
9296 
9297 static void PrintMachHeader(const MachOObjectFile *Obj, bool verbose) {
9298   if (Obj->is64Bit()) {
9299     MachO::mach_header_64 H_64;
9300     H_64 = Obj->getHeader64();
9301     PrintMachHeader(H_64.magic, H_64.cputype, H_64.cpusubtype, H_64.filetype,
9302                     H_64.ncmds, H_64.sizeofcmds, H_64.flags, verbose);
9303   } else {
9304     MachO::mach_header H;
9305     H = Obj->getHeader();
9306     PrintMachHeader(H.magic, H.cputype, H.cpusubtype, H.filetype, H.ncmds,
9307                     H.sizeofcmds, H.flags, verbose);
9308   }
9309 }
9310 
9311 void llvm::printMachOFileHeader(const object::ObjectFile *Obj) {
9312   const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
9313   PrintMachHeader(file, !NonVerbose);
9314 }
9315 
9316 void llvm::printMachOLoadCommands(const object::ObjectFile *Obj) {
9317   const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
9318   uint32_t filetype = 0;
9319   uint32_t cputype = 0;
9320   if (file->is64Bit()) {
9321     MachO::mach_header_64 H_64;
9322     H_64 = file->getHeader64();
9323     filetype = H_64.filetype;
9324     cputype = H_64.cputype;
9325   } else {
9326     MachO::mach_header H;
9327     H = file->getHeader();
9328     filetype = H.filetype;
9329     cputype = H.cputype;
9330   }
9331   PrintLoadCommands(file, filetype, cputype, !NonVerbose);
9332 }
9333 
9334 //===----------------------------------------------------------------------===//
9335 // export trie dumping
9336 //===----------------------------------------------------------------------===//
9337 
9338 void llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) {
9339   for (const llvm::object::ExportEntry &Entry : Obj->exports()) {
9340     uint64_t Flags = Entry.flags();
9341     bool ReExport = (Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
9342     bool WeakDef = (Flags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
9343     bool ThreadLocal = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
9344                         MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL);
9345     bool Abs = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
9346                 MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
9347     bool Resolver = (Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
9348     if (ReExport)
9349       outs() << "[re-export] ";
9350     else
9351       outs() << format("0x%08llX  ",
9352                        Entry.address()); // FIXME:add in base address
9353     outs() << Entry.name();
9354     if (WeakDef || ThreadLocal || Resolver || Abs) {
9355       bool NeedsComma = false;
9356       outs() << " [";
9357       if (WeakDef) {
9358         outs() << "weak_def";
9359         NeedsComma = true;
9360       }
9361       if (ThreadLocal) {
9362         if (NeedsComma)
9363           outs() << ", ";
9364         outs() << "per-thread";
9365         NeedsComma = true;
9366       }
9367       if (Abs) {
9368         if (NeedsComma)
9369           outs() << ", ";
9370         outs() << "absolute";
9371         NeedsComma = true;
9372       }
9373       if (Resolver) {
9374         if (NeedsComma)
9375           outs() << ", ";
9376         outs() << format("resolver=0x%08llX", Entry.other());
9377         NeedsComma = true;
9378       }
9379       outs() << "]";
9380     }
9381     if (ReExport) {
9382       StringRef DylibName = "unknown";
9383       int Ordinal = Entry.other() - 1;
9384       Obj->getLibraryShortNameByIndex(Ordinal, DylibName);
9385       if (Entry.otherName().empty())
9386         outs() << " (from " << DylibName << ")";
9387       else
9388         outs() << " (" << Entry.otherName() << " from " << DylibName << ")";
9389     }
9390     outs() << "\n";
9391   }
9392 }
9393 
9394 //===----------------------------------------------------------------------===//
9395 // rebase table dumping
9396 //===----------------------------------------------------------------------===//
9397 
9398 void llvm::printMachORebaseTable(object::MachOObjectFile *Obj) {
9399   outs() << "segment  section            address     type\n";
9400   Error Err = Error::success();
9401   for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(Err)) {
9402     StringRef SegmentName = Entry.segmentName();
9403     StringRef SectionName = Entry.sectionName();
9404     uint64_t Address = Entry.address();
9405 
9406     // Table lines look like: __DATA  __nl_symbol_ptr  0x0000F00C  pointer
9407     outs() << format("%-8s %-18s 0x%08" PRIX64 "  %s\n",
9408                      SegmentName.str().c_str(), SectionName.str().c_str(),
9409                      Address, Entry.typeName().str().c_str());
9410   }
9411   if (Err)
9412     report_error(Obj->getFileName(), std::move(Err));
9413 }
9414 
9415 static StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) {
9416   StringRef DylibName;
9417   switch (Ordinal) {
9418   case MachO::BIND_SPECIAL_DYLIB_SELF:
9419     return "this-image";
9420   case MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE:
9421     return "main-executable";
9422   case MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP:
9423     return "flat-namespace";
9424   default:
9425     if (Ordinal > 0) {
9426       std::error_code EC =
9427           Obj->getLibraryShortNameByIndex(Ordinal - 1, DylibName);
9428       if (EC)
9429         return "<<bad library ordinal>>";
9430       return DylibName;
9431     }
9432   }
9433   return "<<unknown special ordinal>>";
9434 }
9435 
9436 //===----------------------------------------------------------------------===//
9437 // bind table dumping
9438 //===----------------------------------------------------------------------===//
9439 
9440 void llvm::printMachOBindTable(object::MachOObjectFile *Obj) {
9441   // Build table of sections so names can used in final output.
9442   outs() << "segment  section            address    type       "
9443             "addend dylib            symbol\n";
9444   Error Err = Error::success();
9445   for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(Err)) {
9446     StringRef SegmentName = Entry.segmentName();
9447     StringRef SectionName = Entry.sectionName();
9448     uint64_t Address = Entry.address();
9449 
9450     // Table lines look like:
9451     //  __DATA  __got  0x00012010    pointer   0 libSystem ___stack_chk_guard
9452     StringRef Attr;
9453     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT)
9454       Attr = " (weak_import)";
9455     outs() << left_justify(SegmentName, 8) << " "
9456            << left_justify(SectionName, 18) << " "
9457            << format_hex(Address, 10, true) << " "
9458            << left_justify(Entry.typeName(), 8) << " "
9459            << format_decimal(Entry.addend(), 8) << " "
9460            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
9461            << Entry.symbolName() << Attr << "\n";
9462   }
9463   if (Err)
9464     report_error(Obj->getFileName(), std::move(Err));
9465 }
9466 
9467 //===----------------------------------------------------------------------===//
9468 // lazy bind table dumping
9469 //===----------------------------------------------------------------------===//
9470 
9471 void llvm::printMachOLazyBindTable(object::MachOObjectFile *Obj) {
9472   outs() << "segment  section            address     "
9473             "dylib            symbol\n";
9474   Error Err = Error::success();
9475   for (const llvm::object::MachOBindEntry &Entry : Obj->lazyBindTable(Err)) {
9476     StringRef SegmentName = Entry.segmentName();
9477     StringRef SectionName = Entry.sectionName();
9478     uint64_t Address = Entry.address();
9479 
9480     // Table lines look like:
9481     //  __DATA  __got  0x00012010 libSystem ___stack_chk_guard
9482     outs() << left_justify(SegmentName, 8) << " "
9483            << left_justify(SectionName, 18) << " "
9484            << format_hex(Address, 10, true) << " "
9485            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
9486            << Entry.symbolName() << "\n";
9487   }
9488   if (Err)
9489     report_error(Obj->getFileName(), std::move(Err));
9490 }
9491 
9492 //===----------------------------------------------------------------------===//
9493 // weak bind table dumping
9494 //===----------------------------------------------------------------------===//
9495 
9496 void llvm::printMachOWeakBindTable(object::MachOObjectFile *Obj) {
9497   outs() << "segment  section            address     "
9498             "type       addend   symbol\n";
9499   Error Err = Error::success();
9500   for (const llvm::object::MachOBindEntry &Entry : Obj->weakBindTable(Err)) {
9501     // Strong symbols don't have a location to update.
9502     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
9503       outs() << "                                        strong              "
9504              << Entry.symbolName() << "\n";
9505       continue;
9506     }
9507     StringRef SegmentName = Entry.segmentName();
9508     StringRef SectionName = Entry.sectionName();
9509     uint64_t Address = Entry.address();
9510 
9511     // Table lines look like:
9512     // __DATA  __data  0x00001000  pointer    0   _foo
9513     outs() << left_justify(SegmentName, 8) << " "
9514            << left_justify(SectionName, 18) << " "
9515            << format_hex(Address, 10, true) << " "
9516            << left_justify(Entry.typeName(), 8) << " "
9517            << format_decimal(Entry.addend(), 8) << "   " << Entry.symbolName()
9518            << "\n";
9519   }
9520   if (Err)
9521     report_error(Obj->getFileName(), std::move(Err));
9522 }
9523 
9524 // get_dyld_bind_info_symbolname() is used for disassembly and passed an
9525 // address, ReferenceValue, in the Mach-O file and looks in the dyld bind
9526 // information for that address. If the address is found its binding symbol
9527 // name is returned.  If not nullptr is returned.
9528 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
9529                                                  struct DisassembleInfo *info) {
9530   if (info->bindtable == nullptr) {
9531     info->bindtable = llvm::make_unique<SymbolAddressMap>();
9532     Error Err = Error::success();
9533     for (const llvm::object::MachOBindEntry &Entry : info->O->bindTable(Err)) {
9534       uint64_t Address = Entry.address();
9535       StringRef name = Entry.symbolName();
9536       if (!name.empty())
9537         (*info->bindtable)[Address] = name;
9538     }
9539     if (Err)
9540       report_error(info->O->getFileName(), std::move(Err));
9541   }
9542   auto name = info->bindtable->lookup(ReferenceValue);
9543   return !name.empty() ? name.data() : nullptr;
9544 }
9545