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