xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-objdump/MachODump.cpp (revision a7623790fb345e6dc986dfd31df0ace115e6f2e4)
1 //===-- MachODump.cpp - Object file dumping utility for llvm --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the MachO-specific dumper for llvm-objdump.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MachODump.h"
14 
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/BinaryFormat/MachO.h"
21 #include "llvm/Config/config.h"
22 #include "llvm/DebugInfo/DIContext.h"
23 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
24 #include "llvm/Demangle/Demangle.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
28 #include "llvm/MC/MCInst.h"
29 #include "llvm/MC/MCInstPrinter.h"
30 #include "llvm/MC/MCInstrDesc.h"
31 #include "llvm/MC/MCInstrInfo.h"
32 #include "llvm/MC/MCRegisterInfo.h"
33 #include "llvm/MC/MCSubtargetInfo.h"
34 #include "llvm/MC/MCTargetOptions.h"
35 #include "llvm/Object/MachO.h"
36 #include "llvm/Object/MachOUniversal.h"
37 #include "llvm/Support/Casting.h"
38 #include "llvm/Support/CommandLine.h"
39 #include "llvm/Support/Debug.h"
40 #include "llvm/Support/Endian.h"
41 #include "llvm/Support/Format.h"
42 #include "llvm/Support/FormattedStream.h"
43 #include "llvm/Support/GraphWriter.h"
44 #include "llvm/Support/LEB128.h"
45 #include "llvm/Support/MemoryBuffer.h"
46 #include "llvm/Support/TargetRegistry.h"
47 #include "llvm/Support/TargetSelect.h"
48 #include "llvm/Support/ToolOutputFile.h"
49 #include "llvm/Support/WithColor.h"
50 #include "llvm/Support/raw_ostream.h"
51 #include <algorithm>
52 #include <cstring>
53 #include <system_error>
54 
55 #ifdef HAVE_LIBXAR
56 extern "C" {
57 #include <xar/xar.h>
58 }
59 #endif
60 
61 using namespace llvm;
62 using namespace llvm::object;
63 using namespace llvm::objdump;
64 
65 cl::OptionCategory objdump::MachOCat("llvm-objdump MachO Specific Options");
66 
67 cl::opt<bool> objdump::FirstPrivateHeader(
68     "private-header",
69     cl::desc("Display only the first format specific file header"),
70     cl::cat(MachOCat));
71 
72 cl::opt<bool> objdump::ExportsTrie("exports-trie",
73                                    cl::desc("Display mach-o exported symbols"),
74                                    cl::cat(MachOCat));
75 
76 cl::opt<bool> objdump::Rebase("rebase",
77                               cl::desc("Display mach-o rebasing info"),
78                               cl::cat(MachOCat));
79 
80 cl::opt<bool> objdump::Bind("bind", cl::desc("Display mach-o binding info"),
81                             cl::cat(MachOCat));
82 
83 cl::opt<bool> objdump::LazyBind("lazy-bind",
84                                 cl::desc("Display mach-o lazy binding info"),
85                                 cl::cat(MachOCat));
86 
87 cl::opt<bool> objdump::WeakBind("weak-bind",
88                                 cl::desc("Display mach-o weak binding info"),
89                                 cl::cat(MachOCat));
90 
91 static cl::opt<bool>
92     UseDbg("g", cl::Grouping,
93            cl::desc("Print line information from debug info if available"),
94            cl::cat(MachOCat));
95 
96 static cl::opt<std::string> DSYMFile("dsym",
97                                      cl::desc("Use .dSYM file for debug info"),
98                                      cl::cat(MachOCat));
99 
100 static cl::opt<bool> FullLeadingAddr("full-leading-addr",
101                                      cl::desc("Print full leading address"),
102                                      cl::cat(MachOCat));
103 
104 static cl::opt<bool> NoLeadingHeaders("no-leading-headers",
105                                       cl::desc("Print no leading headers"),
106                                       cl::cat(MachOCat));
107 
108 cl::opt<bool> objdump::UniversalHeaders(
109     "universal-headers",
110     cl::desc("Print Mach-O universal headers (requires -macho)"),
111     cl::cat(MachOCat));
112 
113 static cl::opt<bool> ArchiveMemberOffsets(
114     "archive-member-offsets",
115     cl::desc("Print the offset to each archive member for Mach-O archives "
116              "(requires -macho and -archive-headers)"),
117     cl::cat(MachOCat));
118 
119 cl::opt<bool> objdump::IndirectSymbols(
120     "indirect-symbols",
121     cl::desc(
122         "Print indirect symbol table for Mach-O objects (requires -macho)"),
123     cl::cat(MachOCat));
124 
125 cl::opt<bool> objdump::DataInCode(
126     "data-in-code",
127     cl::desc(
128         "Print the data in code table for Mach-O objects (requires -macho)"),
129     cl::cat(MachOCat));
130 
131 cl::opt<bool>
132     objdump::LinkOptHints("link-opt-hints",
133                           cl::desc("Print the linker optimization hints for "
134                                    "Mach-O objects (requires -macho)"),
135                           cl::cat(MachOCat));
136 
137 cl::opt<bool>
138     objdump::InfoPlist("info-plist",
139                        cl::desc("Print the info plist section as strings for "
140                                 "Mach-O objects (requires -macho)"),
141                        cl::cat(MachOCat));
142 
143 cl::opt<bool>
144     objdump::DylibsUsed("dylibs-used",
145                         cl::desc("Print the shared libraries used for linked "
146                                  "Mach-O files (requires -macho)"),
147                         cl::cat(MachOCat));
148 
149 cl::opt<bool> objdump::DylibId("dylib-id",
150                                cl::desc("Print the shared library's id for the "
151                                         "dylib Mach-O file (requires -macho)"),
152                                cl::cat(MachOCat));
153 
154 static cl::opt<bool>
155     NonVerbose("non-verbose",
156                cl::desc("Print the info for Mach-O objects in non-verbose or "
157                         "numeric form (requires -macho)"),
158                cl::cat(MachOCat));
159 
160 cl::opt<bool>
161     objdump::ObjcMetaData("objc-meta-data",
162                           cl::desc("Print the Objective-C runtime meta data "
163                                    "for Mach-O files (requires -macho)"),
164                           cl::cat(MachOCat));
165 
166 static cl::opt<std::string> DisSymName(
167     "dis-symname",
168     cl::desc("disassemble just this symbol's instructions (requires -macho)"),
169     cl::cat(MachOCat));
170 
171 static cl::opt<bool> NoSymbolicOperands(
172     "no-symbolic-operands",
173     cl::desc("do not symbolic operands when disassembling (requires -macho)"),
174     cl::cat(MachOCat));
175 
176 static cl::list<std::string>
177     ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
178               cl::ZeroOrMore, cl::cat(MachOCat));
179 
180 static bool ArchAll = false;
181 
182 static std::string ThumbTripleName;
183 
184 static const Target *GetTarget(const MachOObjectFile *MachOObj,
185                                const char **McpuDefault,
186                                const Target **ThumbTarget) {
187   // Figure out the target triple.
188   Triple TT(TripleName);
189   if (TripleName.empty()) {
190     TT = MachOObj->getArchTriple(McpuDefault);
191     TripleName = TT.str();
192   }
193 
194   if (TT.getArch() == Triple::arm) {
195     // We've inferred a 32-bit ARM target from the object file. All MachO CPUs
196     // that support ARM are also capable of Thumb mode.
197     Triple ThumbTriple = TT;
198     std::string ThumbName = (Twine("thumb") + TT.getArchName().substr(3)).str();
199     ThumbTriple.setArchName(ThumbName);
200     ThumbTripleName = ThumbTriple.str();
201   }
202 
203   // Get the target specific parser.
204   std::string Error;
205   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
206   if (TheTarget && ThumbTripleName.empty())
207     return TheTarget;
208 
209   *ThumbTarget = TargetRegistry::lookupTarget(ThumbTripleName, Error);
210   if (*ThumbTarget)
211     return TheTarget;
212 
213   WithColor::error(errs(), "llvm-objdump") << "unable to get target for '";
214   if (!TheTarget)
215     errs() << TripleName;
216   else
217     errs() << ThumbTripleName;
218   errs() << "', see --version and --triple.\n";
219   return nullptr;
220 }
221 
222 namespace {
223 struct SymbolSorter {
224   bool operator()(const SymbolRef &A, const SymbolRef &B) {
225     Expected<SymbolRef::Type> ATypeOrErr = A.getType();
226     if (!ATypeOrErr)
227       reportError(ATypeOrErr.takeError(), A.getObject()->getFileName());
228     SymbolRef::Type AType = *ATypeOrErr;
229     Expected<SymbolRef::Type> BTypeOrErr = B.getType();
230     if (!BTypeOrErr)
231       reportError(BTypeOrErr.takeError(), B.getObject()->getFileName());
232     SymbolRef::Type BType = *BTypeOrErr;
233     uint64_t AAddr =
234         (AType != SymbolRef::ST_Function) ? 0 : cantFail(A.getValue());
235     uint64_t BAddr =
236         (BType != SymbolRef::ST_Function) ? 0 : cantFail(B.getValue());
237     return AAddr < BAddr;
238   }
239 };
240 } // namespace
241 
242 // Types for the storted data in code table that is built before disassembly
243 // and the predicate function to sort them.
244 typedef std::pair<uint64_t, DiceRef> DiceTableEntry;
245 typedef std::vector<DiceTableEntry> DiceTable;
246 typedef DiceTable::iterator dice_table_iterator;
247 
248 #ifdef HAVE_LIBXAR
249 namespace {
250 struct ScopedXarFile {
251   xar_t xar;
252   ScopedXarFile(const char *filename, int32_t flags)
253       : xar(xar_open(filename, flags)) {}
254   ~ScopedXarFile() {
255     if (xar)
256       xar_close(xar);
257   }
258   ScopedXarFile(const ScopedXarFile &) = delete;
259   ScopedXarFile &operator=(const ScopedXarFile &) = delete;
260   operator xar_t() { return xar; }
261 };
262 
263 struct ScopedXarIter {
264   xar_iter_t iter;
265   ScopedXarIter() : iter(xar_iter_new()) {}
266   ~ScopedXarIter() {
267     if (iter)
268       xar_iter_free(iter);
269   }
270   ScopedXarIter(const ScopedXarIter &) = delete;
271   ScopedXarIter &operator=(const ScopedXarIter &) = delete;
272   operator xar_iter_t() { return iter; }
273 };
274 } // namespace
275 #endif // defined(HAVE_LIBXAR)
276 
277 // This is used to search for a data in code table entry for the PC being
278 // disassembled.  The j parameter has the PC in j.first.  A single data in code
279 // table entry can cover many bytes for each of its Kind's.  So if the offset,
280 // aka the i.first value, of the data in code table entry plus its Length
281 // covers the PC being searched for this will return true.  If not it will
282 // return false.
283 static bool compareDiceTableEntries(const DiceTableEntry &i,
284                                     const DiceTableEntry &j) {
285   uint16_t Length;
286   i.second.getLength(Length);
287 
288   return j.first >= i.first && j.first < i.first + Length;
289 }
290 
291 static uint64_t DumpDataInCode(const uint8_t *bytes, uint64_t Length,
292                                unsigned short Kind) {
293   uint32_t Value, Size = 1;
294 
295   switch (Kind) {
296   default:
297   case MachO::DICE_KIND_DATA:
298     if (Length >= 4) {
299       if (!NoShowRawInsn)
300         dumpBytes(makeArrayRef(bytes, 4), outs());
301       Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
302       outs() << "\t.long " << Value;
303       Size = 4;
304     } else if (Length >= 2) {
305       if (!NoShowRawInsn)
306         dumpBytes(makeArrayRef(bytes, 2), outs());
307       Value = bytes[1] << 8 | bytes[0];
308       outs() << "\t.short " << Value;
309       Size = 2;
310     } else {
311       if (!NoShowRawInsn)
312         dumpBytes(makeArrayRef(bytes, 2), outs());
313       Value = bytes[0];
314       outs() << "\t.byte " << Value;
315       Size = 1;
316     }
317     if (Kind == MachO::DICE_KIND_DATA)
318       outs() << "\t@ KIND_DATA\n";
319     else
320       outs() << "\t@ data in code kind = " << Kind << "\n";
321     break;
322   case MachO::DICE_KIND_JUMP_TABLE8:
323     if (!NoShowRawInsn)
324       dumpBytes(makeArrayRef(bytes, 1), outs());
325     Value = bytes[0];
326     outs() << "\t.byte " << format("%3u", Value) << "\t@ KIND_JUMP_TABLE8\n";
327     Size = 1;
328     break;
329   case MachO::DICE_KIND_JUMP_TABLE16:
330     if (!NoShowRawInsn)
331       dumpBytes(makeArrayRef(bytes, 2), outs());
332     Value = bytes[1] << 8 | bytes[0];
333     outs() << "\t.short " << format("%5u", Value & 0xffff)
334            << "\t@ KIND_JUMP_TABLE16\n";
335     Size = 2;
336     break;
337   case MachO::DICE_KIND_JUMP_TABLE32:
338   case MachO::DICE_KIND_ABS_JUMP_TABLE32:
339     if (!NoShowRawInsn)
340       dumpBytes(makeArrayRef(bytes, 4), outs());
341     Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
342     outs() << "\t.long " << Value;
343     if (Kind == MachO::DICE_KIND_JUMP_TABLE32)
344       outs() << "\t@ KIND_JUMP_TABLE32\n";
345     else
346       outs() << "\t@ KIND_ABS_JUMP_TABLE32\n";
347     Size = 4;
348     break;
349   }
350   return Size;
351 }
352 
353 static void getSectionsAndSymbols(MachOObjectFile *MachOObj,
354                                   std::vector<SectionRef> &Sections,
355                                   std::vector<SymbolRef> &Symbols,
356                                   SmallVectorImpl<uint64_t> &FoundFns,
357                                   uint64_t &BaseSegmentAddress) {
358   const StringRef FileName = MachOObj->getFileName();
359   for (const SymbolRef &Symbol : MachOObj->symbols()) {
360     StringRef SymName = unwrapOrError(Symbol.getName(), FileName);
361     if (!SymName.startswith("ltmp"))
362       Symbols.push_back(Symbol);
363   }
364 
365   for (const SectionRef &Section : MachOObj->sections())
366     Sections.push_back(Section);
367 
368   bool BaseSegmentAddressSet = false;
369   for (const auto &Command : MachOObj->load_commands()) {
370     if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
371       // We found a function starts segment, parse the addresses for later
372       // consumption.
373       MachO::linkedit_data_command LLC =
374           MachOObj->getLinkeditDataLoadCommand(Command);
375 
376       MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
377     } else if (Command.C.cmd == MachO::LC_SEGMENT) {
378       MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command);
379       StringRef SegName = SLC.segname;
380       if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
381         BaseSegmentAddressSet = true;
382         BaseSegmentAddress = SLC.vmaddr;
383       }
384     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
385       MachO::segment_command_64 SLC = MachOObj->getSegment64LoadCommand(Command);
386       StringRef SegName = SLC.segname;
387       if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
388         BaseSegmentAddressSet = true;
389         BaseSegmentAddress = SLC.vmaddr;
390       }
391     }
392   }
393 }
394 
395 static bool DumpAndSkipDataInCode(uint64_t PC, const uint8_t *bytes,
396                                  DiceTable &Dices, uint64_t &InstSize) {
397   // Check the data in code table here to see if this is data not an
398   // instruction to be disassembled.
399   DiceTable Dice;
400   Dice.push_back(std::make_pair(PC, DiceRef()));
401   dice_table_iterator DTI =
402       std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(),
403                   compareDiceTableEntries);
404   if (DTI != Dices.end()) {
405     uint16_t Length;
406     DTI->second.getLength(Length);
407     uint16_t Kind;
408     DTI->second.getKind(Kind);
409     InstSize = DumpDataInCode(bytes, Length, Kind);
410     if ((Kind == MachO::DICE_KIND_JUMP_TABLE8) &&
411         (PC == (DTI->first + Length - 1)) && (Length & 1))
412       InstSize++;
413     return true;
414   }
415   return false;
416 }
417 
418 static void printRelocationTargetName(const MachOObjectFile *O,
419                                       const MachO::any_relocation_info &RE,
420                                       raw_string_ostream &Fmt) {
421   // Target of a scattered relocation is an address.  In the interest of
422   // generating pretty output, scan through the symbol table looking for a
423   // symbol that aligns with that address.  If we find one, print it.
424   // Otherwise, we just print the hex address of the target.
425   const StringRef FileName = O->getFileName();
426   if (O->isRelocationScattered(RE)) {
427     uint32_t Val = O->getPlainRelocationSymbolNum(RE);
428 
429     for (const SymbolRef &Symbol : O->symbols()) {
430       uint64_t Addr = unwrapOrError(Symbol.getAddress(), FileName);
431       if (Addr != Val)
432         continue;
433       Fmt << unwrapOrError(Symbol.getName(), FileName);
434       return;
435     }
436 
437     // If we couldn't find a symbol that this relocation refers to, try
438     // to find a section beginning instead.
439     for (const SectionRef &Section : ToolSectionFilter(*O)) {
440       uint64_t Addr = Section.getAddress();
441       if (Addr != Val)
442         continue;
443       StringRef NameOrErr = unwrapOrError(Section.getName(), O->getFileName());
444       Fmt << NameOrErr;
445       return;
446     }
447 
448     Fmt << format("0x%x", Val);
449     return;
450   }
451 
452   StringRef S;
453   bool isExtern = O->getPlainRelocationExternal(RE);
454   uint64_t Val = O->getPlainRelocationSymbolNum(RE);
455 
456   if (O->getAnyRelocationType(RE) == MachO::ARM64_RELOC_ADDEND) {
457     Fmt << format("0x%0" PRIx64, Val);
458     return;
459   }
460 
461   if (isExtern) {
462     symbol_iterator SI = O->symbol_begin();
463     advance(SI, Val);
464     S = unwrapOrError(SI->getName(), FileName);
465   } else {
466     section_iterator SI = O->section_begin();
467     // Adjust for the fact that sections are 1-indexed.
468     if (Val == 0) {
469       Fmt << "0 (?,?)";
470       return;
471     }
472     uint32_t I = Val - 1;
473     while (I != 0 && SI != O->section_end()) {
474       --I;
475       advance(SI, 1);
476     }
477     if (SI == O->section_end()) {
478       Fmt << Val << " (?,?)";
479     } else {
480       if (Expected<StringRef> NameOrErr = SI->getName())
481         S = *NameOrErr;
482       else
483         consumeError(NameOrErr.takeError());
484     }
485   }
486 
487   Fmt << S;
488 }
489 
490 Error objdump::getMachORelocationValueString(const MachOObjectFile *Obj,
491                                              const RelocationRef &RelRef,
492                                              SmallVectorImpl<char> &Result) {
493   DataRefImpl Rel = RelRef.getRawDataRefImpl();
494   MachO::any_relocation_info RE = Obj->getRelocation(Rel);
495 
496   unsigned Arch = Obj->getArch();
497 
498   std::string FmtBuf;
499   raw_string_ostream Fmt(FmtBuf);
500   unsigned Type = Obj->getAnyRelocationType(RE);
501   bool IsPCRel = Obj->getAnyRelocationPCRel(RE);
502 
503   // Determine any addends that should be displayed with the relocation.
504   // These require decoding the relocation type, which is triple-specific.
505 
506   // X86_64 has entirely custom relocation types.
507   if (Arch == Triple::x86_64) {
508     switch (Type) {
509     case MachO::X86_64_RELOC_GOT_LOAD:
510     case MachO::X86_64_RELOC_GOT: {
511       printRelocationTargetName(Obj, RE, Fmt);
512       Fmt << "@GOT";
513       if (IsPCRel)
514         Fmt << "PCREL";
515       break;
516     }
517     case MachO::X86_64_RELOC_SUBTRACTOR: {
518       DataRefImpl RelNext = Rel;
519       Obj->moveRelocationNext(RelNext);
520       MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
521 
522       // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
523       // X86_64_RELOC_UNSIGNED.
524       // NOTE: Scattered relocations don't exist on x86_64.
525       unsigned RType = Obj->getAnyRelocationType(RENext);
526       if (RType != MachO::X86_64_RELOC_UNSIGNED)
527         reportError(Obj->getFileName(), "Expected X86_64_RELOC_UNSIGNED after "
528                                         "X86_64_RELOC_SUBTRACTOR.");
529 
530       // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
531       // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
532       printRelocationTargetName(Obj, RENext, Fmt);
533       Fmt << "-";
534       printRelocationTargetName(Obj, RE, Fmt);
535       break;
536     }
537     case MachO::X86_64_RELOC_TLV:
538       printRelocationTargetName(Obj, RE, Fmt);
539       Fmt << "@TLV";
540       if (IsPCRel)
541         Fmt << "P";
542       break;
543     case MachO::X86_64_RELOC_SIGNED_1:
544       printRelocationTargetName(Obj, RE, Fmt);
545       Fmt << "-1";
546       break;
547     case MachO::X86_64_RELOC_SIGNED_2:
548       printRelocationTargetName(Obj, RE, Fmt);
549       Fmt << "-2";
550       break;
551     case MachO::X86_64_RELOC_SIGNED_4:
552       printRelocationTargetName(Obj, RE, Fmt);
553       Fmt << "-4";
554       break;
555     default:
556       printRelocationTargetName(Obj, RE, Fmt);
557       break;
558     }
559     // X86 and ARM share some relocation types in common.
560   } else if (Arch == Triple::x86 || Arch == Triple::arm ||
561              Arch == Triple::ppc) {
562     // Generic relocation types...
563     switch (Type) {
564     case MachO::GENERIC_RELOC_PAIR: // prints no info
565       return Error::success();
566     case MachO::GENERIC_RELOC_SECTDIFF: {
567       DataRefImpl RelNext = Rel;
568       Obj->moveRelocationNext(RelNext);
569       MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
570 
571       // X86 sect diff's must be followed by a relocation of type
572       // GENERIC_RELOC_PAIR.
573       unsigned RType = Obj->getAnyRelocationType(RENext);
574 
575       if (RType != MachO::GENERIC_RELOC_PAIR)
576         reportError(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
577                                         "GENERIC_RELOC_SECTDIFF.");
578 
579       printRelocationTargetName(Obj, RE, Fmt);
580       Fmt << "-";
581       printRelocationTargetName(Obj, RENext, Fmt);
582       break;
583     }
584     }
585 
586     if (Arch == Triple::x86 || Arch == Triple::ppc) {
587       switch (Type) {
588       case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
589         DataRefImpl RelNext = Rel;
590         Obj->moveRelocationNext(RelNext);
591         MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
592 
593         // X86 sect diff's must be followed by a relocation of type
594         // GENERIC_RELOC_PAIR.
595         unsigned RType = Obj->getAnyRelocationType(RENext);
596         if (RType != MachO::GENERIC_RELOC_PAIR)
597           reportError(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
598                                           "GENERIC_RELOC_LOCAL_SECTDIFF.");
599 
600         printRelocationTargetName(Obj, RE, Fmt);
601         Fmt << "-";
602         printRelocationTargetName(Obj, RENext, Fmt);
603         break;
604       }
605       case MachO::GENERIC_RELOC_TLV: {
606         printRelocationTargetName(Obj, RE, Fmt);
607         Fmt << "@TLV";
608         if (IsPCRel)
609           Fmt << "P";
610         break;
611       }
612       default:
613         printRelocationTargetName(Obj, RE, Fmt);
614       }
615     } else { // ARM-specific relocations
616       switch (Type) {
617       case MachO::ARM_RELOC_HALF:
618       case MachO::ARM_RELOC_HALF_SECTDIFF: {
619         // Half relocations steal a bit from the length field to encode
620         // whether this is an upper16 or a lower16 relocation.
621         bool isUpper = (Obj->getAnyRelocationLength(RE) & 0x1) == 1;
622 
623         if (isUpper)
624           Fmt << ":upper16:(";
625         else
626           Fmt << ":lower16:(";
627         printRelocationTargetName(Obj, RE, Fmt);
628 
629         DataRefImpl RelNext = Rel;
630         Obj->moveRelocationNext(RelNext);
631         MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
632 
633         // ARM half relocs must be followed by a relocation of type
634         // ARM_RELOC_PAIR.
635         unsigned RType = Obj->getAnyRelocationType(RENext);
636         if (RType != MachO::ARM_RELOC_PAIR)
637           reportError(Obj->getFileName(), "Expected ARM_RELOC_PAIR after "
638                                           "ARM_RELOC_HALF");
639 
640         // NOTE: The half of the target virtual address is stashed in the
641         // address field of the secondary relocation, but we can't reverse
642         // engineer the constant offset from it without decoding the movw/movt
643         // instruction to find the other half in its immediate field.
644 
645         // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
646         // symbol/section pointer of the follow-on relocation.
647         if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
648           Fmt << "-";
649           printRelocationTargetName(Obj, RENext, Fmt);
650         }
651 
652         Fmt << ")";
653         break;
654       }
655       default: {
656         printRelocationTargetName(Obj, RE, Fmt);
657       }
658       }
659     }
660   } else
661     printRelocationTargetName(Obj, RE, Fmt);
662 
663   Fmt.flush();
664   Result.append(FmtBuf.begin(), FmtBuf.end());
665   return Error::success();
666 }
667 
668 static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose,
669                                      uint32_t n, uint32_t count,
670                                      uint32_t stride, uint64_t addr) {
671   MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
672   uint32_t nindirectsyms = Dysymtab.nindirectsyms;
673   if (n > nindirectsyms)
674     outs() << " (entries start past the end of the indirect symbol "
675               "table) (reserved1 field greater than the table size)";
676   else if (n + count > nindirectsyms)
677     outs() << " (entries extends past the end of the indirect symbol "
678               "table)";
679   outs() << "\n";
680   uint32_t cputype = O->getHeader().cputype;
681   if (cputype & MachO::CPU_ARCH_ABI64)
682     outs() << "address            index";
683   else
684     outs() << "address    index";
685   if (verbose)
686     outs() << " name\n";
687   else
688     outs() << "\n";
689   for (uint32_t j = 0; j < count && n + j < nindirectsyms; j++) {
690     if (cputype & MachO::CPU_ARCH_ABI64)
691       outs() << format("0x%016" PRIx64, addr + j * stride) << " ";
692     else
693       outs() << format("0x%08" PRIx32, (uint32_t)addr + j * stride) << " ";
694     MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
695     uint32_t indirect_symbol = O->getIndirectSymbolTableEntry(Dysymtab, n + j);
696     if (indirect_symbol == MachO::INDIRECT_SYMBOL_LOCAL) {
697       outs() << "LOCAL\n";
698       continue;
699     }
700     if (indirect_symbol ==
701         (MachO::INDIRECT_SYMBOL_LOCAL | MachO::INDIRECT_SYMBOL_ABS)) {
702       outs() << "LOCAL ABSOLUTE\n";
703       continue;
704     }
705     if (indirect_symbol == MachO::INDIRECT_SYMBOL_ABS) {
706       outs() << "ABSOLUTE\n";
707       continue;
708     }
709     outs() << format("%5u ", indirect_symbol);
710     if (verbose) {
711       MachO::symtab_command Symtab = O->getSymtabLoadCommand();
712       if (indirect_symbol < Symtab.nsyms) {
713         symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol);
714         SymbolRef Symbol = *Sym;
715         outs() << unwrapOrError(Symbol.getName(), O->getFileName());
716       } else {
717         outs() << "?";
718       }
719     }
720     outs() << "\n";
721   }
722 }
723 
724 static void PrintIndirectSymbols(MachOObjectFile *O, bool verbose) {
725   for (const auto &Load : O->load_commands()) {
726     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
727       MachO::segment_command_64 Seg = O->getSegment64LoadCommand(Load);
728       for (unsigned J = 0; J < Seg.nsects; ++J) {
729         MachO::section_64 Sec = O->getSection64(Load, J);
730         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
731         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
732             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
733             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
734             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
735             section_type == MachO::S_SYMBOL_STUBS) {
736           uint32_t stride;
737           if (section_type == MachO::S_SYMBOL_STUBS)
738             stride = Sec.reserved2;
739           else
740             stride = 8;
741           if (stride == 0) {
742             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
743                    << Sec.sectname << ") "
744                    << "(size of stubs in reserved2 field is zero)\n";
745             continue;
746           }
747           uint32_t count = Sec.size / stride;
748           outs() << "Indirect symbols for (" << Sec.segname << ","
749                  << Sec.sectname << ") " << count << " entries";
750           uint32_t n = Sec.reserved1;
751           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
752         }
753       }
754     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
755       MachO::segment_command Seg = O->getSegmentLoadCommand(Load);
756       for (unsigned J = 0; J < Seg.nsects; ++J) {
757         MachO::section Sec = O->getSection(Load, J);
758         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
759         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
760             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
761             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
762             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
763             section_type == MachO::S_SYMBOL_STUBS) {
764           uint32_t stride;
765           if (section_type == MachO::S_SYMBOL_STUBS)
766             stride = Sec.reserved2;
767           else
768             stride = 4;
769           if (stride == 0) {
770             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
771                    << Sec.sectname << ") "
772                    << "(size of stubs in reserved2 field is zero)\n";
773             continue;
774           }
775           uint32_t count = Sec.size / stride;
776           outs() << "Indirect symbols for (" << Sec.segname << ","
777                  << Sec.sectname << ") " << count << " entries";
778           uint32_t n = Sec.reserved1;
779           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
780         }
781       }
782     }
783   }
784 }
785 
786 static void PrintRType(const uint64_t cputype, const unsigned r_type) {
787   static char const *generic_r_types[] = {
788     "VANILLA ", "PAIR    ", "SECTDIF ", "PBLAPTR ", "LOCSDIF ", "TLV     ",
789     "  6 (?) ", "  7 (?) ", "  8 (?) ", "  9 (?) ", " 10 (?) ", " 11 (?) ",
790     " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) "
791   };
792   static char const *x86_64_r_types[] = {
793     "UNSIGND ", "SIGNED  ", "BRANCH  ", "GOT_LD  ", "GOT     ", "SUB     ",
794     "SIGNED1 ", "SIGNED2 ", "SIGNED4 ", "TLV     ", " 10 (?) ", " 11 (?) ",
795     " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) "
796   };
797   static char const *arm_r_types[] = {
798     "VANILLA ", "PAIR    ", "SECTDIFF", "LOCSDIF ", "PBLAPTR ",
799     "BR24    ", "T_BR22  ", "T_BR32  ", "HALF    ", "HALFDIF ",
800     " 10 (?) ", " 11 (?) ", " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) "
801   };
802   static char const *arm64_r_types[] = {
803     "UNSIGND ", "SUB     ", "BR26    ", "PAGE21  ", "PAGOF12 ",
804     "GOTLDP  ", "GOTLDPOF", "PTRTGOT ", "TLVLDP  ", "TLVLDPOF",
805     "ADDEND  ", " 11 (?) ", " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) "
806   };
807 
808   if (r_type > 0xf){
809     outs() << format("%-7u", r_type) << " ";
810     return;
811   }
812   switch (cputype) {
813     case MachO::CPU_TYPE_I386:
814       outs() << generic_r_types[r_type];
815       break;
816     case MachO::CPU_TYPE_X86_64:
817       outs() << x86_64_r_types[r_type];
818       break;
819     case MachO::CPU_TYPE_ARM:
820       outs() << arm_r_types[r_type];
821       break;
822     case MachO::CPU_TYPE_ARM64:
823     case MachO::CPU_TYPE_ARM64_32:
824       outs() << arm64_r_types[r_type];
825       break;
826     default:
827       outs() << format("%-7u ", r_type);
828   }
829 }
830 
831 static void PrintRLength(const uint64_t cputype, const unsigned r_type,
832                          const unsigned r_length, const bool previous_arm_half){
833   if (cputype == MachO::CPU_TYPE_ARM &&
834       (r_type == MachO::ARM_RELOC_HALF ||
835        r_type == MachO::ARM_RELOC_HALF_SECTDIFF || previous_arm_half == true)) {
836     if ((r_length & 0x1) == 0)
837       outs() << "lo/";
838     else
839       outs() << "hi/";
840     if ((r_length & 0x1) == 0)
841       outs() << "arm ";
842     else
843       outs() << "thm ";
844   } else {
845     switch (r_length) {
846       case 0:
847         outs() << "byte   ";
848         break;
849       case 1:
850         outs() << "word   ";
851         break;
852       case 2:
853         outs() << "long   ";
854         break;
855       case 3:
856         if (cputype == MachO::CPU_TYPE_X86_64)
857           outs() << "quad   ";
858         else
859           outs() << format("?(%2d)  ", r_length);
860         break;
861       default:
862         outs() << format("?(%2d)  ", r_length);
863     }
864   }
865 }
866 
867 static void PrintRelocationEntries(const MachOObjectFile *O,
868                                    const relocation_iterator Begin,
869                                    const relocation_iterator End,
870                                    const uint64_t cputype,
871                                    const bool verbose) {
872   const MachO::symtab_command Symtab = O->getSymtabLoadCommand();
873   bool previous_arm_half = false;
874   bool previous_sectdiff = false;
875   uint32_t sectdiff_r_type = 0;
876 
877   for (relocation_iterator Reloc = Begin; Reloc != End; ++Reloc) {
878     const DataRefImpl Rel = Reloc->getRawDataRefImpl();
879     const MachO::any_relocation_info RE = O->getRelocation(Rel);
880     const unsigned r_type = O->getAnyRelocationType(RE);
881     const bool r_scattered = O->isRelocationScattered(RE);
882     const unsigned r_pcrel = O->getAnyRelocationPCRel(RE);
883     const unsigned r_length = O->getAnyRelocationLength(RE);
884     const unsigned r_address = O->getAnyRelocationAddress(RE);
885     const bool r_extern = (r_scattered ? false :
886                            O->getPlainRelocationExternal(RE));
887     const uint32_t r_value = (r_scattered ?
888                               O->getScatteredRelocationValue(RE) : 0);
889     const unsigned r_symbolnum = (r_scattered ? 0 :
890                                   O->getPlainRelocationSymbolNum(RE));
891 
892     if (r_scattered && cputype != MachO::CPU_TYPE_X86_64) {
893       if (verbose) {
894         // scattered: address
895         if ((cputype == MachO::CPU_TYPE_I386 &&
896              r_type == MachO::GENERIC_RELOC_PAIR) ||
897             (cputype == MachO::CPU_TYPE_ARM && r_type == MachO::ARM_RELOC_PAIR))
898           outs() << "         ";
899         else
900           outs() << format("%08x ", (unsigned int)r_address);
901 
902         // scattered: pcrel
903         if (r_pcrel)
904           outs() << "True  ";
905         else
906           outs() << "False ";
907 
908         // scattered: length
909         PrintRLength(cputype, r_type, r_length, previous_arm_half);
910 
911         // scattered: extern & type
912         outs() << "n/a    ";
913         PrintRType(cputype, r_type);
914 
915         // scattered: scattered & value
916         outs() << format("True      0x%08x", (unsigned int)r_value);
917         if (previous_sectdiff == false) {
918           if ((cputype == MachO::CPU_TYPE_ARM &&
919                r_type == MachO::ARM_RELOC_PAIR))
920             outs() << format(" half = 0x%04x ", (unsigned int)r_address);
921         } else if (cputype == MachO::CPU_TYPE_ARM &&
922                    sectdiff_r_type == MachO::ARM_RELOC_HALF_SECTDIFF)
923           outs() << format(" other_half = 0x%04x ", (unsigned int)r_address);
924         if ((cputype == MachO::CPU_TYPE_I386 &&
925              (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
926               r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) ||
927             (cputype == MachO::CPU_TYPE_ARM &&
928              (sectdiff_r_type == MachO::ARM_RELOC_SECTDIFF ||
929               sectdiff_r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
930               sectdiff_r_type == MachO::ARM_RELOC_HALF_SECTDIFF))) {
931           previous_sectdiff = true;
932           sectdiff_r_type = r_type;
933         } else {
934           previous_sectdiff = false;
935           sectdiff_r_type = 0;
936         }
937         if (cputype == MachO::CPU_TYPE_ARM &&
938             (r_type == MachO::ARM_RELOC_HALF ||
939              r_type == MachO::ARM_RELOC_HALF_SECTDIFF))
940           previous_arm_half = true;
941         else
942           previous_arm_half = false;
943         outs() << "\n";
944       }
945       else {
946         // scattered: address pcrel length extern type scattered value
947         outs() << format("%08x %1d     %-2d     n/a    %-7d 1         0x%08x\n",
948                          (unsigned int)r_address, r_pcrel, r_length, r_type,
949                          (unsigned int)r_value);
950       }
951     }
952     else {
953       if (verbose) {
954         // plain: address
955         if (cputype == MachO::CPU_TYPE_ARM && r_type == MachO::ARM_RELOC_PAIR)
956           outs() << "         ";
957         else
958           outs() << format("%08x ", (unsigned int)r_address);
959 
960         // plain: pcrel
961         if (r_pcrel)
962           outs() << "True  ";
963         else
964           outs() << "False ";
965 
966         // plain: length
967         PrintRLength(cputype, r_type, r_length, previous_arm_half);
968 
969         if (r_extern) {
970           // plain: extern & type & scattered
971           outs() << "True   ";
972           PrintRType(cputype, r_type);
973           outs() << "False     ";
974 
975           // plain: symbolnum/value
976           if (r_symbolnum > Symtab.nsyms)
977             outs() << format("?(%d)\n", r_symbolnum);
978           else {
979             SymbolRef Symbol = *O->getSymbolByIndex(r_symbolnum);
980             Expected<StringRef> SymNameNext = Symbol.getName();
981             const char *name = NULL;
982             if (SymNameNext)
983               name = SymNameNext->data();
984             if (name == NULL)
985               outs() << format("?(%d)\n", r_symbolnum);
986             else
987               outs() << name << "\n";
988           }
989         }
990         else {
991           // plain: extern & type & scattered
992           outs() << "False  ";
993           PrintRType(cputype, r_type);
994           outs() << "False     ";
995 
996           // plain: symbolnum/value
997           if (cputype == MachO::CPU_TYPE_ARM && r_type == MachO::ARM_RELOC_PAIR)
998             outs() << format("other_half = 0x%04x\n", (unsigned int)r_address);
999           else if ((cputype == MachO::CPU_TYPE_ARM64 ||
1000                     cputype == MachO::CPU_TYPE_ARM64_32) &&
1001                    r_type == MachO::ARM64_RELOC_ADDEND)
1002             outs() << format("addend = 0x%06x\n", (unsigned int)r_symbolnum);
1003           else {
1004             outs() << format("%d ", r_symbolnum);
1005             if (r_symbolnum == MachO::R_ABS)
1006               outs() << "R_ABS\n";
1007             else {
1008               // in this case, r_symbolnum is actually a 1-based section number
1009               uint32_t nsects = O->section_end()->getRawDataRefImpl().d.a;
1010               if (r_symbolnum > 0 && r_symbolnum <= nsects) {
1011                 object::DataRefImpl DRI;
1012                 DRI.d.a = r_symbolnum-1;
1013                 StringRef SegName = O->getSectionFinalSegmentName(DRI);
1014                 if (Expected<StringRef> NameOrErr = O->getSectionName(DRI))
1015                   outs() << "(" << SegName << "," << *NameOrErr << ")\n";
1016                 else
1017                   outs() << "(?,?)\n";
1018               }
1019               else {
1020                 outs() << "(?,?)\n";
1021               }
1022             }
1023           }
1024         }
1025         if (cputype == MachO::CPU_TYPE_ARM &&
1026             (r_type == MachO::ARM_RELOC_HALF ||
1027              r_type == MachO::ARM_RELOC_HALF_SECTDIFF))
1028           previous_arm_half = true;
1029         else
1030           previous_arm_half = false;
1031       }
1032       else {
1033         // plain: address pcrel length extern type scattered symbolnum/section
1034         outs() << format("%08x %1d     %-2d     %1d      %-7d 0         %d\n",
1035                          (unsigned int)r_address, r_pcrel, r_length, r_extern,
1036                          r_type, r_symbolnum);
1037       }
1038     }
1039   }
1040 }
1041 
1042 static void PrintRelocations(const MachOObjectFile *O, const bool verbose) {
1043   const uint64_t cputype = O->getHeader().cputype;
1044   const MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
1045   if (Dysymtab.nextrel != 0) {
1046     outs() << "External relocation information " << Dysymtab.nextrel
1047            << " entries";
1048     outs() << "\naddress  pcrel length extern type    scattered "
1049               "symbolnum/value\n";
1050     PrintRelocationEntries(O, O->extrel_begin(), O->extrel_end(), cputype,
1051                            verbose);
1052   }
1053   if (Dysymtab.nlocrel != 0) {
1054     outs() << format("Local relocation information %u entries",
1055                      Dysymtab.nlocrel);
1056     outs() << "\naddress  pcrel length extern type    scattered "
1057               "symbolnum/value\n";
1058     PrintRelocationEntries(O, O->locrel_begin(), O->locrel_end(), cputype,
1059                            verbose);
1060   }
1061   for (const auto &Load : O->load_commands()) {
1062     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1063       const MachO::segment_command_64 Seg = O->getSegment64LoadCommand(Load);
1064       for (unsigned J = 0; J < Seg.nsects; ++J) {
1065         const MachO::section_64 Sec = O->getSection64(Load, J);
1066         if (Sec.nreloc != 0) {
1067           DataRefImpl DRI;
1068           DRI.d.a = J;
1069           const StringRef SegName = O->getSectionFinalSegmentName(DRI);
1070           if (Expected<StringRef> NameOrErr = O->getSectionName(DRI))
1071             outs() << "Relocation information (" << SegName << "," << *NameOrErr
1072                    << format(") %u entries", Sec.nreloc);
1073           else
1074             outs() << "Relocation information (" << SegName << ",?) "
1075                    << format("%u entries", Sec.nreloc);
1076           outs() << "\naddress  pcrel length extern type    scattered "
1077                     "symbolnum/value\n";
1078           PrintRelocationEntries(O, O->section_rel_begin(DRI),
1079                                  O->section_rel_end(DRI), cputype, verbose);
1080         }
1081       }
1082     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1083       const MachO::segment_command Seg = O->getSegmentLoadCommand(Load);
1084       for (unsigned J = 0; J < Seg.nsects; ++J) {
1085         const MachO::section Sec = O->getSection(Load, J);
1086         if (Sec.nreloc != 0) {
1087           DataRefImpl DRI;
1088           DRI.d.a = J;
1089           const StringRef SegName = O->getSectionFinalSegmentName(DRI);
1090           if (Expected<StringRef> NameOrErr = O->getSectionName(DRI))
1091             outs() << "Relocation information (" << SegName << "," << *NameOrErr
1092                    << format(") %u entries", Sec.nreloc);
1093           else
1094             outs() << "Relocation information (" << SegName << ",?) "
1095                    << format("%u entries", Sec.nreloc);
1096           outs() << "\naddress  pcrel length extern type    scattered "
1097                     "symbolnum/value\n";
1098           PrintRelocationEntries(O, O->section_rel_begin(DRI),
1099                                  O->section_rel_end(DRI), cputype, verbose);
1100         }
1101       }
1102     }
1103   }
1104 }
1105 
1106 static void PrintDataInCodeTable(MachOObjectFile *O, bool verbose) {
1107   MachO::linkedit_data_command DIC = O->getDataInCodeLoadCommand();
1108   uint32_t nentries = DIC.datasize / sizeof(struct MachO::data_in_code_entry);
1109   outs() << "Data in code table (" << nentries << " entries)\n";
1110   outs() << "offset     length kind\n";
1111   for (dice_iterator DI = O->begin_dices(), DE = O->end_dices(); DI != DE;
1112        ++DI) {
1113     uint32_t Offset;
1114     DI->getOffset(Offset);
1115     outs() << format("0x%08" PRIx32, Offset) << " ";
1116     uint16_t Length;
1117     DI->getLength(Length);
1118     outs() << format("%6u", Length) << " ";
1119     uint16_t Kind;
1120     DI->getKind(Kind);
1121     if (verbose) {
1122       switch (Kind) {
1123       case MachO::DICE_KIND_DATA:
1124         outs() << "DATA";
1125         break;
1126       case MachO::DICE_KIND_JUMP_TABLE8:
1127         outs() << "JUMP_TABLE8";
1128         break;
1129       case MachO::DICE_KIND_JUMP_TABLE16:
1130         outs() << "JUMP_TABLE16";
1131         break;
1132       case MachO::DICE_KIND_JUMP_TABLE32:
1133         outs() << "JUMP_TABLE32";
1134         break;
1135       case MachO::DICE_KIND_ABS_JUMP_TABLE32:
1136         outs() << "ABS_JUMP_TABLE32";
1137         break;
1138       default:
1139         outs() << format("0x%04" PRIx32, Kind);
1140         break;
1141       }
1142     } else
1143       outs() << format("0x%04" PRIx32, Kind);
1144     outs() << "\n";
1145   }
1146 }
1147 
1148 static void PrintLinkOptHints(MachOObjectFile *O) {
1149   MachO::linkedit_data_command LohLC = O->getLinkOptHintsLoadCommand();
1150   const char *loh = O->getData().substr(LohLC.dataoff, 1).data();
1151   uint32_t nloh = LohLC.datasize;
1152   outs() << "Linker optimiztion hints (" << nloh << " total bytes)\n";
1153   for (uint32_t i = 0; i < nloh;) {
1154     unsigned n;
1155     uint64_t identifier = decodeULEB128((const uint8_t *)(loh + i), &n);
1156     i += n;
1157     outs() << "    identifier " << identifier << " ";
1158     if (i >= nloh)
1159       return;
1160     switch (identifier) {
1161     case 1:
1162       outs() << "AdrpAdrp\n";
1163       break;
1164     case 2:
1165       outs() << "AdrpLdr\n";
1166       break;
1167     case 3:
1168       outs() << "AdrpAddLdr\n";
1169       break;
1170     case 4:
1171       outs() << "AdrpLdrGotLdr\n";
1172       break;
1173     case 5:
1174       outs() << "AdrpAddStr\n";
1175       break;
1176     case 6:
1177       outs() << "AdrpLdrGotStr\n";
1178       break;
1179     case 7:
1180       outs() << "AdrpAdd\n";
1181       break;
1182     case 8:
1183       outs() << "AdrpLdrGot\n";
1184       break;
1185     default:
1186       outs() << "Unknown identifier value\n";
1187       break;
1188     }
1189     uint64_t narguments = decodeULEB128((const uint8_t *)(loh + i), &n);
1190     i += n;
1191     outs() << "    narguments " << narguments << "\n";
1192     if (i >= nloh)
1193       return;
1194 
1195     for (uint32_t j = 0; j < narguments; j++) {
1196       uint64_t value = decodeULEB128((const uint8_t *)(loh + i), &n);
1197       i += n;
1198       outs() << "\tvalue " << format("0x%" PRIx64, value) << "\n";
1199       if (i >= nloh)
1200         return;
1201     }
1202   }
1203 }
1204 
1205 static void PrintDylibs(MachOObjectFile *O, bool JustId) {
1206   unsigned Index = 0;
1207   for (const auto &Load : O->load_commands()) {
1208     if ((JustId && Load.C.cmd == MachO::LC_ID_DYLIB) ||
1209         (!JustId && (Load.C.cmd == MachO::LC_ID_DYLIB ||
1210                      Load.C.cmd == MachO::LC_LOAD_DYLIB ||
1211                      Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
1212                      Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
1213                      Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
1214                      Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB))) {
1215       MachO::dylib_command dl = O->getDylibIDLoadCommand(Load);
1216       if (dl.dylib.name < dl.cmdsize) {
1217         const char *p = (const char *)(Load.Ptr) + dl.dylib.name;
1218         if (JustId)
1219           outs() << p << "\n";
1220         else {
1221           outs() << "\t" << p;
1222           outs() << " (compatibility version "
1223                  << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
1224                  << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
1225                  << (dl.dylib.compatibility_version & 0xff) << ",";
1226           outs() << " current version "
1227                  << ((dl.dylib.current_version >> 16) & 0xffff) << "."
1228                  << ((dl.dylib.current_version >> 8) & 0xff) << "."
1229                  << (dl.dylib.current_version & 0xff);
1230           if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB)
1231             outs() << ", weak";
1232           if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB)
1233             outs() << ", reexport";
1234           if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
1235             outs() << ", upward";
1236           if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB)
1237             outs() << ", lazy";
1238           outs() << ")\n";
1239         }
1240       } else {
1241         outs() << "\tBad offset (" << dl.dylib.name << ") for name of ";
1242         if (Load.C.cmd == MachO::LC_ID_DYLIB)
1243           outs() << "LC_ID_DYLIB ";
1244         else if (Load.C.cmd == MachO::LC_LOAD_DYLIB)
1245           outs() << "LC_LOAD_DYLIB ";
1246         else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB)
1247           outs() << "LC_LOAD_WEAK_DYLIB ";
1248         else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB)
1249           outs() << "LC_LAZY_LOAD_DYLIB ";
1250         else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB)
1251           outs() << "LC_REEXPORT_DYLIB ";
1252         else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
1253           outs() << "LC_LOAD_UPWARD_DYLIB ";
1254         else
1255           outs() << "LC_??? ";
1256         outs() << "command " << Index++ << "\n";
1257       }
1258     }
1259   }
1260 }
1261 
1262 typedef DenseMap<uint64_t, StringRef> SymbolAddressMap;
1263 
1264 static void CreateSymbolAddressMap(MachOObjectFile *O,
1265                                    SymbolAddressMap *AddrMap) {
1266   // Create a map of symbol addresses to symbol names.
1267   const StringRef FileName = O->getFileName();
1268   for (const SymbolRef &Symbol : O->symbols()) {
1269     SymbolRef::Type ST = unwrapOrError(Symbol.getType(), FileName);
1270     if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
1271         ST == SymbolRef::ST_Other) {
1272       uint64_t Address = cantFail(Symbol.getValue());
1273       StringRef SymName = unwrapOrError(Symbol.getName(), FileName);
1274       if (!SymName.startswith(".objc"))
1275         (*AddrMap)[Address] = SymName;
1276     }
1277   }
1278 }
1279 
1280 // GuessSymbolName is passed the address of what might be a symbol and a
1281 // pointer to the SymbolAddressMap.  It returns the name of a symbol
1282 // with that address or nullptr if no symbol is found with that address.
1283 static const char *GuessSymbolName(uint64_t value, SymbolAddressMap *AddrMap) {
1284   const char *SymbolName = nullptr;
1285   // A DenseMap can't lookup up some values.
1286   if (value != 0xffffffffffffffffULL && value != 0xfffffffffffffffeULL) {
1287     StringRef name = AddrMap->lookup(value);
1288     if (!name.empty())
1289       SymbolName = name.data();
1290   }
1291   return SymbolName;
1292 }
1293 
1294 static void DumpCstringChar(const char c) {
1295   char p[2];
1296   p[0] = c;
1297   p[1] = '\0';
1298   outs().write_escaped(p);
1299 }
1300 
1301 static void DumpCstringSection(MachOObjectFile *O, const char *sect,
1302                                uint32_t sect_size, uint64_t sect_addr,
1303                                bool print_addresses) {
1304   for (uint32_t i = 0; i < sect_size; i++) {
1305     if (print_addresses) {
1306       if (O->is64Bit())
1307         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1308       else
1309         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1310     }
1311     for (; i < sect_size && sect[i] != '\0'; i++)
1312       DumpCstringChar(sect[i]);
1313     if (i < sect_size && sect[i] == '\0')
1314       outs() << "\n";
1315   }
1316 }
1317 
1318 static void DumpLiteral4(uint32_t l, float f) {
1319   outs() << format("0x%08" PRIx32, l);
1320   if ((l & 0x7f800000) != 0x7f800000)
1321     outs() << format(" (%.16e)\n", f);
1322   else {
1323     if (l == 0x7f800000)
1324       outs() << " (+Infinity)\n";
1325     else if (l == 0xff800000)
1326       outs() << " (-Infinity)\n";
1327     else if ((l & 0x00400000) == 0x00400000)
1328       outs() << " (non-signaling Not-a-Number)\n";
1329     else
1330       outs() << " (signaling Not-a-Number)\n";
1331   }
1332 }
1333 
1334 static void DumpLiteral4Section(MachOObjectFile *O, const char *sect,
1335                                 uint32_t sect_size, uint64_t sect_addr,
1336                                 bool print_addresses) {
1337   for (uint32_t i = 0; i < sect_size; i += sizeof(float)) {
1338     if (print_addresses) {
1339       if (O->is64Bit())
1340         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1341       else
1342         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1343     }
1344     float f;
1345     memcpy(&f, sect + i, sizeof(float));
1346     if (O->isLittleEndian() != sys::IsLittleEndianHost)
1347       sys::swapByteOrder(f);
1348     uint32_t l;
1349     memcpy(&l, sect + i, sizeof(uint32_t));
1350     if (O->isLittleEndian() != sys::IsLittleEndianHost)
1351       sys::swapByteOrder(l);
1352     DumpLiteral4(l, f);
1353   }
1354 }
1355 
1356 static void DumpLiteral8(MachOObjectFile *O, uint32_t l0, uint32_t l1,
1357                          double d) {
1358   outs() << format("0x%08" PRIx32, l0) << " " << format("0x%08" PRIx32, l1);
1359   uint32_t Hi, Lo;
1360   Hi = (O->isLittleEndian()) ? l1 : l0;
1361   Lo = (O->isLittleEndian()) ? l0 : l1;
1362 
1363   // Hi is the high word, so this is equivalent to if(isfinite(d))
1364   if ((Hi & 0x7ff00000) != 0x7ff00000)
1365     outs() << format(" (%.16e)\n", d);
1366   else {
1367     if (Hi == 0x7ff00000 && Lo == 0)
1368       outs() << " (+Infinity)\n";
1369     else if (Hi == 0xfff00000 && Lo == 0)
1370       outs() << " (-Infinity)\n";
1371     else if ((Hi & 0x00080000) == 0x00080000)
1372       outs() << " (non-signaling Not-a-Number)\n";
1373     else
1374       outs() << " (signaling Not-a-Number)\n";
1375   }
1376 }
1377 
1378 static void DumpLiteral8Section(MachOObjectFile *O, const char *sect,
1379                                 uint32_t sect_size, uint64_t sect_addr,
1380                                 bool print_addresses) {
1381   for (uint32_t i = 0; i < sect_size; i += sizeof(double)) {
1382     if (print_addresses) {
1383       if (O->is64Bit())
1384         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1385       else
1386         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1387     }
1388     double d;
1389     memcpy(&d, sect + i, sizeof(double));
1390     if (O->isLittleEndian() != sys::IsLittleEndianHost)
1391       sys::swapByteOrder(d);
1392     uint32_t l0, l1;
1393     memcpy(&l0, sect + i, sizeof(uint32_t));
1394     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
1395     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1396       sys::swapByteOrder(l0);
1397       sys::swapByteOrder(l1);
1398     }
1399     DumpLiteral8(O, l0, l1, d);
1400   }
1401 }
1402 
1403 static void DumpLiteral16(uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3) {
1404   outs() << format("0x%08" PRIx32, l0) << " ";
1405   outs() << format("0x%08" PRIx32, l1) << " ";
1406   outs() << format("0x%08" PRIx32, l2) << " ";
1407   outs() << format("0x%08" PRIx32, l3) << "\n";
1408 }
1409 
1410 static void DumpLiteral16Section(MachOObjectFile *O, const char *sect,
1411                                  uint32_t sect_size, uint64_t sect_addr,
1412                                  bool print_addresses) {
1413   for (uint32_t i = 0; i < sect_size; i += 16) {
1414     if (print_addresses) {
1415       if (O->is64Bit())
1416         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1417       else
1418         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1419     }
1420     uint32_t l0, l1, l2, l3;
1421     memcpy(&l0, sect + i, sizeof(uint32_t));
1422     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
1423     memcpy(&l2, sect + i + 2 * sizeof(uint32_t), sizeof(uint32_t));
1424     memcpy(&l3, sect + i + 3 * sizeof(uint32_t), sizeof(uint32_t));
1425     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1426       sys::swapByteOrder(l0);
1427       sys::swapByteOrder(l1);
1428       sys::swapByteOrder(l2);
1429       sys::swapByteOrder(l3);
1430     }
1431     DumpLiteral16(l0, l1, l2, l3);
1432   }
1433 }
1434 
1435 static void DumpLiteralPointerSection(MachOObjectFile *O,
1436                                       const SectionRef &Section,
1437                                       const char *sect, uint32_t sect_size,
1438                                       uint64_t sect_addr,
1439                                       bool print_addresses) {
1440   // Collect the literal sections in this Mach-O file.
1441   std::vector<SectionRef> LiteralSections;
1442   for (const SectionRef &Section : O->sections()) {
1443     DataRefImpl Ref = Section.getRawDataRefImpl();
1444     uint32_t section_type;
1445     if (O->is64Bit()) {
1446       const MachO::section_64 Sec = O->getSection64(Ref);
1447       section_type = Sec.flags & MachO::SECTION_TYPE;
1448     } else {
1449       const MachO::section Sec = O->getSection(Ref);
1450       section_type = Sec.flags & MachO::SECTION_TYPE;
1451     }
1452     if (section_type == MachO::S_CSTRING_LITERALS ||
1453         section_type == MachO::S_4BYTE_LITERALS ||
1454         section_type == MachO::S_8BYTE_LITERALS ||
1455         section_type == MachO::S_16BYTE_LITERALS)
1456       LiteralSections.push_back(Section);
1457   }
1458 
1459   // Set the size of the literal pointer.
1460   uint32_t lp_size = O->is64Bit() ? 8 : 4;
1461 
1462   // Collect the external relocation symbols for the literal pointers.
1463   std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
1464   for (const RelocationRef &Reloc : Section.relocations()) {
1465     DataRefImpl Rel;
1466     MachO::any_relocation_info RE;
1467     bool isExtern = false;
1468     Rel = Reloc.getRawDataRefImpl();
1469     RE = O->getRelocation(Rel);
1470     isExtern = O->getPlainRelocationExternal(RE);
1471     if (isExtern) {
1472       uint64_t RelocOffset = Reloc.getOffset();
1473       symbol_iterator RelocSym = Reloc.getSymbol();
1474       Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
1475     }
1476   }
1477   array_pod_sort(Relocs.begin(), Relocs.end());
1478 
1479   // Dump each literal pointer.
1480   for (uint32_t i = 0; i < sect_size; i += lp_size) {
1481     if (print_addresses) {
1482       if (O->is64Bit())
1483         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1484       else
1485         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1486     }
1487     uint64_t lp;
1488     if (O->is64Bit()) {
1489       memcpy(&lp, sect + i, sizeof(uint64_t));
1490       if (O->isLittleEndian() != sys::IsLittleEndianHost)
1491         sys::swapByteOrder(lp);
1492     } else {
1493       uint32_t li;
1494       memcpy(&li, sect + i, sizeof(uint32_t));
1495       if (O->isLittleEndian() != sys::IsLittleEndianHost)
1496         sys::swapByteOrder(li);
1497       lp = li;
1498     }
1499 
1500     // First look for an external relocation entry for this literal pointer.
1501     auto Reloc = find_if(Relocs, [&](const std::pair<uint64_t, SymbolRef> &P) {
1502       return P.first == i;
1503     });
1504     if (Reloc != Relocs.end()) {
1505       symbol_iterator RelocSym = Reloc->second;
1506       StringRef SymName = unwrapOrError(RelocSym->getName(), O->getFileName());
1507       outs() << "external relocation entry for symbol:" << SymName << "\n";
1508       continue;
1509     }
1510 
1511     // For local references see what the section the literal pointer points to.
1512     auto Sect = find_if(LiteralSections, [&](const SectionRef &R) {
1513       return lp >= R.getAddress() && lp < R.getAddress() + R.getSize();
1514     });
1515     if (Sect == LiteralSections.end()) {
1516       outs() << format("0x%" PRIx64, lp) << " (not in a literal section)\n";
1517       continue;
1518     }
1519 
1520     uint64_t SectAddress = Sect->getAddress();
1521     uint64_t SectSize = Sect->getSize();
1522 
1523     StringRef SectName;
1524     Expected<StringRef> SectNameOrErr = Sect->getName();
1525     if (SectNameOrErr)
1526       SectName = *SectNameOrErr;
1527     else
1528       consumeError(SectNameOrErr.takeError());
1529 
1530     DataRefImpl Ref = Sect->getRawDataRefImpl();
1531     StringRef SegmentName = O->getSectionFinalSegmentName(Ref);
1532     outs() << SegmentName << ":" << SectName << ":";
1533 
1534     uint32_t section_type;
1535     if (O->is64Bit()) {
1536       const MachO::section_64 Sec = O->getSection64(Ref);
1537       section_type = Sec.flags & MachO::SECTION_TYPE;
1538     } else {
1539       const MachO::section Sec = O->getSection(Ref);
1540       section_type = Sec.flags & MachO::SECTION_TYPE;
1541     }
1542 
1543     StringRef BytesStr = unwrapOrError(Sect->getContents(), O->getFileName());
1544 
1545     const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
1546 
1547     switch (section_type) {
1548     case MachO::S_CSTRING_LITERALS:
1549       for (uint64_t i = lp - SectAddress; i < SectSize && Contents[i] != '\0';
1550            i++) {
1551         DumpCstringChar(Contents[i]);
1552       }
1553       outs() << "\n";
1554       break;
1555     case MachO::S_4BYTE_LITERALS:
1556       float f;
1557       memcpy(&f, Contents + (lp - SectAddress), sizeof(float));
1558       uint32_t l;
1559       memcpy(&l, Contents + (lp - SectAddress), sizeof(uint32_t));
1560       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1561         sys::swapByteOrder(f);
1562         sys::swapByteOrder(l);
1563       }
1564       DumpLiteral4(l, f);
1565       break;
1566     case MachO::S_8BYTE_LITERALS: {
1567       double d;
1568       memcpy(&d, Contents + (lp - SectAddress), sizeof(double));
1569       uint32_t l0, l1;
1570       memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
1571       memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
1572              sizeof(uint32_t));
1573       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1574         sys::swapByteOrder(f);
1575         sys::swapByteOrder(l0);
1576         sys::swapByteOrder(l1);
1577       }
1578       DumpLiteral8(O, l0, l1, d);
1579       break;
1580     }
1581     case MachO::S_16BYTE_LITERALS: {
1582       uint32_t l0, l1, l2, l3;
1583       memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
1584       memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
1585              sizeof(uint32_t));
1586       memcpy(&l2, Contents + (lp - SectAddress) + 2 * sizeof(uint32_t),
1587              sizeof(uint32_t));
1588       memcpy(&l3, Contents + (lp - SectAddress) + 3 * sizeof(uint32_t),
1589              sizeof(uint32_t));
1590       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1591         sys::swapByteOrder(l0);
1592         sys::swapByteOrder(l1);
1593         sys::swapByteOrder(l2);
1594         sys::swapByteOrder(l3);
1595       }
1596       DumpLiteral16(l0, l1, l2, l3);
1597       break;
1598     }
1599     }
1600   }
1601 }
1602 
1603 static void DumpInitTermPointerSection(MachOObjectFile *O,
1604                                        const SectionRef &Section,
1605                                        const char *sect,
1606                                        uint32_t sect_size, uint64_t sect_addr,
1607                                        SymbolAddressMap *AddrMap,
1608                                        bool verbose) {
1609   uint32_t stride;
1610   stride = (O->is64Bit()) ? sizeof(uint64_t) : sizeof(uint32_t);
1611 
1612   // Collect the external relocation symbols for the pointers.
1613   std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
1614   for (const RelocationRef &Reloc : Section.relocations()) {
1615     DataRefImpl Rel;
1616     MachO::any_relocation_info RE;
1617     bool isExtern = false;
1618     Rel = Reloc.getRawDataRefImpl();
1619     RE = O->getRelocation(Rel);
1620     isExtern = O->getPlainRelocationExternal(RE);
1621     if (isExtern) {
1622       uint64_t RelocOffset = Reloc.getOffset();
1623       symbol_iterator RelocSym = Reloc.getSymbol();
1624       Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
1625     }
1626   }
1627   array_pod_sort(Relocs.begin(), Relocs.end());
1628 
1629   for (uint32_t i = 0; i < sect_size; i += stride) {
1630     const char *SymbolName = nullptr;
1631     uint64_t p;
1632     if (O->is64Bit()) {
1633       outs() << format("0x%016" PRIx64, sect_addr + i * stride) << " ";
1634       uint64_t pointer_value;
1635       memcpy(&pointer_value, sect + i, stride);
1636       if (O->isLittleEndian() != sys::IsLittleEndianHost)
1637         sys::swapByteOrder(pointer_value);
1638       outs() << format("0x%016" PRIx64, pointer_value);
1639       p = pointer_value;
1640     } else {
1641       outs() << format("0x%08" PRIx64, sect_addr + i * stride) << " ";
1642       uint32_t pointer_value;
1643       memcpy(&pointer_value, sect + i, stride);
1644       if (O->isLittleEndian() != sys::IsLittleEndianHost)
1645         sys::swapByteOrder(pointer_value);
1646       outs() << format("0x%08" PRIx32, pointer_value);
1647       p = pointer_value;
1648     }
1649     if (verbose) {
1650       // First look for an external relocation entry for this pointer.
1651       auto Reloc = find_if(Relocs, [&](const std::pair<uint64_t, SymbolRef> &P) {
1652         return P.first == i;
1653       });
1654       if (Reloc != Relocs.end()) {
1655         symbol_iterator RelocSym = Reloc->second;
1656         outs() << " " << unwrapOrError(RelocSym->getName(), O->getFileName());
1657       } else {
1658         SymbolName = GuessSymbolName(p, AddrMap);
1659         if (SymbolName)
1660           outs() << " " << SymbolName;
1661       }
1662     }
1663     outs() << "\n";
1664   }
1665 }
1666 
1667 static void DumpRawSectionContents(MachOObjectFile *O, const char *sect,
1668                                    uint32_t size, uint64_t addr) {
1669   uint32_t cputype = O->getHeader().cputype;
1670   if (cputype == MachO::CPU_TYPE_I386 || cputype == MachO::CPU_TYPE_X86_64) {
1671     uint32_t j;
1672     for (uint32_t i = 0; i < size; i += j, addr += j) {
1673       if (O->is64Bit())
1674         outs() << format("%016" PRIx64, addr) << "\t";
1675       else
1676         outs() << format("%08" PRIx64, addr) << "\t";
1677       for (j = 0; j < 16 && i + j < size; j++) {
1678         uint8_t byte_word = *(sect + i + j);
1679         outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
1680       }
1681       outs() << "\n";
1682     }
1683   } else {
1684     uint32_t j;
1685     for (uint32_t i = 0; i < size; i += j, addr += j) {
1686       if (O->is64Bit())
1687         outs() << format("%016" PRIx64, addr) << "\t";
1688       else
1689         outs() << format("%08" PRIx64, addr) << "\t";
1690       for (j = 0; j < 4 * sizeof(int32_t) && i + j < size;
1691            j += sizeof(int32_t)) {
1692         if (i + j + sizeof(int32_t) <= size) {
1693           uint32_t long_word;
1694           memcpy(&long_word, sect + i + j, sizeof(int32_t));
1695           if (O->isLittleEndian() != sys::IsLittleEndianHost)
1696             sys::swapByteOrder(long_word);
1697           outs() << format("%08" PRIx32, long_word) << " ";
1698         } else {
1699           for (uint32_t k = 0; i + j + k < size; k++) {
1700             uint8_t byte_word = *(sect + i + j + k);
1701             outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
1702           }
1703         }
1704       }
1705       outs() << "\n";
1706     }
1707   }
1708 }
1709 
1710 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
1711                              StringRef DisSegName, StringRef DisSectName);
1712 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,
1713                                 uint32_t size, uint32_t addr);
1714 #ifdef HAVE_LIBXAR
1715 static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
1716                                 uint32_t size, bool verbose,
1717                                 bool PrintXarHeader, bool PrintXarFileHeaders,
1718                                 std::string XarMemberName);
1719 #endif // defined(HAVE_LIBXAR)
1720 
1721 static void DumpSectionContents(StringRef Filename, MachOObjectFile *O,
1722                                 bool verbose) {
1723   SymbolAddressMap AddrMap;
1724   if (verbose)
1725     CreateSymbolAddressMap(O, &AddrMap);
1726 
1727   for (unsigned i = 0; i < FilterSections.size(); ++i) {
1728     StringRef DumpSection = FilterSections[i];
1729     std::pair<StringRef, StringRef> DumpSegSectName;
1730     DumpSegSectName = DumpSection.split(',');
1731     StringRef DumpSegName, DumpSectName;
1732     if (!DumpSegSectName.second.empty()) {
1733       DumpSegName = DumpSegSectName.first;
1734       DumpSectName = DumpSegSectName.second;
1735     } else {
1736       DumpSegName = "";
1737       DumpSectName = DumpSegSectName.first;
1738     }
1739     for (const SectionRef &Section : O->sections()) {
1740       StringRef SectName;
1741       Expected<StringRef> SecNameOrErr = Section.getName();
1742       if (SecNameOrErr)
1743         SectName = *SecNameOrErr;
1744       else
1745         consumeError(SecNameOrErr.takeError());
1746 
1747       if (!DumpSection.empty())
1748         FoundSectionSet.insert(DumpSection);
1749 
1750       DataRefImpl Ref = Section.getRawDataRefImpl();
1751       StringRef SegName = O->getSectionFinalSegmentName(Ref);
1752       if ((DumpSegName.empty() || SegName == DumpSegName) &&
1753           (SectName == DumpSectName)) {
1754 
1755         uint32_t section_flags;
1756         if (O->is64Bit()) {
1757           const MachO::section_64 Sec = O->getSection64(Ref);
1758           section_flags = Sec.flags;
1759 
1760         } else {
1761           const MachO::section Sec = O->getSection(Ref);
1762           section_flags = Sec.flags;
1763         }
1764         uint32_t section_type = section_flags & MachO::SECTION_TYPE;
1765 
1766         StringRef BytesStr =
1767             unwrapOrError(Section.getContents(), O->getFileName());
1768         const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1769         uint32_t sect_size = BytesStr.size();
1770         uint64_t sect_addr = Section.getAddress();
1771 
1772         if (!NoLeadingHeaders)
1773           outs() << "Contents of (" << SegName << "," << SectName
1774                  << ") section\n";
1775 
1776         if (verbose) {
1777           if ((section_flags & MachO::S_ATTR_PURE_INSTRUCTIONS) ||
1778               (section_flags & MachO::S_ATTR_SOME_INSTRUCTIONS)) {
1779             DisassembleMachO(Filename, O, SegName, SectName);
1780             continue;
1781           }
1782           if (SegName == "__TEXT" && SectName == "__info_plist") {
1783             outs() << sect;
1784             continue;
1785           }
1786           if (SegName == "__OBJC" && SectName == "__protocol") {
1787             DumpProtocolSection(O, sect, sect_size, sect_addr);
1788             continue;
1789           }
1790 #ifdef HAVE_LIBXAR
1791           if (SegName == "__LLVM" && SectName == "__bundle") {
1792             DumpBitcodeSection(O, sect, sect_size, verbose, !NoSymbolicOperands,
1793                                ArchiveHeaders, "");
1794             continue;
1795           }
1796 #endif // defined(HAVE_LIBXAR)
1797           switch (section_type) {
1798           case MachO::S_REGULAR:
1799             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1800             break;
1801           case MachO::S_ZEROFILL:
1802             outs() << "zerofill section and has no contents in the file\n";
1803             break;
1804           case MachO::S_CSTRING_LITERALS:
1805             DumpCstringSection(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1806             break;
1807           case MachO::S_4BYTE_LITERALS:
1808             DumpLiteral4Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1809             break;
1810           case MachO::S_8BYTE_LITERALS:
1811             DumpLiteral8Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1812             break;
1813           case MachO::S_16BYTE_LITERALS:
1814             DumpLiteral16Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1815             break;
1816           case MachO::S_LITERAL_POINTERS:
1817             DumpLiteralPointerSection(O, Section, sect, sect_size, sect_addr,
1818                                       !NoLeadingAddr);
1819             break;
1820           case MachO::S_MOD_INIT_FUNC_POINTERS:
1821           case MachO::S_MOD_TERM_FUNC_POINTERS:
1822             DumpInitTermPointerSection(O, Section, sect, sect_size, sect_addr,
1823                                        &AddrMap, verbose);
1824             break;
1825           default:
1826             outs() << "Unknown section type ("
1827                    << format("0x%08" PRIx32, section_type) << ")\n";
1828             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1829             break;
1830           }
1831         } else {
1832           if (section_type == MachO::S_ZEROFILL)
1833             outs() << "zerofill section and has no contents in the file\n";
1834           else
1835             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1836         }
1837       }
1838     }
1839   }
1840 }
1841 
1842 static void DumpInfoPlistSectionContents(StringRef Filename,
1843                                          MachOObjectFile *O) {
1844   for (const SectionRef &Section : O->sections()) {
1845     StringRef SectName;
1846     Expected<StringRef> SecNameOrErr = Section.getName();
1847     if (SecNameOrErr)
1848       SectName = *SecNameOrErr;
1849     else
1850       consumeError(SecNameOrErr.takeError());
1851 
1852     DataRefImpl Ref = Section.getRawDataRefImpl();
1853     StringRef SegName = O->getSectionFinalSegmentName(Ref);
1854     if (SegName == "__TEXT" && SectName == "__info_plist") {
1855       if (!NoLeadingHeaders)
1856         outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
1857       StringRef BytesStr =
1858           unwrapOrError(Section.getContents(), O->getFileName());
1859       const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1860       outs() << format("%.*s", BytesStr.size(), sect) << "\n";
1861       return;
1862     }
1863   }
1864 }
1865 
1866 // checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file
1867 // and if it is and there is a list of architecture flags is specified then
1868 // check to make sure this Mach-O file is one of those architectures or all
1869 // architectures were specified.  If not then an error is generated and this
1870 // routine returns false.  Else it returns true.
1871 static bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) {
1872   auto *MachO = dyn_cast<MachOObjectFile>(O);
1873 
1874   if (!MachO || ArchAll || ArchFlags.empty())
1875     return true;
1876 
1877   MachO::mach_header H;
1878   MachO::mach_header_64 H_64;
1879   Triple T;
1880   const char *McpuDefault, *ArchFlag;
1881   if (MachO->is64Bit()) {
1882     H_64 = MachO->MachOObjectFile::getHeader64();
1883     T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype,
1884                                        &McpuDefault, &ArchFlag);
1885   } else {
1886     H = MachO->MachOObjectFile::getHeader();
1887     T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype,
1888                                        &McpuDefault, &ArchFlag);
1889   }
1890   const std::string ArchFlagName(ArchFlag);
1891   if (none_of(ArchFlags, [&](const std::string &Name) {
1892         return Name == ArchFlagName;
1893       })) {
1894     WithColor::error(errs(), "llvm-objdump")
1895         << Filename << ": no architecture specified.\n";
1896     return false;
1897   }
1898   return true;
1899 }
1900 
1901 static void printObjcMetaData(MachOObjectFile *O, bool verbose);
1902 
1903 // ProcessMachO() is passed a single opened Mach-O file, which may be an
1904 // archive member and or in a slice of a universal file.  It prints the
1905 // the file name and header info and then processes it according to the
1906 // command line options.
1907 static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
1908                          StringRef ArchiveMemberName = StringRef(),
1909                          StringRef ArchitectureName = StringRef()) {
1910   // If we are doing some processing here on the Mach-O file print the header
1911   // info.  And don't print it otherwise like in the case of printing the
1912   // UniversalHeaders or ArchiveHeaders.
1913   if (Disassemble || Relocations || PrivateHeaders || ExportsTrie || Rebase ||
1914       Bind || SymbolTable || LazyBind || WeakBind || IndirectSymbols ||
1915       DataInCode || LinkOptHints || DylibsUsed || DylibId || ObjcMetaData ||
1916       (!FilterSections.empty())) {
1917     if (!NoLeadingHeaders) {
1918       outs() << Name;
1919       if (!ArchiveMemberName.empty())
1920         outs() << '(' << ArchiveMemberName << ')';
1921       if (!ArchitectureName.empty())
1922         outs() << " (architecture " << ArchitectureName << ")";
1923       outs() << ":\n";
1924     }
1925   }
1926   // To use the report_error() form with an ArchiveName and FileName set
1927   // these up based on what is passed for Name and ArchiveMemberName.
1928   StringRef ArchiveName;
1929   StringRef FileName;
1930   if (!ArchiveMemberName.empty()) {
1931     ArchiveName = Name;
1932     FileName = ArchiveMemberName;
1933   } else {
1934     ArchiveName = StringRef();
1935     FileName = Name;
1936   }
1937 
1938   // If we need the symbol table to do the operation then check it here to
1939   // produce a good error message as to where the Mach-O file comes from in
1940   // the error message.
1941   if (Disassemble || IndirectSymbols || !FilterSections.empty() || UnwindInfo)
1942     if (Error Err = MachOOF->checkSymbolTable())
1943       reportError(std::move(Err), FileName, ArchiveName, ArchitectureName);
1944 
1945   if (DisassembleAll) {
1946     for (const SectionRef &Section : MachOOF->sections()) {
1947       StringRef SectName;
1948       if (Expected<StringRef> NameOrErr = Section.getName())
1949         SectName = *NameOrErr;
1950       else
1951         consumeError(NameOrErr.takeError());
1952 
1953       if (SectName.equals("__text")) {
1954         DataRefImpl Ref = Section.getRawDataRefImpl();
1955         StringRef SegName = MachOOF->getSectionFinalSegmentName(Ref);
1956         DisassembleMachO(FileName, MachOOF, SegName, SectName);
1957       }
1958     }
1959   }
1960   else if (Disassemble) {
1961     if (MachOOF->getHeader().filetype == MachO::MH_KEXT_BUNDLE &&
1962         MachOOF->getHeader().cputype == MachO::CPU_TYPE_ARM64)
1963       DisassembleMachO(FileName, MachOOF, "__TEXT_EXEC", "__text");
1964     else
1965       DisassembleMachO(FileName, MachOOF, "__TEXT", "__text");
1966   }
1967   if (IndirectSymbols)
1968     PrintIndirectSymbols(MachOOF, !NonVerbose);
1969   if (DataInCode)
1970     PrintDataInCodeTable(MachOOF, !NonVerbose);
1971   if (LinkOptHints)
1972     PrintLinkOptHints(MachOOF);
1973   if (Relocations)
1974     PrintRelocations(MachOOF, !NonVerbose);
1975   if (SectionHeaders)
1976     printSectionHeaders(MachOOF);
1977   if (SectionContents)
1978     printSectionContents(MachOOF);
1979   if (!FilterSections.empty())
1980     DumpSectionContents(FileName, MachOOF, !NonVerbose);
1981   if (InfoPlist)
1982     DumpInfoPlistSectionContents(FileName, MachOOF);
1983   if (DylibsUsed)
1984     PrintDylibs(MachOOF, false);
1985   if (DylibId)
1986     PrintDylibs(MachOOF, true);
1987   if (SymbolTable)
1988     printSymbolTable(MachOOF, ArchiveName, ArchitectureName);
1989   if (UnwindInfo)
1990     printMachOUnwindInfo(MachOOF);
1991   if (PrivateHeaders) {
1992     printMachOFileHeader(MachOOF);
1993     printMachOLoadCommands(MachOOF);
1994   }
1995   if (FirstPrivateHeader)
1996     printMachOFileHeader(MachOOF);
1997   if (ObjcMetaData)
1998     printObjcMetaData(MachOOF, !NonVerbose);
1999   if (ExportsTrie)
2000     printExportsTrie(MachOOF);
2001   if (Rebase)
2002     printRebaseTable(MachOOF);
2003   if (Bind)
2004     printBindTable(MachOOF);
2005   if (LazyBind)
2006     printLazyBindTable(MachOOF);
2007   if (WeakBind)
2008     printWeakBindTable(MachOOF);
2009 
2010   if (DwarfDumpType != DIDT_Null) {
2011     std::unique_ptr<DIContext> DICtx = DWARFContext::create(*MachOOF);
2012     // Dump the complete DWARF structure.
2013     DIDumpOptions DumpOpts;
2014     DumpOpts.DumpType = DwarfDumpType;
2015     DICtx->dump(outs(), DumpOpts);
2016   }
2017 }
2018 
2019 // printUnknownCPUType() helps print_fat_headers for unknown CPU's.
2020 static void printUnknownCPUType(uint32_t cputype, uint32_t cpusubtype) {
2021   outs() << "    cputype (" << cputype << ")\n";
2022   outs() << "    cpusubtype (" << cpusubtype << ")\n";
2023 }
2024 
2025 // printCPUType() helps print_fat_headers by printing the cputype and
2026 // pusubtype (symbolically for the one's it knows about).
2027 static void printCPUType(uint32_t cputype, uint32_t cpusubtype) {
2028   switch (cputype) {
2029   case MachO::CPU_TYPE_I386:
2030     switch (cpusubtype) {
2031     case MachO::CPU_SUBTYPE_I386_ALL:
2032       outs() << "    cputype CPU_TYPE_I386\n";
2033       outs() << "    cpusubtype CPU_SUBTYPE_I386_ALL\n";
2034       break;
2035     default:
2036       printUnknownCPUType(cputype, cpusubtype);
2037       break;
2038     }
2039     break;
2040   case MachO::CPU_TYPE_X86_64:
2041     switch (cpusubtype) {
2042     case MachO::CPU_SUBTYPE_X86_64_ALL:
2043       outs() << "    cputype CPU_TYPE_X86_64\n";
2044       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_ALL\n";
2045       break;
2046     case MachO::CPU_SUBTYPE_X86_64_H:
2047       outs() << "    cputype CPU_TYPE_X86_64\n";
2048       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_H\n";
2049       break;
2050     default:
2051       printUnknownCPUType(cputype, cpusubtype);
2052       break;
2053     }
2054     break;
2055   case MachO::CPU_TYPE_ARM:
2056     switch (cpusubtype) {
2057     case MachO::CPU_SUBTYPE_ARM_ALL:
2058       outs() << "    cputype CPU_TYPE_ARM\n";
2059       outs() << "    cpusubtype CPU_SUBTYPE_ARM_ALL\n";
2060       break;
2061     case MachO::CPU_SUBTYPE_ARM_V4T:
2062       outs() << "    cputype CPU_TYPE_ARM\n";
2063       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V4T\n";
2064       break;
2065     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
2066       outs() << "    cputype CPU_TYPE_ARM\n";
2067       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n";
2068       break;
2069     case MachO::CPU_SUBTYPE_ARM_XSCALE:
2070       outs() << "    cputype CPU_TYPE_ARM\n";
2071       outs() << "    cpusubtype CPU_SUBTYPE_ARM_XSCALE\n";
2072       break;
2073     case MachO::CPU_SUBTYPE_ARM_V6:
2074       outs() << "    cputype CPU_TYPE_ARM\n";
2075       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6\n";
2076       break;
2077     case MachO::CPU_SUBTYPE_ARM_V6M:
2078       outs() << "    cputype CPU_TYPE_ARM\n";
2079       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6M\n";
2080       break;
2081     case MachO::CPU_SUBTYPE_ARM_V7:
2082       outs() << "    cputype CPU_TYPE_ARM\n";
2083       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7\n";
2084       break;
2085     case MachO::CPU_SUBTYPE_ARM_V7EM:
2086       outs() << "    cputype CPU_TYPE_ARM\n";
2087       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7EM\n";
2088       break;
2089     case MachO::CPU_SUBTYPE_ARM_V7K:
2090       outs() << "    cputype CPU_TYPE_ARM\n";
2091       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7K\n";
2092       break;
2093     case MachO::CPU_SUBTYPE_ARM_V7M:
2094       outs() << "    cputype CPU_TYPE_ARM\n";
2095       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7M\n";
2096       break;
2097     case MachO::CPU_SUBTYPE_ARM_V7S:
2098       outs() << "    cputype CPU_TYPE_ARM\n";
2099       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7S\n";
2100       break;
2101     default:
2102       printUnknownCPUType(cputype, cpusubtype);
2103       break;
2104     }
2105     break;
2106   case MachO::CPU_TYPE_ARM64:
2107     switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
2108     case MachO::CPU_SUBTYPE_ARM64_ALL:
2109       outs() << "    cputype CPU_TYPE_ARM64\n";
2110       outs() << "    cpusubtype CPU_SUBTYPE_ARM64_ALL\n";
2111       break;
2112     case MachO::CPU_SUBTYPE_ARM64E:
2113       outs() << "    cputype CPU_TYPE_ARM64\n";
2114       outs() << "    cpusubtype CPU_SUBTYPE_ARM64E\n";
2115       break;
2116     default:
2117       printUnknownCPUType(cputype, cpusubtype);
2118       break;
2119     }
2120     break;
2121   case MachO::CPU_TYPE_ARM64_32:
2122     switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
2123     case MachO::CPU_SUBTYPE_ARM64_32_V8:
2124       outs() << "    cputype CPU_TYPE_ARM64_32\n";
2125       outs() << "    cpusubtype CPU_SUBTYPE_ARM64_32_V8\n";
2126       break;
2127     default:
2128       printUnknownCPUType(cputype, cpusubtype);
2129       break;
2130     }
2131     break;
2132   default:
2133     printUnknownCPUType(cputype, cpusubtype);
2134     break;
2135   }
2136 }
2137 
2138 static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB,
2139                                        bool verbose) {
2140   outs() << "Fat headers\n";
2141   if (verbose) {
2142     if (UB->getMagic() == MachO::FAT_MAGIC)
2143       outs() << "fat_magic FAT_MAGIC\n";
2144     else // UB->getMagic() == MachO::FAT_MAGIC_64
2145       outs() << "fat_magic FAT_MAGIC_64\n";
2146   } else
2147     outs() << "fat_magic " << format("0x%" PRIx32, MachO::FAT_MAGIC) << "\n";
2148 
2149   uint32_t nfat_arch = UB->getNumberOfObjects();
2150   StringRef Buf = UB->getData();
2151   uint64_t size = Buf.size();
2152   uint64_t big_size = sizeof(struct MachO::fat_header) +
2153                       nfat_arch * sizeof(struct MachO::fat_arch);
2154   outs() << "nfat_arch " << UB->getNumberOfObjects();
2155   if (nfat_arch == 0)
2156     outs() << " (malformed, contains zero architecture types)\n";
2157   else if (big_size > size)
2158     outs() << " (malformed, architectures past end of file)\n";
2159   else
2160     outs() << "\n";
2161 
2162   for (uint32_t i = 0; i < nfat_arch; ++i) {
2163     MachOUniversalBinary::ObjectForArch OFA(UB, i);
2164     uint32_t cputype = OFA.getCPUType();
2165     uint32_t cpusubtype = OFA.getCPUSubType();
2166     outs() << "architecture ";
2167     for (uint32_t j = 0; i != 0 && j <= i - 1; j++) {
2168       MachOUniversalBinary::ObjectForArch other_OFA(UB, j);
2169       uint32_t other_cputype = other_OFA.getCPUType();
2170       uint32_t other_cpusubtype = other_OFA.getCPUSubType();
2171       if (cputype != 0 && cpusubtype != 0 && cputype == other_cputype &&
2172           (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) ==
2173               (other_cpusubtype & ~MachO::CPU_SUBTYPE_MASK)) {
2174         outs() << "(illegal duplicate architecture) ";
2175         break;
2176       }
2177     }
2178     if (verbose) {
2179       outs() << OFA.getArchFlagName() << "\n";
2180       printCPUType(cputype, cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
2181     } else {
2182       outs() << i << "\n";
2183       outs() << "    cputype " << cputype << "\n";
2184       outs() << "    cpusubtype " << (cpusubtype & ~MachO::CPU_SUBTYPE_MASK)
2185              << "\n";
2186     }
2187     if (verbose &&
2188         (cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64)
2189       outs() << "    capabilities CPU_SUBTYPE_LIB64\n";
2190     else
2191       outs() << "    capabilities "
2192              << format("0x%" PRIx32,
2193                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24) << "\n";
2194     outs() << "    offset " << OFA.getOffset();
2195     if (OFA.getOffset() > size)
2196       outs() << " (past end of file)";
2197     if (OFA.getOffset() % (1ull << OFA.getAlign()) != 0)
2198       outs() << " (not aligned on it's alignment (2^" << OFA.getAlign() << ")";
2199     outs() << "\n";
2200     outs() << "    size " << OFA.getSize();
2201     big_size = OFA.getOffset() + OFA.getSize();
2202     if (big_size > size)
2203       outs() << " (past end of file)";
2204     outs() << "\n";
2205     outs() << "    align 2^" << OFA.getAlign() << " (" << (1 << OFA.getAlign())
2206            << ")\n";
2207   }
2208 }
2209 
2210 static void printArchiveChild(StringRef Filename, const Archive::Child &C,
2211                               size_t ChildIndex, bool verbose,
2212                               bool print_offset,
2213                               StringRef ArchitectureName = StringRef()) {
2214   if (print_offset)
2215     outs() << C.getChildOffset() << "\t";
2216   sys::fs::perms Mode =
2217       unwrapOrError(C.getAccessMode(), getFileNameForError(C, ChildIndex),
2218                     Filename, ArchitectureName);
2219   if (verbose) {
2220     // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
2221     // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
2222     outs() << "-";
2223     outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
2224     outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
2225     outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
2226     outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
2227     outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
2228     outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
2229     outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
2230     outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
2231     outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
2232   } else {
2233     outs() << format("0%o ", Mode);
2234   }
2235 
2236   outs() << format("%3d/%-3d %5" PRId64 " ",
2237                    unwrapOrError(C.getUID(), getFileNameForError(C, ChildIndex),
2238                                  Filename, ArchitectureName),
2239                    unwrapOrError(C.getGID(), getFileNameForError(C, ChildIndex),
2240                                  Filename, ArchitectureName),
2241                    unwrapOrError(C.getRawSize(),
2242                                  getFileNameForError(C, ChildIndex), Filename,
2243                                  ArchitectureName));
2244 
2245   StringRef RawLastModified = C.getRawLastModified();
2246   if (verbose) {
2247     unsigned Seconds;
2248     if (RawLastModified.getAsInteger(10, Seconds))
2249       outs() << "(date: \"" << RawLastModified
2250              << "\" contains non-decimal chars) ";
2251     else {
2252       // Since cime(3) returns a 26 character string of the form:
2253       // "Sun Sep 16 01:03:52 1973\n\0"
2254       // just print 24 characters.
2255       time_t t = Seconds;
2256       outs() << format("%.24s ", ctime(&t));
2257     }
2258   } else {
2259     outs() << RawLastModified << " ";
2260   }
2261 
2262   if (verbose) {
2263     Expected<StringRef> NameOrErr = C.getName();
2264     if (!NameOrErr) {
2265       consumeError(NameOrErr.takeError());
2266       outs() << unwrapOrError(C.getRawName(),
2267                               getFileNameForError(C, ChildIndex), Filename,
2268                               ArchitectureName)
2269              << "\n";
2270     } else {
2271       StringRef Name = NameOrErr.get();
2272       outs() << Name << "\n";
2273     }
2274   } else {
2275     outs() << unwrapOrError(C.getRawName(), getFileNameForError(C, ChildIndex),
2276                             Filename, ArchitectureName)
2277            << "\n";
2278   }
2279 }
2280 
2281 static void printArchiveHeaders(StringRef Filename, Archive *A, bool verbose,
2282                                 bool print_offset,
2283                                 StringRef ArchitectureName = StringRef()) {
2284   Error Err = Error::success();
2285   size_t I = 0;
2286   for (const auto &C : A->children(Err, false))
2287     printArchiveChild(Filename, C, I++, verbose, print_offset,
2288                       ArchitectureName);
2289 
2290   if (Err)
2291     reportError(std::move(Err), Filename, "", ArchitectureName);
2292 }
2293 
2294 static bool ValidateArchFlags() {
2295   // Check for -arch all and verifiy the -arch flags are valid.
2296   for (unsigned i = 0; i < ArchFlags.size(); ++i) {
2297     if (ArchFlags[i] == "all") {
2298       ArchAll = true;
2299     } else {
2300       if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
2301         WithColor::error(errs(), "llvm-objdump")
2302             << "unknown architecture named '" + ArchFlags[i] +
2303                    "'for the -arch option\n";
2304         return false;
2305       }
2306     }
2307   }
2308   return true;
2309 }
2310 
2311 // ParseInputMachO() parses the named Mach-O file in Filename and handles the
2312 // -arch flags selecting just those slices as specified by them and also parses
2313 // archive files.  Then for each individual Mach-O file ProcessMachO() is
2314 // called to process the file based on the command line options.
2315 void objdump::parseInputMachO(StringRef Filename) {
2316   if (!ValidateArchFlags())
2317     return;
2318 
2319   // Attempt to open the binary.
2320   Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
2321   if (!BinaryOrErr) {
2322     if (Error E = isNotObjectErrorInvalidFileType(BinaryOrErr.takeError()))
2323       reportError(std::move(E), Filename);
2324     else
2325       outs() << Filename << ": is not an object file\n";
2326     return;
2327   }
2328   Binary &Bin = *BinaryOrErr.get().getBinary();
2329 
2330   if (Archive *A = dyn_cast<Archive>(&Bin)) {
2331     outs() << "Archive : " << Filename << "\n";
2332     if (ArchiveHeaders)
2333       printArchiveHeaders(Filename, A, !NonVerbose, ArchiveMemberOffsets);
2334 
2335     Error Err = Error::success();
2336     unsigned I = -1;
2337     for (auto &C : A->children(Err)) {
2338       ++I;
2339       Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2340       if (!ChildOrErr) {
2341         if (Error E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2342           reportError(std::move(E), getFileNameForError(C, I), Filename);
2343         continue;
2344       }
2345       if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
2346         if (!checkMachOAndArchFlags(O, Filename))
2347           return;
2348         ProcessMachO(Filename, O, O->getFileName());
2349       }
2350     }
2351     if (Err)
2352       reportError(std::move(Err), Filename);
2353     return;
2354   }
2355   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
2356     parseInputMachO(UB);
2357     return;
2358   }
2359   if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
2360     if (!checkMachOAndArchFlags(O, Filename))
2361       return;
2362     if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O))
2363       ProcessMachO(Filename, MachOOF);
2364     else
2365       WithColor::error(errs(), "llvm-objdump")
2366           << Filename << "': "
2367           << "object is not a Mach-O file type.\n";
2368     return;
2369   }
2370   llvm_unreachable("Input object can't be invalid at this point");
2371 }
2372 
2373 void objdump::parseInputMachO(MachOUniversalBinary *UB) {
2374   if (!ValidateArchFlags())
2375     return;
2376 
2377   auto Filename = UB->getFileName();
2378 
2379   if (UniversalHeaders)
2380     printMachOUniversalHeaders(UB, !NonVerbose);
2381 
2382   // If we have a list of architecture flags specified dump only those.
2383   if (!ArchAll && !ArchFlags.empty()) {
2384     // Look for a slice in the universal binary that matches each ArchFlag.
2385     bool ArchFound;
2386     for (unsigned i = 0; i < ArchFlags.size(); ++i) {
2387       ArchFound = false;
2388       for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
2389                                                   E = UB->end_objects();
2390             I != E; ++I) {
2391         if (ArchFlags[i] == I->getArchFlagName()) {
2392           ArchFound = true;
2393           Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
2394               I->getAsObjectFile();
2395           std::string ArchitectureName = "";
2396           if (ArchFlags.size() > 1)
2397             ArchitectureName = I->getArchFlagName();
2398           if (ObjOrErr) {
2399             ObjectFile &O = *ObjOrErr.get();
2400             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
2401               ProcessMachO(Filename, MachOOF, "", ArchitectureName);
2402           } else if (Error E = isNotObjectErrorInvalidFileType(
2403                          ObjOrErr.takeError())) {
2404             reportError(std::move(E), "", Filename, ArchitectureName);
2405             continue;
2406           } else if (Expected<std::unique_ptr<Archive>> AOrErr =
2407                          I->getAsArchive()) {
2408             std::unique_ptr<Archive> &A = *AOrErr;
2409             outs() << "Archive : " << Filename;
2410             if (!ArchitectureName.empty())
2411               outs() << " (architecture " << ArchitectureName << ")";
2412             outs() << "\n";
2413             if (ArchiveHeaders)
2414               printArchiveHeaders(Filename, A.get(), !NonVerbose,
2415                                   ArchiveMemberOffsets, ArchitectureName);
2416             Error Err = Error::success();
2417             unsigned I = -1;
2418             for (auto &C : A->children(Err)) {
2419               ++I;
2420               Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2421               if (!ChildOrErr) {
2422                 if (Error E =
2423                         isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2424                   reportError(std::move(E), getFileNameForError(C, I), Filename,
2425                               ArchitectureName);
2426                 continue;
2427               }
2428               if (MachOObjectFile *O =
2429                       dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
2430                 ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
2431             }
2432             if (Err)
2433               reportError(std::move(Err), Filename);
2434           } else {
2435             consumeError(AOrErr.takeError());
2436             reportError(Filename,
2437                         "Mach-O universal file for architecture " +
2438                             StringRef(I->getArchFlagName()) +
2439                             " is not a Mach-O file or an archive file");
2440           }
2441         }
2442       }
2443       if (!ArchFound) {
2444         WithColor::error(errs(), "llvm-objdump")
2445             << "file: " + Filename + " does not contain "
2446             << "architecture: " + ArchFlags[i] + "\n";
2447         return;
2448       }
2449     }
2450     return;
2451   }
2452   // No architecture flags were specified so if this contains a slice that
2453   // matches the host architecture dump only that.
2454   if (!ArchAll) {
2455     for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
2456                                                 E = UB->end_objects();
2457           I != E; ++I) {
2458       if (MachOObjectFile::getHostArch().getArchName() ==
2459           I->getArchFlagName()) {
2460         Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
2461         std::string ArchiveName;
2462         ArchiveName.clear();
2463         if (ObjOrErr) {
2464           ObjectFile &O = *ObjOrErr.get();
2465           if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
2466             ProcessMachO(Filename, MachOOF);
2467         } else if (Error E =
2468                        isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
2469           reportError(std::move(E), Filename);
2470         } else if (Expected<std::unique_ptr<Archive>> AOrErr =
2471                        I->getAsArchive()) {
2472           std::unique_ptr<Archive> &A = *AOrErr;
2473           outs() << "Archive : " << Filename << "\n";
2474           if (ArchiveHeaders)
2475             printArchiveHeaders(Filename, A.get(), !NonVerbose,
2476                                 ArchiveMemberOffsets);
2477           Error Err = Error::success();
2478           unsigned I = -1;
2479           for (auto &C : A->children(Err)) {
2480             ++I;
2481             Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2482             if (!ChildOrErr) {
2483               if (Error E =
2484                       isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2485                 reportError(std::move(E), getFileNameForError(C, I), Filename);
2486               continue;
2487             }
2488             if (MachOObjectFile *O =
2489                     dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
2490               ProcessMachO(Filename, O, O->getFileName());
2491           }
2492           if (Err)
2493             reportError(std::move(Err), Filename);
2494         } else {
2495           consumeError(AOrErr.takeError());
2496           reportError(Filename, "Mach-O universal file for architecture " +
2497                                     StringRef(I->getArchFlagName()) +
2498                                     " is not a Mach-O file or an archive file");
2499         }
2500         return;
2501       }
2502     }
2503   }
2504   // Either all architectures have been specified or none have been specified
2505   // and this does not contain the host architecture so dump all the slices.
2506   bool moreThanOneArch = UB->getNumberOfObjects() > 1;
2507   for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
2508                                               E = UB->end_objects();
2509         I != E; ++I) {
2510     Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
2511     std::string ArchitectureName = "";
2512     if (moreThanOneArch)
2513       ArchitectureName = I->getArchFlagName();
2514     if (ObjOrErr) {
2515       ObjectFile &Obj = *ObjOrErr.get();
2516       if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
2517         ProcessMachO(Filename, MachOOF, "", ArchitectureName);
2518     } else if (Error E =
2519                    isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
2520       reportError(std::move(E), Filename, "", ArchitectureName);
2521     } else if (Expected<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
2522       std::unique_ptr<Archive> &A = *AOrErr;
2523       outs() << "Archive : " << Filename;
2524       if (!ArchitectureName.empty())
2525         outs() << " (architecture " << ArchitectureName << ")";
2526       outs() << "\n";
2527       if (ArchiveHeaders)
2528         printArchiveHeaders(Filename, A.get(), !NonVerbose,
2529                             ArchiveMemberOffsets, ArchitectureName);
2530       Error Err = Error::success();
2531       unsigned I = -1;
2532       for (auto &C : A->children(Err)) {
2533         ++I;
2534         Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2535         if (!ChildOrErr) {
2536           if (Error E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2537             reportError(std::move(E), getFileNameForError(C, I), Filename,
2538                         ArchitectureName);
2539           continue;
2540         }
2541         if (MachOObjectFile *O =
2542                 dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
2543           if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
2544             ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
2545                           ArchitectureName);
2546         }
2547       }
2548       if (Err)
2549         reportError(std::move(Err), Filename);
2550     } else {
2551       consumeError(AOrErr.takeError());
2552       reportError(Filename, "Mach-O universal file for architecture " +
2553                                 StringRef(I->getArchFlagName()) +
2554                                 " is not a Mach-O file or an archive file");
2555     }
2556   }
2557 }
2558 
2559 namespace {
2560 // The block of info used by the Symbolizer call backs.
2561 struct DisassembleInfo {
2562   DisassembleInfo(MachOObjectFile *O, SymbolAddressMap *AddrMap,
2563                   std::vector<SectionRef> *Sections, bool verbose)
2564     : verbose(verbose), O(O), AddrMap(AddrMap), Sections(Sections) {}
2565   bool verbose;
2566   MachOObjectFile *O;
2567   SectionRef S;
2568   SymbolAddressMap *AddrMap;
2569   std::vector<SectionRef> *Sections;
2570   const char *class_name = nullptr;
2571   const char *selector_name = nullptr;
2572   std::unique_ptr<char[]> method = nullptr;
2573   char *demangled_name = nullptr;
2574   uint64_t adrp_addr = 0;
2575   uint32_t adrp_inst = 0;
2576   std::unique_ptr<SymbolAddressMap> bindtable;
2577   uint32_t depth = 0;
2578 };
2579 } // namespace
2580 
2581 // SymbolizerGetOpInfo() is the operand information call back function.
2582 // This is called to get the symbolic information for operand(s) of an
2583 // instruction when it is being done.  This routine does this from
2584 // the relocation information, symbol table, etc. That block of information
2585 // is a pointer to the struct DisassembleInfo that was passed when the
2586 // disassembler context was created and passed to back to here when
2587 // called back by the disassembler for instruction operands that could have
2588 // relocation information. The address of the instruction containing operand is
2589 // at the Pc parameter.  The immediate value the operand has is passed in
2590 // op_info->Value and is at Offset past the start of the instruction and has a
2591 // byte Size of 1, 2 or 4. The symbolc information is returned in TagBuf is the
2592 // LLVMOpInfo1 struct defined in the header "llvm-c/Disassembler.h" as symbol
2593 // names and addends of the symbolic expression to add for the operand.  The
2594 // value of TagType is currently 1 (for the LLVMOpInfo1 struct). If symbolic
2595 // information is returned then this function returns 1 else it returns 0.
2596 static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
2597                                uint64_t Size, int TagType, void *TagBuf) {
2598   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
2599   struct LLVMOpInfo1 *op_info = (struct LLVMOpInfo1 *)TagBuf;
2600   uint64_t value = op_info->Value;
2601 
2602   // Make sure all fields returned are zero if we don't set them.
2603   memset((void *)op_info, '\0', sizeof(struct LLVMOpInfo1));
2604   op_info->Value = value;
2605 
2606   // If the TagType is not the value 1 which it code knows about or if no
2607   // verbose symbolic information is wanted then just return 0, indicating no
2608   // information is being returned.
2609   if (TagType != 1 || !info->verbose)
2610     return 0;
2611 
2612   unsigned int Arch = info->O->getArch();
2613   if (Arch == Triple::x86) {
2614     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
2615       return 0;
2616     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2617       // TODO:
2618       // Search the external relocation entries of a fully linked image
2619       // (if any) for an entry that matches this segment offset.
2620       // uint32_t seg_offset = (Pc + Offset);
2621       return 0;
2622     }
2623     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2624     // for an entry for this section offset.
2625     uint32_t sect_addr = info->S.getAddress();
2626     uint32_t sect_offset = (Pc + Offset) - sect_addr;
2627     bool reloc_found = false;
2628     DataRefImpl Rel;
2629     MachO::any_relocation_info RE;
2630     bool isExtern = false;
2631     SymbolRef Symbol;
2632     bool r_scattered = false;
2633     uint32_t r_value, pair_r_value, r_type;
2634     for (const RelocationRef &Reloc : info->S.relocations()) {
2635       uint64_t RelocOffset = Reloc.getOffset();
2636       if (RelocOffset == sect_offset) {
2637         Rel = Reloc.getRawDataRefImpl();
2638         RE = info->O->getRelocation(Rel);
2639         r_type = info->O->getAnyRelocationType(RE);
2640         r_scattered = info->O->isRelocationScattered(RE);
2641         if (r_scattered) {
2642           r_value = info->O->getScatteredRelocationValue(RE);
2643           if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
2644               r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
2645             DataRefImpl RelNext = Rel;
2646             info->O->moveRelocationNext(RelNext);
2647             MachO::any_relocation_info RENext;
2648             RENext = info->O->getRelocation(RelNext);
2649             if (info->O->isRelocationScattered(RENext))
2650               pair_r_value = info->O->getScatteredRelocationValue(RENext);
2651             else
2652               return 0;
2653           }
2654         } else {
2655           isExtern = info->O->getPlainRelocationExternal(RE);
2656           if (isExtern) {
2657             symbol_iterator RelocSym = Reloc.getSymbol();
2658             Symbol = *RelocSym;
2659           }
2660         }
2661         reloc_found = true;
2662         break;
2663       }
2664     }
2665     if (reloc_found && isExtern) {
2666       op_info->AddSymbol.Present = 1;
2667       op_info->AddSymbol.Name =
2668           unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2669       // For i386 extern relocation entries the value in the instruction is
2670       // the offset from the symbol, and value is already set in op_info->Value.
2671       return 1;
2672     }
2673     if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
2674                         r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
2675       const char *add = GuessSymbolName(r_value, info->AddrMap);
2676       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
2677       uint32_t offset = value - (r_value - pair_r_value);
2678       op_info->AddSymbol.Present = 1;
2679       if (add != nullptr)
2680         op_info->AddSymbol.Name = add;
2681       else
2682         op_info->AddSymbol.Value = r_value;
2683       op_info->SubtractSymbol.Present = 1;
2684       if (sub != nullptr)
2685         op_info->SubtractSymbol.Name = sub;
2686       else
2687         op_info->SubtractSymbol.Value = pair_r_value;
2688       op_info->Value = offset;
2689       return 1;
2690     }
2691     return 0;
2692   }
2693   if (Arch == Triple::x86_64) {
2694     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
2695       return 0;
2696     // For non MH_OBJECT types, like MH_KEXT_BUNDLE, Search the external
2697     // relocation entries of a linked image (if any) for an entry that matches
2698     // this segment offset.
2699     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2700       uint64_t seg_offset = Pc + Offset;
2701       bool reloc_found = false;
2702       DataRefImpl Rel;
2703       MachO::any_relocation_info RE;
2704       bool isExtern = false;
2705       SymbolRef Symbol;
2706       for (const RelocationRef &Reloc : info->O->external_relocations()) {
2707         uint64_t RelocOffset = Reloc.getOffset();
2708         if (RelocOffset == seg_offset) {
2709           Rel = Reloc.getRawDataRefImpl();
2710           RE = info->O->getRelocation(Rel);
2711           // external relocation entries should always be external.
2712           isExtern = info->O->getPlainRelocationExternal(RE);
2713           if (isExtern) {
2714             symbol_iterator RelocSym = Reloc.getSymbol();
2715             Symbol = *RelocSym;
2716           }
2717           reloc_found = true;
2718           break;
2719         }
2720       }
2721       if (reloc_found && isExtern) {
2722         // The Value passed in will be adjusted by the Pc if the instruction
2723         // adds the Pc.  But for x86_64 external relocation entries the Value
2724         // is the offset from the external symbol.
2725         if (info->O->getAnyRelocationPCRel(RE))
2726           op_info->Value -= Pc + Offset + Size;
2727         const char *name =
2728             unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2729         op_info->AddSymbol.Present = 1;
2730         op_info->AddSymbol.Name = name;
2731         return 1;
2732       }
2733       return 0;
2734     }
2735     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2736     // for an entry for this section offset.
2737     uint64_t sect_addr = info->S.getAddress();
2738     uint64_t sect_offset = (Pc + Offset) - sect_addr;
2739     bool reloc_found = false;
2740     DataRefImpl Rel;
2741     MachO::any_relocation_info RE;
2742     bool isExtern = false;
2743     SymbolRef Symbol;
2744     for (const RelocationRef &Reloc : info->S.relocations()) {
2745       uint64_t RelocOffset = Reloc.getOffset();
2746       if (RelocOffset == sect_offset) {
2747         Rel = Reloc.getRawDataRefImpl();
2748         RE = info->O->getRelocation(Rel);
2749         // NOTE: Scattered relocations don't exist on x86_64.
2750         isExtern = info->O->getPlainRelocationExternal(RE);
2751         if (isExtern) {
2752           symbol_iterator RelocSym = Reloc.getSymbol();
2753           Symbol = *RelocSym;
2754         }
2755         reloc_found = true;
2756         break;
2757       }
2758     }
2759     if (reloc_found && isExtern) {
2760       // The Value passed in will be adjusted by the Pc if the instruction
2761       // adds the Pc.  But for x86_64 external relocation entries the Value
2762       // is the offset from the external symbol.
2763       if (info->O->getAnyRelocationPCRel(RE))
2764         op_info->Value -= Pc + Offset + Size;
2765       const char *name =
2766           unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2767       unsigned Type = info->O->getAnyRelocationType(RE);
2768       if (Type == MachO::X86_64_RELOC_SUBTRACTOR) {
2769         DataRefImpl RelNext = Rel;
2770         info->O->moveRelocationNext(RelNext);
2771         MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
2772         unsigned TypeNext = info->O->getAnyRelocationType(RENext);
2773         bool isExternNext = info->O->getPlainRelocationExternal(RENext);
2774         unsigned SymbolNum = info->O->getPlainRelocationSymbolNum(RENext);
2775         if (TypeNext == MachO::X86_64_RELOC_UNSIGNED && isExternNext) {
2776           op_info->SubtractSymbol.Present = 1;
2777           op_info->SubtractSymbol.Name = name;
2778           symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum);
2779           Symbol = *RelocSymNext;
2780           name = unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2781         }
2782       }
2783       // TODO: add the VariantKinds to op_info->VariantKind for relocation types
2784       // like: X86_64_RELOC_TLV, X86_64_RELOC_GOT_LOAD and X86_64_RELOC_GOT.
2785       op_info->AddSymbol.Present = 1;
2786       op_info->AddSymbol.Name = name;
2787       return 1;
2788     }
2789     return 0;
2790   }
2791   if (Arch == Triple::arm) {
2792     if (Offset != 0 || (Size != 4 && Size != 2))
2793       return 0;
2794     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2795       // TODO:
2796       // Search the external relocation entries of a fully linked image
2797       // (if any) for an entry that matches this segment offset.
2798       // uint32_t seg_offset = (Pc + Offset);
2799       return 0;
2800     }
2801     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2802     // for an entry for this section offset.
2803     uint32_t sect_addr = info->S.getAddress();
2804     uint32_t sect_offset = (Pc + Offset) - sect_addr;
2805     DataRefImpl Rel;
2806     MachO::any_relocation_info RE;
2807     bool isExtern = false;
2808     SymbolRef Symbol;
2809     bool r_scattered = false;
2810     uint32_t r_value, pair_r_value, r_type, r_length, other_half;
2811     auto Reloc =
2812         find_if(info->S.relocations(), [&](const RelocationRef &Reloc) {
2813           uint64_t RelocOffset = Reloc.getOffset();
2814           return RelocOffset == sect_offset;
2815         });
2816 
2817     if (Reloc == info->S.relocations().end())
2818       return 0;
2819 
2820     Rel = Reloc->getRawDataRefImpl();
2821     RE = info->O->getRelocation(Rel);
2822     r_length = info->O->getAnyRelocationLength(RE);
2823     r_scattered = info->O->isRelocationScattered(RE);
2824     if (r_scattered) {
2825       r_value = info->O->getScatteredRelocationValue(RE);
2826       r_type = info->O->getScatteredRelocationType(RE);
2827     } else {
2828       r_type = info->O->getAnyRelocationType(RE);
2829       isExtern = info->O->getPlainRelocationExternal(RE);
2830       if (isExtern) {
2831         symbol_iterator RelocSym = Reloc->getSymbol();
2832         Symbol = *RelocSym;
2833       }
2834     }
2835     if (r_type == MachO::ARM_RELOC_HALF ||
2836         r_type == MachO::ARM_RELOC_SECTDIFF ||
2837         r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
2838         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2839       DataRefImpl RelNext = Rel;
2840       info->O->moveRelocationNext(RelNext);
2841       MachO::any_relocation_info RENext;
2842       RENext = info->O->getRelocation(RelNext);
2843       other_half = info->O->getAnyRelocationAddress(RENext) & 0xffff;
2844       if (info->O->isRelocationScattered(RENext))
2845         pair_r_value = info->O->getScatteredRelocationValue(RENext);
2846     }
2847 
2848     if (isExtern) {
2849       const char *name =
2850           unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2851       op_info->AddSymbol.Present = 1;
2852       op_info->AddSymbol.Name = name;
2853       switch (r_type) {
2854       case MachO::ARM_RELOC_HALF:
2855         if ((r_length & 0x1) == 1) {
2856           op_info->Value = value << 16 | other_half;
2857           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2858         } else {
2859           op_info->Value = other_half << 16 | value;
2860           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2861         }
2862         break;
2863       default:
2864         break;
2865       }
2866       return 1;
2867     }
2868     // If we have a branch that is not an external relocation entry then
2869     // return 0 so the code in tryAddingSymbolicOperand() can use the
2870     // SymbolLookUp call back with the branch target address to look up the
2871     // symbol and possibility add an annotation for a symbol stub.
2872     if (isExtern == 0 && (r_type == MachO::ARM_RELOC_BR24 ||
2873                           r_type == MachO::ARM_THUMB_RELOC_BR22))
2874       return 0;
2875 
2876     uint32_t offset = 0;
2877     if (r_type == MachO::ARM_RELOC_HALF ||
2878         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2879       if ((r_length & 0x1) == 1)
2880         value = value << 16 | other_half;
2881       else
2882         value = other_half << 16 | value;
2883     }
2884     if (r_scattered && (r_type != MachO::ARM_RELOC_HALF &&
2885                         r_type != MachO::ARM_RELOC_HALF_SECTDIFF)) {
2886       offset = value - r_value;
2887       value = r_value;
2888     }
2889 
2890     if (r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2891       if ((r_length & 0x1) == 1)
2892         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2893       else
2894         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2895       const char *add = GuessSymbolName(r_value, info->AddrMap);
2896       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
2897       int32_t offset = value - (r_value - pair_r_value);
2898       op_info->AddSymbol.Present = 1;
2899       if (add != nullptr)
2900         op_info->AddSymbol.Name = add;
2901       else
2902         op_info->AddSymbol.Value = r_value;
2903       op_info->SubtractSymbol.Present = 1;
2904       if (sub != nullptr)
2905         op_info->SubtractSymbol.Name = sub;
2906       else
2907         op_info->SubtractSymbol.Value = pair_r_value;
2908       op_info->Value = offset;
2909       return 1;
2910     }
2911 
2912     op_info->AddSymbol.Present = 1;
2913     op_info->Value = offset;
2914     if (r_type == MachO::ARM_RELOC_HALF) {
2915       if ((r_length & 0x1) == 1)
2916         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2917       else
2918         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2919     }
2920     const char *add = GuessSymbolName(value, info->AddrMap);
2921     if (add != nullptr) {
2922       op_info->AddSymbol.Name = add;
2923       return 1;
2924     }
2925     op_info->AddSymbol.Value = value;
2926     return 1;
2927   }
2928   if (Arch == Triple::aarch64) {
2929     if (Offset != 0 || Size != 4)
2930       return 0;
2931     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2932       // TODO:
2933       // Search the external relocation entries of a fully linked image
2934       // (if any) for an entry that matches this segment offset.
2935       // uint64_t seg_offset = (Pc + Offset);
2936       return 0;
2937     }
2938     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2939     // for an entry for this section offset.
2940     uint64_t sect_addr = info->S.getAddress();
2941     uint64_t sect_offset = (Pc + Offset) - sect_addr;
2942     auto Reloc =
2943         find_if(info->S.relocations(), [&](const RelocationRef &Reloc) {
2944           uint64_t RelocOffset = Reloc.getOffset();
2945           return RelocOffset == sect_offset;
2946         });
2947 
2948     if (Reloc == info->S.relocations().end())
2949       return 0;
2950 
2951     DataRefImpl Rel = Reloc->getRawDataRefImpl();
2952     MachO::any_relocation_info RE = info->O->getRelocation(Rel);
2953     uint32_t r_type = info->O->getAnyRelocationType(RE);
2954     if (r_type == MachO::ARM64_RELOC_ADDEND) {
2955       DataRefImpl RelNext = Rel;
2956       info->O->moveRelocationNext(RelNext);
2957       MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
2958       if (value == 0) {
2959         value = info->O->getPlainRelocationSymbolNum(RENext);
2960         op_info->Value = value;
2961       }
2962     }
2963     // NOTE: Scattered relocations don't exist on arm64.
2964     if (!info->O->getPlainRelocationExternal(RE))
2965       return 0;
2966     const char *name =
2967         unwrapOrError(Reloc->getSymbol()->getName(), info->O->getFileName())
2968             .data();
2969     op_info->AddSymbol.Present = 1;
2970     op_info->AddSymbol.Name = name;
2971 
2972     switch (r_type) {
2973     case MachO::ARM64_RELOC_PAGE21:
2974       /* @page */
2975       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGE;
2976       break;
2977     case MachO::ARM64_RELOC_PAGEOFF12:
2978       /* @pageoff */
2979       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGEOFF;
2980       break;
2981     case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
2982       /* @gotpage */
2983       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGE;
2984       break;
2985     case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
2986       /* @gotpageoff */
2987       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF;
2988       break;
2989     case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
2990       /* @tvlppage is not implemented in llvm-mc */
2991       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVP;
2992       break;
2993     case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
2994       /* @tvlppageoff is not implemented in llvm-mc */
2995       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVOFF;
2996       break;
2997     default:
2998     case MachO::ARM64_RELOC_BRANCH26:
2999       op_info->VariantKind = LLVMDisassembler_VariantKind_None;
3000       break;
3001     }
3002     return 1;
3003   }
3004   return 0;
3005 }
3006 
3007 // GuessCstringPointer is passed the address of what might be a pointer to a
3008 // literal string in a cstring section.  If that address is in a cstring section
3009 // it returns a pointer to that string.  Else it returns nullptr.
3010 static const char *GuessCstringPointer(uint64_t ReferenceValue,
3011                                        struct DisassembleInfo *info) {
3012   for (const auto &Load : info->O->load_commands()) {
3013     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
3014       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
3015       for (unsigned J = 0; J < Seg.nsects; ++J) {
3016         MachO::section_64 Sec = info->O->getSection64(Load, J);
3017         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
3018         if (section_type == MachO::S_CSTRING_LITERALS &&
3019             ReferenceValue >= Sec.addr &&
3020             ReferenceValue < Sec.addr + Sec.size) {
3021           uint64_t sect_offset = ReferenceValue - Sec.addr;
3022           uint64_t object_offset = Sec.offset + sect_offset;
3023           StringRef MachOContents = info->O->getData();
3024           uint64_t object_size = MachOContents.size();
3025           const char *object_addr = (const char *)MachOContents.data();
3026           if (object_offset < object_size) {
3027             const char *name = object_addr + object_offset;
3028             return name;
3029           } else {
3030             return nullptr;
3031           }
3032         }
3033       }
3034     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
3035       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
3036       for (unsigned J = 0; J < Seg.nsects; ++J) {
3037         MachO::section Sec = info->O->getSection(Load, J);
3038         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
3039         if (section_type == MachO::S_CSTRING_LITERALS &&
3040             ReferenceValue >= Sec.addr &&
3041             ReferenceValue < Sec.addr + Sec.size) {
3042           uint64_t sect_offset = ReferenceValue - Sec.addr;
3043           uint64_t object_offset = Sec.offset + sect_offset;
3044           StringRef MachOContents = info->O->getData();
3045           uint64_t object_size = MachOContents.size();
3046           const char *object_addr = (const char *)MachOContents.data();
3047           if (object_offset < object_size) {
3048             const char *name = object_addr + object_offset;
3049             return name;
3050           } else {
3051             return nullptr;
3052           }
3053         }
3054       }
3055     }
3056   }
3057   return nullptr;
3058 }
3059 
3060 // GuessIndirectSymbol returns the name of the indirect symbol for the
3061 // ReferenceValue passed in or nullptr.  This is used when ReferenceValue maybe
3062 // an address of a symbol stub or a lazy or non-lazy pointer to associate the
3063 // symbol name being referenced by the stub or pointer.
3064 static const char *GuessIndirectSymbol(uint64_t ReferenceValue,
3065                                        struct DisassembleInfo *info) {
3066   MachO::dysymtab_command Dysymtab = info->O->getDysymtabLoadCommand();
3067   MachO::symtab_command Symtab = info->O->getSymtabLoadCommand();
3068   for (const auto &Load : info->O->load_commands()) {
3069     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
3070       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
3071       for (unsigned J = 0; J < Seg.nsects; ++J) {
3072         MachO::section_64 Sec = info->O->getSection64(Load, J);
3073         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
3074         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
3075              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
3076              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
3077              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
3078              section_type == MachO::S_SYMBOL_STUBS) &&
3079             ReferenceValue >= Sec.addr &&
3080             ReferenceValue < Sec.addr + Sec.size) {
3081           uint32_t stride;
3082           if (section_type == MachO::S_SYMBOL_STUBS)
3083             stride = Sec.reserved2;
3084           else
3085             stride = 8;
3086           if (stride == 0)
3087             return nullptr;
3088           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
3089           if (index < Dysymtab.nindirectsyms) {
3090             uint32_t indirect_symbol =
3091                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
3092             if (indirect_symbol < Symtab.nsyms) {
3093               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
3094               return unwrapOrError(Sym->getName(), info->O->getFileName())
3095                   .data();
3096             }
3097           }
3098         }
3099       }
3100     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
3101       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
3102       for (unsigned J = 0; J < Seg.nsects; ++J) {
3103         MachO::section Sec = info->O->getSection(Load, J);
3104         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
3105         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
3106              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
3107              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
3108              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
3109              section_type == MachO::S_SYMBOL_STUBS) &&
3110             ReferenceValue >= Sec.addr &&
3111             ReferenceValue < Sec.addr + Sec.size) {
3112           uint32_t stride;
3113           if (section_type == MachO::S_SYMBOL_STUBS)
3114             stride = Sec.reserved2;
3115           else
3116             stride = 4;
3117           if (stride == 0)
3118             return nullptr;
3119           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
3120           if (index < Dysymtab.nindirectsyms) {
3121             uint32_t indirect_symbol =
3122                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
3123             if (indirect_symbol < Symtab.nsyms) {
3124               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
3125               return unwrapOrError(Sym->getName(), info->O->getFileName())
3126                   .data();
3127             }
3128           }
3129         }
3130       }
3131     }
3132   }
3133   return nullptr;
3134 }
3135 
3136 // method_reference() is called passing it the ReferenceName that might be
3137 // a reference it to an Objective-C method call.  If so then it allocates and
3138 // assembles a method call string with the values last seen and saved in
3139 // the DisassembleInfo's class_name and selector_name fields.  This is saved
3140 // into the method field of the info and any previous string is free'ed.
3141 // Then the class_name field in the info is set to nullptr.  The method call
3142 // string is set into ReferenceName and ReferenceType is set to
3143 // LLVMDisassembler_ReferenceType_Out_Objc_Message.  If this not a method call
3144 // then both ReferenceType and ReferenceName are left unchanged.
3145 static void method_reference(struct DisassembleInfo *info,
3146                              uint64_t *ReferenceType,
3147                              const char **ReferenceName) {
3148   unsigned int Arch = info->O->getArch();
3149   if (*ReferenceName != nullptr) {
3150     if (strcmp(*ReferenceName, "_objc_msgSend") == 0) {
3151       if (info->selector_name != nullptr) {
3152         if (info->class_name != nullptr) {
3153           info->method = std::make_unique<char[]>(
3154               5 + strlen(info->class_name) + strlen(info->selector_name));
3155           char *method = info->method.get();
3156           if (method != nullptr) {
3157             strcpy(method, "+[");
3158             strcat(method, info->class_name);
3159             strcat(method, " ");
3160             strcat(method, info->selector_name);
3161             strcat(method, "]");
3162             *ReferenceName = method;
3163             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
3164           }
3165         } else {
3166           info->method =
3167               std::make_unique<char[]>(9 + strlen(info->selector_name));
3168           char *method = info->method.get();
3169           if (method != nullptr) {
3170             if (Arch == Triple::x86_64)
3171               strcpy(method, "-[%rdi ");
3172             else if (Arch == Triple::aarch64)
3173               strcpy(method, "-[x0 ");
3174             else
3175               strcpy(method, "-[r? ");
3176             strcat(method, info->selector_name);
3177             strcat(method, "]");
3178             *ReferenceName = method;
3179             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
3180           }
3181         }
3182         info->class_name = nullptr;
3183       }
3184     } else if (strcmp(*ReferenceName, "_objc_msgSendSuper2") == 0) {
3185       if (info->selector_name != nullptr) {
3186         info->method =
3187             std::make_unique<char[]>(17 + strlen(info->selector_name));
3188         char *method = info->method.get();
3189         if (method != nullptr) {
3190           if (Arch == Triple::x86_64)
3191             strcpy(method, "-[[%rdi super] ");
3192           else if (Arch == Triple::aarch64)
3193             strcpy(method, "-[[x0 super] ");
3194           else
3195             strcpy(method, "-[[r? super] ");
3196           strcat(method, info->selector_name);
3197           strcat(method, "]");
3198           *ReferenceName = method;
3199           *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
3200         }
3201         info->class_name = nullptr;
3202       }
3203     }
3204   }
3205 }
3206 
3207 // GuessPointerPointer() is passed the address of what might be a pointer to
3208 // a reference to an Objective-C class, selector, message ref or cfstring.
3209 // If so the value of the pointer is returned and one of the booleans are set
3210 // to true.  If not zero is returned and all the booleans are set to false.
3211 static uint64_t GuessPointerPointer(uint64_t ReferenceValue,
3212                                     struct DisassembleInfo *info,
3213                                     bool &classref, bool &selref, bool &msgref,
3214                                     bool &cfstring) {
3215   classref = false;
3216   selref = false;
3217   msgref = false;
3218   cfstring = false;
3219   for (const auto &Load : info->O->load_commands()) {
3220     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
3221       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
3222       for (unsigned J = 0; J < Seg.nsects; ++J) {
3223         MachO::section_64 Sec = info->O->getSection64(Load, J);
3224         if ((strncmp(Sec.sectname, "__objc_selrefs", 16) == 0 ||
3225              strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
3226              strncmp(Sec.sectname, "__objc_superrefs", 16) == 0 ||
3227              strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 ||
3228              strncmp(Sec.sectname, "__cfstring", 16) == 0) &&
3229             ReferenceValue >= Sec.addr &&
3230             ReferenceValue < Sec.addr + Sec.size) {
3231           uint64_t sect_offset = ReferenceValue - Sec.addr;
3232           uint64_t object_offset = Sec.offset + sect_offset;
3233           StringRef MachOContents = info->O->getData();
3234           uint64_t object_size = MachOContents.size();
3235           const char *object_addr = (const char *)MachOContents.data();
3236           if (object_offset < object_size) {
3237             uint64_t pointer_value;
3238             memcpy(&pointer_value, object_addr + object_offset,
3239                    sizeof(uint64_t));
3240             if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3241               sys::swapByteOrder(pointer_value);
3242             if (strncmp(Sec.sectname, "__objc_selrefs", 16) == 0)
3243               selref = true;
3244             else if (strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
3245                      strncmp(Sec.sectname, "__objc_superrefs", 16) == 0)
3246               classref = true;
3247             else if (strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 &&
3248                      ReferenceValue + 8 < Sec.addr + Sec.size) {
3249               msgref = true;
3250               memcpy(&pointer_value, object_addr + object_offset + 8,
3251                      sizeof(uint64_t));
3252               if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3253                 sys::swapByteOrder(pointer_value);
3254             } else if (strncmp(Sec.sectname, "__cfstring", 16) == 0)
3255               cfstring = true;
3256             return pointer_value;
3257           } else {
3258             return 0;
3259           }
3260         }
3261       }
3262     }
3263     // TODO: Look for LC_SEGMENT for 32-bit Mach-O files.
3264   }
3265   return 0;
3266 }
3267 
3268 // get_pointer_64 returns a pointer to the bytes in the object file at the
3269 // Address from a section in the Mach-O file.  And indirectly returns the
3270 // offset into the section, number of bytes left in the section past the offset
3271 // and which section is was being referenced.  If the Address is not in a
3272 // section nullptr is returned.
3273 static const char *get_pointer_64(uint64_t Address, uint32_t &offset,
3274                                   uint32_t &left, SectionRef &S,
3275                                   DisassembleInfo *info,
3276                                   bool objc_only = false) {
3277   offset = 0;
3278   left = 0;
3279   S = SectionRef();
3280   for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) {
3281     uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress();
3282     uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize();
3283     if (SectSize == 0)
3284       continue;
3285     if (objc_only) {
3286       StringRef SectName;
3287       Expected<StringRef> SecNameOrErr =
3288           ((*(info->Sections))[SectIdx]).getName();
3289       if (SecNameOrErr)
3290         SectName = *SecNameOrErr;
3291       else
3292         consumeError(SecNameOrErr.takeError());
3293 
3294       DataRefImpl Ref = ((*(info->Sections))[SectIdx]).getRawDataRefImpl();
3295       StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
3296       if (SegName != "__OBJC" && SectName != "__cstring")
3297         continue;
3298     }
3299     if (Address >= SectAddress && Address < SectAddress + SectSize) {
3300       S = (*(info->Sections))[SectIdx];
3301       offset = Address - SectAddress;
3302       left = SectSize - offset;
3303       StringRef SectContents = unwrapOrError(
3304           ((*(info->Sections))[SectIdx]).getContents(), info->O->getFileName());
3305       return SectContents.data() + offset;
3306     }
3307   }
3308   return nullptr;
3309 }
3310 
3311 static const char *get_pointer_32(uint32_t Address, uint32_t &offset,
3312                                   uint32_t &left, SectionRef &S,
3313                                   DisassembleInfo *info,
3314                                   bool objc_only = false) {
3315   return get_pointer_64(Address, offset, left, S, info, objc_only);
3316 }
3317 
3318 // get_symbol_64() returns the name of a symbol (or nullptr) and the address of
3319 // the symbol indirectly through n_value. Based on the relocation information
3320 // for the specified section offset in the specified section reference.
3321 // If no relocation information is found and a non-zero ReferenceValue for the
3322 // symbol is passed, look up that address in the info's AddrMap.
3323 static const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
3324                                  DisassembleInfo *info, uint64_t &n_value,
3325                                  uint64_t ReferenceValue = 0) {
3326   n_value = 0;
3327   if (!info->verbose)
3328     return nullptr;
3329 
3330   // See if there is an external relocation entry at the sect_offset.
3331   bool reloc_found = false;
3332   DataRefImpl Rel;
3333   MachO::any_relocation_info RE;
3334   bool isExtern = false;
3335   SymbolRef Symbol;
3336   for (const RelocationRef &Reloc : S.relocations()) {
3337     uint64_t RelocOffset = Reloc.getOffset();
3338     if (RelocOffset == sect_offset) {
3339       Rel = Reloc.getRawDataRefImpl();
3340       RE = info->O->getRelocation(Rel);
3341       if (info->O->isRelocationScattered(RE))
3342         continue;
3343       isExtern = info->O->getPlainRelocationExternal(RE);
3344       if (isExtern) {
3345         symbol_iterator RelocSym = Reloc.getSymbol();
3346         Symbol = *RelocSym;
3347       }
3348       reloc_found = true;
3349       break;
3350     }
3351   }
3352   // If there is an external relocation entry for a symbol in this section
3353   // at this section_offset then use that symbol's value for the n_value
3354   // and return its name.
3355   const char *SymbolName = nullptr;
3356   if (reloc_found && isExtern) {
3357     n_value = cantFail(Symbol.getValue());
3358     StringRef Name = unwrapOrError(Symbol.getName(), info->O->getFileName());
3359     if (!Name.empty()) {
3360       SymbolName = Name.data();
3361       return SymbolName;
3362     }
3363   }
3364 
3365   // TODO: For fully linked images, look through the external relocation
3366   // entries off the dynamic symtab command. For these the r_offset is from the
3367   // start of the first writeable segment in the Mach-O file.  So the offset
3368   // to this section from that segment is passed to this routine by the caller,
3369   // as the database_offset. Which is the difference of the section's starting
3370   // address and the first writable segment.
3371   //
3372   // NOTE: need add passing the database_offset to this routine.
3373 
3374   // We did not find an external relocation entry so look up the ReferenceValue
3375   // as an address of a symbol and if found return that symbol's name.
3376   SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
3377 
3378   return SymbolName;
3379 }
3380 
3381 static const char *get_symbol_32(uint32_t sect_offset, SectionRef S,
3382                                  DisassembleInfo *info,
3383                                  uint32_t ReferenceValue) {
3384   uint64_t n_value64;
3385   return get_symbol_64(sect_offset, S, info, n_value64, ReferenceValue);
3386 }
3387 
3388 namespace {
3389 
3390 // These are structs in the Objective-C meta data and read to produce the
3391 // comments for disassembly.  While these are part of the ABI they are no
3392 // public defintions.  So the are here not in include/llvm/BinaryFormat/MachO.h
3393 // .
3394 
3395 // The cfstring object in a 64-bit Mach-O file.
3396 struct cfstring64_t {
3397   uint64_t isa;        // class64_t * (64-bit pointer)
3398   uint64_t flags;      // flag bits
3399   uint64_t characters; // char * (64-bit pointer)
3400   uint64_t length;     // number of non-NULL characters in above
3401 };
3402 
3403 // The class object in a 64-bit Mach-O file.
3404 struct class64_t {
3405   uint64_t isa;        // class64_t * (64-bit pointer)
3406   uint64_t superclass; // class64_t * (64-bit pointer)
3407   uint64_t cache;      // Cache (64-bit pointer)
3408   uint64_t vtable;     // IMP * (64-bit pointer)
3409   uint64_t data;       // class_ro64_t * (64-bit pointer)
3410 };
3411 
3412 struct class32_t {
3413   uint32_t isa;        /* class32_t * (32-bit pointer) */
3414   uint32_t superclass; /* class32_t * (32-bit pointer) */
3415   uint32_t cache;      /* Cache (32-bit pointer) */
3416   uint32_t vtable;     /* IMP * (32-bit pointer) */
3417   uint32_t data;       /* class_ro32_t * (32-bit pointer) */
3418 };
3419 
3420 struct class_ro64_t {
3421   uint32_t flags;
3422   uint32_t instanceStart;
3423   uint32_t instanceSize;
3424   uint32_t reserved;
3425   uint64_t ivarLayout;     // const uint8_t * (64-bit pointer)
3426   uint64_t name;           // const char * (64-bit pointer)
3427   uint64_t baseMethods;    // const method_list_t * (64-bit pointer)
3428   uint64_t baseProtocols;  // const protocol_list_t * (64-bit pointer)
3429   uint64_t ivars;          // const ivar_list_t * (64-bit pointer)
3430   uint64_t weakIvarLayout; // const uint8_t * (64-bit pointer)
3431   uint64_t baseProperties; // const struct objc_property_list (64-bit pointer)
3432 };
3433 
3434 struct class_ro32_t {
3435   uint32_t flags;
3436   uint32_t instanceStart;
3437   uint32_t instanceSize;
3438   uint32_t ivarLayout;     /* const uint8_t * (32-bit pointer) */
3439   uint32_t name;           /* const char * (32-bit pointer) */
3440   uint32_t baseMethods;    /* const method_list_t * (32-bit pointer) */
3441   uint32_t baseProtocols;  /* const protocol_list_t * (32-bit pointer) */
3442   uint32_t ivars;          /* const ivar_list_t * (32-bit pointer) */
3443   uint32_t weakIvarLayout; /* const uint8_t * (32-bit pointer) */
3444   uint32_t baseProperties; /* const struct objc_property_list *
3445                                                    (32-bit pointer) */
3446 };
3447 
3448 /* Values for class_ro{64,32}_t->flags */
3449 #define RO_META (1 << 0)
3450 #define RO_ROOT (1 << 1)
3451 #define RO_HAS_CXX_STRUCTORS (1 << 2)
3452 
3453 struct method_list64_t {
3454   uint32_t entsize;
3455   uint32_t count;
3456   /* struct method64_t first;  These structures follow inline */
3457 };
3458 
3459 struct method_list32_t {
3460   uint32_t entsize;
3461   uint32_t count;
3462   /* struct method32_t first;  These structures follow inline */
3463 };
3464 
3465 struct method64_t {
3466   uint64_t name;  /* SEL (64-bit pointer) */
3467   uint64_t types; /* const char * (64-bit pointer) */
3468   uint64_t imp;   /* IMP (64-bit pointer) */
3469 };
3470 
3471 struct method32_t {
3472   uint32_t name;  /* SEL (32-bit pointer) */
3473   uint32_t types; /* const char * (32-bit pointer) */
3474   uint32_t imp;   /* IMP (32-bit pointer) */
3475 };
3476 
3477 struct protocol_list64_t {
3478   uint64_t count; /* uintptr_t (a 64-bit value) */
3479   /* struct protocol64_t * list[0];  These pointers follow inline */
3480 };
3481 
3482 struct protocol_list32_t {
3483   uint32_t count; /* uintptr_t (a 32-bit value) */
3484   /* struct protocol32_t * list[0];  These pointers follow inline */
3485 };
3486 
3487 struct protocol64_t {
3488   uint64_t isa;                     /* id * (64-bit pointer) */
3489   uint64_t name;                    /* const char * (64-bit pointer) */
3490   uint64_t protocols;               /* struct protocol_list64_t *
3491                                                     (64-bit pointer) */
3492   uint64_t instanceMethods;         /* method_list_t * (64-bit pointer) */
3493   uint64_t classMethods;            /* method_list_t * (64-bit pointer) */
3494   uint64_t optionalInstanceMethods; /* method_list_t * (64-bit pointer) */
3495   uint64_t optionalClassMethods;    /* method_list_t * (64-bit pointer) */
3496   uint64_t instanceProperties;      /* struct objc_property_list *
3497                                                        (64-bit pointer) */
3498 };
3499 
3500 struct protocol32_t {
3501   uint32_t isa;                     /* id * (32-bit pointer) */
3502   uint32_t name;                    /* const char * (32-bit pointer) */
3503   uint32_t protocols;               /* struct protocol_list_t *
3504                                                     (32-bit pointer) */
3505   uint32_t instanceMethods;         /* method_list_t * (32-bit pointer) */
3506   uint32_t classMethods;            /* method_list_t * (32-bit pointer) */
3507   uint32_t optionalInstanceMethods; /* method_list_t * (32-bit pointer) */
3508   uint32_t optionalClassMethods;    /* method_list_t * (32-bit pointer) */
3509   uint32_t instanceProperties;      /* struct objc_property_list *
3510                                                        (32-bit pointer) */
3511 };
3512 
3513 struct ivar_list64_t {
3514   uint32_t entsize;
3515   uint32_t count;
3516   /* struct ivar64_t first;  These structures follow inline */
3517 };
3518 
3519 struct ivar_list32_t {
3520   uint32_t entsize;
3521   uint32_t count;
3522   /* struct ivar32_t first;  These structures follow inline */
3523 };
3524 
3525 struct ivar64_t {
3526   uint64_t offset; /* uintptr_t * (64-bit pointer) */
3527   uint64_t name;   /* const char * (64-bit pointer) */
3528   uint64_t type;   /* const char * (64-bit pointer) */
3529   uint32_t alignment;
3530   uint32_t size;
3531 };
3532 
3533 struct ivar32_t {
3534   uint32_t offset; /* uintptr_t * (32-bit pointer) */
3535   uint32_t name;   /* const char * (32-bit pointer) */
3536   uint32_t type;   /* const char * (32-bit pointer) */
3537   uint32_t alignment;
3538   uint32_t size;
3539 };
3540 
3541 struct objc_property_list64 {
3542   uint32_t entsize;
3543   uint32_t count;
3544   /* struct objc_property64 first;  These structures follow inline */
3545 };
3546 
3547 struct objc_property_list32 {
3548   uint32_t entsize;
3549   uint32_t count;
3550   /* struct objc_property32 first;  These structures follow inline */
3551 };
3552 
3553 struct objc_property64 {
3554   uint64_t name;       /* const char * (64-bit pointer) */
3555   uint64_t attributes; /* const char * (64-bit pointer) */
3556 };
3557 
3558 struct objc_property32 {
3559   uint32_t name;       /* const char * (32-bit pointer) */
3560   uint32_t attributes; /* const char * (32-bit pointer) */
3561 };
3562 
3563 struct category64_t {
3564   uint64_t name;               /* const char * (64-bit pointer) */
3565   uint64_t cls;                /* struct class_t * (64-bit pointer) */
3566   uint64_t instanceMethods;    /* struct method_list_t * (64-bit pointer) */
3567   uint64_t classMethods;       /* struct method_list_t * (64-bit pointer) */
3568   uint64_t protocols;          /* struct protocol_list_t * (64-bit pointer) */
3569   uint64_t instanceProperties; /* struct objc_property_list *
3570                                   (64-bit pointer) */
3571 };
3572 
3573 struct category32_t {
3574   uint32_t name;               /* const char * (32-bit pointer) */
3575   uint32_t cls;                /* struct class_t * (32-bit pointer) */
3576   uint32_t instanceMethods;    /* struct method_list_t * (32-bit pointer) */
3577   uint32_t classMethods;       /* struct method_list_t * (32-bit pointer) */
3578   uint32_t protocols;          /* struct protocol_list_t * (32-bit pointer) */
3579   uint32_t instanceProperties; /* struct objc_property_list *
3580                                   (32-bit pointer) */
3581 };
3582 
3583 struct objc_image_info64 {
3584   uint32_t version;
3585   uint32_t flags;
3586 };
3587 struct objc_image_info32 {
3588   uint32_t version;
3589   uint32_t flags;
3590 };
3591 struct imageInfo_t {
3592   uint32_t version;
3593   uint32_t flags;
3594 };
3595 /* masks for objc_image_info.flags */
3596 #define OBJC_IMAGE_IS_REPLACEMENT (1 << 0)
3597 #define OBJC_IMAGE_SUPPORTS_GC (1 << 1)
3598 #define OBJC_IMAGE_IS_SIMULATED (1 << 5)
3599 #define OBJC_IMAGE_HAS_CATEGORY_CLASS_PROPERTIES (1 << 6)
3600 
3601 struct message_ref64 {
3602   uint64_t imp; /* IMP (64-bit pointer) */
3603   uint64_t sel; /* SEL (64-bit pointer) */
3604 };
3605 
3606 struct message_ref32 {
3607   uint32_t imp; /* IMP (32-bit pointer) */
3608   uint32_t sel; /* SEL (32-bit pointer) */
3609 };
3610 
3611 // Objective-C 1 (32-bit only) meta data structs.
3612 
3613 struct objc_module_t {
3614   uint32_t version;
3615   uint32_t size;
3616   uint32_t name;   /* char * (32-bit pointer) */
3617   uint32_t symtab; /* struct objc_symtab * (32-bit pointer) */
3618 };
3619 
3620 struct objc_symtab_t {
3621   uint32_t sel_ref_cnt;
3622   uint32_t refs; /* SEL * (32-bit pointer) */
3623   uint16_t cls_def_cnt;
3624   uint16_t cat_def_cnt;
3625   // uint32_t defs[1];        /* void * (32-bit pointer) variable size */
3626 };
3627 
3628 struct objc_class_t {
3629   uint32_t isa;         /* struct objc_class * (32-bit pointer) */
3630   uint32_t super_class; /* struct objc_class * (32-bit pointer) */
3631   uint32_t name;        /* const char * (32-bit pointer) */
3632   int32_t version;
3633   int32_t info;
3634   int32_t instance_size;
3635   uint32_t ivars;       /* struct objc_ivar_list * (32-bit pointer) */
3636   uint32_t methodLists; /* struct objc_method_list ** (32-bit pointer) */
3637   uint32_t cache;       /* struct objc_cache * (32-bit pointer) */
3638   uint32_t protocols;   /* struct objc_protocol_list * (32-bit pointer) */
3639 };
3640 
3641 #define CLS_GETINFO(cls, infomask) ((cls)->info & (infomask))
3642 // class is not a metaclass
3643 #define CLS_CLASS 0x1
3644 // class is a metaclass
3645 #define CLS_META 0x2
3646 
3647 struct objc_category_t {
3648   uint32_t category_name;    /* char * (32-bit pointer) */
3649   uint32_t class_name;       /* char * (32-bit pointer) */
3650   uint32_t instance_methods; /* struct objc_method_list * (32-bit pointer) */
3651   uint32_t class_methods;    /* struct objc_method_list * (32-bit pointer) */
3652   uint32_t protocols;        /* struct objc_protocol_list * (32-bit ptr) */
3653 };
3654 
3655 struct objc_ivar_t {
3656   uint32_t ivar_name; /* char * (32-bit pointer) */
3657   uint32_t ivar_type; /* char * (32-bit pointer) */
3658   int32_t ivar_offset;
3659 };
3660 
3661 struct objc_ivar_list_t {
3662   int32_t ivar_count;
3663   // struct objc_ivar_t ivar_list[1];          /* variable length structure */
3664 };
3665 
3666 struct objc_method_list_t {
3667   uint32_t obsolete; /* struct objc_method_list * (32-bit pointer) */
3668   int32_t method_count;
3669   // struct objc_method_t method_list[1];      /* variable length structure */
3670 };
3671 
3672 struct objc_method_t {
3673   uint32_t method_name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
3674   uint32_t method_types; /* char * (32-bit pointer) */
3675   uint32_t method_imp;   /* IMP, aka function pointer, (*IMP)(id, SEL, ...)
3676                             (32-bit pointer) */
3677 };
3678 
3679 struct objc_protocol_list_t {
3680   uint32_t next; /* struct objc_protocol_list * (32-bit pointer) */
3681   int32_t count;
3682   // uint32_t list[1];   /* Protocol *, aka struct objc_protocol_t *
3683   //                        (32-bit pointer) */
3684 };
3685 
3686 struct objc_protocol_t {
3687   uint32_t isa;              /* struct objc_class * (32-bit pointer) */
3688   uint32_t protocol_name;    /* char * (32-bit pointer) */
3689   uint32_t protocol_list;    /* struct objc_protocol_list * (32-bit pointer) */
3690   uint32_t instance_methods; /* struct objc_method_description_list *
3691                                 (32-bit pointer) */
3692   uint32_t class_methods;    /* struct objc_method_description_list *
3693                                 (32-bit pointer) */
3694 };
3695 
3696 struct objc_method_description_list_t {
3697   int32_t count;
3698   // struct objc_method_description_t list[1];
3699 };
3700 
3701 struct objc_method_description_t {
3702   uint32_t name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
3703   uint32_t types; /* char * (32-bit pointer) */
3704 };
3705 
3706 inline void swapStruct(struct cfstring64_t &cfs) {
3707   sys::swapByteOrder(cfs.isa);
3708   sys::swapByteOrder(cfs.flags);
3709   sys::swapByteOrder(cfs.characters);
3710   sys::swapByteOrder(cfs.length);
3711 }
3712 
3713 inline void swapStruct(struct class64_t &c) {
3714   sys::swapByteOrder(c.isa);
3715   sys::swapByteOrder(c.superclass);
3716   sys::swapByteOrder(c.cache);
3717   sys::swapByteOrder(c.vtable);
3718   sys::swapByteOrder(c.data);
3719 }
3720 
3721 inline void swapStruct(struct class32_t &c) {
3722   sys::swapByteOrder(c.isa);
3723   sys::swapByteOrder(c.superclass);
3724   sys::swapByteOrder(c.cache);
3725   sys::swapByteOrder(c.vtable);
3726   sys::swapByteOrder(c.data);
3727 }
3728 
3729 inline void swapStruct(struct class_ro64_t &cro) {
3730   sys::swapByteOrder(cro.flags);
3731   sys::swapByteOrder(cro.instanceStart);
3732   sys::swapByteOrder(cro.instanceSize);
3733   sys::swapByteOrder(cro.reserved);
3734   sys::swapByteOrder(cro.ivarLayout);
3735   sys::swapByteOrder(cro.name);
3736   sys::swapByteOrder(cro.baseMethods);
3737   sys::swapByteOrder(cro.baseProtocols);
3738   sys::swapByteOrder(cro.ivars);
3739   sys::swapByteOrder(cro.weakIvarLayout);
3740   sys::swapByteOrder(cro.baseProperties);
3741 }
3742 
3743 inline void swapStruct(struct class_ro32_t &cro) {
3744   sys::swapByteOrder(cro.flags);
3745   sys::swapByteOrder(cro.instanceStart);
3746   sys::swapByteOrder(cro.instanceSize);
3747   sys::swapByteOrder(cro.ivarLayout);
3748   sys::swapByteOrder(cro.name);
3749   sys::swapByteOrder(cro.baseMethods);
3750   sys::swapByteOrder(cro.baseProtocols);
3751   sys::swapByteOrder(cro.ivars);
3752   sys::swapByteOrder(cro.weakIvarLayout);
3753   sys::swapByteOrder(cro.baseProperties);
3754 }
3755 
3756 inline void swapStruct(struct method_list64_t &ml) {
3757   sys::swapByteOrder(ml.entsize);
3758   sys::swapByteOrder(ml.count);
3759 }
3760 
3761 inline void swapStruct(struct method_list32_t &ml) {
3762   sys::swapByteOrder(ml.entsize);
3763   sys::swapByteOrder(ml.count);
3764 }
3765 
3766 inline void swapStruct(struct method64_t &m) {
3767   sys::swapByteOrder(m.name);
3768   sys::swapByteOrder(m.types);
3769   sys::swapByteOrder(m.imp);
3770 }
3771 
3772 inline void swapStruct(struct method32_t &m) {
3773   sys::swapByteOrder(m.name);
3774   sys::swapByteOrder(m.types);
3775   sys::swapByteOrder(m.imp);
3776 }
3777 
3778 inline void swapStruct(struct protocol_list64_t &pl) {
3779   sys::swapByteOrder(pl.count);
3780 }
3781 
3782 inline void swapStruct(struct protocol_list32_t &pl) {
3783   sys::swapByteOrder(pl.count);
3784 }
3785 
3786 inline void swapStruct(struct protocol64_t &p) {
3787   sys::swapByteOrder(p.isa);
3788   sys::swapByteOrder(p.name);
3789   sys::swapByteOrder(p.protocols);
3790   sys::swapByteOrder(p.instanceMethods);
3791   sys::swapByteOrder(p.classMethods);
3792   sys::swapByteOrder(p.optionalInstanceMethods);
3793   sys::swapByteOrder(p.optionalClassMethods);
3794   sys::swapByteOrder(p.instanceProperties);
3795 }
3796 
3797 inline void swapStruct(struct protocol32_t &p) {
3798   sys::swapByteOrder(p.isa);
3799   sys::swapByteOrder(p.name);
3800   sys::swapByteOrder(p.protocols);
3801   sys::swapByteOrder(p.instanceMethods);
3802   sys::swapByteOrder(p.classMethods);
3803   sys::swapByteOrder(p.optionalInstanceMethods);
3804   sys::swapByteOrder(p.optionalClassMethods);
3805   sys::swapByteOrder(p.instanceProperties);
3806 }
3807 
3808 inline void swapStruct(struct ivar_list64_t &il) {
3809   sys::swapByteOrder(il.entsize);
3810   sys::swapByteOrder(il.count);
3811 }
3812 
3813 inline void swapStruct(struct ivar_list32_t &il) {
3814   sys::swapByteOrder(il.entsize);
3815   sys::swapByteOrder(il.count);
3816 }
3817 
3818 inline void swapStruct(struct ivar64_t &i) {
3819   sys::swapByteOrder(i.offset);
3820   sys::swapByteOrder(i.name);
3821   sys::swapByteOrder(i.type);
3822   sys::swapByteOrder(i.alignment);
3823   sys::swapByteOrder(i.size);
3824 }
3825 
3826 inline void swapStruct(struct ivar32_t &i) {
3827   sys::swapByteOrder(i.offset);
3828   sys::swapByteOrder(i.name);
3829   sys::swapByteOrder(i.type);
3830   sys::swapByteOrder(i.alignment);
3831   sys::swapByteOrder(i.size);
3832 }
3833 
3834 inline void swapStruct(struct objc_property_list64 &pl) {
3835   sys::swapByteOrder(pl.entsize);
3836   sys::swapByteOrder(pl.count);
3837 }
3838 
3839 inline void swapStruct(struct objc_property_list32 &pl) {
3840   sys::swapByteOrder(pl.entsize);
3841   sys::swapByteOrder(pl.count);
3842 }
3843 
3844 inline void swapStruct(struct objc_property64 &op) {
3845   sys::swapByteOrder(op.name);
3846   sys::swapByteOrder(op.attributes);
3847 }
3848 
3849 inline void swapStruct(struct objc_property32 &op) {
3850   sys::swapByteOrder(op.name);
3851   sys::swapByteOrder(op.attributes);
3852 }
3853 
3854 inline void swapStruct(struct category64_t &c) {
3855   sys::swapByteOrder(c.name);
3856   sys::swapByteOrder(c.cls);
3857   sys::swapByteOrder(c.instanceMethods);
3858   sys::swapByteOrder(c.classMethods);
3859   sys::swapByteOrder(c.protocols);
3860   sys::swapByteOrder(c.instanceProperties);
3861 }
3862 
3863 inline void swapStruct(struct category32_t &c) {
3864   sys::swapByteOrder(c.name);
3865   sys::swapByteOrder(c.cls);
3866   sys::swapByteOrder(c.instanceMethods);
3867   sys::swapByteOrder(c.classMethods);
3868   sys::swapByteOrder(c.protocols);
3869   sys::swapByteOrder(c.instanceProperties);
3870 }
3871 
3872 inline void swapStruct(struct objc_image_info64 &o) {
3873   sys::swapByteOrder(o.version);
3874   sys::swapByteOrder(o.flags);
3875 }
3876 
3877 inline void swapStruct(struct objc_image_info32 &o) {
3878   sys::swapByteOrder(o.version);
3879   sys::swapByteOrder(o.flags);
3880 }
3881 
3882 inline void swapStruct(struct imageInfo_t &o) {
3883   sys::swapByteOrder(o.version);
3884   sys::swapByteOrder(o.flags);
3885 }
3886 
3887 inline void swapStruct(struct message_ref64 &mr) {
3888   sys::swapByteOrder(mr.imp);
3889   sys::swapByteOrder(mr.sel);
3890 }
3891 
3892 inline void swapStruct(struct message_ref32 &mr) {
3893   sys::swapByteOrder(mr.imp);
3894   sys::swapByteOrder(mr.sel);
3895 }
3896 
3897 inline void swapStruct(struct objc_module_t &module) {
3898   sys::swapByteOrder(module.version);
3899   sys::swapByteOrder(module.size);
3900   sys::swapByteOrder(module.name);
3901   sys::swapByteOrder(module.symtab);
3902 }
3903 
3904 inline void swapStruct(struct objc_symtab_t &symtab) {
3905   sys::swapByteOrder(symtab.sel_ref_cnt);
3906   sys::swapByteOrder(symtab.refs);
3907   sys::swapByteOrder(symtab.cls_def_cnt);
3908   sys::swapByteOrder(symtab.cat_def_cnt);
3909 }
3910 
3911 inline void swapStruct(struct objc_class_t &objc_class) {
3912   sys::swapByteOrder(objc_class.isa);
3913   sys::swapByteOrder(objc_class.super_class);
3914   sys::swapByteOrder(objc_class.name);
3915   sys::swapByteOrder(objc_class.version);
3916   sys::swapByteOrder(objc_class.info);
3917   sys::swapByteOrder(objc_class.instance_size);
3918   sys::swapByteOrder(objc_class.ivars);
3919   sys::swapByteOrder(objc_class.methodLists);
3920   sys::swapByteOrder(objc_class.cache);
3921   sys::swapByteOrder(objc_class.protocols);
3922 }
3923 
3924 inline void swapStruct(struct objc_category_t &objc_category) {
3925   sys::swapByteOrder(objc_category.category_name);
3926   sys::swapByteOrder(objc_category.class_name);
3927   sys::swapByteOrder(objc_category.instance_methods);
3928   sys::swapByteOrder(objc_category.class_methods);
3929   sys::swapByteOrder(objc_category.protocols);
3930 }
3931 
3932 inline void swapStruct(struct objc_ivar_list_t &objc_ivar_list) {
3933   sys::swapByteOrder(objc_ivar_list.ivar_count);
3934 }
3935 
3936 inline void swapStruct(struct objc_ivar_t &objc_ivar) {
3937   sys::swapByteOrder(objc_ivar.ivar_name);
3938   sys::swapByteOrder(objc_ivar.ivar_type);
3939   sys::swapByteOrder(objc_ivar.ivar_offset);
3940 }
3941 
3942 inline void swapStruct(struct objc_method_list_t &method_list) {
3943   sys::swapByteOrder(method_list.obsolete);
3944   sys::swapByteOrder(method_list.method_count);
3945 }
3946 
3947 inline void swapStruct(struct objc_method_t &method) {
3948   sys::swapByteOrder(method.method_name);
3949   sys::swapByteOrder(method.method_types);
3950   sys::swapByteOrder(method.method_imp);
3951 }
3952 
3953 inline void swapStruct(struct objc_protocol_list_t &protocol_list) {
3954   sys::swapByteOrder(protocol_list.next);
3955   sys::swapByteOrder(protocol_list.count);
3956 }
3957 
3958 inline void swapStruct(struct objc_protocol_t &protocol) {
3959   sys::swapByteOrder(protocol.isa);
3960   sys::swapByteOrder(protocol.protocol_name);
3961   sys::swapByteOrder(protocol.protocol_list);
3962   sys::swapByteOrder(protocol.instance_methods);
3963   sys::swapByteOrder(protocol.class_methods);
3964 }
3965 
3966 inline void swapStruct(struct objc_method_description_list_t &mdl) {
3967   sys::swapByteOrder(mdl.count);
3968 }
3969 
3970 inline void swapStruct(struct objc_method_description_t &md) {
3971   sys::swapByteOrder(md.name);
3972   sys::swapByteOrder(md.types);
3973 }
3974 
3975 } // namespace
3976 
3977 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
3978                                                  struct DisassembleInfo *info);
3979 
3980 // get_objc2_64bit_class_name() is used for disassembly and is passed a pointer
3981 // to an Objective-C class and returns the class name.  It is also passed the
3982 // address of the pointer, so when the pointer is zero as it can be in an .o
3983 // file, that is used to look for an external relocation entry with a symbol
3984 // name.
3985 static const char *get_objc2_64bit_class_name(uint64_t pointer_value,
3986                                               uint64_t ReferenceValue,
3987                                               struct DisassembleInfo *info) {
3988   const char *r;
3989   uint32_t offset, left;
3990   SectionRef S;
3991 
3992   // The pointer_value can be 0 in an object file and have a relocation
3993   // entry for the class symbol at the ReferenceValue (the address of the
3994   // pointer).
3995   if (pointer_value == 0) {
3996     r = get_pointer_64(ReferenceValue, offset, left, S, info);
3997     if (r == nullptr || left < sizeof(uint64_t))
3998       return nullptr;
3999     uint64_t n_value;
4000     const char *symbol_name = get_symbol_64(offset, S, info, n_value);
4001     if (symbol_name == nullptr)
4002       return nullptr;
4003     const char *class_name = strrchr(symbol_name, '$');
4004     if (class_name != nullptr && class_name[1] == '_' && class_name[2] != '\0')
4005       return class_name + 2;
4006     else
4007       return nullptr;
4008   }
4009 
4010   // The case were the pointer_value is non-zero and points to a class defined
4011   // in this Mach-O file.
4012   r = get_pointer_64(pointer_value, offset, left, S, info);
4013   if (r == nullptr || left < sizeof(struct class64_t))
4014     return nullptr;
4015   struct class64_t c;
4016   memcpy(&c, r, sizeof(struct class64_t));
4017   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4018     swapStruct(c);
4019   if (c.data == 0)
4020     return nullptr;
4021   r = get_pointer_64(c.data, offset, left, S, info);
4022   if (r == nullptr || left < sizeof(struct class_ro64_t))
4023     return nullptr;
4024   struct class_ro64_t cro;
4025   memcpy(&cro, r, sizeof(struct class_ro64_t));
4026   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4027     swapStruct(cro);
4028   if (cro.name == 0)
4029     return nullptr;
4030   const char *name = get_pointer_64(cro.name, offset, left, S, info);
4031   return name;
4032 }
4033 
4034 // get_objc2_64bit_cfstring_name is used for disassembly and is passed a
4035 // pointer to a cfstring and returns its name or nullptr.
4036 static const char *get_objc2_64bit_cfstring_name(uint64_t ReferenceValue,
4037                                                  struct DisassembleInfo *info) {
4038   const char *r, *name;
4039   uint32_t offset, left;
4040   SectionRef S;
4041   struct cfstring64_t cfs;
4042   uint64_t cfs_characters;
4043 
4044   r = get_pointer_64(ReferenceValue, offset, left, S, info);
4045   if (r == nullptr || left < sizeof(struct cfstring64_t))
4046     return nullptr;
4047   memcpy(&cfs, r, sizeof(struct cfstring64_t));
4048   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4049     swapStruct(cfs);
4050   if (cfs.characters == 0) {
4051     uint64_t n_value;
4052     const char *symbol_name = get_symbol_64(
4053         offset + offsetof(struct cfstring64_t, characters), S, info, n_value);
4054     if (symbol_name == nullptr)
4055       return nullptr;
4056     cfs_characters = n_value;
4057   } else
4058     cfs_characters = cfs.characters;
4059   name = get_pointer_64(cfs_characters, offset, left, S, info);
4060 
4061   return name;
4062 }
4063 
4064 // get_objc2_64bit_selref() is used for disassembly and is passed a the address
4065 // of a pointer to an Objective-C selector reference when the pointer value is
4066 // zero as in a .o file and is likely to have a external relocation entry with
4067 // who's symbol's n_value is the real pointer to the selector name.  If that is
4068 // the case the real pointer to the selector name is returned else 0 is
4069 // returned
4070 static uint64_t get_objc2_64bit_selref(uint64_t ReferenceValue,
4071                                        struct DisassembleInfo *info) {
4072   uint32_t offset, left;
4073   SectionRef S;
4074 
4075   const char *r = get_pointer_64(ReferenceValue, offset, left, S, info);
4076   if (r == nullptr || left < sizeof(uint64_t))
4077     return 0;
4078   uint64_t n_value;
4079   const char *symbol_name = get_symbol_64(offset, S, info, n_value);
4080   if (symbol_name == nullptr)
4081     return 0;
4082   return n_value;
4083 }
4084 
4085 static const SectionRef get_section(MachOObjectFile *O, const char *segname,
4086                                     const char *sectname) {
4087   for (const SectionRef &Section : O->sections()) {
4088     StringRef SectName;
4089     Expected<StringRef> SecNameOrErr = Section.getName();
4090     if (SecNameOrErr)
4091       SectName = *SecNameOrErr;
4092     else
4093       consumeError(SecNameOrErr.takeError());
4094 
4095     DataRefImpl Ref = Section.getRawDataRefImpl();
4096     StringRef SegName = O->getSectionFinalSegmentName(Ref);
4097     if (SegName == segname && SectName == sectname)
4098       return Section;
4099   }
4100   return SectionRef();
4101 }
4102 
4103 static void
4104 walk_pointer_list_64(const char *listname, const SectionRef S,
4105                      MachOObjectFile *O, struct DisassembleInfo *info,
4106                      void (*func)(uint64_t, struct DisassembleInfo *info)) {
4107   if (S == SectionRef())
4108     return;
4109 
4110   StringRef SectName;
4111   Expected<StringRef> SecNameOrErr = S.getName();
4112   if (SecNameOrErr)
4113     SectName = *SecNameOrErr;
4114   else
4115     consumeError(SecNameOrErr.takeError());
4116 
4117   DataRefImpl Ref = S.getRawDataRefImpl();
4118   StringRef SegName = O->getSectionFinalSegmentName(Ref);
4119   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
4120 
4121   StringRef BytesStr = unwrapOrError(S.getContents(), O->getFileName());
4122   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
4123 
4124   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint64_t)) {
4125     uint32_t left = S.getSize() - i;
4126     uint32_t size = left < sizeof(uint64_t) ? left : sizeof(uint64_t);
4127     uint64_t p = 0;
4128     memcpy(&p, Contents + i, size);
4129     if (i + sizeof(uint64_t) > S.getSize())
4130       outs() << listname << " list pointer extends past end of (" << SegName
4131              << "," << SectName << ") section\n";
4132     outs() << format("%016" PRIx64, S.getAddress() + i) << " ";
4133 
4134     if (O->isLittleEndian() != sys::IsLittleEndianHost)
4135       sys::swapByteOrder(p);
4136 
4137     uint64_t n_value = 0;
4138     const char *name = get_symbol_64(i, S, info, n_value, p);
4139     if (name == nullptr)
4140       name = get_dyld_bind_info_symbolname(S.getAddress() + i, info);
4141 
4142     if (n_value != 0) {
4143       outs() << format("0x%" PRIx64, n_value);
4144       if (p != 0)
4145         outs() << " + " << format("0x%" PRIx64, p);
4146     } else
4147       outs() << format("0x%" PRIx64, p);
4148     if (name != nullptr)
4149       outs() << " " << name;
4150     outs() << "\n";
4151 
4152     p += n_value;
4153     if (func)
4154       func(p, info);
4155   }
4156 }
4157 
4158 static void
4159 walk_pointer_list_32(const char *listname, const SectionRef S,
4160                      MachOObjectFile *O, struct DisassembleInfo *info,
4161                      void (*func)(uint32_t, struct DisassembleInfo *info)) {
4162   if (S == SectionRef())
4163     return;
4164 
4165   StringRef SectName = unwrapOrError(S.getName(), O->getFileName());
4166   DataRefImpl Ref = S.getRawDataRefImpl();
4167   StringRef SegName = O->getSectionFinalSegmentName(Ref);
4168   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
4169 
4170   StringRef BytesStr = unwrapOrError(S.getContents(), O->getFileName());
4171   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
4172 
4173   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint32_t)) {
4174     uint32_t left = S.getSize() - i;
4175     uint32_t size = left < sizeof(uint32_t) ? left : sizeof(uint32_t);
4176     uint32_t p = 0;
4177     memcpy(&p, Contents + i, size);
4178     if (i + sizeof(uint32_t) > S.getSize())
4179       outs() << listname << " list pointer extends past end of (" << SegName
4180              << "," << SectName << ") section\n";
4181     uint32_t Address = S.getAddress() + i;
4182     outs() << format("%08" PRIx32, Address) << " ";
4183 
4184     if (O->isLittleEndian() != sys::IsLittleEndianHost)
4185       sys::swapByteOrder(p);
4186     outs() << format("0x%" PRIx32, p);
4187 
4188     const char *name = get_symbol_32(i, S, info, p);
4189     if (name != nullptr)
4190       outs() << " " << name;
4191     outs() << "\n";
4192 
4193     if (func)
4194       func(p, info);
4195   }
4196 }
4197 
4198 static void print_layout_map(const char *layout_map, uint32_t left) {
4199   if (layout_map == nullptr)
4200     return;
4201   outs() << "                layout map: ";
4202   do {
4203     outs() << format("0x%02" PRIx32, (*layout_map) & 0xff) << " ";
4204     left--;
4205     layout_map++;
4206   } while (*layout_map != '\0' && left != 0);
4207   outs() << "\n";
4208 }
4209 
4210 static void print_layout_map64(uint64_t p, struct DisassembleInfo *info) {
4211   uint32_t offset, left;
4212   SectionRef S;
4213   const char *layout_map;
4214 
4215   if (p == 0)
4216     return;
4217   layout_map = get_pointer_64(p, offset, left, S, info);
4218   print_layout_map(layout_map, left);
4219 }
4220 
4221 static void print_layout_map32(uint32_t p, struct DisassembleInfo *info) {
4222   uint32_t offset, left;
4223   SectionRef S;
4224   const char *layout_map;
4225 
4226   if (p == 0)
4227     return;
4228   layout_map = get_pointer_32(p, offset, left, S, info);
4229   print_layout_map(layout_map, left);
4230 }
4231 
4232 static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
4233                                   const char *indent) {
4234   struct method_list64_t ml;
4235   struct method64_t m;
4236   const char *r;
4237   uint32_t offset, xoffset, left, i;
4238   SectionRef S, xS;
4239   const char *name, *sym_name;
4240   uint64_t n_value;
4241 
4242   r = get_pointer_64(p, offset, left, S, info);
4243   if (r == nullptr)
4244     return;
4245   memset(&ml, '\0', sizeof(struct method_list64_t));
4246   if (left < sizeof(struct method_list64_t)) {
4247     memcpy(&ml, r, left);
4248     outs() << "   (method_list_t entends past the end of the section)\n";
4249   } else
4250     memcpy(&ml, r, sizeof(struct method_list64_t));
4251   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4252     swapStruct(ml);
4253   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
4254   outs() << indent << "\t\t     count " << ml.count << "\n";
4255 
4256   p += sizeof(struct method_list64_t);
4257   offset += sizeof(struct method_list64_t);
4258   for (i = 0; i < ml.count; i++) {
4259     r = get_pointer_64(p, offset, left, S, info);
4260     if (r == nullptr)
4261       return;
4262     memset(&m, '\0', sizeof(struct method64_t));
4263     if (left < sizeof(struct method64_t)) {
4264       memcpy(&m, r, left);
4265       outs() << indent << "   (method_t extends past the end of the section)\n";
4266     } else
4267       memcpy(&m, r, sizeof(struct method64_t));
4268     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4269       swapStruct(m);
4270 
4271     outs() << indent << "\t\t      name ";
4272     sym_name = get_symbol_64(offset + offsetof(struct method64_t, name), S,
4273                              info, n_value, m.name);
4274     if (n_value != 0) {
4275       if (info->verbose && sym_name != nullptr)
4276         outs() << sym_name;
4277       else
4278         outs() << format("0x%" PRIx64, n_value);
4279       if (m.name != 0)
4280         outs() << " + " << format("0x%" PRIx64, m.name);
4281     } else
4282       outs() << format("0x%" PRIx64, m.name);
4283     name = get_pointer_64(m.name + n_value, xoffset, left, xS, info);
4284     if (name != nullptr)
4285       outs() << format(" %.*s", left, name);
4286     outs() << "\n";
4287 
4288     outs() << indent << "\t\t     types ";
4289     sym_name = get_symbol_64(offset + offsetof(struct method64_t, types), S,
4290                              info, n_value, m.types);
4291     if (n_value != 0) {
4292       if (info->verbose && sym_name != nullptr)
4293         outs() << sym_name;
4294       else
4295         outs() << format("0x%" PRIx64, n_value);
4296       if (m.types != 0)
4297         outs() << " + " << format("0x%" PRIx64, m.types);
4298     } else
4299       outs() << format("0x%" PRIx64, m.types);
4300     name = get_pointer_64(m.types + n_value, xoffset, left, xS, info);
4301     if (name != nullptr)
4302       outs() << format(" %.*s", left, name);
4303     outs() << "\n";
4304 
4305     outs() << indent << "\t\t       imp ";
4306     name = get_symbol_64(offset + offsetof(struct method64_t, imp), S, info,
4307                          n_value, m.imp);
4308     if (info->verbose && name == nullptr) {
4309       if (n_value != 0) {
4310         outs() << format("0x%" PRIx64, n_value) << " ";
4311         if (m.imp != 0)
4312           outs() << "+ " << format("0x%" PRIx64, m.imp) << " ";
4313       } else
4314         outs() << format("0x%" PRIx64, m.imp) << " ";
4315     }
4316     if (name != nullptr)
4317       outs() << name;
4318     outs() << "\n";
4319 
4320     p += sizeof(struct method64_t);
4321     offset += sizeof(struct method64_t);
4322   }
4323 }
4324 
4325 static void print_method_list32_t(uint64_t p, struct DisassembleInfo *info,
4326                                   const char *indent) {
4327   struct method_list32_t ml;
4328   struct method32_t m;
4329   const char *r, *name;
4330   uint32_t offset, xoffset, left, i;
4331   SectionRef S, xS;
4332 
4333   r = get_pointer_32(p, offset, left, S, info);
4334   if (r == nullptr)
4335     return;
4336   memset(&ml, '\0', sizeof(struct method_list32_t));
4337   if (left < sizeof(struct method_list32_t)) {
4338     memcpy(&ml, r, left);
4339     outs() << "   (method_list_t entends past the end of the section)\n";
4340   } else
4341     memcpy(&ml, r, sizeof(struct method_list32_t));
4342   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4343     swapStruct(ml);
4344   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
4345   outs() << indent << "\t\t     count " << ml.count << "\n";
4346 
4347   p += sizeof(struct method_list32_t);
4348   offset += sizeof(struct method_list32_t);
4349   for (i = 0; i < ml.count; i++) {
4350     r = get_pointer_32(p, offset, left, S, info);
4351     if (r == nullptr)
4352       return;
4353     memset(&m, '\0', sizeof(struct method32_t));
4354     if (left < sizeof(struct method32_t)) {
4355       memcpy(&ml, r, left);
4356       outs() << indent << "   (method_t entends past the end of the section)\n";
4357     } else
4358       memcpy(&m, r, sizeof(struct method32_t));
4359     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4360       swapStruct(m);
4361 
4362     outs() << indent << "\t\t      name " << format("0x%" PRIx32, m.name);
4363     name = get_pointer_32(m.name, xoffset, left, xS, info);
4364     if (name != nullptr)
4365       outs() << format(" %.*s", left, name);
4366     outs() << "\n";
4367 
4368     outs() << indent << "\t\t     types " << format("0x%" PRIx32, m.types);
4369     name = get_pointer_32(m.types, xoffset, left, xS, info);
4370     if (name != nullptr)
4371       outs() << format(" %.*s", left, name);
4372     outs() << "\n";
4373 
4374     outs() << indent << "\t\t       imp " << format("0x%" PRIx32, m.imp);
4375     name = get_symbol_32(offset + offsetof(struct method32_t, imp), S, info,
4376                          m.imp);
4377     if (name != nullptr)
4378       outs() << " " << name;
4379     outs() << "\n";
4380 
4381     p += sizeof(struct method32_t);
4382     offset += sizeof(struct method32_t);
4383   }
4384 }
4385 
4386 static bool print_method_list(uint32_t p, struct DisassembleInfo *info) {
4387   uint32_t offset, left, xleft;
4388   SectionRef S;
4389   struct objc_method_list_t method_list;
4390   struct objc_method_t method;
4391   const char *r, *methods, *name, *SymbolName;
4392   int32_t i;
4393 
4394   r = get_pointer_32(p, offset, left, S, info, true);
4395   if (r == nullptr)
4396     return true;
4397 
4398   outs() << "\n";
4399   if (left > sizeof(struct objc_method_list_t)) {
4400     memcpy(&method_list, r, sizeof(struct objc_method_list_t));
4401   } else {
4402     outs() << "\t\t objc_method_list extends past end of the section\n";
4403     memset(&method_list, '\0', sizeof(struct objc_method_list_t));
4404     memcpy(&method_list, r, left);
4405   }
4406   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4407     swapStruct(method_list);
4408 
4409   outs() << "\t\t         obsolete "
4410          << format("0x%08" PRIx32, method_list.obsolete) << "\n";
4411   outs() << "\t\t     method_count " << method_list.method_count << "\n";
4412 
4413   methods = r + sizeof(struct objc_method_list_t);
4414   for (i = 0; i < method_list.method_count; i++) {
4415     if ((i + 1) * sizeof(struct objc_method_t) > left) {
4416       outs() << "\t\t remaining method's extend past the of the section\n";
4417       break;
4418     }
4419     memcpy(&method, methods + i * sizeof(struct objc_method_t),
4420            sizeof(struct objc_method_t));
4421     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4422       swapStruct(method);
4423 
4424     outs() << "\t\t      method_name "
4425            << format("0x%08" PRIx32, method.method_name);
4426     if (info->verbose) {
4427       name = get_pointer_32(method.method_name, offset, xleft, S, info, true);
4428       if (name != nullptr)
4429         outs() << format(" %.*s", xleft, name);
4430       else
4431         outs() << " (not in an __OBJC section)";
4432     }
4433     outs() << "\n";
4434 
4435     outs() << "\t\t     method_types "
4436            << format("0x%08" PRIx32, method.method_types);
4437     if (info->verbose) {
4438       name = get_pointer_32(method.method_types, offset, xleft, S, info, true);
4439       if (name != nullptr)
4440         outs() << format(" %.*s", xleft, name);
4441       else
4442         outs() << " (not in an __OBJC section)";
4443     }
4444     outs() << "\n";
4445 
4446     outs() << "\t\t       method_imp "
4447            << format("0x%08" PRIx32, method.method_imp) << " ";
4448     if (info->verbose) {
4449       SymbolName = GuessSymbolName(method.method_imp, info->AddrMap);
4450       if (SymbolName != nullptr)
4451         outs() << SymbolName;
4452     }
4453     outs() << "\n";
4454   }
4455   return false;
4456 }
4457 
4458 static void print_protocol_list64_t(uint64_t p, struct DisassembleInfo *info) {
4459   struct protocol_list64_t pl;
4460   uint64_t q, n_value;
4461   struct protocol64_t pc;
4462   const char *r;
4463   uint32_t offset, xoffset, left, i;
4464   SectionRef S, xS;
4465   const char *name, *sym_name;
4466 
4467   r = get_pointer_64(p, offset, left, S, info);
4468   if (r == nullptr)
4469     return;
4470   memset(&pl, '\0', sizeof(struct protocol_list64_t));
4471   if (left < sizeof(struct protocol_list64_t)) {
4472     memcpy(&pl, r, left);
4473     outs() << "   (protocol_list_t entends past the end of the section)\n";
4474   } else
4475     memcpy(&pl, r, sizeof(struct protocol_list64_t));
4476   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4477     swapStruct(pl);
4478   outs() << "                      count " << pl.count << "\n";
4479 
4480   p += sizeof(struct protocol_list64_t);
4481   offset += sizeof(struct protocol_list64_t);
4482   for (i = 0; i < pl.count; i++) {
4483     r = get_pointer_64(p, offset, left, S, info);
4484     if (r == nullptr)
4485       return;
4486     q = 0;
4487     if (left < sizeof(uint64_t)) {
4488       memcpy(&q, r, left);
4489       outs() << "   (protocol_t * entends past the end of the section)\n";
4490     } else
4491       memcpy(&q, r, sizeof(uint64_t));
4492     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4493       sys::swapByteOrder(q);
4494 
4495     outs() << "\t\t      list[" << i << "] ";
4496     sym_name = get_symbol_64(offset, S, info, n_value, q);
4497     if (n_value != 0) {
4498       if (info->verbose && sym_name != nullptr)
4499         outs() << sym_name;
4500       else
4501         outs() << format("0x%" PRIx64, n_value);
4502       if (q != 0)
4503         outs() << " + " << format("0x%" PRIx64, q);
4504     } else
4505       outs() << format("0x%" PRIx64, q);
4506     outs() << " (struct protocol_t *)\n";
4507 
4508     r = get_pointer_64(q + n_value, offset, left, S, info);
4509     if (r == nullptr)
4510       return;
4511     memset(&pc, '\0', sizeof(struct protocol64_t));
4512     if (left < sizeof(struct protocol64_t)) {
4513       memcpy(&pc, r, left);
4514       outs() << "   (protocol_t entends past the end of the section)\n";
4515     } else
4516       memcpy(&pc, r, sizeof(struct protocol64_t));
4517     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4518       swapStruct(pc);
4519 
4520     outs() << "\t\t\t      isa " << format("0x%" PRIx64, pc.isa) << "\n";
4521 
4522     outs() << "\t\t\t     name ";
4523     sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, name), S,
4524                              info, n_value, pc.name);
4525     if (n_value != 0) {
4526       if (info->verbose && sym_name != nullptr)
4527         outs() << sym_name;
4528       else
4529         outs() << format("0x%" PRIx64, n_value);
4530       if (pc.name != 0)
4531         outs() << " + " << format("0x%" PRIx64, pc.name);
4532     } else
4533       outs() << format("0x%" PRIx64, pc.name);
4534     name = get_pointer_64(pc.name + n_value, xoffset, left, xS, info);
4535     if (name != nullptr)
4536       outs() << format(" %.*s", left, name);
4537     outs() << "\n";
4538 
4539     outs() << "\t\t\tprotocols " << format("0x%" PRIx64, pc.protocols) << "\n";
4540 
4541     outs() << "\t\t  instanceMethods ";
4542     sym_name =
4543         get_symbol_64(offset + offsetof(struct protocol64_t, instanceMethods),
4544                       S, info, n_value, pc.instanceMethods);
4545     if (n_value != 0) {
4546       if (info->verbose && sym_name != nullptr)
4547         outs() << sym_name;
4548       else
4549         outs() << format("0x%" PRIx64, n_value);
4550       if (pc.instanceMethods != 0)
4551         outs() << " + " << format("0x%" PRIx64, pc.instanceMethods);
4552     } else
4553       outs() << format("0x%" PRIx64, pc.instanceMethods);
4554     outs() << " (struct method_list_t *)\n";
4555     if (pc.instanceMethods + n_value != 0)
4556       print_method_list64_t(pc.instanceMethods + n_value, info, "\t");
4557 
4558     outs() << "\t\t     classMethods ";
4559     sym_name =
4560         get_symbol_64(offset + offsetof(struct protocol64_t, classMethods), S,
4561                       info, n_value, pc.classMethods);
4562     if (n_value != 0) {
4563       if (info->verbose && sym_name != nullptr)
4564         outs() << sym_name;
4565       else
4566         outs() << format("0x%" PRIx64, n_value);
4567       if (pc.classMethods != 0)
4568         outs() << " + " << format("0x%" PRIx64, pc.classMethods);
4569     } else
4570       outs() << format("0x%" PRIx64, pc.classMethods);
4571     outs() << " (struct method_list_t *)\n";
4572     if (pc.classMethods + n_value != 0)
4573       print_method_list64_t(pc.classMethods + n_value, info, "\t");
4574 
4575     outs() << "\t  optionalInstanceMethods "
4576            << format("0x%" PRIx64, pc.optionalInstanceMethods) << "\n";
4577     outs() << "\t     optionalClassMethods "
4578            << format("0x%" PRIx64, pc.optionalClassMethods) << "\n";
4579     outs() << "\t       instanceProperties "
4580            << format("0x%" PRIx64, pc.instanceProperties) << "\n";
4581 
4582     p += sizeof(uint64_t);
4583     offset += sizeof(uint64_t);
4584   }
4585 }
4586 
4587 static void print_protocol_list32_t(uint32_t p, struct DisassembleInfo *info) {
4588   struct protocol_list32_t pl;
4589   uint32_t q;
4590   struct protocol32_t pc;
4591   const char *r;
4592   uint32_t offset, xoffset, left, i;
4593   SectionRef S, xS;
4594   const char *name;
4595 
4596   r = get_pointer_32(p, offset, left, S, info);
4597   if (r == nullptr)
4598     return;
4599   memset(&pl, '\0', sizeof(struct protocol_list32_t));
4600   if (left < sizeof(struct protocol_list32_t)) {
4601     memcpy(&pl, r, left);
4602     outs() << "   (protocol_list_t entends past the end of the section)\n";
4603   } else
4604     memcpy(&pl, r, sizeof(struct protocol_list32_t));
4605   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4606     swapStruct(pl);
4607   outs() << "                      count " << pl.count << "\n";
4608 
4609   p += sizeof(struct protocol_list32_t);
4610   offset += sizeof(struct protocol_list32_t);
4611   for (i = 0; i < pl.count; i++) {
4612     r = get_pointer_32(p, offset, left, S, info);
4613     if (r == nullptr)
4614       return;
4615     q = 0;
4616     if (left < sizeof(uint32_t)) {
4617       memcpy(&q, r, left);
4618       outs() << "   (protocol_t * entends past the end of the section)\n";
4619     } else
4620       memcpy(&q, r, sizeof(uint32_t));
4621     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4622       sys::swapByteOrder(q);
4623     outs() << "\t\t      list[" << i << "] " << format("0x%" PRIx32, q)
4624            << " (struct protocol_t *)\n";
4625     r = get_pointer_32(q, offset, left, S, info);
4626     if (r == nullptr)
4627       return;
4628     memset(&pc, '\0', sizeof(struct protocol32_t));
4629     if (left < sizeof(struct protocol32_t)) {
4630       memcpy(&pc, r, left);
4631       outs() << "   (protocol_t entends past the end of the section)\n";
4632     } else
4633       memcpy(&pc, r, sizeof(struct protocol32_t));
4634     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4635       swapStruct(pc);
4636     outs() << "\t\t\t      isa " << format("0x%" PRIx32, pc.isa) << "\n";
4637     outs() << "\t\t\t     name " << format("0x%" PRIx32, pc.name);
4638     name = get_pointer_32(pc.name, xoffset, left, xS, info);
4639     if (name != nullptr)
4640       outs() << format(" %.*s", left, name);
4641     outs() << "\n";
4642     outs() << "\t\t\tprotocols " << format("0x%" PRIx32, pc.protocols) << "\n";
4643     outs() << "\t\t  instanceMethods "
4644            << format("0x%" PRIx32, pc.instanceMethods)
4645            << " (struct method_list_t *)\n";
4646     if (pc.instanceMethods != 0)
4647       print_method_list32_t(pc.instanceMethods, info, "\t");
4648     outs() << "\t\t     classMethods " << format("0x%" PRIx32, pc.classMethods)
4649            << " (struct method_list_t *)\n";
4650     if (pc.classMethods != 0)
4651       print_method_list32_t(pc.classMethods, info, "\t");
4652     outs() << "\t  optionalInstanceMethods "
4653            << format("0x%" PRIx32, pc.optionalInstanceMethods) << "\n";
4654     outs() << "\t     optionalClassMethods "
4655            << format("0x%" PRIx32, pc.optionalClassMethods) << "\n";
4656     outs() << "\t       instanceProperties "
4657            << format("0x%" PRIx32, pc.instanceProperties) << "\n";
4658     p += sizeof(uint32_t);
4659     offset += sizeof(uint32_t);
4660   }
4661 }
4662 
4663 static void print_indent(uint32_t indent) {
4664   for (uint32_t i = 0; i < indent;) {
4665     if (indent - i >= 8) {
4666       outs() << "\t";
4667       i += 8;
4668     } else {
4669       for (uint32_t j = i; j < indent; j++)
4670         outs() << " ";
4671       return;
4672     }
4673   }
4674 }
4675 
4676 static bool print_method_description_list(uint32_t p, uint32_t indent,
4677                                           struct DisassembleInfo *info) {
4678   uint32_t offset, left, xleft;
4679   SectionRef S;
4680   struct objc_method_description_list_t mdl;
4681   struct objc_method_description_t md;
4682   const char *r, *list, *name;
4683   int32_t i;
4684 
4685   r = get_pointer_32(p, offset, left, S, info, true);
4686   if (r == nullptr)
4687     return true;
4688 
4689   outs() << "\n";
4690   if (left > sizeof(struct objc_method_description_list_t)) {
4691     memcpy(&mdl, r, sizeof(struct objc_method_description_list_t));
4692   } else {
4693     print_indent(indent);
4694     outs() << " objc_method_description_list extends past end of the section\n";
4695     memset(&mdl, '\0', sizeof(struct objc_method_description_list_t));
4696     memcpy(&mdl, r, left);
4697   }
4698   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4699     swapStruct(mdl);
4700 
4701   print_indent(indent);
4702   outs() << "        count " << mdl.count << "\n";
4703 
4704   list = r + sizeof(struct objc_method_description_list_t);
4705   for (i = 0; i < mdl.count; i++) {
4706     if ((i + 1) * sizeof(struct objc_method_description_t) > left) {
4707       print_indent(indent);
4708       outs() << " remaining list entries extend past the of the section\n";
4709       break;
4710     }
4711     print_indent(indent);
4712     outs() << "        list[" << i << "]\n";
4713     memcpy(&md, list + i * sizeof(struct objc_method_description_t),
4714            sizeof(struct objc_method_description_t));
4715     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4716       swapStruct(md);
4717 
4718     print_indent(indent);
4719     outs() << "             name " << format("0x%08" PRIx32, md.name);
4720     if (info->verbose) {
4721       name = get_pointer_32(md.name, offset, xleft, S, info, true);
4722       if (name != nullptr)
4723         outs() << format(" %.*s", xleft, name);
4724       else
4725         outs() << " (not in an __OBJC section)";
4726     }
4727     outs() << "\n";
4728 
4729     print_indent(indent);
4730     outs() << "            types " << format("0x%08" PRIx32, md.types);
4731     if (info->verbose) {
4732       name = get_pointer_32(md.types, offset, xleft, S, info, true);
4733       if (name != nullptr)
4734         outs() << format(" %.*s", xleft, name);
4735       else
4736         outs() << " (not in an __OBJC section)";
4737     }
4738     outs() << "\n";
4739   }
4740   return false;
4741 }
4742 
4743 static bool print_protocol_list(uint32_t p, uint32_t indent,
4744                                 struct DisassembleInfo *info);
4745 
4746 static bool print_protocol(uint32_t p, uint32_t indent,
4747                            struct DisassembleInfo *info) {
4748   uint32_t offset, left;
4749   SectionRef S;
4750   struct objc_protocol_t protocol;
4751   const char *r, *name;
4752 
4753   r = get_pointer_32(p, offset, left, S, info, true);
4754   if (r == nullptr)
4755     return true;
4756 
4757   outs() << "\n";
4758   if (left >= sizeof(struct objc_protocol_t)) {
4759     memcpy(&protocol, r, sizeof(struct objc_protocol_t));
4760   } else {
4761     print_indent(indent);
4762     outs() << "            Protocol extends past end of the section\n";
4763     memset(&protocol, '\0', sizeof(struct objc_protocol_t));
4764     memcpy(&protocol, r, left);
4765   }
4766   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4767     swapStruct(protocol);
4768 
4769   print_indent(indent);
4770   outs() << "              isa " << format("0x%08" PRIx32, protocol.isa)
4771          << "\n";
4772 
4773   print_indent(indent);
4774   outs() << "    protocol_name "
4775          << format("0x%08" PRIx32, protocol.protocol_name);
4776   if (info->verbose) {
4777     name = get_pointer_32(protocol.protocol_name, offset, left, S, info, true);
4778     if (name != nullptr)
4779       outs() << format(" %.*s", left, name);
4780     else
4781       outs() << " (not in an __OBJC section)";
4782   }
4783   outs() << "\n";
4784 
4785   print_indent(indent);
4786   outs() << "    protocol_list "
4787          << format("0x%08" PRIx32, protocol.protocol_list);
4788   if (print_protocol_list(protocol.protocol_list, indent + 4, info))
4789     outs() << " (not in an __OBJC section)\n";
4790 
4791   print_indent(indent);
4792   outs() << " instance_methods "
4793          << format("0x%08" PRIx32, protocol.instance_methods);
4794   if (print_method_description_list(protocol.instance_methods, indent, info))
4795     outs() << " (not in an __OBJC section)\n";
4796 
4797   print_indent(indent);
4798   outs() << "    class_methods "
4799          << format("0x%08" PRIx32, protocol.class_methods);
4800   if (print_method_description_list(protocol.class_methods, indent, info))
4801     outs() << " (not in an __OBJC section)\n";
4802 
4803   return false;
4804 }
4805 
4806 static bool print_protocol_list(uint32_t p, uint32_t indent,
4807                                 struct DisassembleInfo *info) {
4808   uint32_t offset, left, l;
4809   SectionRef S;
4810   struct objc_protocol_list_t protocol_list;
4811   const char *r, *list;
4812   int32_t i;
4813 
4814   r = get_pointer_32(p, offset, left, S, info, true);
4815   if (r == nullptr)
4816     return true;
4817 
4818   outs() << "\n";
4819   if (left > sizeof(struct objc_protocol_list_t)) {
4820     memcpy(&protocol_list, r, sizeof(struct objc_protocol_list_t));
4821   } else {
4822     outs() << "\t\t objc_protocol_list_t extends past end of the section\n";
4823     memset(&protocol_list, '\0', sizeof(struct objc_protocol_list_t));
4824     memcpy(&protocol_list, r, left);
4825   }
4826   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4827     swapStruct(protocol_list);
4828 
4829   print_indent(indent);
4830   outs() << "         next " << format("0x%08" PRIx32, protocol_list.next)
4831          << "\n";
4832   print_indent(indent);
4833   outs() << "        count " << protocol_list.count << "\n";
4834 
4835   list = r + sizeof(struct objc_protocol_list_t);
4836   for (i = 0; i < protocol_list.count; i++) {
4837     if ((i + 1) * sizeof(uint32_t) > left) {
4838       outs() << "\t\t remaining list entries extend past the of the section\n";
4839       break;
4840     }
4841     memcpy(&l, list + i * sizeof(uint32_t), sizeof(uint32_t));
4842     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4843       sys::swapByteOrder(l);
4844 
4845     print_indent(indent);
4846     outs() << "      list[" << i << "] " << format("0x%08" PRIx32, l);
4847     if (print_protocol(l, indent, info))
4848       outs() << "(not in an __OBJC section)\n";
4849   }
4850   return false;
4851 }
4852 
4853 static void print_ivar_list64_t(uint64_t p, struct DisassembleInfo *info) {
4854   struct ivar_list64_t il;
4855   struct ivar64_t i;
4856   const char *r;
4857   uint32_t offset, xoffset, left, j;
4858   SectionRef S, xS;
4859   const char *name, *sym_name, *ivar_offset_p;
4860   uint64_t ivar_offset, n_value;
4861 
4862   r = get_pointer_64(p, offset, left, S, info);
4863   if (r == nullptr)
4864     return;
4865   memset(&il, '\0', sizeof(struct ivar_list64_t));
4866   if (left < sizeof(struct ivar_list64_t)) {
4867     memcpy(&il, r, left);
4868     outs() << "   (ivar_list_t entends past the end of the section)\n";
4869   } else
4870     memcpy(&il, r, sizeof(struct ivar_list64_t));
4871   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4872     swapStruct(il);
4873   outs() << "                    entsize " << il.entsize << "\n";
4874   outs() << "                      count " << il.count << "\n";
4875 
4876   p += sizeof(struct ivar_list64_t);
4877   offset += sizeof(struct ivar_list64_t);
4878   for (j = 0; j < il.count; j++) {
4879     r = get_pointer_64(p, offset, left, S, info);
4880     if (r == nullptr)
4881       return;
4882     memset(&i, '\0', sizeof(struct ivar64_t));
4883     if (left < sizeof(struct ivar64_t)) {
4884       memcpy(&i, r, left);
4885       outs() << "   (ivar_t entends past the end of the section)\n";
4886     } else
4887       memcpy(&i, r, sizeof(struct ivar64_t));
4888     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4889       swapStruct(i);
4890 
4891     outs() << "\t\t\t   offset ";
4892     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, offset), S,
4893                              info, n_value, i.offset);
4894     if (n_value != 0) {
4895       if (info->verbose && sym_name != nullptr)
4896         outs() << sym_name;
4897       else
4898         outs() << format("0x%" PRIx64, n_value);
4899       if (i.offset != 0)
4900         outs() << " + " << format("0x%" PRIx64, i.offset);
4901     } else
4902       outs() << format("0x%" PRIx64, i.offset);
4903     ivar_offset_p = get_pointer_64(i.offset + n_value, xoffset, left, xS, info);
4904     if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
4905       memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
4906       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4907         sys::swapByteOrder(ivar_offset);
4908       outs() << " " << ivar_offset << "\n";
4909     } else
4910       outs() << "\n";
4911 
4912     outs() << "\t\t\t     name ";
4913     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, name), S, info,
4914                              n_value, i.name);
4915     if (n_value != 0) {
4916       if (info->verbose && sym_name != nullptr)
4917         outs() << sym_name;
4918       else
4919         outs() << format("0x%" PRIx64, n_value);
4920       if (i.name != 0)
4921         outs() << " + " << format("0x%" PRIx64, i.name);
4922     } else
4923       outs() << format("0x%" PRIx64, i.name);
4924     name = get_pointer_64(i.name + n_value, xoffset, left, xS, info);
4925     if (name != nullptr)
4926       outs() << format(" %.*s", left, name);
4927     outs() << "\n";
4928 
4929     outs() << "\t\t\t     type ";
4930     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, type), S, info,
4931                              n_value, i.name);
4932     name = get_pointer_64(i.type + n_value, xoffset, left, xS, info);
4933     if (n_value != 0) {
4934       if (info->verbose && sym_name != nullptr)
4935         outs() << sym_name;
4936       else
4937         outs() << format("0x%" PRIx64, n_value);
4938       if (i.type != 0)
4939         outs() << " + " << format("0x%" PRIx64, i.type);
4940     } else
4941       outs() << format("0x%" PRIx64, i.type);
4942     if (name != nullptr)
4943       outs() << format(" %.*s", left, name);
4944     outs() << "\n";
4945 
4946     outs() << "\t\t\talignment " << i.alignment << "\n";
4947     outs() << "\t\t\t     size " << i.size << "\n";
4948 
4949     p += sizeof(struct ivar64_t);
4950     offset += sizeof(struct ivar64_t);
4951   }
4952 }
4953 
4954 static void print_ivar_list32_t(uint32_t p, struct DisassembleInfo *info) {
4955   struct ivar_list32_t il;
4956   struct ivar32_t i;
4957   const char *r;
4958   uint32_t offset, xoffset, left, j;
4959   SectionRef S, xS;
4960   const char *name, *ivar_offset_p;
4961   uint32_t ivar_offset;
4962 
4963   r = get_pointer_32(p, offset, left, S, info);
4964   if (r == nullptr)
4965     return;
4966   memset(&il, '\0', sizeof(struct ivar_list32_t));
4967   if (left < sizeof(struct ivar_list32_t)) {
4968     memcpy(&il, r, left);
4969     outs() << "   (ivar_list_t entends past the end of the section)\n";
4970   } else
4971     memcpy(&il, r, sizeof(struct ivar_list32_t));
4972   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4973     swapStruct(il);
4974   outs() << "                    entsize " << il.entsize << "\n";
4975   outs() << "                      count " << il.count << "\n";
4976 
4977   p += sizeof(struct ivar_list32_t);
4978   offset += sizeof(struct ivar_list32_t);
4979   for (j = 0; j < il.count; j++) {
4980     r = get_pointer_32(p, offset, left, S, info);
4981     if (r == nullptr)
4982       return;
4983     memset(&i, '\0', sizeof(struct ivar32_t));
4984     if (left < sizeof(struct ivar32_t)) {
4985       memcpy(&i, r, left);
4986       outs() << "   (ivar_t entends past the end of the section)\n";
4987     } else
4988       memcpy(&i, r, sizeof(struct ivar32_t));
4989     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4990       swapStruct(i);
4991 
4992     outs() << "\t\t\t   offset " << format("0x%" PRIx32, i.offset);
4993     ivar_offset_p = get_pointer_32(i.offset, xoffset, left, xS, info);
4994     if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
4995       memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
4996       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4997         sys::swapByteOrder(ivar_offset);
4998       outs() << " " << ivar_offset << "\n";
4999     } else
5000       outs() << "\n";
5001 
5002     outs() << "\t\t\t     name " << format("0x%" PRIx32, i.name);
5003     name = get_pointer_32(i.name, xoffset, left, xS, info);
5004     if (name != nullptr)
5005       outs() << format(" %.*s", left, name);
5006     outs() << "\n";
5007 
5008     outs() << "\t\t\t     type " << format("0x%" PRIx32, i.type);
5009     name = get_pointer_32(i.type, xoffset, left, xS, info);
5010     if (name != nullptr)
5011       outs() << format(" %.*s", left, name);
5012     outs() << "\n";
5013 
5014     outs() << "\t\t\talignment " << i.alignment << "\n";
5015     outs() << "\t\t\t     size " << i.size << "\n";
5016 
5017     p += sizeof(struct ivar32_t);
5018     offset += sizeof(struct ivar32_t);
5019   }
5020 }
5021 
5022 static void print_objc_property_list64(uint64_t p,
5023                                        struct DisassembleInfo *info) {
5024   struct objc_property_list64 opl;
5025   struct objc_property64 op;
5026   const char *r;
5027   uint32_t offset, xoffset, left, j;
5028   SectionRef S, xS;
5029   const char *name, *sym_name;
5030   uint64_t n_value;
5031 
5032   r = get_pointer_64(p, offset, left, S, info);
5033   if (r == nullptr)
5034     return;
5035   memset(&opl, '\0', sizeof(struct objc_property_list64));
5036   if (left < sizeof(struct objc_property_list64)) {
5037     memcpy(&opl, r, left);
5038     outs() << "   (objc_property_list entends past the end of the section)\n";
5039   } else
5040     memcpy(&opl, r, sizeof(struct objc_property_list64));
5041   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5042     swapStruct(opl);
5043   outs() << "                    entsize " << opl.entsize << "\n";
5044   outs() << "                      count " << opl.count << "\n";
5045 
5046   p += sizeof(struct objc_property_list64);
5047   offset += sizeof(struct objc_property_list64);
5048   for (j = 0; j < opl.count; j++) {
5049     r = get_pointer_64(p, offset, left, S, info);
5050     if (r == nullptr)
5051       return;
5052     memset(&op, '\0', sizeof(struct objc_property64));
5053     if (left < sizeof(struct objc_property64)) {
5054       memcpy(&op, r, left);
5055       outs() << "   (objc_property entends past the end of the section)\n";
5056     } else
5057       memcpy(&op, r, sizeof(struct objc_property64));
5058     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5059       swapStruct(op);
5060 
5061     outs() << "\t\t\t     name ";
5062     sym_name = get_symbol_64(offset + offsetof(struct objc_property64, name), S,
5063                              info, n_value, op.name);
5064     if (n_value != 0) {
5065       if (info->verbose && sym_name != nullptr)
5066         outs() << sym_name;
5067       else
5068         outs() << format("0x%" PRIx64, n_value);
5069       if (op.name != 0)
5070         outs() << " + " << format("0x%" PRIx64, op.name);
5071     } else
5072       outs() << format("0x%" PRIx64, op.name);
5073     name = get_pointer_64(op.name + n_value, xoffset, left, xS, info);
5074     if (name != nullptr)
5075       outs() << format(" %.*s", left, name);
5076     outs() << "\n";
5077 
5078     outs() << "\t\t\tattributes ";
5079     sym_name =
5080         get_symbol_64(offset + offsetof(struct objc_property64, attributes), S,
5081                       info, n_value, op.attributes);
5082     if (n_value != 0) {
5083       if (info->verbose && sym_name != nullptr)
5084         outs() << sym_name;
5085       else
5086         outs() << format("0x%" PRIx64, n_value);
5087       if (op.attributes != 0)
5088         outs() << " + " << format("0x%" PRIx64, op.attributes);
5089     } else
5090       outs() << format("0x%" PRIx64, op.attributes);
5091     name = get_pointer_64(op.attributes + n_value, xoffset, left, xS, info);
5092     if (name != nullptr)
5093       outs() << format(" %.*s", left, name);
5094     outs() << "\n";
5095 
5096     p += sizeof(struct objc_property64);
5097     offset += sizeof(struct objc_property64);
5098   }
5099 }
5100 
5101 static void print_objc_property_list32(uint32_t p,
5102                                        struct DisassembleInfo *info) {
5103   struct objc_property_list32 opl;
5104   struct objc_property32 op;
5105   const char *r;
5106   uint32_t offset, xoffset, left, j;
5107   SectionRef S, xS;
5108   const char *name;
5109 
5110   r = get_pointer_32(p, offset, left, S, info);
5111   if (r == nullptr)
5112     return;
5113   memset(&opl, '\0', sizeof(struct objc_property_list32));
5114   if (left < sizeof(struct objc_property_list32)) {
5115     memcpy(&opl, r, left);
5116     outs() << "   (objc_property_list entends past the end of the section)\n";
5117   } else
5118     memcpy(&opl, r, sizeof(struct objc_property_list32));
5119   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5120     swapStruct(opl);
5121   outs() << "                    entsize " << opl.entsize << "\n";
5122   outs() << "                      count " << opl.count << "\n";
5123 
5124   p += sizeof(struct objc_property_list32);
5125   offset += sizeof(struct objc_property_list32);
5126   for (j = 0; j < opl.count; j++) {
5127     r = get_pointer_32(p, offset, left, S, info);
5128     if (r == nullptr)
5129       return;
5130     memset(&op, '\0', sizeof(struct objc_property32));
5131     if (left < sizeof(struct objc_property32)) {
5132       memcpy(&op, r, left);
5133       outs() << "   (objc_property entends past the end of the section)\n";
5134     } else
5135       memcpy(&op, r, sizeof(struct objc_property32));
5136     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5137       swapStruct(op);
5138 
5139     outs() << "\t\t\t     name " << format("0x%" PRIx32, op.name);
5140     name = get_pointer_32(op.name, xoffset, left, xS, info);
5141     if (name != nullptr)
5142       outs() << format(" %.*s", left, name);
5143     outs() << "\n";
5144 
5145     outs() << "\t\t\tattributes " << format("0x%" PRIx32, op.attributes);
5146     name = get_pointer_32(op.attributes, xoffset, left, xS, info);
5147     if (name != nullptr)
5148       outs() << format(" %.*s", left, name);
5149     outs() << "\n";
5150 
5151     p += sizeof(struct objc_property32);
5152     offset += sizeof(struct objc_property32);
5153   }
5154 }
5155 
5156 static bool print_class_ro64_t(uint64_t p, struct DisassembleInfo *info,
5157                                bool &is_meta_class) {
5158   struct class_ro64_t cro;
5159   const char *r;
5160   uint32_t offset, xoffset, left;
5161   SectionRef S, xS;
5162   const char *name, *sym_name;
5163   uint64_t n_value;
5164 
5165   r = get_pointer_64(p, offset, left, S, info);
5166   if (r == nullptr || left < sizeof(struct class_ro64_t))
5167     return false;
5168   memcpy(&cro, r, sizeof(struct class_ro64_t));
5169   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5170     swapStruct(cro);
5171   outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
5172   if (cro.flags & RO_META)
5173     outs() << " RO_META";
5174   if (cro.flags & RO_ROOT)
5175     outs() << " RO_ROOT";
5176   if (cro.flags & RO_HAS_CXX_STRUCTORS)
5177     outs() << " RO_HAS_CXX_STRUCTORS";
5178   outs() << "\n";
5179   outs() << "            instanceStart " << cro.instanceStart << "\n";
5180   outs() << "             instanceSize " << cro.instanceSize << "\n";
5181   outs() << "                 reserved " << format("0x%" PRIx32, cro.reserved)
5182          << "\n";
5183   outs() << "               ivarLayout " << format("0x%" PRIx64, cro.ivarLayout)
5184          << "\n";
5185   print_layout_map64(cro.ivarLayout, info);
5186 
5187   outs() << "                     name ";
5188   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, name), S,
5189                            info, n_value, cro.name);
5190   if (n_value != 0) {
5191     if (info->verbose && sym_name != nullptr)
5192       outs() << sym_name;
5193     else
5194       outs() << format("0x%" PRIx64, n_value);
5195     if (cro.name != 0)
5196       outs() << " + " << format("0x%" PRIx64, cro.name);
5197   } else
5198     outs() << format("0x%" PRIx64, cro.name);
5199   name = get_pointer_64(cro.name + n_value, xoffset, left, xS, info);
5200   if (name != nullptr)
5201     outs() << format(" %.*s", left, name);
5202   outs() << "\n";
5203 
5204   outs() << "              baseMethods ";
5205   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, baseMethods),
5206                            S, info, n_value, cro.baseMethods);
5207   if (n_value != 0) {
5208     if (info->verbose && sym_name != nullptr)
5209       outs() << sym_name;
5210     else
5211       outs() << format("0x%" PRIx64, n_value);
5212     if (cro.baseMethods != 0)
5213       outs() << " + " << format("0x%" PRIx64, cro.baseMethods);
5214   } else
5215     outs() << format("0x%" PRIx64, cro.baseMethods);
5216   outs() << " (struct method_list_t *)\n";
5217   if (cro.baseMethods + n_value != 0)
5218     print_method_list64_t(cro.baseMethods + n_value, info, "");
5219 
5220   outs() << "            baseProtocols ";
5221   sym_name =
5222       get_symbol_64(offset + offsetof(struct class_ro64_t, baseProtocols), S,
5223                     info, n_value, cro.baseProtocols);
5224   if (n_value != 0) {
5225     if (info->verbose && sym_name != nullptr)
5226       outs() << sym_name;
5227     else
5228       outs() << format("0x%" PRIx64, n_value);
5229     if (cro.baseProtocols != 0)
5230       outs() << " + " << format("0x%" PRIx64, cro.baseProtocols);
5231   } else
5232     outs() << format("0x%" PRIx64, cro.baseProtocols);
5233   outs() << "\n";
5234   if (cro.baseProtocols + n_value != 0)
5235     print_protocol_list64_t(cro.baseProtocols + n_value, info);
5236 
5237   outs() << "                    ivars ";
5238   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, ivars), S,
5239                            info, n_value, cro.ivars);
5240   if (n_value != 0) {
5241     if (info->verbose && sym_name != nullptr)
5242       outs() << sym_name;
5243     else
5244       outs() << format("0x%" PRIx64, n_value);
5245     if (cro.ivars != 0)
5246       outs() << " + " << format("0x%" PRIx64, cro.ivars);
5247   } else
5248     outs() << format("0x%" PRIx64, cro.ivars);
5249   outs() << "\n";
5250   if (cro.ivars + n_value != 0)
5251     print_ivar_list64_t(cro.ivars + n_value, info);
5252 
5253   outs() << "           weakIvarLayout ";
5254   sym_name =
5255       get_symbol_64(offset + offsetof(struct class_ro64_t, weakIvarLayout), S,
5256                     info, n_value, cro.weakIvarLayout);
5257   if (n_value != 0) {
5258     if (info->verbose && sym_name != nullptr)
5259       outs() << sym_name;
5260     else
5261       outs() << format("0x%" PRIx64, n_value);
5262     if (cro.weakIvarLayout != 0)
5263       outs() << " + " << format("0x%" PRIx64, cro.weakIvarLayout);
5264   } else
5265     outs() << format("0x%" PRIx64, cro.weakIvarLayout);
5266   outs() << "\n";
5267   print_layout_map64(cro.weakIvarLayout + n_value, info);
5268 
5269   outs() << "           baseProperties ";
5270   sym_name =
5271       get_symbol_64(offset + offsetof(struct class_ro64_t, baseProperties), S,
5272                     info, n_value, cro.baseProperties);
5273   if (n_value != 0) {
5274     if (info->verbose && sym_name != nullptr)
5275       outs() << sym_name;
5276     else
5277       outs() << format("0x%" PRIx64, n_value);
5278     if (cro.baseProperties != 0)
5279       outs() << " + " << format("0x%" PRIx64, cro.baseProperties);
5280   } else
5281     outs() << format("0x%" PRIx64, cro.baseProperties);
5282   outs() << "\n";
5283   if (cro.baseProperties + n_value != 0)
5284     print_objc_property_list64(cro.baseProperties + n_value, info);
5285 
5286   is_meta_class = (cro.flags & RO_META) != 0;
5287   return true;
5288 }
5289 
5290 static bool print_class_ro32_t(uint32_t p, struct DisassembleInfo *info,
5291                                bool &is_meta_class) {
5292   struct class_ro32_t cro;
5293   const char *r;
5294   uint32_t offset, xoffset, left;
5295   SectionRef S, xS;
5296   const char *name;
5297 
5298   r = get_pointer_32(p, offset, left, S, info);
5299   if (r == nullptr)
5300     return false;
5301   memset(&cro, '\0', sizeof(struct class_ro32_t));
5302   if (left < sizeof(struct class_ro32_t)) {
5303     memcpy(&cro, r, left);
5304     outs() << "   (class_ro_t entends past the end of the section)\n";
5305   } else
5306     memcpy(&cro, r, sizeof(struct class_ro32_t));
5307   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5308     swapStruct(cro);
5309   outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
5310   if (cro.flags & RO_META)
5311     outs() << " RO_META";
5312   if (cro.flags & RO_ROOT)
5313     outs() << " RO_ROOT";
5314   if (cro.flags & RO_HAS_CXX_STRUCTORS)
5315     outs() << " RO_HAS_CXX_STRUCTORS";
5316   outs() << "\n";
5317   outs() << "            instanceStart " << cro.instanceStart << "\n";
5318   outs() << "             instanceSize " << cro.instanceSize << "\n";
5319   outs() << "               ivarLayout " << format("0x%" PRIx32, cro.ivarLayout)
5320          << "\n";
5321   print_layout_map32(cro.ivarLayout, info);
5322 
5323   outs() << "                     name " << format("0x%" PRIx32, cro.name);
5324   name = get_pointer_32(cro.name, xoffset, left, xS, info);
5325   if (name != nullptr)
5326     outs() << format(" %.*s", left, name);
5327   outs() << "\n";
5328 
5329   outs() << "              baseMethods "
5330          << format("0x%" PRIx32, cro.baseMethods)
5331          << " (struct method_list_t *)\n";
5332   if (cro.baseMethods != 0)
5333     print_method_list32_t(cro.baseMethods, info, "");
5334 
5335   outs() << "            baseProtocols "
5336          << format("0x%" PRIx32, cro.baseProtocols) << "\n";
5337   if (cro.baseProtocols != 0)
5338     print_protocol_list32_t(cro.baseProtocols, info);
5339   outs() << "                    ivars " << format("0x%" PRIx32, cro.ivars)
5340          << "\n";
5341   if (cro.ivars != 0)
5342     print_ivar_list32_t(cro.ivars, info);
5343   outs() << "           weakIvarLayout "
5344          << format("0x%" PRIx32, cro.weakIvarLayout) << "\n";
5345   print_layout_map32(cro.weakIvarLayout, info);
5346   outs() << "           baseProperties "
5347          << format("0x%" PRIx32, cro.baseProperties) << "\n";
5348   if (cro.baseProperties != 0)
5349     print_objc_property_list32(cro.baseProperties, info);
5350   is_meta_class = (cro.flags & RO_META) != 0;
5351   return true;
5352 }
5353 
5354 static void print_class64_t(uint64_t p, struct DisassembleInfo *info) {
5355   struct class64_t c;
5356   const char *r;
5357   uint32_t offset, left;
5358   SectionRef S;
5359   const char *name;
5360   uint64_t isa_n_value, n_value;
5361 
5362   r = get_pointer_64(p, offset, left, S, info);
5363   if (r == nullptr || left < sizeof(struct class64_t))
5364     return;
5365   memcpy(&c, r, sizeof(struct class64_t));
5366   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5367     swapStruct(c);
5368 
5369   outs() << "           isa " << format("0x%" PRIx64, c.isa);
5370   name = get_symbol_64(offset + offsetof(struct class64_t, isa), S, info,
5371                        isa_n_value, c.isa);
5372   if (name != nullptr)
5373     outs() << " " << name;
5374   outs() << "\n";
5375 
5376   outs() << "    superclass " << format("0x%" PRIx64, c.superclass);
5377   name = get_symbol_64(offset + offsetof(struct class64_t, superclass), S, info,
5378                        n_value, c.superclass);
5379   if (name != nullptr)
5380     outs() << " " << name;
5381   else {
5382     name = get_dyld_bind_info_symbolname(S.getAddress() +
5383              offset + offsetof(struct class64_t, superclass), info);
5384     if (name != nullptr)
5385       outs() << " " << name;
5386   }
5387   outs() << "\n";
5388 
5389   outs() << "         cache " << format("0x%" PRIx64, c.cache);
5390   name = get_symbol_64(offset + offsetof(struct class64_t, cache), S, info,
5391                        n_value, c.cache);
5392   if (name != nullptr)
5393     outs() << " " << name;
5394   outs() << "\n";
5395 
5396   outs() << "        vtable " << format("0x%" PRIx64, c.vtable);
5397   name = get_symbol_64(offset + offsetof(struct class64_t, vtable), S, info,
5398                        n_value, c.vtable);
5399   if (name != nullptr)
5400     outs() << " " << name;
5401   outs() << "\n";
5402 
5403   name = get_symbol_64(offset + offsetof(struct class64_t, data), S, info,
5404                        n_value, c.data);
5405   outs() << "          data ";
5406   if (n_value != 0) {
5407     if (info->verbose && name != nullptr)
5408       outs() << name;
5409     else
5410       outs() << format("0x%" PRIx64, n_value);
5411     if (c.data != 0)
5412       outs() << " + " << format("0x%" PRIx64, c.data);
5413   } else
5414     outs() << format("0x%" PRIx64, c.data);
5415   outs() << " (struct class_ro_t *)";
5416 
5417   // This is a Swift class if some of the low bits of the pointer are set.
5418   if ((c.data + n_value) & 0x7)
5419     outs() << " Swift class";
5420   outs() << "\n";
5421   bool is_meta_class;
5422   if (!print_class_ro64_t((c.data + n_value) & ~0x7, info, is_meta_class))
5423     return;
5424 
5425   if (!is_meta_class &&
5426       c.isa + isa_n_value != p &&
5427       c.isa + isa_n_value != 0 &&
5428       info->depth < 100) {
5429       info->depth++;
5430       outs() << "Meta Class\n";
5431       print_class64_t(c.isa + isa_n_value, info);
5432   }
5433 }
5434 
5435 static void print_class32_t(uint32_t p, struct DisassembleInfo *info) {
5436   struct class32_t c;
5437   const char *r;
5438   uint32_t offset, left;
5439   SectionRef S;
5440   const char *name;
5441 
5442   r = get_pointer_32(p, offset, left, S, info);
5443   if (r == nullptr)
5444     return;
5445   memset(&c, '\0', sizeof(struct class32_t));
5446   if (left < sizeof(struct class32_t)) {
5447     memcpy(&c, r, left);
5448     outs() << "   (class_t entends past the end of the section)\n";
5449   } else
5450     memcpy(&c, r, sizeof(struct class32_t));
5451   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5452     swapStruct(c);
5453 
5454   outs() << "           isa " << format("0x%" PRIx32, c.isa);
5455   name =
5456       get_symbol_32(offset + offsetof(struct class32_t, isa), S, info, c.isa);
5457   if (name != nullptr)
5458     outs() << " " << name;
5459   outs() << "\n";
5460 
5461   outs() << "    superclass " << format("0x%" PRIx32, c.superclass);
5462   name = get_symbol_32(offset + offsetof(struct class32_t, superclass), S, info,
5463                        c.superclass);
5464   if (name != nullptr)
5465     outs() << " " << name;
5466   outs() << "\n";
5467 
5468   outs() << "         cache " << format("0x%" PRIx32, c.cache);
5469   name = get_symbol_32(offset + offsetof(struct class32_t, cache), S, info,
5470                        c.cache);
5471   if (name != nullptr)
5472     outs() << " " << name;
5473   outs() << "\n";
5474 
5475   outs() << "        vtable " << format("0x%" PRIx32, c.vtable);
5476   name = get_symbol_32(offset + offsetof(struct class32_t, vtable), S, info,
5477                        c.vtable);
5478   if (name != nullptr)
5479     outs() << " " << name;
5480   outs() << "\n";
5481 
5482   name =
5483       get_symbol_32(offset + offsetof(struct class32_t, data), S, info, c.data);
5484   outs() << "          data " << format("0x%" PRIx32, c.data)
5485          << " (struct class_ro_t *)";
5486 
5487   // This is a Swift class if some of the low bits of the pointer are set.
5488   if (c.data & 0x3)
5489     outs() << " Swift class";
5490   outs() << "\n";
5491   bool is_meta_class;
5492   if (!print_class_ro32_t(c.data & ~0x3, info, is_meta_class))
5493     return;
5494 
5495   if (!is_meta_class) {
5496     outs() << "Meta Class\n";
5497     print_class32_t(c.isa, info);
5498   }
5499 }
5500 
5501 static void print_objc_class_t(struct objc_class_t *objc_class,
5502                                struct DisassembleInfo *info) {
5503   uint32_t offset, left, xleft;
5504   const char *name, *p, *ivar_list;
5505   SectionRef S;
5506   int32_t i;
5507   struct objc_ivar_list_t objc_ivar_list;
5508   struct objc_ivar_t ivar;
5509 
5510   outs() << "\t\t      isa " << format("0x%08" PRIx32, objc_class->isa);
5511   if (info->verbose && CLS_GETINFO(objc_class, CLS_META)) {
5512     name = get_pointer_32(objc_class->isa, offset, left, S, info, true);
5513     if (name != nullptr)
5514       outs() << format(" %.*s", left, name);
5515     else
5516       outs() << " (not in an __OBJC section)";
5517   }
5518   outs() << "\n";
5519 
5520   outs() << "\t      super_class "
5521          << format("0x%08" PRIx32, objc_class->super_class);
5522   if (info->verbose) {
5523     name = get_pointer_32(objc_class->super_class, offset, left, S, info, true);
5524     if (name != nullptr)
5525       outs() << format(" %.*s", left, name);
5526     else
5527       outs() << " (not in an __OBJC section)";
5528   }
5529   outs() << "\n";
5530 
5531   outs() << "\t\t     name " << format("0x%08" PRIx32, objc_class->name);
5532   if (info->verbose) {
5533     name = get_pointer_32(objc_class->name, offset, left, S, info, true);
5534     if (name != nullptr)
5535       outs() << format(" %.*s", left, name);
5536     else
5537       outs() << " (not in an __OBJC section)";
5538   }
5539   outs() << "\n";
5540 
5541   outs() << "\t\t  version " << format("0x%08" PRIx32, objc_class->version)
5542          << "\n";
5543 
5544   outs() << "\t\t     info " << format("0x%08" PRIx32, objc_class->info);
5545   if (info->verbose) {
5546     if (CLS_GETINFO(objc_class, CLS_CLASS))
5547       outs() << " CLS_CLASS";
5548     else if (CLS_GETINFO(objc_class, CLS_META))
5549       outs() << " CLS_META";
5550   }
5551   outs() << "\n";
5552 
5553   outs() << "\t    instance_size "
5554          << format("0x%08" PRIx32, objc_class->instance_size) << "\n";
5555 
5556   p = get_pointer_32(objc_class->ivars, offset, left, S, info, true);
5557   outs() << "\t\t    ivars " << format("0x%08" PRIx32, objc_class->ivars);
5558   if (p != nullptr) {
5559     if (left > sizeof(struct objc_ivar_list_t)) {
5560       outs() << "\n";
5561       memcpy(&objc_ivar_list, p, sizeof(struct objc_ivar_list_t));
5562     } else {
5563       outs() << " (entends past the end of the section)\n";
5564       memset(&objc_ivar_list, '\0', sizeof(struct objc_ivar_list_t));
5565       memcpy(&objc_ivar_list, p, left);
5566     }
5567     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5568       swapStruct(objc_ivar_list);
5569     outs() << "\t\t       ivar_count " << objc_ivar_list.ivar_count << "\n";
5570     ivar_list = p + sizeof(struct objc_ivar_list_t);
5571     for (i = 0; i < objc_ivar_list.ivar_count; i++) {
5572       if ((i + 1) * sizeof(struct objc_ivar_t) > left) {
5573         outs() << "\t\t remaining ivar's extend past the of the section\n";
5574         break;
5575       }
5576       memcpy(&ivar, ivar_list + i * sizeof(struct objc_ivar_t),
5577              sizeof(struct objc_ivar_t));
5578       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5579         swapStruct(ivar);
5580 
5581       outs() << "\t\t\tivar_name " << format("0x%08" PRIx32, ivar.ivar_name);
5582       if (info->verbose) {
5583         name = get_pointer_32(ivar.ivar_name, offset, xleft, S, info, true);
5584         if (name != nullptr)
5585           outs() << format(" %.*s", xleft, name);
5586         else
5587           outs() << " (not in an __OBJC section)";
5588       }
5589       outs() << "\n";
5590 
5591       outs() << "\t\t\tivar_type " << format("0x%08" PRIx32, ivar.ivar_type);
5592       if (info->verbose) {
5593         name = get_pointer_32(ivar.ivar_type, offset, xleft, S, info, true);
5594         if (name != nullptr)
5595           outs() << format(" %.*s", xleft, name);
5596         else
5597           outs() << " (not in an __OBJC section)";
5598       }
5599       outs() << "\n";
5600 
5601       outs() << "\t\t      ivar_offset "
5602              << format("0x%08" PRIx32, ivar.ivar_offset) << "\n";
5603     }
5604   } else {
5605     outs() << " (not in an __OBJC section)\n";
5606   }
5607 
5608   outs() << "\t\t  methods " << format("0x%08" PRIx32, objc_class->methodLists);
5609   if (print_method_list(objc_class->methodLists, info))
5610     outs() << " (not in an __OBJC section)\n";
5611 
5612   outs() << "\t\t    cache " << format("0x%08" PRIx32, objc_class->cache)
5613          << "\n";
5614 
5615   outs() << "\t\tprotocols " << format("0x%08" PRIx32, objc_class->protocols);
5616   if (print_protocol_list(objc_class->protocols, 16, info))
5617     outs() << " (not in an __OBJC section)\n";
5618 }
5619 
5620 static void print_objc_objc_category_t(struct objc_category_t *objc_category,
5621                                        struct DisassembleInfo *info) {
5622   uint32_t offset, left;
5623   const char *name;
5624   SectionRef S;
5625 
5626   outs() << "\t       category name "
5627          << format("0x%08" PRIx32, objc_category->category_name);
5628   if (info->verbose) {
5629     name = get_pointer_32(objc_category->category_name, offset, left, S, info,
5630                           true);
5631     if (name != nullptr)
5632       outs() << format(" %.*s", left, name);
5633     else
5634       outs() << " (not in an __OBJC section)";
5635   }
5636   outs() << "\n";
5637 
5638   outs() << "\t\t  class name "
5639          << format("0x%08" PRIx32, objc_category->class_name);
5640   if (info->verbose) {
5641     name =
5642         get_pointer_32(objc_category->class_name, offset, left, S, info, true);
5643     if (name != nullptr)
5644       outs() << format(" %.*s", left, name);
5645     else
5646       outs() << " (not in an __OBJC section)";
5647   }
5648   outs() << "\n";
5649 
5650   outs() << "\t    instance methods "
5651          << format("0x%08" PRIx32, objc_category->instance_methods);
5652   if (print_method_list(objc_category->instance_methods, info))
5653     outs() << " (not in an __OBJC section)\n";
5654 
5655   outs() << "\t       class methods "
5656          << format("0x%08" PRIx32, objc_category->class_methods);
5657   if (print_method_list(objc_category->class_methods, info))
5658     outs() << " (not in an __OBJC section)\n";
5659 }
5660 
5661 static void print_category64_t(uint64_t p, struct DisassembleInfo *info) {
5662   struct category64_t c;
5663   const char *r;
5664   uint32_t offset, xoffset, left;
5665   SectionRef S, xS;
5666   const char *name, *sym_name;
5667   uint64_t n_value;
5668 
5669   r = get_pointer_64(p, offset, left, S, info);
5670   if (r == nullptr)
5671     return;
5672   memset(&c, '\0', sizeof(struct category64_t));
5673   if (left < sizeof(struct category64_t)) {
5674     memcpy(&c, r, left);
5675     outs() << "   (category_t entends past the end of the section)\n";
5676   } else
5677     memcpy(&c, r, sizeof(struct category64_t));
5678   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5679     swapStruct(c);
5680 
5681   outs() << "              name ";
5682   sym_name = get_symbol_64(offset + offsetof(struct category64_t, name), S,
5683                            info, n_value, c.name);
5684   if (n_value != 0) {
5685     if (info->verbose && sym_name != nullptr)
5686       outs() << sym_name;
5687     else
5688       outs() << format("0x%" PRIx64, n_value);
5689     if (c.name != 0)
5690       outs() << " + " << format("0x%" PRIx64, c.name);
5691   } else
5692     outs() << format("0x%" PRIx64, c.name);
5693   name = get_pointer_64(c.name + n_value, xoffset, left, xS, info);
5694   if (name != nullptr)
5695     outs() << format(" %.*s", left, name);
5696   outs() << "\n";
5697 
5698   outs() << "               cls ";
5699   sym_name = get_symbol_64(offset + offsetof(struct category64_t, cls), S, info,
5700                            n_value, c.cls);
5701   if (n_value != 0) {
5702     if (info->verbose && sym_name != nullptr)
5703       outs() << sym_name;
5704     else
5705       outs() << format("0x%" PRIx64, n_value);
5706     if (c.cls != 0)
5707       outs() << " + " << format("0x%" PRIx64, c.cls);
5708   } else
5709     outs() << format("0x%" PRIx64, c.cls);
5710   outs() << "\n";
5711   if (c.cls + n_value != 0)
5712     print_class64_t(c.cls + n_value, info);
5713 
5714   outs() << "   instanceMethods ";
5715   sym_name =
5716       get_symbol_64(offset + offsetof(struct category64_t, instanceMethods), S,
5717                     info, n_value, c.instanceMethods);
5718   if (n_value != 0) {
5719     if (info->verbose && sym_name != nullptr)
5720       outs() << sym_name;
5721     else
5722       outs() << format("0x%" PRIx64, n_value);
5723     if (c.instanceMethods != 0)
5724       outs() << " + " << format("0x%" PRIx64, c.instanceMethods);
5725   } else
5726     outs() << format("0x%" PRIx64, c.instanceMethods);
5727   outs() << "\n";
5728   if (c.instanceMethods + n_value != 0)
5729     print_method_list64_t(c.instanceMethods + n_value, info, "");
5730 
5731   outs() << "      classMethods ";
5732   sym_name = get_symbol_64(offset + offsetof(struct category64_t, classMethods),
5733                            S, info, n_value, c.classMethods);
5734   if (n_value != 0) {
5735     if (info->verbose && sym_name != nullptr)
5736       outs() << sym_name;
5737     else
5738       outs() << format("0x%" PRIx64, n_value);
5739     if (c.classMethods != 0)
5740       outs() << " + " << format("0x%" PRIx64, c.classMethods);
5741   } else
5742     outs() << format("0x%" PRIx64, c.classMethods);
5743   outs() << "\n";
5744   if (c.classMethods + n_value != 0)
5745     print_method_list64_t(c.classMethods + n_value, info, "");
5746 
5747   outs() << "         protocols ";
5748   sym_name = get_symbol_64(offset + offsetof(struct category64_t, protocols), S,
5749                            info, n_value, c.protocols);
5750   if (n_value != 0) {
5751     if (info->verbose && sym_name != nullptr)
5752       outs() << sym_name;
5753     else
5754       outs() << format("0x%" PRIx64, n_value);
5755     if (c.protocols != 0)
5756       outs() << " + " << format("0x%" PRIx64, c.protocols);
5757   } else
5758     outs() << format("0x%" PRIx64, c.protocols);
5759   outs() << "\n";
5760   if (c.protocols + n_value != 0)
5761     print_protocol_list64_t(c.protocols + n_value, info);
5762 
5763   outs() << "instanceProperties ";
5764   sym_name =
5765       get_symbol_64(offset + offsetof(struct category64_t, instanceProperties),
5766                     S, info, n_value, c.instanceProperties);
5767   if (n_value != 0) {
5768     if (info->verbose && sym_name != nullptr)
5769       outs() << sym_name;
5770     else
5771       outs() << format("0x%" PRIx64, n_value);
5772     if (c.instanceProperties != 0)
5773       outs() << " + " << format("0x%" PRIx64, c.instanceProperties);
5774   } else
5775     outs() << format("0x%" PRIx64, c.instanceProperties);
5776   outs() << "\n";
5777   if (c.instanceProperties + n_value != 0)
5778     print_objc_property_list64(c.instanceProperties + n_value, info);
5779 }
5780 
5781 static void print_category32_t(uint32_t p, struct DisassembleInfo *info) {
5782   struct category32_t c;
5783   const char *r;
5784   uint32_t offset, left;
5785   SectionRef S, xS;
5786   const char *name;
5787 
5788   r = get_pointer_32(p, offset, left, S, info);
5789   if (r == nullptr)
5790     return;
5791   memset(&c, '\0', sizeof(struct category32_t));
5792   if (left < sizeof(struct category32_t)) {
5793     memcpy(&c, r, left);
5794     outs() << "   (category_t entends past the end of the section)\n";
5795   } else
5796     memcpy(&c, r, sizeof(struct category32_t));
5797   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5798     swapStruct(c);
5799 
5800   outs() << "              name " << format("0x%" PRIx32, c.name);
5801   name = get_symbol_32(offset + offsetof(struct category32_t, name), S, info,
5802                        c.name);
5803   if (name)
5804     outs() << " " << name;
5805   outs() << "\n";
5806 
5807   outs() << "               cls " << format("0x%" PRIx32, c.cls) << "\n";
5808   if (c.cls != 0)
5809     print_class32_t(c.cls, info);
5810   outs() << "   instanceMethods " << format("0x%" PRIx32, c.instanceMethods)
5811          << "\n";
5812   if (c.instanceMethods != 0)
5813     print_method_list32_t(c.instanceMethods, info, "");
5814   outs() << "      classMethods " << format("0x%" PRIx32, c.classMethods)
5815          << "\n";
5816   if (c.classMethods != 0)
5817     print_method_list32_t(c.classMethods, info, "");
5818   outs() << "         protocols " << format("0x%" PRIx32, c.protocols) << "\n";
5819   if (c.protocols != 0)
5820     print_protocol_list32_t(c.protocols, info);
5821   outs() << "instanceProperties " << format("0x%" PRIx32, c.instanceProperties)
5822          << "\n";
5823   if (c.instanceProperties != 0)
5824     print_objc_property_list32(c.instanceProperties, info);
5825 }
5826 
5827 static void print_message_refs64(SectionRef S, struct DisassembleInfo *info) {
5828   uint32_t i, left, offset, xoffset;
5829   uint64_t p, n_value;
5830   struct message_ref64 mr;
5831   const char *name, *sym_name;
5832   const char *r;
5833   SectionRef xS;
5834 
5835   if (S == SectionRef())
5836     return;
5837 
5838   StringRef SectName;
5839   Expected<StringRef> SecNameOrErr = S.getName();
5840   if (SecNameOrErr)
5841     SectName = *SecNameOrErr;
5842   else
5843     consumeError(SecNameOrErr.takeError());
5844 
5845   DataRefImpl Ref = S.getRawDataRefImpl();
5846   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5847   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5848   offset = 0;
5849   for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
5850     p = S.getAddress() + i;
5851     r = get_pointer_64(p, offset, left, S, info);
5852     if (r == nullptr)
5853       return;
5854     memset(&mr, '\0', sizeof(struct message_ref64));
5855     if (left < sizeof(struct message_ref64)) {
5856       memcpy(&mr, r, left);
5857       outs() << "   (message_ref entends past the end of the section)\n";
5858     } else
5859       memcpy(&mr, r, sizeof(struct message_ref64));
5860     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5861       swapStruct(mr);
5862 
5863     outs() << "  imp ";
5864     name = get_symbol_64(offset + offsetof(struct message_ref64, imp), S, info,
5865                          n_value, mr.imp);
5866     if (n_value != 0) {
5867       outs() << format("0x%" PRIx64, n_value) << " ";
5868       if (mr.imp != 0)
5869         outs() << "+ " << format("0x%" PRIx64, mr.imp) << " ";
5870     } else
5871       outs() << format("0x%" PRIx64, mr.imp) << " ";
5872     if (name != nullptr)
5873       outs() << " " << name;
5874     outs() << "\n";
5875 
5876     outs() << "  sel ";
5877     sym_name = get_symbol_64(offset + offsetof(struct message_ref64, sel), S,
5878                              info, n_value, mr.sel);
5879     if (n_value != 0) {
5880       if (info->verbose && sym_name != nullptr)
5881         outs() << sym_name;
5882       else
5883         outs() << format("0x%" PRIx64, n_value);
5884       if (mr.sel != 0)
5885         outs() << " + " << format("0x%" PRIx64, mr.sel);
5886     } else
5887       outs() << format("0x%" PRIx64, mr.sel);
5888     name = get_pointer_64(mr.sel + n_value, xoffset, left, xS, info);
5889     if (name != nullptr)
5890       outs() << format(" %.*s", left, name);
5891     outs() << "\n";
5892 
5893     offset += sizeof(struct message_ref64);
5894   }
5895 }
5896 
5897 static void print_message_refs32(SectionRef S, struct DisassembleInfo *info) {
5898   uint32_t i, left, offset, xoffset, p;
5899   struct message_ref32 mr;
5900   const char *name, *r;
5901   SectionRef xS;
5902 
5903   if (S == SectionRef())
5904     return;
5905 
5906   StringRef SectName;
5907   Expected<StringRef> SecNameOrErr = S.getName();
5908   if (SecNameOrErr)
5909     SectName = *SecNameOrErr;
5910   else
5911     consumeError(SecNameOrErr.takeError());
5912 
5913   DataRefImpl Ref = S.getRawDataRefImpl();
5914   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5915   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5916   offset = 0;
5917   for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
5918     p = S.getAddress() + i;
5919     r = get_pointer_32(p, offset, left, S, info);
5920     if (r == nullptr)
5921       return;
5922     memset(&mr, '\0', sizeof(struct message_ref32));
5923     if (left < sizeof(struct message_ref32)) {
5924       memcpy(&mr, r, left);
5925       outs() << "   (message_ref entends past the end of the section)\n";
5926     } else
5927       memcpy(&mr, r, sizeof(struct message_ref32));
5928     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5929       swapStruct(mr);
5930 
5931     outs() << "  imp " << format("0x%" PRIx32, mr.imp);
5932     name = get_symbol_32(offset + offsetof(struct message_ref32, imp), S, info,
5933                          mr.imp);
5934     if (name != nullptr)
5935       outs() << " " << name;
5936     outs() << "\n";
5937 
5938     outs() << "  sel " << format("0x%" PRIx32, mr.sel);
5939     name = get_pointer_32(mr.sel, xoffset, left, xS, info);
5940     if (name != nullptr)
5941       outs() << " " << name;
5942     outs() << "\n";
5943 
5944     offset += sizeof(struct message_ref32);
5945   }
5946 }
5947 
5948 static void print_image_info64(SectionRef S, struct DisassembleInfo *info) {
5949   uint32_t left, offset, swift_version;
5950   uint64_t p;
5951   struct objc_image_info64 o;
5952   const char *r;
5953 
5954   if (S == SectionRef())
5955     return;
5956 
5957   StringRef SectName;
5958   Expected<StringRef> SecNameOrErr = S.getName();
5959   if (SecNameOrErr)
5960     SectName = *SecNameOrErr;
5961   else
5962     consumeError(SecNameOrErr.takeError());
5963 
5964   DataRefImpl Ref = S.getRawDataRefImpl();
5965   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5966   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5967   p = S.getAddress();
5968   r = get_pointer_64(p, offset, left, S, info);
5969   if (r == nullptr)
5970     return;
5971   memset(&o, '\0', sizeof(struct objc_image_info64));
5972   if (left < sizeof(struct objc_image_info64)) {
5973     memcpy(&o, r, left);
5974     outs() << "   (objc_image_info entends past the end of the section)\n";
5975   } else
5976     memcpy(&o, r, sizeof(struct objc_image_info64));
5977   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5978     swapStruct(o);
5979   outs() << "  version " << o.version << "\n";
5980   outs() << "    flags " << format("0x%" PRIx32, o.flags);
5981   if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
5982     outs() << " OBJC_IMAGE_IS_REPLACEMENT";
5983   if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
5984     outs() << " OBJC_IMAGE_SUPPORTS_GC";
5985   if (o.flags & OBJC_IMAGE_IS_SIMULATED)
5986     outs() << " OBJC_IMAGE_IS_SIMULATED";
5987   if (o.flags & OBJC_IMAGE_HAS_CATEGORY_CLASS_PROPERTIES)
5988     outs() << " OBJC_IMAGE_HAS_CATEGORY_CLASS_PROPERTIES";
5989   swift_version = (o.flags >> 8) & 0xff;
5990   if (swift_version != 0) {
5991     if (swift_version == 1)
5992       outs() << " Swift 1.0";
5993     else if (swift_version == 2)
5994       outs() << " Swift 1.1";
5995     else if(swift_version == 3)
5996       outs() << " Swift 2.0";
5997     else if(swift_version == 4)
5998       outs() << " Swift 3.0";
5999     else if(swift_version == 5)
6000       outs() << " Swift 4.0";
6001     else if(swift_version == 6)
6002       outs() << " Swift 4.1/Swift 4.2";
6003     else if(swift_version == 7)
6004       outs() << " Swift 5 or later";
6005     else
6006       outs() << " unknown future Swift version (" << swift_version << ")";
6007   }
6008   outs() << "\n";
6009 }
6010 
6011 static void print_image_info32(SectionRef S, struct DisassembleInfo *info) {
6012   uint32_t left, offset, swift_version, p;
6013   struct objc_image_info32 o;
6014   const char *r;
6015 
6016   if (S == SectionRef())
6017     return;
6018 
6019   StringRef SectName;
6020   Expected<StringRef> SecNameOrErr = S.getName();
6021   if (SecNameOrErr)
6022     SectName = *SecNameOrErr;
6023   else
6024     consumeError(SecNameOrErr.takeError());
6025 
6026   DataRefImpl Ref = S.getRawDataRefImpl();
6027   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
6028   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
6029   p = S.getAddress();
6030   r = get_pointer_32(p, offset, left, S, info);
6031   if (r == nullptr)
6032     return;
6033   memset(&o, '\0', sizeof(struct objc_image_info32));
6034   if (left < sizeof(struct objc_image_info32)) {
6035     memcpy(&o, r, left);
6036     outs() << "   (objc_image_info entends past the end of the section)\n";
6037   } else
6038     memcpy(&o, r, sizeof(struct objc_image_info32));
6039   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
6040     swapStruct(o);
6041   outs() << "  version " << o.version << "\n";
6042   outs() << "    flags " << format("0x%" PRIx32, o.flags);
6043   if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
6044     outs() << " OBJC_IMAGE_IS_REPLACEMENT";
6045   if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
6046     outs() << " OBJC_IMAGE_SUPPORTS_GC";
6047   swift_version = (o.flags >> 8) & 0xff;
6048   if (swift_version != 0) {
6049     if (swift_version == 1)
6050       outs() << " Swift 1.0";
6051     else if (swift_version == 2)
6052       outs() << " Swift 1.1";
6053     else if(swift_version == 3)
6054       outs() << " Swift 2.0";
6055     else if(swift_version == 4)
6056       outs() << " Swift 3.0";
6057     else if(swift_version == 5)
6058       outs() << " Swift 4.0";
6059     else if(swift_version == 6)
6060       outs() << " Swift 4.1/Swift 4.2";
6061     else if(swift_version == 7)
6062       outs() << " Swift 5 or later";
6063     else
6064       outs() << " unknown future Swift version (" << swift_version << ")";
6065   }
6066   outs() << "\n";
6067 }
6068 
6069 static void print_image_info(SectionRef S, struct DisassembleInfo *info) {
6070   uint32_t left, offset, p;
6071   struct imageInfo_t o;
6072   const char *r;
6073 
6074   StringRef SectName;
6075   Expected<StringRef> SecNameOrErr = S.getName();
6076   if (SecNameOrErr)
6077     SectName = *SecNameOrErr;
6078   else
6079     consumeError(SecNameOrErr.takeError());
6080 
6081   DataRefImpl Ref = S.getRawDataRefImpl();
6082   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
6083   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
6084   p = S.getAddress();
6085   r = get_pointer_32(p, offset, left, S, info);
6086   if (r == nullptr)
6087     return;
6088   memset(&o, '\0', sizeof(struct imageInfo_t));
6089   if (left < sizeof(struct imageInfo_t)) {
6090     memcpy(&o, r, left);
6091     outs() << " (imageInfo entends past the end of the section)\n";
6092   } else
6093     memcpy(&o, r, sizeof(struct imageInfo_t));
6094   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
6095     swapStruct(o);
6096   outs() << "  version " << o.version << "\n";
6097   outs() << "    flags " << format("0x%" PRIx32, o.flags);
6098   if (o.flags & 0x1)
6099     outs() << "  F&C";
6100   if (o.flags & 0x2)
6101     outs() << " GC";
6102   if (o.flags & 0x4)
6103     outs() << " GC-only";
6104   else
6105     outs() << " RR";
6106   outs() << "\n";
6107 }
6108 
6109 static void printObjc2_64bit_MetaData(MachOObjectFile *O, bool verbose) {
6110   SymbolAddressMap AddrMap;
6111   if (verbose)
6112     CreateSymbolAddressMap(O, &AddrMap);
6113 
6114   std::vector<SectionRef> Sections;
6115   for (const SectionRef &Section : O->sections())
6116     Sections.push_back(Section);
6117 
6118   struct DisassembleInfo info(O, &AddrMap, &Sections, verbose);
6119 
6120   SectionRef CL = get_section(O, "__OBJC2", "__class_list");
6121   if (CL == SectionRef())
6122     CL = get_section(O, "__DATA", "__objc_classlist");
6123   if (CL == SectionRef())
6124     CL = get_section(O, "__DATA_CONST", "__objc_classlist");
6125   if (CL == SectionRef())
6126     CL = get_section(O, "__DATA_DIRTY", "__objc_classlist");
6127   info.S = CL;
6128   walk_pointer_list_64("class", CL, O, &info, print_class64_t);
6129 
6130   SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
6131   if (CR == SectionRef())
6132     CR = get_section(O, "__DATA", "__objc_classrefs");
6133   if (CR == SectionRef())
6134     CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
6135   if (CR == SectionRef())
6136     CR = get_section(O, "__DATA_DIRTY", "__objc_classrefs");
6137   info.S = CR;
6138   walk_pointer_list_64("class refs", CR, O, &info, nullptr);
6139 
6140   SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
6141   if (SR == SectionRef())
6142     SR = get_section(O, "__DATA", "__objc_superrefs");
6143   if (SR == SectionRef())
6144     SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
6145   if (SR == SectionRef())
6146     SR = get_section(O, "__DATA_DIRTY", "__objc_superrefs");
6147   info.S = SR;
6148   walk_pointer_list_64("super refs", SR, O, &info, nullptr);
6149 
6150   SectionRef CA = get_section(O, "__OBJC2", "__category_list");
6151   if (CA == SectionRef())
6152     CA = get_section(O, "__DATA", "__objc_catlist");
6153   if (CA == SectionRef())
6154     CA = get_section(O, "__DATA_CONST", "__objc_catlist");
6155   if (CA == SectionRef())
6156     CA = get_section(O, "__DATA_DIRTY", "__objc_catlist");
6157   info.S = CA;
6158   walk_pointer_list_64("category", CA, O, &info, print_category64_t);
6159 
6160   SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
6161   if (PL == SectionRef())
6162     PL = get_section(O, "__DATA", "__objc_protolist");
6163   if (PL == SectionRef())
6164     PL = get_section(O, "__DATA_CONST", "__objc_protolist");
6165   if (PL == SectionRef())
6166     PL = get_section(O, "__DATA_DIRTY", "__objc_protolist");
6167   info.S = PL;
6168   walk_pointer_list_64("protocol", PL, O, &info, nullptr);
6169 
6170   SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
6171   if (MR == SectionRef())
6172     MR = get_section(O, "__DATA", "__objc_msgrefs");
6173   if (MR == SectionRef())
6174     MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
6175   if (MR == SectionRef())
6176     MR = get_section(O, "__DATA_DIRTY", "__objc_msgrefs");
6177   info.S = MR;
6178   print_message_refs64(MR, &info);
6179 
6180   SectionRef II = get_section(O, "__OBJC2", "__image_info");
6181   if (II == SectionRef())
6182     II = get_section(O, "__DATA", "__objc_imageinfo");
6183   if (II == SectionRef())
6184     II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
6185   if (II == SectionRef())
6186     II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
6187   info.S = II;
6188   print_image_info64(II, &info);
6189 }
6190 
6191 static void printObjc2_32bit_MetaData(MachOObjectFile *O, bool verbose) {
6192   SymbolAddressMap AddrMap;
6193   if (verbose)
6194     CreateSymbolAddressMap(O, &AddrMap);
6195 
6196   std::vector<SectionRef> Sections;
6197   for (const SectionRef &Section : O->sections())
6198     Sections.push_back(Section);
6199 
6200   struct DisassembleInfo info(O, &AddrMap, &Sections, verbose);
6201 
6202   SectionRef CL = get_section(O, "__OBJC2", "__class_list");
6203   if (CL == SectionRef())
6204     CL = get_section(O, "__DATA", "__objc_classlist");
6205   if (CL == SectionRef())
6206     CL = get_section(O, "__DATA_CONST", "__objc_classlist");
6207   if (CL == SectionRef())
6208     CL = get_section(O, "__DATA_DIRTY", "__objc_classlist");
6209   info.S = CL;
6210   walk_pointer_list_32("class", CL, O, &info, print_class32_t);
6211 
6212   SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
6213   if (CR == SectionRef())
6214     CR = get_section(O, "__DATA", "__objc_classrefs");
6215   if (CR == SectionRef())
6216     CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
6217   if (CR == SectionRef())
6218     CR = get_section(O, "__DATA_DIRTY", "__objc_classrefs");
6219   info.S = CR;
6220   walk_pointer_list_32("class refs", CR, O, &info, nullptr);
6221 
6222   SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
6223   if (SR == SectionRef())
6224     SR = get_section(O, "__DATA", "__objc_superrefs");
6225   if (SR == SectionRef())
6226     SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
6227   if (SR == SectionRef())
6228     SR = get_section(O, "__DATA_DIRTY", "__objc_superrefs");
6229   info.S = SR;
6230   walk_pointer_list_32("super refs", SR, O, &info, nullptr);
6231 
6232   SectionRef CA = get_section(O, "__OBJC2", "__category_list");
6233   if (CA == SectionRef())
6234     CA = get_section(O, "__DATA", "__objc_catlist");
6235   if (CA == SectionRef())
6236     CA = get_section(O, "__DATA_CONST", "__objc_catlist");
6237   if (CA == SectionRef())
6238     CA = get_section(O, "__DATA_DIRTY", "__objc_catlist");
6239   info.S = CA;
6240   walk_pointer_list_32("category", CA, O, &info, print_category32_t);
6241 
6242   SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
6243   if (PL == SectionRef())
6244     PL = get_section(O, "__DATA", "__objc_protolist");
6245   if (PL == SectionRef())
6246     PL = get_section(O, "__DATA_CONST", "__objc_protolist");
6247   if (PL == SectionRef())
6248     PL = get_section(O, "__DATA_DIRTY", "__objc_protolist");
6249   info.S = PL;
6250   walk_pointer_list_32("protocol", PL, O, &info, nullptr);
6251 
6252   SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
6253   if (MR == SectionRef())
6254     MR = get_section(O, "__DATA", "__objc_msgrefs");
6255   if (MR == SectionRef())
6256     MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
6257   if (MR == SectionRef())
6258     MR = get_section(O, "__DATA_DIRTY", "__objc_msgrefs");
6259   info.S = MR;
6260   print_message_refs32(MR, &info);
6261 
6262   SectionRef II = get_section(O, "__OBJC2", "__image_info");
6263   if (II == SectionRef())
6264     II = get_section(O, "__DATA", "__objc_imageinfo");
6265   if (II == SectionRef())
6266     II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
6267   if (II == SectionRef())
6268     II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
6269   info.S = II;
6270   print_image_info32(II, &info);
6271 }
6272 
6273 static bool printObjc1_32bit_MetaData(MachOObjectFile *O, bool verbose) {
6274   uint32_t i, j, p, offset, xoffset, left, defs_left, def;
6275   const char *r, *name, *defs;
6276   struct objc_module_t module;
6277   SectionRef S, xS;
6278   struct objc_symtab_t symtab;
6279   struct objc_class_t objc_class;
6280   struct objc_category_t objc_category;
6281 
6282   outs() << "Objective-C segment\n";
6283   S = get_section(O, "__OBJC", "__module_info");
6284   if (S == SectionRef())
6285     return false;
6286 
6287   SymbolAddressMap AddrMap;
6288   if (verbose)
6289     CreateSymbolAddressMap(O, &AddrMap);
6290 
6291   std::vector<SectionRef> Sections;
6292   for (const SectionRef &Section : O->sections())
6293     Sections.push_back(Section);
6294 
6295   struct DisassembleInfo info(O, &AddrMap, &Sections, verbose);
6296 
6297   for (i = 0; i < S.getSize(); i += sizeof(struct objc_module_t)) {
6298     p = S.getAddress() + i;
6299     r = get_pointer_32(p, offset, left, S, &info, true);
6300     if (r == nullptr)
6301       return true;
6302     memset(&module, '\0', sizeof(struct objc_module_t));
6303     if (left < sizeof(struct objc_module_t)) {
6304       memcpy(&module, r, left);
6305       outs() << "   (module extends past end of __module_info section)\n";
6306     } else
6307       memcpy(&module, r, sizeof(struct objc_module_t));
6308     if (O->isLittleEndian() != sys::IsLittleEndianHost)
6309       swapStruct(module);
6310 
6311     outs() << "Module " << format("0x%" PRIx32, p) << "\n";
6312     outs() << "    version " << module.version << "\n";
6313     outs() << "       size " << module.size << "\n";
6314     outs() << "       name ";
6315     name = get_pointer_32(module.name, xoffset, left, xS, &info, true);
6316     if (name != nullptr)
6317       outs() << format("%.*s", left, name);
6318     else
6319       outs() << format("0x%08" PRIx32, module.name)
6320              << "(not in an __OBJC section)";
6321     outs() << "\n";
6322 
6323     r = get_pointer_32(module.symtab, xoffset, left, xS, &info, true);
6324     if (module.symtab == 0 || r == nullptr) {
6325       outs() << "     symtab " << format("0x%08" PRIx32, module.symtab)
6326              << " (not in an __OBJC section)\n";
6327       continue;
6328     }
6329     outs() << "     symtab " << format("0x%08" PRIx32, module.symtab) << "\n";
6330     memset(&symtab, '\0', sizeof(struct objc_symtab_t));
6331     defs_left = 0;
6332     defs = nullptr;
6333     if (left < sizeof(struct objc_symtab_t)) {
6334       memcpy(&symtab, r, left);
6335       outs() << "\tsymtab extends past end of an __OBJC section)\n";
6336     } else {
6337       memcpy(&symtab, r, sizeof(struct objc_symtab_t));
6338       if (left > sizeof(struct objc_symtab_t)) {
6339         defs_left = left - sizeof(struct objc_symtab_t);
6340         defs = r + sizeof(struct objc_symtab_t);
6341       }
6342     }
6343     if (O->isLittleEndian() != sys::IsLittleEndianHost)
6344       swapStruct(symtab);
6345 
6346     outs() << "\tsel_ref_cnt " << symtab.sel_ref_cnt << "\n";
6347     r = get_pointer_32(symtab.refs, xoffset, left, xS, &info, true);
6348     outs() << "\trefs " << format("0x%08" PRIx32, symtab.refs);
6349     if (r == nullptr)
6350       outs() << " (not in an __OBJC section)";
6351     outs() << "\n";
6352     outs() << "\tcls_def_cnt " << symtab.cls_def_cnt << "\n";
6353     outs() << "\tcat_def_cnt " << symtab.cat_def_cnt << "\n";
6354     if (symtab.cls_def_cnt > 0)
6355       outs() << "\tClass Definitions\n";
6356     for (j = 0; j < symtab.cls_def_cnt; j++) {
6357       if ((j + 1) * sizeof(uint32_t) > defs_left) {
6358         outs() << "\t(remaining class defs entries entends past the end of the "
6359                << "section)\n";
6360         break;
6361       }
6362       memcpy(&def, defs + j * sizeof(uint32_t), sizeof(uint32_t));
6363       if (O->isLittleEndian() != sys::IsLittleEndianHost)
6364         sys::swapByteOrder(def);
6365 
6366       r = get_pointer_32(def, xoffset, left, xS, &info, true);
6367       outs() << "\tdefs[" << j << "] " << format("0x%08" PRIx32, def);
6368       if (r != nullptr) {
6369         if (left > sizeof(struct objc_class_t)) {
6370           outs() << "\n";
6371           memcpy(&objc_class, r, sizeof(struct objc_class_t));
6372         } else {
6373           outs() << " (entends past the end of the section)\n";
6374           memset(&objc_class, '\0', sizeof(struct objc_class_t));
6375           memcpy(&objc_class, r, left);
6376         }
6377         if (O->isLittleEndian() != sys::IsLittleEndianHost)
6378           swapStruct(objc_class);
6379         print_objc_class_t(&objc_class, &info);
6380       } else {
6381         outs() << "(not in an __OBJC section)\n";
6382       }
6383 
6384       if (CLS_GETINFO(&objc_class, CLS_CLASS)) {
6385         outs() << "\tMeta Class";
6386         r = get_pointer_32(objc_class.isa, xoffset, left, xS, &info, true);
6387         if (r != nullptr) {
6388           if (left > sizeof(struct objc_class_t)) {
6389             outs() << "\n";
6390             memcpy(&objc_class, r, sizeof(struct objc_class_t));
6391           } else {
6392             outs() << " (entends past the end of the section)\n";
6393             memset(&objc_class, '\0', sizeof(struct objc_class_t));
6394             memcpy(&objc_class, r, left);
6395           }
6396           if (O->isLittleEndian() != sys::IsLittleEndianHost)
6397             swapStruct(objc_class);
6398           print_objc_class_t(&objc_class, &info);
6399         } else {
6400           outs() << "(not in an __OBJC section)\n";
6401         }
6402       }
6403     }
6404     if (symtab.cat_def_cnt > 0)
6405       outs() << "\tCategory Definitions\n";
6406     for (j = 0; j < symtab.cat_def_cnt; j++) {
6407       if ((j + symtab.cls_def_cnt + 1) * sizeof(uint32_t) > defs_left) {
6408         outs() << "\t(remaining category defs entries entends past the end of "
6409                << "the section)\n";
6410         break;
6411       }
6412       memcpy(&def, defs + (j + symtab.cls_def_cnt) * sizeof(uint32_t),
6413              sizeof(uint32_t));
6414       if (O->isLittleEndian() != sys::IsLittleEndianHost)
6415         sys::swapByteOrder(def);
6416 
6417       r = get_pointer_32(def, xoffset, left, xS, &info, true);
6418       outs() << "\tdefs[" << j + symtab.cls_def_cnt << "] "
6419              << format("0x%08" PRIx32, def);
6420       if (r != nullptr) {
6421         if (left > sizeof(struct objc_category_t)) {
6422           outs() << "\n";
6423           memcpy(&objc_category, r, sizeof(struct objc_category_t));
6424         } else {
6425           outs() << " (entends past the end of the section)\n";
6426           memset(&objc_category, '\0', sizeof(struct objc_category_t));
6427           memcpy(&objc_category, r, left);
6428         }
6429         if (O->isLittleEndian() != sys::IsLittleEndianHost)
6430           swapStruct(objc_category);
6431         print_objc_objc_category_t(&objc_category, &info);
6432       } else {
6433         outs() << "(not in an __OBJC section)\n";
6434       }
6435     }
6436   }
6437   const SectionRef II = get_section(O, "__OBJC", "__image_info");
6438   if (II != SectionRef())
6439     print_image_info(II, &info);
6440 
6441   return true;
6442 }
6443 
6444 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,
6445                                 uint32_t size, uint32_t addr) {
6446   SymbolAddressMap AddrMap;
6447   CreateSymbolAddressMap(O, &AddrMap);
6448 
6449   std::vector<SectionRef> Sections;
6450   for (const SectionRef &Section : O->sections())
6451     Sections.push_back(Section);
6452 
6453   struct DisassembleInfo info(O, &AddrMap, &Sections, true);
6454 
6455   const char *p;
6456   struct objc_protocol_t protocol;
6457   uint32_t left, paddr;
6458   for (p = sect; p < sect + size; p += sizeof(struct objc_protocol_t)) {
6459     memset(&protocol, '\0', sizeof(struct objc_protocol_t));
6460     left = size - (p - sect);
6461     if (left < sizeof(struct objc_protocol_t)) {
6462       outs() << "Protocol extends past end of __protocol section\n";
6463       memcpy(&protocol, p, left);
6464     } else
6465       memcpy(&protocol, p, sizeof(struct objc_protocol_t));
6466     if (O->isLittleEndian() != sys::IsLittleEndianHost)
6467       swapStruct(protocol);
6468     paddr = addr + (p - sect);
6469     outs() << "Protocol " << format("0x%" PRIx32, paddr);
6470     if (print_protocol(paddr, 0, &info))
6471       outs() << "(not in an __OBJC section)\n";
6472   }
6473 }
6474 
6475 #ifdef HAVE_LIBXAR
6476 static inline void swapStruct(struct xar_header &xar) {
6477   sys::swapByteOrder(xar.magic);
6478   sys::swapByteOrder(xar.size);
6479   sys::swapByteOrder(xar.version);
6480   sys::swapByteOrder(xar.toc_length_compressed);
6481   sys::swapByteOrder(xar.toc_length_uncompressed);
6482   sys::swapByteOrder(xar.cksum_alg);
6483 }
6484 
6485 static void PrintModeVerbose(uint32_t mode) {
6486   switch(mode & S_IFMT){
6487   case S_IFDIR:
6488     outs() << "d";
6489     break;
6490   case S_IFCHR:
6491     outs() << "c";
6492     break;
6493   case S_IFBLK:
6494     outs() << "b";
6495     break;
6496   case S_IFREG:
6497     outs() << "-";
6498     break;
6499   case S_IFLNK:
6500     outs() << "l";
6501     break;
6502   case S_IFSOCK:
6503     outs() << "s";
6504     break;
6505   default:
6506     outs() << "?";
6507     break;
6508   }
6509 
6510   /* owner permissions */
6511   if(mode & S_IREAD)
6512     outs() << "r";
6513   else
6514     outs() << "-";
6515   if(mode & S_IWRITE)
6516     outs() << "w";
6517   else
6518     outs() << "-";
6519   if(mode & S_ISUID)
6520     outs() << "s";
6521   else if(mode & S_IEXEC)
6522     outs() << "x";
6523   else
6524     outs() << "-";
6525 
6526   /* group permissions */
6527   if(mode & (S_IREAD >> 3))
6528     outs() << "r";
6529   else
6530     outs() << "-";
6531   if(mode & (S_IWRITE >> 3))
6532     outs() << "w";
6533   else
6534     outs() << "-";
6535   if(mode & S_ISGID)
6536     outs() << "s";
6537   else if(mode & (S_IEXEC >> 3))
6538     outs() << "x";
6539   else
6540     outs() << "-";
6541 
6542   /* other permissions */
6543   if(mode & (S_IREAD >> 6))
6544     outs() << "r";
6545   else
6546     outs() << "-";
6547   if(mode & (S_IWRITE >> 6))
6548     outs() << "w";
6549   else
6550     outs() << "-";
6551   if(mode & S_ISVTX)
6552     outs() << "t";
6553   else if(mode & (S_IEXEC >> 6))
6554     outs() << "x";
6555   else
6556     outs() << "-";
6557 }
6558 
6559 static void PrintXarFilesSummary(const char *XarFilename, xar_t xar) {
6560   xar_file_t xf;
6561   const char *key, *type, *mode, *user, *group, *size, *mtime, *name, *m;
6562   char *endp;
6563   uint32_t mode_value;
6564 
6565   ScopedXarIter xi;
6566   if (!xi) {
6567     WithColor::error(errs(), "llvm-objdump")
6568         << "can't obtain an xar iterator for xar archive " << XarFilename
6569         << "\n";
6570     return;
6571   }
6572 
6573   // Go through the xar's files.
6574   for (xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)) {
6575     ScopedXarIter xp;
6576     if(!xp){
6577       WithColor::error(errs(), "llvm-objdump")
6578           << "can't obtain an xar iterator for xar archive " << XarFilename
6579           << "\n";
6580       return;
6581     }
6582     type = nullptr;
6583     mode = nullptr;
6584     user = nullptr;
6585     group = nullptr;
6586     size = nullptr;
6587     mtime = nullptr;
6588     name = nullptr;
6589     for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
6590       const char *val = nullptr;
6591       xar_prop_get(xf, key, &val);
6592 #if 0 // Useful for debugging.
6593       outs() << "key: " << key << " value: " << val << "\n";
6594 #endif
6595       if(strcmp(key, "type") == 0)
6596         type = val;
6597       if(strcmp(key, "mode") == 0)
6598         mode = val;
6599       if(strcmp(key, "user") == 0)
6600         user = val;
6601       if(strcmp(key, "group") == 0)
6602         group = val;
6603       if(strcmp(key, "data/size") == 0)
6604         size = val;
6605       if(strcmp(key, "mtime") == 0)
6606         mtime = val;
6607       if(strcmp(key, "name") == 0)
6608         name = val;
6609     }
6610     if(mode != nullptr){
6611       mode_value = strtoul(mode, &endp, 8);
6612       if(*endp != '\0')
6613         outs() << "(mode: \"" << mode << "\" contains non-octal chars) ";
6614       if(strcmp(type, "file") == 0)
6615         mode_value |= S_IFREG;
6616       PrintModeVerbose(mode_value);
6617       outs() << " ";
6618     }
6619     if(user != nullptr)
6620       outs() << format("%10s/", user);
6621     if(group != nullptr)
6622       outs() << format("%-10s ", group);
6623     if(size != nullptr)
6624       outs() << format("%7s ", size);
6625     if(mtime != nullptr){
6626       for(m = mtime; *m != 'T' && *m != '\0'; m++)
6627         outs() << *m;
6628       if(*m == 'T')
6629         m++;
6630       outs() << " ";
6631       for( ; *m != 'Z' && *m != '\0'; m++)
6632         outs() << *m;
6633       outs() << " ";
6634     }
6635     if(name != nullptr)
6636       outs() << name;
6637     outs() << "\n";
6638   }
6639 }
6640 
6641 static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
6642                                 uint32_t size, bool verbose,
6643                                 bool PrintXarHeader, bool PrintXarFileHeaders,
6644                                 std::string XarMemberName) {
6645   if(size < sizeof(struct xar_header)) {
6646     outs() << "size of (__LLVM,__bundle) section too small (smaller than size "
6647               "of struct xar_header)\n";
6648     return;
6649   }
6650   struct xar_header XarHeader;
6651   memcpy(&XarHeader, sect, sizeof(struct xar_header));
6652   if (sys::IsLittleEndianHost)
6653     swapStruct(XarHeader);
6654   if (PrintXarHeader) {
6655     if (!XarMemberName.empty())
6656       outs() << "In xar member " << XarMemberName << ": ";
6657     else
6658       outs() << "For (__LLVM,__bundle) section: ";
6659     outs() << "xar header\n";
6660     if (XarHeader.magic == XAR_HEADER_MAGIC)
6661       outs() << "                  magic XAR_HEADER_MAGIC\n";
6662     else
6663       outs() << "                  magic "
6664              << format_hex(XarHeader.magic, 10, true)
6665              << " (not XAR_HEADER_MAGIC)\n";
6666     outs() << "                   size " << XarHeader.size << "\n";
6667     outs() << "                version " << XarHeader.version << "\n";
6668     outs() << "  toc_length_compressed " << XarHeader.toc_length_compressed
6669            << "\n";
6670     outs() << "toc_length_uncompressed " << XarHeader.toc_length_uncompressed
6671            << "\n";
6672     outs() << "              cksum_alg ";
6673     switch (XarHeader.cksum_alg) {
6674       case XAR_CKSUM_NONE:
6675         outs() << "XAR_CKSUM_NONE\n";
6676         break;
6677       case XAR_CKSUM_SHA1:
6678         outs() << "XAR_CKSUM_SHA1\n";
6679         break;
6680       case XAR_CKSUM_MD5:
6681         outs() << "XAR_CKSUM_MD5\n";
6682         break;
6683 #ifdef XAR_CKSUM_SHA256
6684       case XAR_CKSUM_SHA256:
6685         outs() << "XAR_CKSUM_SHA256\n";
6686         break;
6687 #endif
6688 #ifdef XAR_CKSUM_SHA512
6689       case XAR_CKSUM_SHA512:
6690         outs() << "XAR_CKSUM_SHA512\n";
6691         break;
6692 #endif
6693       default:
6694         outs() << XarHeader.cksum_alg << "\n";
6695     }
6696   }
6697 
6698   SmallString<128> XarFilename;
6699   int FD;
6700   std::error_code XarEC =
6701       sys::fs::createTemporaryFile("llvm-objdump", "xar", FD, XarFilename);
6702   if (XarEC) {
6703     WithColor::error(errs(), "llvm-objdump") << XarEC.message() << "\n";
6704     return;
6705   }
6706   ToolOutputFile XarFile(XarFilename, FD);
6707   raw_fd_ostream &XarOut = XarFile.os();
6708   StringRef XarContents(sect, size);
6709   XarOut << XarContents;
6710   XarOut.close();
6711   if (XarOut.has_error())
6712     return;
6713 
6714   ScopedXarFile xar(XarFilename.c_str(), READ);
6715   if (!xar) {
6716     WithColor::error(errs(), "llvm-objdump")
6717         << "can't create temporary xar archive " << XarFilename << "\n";
6718     return;
6719   }
6720 
6721   SmallString<128> TocFilename;
6722   std::error_code TocEC =
6723       sys::fs::createTemporaryFile("llvm-objdump", "toc", TocFilename);
6724   if (TocEC) {
6725     WithColor::error(errs(), "llvm-objdump") << TocEC.message() << "\n";
6726     return;
6727   }
6728   xar_serialize(xar, TocFilename.c_str());
6729 
6730   if (PrintXarFileHeaders) {
6731     if (!XarMemberName.empty())
6732       outs() << "In xar member " << XarMemberName << ": ";
6733     else
6734       outs() << "For (__LLVM,__bundle) section: ";
6735     outs() << "xar archive files:\n";
6736     PrintXarFilesSummary(XarFilename.c_str(), xar);
6737   }
6738 
6739   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
6740     MemoryBuffer::getFileOrSTDIN(TocFilename.c_str());
6741   if (std::error_code EC = FileOrErr.getError()) {
6742     WithColor::error(errs(), "llvm-objdump") << EC.message() << "\n";
6743     return;
6744   }
6745   std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
6746 
6747   if (!XarMemberName.empty())
6748     outs() << "In xar member " << XarMemberName << ": ";
6749   else
6750     outs() << "For (__LLVM,__bundle) section: ";
6751   outs() << "xar table of contents:\n";
6752   outs() << Buffer->getBuffer() << "\n";
6753 
6754   // TODO: Go through the xar's files.
6755   ScopedXarIter xi;
6756   if(!xi){
6757     WithColor::error(errs(), "llvm-objdump")
6758         << "can't obtain an xar iterator for xar archive "
6759         << XarFilename.c_str() << "\n";
6760     return;
6761   }
6762   for(xar_file_t xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)){
6763     const char *key;
6764     const char *member_name, *member_type, *member_size_string;
6765     size_t member_size;
6766 
6767     ScopedXarIter xp;
6768     if(!xp){
6769       WithColor::error(errs(), "llvm-objdump")
6770           << "can't obtain an xar iterator for xar archive "
6771           << XarFilename.c_str() << "\n";
6772       return;
6773     }
6774     member_name = NULL;
6775     member_type = NULL;
6776     member_size_string = NULL;
6777     for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
6778       const char *val = nullptr;
6779       xar_prop_get(xf, key, &val);
6780 #if 0 // Useful for debugging.
6781       outs() << "key: " << key << " value: " << val << "\n";
6782 #endif
6783       if (strcmp(key, "name") == 0)
6784         member_name = val;
6785       if (strcmp(key, "type") == 0)
6786         member_type = val;
6787       if (strcmp(key, "data/size") == 0)
6788         member_size_string = val;
6789     }
6790     /*
6791      * If we find a file with a name, date/size and type properties
6792      * and with the type being "file" see if that is a xar file.
6793      */
6794     if (member_name != NULL && member_type != NULL &&
6795         strcmp(member_type, "file") == 0 &&
6796         member_size_string != NULL){
6797       // Extract the file into a buffer.
6798       char *endptr;
6799       member_size = strtoul(member_size_string, &endptr, 10);
6800       if (*endptr == '\0' && member_size != 0) {
6801         char *buffer;
6802         if (xar_extract_tobuffersz(xar, xf, &buffer, &member_size) == 0) {
6803 #if 0 // Useful for debugging.
6804           outs() << "xar member: " << member_name << " extracted\n";
6805 #endif
6806           // Set the XarMemberName we want to see printed in the header.
6807           std::string OldXarMemberName;
6808           // If XarMemberName is already set this is nested. So
6809           // save the old name and create the nested name.
6810           if (!XarMemberName.empty()) {
6811             OldXarMemberName = XarMemberName;
6812             XarMemberName =
6813                 (Twine("[") + XarMemberName + "]" + member_name).str();
6814           } else {
6815             OldXarMemberName = "";
6816             XarMemberName = member_name;
6817           }
6818           // See if this is could be a xar file (nested).
6819           if (member_size >= sizeof(struct xar_header)) {
6820 #if 0 // Useful for debugging.
6821             outs() << "could be a xar file: " << member_name << "\n";
6822 #endif
6823             memcpy((char *)&XarHeader, buffer, sizeof(struct xar_header));
6824             if (sys::IsLittleEndianHost)
6825               swapStruct(XarHeader);
6826             if (XarHeader.magic == XAR_HEADER_MAGIC)
6827               DumpBitcodeSection(O, buffer, member_size, verbose,
6828                                  PrintXarHeader, PrintXarFileHeaders,
6829                                  XarMemberName);
6830           }
6831           XarMemberName = OldXarMemberName;
6832           delete buffer;
6833         }
6834       }
6835     }
6836   }
6837 }
6838 #endif // defined(HAVE_LIBXAR)
6839 
6840 static void printObjcMetaData(MachOObjectFile *O, bool verbose) {
6841   if (O->is64Bit())
6842     printObjc2_64bit_MetaData(O, verbose);
6843   else {
6844     MachO::mach_header H;
6845     H = O->getHeader();
6846     if (H.cputype == MachO::CPU_TYPE_ARM)
6847       printObjc2_32bit_MetaData(O, verbose);
6848     else {
6849       // This is the 32-bit non-arm cputype case.  Which is normally
6850       // the first Objective-C ABI.  But it may be the case of a
6851       // binary for the iOS simulator which is the second Objective-C
6852       // ABI.  In that case printObjc1_32bit_MetaData() will determine that
6853       // and return false.
6854       if (!printObjc1_32bit_MetaData(O, verbose))
6855         printObjc2_32bit_MetaData(O, verbose);
6856     }
6857   }
6858 }
6859 
6860 // GuessLiteralPointer returns a string which for the item in the Mach-O file
6861 // for the address passed in as ReferenceValue for printing as a comment with
6862 // the instruction and also returns the corresponding type of that item
6863 // indirectly through ReferenceType.
6864 //
6865 // If ReferenceValue is an address of literal cstring then a pointer to the
6866 // cstring is returned and ReferenceType is set to
6867 // LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr .
6868 //
6869 // If ReferenceValue is an address of an Objective-C CFString, Selector ref or
6870 // Class ref that name is returned and the ReferenceType is set accordingly.
6871 //
6872 // Lastly, literals which are Symbol address in a literal pool are looked for
6873 // and if found the symbol name is returned and ReferenceType is set to
6874 // LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr .
6875 //
6876 // If there is no item in the Mach-O file for the address passed in as
6877 // ReferenceValue nullptr is returned and ReferenceType is unchanged.
6878 static const char *GuessLiteralPointer(uint64_t ReferenceValue,
6879                                        uint64_t ReferencePC,
6880                                        uint64_t *ReferenceType,
6881                                        struct DisassembleInfo *info) {
6882   // First see if there is an external relocation entry at the ReferencePC.
6883   if (info->O->getHeader().filetype == MachO::MH_OBJECT) {
6884     uint64_t sect_addr = info->S.getAddress();
6885     uint64_t sect_offset = ReferencePC - sect_addr;
6886     bool reloc_found = false;
6887     DataRefImpl Rel;
6888     MachO::any_relocation_info RE;
6889     bool isExtern = false;
6890     SymbolRef Symbol;
6891     for (const RelocationRef &Reloc : info->S.relocations()) {
6892       uint64_t RelocOffset = Reloc.getOffset();
6893       if (RelocOffset == sect_offset) {
6894         Rel = Reloc.getRawDataRefImpl();
6895         RE = info->O->getRelocation(Rel);
6896         if (info->O->isRelocationScattered(RE))
6897           continue;
6898         isExtern = info->O->getPlainRelocationExternal(RE);
6899         if (isExtern) {
6900           symbol_iterator RelocSym = Reloc.getSymbol();
6901           Symbol = *RelocSym;
6902         }
6903         reloc_found = true;
6904         break;
6905       }
6906     }
6907     // If there is an external relocation entry for a symbol in a section
6908     // then used that symbol's value for the value of the reference.
6909     if (reloc_found && isExtern) {
6910       if (info->O->getAnyRelocationPCRel(RE)) {
6911         unsigned Type = info->O->getAnyRelocationType(RE);
6912         if (Type == MachO::X86_64_RELOC_SIGNED) {
6913           ReferenceValue = cantFail(Symbol.getValue());
6914         }
6915       }
6916     }
6917   }
6918 
6919   // Look for literals such as Objective-C CFStrings refs, Selector refs,
6920   // Message refs and Class refs.
6921   bool classref, selref, msgref, cfstring;
6922   uint64_t pointer_value = GuessPointerPointer(ReferenceValue, info, classref,
6923                                                selref, msgref, cfstring);
6924   if (classref && pointer_value == 0) {
6925     // Note the ReferenceValue is a pointer into the __objc_classrefs section.
6926     // And the pointer_value in that section is typically zero as it will be
6927     // set by dyld as part of the "bind information".
6928     const char *name = get_dyld_bind_info_symbolname(ReferenceValue, info);
6929     if (name != nullptr) {
6930       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
6931       const char *class_name = strrchr(name, '$');
6932       if (class_name != nullptr && class_name[1] == '_' &&
6933           class_name[2] != '\0') {
6934         info->class_name = class_name + 2;
6935         return name;
6936       }
6937     }
6938   }
6939 
6940   if (classref) {
6941     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
6942     const char *name =
6943         get_objc2_64bit_class_name(pointer_value, ReferenceValue, info);
6944     if (name != nullptr)
6945       info->class_name = name;
6946     else
6947       name = "bad class ref";
6948     return name;
6949   }
6950 
6951   if (cfstring) {
6952     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref;
6953     const char *name = get_objc2_64bit_cfstring_name(ReferenceValue, info);
6954     return name;
6955   }
6956 
6957   if (selref && pointer_value == 0)
6958     pointer_value = get_objc2_64bit_selref(ReferenceValue, info);
6959 
6960   if (pointer_value != 0)
6961     ReferenceValue = pointer_value;
6962 
6963   const char *name = GuessCstringPointer(ReferenceValue, info);
6964   if (name) {
6965     if (pointer_value != 0 && selref) {
6966       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref;
6967       info->selector_name = name;
6968     } else if (pointer_value != 0 && msgref) {
6969       info->class_name = nullptr;
6970       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref;
6971       info->selector_name = name;
6972     } else
6973       *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr;
6974     return name;
6975   }
6976 
6977   // Lastly look for an indirect symbol with this ReferenceValue which is in
6978   // a literal pool.  If found return that symbol name.
6979   name = GuessIndirectSymbol(ReferenceValue, info);
6980   if (name) {
6981     *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr;
6982     return name;
6983   }
6984 
6985   return nullptr;
6986 }
6987 
6988 // SymbolizerSymbolLookUp is the symbol lookup function passed when creating
6989 // the Symbolizer.  It looks up the ReferenceValue using the info passed via the
6990 // pointer to the struct DisassembleInfo that was passed when MCSymbolizer
6991 // is created and returns the symbol name that matches the ReferenceValue or
6992 // nullptr if none.  The ReferenceType is passed in for the IN type of
6993 // reference the instruction is making from the values in defined in the header
6994 // "llvm-c/Disassembler.h".  On return the ReferenceType can set to a specific
6995 // Out type and the ReferenceName will also be set which is added as a comment
6996 // to the disassembled instruction.
6997 //
6998 // If the symbol name is a C++ mangled name then the demangled name is
6999 // returned through ReferenceName and ReferenceType is set to
7000 // LLVMDisassembler_ReferenceType_DeMangled_Name .
7001 //
7002 // When this is called to get a symbol name for a branch target then the
7003 // ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then
7004 // SymbolValue will be looked for in the indirect symbol table to determine if
7005 // it is an address for a symbol stub.  If so then the symbol name for that
7006 // stub is returned indirectly through ReferenceName and then ReferenceType is
7007 // set to LLVMDisassembler_ReferenceType_Out_SymbolStub.
7008 //
7009 // When this is called with an value loaded via a PC relative load then
7010 // ReferenceType will be LLVMDisassembler_ReferenceType_In_PCrel_Load then the
7011 // SymbolValue is checked to be an address of literal pointer, symbol pointer,
7012 // or an Objective-C meta data reference.  If so the output ReferenceType is
7013 // set to correspond to that as well as setting the ReferenceName.
7014 static const char *SymbolizerSymbolLookUp(void *DisInfo,
7015                                           uint64_t ReferenceValue,
7016                                           uint64_t *ReferenceType,
7017                                           uint64_t ReferencePC,
7018                                           const char **ReferenceName) {
7019   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
7020   // If no verbose symbolic information is wanted then just return nullptr.
7021   if (!info->verbose) {
7022     *ReferenceName = nullptr;
7023     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7024     return nullptr;
7025   }
7026 
7027   const char *SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
7028 
7029   if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
7030     *ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
7031     if (*ReferenceName != nullptr) {
7032       method_reference(info, ReferenceType, ReferenceName);
7033       if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message)
7034         *ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
7035     } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
7036       if (info->demangled_name != nullptr)
7037         free(info->demangled_name);
7038       int status;
7039       info->demangled_name =
7040           itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
7041       if (info->demangled_name != nullptr) {
7042         *ReferenceName = info->demangled_name;
7043         *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
7044       } else
7045         *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7046     } else
7047       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7048   } else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
7049     *ReferenceName =
7050         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
7051     if (*ReferenceName)
7052       method_reference(info, ReferenceType, ReferenceName);
7053     else
7054       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7055     // If this is arm64 and the reference is an adrp instruction save the
7056     // instruction, passed in ReferenceValue and the address of the instruction
7057     // for use later if we see and add immediate instruction.
7058   } else if (info->O->getArch() == Triple::aarch64 &&
7059              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
7060     info->adrp_inst = ReferenceValue;
7061     info->adrp_addr = ReferencePC;
7062     SymbolName = nullptr;
7063     *ReferenceName = nullptr;
7064     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7065     // If this is arm64 and reference is an add immediate instruction and we
7066     // have
7067     // seen an adrp instruction just before it and the adrp's Xd register
7068     // matches
7069     // this add's Xn register reconstruct the value being referenced and look to
7070     // see if it is a literal pointer.  Note the add immediate instruction is
7071     // passed in ReferenceValue.
7072   } else if (info->O->getArch() == Triple::aarch64 &&
7073              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
7074              ReferencePC - 4 == info->adrp_addr &&
7075              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
7076              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
7077     uint32_t addxri_inst;
7078     uint64_t adrp_imm, addxri_imm;
7079 
7080     adrp_imm =
7081         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
7082     if (info->adrp_inst & 0x0200000)
7083       adrp_imm |= 0xfffffffffc000000LL;
7084 
7085     addxri_inst = ReferenceValue;
7086     addxri_imm = (addxri_inst >> 10) & 0xfff;
7087     if (((addxri_inst >> 22) & 0x3) == 1)
7088       addxri_imm <<= 12;
7089 
7090     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
7091                      (adrp_imm << 12) + addxri_imm;
7092 
7093     *ReferenceName =
7094         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
7095     if (*ReferenceName == nullptr)
7096       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7097     // If this is arm64 and the reference is a load register instruction and we
7098     // have seen an adrp instruction just before it and the adrp's Xd register
7099     // matches this add's Xn register reconstruct the value being referenced and
7100     // look to see if it is a literal pointer.  Note the load register
7101     // instruction is passed in ReferenceValue.
7102   } else if (info->O->getArch() == Triple::aarch64 &&
7103              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXui &&
7104              ReferencePC - 4 == info->adrp_addr &&
7105              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
7106              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
7107     uint32_t ldrxui_inst;
7108     uint64_t adrp_imm, ldrxui_imm;
7109 
7110     adrp_imm =
7111         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
7112     if (info->adrp_inst & 0x0200000)
7113       adrp_imm |= 0xfffffffffc000000LL;
7114 
7115     ldrxui_inst = ReferenceValue;
7116     ldrxui_imm = (ldrxui_inst >> 10) & 0xfff;
7117 
7118     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
7119                      (adrp_imm << 12) + (ldrxui_imm << 3);
7120 
7121     *ReferenceName =
7122         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
7123     if (*ReferenceName == nullptr)
7124       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7125   }
7126   // If this arm64 and is an load register (PC-relative) instruction the
7127   // ReferenceValue is the PC plus the immediate value.
7128   else if (info->O->getArch() == Triple::aarch64 &&
7129            (*ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXl ||
7130             *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADR)) {
7131     *ReferenceName =
7132         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
7133     if (*ReferenceName == nullptr)
7134       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7135   } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
7136     if (info->demangled_name != nullptr)
7137       free(info->demangled_name);
7138     int status;
7139     info->demangled_name =
7140         itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
7141     if (info->demangled_name != nullptr) {
7142       *ReferenceName = info->demangled_name;
7143       *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
7144     }
7145   }
7146   else {
7147     *ReferenceName = nullptr;
7148     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7149   }
7150 
7151   return SymbolName;
7152 }
7153 
7154 /// Emits the comments that are stored in the CommentStream.
7155 /// Each comment in the CommentStream must end with a newline.
7156 static void emitComments(raw_svector_ostream &CommentStream,
7157                          SmallString<128> &CommentsToEmit,
7158                          formatted_raw_ostream &FormattedOS,
7159                          const MCAsmInfo &MAI) {
7160   // Flush the stream before taking its content.
7161   StringRef Comments = CommentsToEmit.str();
7162   // Get the default information for printing a comment.
7163   StringRef CommentBegin = MAI.getCommentString();
7164   unsigned CommentColumn = MAI.getCommentColumn();
7165   bool IsFirst = true;
7166   while (!Comments.empty()) {
7167     if (!IsFirst)
7168       FormattedOS << '\n';
7169     // Emit a line of comments.
7170     FormattedOS.PadToColumn(CommentColumn);
7171     size_t Position = Comments.find('\n');
7172     FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
7173     // Move after the newline character.
7174     Comments = Comments.substr(Position + 1);
7175     IsFirst = false;
7176   }
7177   FormattedOS.flush();
7178 
7179   // Tell the comment stream that the vector changed underneath it.
7180   CommentsToEmit.clear();
7181 }
7182 
7183 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
7184                              StringRef DisSegName, StringRef DisSectName) {
7185   const char *McpuDefault = nullptr;
7186   const Target *ThumbTarget = nullptr;
7187   const Target *TheTarget = GetTarget(MachOOF, &McpuDefault, &ThumbTarget);
7188   if (!TheTarget) {
7189     // GetTarget prints out stuff.
7190     return;
7191   }
7192   std::string MachOMCPU;
7193   if (MCPU.empty() && McpuDefault)
7194     MachOMCPU = McpuDefault;
7195   else
7196     MachOMCPU = MCPU;
7197 
7198   std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
7199   std::unique_ptr<const MCInstrInfo> ThumbInstrInfo;
7200   if (ThumbTarget)
7201     ThumbInstrInfo.reset(ThumbTarget->createMCInstrInfo());
7202 
7203   // Package up features to be passed to target/subtarget
7204   std::string FeaturesStr;
7205   if (!MAttrs.empty()) {
7206     SubtargetFeatures Features;
7207     for (unsigned i = 0; i != MAttrs.size(); ++i)
7208       Features.AddFeature(MAttrs[i]);
7209     FeaturesStr = Features.getString();
7210   }
7211 
7212   MCTargetOptions MCOptions;
7213   // Set up disassembler.
7214   std::unique_ptr<const MCRegisterInfo> MRI(
7215       TheTarget->createMCRegInfo(TripleName));
7216   std::unique_ptr<const MCAsmInfo> AsmInfo(
7217       TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
7218   std::unique_ptr<const MCSubtargetInfo> STI(
7219       TheTarget->createMCSubtargetInfo(TripleName, MachOMCPU, FeaturesStr));
7220   MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr);
7221   std::unique_ptr<MCDisassembler> DisAsm(
7222       TheTarget->createMCDisassembler(*STI, Ctx));
7223   std::unique_ptr<MCSymbolizer> Symbolizer;
7224   struct DisassembleInfo SymbolizerInfo(nullptr, nullptr, nullptr, false);
7225   std::unique_ptr<MCRelocationInfo> RelInfo(
7226       TheTarget->createMCRelocationInfo(TripleName, Ctx));
7227   if (RelInfo) {
7228     Symbolizer.reset(TheTarget->createMCSymbolizer(
7229         TripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
7230         &SymbolizerInfo, &Ctx, std::move(RelInfo)));
7231     DisAsm->setSymbolizer(std::move(Symbolizer));
7232   }
7233   int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
7234   std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
7235       Triple(TripleName), AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI));
7236   // Set the display preference for hex vs. decimal immediates.
7237   IP->setPrintImmHex(PrintImmHex);
7238   // Comment stream and backing vector.
7239   SmallString<128> CommentsToEmit;
7240   raw_svector_ostream CommentStream(CommentsToEmit);
7241   // FIXME: Setting the CommentStream in the InstPrinter is problematic in that
7242   // if it is done then arm64 comments for string literals don't get printed
7243   // and some constant get printed instead and not setting it causes intel
7244   // (32-bit and 64-bit) comments printed with different spacing before the
7245   // comment causing different diffs with the 'C' disassembler library API.
7246   // IP->setCommentStream(CommentStream);
7247 
7248   if (!AsmInfo || !STI || !DisAsm || !IP) {
7249     WithColor::error(errs(), "llvm-objdump")
7250         << "couldn't initialize disassembler for target " << TripleName << '\n';
7251     return;
7252   }
7253 
7254   // Set up separate thumb disassembler if needed.
7255   std::unique_ptr<const MCRegisterInfo> ThumbMRI;
7256   std::unique_ptr<const MCAsmInfo> ThumbAsmInfo;
7257   std::unique_ptr<const MCSubtargetInfo> ThumbSTI;
7258   std::unique_ptr<MCDisassembler> ThumbDisAsm;
7259   std::unique_ptr<MCInstPrinter> ThumbIP;
7260   std::unique_ptr<MCContext> ThumbCtx;
7261   std::unique_ptr<MCSymbolizer> ThumbSymbolizer;
7262   struct DisassembleInfo ThumbSymbolizerInfo(nullptr, nullptr, nullptr, false);
7263   std::unique_ptr<MCRelocationInfo> ThumbRelInfo;
7264   if (ThumbTarget) {
7265     ThumbMRI.reset(ThumbTarget->createMCRegInfo(ThumbTripleName));
7266     ThumbAsmInfo.reset(
7267         ThumbTarget->createMCAsmInfo(*ThumbMRI, ThumbTripleName, MCOptions));
7268     ThumbSTI.reset(
7269         ThumbTarget->createMCSubtargetInfo(ThumbTripleName, MachOMCPU,
7270                                            FeaturesStr));
7271     ThumbCtx.reset(new MCContext(ThumbAsmInfo.get(), ThumbMRI.get(), nullptr));
7272     ThumbDisAsm.reset(ThumbTarget->createMCDisassembler(*ThumbSTI, *ThumbCtx));
7273     MCContext *PtrThumbCtx = ThumbCtx.get();
7274     ThumbRelInfo.reset(
7275         ThumbTarget->createMCRelocationInfo(ThumbTripleName, *PtrThumbCtx));
7276     if (ThumbRelInfo) {
7277       ThumbSymbolizer.reset(ThumbTarget->createMCSymbolizer(
7278           ThumbTripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
7279           &ThumbSymbolizerInfo, PtrThumbCtx, std::move(ThumbRelInfo)));
7280       ThumbDisAsm->setSymbolizer(std::move(ThumbSymbolizer));
7281     }
7282     int ThumbAsmPrinterVariant = ThumbAsmInfo->getAssemblerDialect();
7283     ThumbIP.reset(ThumbTarget->createMCInstPrinter(
7284         Triple(ThumbTripleName), ThumbAsmPrinterVariant, *ThumbAsmInfo,
7285         *ThumbInstrInfo, *ThumbMRI));
7286     // Set the display preference for hex vs. decimal immediates.
7287     ThumbIP->setPrintImmHex(PrintImmHex);
7288   }
7289 
7290   if (ThumbTarget && (!ThumbAsmInfo || !ThumbSTI || !ThumbDisAsm || !ThumbIP)) {
7291     WithColor::error(errs(), "llvm-objdump")
7292         << "couldn't initialize disassembler for target " << ThumbTripleName
7293         << '\n';
7294     return;
7295   }
7296 
7297   MachO::mach_header Header = MachOOF->getHeader();
7298 
7299   // FIXME: Using the -cfg command line option, this code used to be able to
7300   // annotate relocations with the referenced symbol's name, and if this was
7301   // inside a __[cf]string section, the data it points to. This is now replaced
7302   // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
7303   std::vector<SectionRef> Sections;
7304   std::vector<SymbolRef> Symbols;
7305   SmallVector<uint64_t, 8> FoundFns;
7306   uint64_t BaseSegmentAddress = 0;
7307 
7308   getSectionsAndSymbols(MachOOF, Sections, Symbols, FoundFns,
7309                         BaseSegmentAddress);
7310 
7311   // Sort the symbols by address, just in case they didn't come in that way.
7312   llvm::sort(Symbols, SymbolSorter());
7313 
7314   // Build a data in code table that is sorted on by the address of each entry.
7315   uint64_t BaseAddress = 0;
7316   if (Header.filetype == MachO::MH_OBJECT)
7317     BaseAddress = Sections[0].getAddress();
7318   else
7319     BaseAddress = BaseSegmentAddress;
7320   DiceTable Dices;
7321   for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
7322        DI != DE; ++DI) {
7323     uint32_t Offset;
7324     DI->getOffset(Offset);
7325     Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
7326   }
7327   array_pod_sort(Dices.begin(), Dices.end());
7328 
7329   // Try to find debug info and set up the DIContext for it.
7330   std::unique_ptr<DIContext> diContext;
7331   std::unique_ptr<Binary> DSYMBinary;
7332   std::unique_ptr<MemoryBuffer> DSYMBuf;
7333   if (UseDbg) {
7334     ObjectFile *DbgObj = MachOOF;
7335 
7336     // A separate DSym file path was specified, parse it as a macho file,
7337     // get the sections and supply it to the section name parsing machinery.
7338     if (!DSYMFile.empty()) {
7339       std::string DSYMPath(DSYMFile);
7340 
7341       // If DSYMPath is a .dSYM directory, append the Mach-O file.
7342       if (llvm::sys::fs::is_directory(DSYMPath) &&
7343           llvm::sys::path::extension(DSYMPath) == ".dSYM") {
7344         SmallString<128> ShortName(llvm::sys::path::filename(DSYMPath));
7345         llvm::sys::path::replace_extension(ShortName, "");
7346         SmallString<1024> FullPath(DSYMPath);
7347         llvm::sys::path::append(FullPath, "Contents", "Resources", "DWARF",
7348                                 ShortName);
7349         DSYMPath = std::string(FullPath.str());
7350       }
7351 
7352       // Load the file.
7353       ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
7354           MemoryBuffer::getFileOrSTDIN(DSYMPath);
7355       if (std::error_code EC = BufOrErr.getError()) {
7356         reportError(errorCodeToError(EC), DSYMPath);
7357         return;
7358       }
7359 
7360       // We need to keep the file alive, because we're replacing DbgObj with it.
7361       DSYMBuf = std::move(BufOrErr.get());
7362 
7363       Expected<std::unique_ptr<Binary>> BinaryOrErr =
7364       createBinary(DSYMBuf.get()->getMemBufferRef());
7365       if (!BinaryOrErr) {
7366         reportError(BinaryOrErr.takeError(), DSYMPath);
7367         return;
7368       }
7369 
7370       // We need to keep the Binary alive with the buffer
7371       DSYMBinary = std::move(BinaryOrErr.get());
7372       if (ObjectFile *O = dyn_cast<ObjectFile>(DSYMBinary.get())) {
7373         // this is a Mach-O object file, use it
7374         if (MachOObjectFile *MachDSYM = dyn_cast<MachOObjectFile>(&*O)) {
7375           DbgObj = MachDSYM;
7376         }
7377         else {
7378           WithColor::error(errs(), "llvm-objdump")
7379             << DSYMPath << " is not a Mach-O file type.\n";
7380           return;
7381         }
7382       }
7383       else if (auto UB = dyn_cast<MachOUniversalBinary>(DSYMBinary.get())){
7384         // this is a Universal Binary, find a Mach-O for this architecture
7385         uint32_t CPUType, CPUSubType;
7386         const char *ArchFlag;
7387         if (MachOOF->is64Bit()) {
7388           const MachO::mach_header_64 H_64 = MachOOF->getHeader64();
7389           CPUType = H_64.cputype;
7390           CPUSubType = H_64.cpusubtype;
7391         } else {
7392           const MachO::mach_header H = MachOOF->getHeader();
7393           CPUType = H.cputype;
7394           CPUSubType = H.cpusubtype;
7395         }
7396         Triple T = MachOObjectFile::getArchTriple(CPUType, CPUSubType, nullptr,
7397                                                   &ArchFlag);
7398         Expected<std::unique_ptr<MachOObjectFile>> MachDSYM =
7399             UB->getMachOObjectForArch(ArchFlag);
7400         if (!MachDSYM) {
7401           reportError(MachDSYM.takeError(), DSYMPath);
7402           return;
7403         }
7404 
7405         // We need to keep the Binary alive with the buffer
7406         DbgObj = &*MachDSYM.get();
7407         DSYMBinary = std::move(*MachDSYM);
7408       }
7409       else {
7410         WithColor::error(errs(), "llvm-objdump")
7411           << DSYMPath << " is not a Mach-O or Universal file type.\n";
7412         return;
7413       }
7414     }
7415 
7416     // Setup the DIContext
7417     diContext = DWARFContext::create(*DbgObj);
7418   }
7419 
7420   if (FilterSections.empty())
7421     outs() << "(" << DisSegName << "," << DisSectName << ") section\n";
7422 
7423   for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
7424     Expected<StringRef> SecNameOrErr = Sections[SectIdx].getName();
7425     if (!SecNameOrErr) {
7426       consumeError(SecNameOrErr.takeError());
7427       continue;
7428     }
7429     if (*SecNameOrErr != DisSectName)
7430       continue;
7431 
7432     DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
7433 
7434     StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
7435     if (SegmentName != DisSegName)
7436       continue;
7437 
7438     StringRef BytesStr =
7439         unwrapOrError(Sections[SectIdx].getContents(), Filename);
7440     ArrayRef<uint8_t> Bytes = arrayRefFromStringRef(BytesStr);
7441     uint64_t SectAddress = Sections[SectIdx].getAddress();
7442 
7443     bool symbolTableWorked = false;
7444 
7445     // Create a map of symbol addresses to symbol names for use by
7446     // the SymbolizerSymbolLookUp() routine.
7447     SymbolAddressMap AddrMap;
7448     bool DisSymNameFound = false;
7449     for (const SymbolRef &Symbol : MachOOF->symbols()) {
7450       SymbolRef::Type ST =
7451           unwrapOrError(Symbol.getType(), MachOOF->getFileName());
7452       if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
7453           ST == SymbolRef::ST_Other) {
7454         uint64_t Address = cantFail(Symbol.getValue());
7455         StringRef SymName =
7456             unwrapOrError(Symbol.getName(), MachOOF->getFileName());
7457         AddrMap[Address] = SymName;
7458         if (!DisSymName.empty() && DisSymName == SymName)
7459           DisSymNameFound = true;
7460       }
7461     }
7462     if (!DisSymName.empty() && !DisSymNameFound) {
7463       outs() << "Can't find -dis-symname: " << DisSymName << "\n";
7464       return;
7465     }
7466     // Set up the block of info used by the Symbolizer call backs.
7467     SymbolizerInfo.verbose = !NoSymbolicOperands;
7468     SymbolizerInfo.O = MachOOF;
7469     SymbolizerInfo.S = Sections[SectIdx];
7470     SymbolizerInfo.AddrMap = &AddrMap;
7471     SymbolizerInfo.Sections = &Sections;
7472     // Same for the ThumbSymbolizer
7473     ThumbSymbolizerInfo.verbose = !NoSymbolicOperands;
7474     ThumbSymbolizerInfo.O = MachOOF;
7475     ThumbSymbolizerInfo.S = Sections[SectIdx];
7476     ThumbSymbolizerInfo.AddrMap = &AddrMap;
7477     ThumbSymbolizerInfo.Sections = &Sections;
7478 
7479     unsigned int Arch = MachOOF->getArch();
7480 
7481     // Skip all symbols if this is a stubs file.
7482     if (Bytes.empty())
7483       return;
7484 
7485     // If the section has symbols but no symbol at the start of the section
7486     // these are used to make sure the bytes before the first symbol are
7487     // disassembled.
7488     bool FirstSymbol = true;
7489     bool FirstSymbolAtSectionStart = true;
7490 
7491     // Disassemble symbol by symbol.
7492     for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
7493       StringRef SymName =
7494           unwrapOrError(Symbols[SymIdx].getName(), MachOOF->getFileName());
7495       SymbolRef::Type ST =
7496           unwrapOrError(Symbols[SymIdx].getType(), MachOOF->getFileName());
7497       if (ST != SymbolRef::ST_Function && ST != SymbolRef::ST_Data)
7498         continue;
7499 
7500       // Make sure the symbol is defined in this section.
7501       bool containsSym = Sections[SectIdx].containsSymbol(Symbols[SymIdx]);
7502       if (!containsSym) {
7503         if (!DisSymName.empty() && DisSymName == SymName) {
7504           outs() << "-dis-symname: " << DisSymName << " not in the section\n";
7505           return;
7506         }
7507         continue;
7508       }
7509       // The __mh_execute_header is special and we need to deal with that fact
7510       // this symbol is before the start of the (__TEXT,__text) section and at the
7511       // address of the start of the __TEXT segment.  This is because this symbol
7512       // is an N_SECT symbol in the (__TEXT,__text) but its address is before the
7513       // start of the section in a standard MH_EXECUTE filetype.
7514       if (!DisSymName.empty() && DisSymName == "__mh_execute_header") {
7515         outs() << "-dis-symname: __mh_execute_header not in any section\n";
7516         return;
7517       }
7518       // When this code is trying to disassemble a symbol at a time and in the
7519       // case there is only the __mh_execute_header symbol left as in a stripped
7520       // executable, we need to deal with this by ignoring this symbol so the
7521       // whole section is disassembled and this symbol is then not displayed.
7522       if (SymName == "__mh_execute_header" || SymName == "__mh_dylib_header" ||
7523           SymName == "__mh_bundle_header" || SymName == "__mh_object_header" ||
7524           SymName == "__mh_preload_header" || SymName == "__mh_dylinker_header")
7525         continue;
7526 
7527       // If we are only disassembling one symbol see if this is that symbol.
7528       if (!DisSymName.empty() && DisSymName != SymName)
7529         continue;
7530 
7531       // Start at the address of the symbol relative to the section's address.
7532       uint64_t SectSize = Sections[SectIdx].getSize();
7533       uint64_t Start = cantFail(Symbols[SymIdx].getValue());
7534       uint64_t SectionAddress = Sections[SectIdx].getAddress();
7535       Start -= SectionAddress;
7536 
7537       if (Start > SectSize) {
7538         outs() << "section data ends, " << SymName
7539                << " lies outside valid range\n";
7540         return;
7541       }
7542 
7543       // Stop disassembling either at the beginning of the next symbol or at
7544       // the end of the section.
7545       bool containsNextSym = false;
7546       uint64_t NextSym = 0;
7547       uint64_t NextSymIdx = SymIdx + 1;
7548       while (Symbols.size() > NextSymIdx) {
7549         SymbolRef::Type NextSymType = unwrapOrError(
7550             Symbols[NextSymIdx].getType(), MachOOF->getFileName());
7551         if (NextSymType == SymbolRef::ST_Function) {
7552           containsNextSym =
7553               Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]);
7554           NextSym = cantFail(Symbols[NextSymIdx].getValue());
7555           NextSym -= SectionAddress;
7556           break;
7557         }
7558         ++NextSymIdx;
7559       }
7560 
7561       uint64_t End = containsNextSym ? std::min(NextSym, SectSize) : SectSize;
7562       uint64_t Size;
7563 
7564       symbolTableWorked = true;
7565 
7566       DataRefImpl Symb = Symbols[SymIdx].getRawDataRefImpl();
7567       uint32_t SymbolFlags = cantFail(MachOOF->getSymbolFlags(Symb));
7568       bool IsThumb = SymbolFlags & SymbolRef::SF_Thumb;
7569 
7570       // We only need the dedicated Thumb target if there's a real choice
7571       // (i.e. we're not targeting M-class) and the function is Thumb.
7572       bool UseThumbTarget = IsThumb && ThumbTarget;
7573 
7574       // If we are not specifying a symbol to start disassembly with and this
7575       // is the first symbol in the section but not at the start of the section
7576       // then move the disassembly index to the start of the section and
7577       // don't print the symbol name just yet.  This is so the bytes before the
7578       // first symbol are disassembled.
7579       uint64_t SymbolStart = Start;
7580       if (DisSymName.empty() && FirstSymbol && Start != 0) {
7581         FirstSymbolAtSectionStart = false;
7582         Start = 0;
7583       }
7584       else
7585         outs() << SymName << ":\n";
7586 
7587       DILineInfo lastLine;
7588       for (uint64_t Index = Start; Index < End; Index += Size) {
7589         MCInst Inst;
7590 
7591         // If this is the first symbol in the section and it was not at the
7592         // start of the section, see if we are at its Index now and if so print
7593         // the symbol name.
7594         if (FirstSymbol && !FirstSymbolAtSectionStart && Index == SymbolStart)
7595           outs() << SymName << ":\n";
7596 
7597         uint64_t PC = SectAddress + Index;
7598         if (!NoLeadingAddr) {
7599           if (FullLeadingAddr) {
7600             if (MachOOF->is64Bit())
7601               outs() << format("%016" PRIx64, PC);
7602             else
7603               outs() << format("%08" PRIx64, PC);
7604           } else {
7605             outs() << format("%8" PRIx64 ":", PC);
7606           }
7607         }
7608         if (!NoShowRawInsn || Arch == Triple::arm)
7609           outs() << "\t";
7610 
7611         if (DumpAndSkipDataInCode(PC, Bytes.data() + Index, Dices, Size))
7612           continue;
7613 
7614         SmallVector<char, 64> AnnotationsBytes;
7615         raw_svector_ostream Annotations(AnnotationsBytes);
7616 
7617         bool gotInst;
7618         if (UseThumbTarget)
7619           gotInst = ThumbDisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
7620                                                 PC, Annotations);
7621         else
7622           gotInst = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index), PC,
7623                                            Annotations);
7624         if (gotInst) {
7625           if (!NoShowRawInsn || Arch == Triple::arm) {
7626             dumpBytes(makeArrayRef(Bytes.data() + Index, Size), outs());
7627           }
7628           formatted_raw_ostream FormattedOS(outs());
7629           StringRef AnnotationsStr = Annotations.str();
7630           if (UseThumbTarget)
7631             ThumbIP->printInst(&Inst, PC, AnnotationsStr, *ThumbSTI,
7632                                FormattedOS);
7633           else
7634             IP->printInst(&Inst, PC, AnnotationsStr, *STI, FormattedOS);
7635           emitComments(CommentStream, CommentsToEmit, FormattedOS, *AsmInfo);
7636 
7637           // Print debug info.
7638           if (diContext) {
7639             DILineInfo dli = diContext->getLineInfoForAddress({PC, SectIdx});
7640             // Print valid line info if it changed.
7641             if (dli != lastLine && dli.Line != 0)
7642               outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
7643                      << dli.Column;
7644             lastLine = dli;
7645           }
7646           outs() << "\n";
7647         } else {
7648           if (MachOOF->getArchTriple().isX86()) {
7649             outs() << format("\t.byte 0x%02x #bad opcode\n",
7650                              *(Bytes.data() + Index) & 0xff);
7651             Size = 1; // skip exactly one illegible byte and move on.
7652           } else if (Arch == Triple::aarch64 ||
7653                      (Arch == Triple::arm && !IsThumb)) {
7654             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
7655                               (*(Bytes.data() + Index + 1) & 0xff) << 8 |
7656                               (*(Bytes.data() + Index + 2) & 0xff) << 16 |
7657                               (*(Bytes.data() + Index + 3) & 0xff) << 24;
7658             outs() << format("\t.long\t0x%08x\n", opcode);
7659             Size = 4;
7660           } else if (Arch == Triple::arm) {
7661             assert(IsThumb && "ARM mode should have been dealt with above");
7662             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
7663                               (*(Bytes.data() + Index + 1) & 0xff) << 8;
7664             outs() << format("\t.short\t0x%04x\n", opcode);
7665             Size = 2;
7666           } else{
7667             WithColor::warning(errs(), "llvm-objdump")
7668                 << "invalid instruction encoding\n";
7669             if (Size == 0)
7670               Size = 1; // skip illegible bytes
7671           }
7672         }
7673       }
7674       // Now that we are done disassembled the first symbol set the bool that
7675       // were doing this to false.
7676       FirstSymbol = false;
7677     }
7678     if (!symbolTableWorked) {
7679       // Reading the symbol table didn't work, disassemble the whole section.
7680       uint64_t SectAddress = Sections[SectIdx].getAddress();
7681       uint64_t SectSize = Sections[SectIdx].getSize();
7682       uint64_t InstSize;
7683       for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
7684         MCInst Inst;
7685 
7686         uint64_t PC = SectAddress + Index;
7687 
7688         if (DumpAndSkipDataInCode(PC, Bytes.data() + Index, Dices, InstSize))
7689           continue;
7690 
7691         SmallVector<char, 64> AnnotationsBytes;
7692         raw_svector_ostream Annotations(AnnotationsBytes);
7693         if (DisAsm->getInstruction(Inst, InstSize, Bytes.slice(Index), PC,
7694                                    Annotations)) {
7695           if (!NoLeadingAddr) {
7696             if (FullLeadingAddr) {
7697               if (MachOOF->is64Bit())
7698                 outs() << format("%016" PRIx64, PC);
7699               else
7700                 outs() << format("%08" PRIx64, PC);
7701             } else {
7702               outs() << format("%8" PRIx64 ":", PC);
7703             }
7704           }
7705           if (!NoShowRawInsn || Arch == Triple::arm) {
7706             outs() << "\t";
7707             dumpBytes(makeArrayRef(Bytes.data() + Index, InstSize), outs());
7708           }
7709           StringRef AnnotationsStr = Annotations.str();
7710           IP->printInst(&Inst, PC, AnnotationsStr, *STI, outs());
7711           outs() << "\n";
7712         } else {
7713           if (MachOOF->getArchTriple().isX86()) {
7714             outs() << format("\t.byte 0x%02x #bad opcode\n",
7715                              *(Bytes.data() + Index) & 0xff);
7716             InstSize = 1; // skip exactly one illegible byte and move on.
7717           } else {
7718             WithColor::warning(errs(), "llvm-objdump")
7719                 << "invalid instruction encoding\n";
7720             if (InstSize == 0)
7721               InstSize = 1; // skip illegible bytes
7722           }
7723         }
7724       }
7725     }
7726     // The TripleName's need to be reset if we are called again for a different
7727     // architecture.
7728     TripleName = "";
7729     ThumbTripleName = "";
7730 
7731     if (SymbolizerInfo.demangled_name != nullptr)
7732       free(SymbolizerInfo.demangled_name);
7733     if (ThumbSymbolizerInfo.demangled_name != nullptr)
7734       free(ThumbSymbolizerInfo.demangled_name);
7735   }
7736 }
7737 
7738 //===----------------------------------------------------------------------===//
7739 // __compact_unwind section dumping
7740 //===----------------------------------------------------------------------===//
7741 
7742 namespace {
7743 
7744 template <typename T>
7745 static uint64_t read(StringRef Contents, ptrdiff_t Offset) {
7746   using llvm::support::little;
7747   using llvm::support::unaligned;
7748 
7749   if (Offset + sizeof(T) > Contents.size()) {
7750     outs() << "warning: attempt to read past end of buffer\n";
7751     return T();
7752   }
7753 
7754   uint64_t Val =
7755       support::endian::read<T, little, unaligned>(Contents.data() + Offset);
7756   return Val;
7757 }
7758 
7759 template <typename T>
7760 static uint64_t readNext(StringRef Contents, ptrdiff_t &Offset) {
7761   T Val = read<T>(Contents, Offset);
7762   Offset += sizeof(T);
7763   return Val;
7764 }
7765 
7766 struct CompactUnwindEntry {
7767   uint32_t OffsetInSection;
7768 
7769   uint64_t FunctionAddr;
7770   uint32_t Length;
7771   uint32_t CompactEncoding;
7772   uint64_t PersonalityAddr;
7773   uint64_t LSDAAddr;
7774 
7775   RelocationRef FunctionReloc;
7776   RelocationRef PersonalityReloc;
7777   RelocationRef LSDAReloc;
7778 
7779   CompactUnwindEntry(StringRef Contents, unsigned Offset, bool Is64)
7780       : OffsetInSection(Offset) {
7781     if (Is64)
7782       read<uint64_t>(Contents, Offset);
7783     else
7784       read<uint32_t>(Contents, Offset);
7785   }
7786 
7787 private:
7788   template <typename UIntPtr> void read(StringRef Contents, ptrdiff_t Offset) {
7789     FunctionAddr = readNext<UIntPtr>(Contents, Offset);
7790     Length = readNext<uint32_t>(Contents, Offset);
7791     CompactEncoding = readNext<uint32_t>(Contents, Offset);
7792     PersonalityAddr = readNext<UIntPtr>(Contents, Offset);
7793     LSDAAddr = readNext<UIntPtr>(Contents, Offset);
7794   }
7795 };
7796 }
7797 
7798 /// Given a relocation from __compact_unwind, consisting of the RelocationRef
7799 /// and data being relocated, determine the best base Name and Addend to use for
7800 /// display purposes.
7801 ///
7802 /// 1. An Extern relocation will directly reference a symbol (and the data is
7803 ///    then already an addend), so use that.
7804 /// 2. Otherwise the data is an offset in the object file's layout; try to find
7805 //     a symbol before it in the same section, and use the offset from there.
7806 /// 3. Finally, if all that fails, fall back to an offset from the start of the
7807 ///    referenced section.
7808 static void findUnwindRelocNameAddend(const MachOObjectFile *Obj,
7809                                       std::map<uint64_t, SymbolRef> &Symbols,
7810                                       const RelocationRef &Reloc, uint64_t Addr,
7811                                       StringRef &Name, uint64_t &Addend) {
7812   if (Reloc.getSymbol() != Obj->symbol_end()) {
7813     Name = unwrapOrError(Reloc.getSymbol()->getName(), Obj->getFileName());
7814     Addend = Addr;
7815     return;
7816   }
7817 
7818   auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl());
7819   SectionRef RelocSection = Obj->getAnyRelocationSection(RE);
7820 
7821   uint64_t SectionAddr = RelocSection.getAddress();
7822 
7823   auto Sym = Symbols.upper_bound(Addr);
7824   if (Sym == Symbols.begin()) {
7825     // The first symbol in the object is after this reference, the best we can
7826     // do is section-relative notation.
7827     if (Expected<StringRef> NameOrErr = RelocSection.getName())
7828       Name = *NameOrErr;
7829     else
7830       consumeError(NameOrErr.takeError());
7831 
7832     Addend = Addr - SectionAddr;
7833     return;
7834   }
7835 
7836   // Go back one so that SymbolAddress <= Addr.
7837   --Sym;
7838 
7839   section_iterator SymSection =
7840       unwrapOrError(Sym->second.getSection(), Obj->getFileName());
7841   if (RelocSection == *SymSection) {
7842     // There's a valid symbol in the same section before this reference.
7843     Name = unwrapOrError(Sym->second.getName(), Obj->getFileName());
7844     Addend = Addr - Sym->first;
7845     return;
7846   }
7847 
7848   // There is a symbol before this reference, but it's in a different
7849   // section. Probably not helpful to mention it, so use the section name.
7850   if (Expected<StringRef> NameOrErr = RelocSection.getName())
7851     Name = *NameOrErr;
7852   else
7853     consumeError(NameOrErr.takeError());
7854 
7855   Addend = Addr - SectionAddr;
7856 }
7857 
7858 static void printUnwindRelocDest(const MachOObjectFile *Obj,
7859                                  std::map<uint64_t, SymbolRef> &Symbols,
7860                                  const RelocationRef &Reloc, uint64_t Addr) {
7861   StringRef Name;
7862   uint64_t Addend;
7863 
7864   if (!Reloc.getObject())
7865     return;
7866 
7867   findUnwindRelocNameAddend(Obj, Symbols, Reloc, Addr, Name, Addend);
7868 
7869   outs() << Name;
7870   if (Addend)
7871     outs() << " + " << format("0x%" PRIx64, Addend);
7872 }
7873 
7874 static void
7875 printMachOCompactUnwindSection(const MachOObjectFile *Obj,
7876                                std::map<uint64_t, SymbolRef> &Symbols,
7877                                const SectionRef &CompactUnwind) {
7878 
7879   if (!Obj->isLittleEndian()) {
7880     outs() << "Skipping big-endian __compact_unwind section\n";
7881     return;
7882   }
7883 
7884   bool Is64 = Obj->is64Bit();
7885   uint32_t PointerSize = Is64 ? sizeof(uint64_t) : sizeof(uint32_t);
7886   uint32_t EntrySize = 3 * PointerSize + 2 * sizeof(uint32_t);
7887 
7888   StringRef Contents =
7889       unwrapOrError(CompactUnwind.getContents(), Obj->getFileName());
7890   SmallVector<CompactUnwindEntry, 4> CompactUnwinds;
7891 
7892   // First populate the initial raw offsets, encodings and so on from the entry.
7893   for (unsigned Offset = 0; Offset < Contents.size(); Offset += EntrySize) {
7894     CompactUnwindEntry Entry(Contents, Offset, Is64);
7895     CompactUnwinds.push_back(Entry);
7896   }
7897 
7898   // Next we need to look at the relocations to find out what objects are
7899   // actually being referred to.
7900   for (const RelocationRef &Reloc : CompactUnwind.relocations()) {
7901     uint64_t RelocAddress = Reloc.getOffset();
7902 
7903     uint32_t EntryIdx = RelocAddress / EntrySize;
7904     uint32_t OffsetInEntry = RelocAddress - EntryIdx * EntrySize;
7905     CompactUnwindEntry &Entry = CompactUnwinds[EntryIdx];
7906 
7907     if (OffsetInEntry == 0)
7908       Entry.FunctionReloc = Reloc;
7909     else if (OffsetInEntry == PointerSize + 2 * sizeof(uint32_t))
7910       Entry.PersonalityReloc = Reloc;
7911     else if (OffsetInEntry == 2 * PointerSize + 2 * sizeof(uint32_t))
7912       Entry.LSDAReloc = Reloc;
7913     else {
7914       outs() << "Invalid relocation in __compact_unwind section\n";
7915       return;
7916     }
7917   }
7918 
7919   // Finally, we're ready to print the data we've gathered.
7920   outs() << "Contents of __compact_unwind section:\n";
7921   for (auto &Entry : CompactUnwinds) {
7922     outs() << "  Entry at offset "
7923            << format("0x%" PRIx32, Entry.OffsetInSection) << ":\n";
7924 
7925     // 1. Start of the region this entry applies to.
7926     outs() << "    start:                " << format("0x%" PRIx64,
7927                                                      Entry.FunctionAddr) << ' ';
7928     printUnwindRelocDest(Obj, Symbols, Entry.FunctionReloc, Entry.FunctionAddr);
7929     outs() << '\n';
7930 
7931     // 2. Length of the region this entry applies to.
7932     outs() << "    length:               " << format("0x%" PRIx32, Entry.Length)
7933            << '\n';
7934     // 3. The 32-bit compact encoding.
7935     outs() << "    compact encoding:     "
7936            << format("0x%08" PRIx32, Entry.CompactEncoding) << '\n';
7937 
7938     // 4. The personality function, if present.
7939     if (Entry.PersonalityReloc.getObject()) {
7940       outs() << "    personality function: "
7941              << format("0x%" PRIx64, Entry.PersonalityAddr) << ' ';
7942       printUnwindRelocDest(Obj, Symbols, Entry.PersonalityReloc,
7943                            Entry.PersonalityAddr);
7944       outs() << '\n';
7945     }
7946 
7947     // 5. This entry's language-specific data area.
7948     if (Entry.LSDAReloc.getObject()) {
7949       outs() << "    LSDA:                 " << format("0x%" PRIx64,
7950                                                        Entry.LSDAAddr) << ' ';
7951       printUnwindRelocDest(Obj, Symbols, Entry.LSDAReloc, Entry.LSDAAddr);
7952       outs() << '\n';
7953     }
7954   }
7955 }
7956 
7957 //===----------------------------------------------------------------------===//
7958 // __unwind_info section dumping
7959 //===----------------------------------------------------------------------===//
7960 
7961 static void printRegularSecondLevelUnwindPage(StringRef PageData) {
7962   ptrdiff_t Pos = 0;
7963   uint32_t Kind = readNext<uint32_t>(PageData, Pos);
7964   (void)Kind;
7965   assert(Kind == 2 && "kind for a regular 2nd level index should be 2");
7966 
7967   uint16_t EntriesStart = readNext<uint16_t>(PageData, Pos);
7968   uint16_t NumEntries = readNext<uint16_t>(PageData, Pos);
7969 
7970   Pos = EntriesStart;
7971   for (unsigned i = 0; i < NumEntries; ++i) {
7972     uint32_t FunctionOffset = readNext<uint32_t>(PageData, Pos);
7973     uint32_t Encoding = readNext<uint32_t>(PageData, Pos);
7974 
7975     outs() << "      [" << i << "]: "
7976            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
7977            << ", "
7978            << "encoding=" << format("0x%08" PRIx32, Encoding) << '\n';
7979   }
7980 }
7981 
7982 static void printCompressedSecondLevelUnwindPage(
7983     StringRef PageData, uint32_t FunctionBase,
7984     const SmallVectorImpl<uint32_t> &CommonEncodings) {
7985   ptrdiff_t Pos = 0;
7986   uint32_t Kind = readNext<uint32_t>(PageData, Pos);
7987   (void)Kind;
7988   assert(Kind == 3 && "kind for a compressed 2nd level index should be 3");
7989 
7990   uint16_t EntriesStart = readNext<uint16_t>(PageData, Pos);
7991   uint16_t NumEntries = readNext<uint16_t>(PageData, Pos);
7992 
7993   uint16_t EncodingsStart = readNext<uint16_t>(PageData, Pos);
7994   readNext<uint16_t>(PageData, Pos);
7995   StringRef PageEncodings = PageData.substr(EncodingsStart, StringRef::npos);
7996 
7997   Pos = EntriesStart;
7998   for (unsigned i = 0; i < NumEntries; ++i) {
7999     uint32_t Entry = readNext<uint32_t>(PageData, Pos);
8000     uint32_t FunctionOffset = FunctionBase + (Entry & 0xffffff);
8001     uint32_t EncodingIdx = Entry >> 24;
8002 
8003     uint32_t Encoding;
8004     if (EncodingIdx < CommonEncodings.size())
8005       Encoding = CommonEncodings[EncodingIdx];
8006     else
8007       Encoding = read<uint32_t>(PageEncodings,
8008                                 sizeof(uint32_t) *
8009                                     (EncodingIdx - CommonEncodings.size()));
8010 
8011     outs() << "      [" << i << "]: "
8012            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
8013            << ", "
8014            << "encoding[" << EncodingIdx
8015            << "]=" << format("0x%08" PRIx32, Encoding) << '\n';
8016   }
8017 }
8018 
8019 static void printMachOUnwindInfoSection(const MachOObjectFile *Obj,
8020                                         std::map<uint64_t, SymbolRef> &Symbols,
8021                                         const SectionRef &UnwindInfo) {
8022 
8023   if (!Obj->isLittleEndian()) {
8024     outs() << "Skipping big-endian __unwind_info section\n";
8025     return;
8026   }
8027 
8028   outs() << "Contents of __unwind_info section:\n";
8029 
8030   StringRef Contents =
8031       unwrapOrError(UnwindInfo.getContents(), Obj->getFileName());
8032   ptrdiff_t Pos = 0;
8033 
8034   //===----------------------------------
8035   // Section header
8036   //===----------------------------------
8037 
8038   uint32_t Version = readNext<uint32_t>(Contents, Pos);
8039   outs() << "  Version:                                   "
8040          << format("0x%" PRIx32, Version) << '\n';
8041   if (Version != 1) {
8042     outs() << "    Skipping section with unknown version\n";
8043     return;
8044   }
8045 
8046   uint32_t CommonEncodingsStart = readNext<uint32_t>(Contents, Pos);
8047   outs() << "  Common encodings array section offset:     "
8048          << format("0x%" PRIx32, CommonEncodingsStart) << '\n';
8049   uint32_t NumCommonEncodings = readNext<uint32_t>(Contents, Pos);
8050   outs() << "  Number of common encodings in array:       "
8051          << format("0x%" PRIx32, NumCommonEncodings) << '\n';
8052 
8053   uint32_t PersonalitiesStart = readNext<uint32_t>(Contents, Pos);
8054   outs() << "  Personality function array section offset: "
8055          << format("0x%" PRIx32, PersonalitiesStart) << '\n';
8056   uint32_t NumPersonalities = readNext<uint32_t>(Contents, Pos);
8057   outs() << "  Number of personality functions in array:  "
8058          << format("0x%" PRIx32, NumPersonalities) << '\n';
8059 
8060   uint32_t IndicesStart = readNext<uint32_t>(Contents, Pos);
8061   outs() << "  Index array section offset:                "
8062          << format("0x%" PRIx32, IndicesStart) << '\n';
8063   uint32_t NumIndices = readNext<uint32_t>(Contents, Pos);
8064   outs() << "  Number of indices in array:                "
8065          << format("0x%" PRIx32, NumIndices) << '\n';
8066 
8067   //===----------------------------------
8068   // A shared list of common encodings
8069   //===----------------------------------
8070 
8071   // These occupy indices in the range [0, N] whenever an encoding is referenced
8072   // from a compressed 2nd level index table. In practice the linker only
8073   // creates ~128 of these, so that indices are available to embed encodings in
8074   // the 2nd level index.
8075 
8076   SmallVector<uint32_t, 64> CommonEncodings;
8077   outs() << "  Common encodings: (count = " << NumCommonEncodings << ")\n";
8078   Pos = CommonEncodingsStart;
8079   for (unsigned i = 0; i < NumCommonEncodings; ++i) {
8080     uint32_t Encoding = readNext<uint32_t>(Contents, Pos);
8081     CommonEncodings.push_back(Encoding);
8082 
8083     outs() << "    encoding[" << i << "]: " << format("0x%08" PRIx32, Encoding)
8084            << '\n';
8085   }
8086 
8087   //===----------------------------------
8088   // Personality functions used in this executable
8089   //===----------------------------------
8090 
8091   // There should be only a handful of these (one per source language,
8092   // roughly). Particularly since they only get 2 bits in the compact encoding.
8093 
8094   outs() << "  Personality functions: (count = " << NumPersonalities << ")\n";
8095   Pos = PersonalitiesStart;
8096   for (unsigned i = 0; i < NumPersonalities; ++i) {
8097     uint32_t PersonalityFn = readNext<uint32_t>(Contents, Pos);
8098     outs() << "    personality[" << i + 1
8099            << "]: " << format("0x%08" PRIx32, PersonalityFn) << '\n';
8100   }
8101 
8102   //===----------------------------------
8103   // The level 1 index entries
8104   //===----------------------------------
8105 
8106   // These specify an approximate place to start searching for the more detailed
8107   // information, sorted by PC.
8108 
8109   struct IndexEntry {
8110     uint32_t FunctionOffset;
8111     uint32_t SecondLevelPageStart;
8112     uint32_t LSDAStart;
8113   };
8114 
8115   SmallVector<IndexEntry, 4> IndexEntries;
8116 
8117   outs() << "  Top level indices: (count = " << NumIndices << ")\n";
8118   Pos = IndicesStart;
8119   for (unsigned i = 0; i < NumIndices; ++i) {
8120     IndexEntry Entry;
8121 
8122     Entry.FunctionOffset = readNext<uint32_t>(Contents, Pos);
8123     Entry.SecondLevelPageStart = readNext<uint32_t>(Contents, Pos);
8124     Entry.LSDAStart = readNext<uint32_t>(Contents, Pos);
8125     IndexEntries.push_back(Entry);
8126 
8127     outs() << "    [" << i << "]: "
8128            << "function offset=" << format("0x%08" PRIx32, Entry.FunctionOffset)
8129            << ", "
8130            << "2nd level page offset="
8131            << format("0x%08" PRIx32, Entry.SecondLevelPageStart) << ", "
8132            << "LSDA offset=" << format("0x%08" PRIx32, Entry.LSDAStart) << '\n';
8133   }
8134 
8135   //===----------------------------------
8136   // Next come the LSDA tables
8137   //===----------------------------------
8138 
8139   // The LSDA layout is rather implicit: it's a contiguous array of entries from
8140   // the first top-level index's LSDAOffset to the last (sentinel).
8141 
8142   outs() << "  LSDA descriptors:\n";
8143   Pos = IndexEntries[0].LSDAStart;
8144   const uint32_t LSDASize = 2 * sizeof(uint32_t);
8145   int NumLSDAs =
8146       (IndexEntries.back().LSDAStart - IndexEntries[0].LSDAStart) / LSDASize;
8147 
8148   for (int i = 0; i < NumLSDAs; ++i) {
8149     uint32_t FunctionOffset = readNext<uint32_t>(Contents, Pos);
8150     uint32_t LSDAOffset = readNext<uint32_t>(Contents, Pos);
8151     outs() << "    [" << i << "]: "
8152            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
8153            << ", "
8154            << "LSDA offset=" << format("0x%08" PRIx32, LSDAOffset) << '\n';
8155   }
8156 
8157   //===----------------------------------
8158   // Finally, the 2nd level indices
8159   //===----------------------------------
8160 
8161   // Generally these are 4K in size, and have 2 possible forms:
8162   //   + Regular stores up to 511 entries with disparate encodings
8163   //   + Compressed stores up to 1021 entries if few enough compact encoding
8164   //     values are used.
8165   outs() << "  Second level indices:\n";
8166   for (unsigned i = 0; i < IndexEntries.size() - 1; ++i) {
8167     // The final sentinel top-level index has no associated 2nd level page
8168     if (IndexEntries[i].SecondLevelPageStart == 0)
8169       break;
8170 
8171     outs() << "    Second level index[" << i << "]: "
8172            << "offset in section="
8173            << format("0x%08" PRIx32, IndexEntries[i].SecondLevelPageStart)
8174            << ", "
8175            << "base function offset="
8176            << format("0x%08" PRIx32, IndexEntries[i].FunctionOffset) << '\n';
8177 
8178     Pos = IndexEntries[i].SecondLevelPageStart;
8179     if (Pos + sizeof(uint32_t) > Contents.size()) {
8180       outs() << "warning: invalid offset for second level page: " << Pos << '\n';
8181       continue;
8182     }
8183 
8184     uint32_t Kind =
8185         *reinterpret_cast<const support::ulittle32_t *>(Contents.data() + Pos);
8186     if (Kind == 2)
8187       printRegularSecondLevelUnwindPage(Contents.substr(Pos, 4096));
8188     else if (Kind == 3)
8189       printCompressedSecondLevelUnwindPage(Contents.substr(Pos, 4096),
8190                                            IndexEntries[i].FunctionOffset,
8191                                            CommonEncodings);
8192     else
8193       outs() << "    Skipping 2nd level page with unknown kind " << Kind
8194              << '\n';
8195   }
8196 }
8197 
8198 void objdump::printMachOUnwindInfo(const MachOObjectFile *Obj) {
8199   std::map<uint64_t, SymbolRef> Symbols;
8200   for (const SymbolRef &SymRef : Obj->symbols()) {
8201     // Discard any undefined or absolute symbols. They're not going to take part
8202     // in the convenience lookup for unwind info and just take up resources.
8203     auto SectOrErr = SymRef.getSection();
8204     if (!SectOrErr) {
8205       // TODO: Actually report errors helpfully.
8206       consumeError(SectOrErr.takeError());
8207       continue;
8208     }
8209     section_iterator Section = *SectOrErr;
8210     if (Section == Obj->section_end())
8211       continue;
8212 
8213     uint64_t Addr = cantFail(SymRef.getValue());
8214     Symbols.insert(std::make_pair(Addr, SymRef));
8215   }
8216 
8217   for (const SectionRef &Section : Obj->sections()) {
8218     StringRef SectName;
8219     if (Expected<StringRef> NameOrErr = Section.getName())
8220       SectName = *NameOrErr;
8221     else
8222       consumeError(NameOrErr.takeError());
8223 
8224     if (SectName == "__compact_unwind")
8225       printMachOCompactUnwindSection(Obj, Symbols, Section);
8226     else if (SectName == "__unwind_info")
8227       printMachOUnwindInfoSection(Obj, Symbols, Section);
8228   }
8229 }
8230 
8231 static void PrintMachHeader(uint32_t magic, uint32_t cputype,
8232                             uint32_t cpusubtype, uint32_t filetype,
8233                             uint32_t ncmds, uint32_t sizeofcmds, uint32_t flags,
8234                             bool verbose) {
8235   outs() << "Mach header\n";
8236   outs() << "      magic cputype cpusubtype  caps    filetype ncmds "
8237             "sizeofcmds      flags\n";
8238   if (verbose) {
8239     if (magic == MachO::MH_MAGIC)
8240       outs() << "   MH_MAGIC";
8241     else if (magic == MachO::MH_MAGIC_64)
8242       outs() << "MH_MAGIC_64";
8243     else
8244       outs() << format(" 0x%08" PRIx32, magic);
8245     switch (cputype) {
8246     case MachO::CPU_TYPE_I386:
8247       outs() << "    I386";
8248       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8249       case MachO::CPU_SUBTYPE_I386_ALL:
8250         outs() << "        ALL";
8251         break;
8252       default:
8253         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8254         break;
8255       }
8256       break;
8257     case MachO::CPU_TYPE_X86_64:
8258       outs() << "  X86_64";
8259       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8260       case MachO::CPU_SUBTYPE_X86_64_ALL:
8261         outs() << "        ALL";
8262         break;
8263       case MachO::CPU_SUBTYPE_X86_64_H:
8264         outs() << "    Haswell";
8265         break;
8266       default:
8267         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8268         break;
8269       }
8270       break;
8271     case MachO::CPU_TYPE_ARM:
8272       outs() << "     ARM";
8273       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8274       case MachO::CPU_SUBTYPE_ARM_ALL:
8275         outs() << "        ALL";
8276         break;
8277       case MachO::CPU_SUBTYPE_ARM_V4T:
8278         outs() << "        V4T";
8279         break;
8280       case MachO::CPU_SUBTYPE_ARM_V5TEJ:
8281         outs() << "      V5TEJ";
8282         break;
8283       case MachO::CPU_SUBTYPE_ARM_XSCALE:
8284         outs() << "     XSCALE";
8285         break;
8286       case MachO::CPU_SUBTYPE_ARM_V6:
8287         outs() << "         V6";
8288         break;
8289       case MachO::CPU_SUBTYPE_ARM_V6M:
8290         outs() << "        V6M";
8291         break;
8292       case MachO::CPU_SUBTYPE_ARM_V7:
8293         outs() << "         V7";
8294         break;
8295       case MachO::CPU_SUBTYPE_ARM_V7EM:
8296         outs() << "       V7EM";
8297         break;
8298       case MachO::CPU_SUBTYPE_ARM_V7K:
8299         outs() << "        V7K";
8300         break;
8301       case MachO::CPU_SUBTYPE_ARM_V7M:
8302         outs() << "        V7M";
8303         break;
8304       case MachO::CPU_SUBTYPE_ARM_V7S:
8305         outs() << "        V7S";
8306         break;
8307       default:
8308         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8309         break;
8310       }
8311       break;
8312     case MachO::CPU_TYPE_ARM64:
8313       outs() << "   ARM64";
8314       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8315       case MachO::CPU_SUBTYPE_ARM64_ALL:
8316         outs() << "        ALL";
8317         break;
8318       case MachO::CPU_SUBTYPE_ARM64E:
8319         outs() << "          E";
8320         break;
8321       default:
8322         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8323         break;
8324       }
8325       break;
8326     case MachO::CPU_TYPE_ARM64_32:
8327       outs() << " ARM64_32";
8328       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8329       case MachO::CPU_SUBTYPE_ARM64_32_V8:
8330         outs() << "        V8";
8331         break;
8332       default:
8333         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8334         break;
8335       }
8336       break;
8337     case MachO::CPU_TYPE_POWERPC:
8338       outs() << "     PPC";
8339       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8340       case MachO::CPU_SUBTYPE_POWERPC_ALL:
8341         outs() << "        ALL";
8342         break;
8343       default:
8344         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8345         break;
8346       }
8347       break;
8348     case MachO::CPU_TYPE_POWERPC64:
8349       outs() << "   PPC64";
8350       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8351       case MachO::CPU_SUBTYPE_POWERPC_ALL:
8352         outs() << "        ALL";
8353         break;
8354       default:
8355         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8356         break;
8357       }
8358       break;
8359     default:
8360       outs() << format(" %7d", cputype);
8361       outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8362       break;
8363     }
8364     if ((cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64) {
8365       outs() << " LIB64";
8366     } else {
8367       outs() << format("  0x%02" PRIx32,
8368                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
8369     }
8370     switch (filetype) {
8371     case MachO::MH_OBJECT:
8372       outs() << "      OBJECT";
8373       break;
8374     case MachO::MH_EXECUTE:
8375       outs() << "     EXECUTE";
8376       break;
8377     case MachO::MH_FVMLIB:
8378       outs() << "      FVMLIB";
8379       break;
8380     case MachO::MH_CORE:
8381       outs() << "        CORE";
8382       break;
8383     case MachO::MH_PRELOAD:
8384       outs() << "     PRELOAD";
8385       break;
8386     case MachO::MH_DYLIB:
8387       outs() << "       DYLIB";
8388       break;
8389     case MachO::MH_DYLIB_STUB:
8390       outs() << "  DYLIB_STUB";
8391       break;
8392     case MachO::MH_DYLINKER:
8393       outs() << "    DYLINKER";
8394       break;
8395     case MachO::MH_BUNDLE:
8396       outs() << "      BUNDLE";
8397       break;
8398     case MachO::MH_DSYM:
8399       outs() << "        DSYM";
8400       break;
8401     case MachO::MH_KEXT_BUNDLE:
8402       outs() << "  KEXTBUNDLE";
8403       break;
8404     default:
8405       outs() << format("  %10u", filetype);
8406       break;
8407     }
8408     outs() << format(" %5u", ncmds);
8409     outs() << format(" %10u", sizeofcmds);
8410     uint32_t f = flags;
8411     if (f & MachO::MH_NOUNDEFS) {
8412       outs() << "   NOUNDEFS";
8413       f &= ~MachO::MH_NOUNDEFS;
8414     }
8415     if (f & MachO::MH_INCRLINK) {
8416       outs() << " INCRLINK";
8417       f &= ~MachO::MH_INCRLINK;
8418     }
8419     if (f & MachO::MH_DYLDLINK) {
8420       outs() << " DYLDLINK";
8421       f &= ~MachO::MH_DYLDLINK;
8422     }
8423     if (f & MachO::MH_BINDATLOAD) {
8424       outs() << " BINDATLOAD";
8425       f &= ~MachO::MH_BINDATLOAD;
8426     }
8427     if (f & MachO::MH_PREBOUND) {
8428       outs() << " PREBOUND";
8429       f &= ~MachO::MH_PREBOUND;
8430     }
8431     if (f & MachO::MH_SPLIT_SEGS) {
8432       outs() << " SPLIT_SEGS";
8433       f &= ~MachO::MH_SPLIT_SEGS;
8434     }
8435     if (f & MachO::MH_LAZY_INIT) {
8436       outs() << " LAZY_INIT";
8437       f &= ~MachO::MH_LAZY_INIT;
8438     }
8439     if (f & MachO::MH_TWOLEVEL) {
8440       outs() << " TWOLEVEL";
8441       f &= ~MachO::MH_TWOLEVEL;
8442     }
8443     if (f & MachO::MH_FORCE_FLAT) {
8444       outs() << " FORCE_FLAT";
8445       f &= ~MachO::MH_FORCE_FLAT;
8446     }
8447     if (f & MachO::MH_NOMULTIDEFS) {
8448       outs() << " NOMULTIDEFS";
8449       f &= ~MachO::MH_NOMULTIDEFS;
8450     }
8451     if (f & MachO::MH_NOFIXPREBINDING) {
8452       outs() << " NOFIXPREBINDING";
8453       f &= ~MachO::MH_NOFIXPREBINDING;
8454     }
8455     if (f & MachO::MH_PREBINDABLE) {
8456       outs() << " PREBINDABLE";
8457       f &= ~MachO::MH_PREBINDABLE;
8458     }
8459     if (f & MachO::MH_ALLMODSBOUND) {
8460       outs() << " ALLMODSBOUND";
8461       f &= ~MachO::MH_ALLMODSBOUND;
8462     }
8463     if (f & MachO::MH_SUBSECTIONS_VIA_SYMBOLS) {
8464       outs() << " SUBSECTIONS_VIA_SYMBOLS";
8465       f &= ~MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
8466     }
8467     if (f & MachO::MH_CANONICAL) {
8468       outs() << " CANONICAL";
8469       f &= ~MachO::MH_CANONICAL;
8470     }
8471     if (f & MachO::MH_WEAK_DEFINES) {
8472       outs() << " WEAK_DEFINES";
8473       f &= ~MachO::MH_WEAK_DEFINES;
8474     }
8475     if (f & MachO::MH_BINDS_TO_WEAK) {
8476       outs() << " BINDS_TO_WEAK";
8477       f &= ~MachO::MH_BINDS_TO_WEAK;
8478     }
8479     if (f & MachO::MH_ALLOW_STACK_EXECUTION) {
8480       outs() << " ALLOW_STACK_EXECUTION";
8481       f &= ~MachO::MH_ALLOW_STACK_EXECUTION;
8482     }
8483     if (f & MachO::MH_DEAD_STRIPPABLE_DYLIB) {
8484       outs() << " DEAD_STRIPPABLE_DYLIB";
8485       f &= ~MachO::MH_DEAD_STRIPPABLE_DYLIB;
8486     }
8487     if (f & MachO::MH_PIE) {
8488       outs() << " PIE";
8489       f &= ~MachO::MH_PIE;
8490     }
8491     if (f & MachO::MH_NO_REEXPORTED_DYLIBS) {
8492       outs() << " NO_REEXPORTED_DYLIBS";
8493       f &= ~MachO::MH_NO_REEXPORTED_DYLIBS;
8494     }
8495     if (f & MachO::MH_HAS_TLV_DESCRIPTORS) {
8496       outs() << " MH_HAS_TLV_DESCRIPTORS";
8497       f &= ~MachO::MH_HAS_TLV_DESCRIPTORS;
8498     }
8499     if (f & MachO::MH_NO_HEAP_EXECUTION) {
8500       outs() << " MH_NO_HEAP_EXECUTION";
8501       f &= ~MachO::MH_NO_HEAP_EXECUTION;
8502     }
8503     if (f & MachO::MH_APP_EXTENSION_SAFE) {
8504       outs() << " APP_EXTENSION_SAFE";
8505       f &= ~MachO::MH_APP_EXTENSION_SAFE;
8506     }
8507     if (f & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) {
8508       outs() << " NLIST_OUTOFSYNC_WITH_DYLDINFO";
8509       f &= ~MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO;
8510     }
8511     if (f != 0 || flags == 0)
8512       outs() << format(" 0x%08" PRIx32, f);
8513   } else {
8514     outs() << format(" 0x%08" PRIx32, magic);
8515     outs() << format(" %7d", cputype);
8516     outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8517     outs() << format("  0x%02" PRIx32,
8518                      (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
8519     outs() << format("  %10u", filetype);
8520     outs() << format(" %5u", ncmds);
8521     outs() << format(" %10u", sizeofcmds);
8522     outs() << format(" 0x%08" PRIx32, flags);
8523   }
8524   outs() << "\n";
8525 }
8526 
8527 static void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize,
8528                                 StringRef SegName, uint64_t vmaddr,
8529                                 uint64_t vmsize, uint64_t fileoff,
8530                                 uint64_t filesize, uint32_t maxprot,
8531                                 uint32_t initprot, uint32_t nsects,
8532                                 uint32_t flags, uint32_t object_size,
8533                                 bool verbose) {
8534   uint64_t expected_cmdsize;
8535   if (cmd == MachO::LC_SEGMENT) {
8536     outs() << "      cmd LC_SEGMENT\n";
8537     expected_cmdsize = nsects;
8538     expected_cmdsize *= sizeof(struct MachO::section);
8539     expected_cmdsize += sizeof(struct MachO::segment_command);
8540   } else {
8541     outs() << "      cmd LC_SEGMENT_64\n";
8542     expected_cmdsize = nsects;
8543     expected_cmdsize *= sizeof(struct MachO::section_64);
8544     expected_cmdsize += sizeof(struct MachO::segment_command_64);
8545   }
8546   outs() << "  cmdsize " << cmdsize;
8547   if (cmdsize != expected_cmdsize)
8548     outs() << " Inconsistent size\n";
8549   else
8550     outs() << "\n";
8551   outs() << "  segname " << SegName << "\n";
8552   if (cmd == MachO::LC_SEGMENT_64) {
8553     outs() << "   vmaddr " << format("0x%016" PRIx64, vmaddr) << "\n";
8554     outs() << "   vmsize " << format("0x%016" PRIx64, vmsize) << "\n";
8555   } else {
8556     outs() << "   vmaddr " << format("0x%08" PRIx64, vmaddr) << "\n";
8557     outs() << "   vmsize " << format("0x%08" PRIx64, vmsize) << "\n";
8558   }
8559   outs() << "  fileoff " << fileoff;
8560   if (fileoff > object_size)
8561     outs() << " (past end of file)\n";
8562   else
8563     outs() << "\n";
8564   outs() << " filesize " << filesize;
8565   if (fileoff + filesize > object_size)
8566     outs() << " (past end of file)\n";
8567   else
8568     outs() << "\n";
8569   if (verbose) {
8570     if ((maxprot &
8571          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
8572            MachO::VM_PROT_EXECUTE)) != 0)
8573       outs() << "  maxprot ?" << format("0x%08" PRIx32, maxprot) << "\n";
8574     else {
8575       outs() << "  maxprot ";
8576       outs() << ((maxprot & MachO::VM_PROT_READ) ? "r" : "-");
8577       outs() << ((maxprot & MachO::VM_PROT_WRITE) ? "w" : "-");
8578       outs() << ((maxprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
8579     }
8580     if ((initprot &
8581          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
8582            MachO::VM_PROT_EXECUTE)) != 0)
8583       outs() << " initprot ?" << format("0x%08" PRIx32, initprot) << "\n";
8584     else {
8585       outs() << " initprot ";
8586       outs() << ((initprot & MachO::VM_PROT_READ) ? "r" : "-");
8587       outs() << ((initprot & MachO::VM_PROT_WRITE) ? "w" : "-");
8588       outs() << ((initprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
8589     }
8590   } else {
8591     outs() << "  maxprot " << format("0x%08" PRIx32, maxprot) << "\n";
8592     outs() << " initprot " << format("0x%08" PRIx32, initprot) << "\n";
8593   }
8594   outs() << "   nsects " << nsects << "\n";
8595   if (verbose) {
8596     outs() << "    flags";
8597     if (flags == 0)
8598       outs() << " (none)\n";
8599     else {
8600       if (flags & MachO::SG_HIGHVM) {
8601         outs() << " HIGHVM";
8602         flags &= ~MachO::SG_HIGHVM;
8603       }
8604       if (flags & MachO::SG_FVMLIB) {
8605         outs() << " FVMLIB";
8606         flags &= ~MachO::SG_FVMLIB;
8607       }
8608       if (flags & MachO::SG_NORELOC) {
8609         outs() << " NORELOC";
8610         flags &= ~MachO::SG_NORELOC;
8611       }
8612       if (flags & MachO::SG_PROTECTED_VERSION_1) {
8613         outs() << " PROTECTED_VERSION_1";
8614         flags &= ~MachO::SG_PROTECTED_VERSION_1;
8615       }
8616       if (flags)
8617         outs() << format(" 0x%08" PRIx32, flags) << " (unknown flags)\n";
8618       else
8619         outs() << "\n";
8620     }
8621   } else {
8622     outs() << "    flags " << format("0x%" PRIx32, flags) << "\n";
8623   }
8624 }
8625 
8626 static void PrintSection(const char *sectname, const char *segname,
8627                          uint64_t addr, uint64_t size, uint32_t offset,
8628                          uint32_t align, uint32_t reloff, uint32_t nreloc,
8629                          uint32_t flags, uint32_t reserved1, uint32_t reserved2,
8630                          uint32_t cmd, const char *sg_segname,
8631                          uint32_t filetype, uint32_t object_size,
8632                          bool verbose) {
8633   outs() << "Section\n";
8634   outs() << "  sectname " << format("%.16s\n", sectname);
8635   outs() << "   segname " << format("%.16s", segname);
8636   if (filetype != MachO::MH_OBJECT && strncmp(sg_segname, segname, 16) != 0)
8637     outs() << " (does not match segment)\n";
8638   else
8639     outs() << "\n";
8640   if (cmd == MachO::LC_SEGMENT_64) {
8641     outs() << "      addr " << format("0x%016" PRIx64, addr) << "\n";
8642     outs() << "      size " << format("0x%016" PRIx64, size);
8643   } else {
8644     outs() << "      addr " << format("0x%08" PRIx64, addr) << "\n";
8645     outs() << "      size " << format("0x%08" PRIx64, size);
8646   }
8647   if ((flags & MachO::S_ZEROFILL) != 0 && offset + size > object_size)
8648     outs() << " (past end of file)\n";
8649   else
8650     outs() << "\n";
8651   outs() << "    offset " << offset;
8652   if (offset > object_size)
8653     outs() << " (past end of file)\n";
8654   else
8655     outs() << "\n";
8656   uint32_t align_shifted = 1 << align;
8657   outs() << "     align 2^" << align << " (" << align_shifted << ")\n";
8658   outs() << "    reloff " << reloff;
8659   if (reloff > object_size)
8660     outs() << " (past end of file)\n";
8661   else
8662     outs() << "\n";
8663   outs() << "    nreloc " << nreloc;
8664   if (reloff + nreloc * sizeof(struct MachO::relocation_info) > object_size)
8665     outs() << " (past end of file)\n";
8666   else
8667     outs() << "\n";
8668   uint32_t section_type = flags & MachO::SECTION_TYPE;
8669   if (verbose) {
8670     outs() << "      type";
8671     if (section_type == MachO::S_REGULAR)
8672       outs() << " S_REGULAR\n";
8673     else if (section_type == MachO::S_ZEROFILL)
8674       outs() << " S_ZEROFILL\n";
8675     else if (section_type == MachO::S_CSTRING_LITERALS)
8676       outs() << " S_CSTRING_LITERALS\n";
8677     else if (section_type == MachO::S_4BYTE_LITERALS)
8678       outs() << " S_4BYTE_LITERALS\n";
8679     else if (section_type == MachO::S_8BYTE_LITERALS)
8680       outs() << " S_8BYTE_LITERALS\n";
8681     else if (section_type == MachO::S_16BYTE_LITERALS)
8682       outs() << " S_16BYTE_LITERALS\n";
8683     else if (section_type == MachO::S_LITERAL_POINTERS)
8684       outs() << " S_LITERAL_POINTERS\n";
8685     else if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS)
8686       outs() << " S_NON_LAZY_SYMBOL_POINTERS\n";
8687     else if (section_type == MachO::S_LAZY_SYMBOL_POINTERS)
8688       outs() << " S_LAZY_SYMBOL_POINTERS\n";
8689     else if (section_type == MachO::S_SYMBOL_STUBS)
8690       outs() << " S_SYMBOL_STUBS\n";
8691     else if (section_type == MachO::S_MOD_INIT_FUNC_POINTERS)
8692       outs() << " S_MOD_INIT_FUNC_POINTERS\n";
8693     else if (section_type == MachO::S_MOD_TERM_FUNC_POINTERS)
8694       outs() << " S_MOD_TERM_FUNC_POINTERS\n";
8695     else if (section_type == MachO::S_COALESCED)
8696       outs() << " S_COALESCED\n";
8697     else if (section_type == MachO::S_INTERPOSING)
8698       outs() << " S_INTERPOSING\n";
8699     else if (section_type == MachO::S_DTRACE_DOF)
8700       outs() << " S_DTRACE_DOF\n";
8701     else if (section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS)
8702       outs() << " S_LAZY_DYLIB_SYMBOL_POINTERS\n";
8703     else if (section_type == MachO::S_THREAD_LOCAL_REGULAR)
8704       outs() << " S_THREAD_LOCAL_REGULAR\n";
8705     else if (section_type == MachO::S_THREAD_LOCAL_ZEROFILL)
8706       outs() << " S_THREAD_LOCAL_ZEROFILL\n";
8707     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLES)
8708       outs() << " S_THREAD_LOCAL_VARIABLES\n";
8709     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
8710       outs() << " S_THREAD_LOCAL_VARIABLE_POINTERS\n";
8711     else if (section_type == MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS)
8712       outs() << " S_THREAD_LOCAL_INIT_FUNCTION_POINTERS\n";
8713     else
8714       outs() << format("0x%08" PRIx32, section_type) << "\n";
8715     outs() << "attributes";
8716     uint32_t section_attributes = flags & MachO::SECTION_ATTRIBUTES;
8717     if (section_attributes & MachO::S_ATTR_PURE_INSTRUCTIONS)
8718       outs() << " PURE_INSTRUCTIONS";
8719     if (section_attributes & MachO::S_ATTR_NO_TOC)
8720       outs() << " NO_TOC";
8721     if (section_attributes & MachO::S_ATTR_STRIP_STATIC_SYMS)
8722       outs() << " STRIP_STATIC_SYMS";
8723     if (section_attributes & MachO::S_ATTR_NO_DEAD_STRIP)
8724       outs() << " NO_DEAD_STRIP";
8725     if (section_attributes & MachO::S_ATTR_LIVE_SUPPORT)
8726       outs() << " LIVE_SUPPORT";
8727     if (section_attributes & MachO::S_ATTR_SELF_MODIFYING_CODE)
8728       outs() << " SELF_MODIFYING_CODE";
8729     if (section_attributes & MachO::S_ATTR_DEBUG)
8730       outs() << " DEBUG";
8731     if (section_attributes & MachO::S_ATTR_SOME_INSTRUCTIONS)
8732       outs() << " SOME_INSTRUCTIONS";
8733     if (section_attributes & MachO::S_ATTR_EXT_RELOC)
8734       outs() << " EXT_RELOC";
8735     if (section_attributes & MachO::S_ATTR_LOC_RELOC)
8736       outs() << " LOC_RELOC";
8737     if (section_attributes == 0)
8738       outs() << " (none)";
8739     outs() << "\n";
8740   } else
8741     outs() << "     flags " << format("0x%08" PRIx32, flags) << "\n";
8742   outs() << " reserved1 " << reserved1;
8743   if (section_type == MachO::S_SYMBOL_STUBS ||
8744       section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
8745       section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
8746       section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
8747       section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
8748     outs() << " (index into indirect symbol table)\n";
8749   else
8750     outs() << "\n";
8751   outs() << " reserved2 " << reserved2;
8752   if (section_type == MachO::S_SYMBOL_STUBS)
8753     outs() << " (size of stubs)\n";
8754   else
8755     outs() << "\n";
8756 }
8757 
8758 static void PrintSymtabLoadCommand(MachO::symtab_command st, bool Is64Bit,
8759                                    uint32_t object_size) {
8760   outs() << "     cmd LC_SYMTAB\n";
8761   outs() << " cmdsize " << st.cmdsize;
8762   if (st.cmdsize != sizeof(struct MachO::symtab_command))
8763     outs() << " Incorrect size\n";
8764   else
8765     outs() << "\n";
8766   outs() << "  symoff " << st.symoff;
8767   if (st.symoff > object_size)
8768     outs() << " (past end of file)\n";
8769   else
8770     outs() << "\n";
8771   outs() << "   nsyms " << st.nsyms;
8772   uint64_t big_size;
8773   if (Is64Bit) {
8774     big_size = st.nsyms;
8775     big_size *= sizeof(struct MachO::nlist_64);
8776     big_size += st.symoff;
8777     if (big_size > object_size)
8778       outs() << " (past end of file)\n";
8779     else
8780       outs() << "\n";
8781   } else {
8782     big_size = st.nsyms;
8783     big_size *= sizeof(struct MachO::nlist);
8784     big_size += st.symoff;
8785     if (big_size > object_size)
8786       outs() << " (past end of file)\n";
8787     else
8788       outs() << "\n";
8789   }
8790   outs() << "  stroff " << st.stroff;
8791   if (st.stroff > object_size)
8792     outs() << " (past end of file)\n";
8793   else
8794     outs() << "\n";
8795   outs() << " strsize " << st.strsize;
8796   big_size = st.stroff;
8797   big_size += st.strsize;
8798   if (big_size > object_size)
8799     outs() << " (past end of file)\n";
8800   else
8801     outs() << "\n";
8802 }
8803 
8804 static void PrintDysymtabLoadCommand(MachO::dysymtab_command dyst,
8805                                      uint32_t nsyms, uint32_t object_size,
8806                                      bool Is64Bit) {
8807   outs() << "            cmd LC_DYSYMTAB\n";
8808   outs() << "        cmdsize " << dyst.cmdsize;
8809   if (dyst.cmdsize != sizeof(struct MachO::dysymtab_command))
8810     outs() << " Incorrect size\n";
8811   else
8812     outs() << "\n";
8813   outs() << "      ilocalsym " << dyst.ilocalsym;
8814   if (dyst.ilocalsym > nsyms)
8815     outs() << " (greater than the number of symbols)\n";
8816   else
8817     outs() << "\n";
8818   outs() << "      nlocalsym " << dyst.nlocalsym;
8819   uint64_t big_size;
8820   big_size = dyst.ilocalsym;
8821   big_size += dyst.nlocalsym;
8822   if (big_size > nsyms)
8823     outs() << " (past the end of the symbol table)\n";
8824   else
8825     outs() << "\n";
8826   outs() << "     iextdefsym " << dyst.iextdefsym;
8827   if (dyst.iextdefsym > nsyms)
8828     outs() << " (greater than the number of symbols)\n";
8829   else
8830     outs() << "\n";
8831   outs() << "     nextdefsym " << dyst.nextdefsym;
8832   big_size = dyst.iextdefsym;
8833   big_size += dyst.nextdefsym;
8834   if (big_size > nsyms)
8835     outs() << " (past the end of the symbol table)\n";
8836   else
8837     outs() << "\n";
8838   outs() << "      iundefsym " << dyst.iundefsym;
8839   if (dyst.iundefsym > nsyms)
8840     outs() << " (greater than the number of symbols)\n";
8841   else
8842     outs() << "\n";
8843   outs() << "      nundefsym " << dyst.nundefsym;
8844   big_size = dyst.iundefsym;
8845   big_size += dyst.nundefsym;
8846   if (big_size > nsyms)
8847     outs() << " (past the end of the symbol table)\n";
8848   else
8849     outs() << "\n";
8850   outs() << "         tocoff " << dyst.tocoff;
8851   if (dyst.tocoff > object_size)
8852     outs() << " (past end of file)\n";
8853   else
8854     outs() << "\n";
8855   outs() << "           ntoc " << dyst.ntoc;
8856   big_size = dyst.ntoc;
8857   big_size *= sizeof(struct MachO::dylib_table_of_contents);
8858   big_size += dyst.tocoff;
8859   if (big_size > object_size)
8860     outs() << " (past end of file)\n";
8861   else
8862     outs() << "\n";
8863   outs() << "      modtaboff " << dyst.modtaboff;
8864   if (dyst.modtaboff > object_size)
8865     outs() << " (past end of file)\n";
8866   else
8867     outs() << "\n";
8868   outs() << "        nmodtab " << dyst.nmodtab;
8869   uint64_t modtabend;
8870   if (Is64Bit) {
8871     modtabend = dyst.nmodtab;
8872     modtabend *= sizeof(struct MachO::dylib_module_64);
8873     modtabend += dyst.modtaboff;
8874   } else {
8875     modtabend = dyst.nmodtab;
8876     modtabend *= sizeof(struct MachO::dylib_module);
8877     modtabend += dyst.modtaboff;
8878   }
8879   if (modtabend > object_size)
8880     outs() << " (past end of file)\n";
8881   else
8882     outs() << "\n";
8883   outs() << "   extrefsymoff " << dyst.extrefsymoff;
8884   if (dyst.extrefsymoff > object_size)
8885     outs() << " (past end of file)\n";
8886   else
8887     outs() << "\n";
8888   outs() << "    nextrefsyms " << dyst.nextrefsyms;
8889   big_size = dyst.nextrefsyms;
8890   big_size *= sizeof(struct MachO::dylib_reference);
8891   big_size += dyst.extrefsymoff;
8892   if (big_size > object_size)
8893     outs() << " (past end of file)\n";
8894   else
8895     outs() << "\n";
8896   outs() << " indirectsymoff " << dyst.indirectsymoff;
8897   if (dyst.indirectsymoff > object_size)
8898     outs() << " (past end of file)\n";
8899   else
8900     outs() << "\n";
8901   outs() << "  nindirectsyms " << dyst.nindirectsyms;
8902   big_size = dyst.nindirectsyms;
8903   big_size *= sizeof(uint32_t);
8904   big_size += dyst.indirectsymoff;
8905   if (big_size > object_size)
8906     outs() << " (past end of file)\n";
8907   else
8908     outs() << "\n";
8909   outs() << "      extreloff " << dyst.extreloff;
8910   if (dyst.extreloff > object_size)
8911     outs() << " (past end of file)\n";
8912   else
8913     outs() << "\n";
8914   outs() << "        nextrel " << dyst.nextrel;
8915   big_size = dyst.nextrel;
8916   big_size *= sizeof(struct MachO::relocation_info);
8917   big_size += dyst.extreloff;
8918   if (big_size > object_size)
8919     outs() << " (past end of file)\n";
8920   else
8921     outs() << "\n";
8922   outs() << "      locreloff " << dyst.locreloff;
8923   if (dyst.locreloff > object_size)
8924     outs() << " (past end of file)\n";
8925   else
8926     outs() << "\n";
8927   outs() << "        nlocrel " << dyst.nlocrel;
8928   big_size = dyst.nlocrel;
8929   big_size *= sizeof(struct MachO::relocation_info);
8930   big_size += dyst.locreloff;
8931   if (big_size > object_size)
8932     outs() << " (past end of file)\n";
8933   else
8934     outs() << "\n";
8935 }
8936 
8937 static void PrintDyldInfoLoadCommand(MachO::dyld_info_command dc,
8938                                      uint32_t object_size) {
8939   if (dc.cmd == MachO::LC_DYLD_INFO)
8940     outs() << "            cmd LC_DYLD_INFO\n";
8941   else
8942     outs() << "            cmd LC_DYLD_INFO_ONLY\n";
8943   outs() << "        cmdsize " << dc.cmdsize;
8944   if (dc.cmdsize != sizeof(struct MachO::dyld_info_command))
8945     outs() << " Incorrect size\n";
8946   else
8947     outs() << "\n";
8948   outs() << "     rebase_off " << dc.rebase_off;
8949   if (dc.rebase_off > object_size)
8950     outs() << " (past end of file)\n";
8951   else
8952     outs() << "\n";
8953   outs() << "    rebase_size " << dc.rebase_size;
8954   uint64_t big_size;
8955   big_size = dc.rebase_off;
8956   big_size += dc.rebase_size;
8957   if (big_size > object_size)
8958     outs() << " (past end of file)\n";
8959   else
8960     outs() << "\n";
8961   outs() << "       bind_off " << dc.bind_off;
8962   if (dc.bind_off > object_size)
8963     outs() << " (past end of file)\n";
8964   else
8965     outs() << "\n";
8966   outs() << "      bind_size " << dc.bind_size;
8967   big_size = dc.bind_off;
8968   big_size += dc.bind_size;
8969   if (big_size > object_size)
8970     outs() << " (past end of file)\n";
8971   else
8972     outs() << "\n";
8973   outs() << "  weak_bind_off " << dc.weak_bind_off;
8974   if (dc.weak_bind_off > object_size)
8975     outs() << " (past end of file)\n";
8976   else
8977     outs() << "\n";
8978   outs() << " weak_bind_size " << dc.weak_bind_size;
8979   big_size = dc.weak_bind_off;
8980   big_size += dc.weak_bind_size;
8981   if (big_size > object_size)
8982     outs() << " (past end of file)\n";
8983   else
8984     outs() << "\n";
8985   outs() << "  lazy_bind_off " << dc.lazy_bind_off;
8986   if (dc.lazy_bind_off > object_size)
8987     outs() << " (past end of file)\n";
8988   else
8989     outs() << "\n";
8990   outs() << " lazy_bind_size " << dc.lazy_bind_size;
8991   big_size = dc.lazy_bind_off;
8992   big_size += dc.lazy_bind_size;
8993   if (big_size > object_size)
8994     outs() << " (past end of file)\n";
8995   else
8996     outs() << "\n";
8997   outs() << "     export_off " << dc.export_off;
8998   if (dc.export_off > object_size)
8999     outs() << " (past end of file)\n";
9000   else
9001     outs() << "\n";
9002   outs() << "    export_size " << dc.export_size;
9003   big_size = dc.export_off;
9004   big_size += dc.export_size;
9005   if (big_size > object_size)
9006     outs() << " (past end of file)\n";
9007   else
9008     outs() << "\n";
9009 }
9010 
9011 static void PrintDyldLoadCommand(MachO::dylinker_command dyld,
9012                                  const char *Ptr) {
9013   if (dyld.cmd == MachO::LC_ID_DYLINKER)
9014     outs() << "          cmd LC_ID_DYLINKER\n";
9015   else if (dyld.cmd == MachO::LC_LOAD_DYLINKER)
9016     outs() << "          cmd LC_LOAD_DYLINKER\n";
9017   else if (dyld.cmd == MachO::LC_DYLD_ENVIRONMENT)
9018     outs() << "          cmd LC_DYLD_ENVIRONMENT\n";
9019   else
9020     outs() << "          cmd ?(" << dyld.cmd << ")\n";
9021   outs() << "      cmdsize " << dyld.cmdsize;
9022   if (dyld.cmdsize < sizeof(struct MachO::dylinker_command))
9023     outs() << " Incorrect size\n";
9024   else
9025     outs() << "\n";
9026   if (dyld.name >= dyld.cmdsize)
9027     outs() << "         name ?(bad offset " << dyld.name << ")\n";
9028   else {
9029     const char *P = (const char *)(Ptr) + dyld.name;
9030     outs() << "         name " << P << " (offset " << dyld.name << ")\n";
9031   }
9032 }
9033 
9034 static void PrintUuidLoadCommand(MachO::uuid_command uuid) {
9035   outs() << "     cmd LC_UUID\n";
9036   outs() << " cmdsize " << uuid.cmdsize;
9037   if (uuid.cmdsize != sizeof(struct MachO::uuid_command))
9038     outs() << " Incorrect size\n";
9039   else
9040     outs() << "\n";
9041   outs() << "    uuid ";
9042   for (int i = 0; i < 16; ++i) {
9043     outs() << format("%02" PRIX32, uuid.uuid[i]);
9044     if (i == 3 || i == 5 || i == 7 || i == 9)
9045       outs() << "-";
9046   }
9047   outs() << "\n";
9048 }
9049 
9050 static void PrintRpathLoadCommand(MachO::rpath_command rpath, const char *Ptr) {
9051   outs() << "          cmd LC_RPATH\n";
9052   outs() << "      cmdsize " << rpath.cmdsize;
9053   if (rpath.cmdsize < sizeof(struct MachO::rpath_command))
9054     outs() << " Incorrect size\n";
9055   else
9056     outs() << "\n";
9057   if (rpath.path >= rpath.cmdsize)
9058     outs() << "         path ?(bad offset " << rpath.path << ")\n";
9059   else {
9060     const char *P = (const char *)(Ptr) + rpath.path;
9061     outs() << "         path " << P << " (offset " << rpath.path << ")\n";
9062   }
9063 }
9064 
9065 static void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
9066   StringRef LoadCmdName;
9067   switch (vd.cmd) {
9068   case MachO::LC_VERSION_MIN_MACOSX:
9069     LoadCmdName = "LC_VERSION_MIN_MACOSX";
9070     break;
9071   case MachO::LC_VERSION_MIN_IPHONEOS:
9072     LoadCmdName = "LC_VERSION_MIN_IPHONEOS";
9073     break;
9074   case MachO::LC_VERSION_MIN_TVOS:
9075     LoadCmdName = "LC_VERSION_MIN_TVOS";
9076     break;
9077   case MachO::LC_VERSION_MIN_WATCHOS:
9078     LoadCmdName = "LC_VERSION_MIN_WATCHOS";
9079     break;
9080   default:
9081     llvm_unreachable("Unknown version min load command");
9082   }
9083 
9084   outs() << "      cmd " << LoadCmdName << '\n';
9085   outs() << "  cmdsize " << vd.cmdsize;
9086   if (vd.cmdsize != sizeof(struct MachO::version_min_command))
9087     outs() << " Incorrect size\n";
9088   else
9089     outs() << "\n";
9090   outs() << "  version "
9091          << MachOObjectFile::getVersionMinMajor(vd, false) << "."
9092          << MachOObjectFile::getVersionMinMinor(vd, false);
9093   uint32_t Update = MachOObjectFile::getVersionMinUpdate(vd, false);
9094   if (Update != 0)
9095     outs() << "." << Update;
9096   outs() << "\n";
9097   if (vd.sdk == 0)
9098     outs() << "      sdk n/a";
9099   else {
9100     outs() << "      sdk "
9101            << MachOObjectFile::getVersionMinMajor(vd, true) << "."
9102            << MachOObjectFile::getVersionMinMinor(vd, true);
9103   }
9104   Update = MachOObjectFile::getVersionMinUpdate(vd, true);
9105   if (Update != 0)
9106     outs() << "." << Update;
9107   outs() << "\n";
9108 }
9109 
9110 static void PrintNoteLoadCommand(MachO::note_command Nt) {
9111   outs() << "       cmd LC_NOTE\n";
9112   outs() << "   cmdsize " << Nt.cmdsize;
9113   if (Nt.cmdsize != sizeof(struct MachO::note_command))
9114     outs() << " Incorrect size\n";
9115   else
9116     outs() << "\n";
9117   const char *d = Nt.data_owner;
9118   outs() << "data_owner " << format("%.16s\n", d);
9119   outs() << "    offset " << Nt.offset << "\n";
9120   outs() << "      size " << Nt.size << "\n";
9121 }
9122 
9123 static void PrintBuildToolVersion(MachO::build_tool_version bv) {
9124   outs() << "      tool " << MachOObjectFile::getBuildTool(bv.tool) << "\n";
9125   outs() << "   version " << MachOObjectFile::getVersionString(bv.version)
9126          << "\n";
9127 }
9128 
9129 static void PrintBuildVersionLoadCommand(const MachOObjectFile *obj,
9130                                          MachO::build_version_command bd) {
9131   outs() << "       cmd LC_BUILD_VERSION\n";
9132   outs() << "   cmdsize " << bd.cmdsize;
9133   if (bd.cmdsize !=
9134       sizeof(struct MachO::build_version_command) +
9135           bd.ntools * sizeof(struct MachO::build_tool_version))
9136     outs() << " Incorrect size\n";
9137   else
9138     outs() << "\n";
9139   outs() << "  platform " << MachOObjectFile::getBuildPlatform(bd.platform)
9140          << "\n";
9141   if (bd.sdk)
9142     outs() << "       sdk " << MachOObjectFile::getVersionString(bd.sdk)
9143            << "\n";
9144   else
9145     outs() << "       sdk n/a\n";
9146   outs() << "     minos " << MachOObjectFile::getVersionString(bd.minos)
9147          << "\n";
9148   outs() << "    ntools " << bd.ntools << "\n";
9149   for (unsigned i = 0; i < bd.ntools; ++i) {
9150     MachO::build_tool_version bv = obj->getBuildToolVersion(i);
9151     PrintBuildToolVersion(bv);
9152   }
9153 }
9154 
9155 static void PrintSourceVersionCommand(MachO::source_version_command sd) {
9156   outs() << "      cmd LC_SOURCE_VERSION\n";
9157   outs() << "  cmdsize " << sd.cmdsize;
9158   if (sd.cmdsize != sizeof(struct MachO::source_version_command))
9159     outs() << " Incorrect size\n";
9160   else
9161     outs() << "\n";
9162   uint64_t a = (sd.version >> 40) & 0xffffff;
9163   uint64_t b = (sd.version >> 30) & 0x3ff;
9164   uint64_t c = (sd.version >> 20) & 0x3ff;
9165   uint64_t d = (sd.version >> 10) & 0x3ff;
9166   uint64_t e = sd.version & 0x3ff;
9167   outs() << "  version " << a << "." << b;
9168   if (e != 0)
9169     outs() << "." << c << "." << d << "." << e;
9170   else if (d != 0)
9171     outs() << "." << c << "." << d;
9172   else if (c != 0)
9173     outs() << "." << c;
9174   outs() << "\n";
9175 }
9176 
9177 static void PrintEntryPointCommand(MachO::entry_point_command ep) {
9178   outs() << "       cmd LC_MAIN\n";
9179   outs() << "   cmdsize " << ep.cmdsize;
9180   if (ep.cmdsize != sizeof(struct MachO::entry_point_command))
9181     outs() << " Incorrect size\n";
9182   else
9183     outs() << "\n";
9184   outs() << "  entryoff " << ep.entryoff << "\n";
9185   outs() << " stacksize " << ep.stacksize << "\n";
9186 }
9187 
9188 static void PrintEncryptionInfoCommand(MachO::encryption_info_command ec,
9189                                        uint32_t object_size) {
9190   outs() << "          cmd LC_ENCRYPTION_INFO\n";
9191   outs() << "      cmdsize " << ec.cmdsize;
9192   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command))
9193     outs() << " Incorrect size\n";
9194   else
9195     outs() << "\n";
9196   outs() << "     cryptoff " << ec.cryptoff;
9197   if (ec.cryptoff > object_size)
9198     outs() << " (past end of file)\n";
9199   else
9200     outs() << "\n";
9201   outs() << "    cryptsize " << ec.cryptsize;
9202   if (ec.cryptsize > object_size)
9203     outs() << " (past end of file)\n";
9204   else
9205     outs() << "\n";
9206   outs() << "      cryptid " << ec.cryptid << "\n";
9207 }
9208 
9209 static void PrintEncryptionInfoCommand64(MachO::encryption_info_command_64 ec,
9210                                          uint32_t object_size) {
9211   outs() << "          cmd LC_ENCRYPTION_INFO_64\n";
9212   outs() << "      cmdsize " << ec.cmdsize;
9213   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command_64))
9214     outs() << " Incorrect size\n";
9215   else
9216     outs() << "\n";
9217   outs() << "     cryptoff " << ec.cryptoff;
9218   if (ec.cryptoff > object_size)
9219     outs() << " (past end of file)\n";
9220   else
9221     outs() << "\n";
9222   outs() << "    cryptsize " << ec.cryptsize;
9223   if (ec.cryptsize > object_size)
9224     outs() << " (past end of file)\n";
9225   else
9226     outs() << "\n";
9227   outs() << "      cryptid " << ec.cryptid << "\n";
9228   outs() << "          pad " << ec.pad << "\n";
9229 }
9230 
9231 static void PrintLinkerOptionCommand(MachO::linker_option_command lo,
9232                                      const char *Ptr) {
9233   outs() << "     cmd LC_LINKER_OPTION\n";
9234   outs() << " cmdsize " << lo.cmdsize;
9235   if (lo.cmdsize < sizeof(struct MachO::linker_option_command))
9236     outs() << " Incorrect size\n";
9237   else
9238     outs() << "\n";
9239   outs() << "   count " << lo.count << "\n";
9240   const char *string = Ptr + sizeof(struct MachO::linker_option_command);
9241   uint32_t left = lo.cmdsize - sizeof(struct MachO::linker_option_command);
9242   uint32_t i = 0;
9243   while (left > 0) {
9244     while (*string == '\0' && left > 0) {
9245       string++;
9246       left--;
9247     }
9248     if (left > 0) {
9249       i++;
9250       outs() << "  string #" << i << " " << format("%.*s\n", left, string);
9251       uint32_t NullPos = StringRef(string, left).find('\0');
9252       uint32_t len = std::min(NullPos, left) + 1;
9253       string += len;
9254       left -= len;
9255     }
9256   }
9257   if (lo.count != i)
9258     outs() << "   count " << lo.count << " does not match number of strings "
9259            << i << "\n";
9260 }
9261 
9262 static void PrintSubFrameworkCommand(MachO::sub_framework_command sub,
9263                                      const char *Ptr) {
9264   outs() << "          cmd LC_SUB_FRAMEWORK\n";
9265   outs() << "      cmdsize " << sub.cmdsize;
9266   if (sub.cmdsize < sizeof(struct MachO::sub_framework_command))
9267     outs() << " Incorrect size\n";
9268   else
9269     outs() << "\n";
9270   if (sub.umbrella < sub.cmdsize) {
9271     const char *P = Ptr + sub.umbrella;
9272     outs() << "     umbrella " << P << " (offset " << sub.umbrella << ")\n";
9273   } else {
9274     outs() << "     umbrella ?(bad offset " << sub.umbrella << ")\n";
9275   }
9276 }
9277 
9278 static void PrintSubUmbrellaCommand(MachO::sub_umbrella_command sub,
9279                                     const char *Ptr) {
9280   outs() << "          cmd LC_SUB_UMBRELLA\n";
9281   outs() << "      cmdsize " << sub.cmdsize;
9282   if (sub.cmdsize < sizeof(struct MachO::sub_umbrella_command))
9283     outs() << " Incorrect size\n";
9284   else
9285     outs() << "\n";
9286   if (sub.sub_umbrella < sub.cmdsize) {
9287     const char *P = Ptr + sub.sub_umbrella;
9288     outs() << " sub_umbrella " << P << " (offset " << sub.sub_umbrella << ")\n";
9289   } else {
9290     outs() << " sub_umbrella ?(bad offset " << sub.sub_umbrella << ")\n";
9291   }
9292 }
9293 
9294 static void PrintSubLibraryCommand(MachO::sub_library_command sub,
9295                                    const char *Ptr) {
9296   outs() << "          cmd LC_SUB_LIBRARY\n";
9297   outs() << "      cmdsize " << sub.cmdsize;
9298   if (sub.cmdsize < sizeof(struct MachO::sub_library_command))
9299     outs() << " Incorrect size\n";
9300   else
9301     outs() << "\n";
9302   if (sub.sub_library < sub.cmdsize) {
9303     const char *P = Ptr + sub.sub_library;
9304     outs() << "  sub_library " << P << " (offset " << sub.sub_library << ")\n";
9305   } else {
9306     outs() << "  sub_library ?(bad offset " << sub.sub_library << ")\n";
9307   }
9308 }
9309 
9310 static void PrintSubClientCommand(MachO::sub_client_command sub,
9311                                   const char *Ptr) {
9312   outs() << "          cmd LC_SUB_CLIENT\n";
9313   outs() << "      cmdsize " << sub.cmdsize;
9314   if (sub.cmdsize < sizeof(struct MachO::sub_client_command))
9315     outs() << " Incorrect size\n";
9316   else
9317     outs() << "\n";
9318   if (sub.client < sub.cmdsize) {
9319     const char *P = Ptr + sub.client;
9320     outs() << "       client " << P << " (offset " << sub.client << ")\n";
9321   } else {
9322     outs() << "       client ?(bad offset " << sub.client << ")\n";
9323   }
9324 }
9325 
9326 static void PrintRoutinesCommand(MachO::routines_command r) {
9327   outs() << "          cmd LC_ROUTINES\n";
9328   outs() << "      cmdsize " << r.cmdsize;
9329   if (r.cmdsize != sizeof(struct MachO::routines_command))
9330     outs() << " Incorrect size\n";
9331   else
9332     outs() << "\n";
9333   outs() << " init_address " << format("0x%08" PRIx32, r.init_address) << "\n";
9334   outs() << "  init_module " << r.init_module << "\n";
9335   outs() << "    reserved1 " << r.reserved1 << "\n";
9336   outs() << "    reserved2 " << r.reserved2 << "\n";
9337   outs() << "    reserved3 " << r.reserved3 << "\n";
9338   outs() << "    reserved4 " << r.reserved4 << "\n";
9339   outs() << "    reserved5 " << r.reserved5 << "\n";
9340   outs() << "    reserved6 " << r.reserved6 << "\n";
9341 }
9342 
9343 static void PrintRoutinesCommand64(MachO::routines_command_64 r) {
9344   outs() << "          cmd LC_ROUTINES_64\n";
9345   outs() << "      cmdsize " << r.cmdsize;
9346   if (r.cmdsize != sizeof(struct MachO::routines_command_64))
9347     outs() << " Incorrect size\n";
9348   else
9349     outs() << "\n";
9350   outs() << " init_address " << format("0x%016" PRIx64, r.init_address) << "\n";
9351   outs() << "  init_module " << r.init_module << "\n";
9352   outs() << "    reserved1 " << r.reserved1 << "\n";
9353   outs() << "    reserved2 " << r.reserved2 << "\n";
9354   outs() << "    reserved3 " << r.reserved3 << "\n";
9355   outs() << "    reserved4 " << r.reserved4 << "\n";
9356   outs() << "    reserved5 " << r.reserved5 << "\n";
9357   outs() << "    reserved6 " << r.reserved6 << "\n";
9358 }
9359 
9360 static void Print_x86_thread_state32_t(MachO::x86_thread_state32_t &cpu32) {
9361   outs() << "\t    eax " << format("0x%08" PRIx32, cpu32.eax);
9362   outs() << " ebx    " << format("0x%08" PRIx32, cpu32.ebx);
9363   outs() << " ecx " << format("0x%08" PRIx32, cpu32.ecx);
9364   outs() << " edx " << format("0x%08" PRIx32, cpu32.edx) << "\n";
9365   outs() << "\t    edi " << format("0x%08" PRIx32, cpu32.edi);
9366   outs() << " esi    " << format("0x%08" PRIx32, cpu32.esi);
9367   outs() << " ebp " << format("0x%08" PRIx32, cpu32.ebp);
9368   outs() << " esp " << format("0x%08" PRIx32, cpu32.esp) << "\n";
9369   outs() << "\t    ss  " << format("0x%08" PRIx32, cpu32.ss);
9370   outs() << " eflags " << format("0x%08" PRIx32, cpu32.eflags);
9371   outs() << " eip " << format("0x%08" PRIx32, cpu32.eip);
9372   outs() << " cs  " << format("0x%08" PRIx32, cpu32.cs) << "\n";
9373   outs() << "\t    ds  " << format("0x%08" PRIx32, cpu32.ds);
9374   outs() << " es     " << format("0x%08" PRIx32, cpu32.es);
9375   outs() << " fs  " << format("0x%08" PRIx32, cpu32.fs);
9376   outs() << " gs  " << format("0x%08" PRIx32, cpu32.gs) << "\n";
9377 }
9378 
9379 static void Print_x86_thread_state64_t(MachO::x86_thread_state64_t &cpu64) {
9380   outs() << "   rax  " << format("0x%016" PRIx64, cpu64.rax);
9381   outs() << " rbx " << format("0x%016" PRIx64, cpu64.rbx);
9382   outs() << " rcx  " << format("0x%016" PRIx64, cpu64.rcx) << "\n";
9383   outs() << "   rdx  " << format("0x%016" PRIx64, cpu64.rdx);
9384   outs() << " rdi " << format("0x%016" PRIx64, cpu64.rdi);
9385   outs() << " rsi  " << format("0x%016" PRIx64, cpu64.rsi) << "\n";
9386   outs() << "   rbp  " << format("0x%016" PRIx64, cpu64.rbp);
9387   outs() << " rsp " << format("0x%016" PRIx64, cpu64.rsp);
9388   outs() << " r8   " << format("0x%016" PRIx64, cpu64.r8) << "\n";
9389   outs() << "    r9  " << format("0x%016" PRIx64, cpu64.r9);
9390   outs() << " r10 " << format("0x%016" PRIx64, cpu64.r10);
9391   outs() << " r11  " << format("0x%016" PRIx64, cpu64.r11) << "\n";
9392   outs() << "   r12  " << format("0x%016" PRIx64, cpu64.r12);
9393   outs() << " r13 " << format("0x%016" PRIx64, cpu64.r13);
9394   outs() << " r14  " << format("0x%016" PRIx64, cpu64.r14) << "\n";
9395   outs() << "   r15  " << format("0x%016" PRIx64, cpu64.r15);
9396   outs() << " rip " << format("0x%016" PRIx64, cpu64.rip) << "\n";
9397   outs() << "rflags  " << format("0x%016" PRIx64, cpu64.rflags);
9398   outs() << " cs  " << format("0x%016" PRIx64, cpu64.cs);
9399   outs() << " fs   " << format("0x%016" PRIx64, cpu64.fs) << "\n";
9400   outs() << "    gs  " << format("0x%016" PRIx64, cpu64.gs) << "\n";
9401 }
9402 
9403 static void Print_mmst_reg(MachO::mmst_reg_t &r) {
9404   uint32_t f;
9405   outs() << "\t      mmst_reg  ";
9406   for (f = 0; f < 10; f++)
9407     outs() << format("%02" PRIx32, (r.mmst_reg[f] & 0xff)) << " ";
9408   outs() << "\n";
9409   outs() << "\t      mmst_rsrv ";
9410   for (f = 0; f < 6; f++)
9411     outs() << format("%02" PRIx32, (r.mmst_rsrv[f] & 0xff)) << " ";
9412   outs() << "\n";
9413 }
9414 
9415 static void Print_xmm_reg(MachO::xmm_reg_t &r) {
9416   uint32_t f;
9417   outs() << "\t      xmm_reg ";
9418   for (f = 0; f < 16; f++)
9419     outs() << format("%02" PRIx32, (r.xmm_reg[f] & 0xff)) << " ";
9420   outs() << "\n";
9421 }
9422 
9423 static void Print_x86_float_state_t(MachO::x86_float_state64_t &fpu) {
9424   outs() << "\t    fpu_reserved[0] " << fpu.fpu_reserved[0];
9425   outs() << " fpu_reserved[1] " << fpu.fpu_reserved[1] << "\n";
9426   outs() << "\t    control: invalid " << fpu.fpu_fcw.invalid;
9427   outs() << " denorm " << fpu.fpu_fcw.denorm;
9428   outs() << " zdiv " << fpu.fpu_fcw.zdiv;
9429   outs() << " ovrfl " << fpu.fpu_fcw.ovrfl;
9430   outs() << " undfl " << fpu.fpu_fcw.undfl;
9431   outs() << " precis " << fpu.fpu_fcw.precis << "\n";
9432   outs() << "\t\t     pc ";
9433   if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_24B)
9434     outs() << "FP_PREC_24B ";
9435   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_53B)
9436     outs() << "FP_PREC_53B ";
9437   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_64B)
9438     outs() << "FP_PREC_64B ";
9439   else
9440     outs() << fpu.fpu_fcw.pc << " ";
9441   outs() << "rc ";
9442   if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_NEAR)
9443     outs() << "FP_RND_NEAR ";
9444   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_DOWN)
9445     outs() << "FP_RND_DOWN ";
9446   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_UP)
9447     outs() << "FP_RND_UP ";
9448   else if (fpu.fpu_fcw.rc == MachO::x86_FP_CHOP)
9449     outs() << "FP_CHOP ";
9450   outs() << "\n";
9451   outs() << "\t    status: invalid " << fpu.fpu_fsw.invalid;
9452   outs() << " denorm " << fpu.fpu_fsw.denorm;
9453   outs() << " zdiv " << fpu.fpu_fsw.zdiv;
9454   outs() << " ovrfl " << fpu.fpu_fsw.ovrfl;
9455   outs() << " undfl " << fpu.fpu_fsw.undfl;
9456   outs() << " precis " << fpu.fpu_fsw.precis;
9457   outs() << " stkflt " << fpu.fpu_fsw.stkflt << "\n";
9458   outs() << "\t            errsumm " << fpu.fpu_fsw.errsumm;
9459   outs() << " c0 " << fpu.fpu_fsw.c0;
9460   outs() << " c1 " << fpu.fpu_fsw.c1;
9461   outs() << " c2 " << fpu.fpu_fsw.c2;
9462   outs() << " tos " << fpu.fpu_fsw.tos;
9463   outs() << " c3 " << fpu.fpu_fsw.c3;
9464   outs() << " busy " << fpu.fpu_fsw.busy << "\n";
9465   outs() << "\t    fpu_ftw " << format("0x%02" PRIx32, fpu.fpu_ftw);
9466   outs() << " fpu_rsrv1 " << format("0x%02" PRIx32, fpu.fpu_rsrv1);
9467   outs() << " fpu_fop " << format("0x%04" PRIx32, fpu.fpu_fop);
9468   outs() << " fpu_ip " << format("0x%08" PRIx32, fpu.fpu_ip) << "\n";
9469   outs() << "\t    fpu_cs " << format("0x%04" PRIx32, fpu.fpu_cs);
9470   outs() << " fpu_rsrv2 " << format("0x%04" PRIx32, fpu.fpu_rsrv2);
9471   outs() << " fpu_dp " << format("0x%08" PRIx32, fpu.fpu_dp);
9472   outs() << " fpu_ds " << format("0x%04" PRIx32, fpu.fpu_ds) << "\n";
9473   outs() << "\t    fpu_rsrv3 " << format("0x%04" PRIx32, fpu.fpu_rsrv3);
9474   outs() << " fpu_mxcsr " << format("0x%08" PRIx32, fpu.fpu_mxcsr);
9475   outs() << " fpu_mxcsrmask " << format("0x%08" PRIx32, fpu.fpu_mxcsrmask);
9476   outs() << "\n";
9477   outs() << "\t    fpu_stmm0:\n";
9478   Print_mmst_reg(fpu.fpu_stmm0);
9479   outs() << "\t    fpu_stmm1:\n";
9480   Print_mmst_reg(fpu.fpu_stmm1);
9481   outs() << "\t    fpu_stmm2:\n";
9482   Print_mmst_reg(fpu.fpu_stmm2);
9483   outs() << "\t    fpu_stmm3:\n";
9484   Print_mmst_reg(fpu.fpu_stmm3);
9485   outs() << "\t    fpu_stmm4:\n";
9486   Print_mmst_reg(fpu.fpu_stmm4);
9487   outs() << "\t    fpu_stmm5:\n";
9488   Print_mmst_reg(fpu.fpu_stmm5);
9489   outs() << "\t    fpu_stmm6:\n";
9490   Print_mmst_reg(fpu.fpu_stmm6);
9491   outs() << "\t    fpu_stmm7:\n";
9492   Print_mmst_reg(fpu.fpu_stmm7);
9493   outs() << "\t    fpu_xmm0:\n";
9494   Print_xmm_reg(fpu.fpu_xmm0);
9495   outs() << "\t    fpu_xmm1:\n";
9496   Print_xmm_reg(fpu.fpu_xmm1);
9497   outs() << "\t    fpu_xmm2:\n";
9498   Print_xmm_reg(fpu.fpu_xmm2);
9499   outs() << "\t    fpu_xmm3:\n";
9500   Print_xmm_reg(fpu.fpu_xmm3);
9501   outs() << "\t    fpu_xmm4:\n";
9502   Print_xmm_reg(fpu.fpu_xmm4);
9503   outs() << "\t    fpu_xmm5:\n";
9504   Print_xmm_reg(fpu.fpu_xmm5);
9505   outs() << "\t    fpu_xmm6:\n";
9506   Print_xmm_reg(fpu.fpu_xmm6);
9507   outs() << "\t    fpu_xmm7:\n";
9508   Print_xmm_reg(fpu.fpu_xmm7);
9509   outs() << "\t    fpu_xmm8:\n";
9510   Print_xmm_reg(fpu.fpu_xmm8);
9511   outs() << "\t    fpu_xmm9:\n";
9512   Print_xmm_reg(fpu.fpu_xmm9);
9513   outs() << "\t    fpu_xmm10:\n";
9514   Print_xmm_reg(fpu.fpu_xmm10);
9515   outs() << "\t    fpu_xmm11:\n";
9516   Print_xmm_reg(fpu.fpu_xmm11);
9517   outs() << "\t    fpu_xmm12:\n";
9518   Print_xmm_reg(fpu.fpu_xmm12);
9519   outs() << "\t    fpu_xmm13:\n";
9520   Print_xmm_reg(fpu.fpu_xmm13);
9521   outs() << "\t    fpu_xmm14:\n";
9522   Print_xmm_reg(fpu.fpu_xmm14);
9523   outs() << "\t    fpu_xmm15:\n";
9524   Print_xmm_reg(fpu.fpu_xmm15);
9525   outs() << "\t    fpu_rsrv4:\n";
9526   for (uint32_t f = 0; f < 6; f++) {
9527     outs() << "\t            ";
9528     for (uint32_t g = 0; g < 16; g++)
9529       outs() << format("%02" PRIx32, fpu.fpu_rsrv4[f * g]) << " ";
9530     outs() << "\n";
9531   }
9532   outs() << "\t    fpu_reserved1 " << format("0x%08" PRIx32, fpu.fpu_reserved1);
9533   outs() << "\n";
9534 }
9535 
9536 static void Print_x86_exception_state_t(MachO::x86_exception_state64_t &exc64) {
9537   outs() << "\t    trapno " << format("0x%08" PRIx32, exc64.trapno);
9538   outs() << " err " << format("0x%08" PRIx32, exc64.err);
9539   outs() << " faultvaddr " << format("0x%016" PRIx64, exc64.faultvaddr) << "\n";
9540 }
9541 
9542 static void Print_arm_thread_state32_t(MachO::arm_thread_state32_t &cpu32) {
9543   outs() << "\t    r0  " << format("0x%08" PRIx32, cpu32.r[0]);
9544   outs() << " r1     "   << format("0x%08" PRIx32, cpu32.r[1]);
9545   outs() << " r2  "      << format("0x%08" PRIx32, cpu32.r[2]);
9546   outs() << " r3  "      << format("0x%08" PRIx32, cpu32.r[3]) << "\n";
9547   outs() << "\t    r4  " << format("0x%08" PRIx32, cpu32.r[4]);
9548   outs() << " r5     "   << format("0x%08" PRIx32, cpu32.r[5]);
9549   outs() << " r6  "      << format("0x%08" PRIx32, cpu32.r[6]);
9550   outs() << " r7  "      << format("0x%08" PRIx32, cpu32.r[7]) << "\n";
9551   outs() << "\t    r8  " << format("0x%08" PRIx32, cpu32.r[8]);
9552   outs() << " r9     "   << format("0x%08" PRIx32, cpu32.r[9]);
9553   outs() << " r10 "      << format("0x%08" PRIx32, cpu32.r[10]);
9554   outs() << " r11 "      << format("0x%08" PRIx32, cpu32.r[11]) << "\n";
9555   outs() << "\t    r12 " << format("0x%08" PRIx32, cpu32.r[12]);
9556   outs() << " sp     "   << format("0x%08" PRIx32, cpu32.sp);
9557   outs() << " lr  "      << format("0x%08" PRIx32, cpu32.lr);
9558   outs() << " pc  "      << format("0x%08" PRIx32, cpu32.pc) << "\n";
9559   outs() << "\t   cpsr " << format("0x%08" PRIx32, cpu32.cpsr) << "\n";
9560 }
9561 
9562 static void Print_arm_thread_state64_t(MachO::arm_thread_state64_t &cpu64) {
9563   outs() << "\t    x0  " << format("0x%016" PRIx64, cpu64.x[0]);
9564   outs() << " x1  "      << format("0x%016" PRIx64, cpu64.x[1]);
9565   outs() << " x2  "      << format("0x%016" PRIx64, cpu64.x[2]) << "\n";
9566   outs() << "\t    x3  " << format("0x%016" PRIx64, cpu64.x[3]);
9567   outs() << " x4  "      << format("0x%016" PRIx64, cpu64.x[4]);
9568   outs() << " x5  "      << format("0x%016" PRIx64, cpu64.x[5]) << "\n";
9569   outs() << "\t    x6  " << format("0x%016" PRIx64, cpu64.x[6]);
9570   outs() << " x7  "      << format("0x%016" PRIx64, cpu64.x[7]);
9571   outs() << " x8  "      << format("0x%016" PRIx64, cpu64.x[8]) << "\n";
9572   outs() << "\t    x9  " << format("0x%016" PRIx64, cpu64.x[9]);
9573   outs() << " x10 "      << format("0x%016" PRIx64, cpu64.x[10]);
9574   outs() << " x11 "      << format("0x%016" PRIx64, cpu64.x[11]) << "\n";
9575   outs() << "\t    x12 " << format("0x%016" PRIx64, cpu64.x[12]);
9576   outs() << " x13 "      << format("0x%016" PRIx64, cpu64.x[13]);
9577   outs() << " x14 "      << format("0x%016" PRIx64, cpu64.x[14]) << "\n";
9578   outs() << "\t    x15 " << format("0x%016" PRIx64, cpu64.x[15]);
9579   outs() << " x16 "      << format("0x%016" PRIx64, cpu64.x[16]);
9580   outs() << " x17 "      << format("0x%016" PRIx64, cpu64.x[17]) << "\n";
9581   outs() << "\t    x18 " << format("0x%016" PRIx64, cpu64.x[18]);
9582   outs() << " x19 "      << format("0x%016" PRIx64, cpu64.x[19]);
9583   outs() << " x20 "      << format("0x%016" PRIx64, cpu64.x[20]) << "\n";
9584   outs() << "\t    x21 " << format("0x%016" PRIx64, cpu64.x[21]);
9585   outs() << " x22 "      << format("0x%016" PRIx64, cpu64.x[22]);
9586   outs() << " x23 "      << format("0x%016" PRIx64, cpu64.x[23]) << "\n";
9587   outs() << "\t    x24 " << format("0x%016" PRIx64, cpu64.x[24]);
9588   outs() << " x25 "      << format("0x%016" PRIx64, cpu64.x[25]);
9589   outs() << " x26 "      << format("0x%016" PRIx64, cpu64.x[26]) << "\n";
9590   outs() << "\t    x27 " << format("0x%016" PRIx64, cpu64.x[27]);
9591   outs() << " x28 "      << format("0x%016" PRIx64, cpu64.x[28]);
9592   outs() << "  fp "      << format("0x%016" PRIx64, cpu64.fp) << "\n";
9593   outs() << "\t     lr " << format("0x%016" PRIx64, cpu64.lr);
9594   outs() << " sp  "      << format("0x%016" PRIx64, cpu64.sp);
9595   outs() << "  pc "      << format("0x%016" PRIx64, cpu64.pc) << "\n";
9596   outs() << "\t   cpsr " << format("0x%08"  PRIx32, cpu64.cpsr) << "\n";
9597 }
9598 
9599 static void PrintThreadCommand(MachO::thread_command t, const char *Ptr,
9600                                bool isLittleEndian, uint32_t cputype) {
9601   if (t.cmd == MachO::LC_THREAD)
9602     outs() << "        cmd LC_THREAD\n";
9603   else if (t.cmd == MachO::LC_UNIXTHREAD)
9604     outs() << "        cmd LC_UNIXTHREAD\n";
9605   else
9606     outs() << "        cmd " << t.cmd << " (unknown)\n";
9607   outs() << "    cmdsize " << t.cmdsize;
9608   if (t.cmdsize < sizeof(struct MachO::thread_command) + 2 * sizeof(uint32_t))
9609     outs() << " Incorrect size\n";
9610   else
9611     outs() << "\n";
9612 
9613   const char *begin = Ptr + sizeof(struct MachO::thread_command);
9614   const char *end = Ptr + t.cmdsize;
9615   uint32_t flavor, count, left;
9616   if (cputype == MachO::CPU_TYPE_I386) {
9617     while (begin < end) {
9618       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9619         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9620         begin += sizeof(uint32_t);
9621       } else {
9622         flavor = 0;
9623         begin = end;
9624       }
9625       if (isLittleEndian != sys::IsLittleEndianHost)
9626         sys::swapByteOrder(flavor);
9627       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9628         memcpy((char *)&count, begin, sizeof(uint32_t));
9629         begin += sizeof(uint32_t);
9630       } else {
9631         count = 0;
9632         begin = end;
9633       }
9634       if (isLittleEndian != sys::IsLittleEndianHost)
9635         sys::swapByteOrder(count);
9636       if (flavor == MachO::x86_THREAD_STATE32) {
9637         outs() << "     flavor i386_THREAD_STATE\n";
9638         if (count == MachO::x86_THREAD_STATE32_COUNT)
9639           outs() << "      count i386_THREAD_STATE_COUNT\n";
9640         else
9641           outs() << "      count " << count
9642                  << " (not x86_THREAD_STATE32_COUNT)\n";
9643         MachO::x86_thread_state32_t cpu32;
9644         left = end - begin;
9645         if (left >= sizeof(MachO::x86_thread_state32_t)) {
9646           memcpy(&cpu32, begin, sizeof(MachO::x86_thread_state32_t));
9647           begin += sizeof(MachO::x86_thread_state32_t);
9648         } else {
9649           memset(&cpu32, '\0', sizeof(MachO::x86_thread_state32_t));
9650           memcpy(&cpu32, begin, left);
9651           begin += left;
9652         }
9653         if (isLittleEndian != sys::IsLittleEndianHost)
9654           swapStruct(cpu32);
9655         Print_x86_thread_state32_t(cpu32);
9656       } else if (flavor == MachO::x86_THREAD_STATE) {
9657         outs() << "     flavor x86_THREAD_STATE\n";
9658         if (count == MachO::x86_THREAD_STATE_COUNT)
9659           outs() << "      count x86_THREAD_STATE_COUNT\n";
9660         else
9661           outs() << "      count " << count
9662                  << " (not x86_THREAD_STATE_COUNT)\n";
9663         struct MachO::x86_thread_state_t ts;
9664         left = end - begin;
9665         if (left >= sizeof(MachO::x86_thread_state_t)) {
9666           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
9667           begin += sizeof(MachO::x86_thread_state_t);
9668         } else {
9669           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
9670           memcpy(&ts, begin, left);
9671           begin += left;
9672         }
9673         if (isLittleEndian != sys::IsLittleEndianHost)
9674           swapStruct(ts);
9675         if (ts.tsh.flavor == MachO::x86_THREAD_STATE32) {
9676           outs() << "\t    tsh.flavor x86_THREAD_STATE32 ";
9677           if (ts.tsh.count == MachO::x86_THREAD_STATE32_COUNT)
9678             outs() << "tsh.count x86_THREAD_STATE32_COUNT\n";
9679           else
9680             outs() << "tsh.count " << ts.tsh.count
9681                    << " (not x86_THREAD_STATE32_COUNT\n";
9682           Print_x86_thread_state32_t(ts.uts.ts32);
9683         } else {
9684           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
9685                  << ts.tsh.count << "\n";
9686         }
9687       } else {
9688         outs() << "     flavor " << flavor << " (unknown)\n";
9689         outs() << "      count " << count << "\n";
9690         outs() << "      state (unknown)\n";
9691         begin += count * sizeof(uint32_t);
9692       }
9693     }
9694   } else if (cputype == MachO::CPU_TYPE_X86_64) {
9695     while (begin < end) {
9696       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9697         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9698         begin += sizeof(uint32_t);
9699       } else {
9700         flavor = 0;
9701         begin = end;
9702       }
9703       if (isLittleEndian != sys::IsLittleEndianHost)
9704         sys::swapByteOrder(flavor);
9705       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9706         memcpy((char *)&count, begin, sizeof(uint32_t));
9707         begin += sizeof(uint32_t);
9708       } else {
9709         count = 0;
9710         begin = end;
9711       }
9712       if (isLittleEndian != sys::IsLittleEndianHost)
9713         sys::swapByteOrder(count);
9714       if (flavor == MachO::x86_THREAD_STATE64) {
9715         outs() << "     flavor x86_THREAD_STATE64\n";
9716         if (count == MachO::x86_THREAD_STATE64_COUNT)
9717           outs() << "      count x86_THREAD_STATE64_COUNT\n";
9718         else
9719           outs() << "      count " << count
9720                  << " (not x86_THREAD_STATE64_COUNT)\n";
9721         MachO::x86_thread_state64_t cpu64;
9722         left = end - begin;
9723         if (left >= sizeof(MachO::x86_thread_state64_t)) {
9724           memcpy(&cpu64, begin, sizeof(MachO::x86_thread_state64_t));
9725           begin += sizeof(MachO::x86_thread_state64_t);
9726         } else {
9727           memset(&cpu64, '\0', sizeof(MachO::x86_thread_state64_t));
9728           memcpy(&cpu64, begin, left);
9729           begin += left;
9730         }
9731         if (isLittleEndian != sys::IsLittleEndianHost)
9732           swapStruct(cpu64);
9733         Print_x86_thread_state64_t(cpu64);
9734       } else if (flavor == MachO::x86_THREAD_STATE) {
9735         outs() << "     flavor x86_THREAD_STATE\n";
9736         if (count == MachO::x86_THREAD_STATE_COUNT)
9737           outs() << "      count x86_THREAD_STATE_COUNT\n";
9738         else
9739           outs() << "      count " << count
9740                  << " (not x86_THREAD_STATE_COUNT)\n";
9741         struct MachO::x86_thread_state_t ts;
9742         left = end - begin;
9743         if (left >= sizeof(MachO::x86_thread_state_t)) {
9744           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
9745           begin += sizeof(MachO::x86_thread_state_t);
9746         } else {
9747           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
9748           memcpy(&ts, begin, left);
9749           begin += left;
9750         }
9751         if (isLittleEndian != sys::IsLittleEndianHost)
9752           swapStruct(ts);
9753         if (ts.tsh.flavor == MachO::x86_THREAD_STATE64) {
9754           outs() << "\t    tsh.flavor x86_THREAD_STATE64 ";
9755           if (ts.tsh.count == MachO::x86_THREAD_STATE64_COUNT)
9756             outs() << "tsh.count x86_THREAD_STATE64_COUNT\n";
9757           else
9758             outs() << "tsh.count " << ts.tsh.count
9759                    << " (not x86_THREAD_STATE64_COUNT\n";
9760           Print_x86_thread_state64_t(ts.uts.ts64);
9761         } else {
9762           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
9763                  << ts.tsh.count << "\n";
9764         }
9765       } else if (flavor == MachO::x86_FLOAT_STATE) {
9766         outs() << "     flavor x86_FLOAT_STATE\n";
9767         if (count == MachO::x86_FLOAT_STATE_COUNT)
9768           outs() << "      count x86_FLOAT_STATE_COUNT\n";
9769         else
9770           outs() << "      count " << count << " (not x86_FLOAT_STATE_COUNT)\n";
9771         struct MachO::x86_float_state_t fs;
9772         left = end - begin;
9773         if (left >= sizeof(MachO::x86_float_state_t)) {
9774           memcpy(&fs, begin, sizeof(MachO::x86_float_state_t));
9775           begin += sizeof(MachO::x86_float_state_t);
9776         } else {
9777           memset(&fs, '\0', sizeof(MachO::x86_float_state_t));
9778           memcpy(&fs, begin, left);
9779           begin += left;
9780         }
9781         if (isLittleEndian != sys::IsLittleEndianHost)
9782           swapStruct(fs);
9783         if (fs.fsh.flavor == MachO::x86_FLOAT_STATE64) {
9784           outs() << "\t    fsh.flavor x86_FLOAT_STATE64 ";
9785           if (fs.fsh.count == MachO::x86_FLOAT_STATE64_COUNT)
9786             outs() << "fsh.count x86_FLOAT_STATE64_COUNT\n";
9787           else
9788             outs() << "fsh.count " << fs.fsh.count
9789                    << " (not x86_FLOAT_STATE64_COUNT\n";
9790           Print_x86_float_state_t(fs.ufs.fs64);
9791         } else {
9792           outs() << "\t    fsh.flavor " << fs.fsh.flavor << "  fsh.count "
9793                  << fs.fsh.count << "\n";
9794         }
9795       } else if (flavor == MachO::x86_EXCEPTION_STATE) {
9796         outs() << "     flavor x86_EXCEPTION_STATE\n";
9797         if (count == MachO::x86_EXCEPTION_STATE_COUNT)
9798           outs() << "      count x86_EXCEPTION_STATE_COUNT\n";
9799         else
9800           outs() << "      count " << count
9801                  << " (not x86_EXCEPTION_STATE_COUNT)\n";
9802         struct MachO::x86_exception_state_t es;
9803         left = end - begin;
9804         if (left >= sizeof(MachO::x86_exception_state_t)) {
9805           memcpy(&es, begin, sizeof(MachO::x86_exception_state_t));
9806           begin += sizeof(MachO::x86_exception_state_t);
9807         } else {
9808           memset(&es, '\0', sizeof(MachO::x86_exception_state_t));
9809           memcpy(&es, begin, left);
9810           begin += left;
9811         }
9812         if (isLittleEndian != sys::IsLittleEndianHost)
9813           swapStruct(es);
9814         if (es.esh.flavor == MachO::x86_EXCEPTION_STATE64) {
9815           outs() << "\t    esh.flavor x86_EXCEPTION_STATE64\n";
9816           if (es.esh.count == MachO::x86_EXCEPTION_STATE64_COUNT)
9817             outs() << "\t    esh.count x86_EXCEPTION_STATE64_COUNT\n";
9818           else
9819             outs() << "\t    esh.count " << es.esh.count
9820                    << " (not x86_EXCEPTION_STATE64_COUNT\n";
9821           Print_x86_exception_state_t(es.ues.es64);
9822         } else {
9823           outs() << "\t    esh.flavor " << es.esh.flavor << "  esh.count "
9824                  << es.esh.count << "\n";
9825         }
9826       } else if (flavor == MachO::x86_EXCEPTION_STATE64) {
9827         outs() << "     flavor x86_EXCEPTION_STATE64\n";
9828         if (count == MachO::x86_EXCEPTION_STATE64_COUNT)
9829           outs() << "      count x86_EXCEPTION_STATE64_COUNT\n";
9830         else
9831           outs() << "      count " << count
9832                  << " (not x86_EXCEPTION_STATE64_COUNT)\n";
9833         struct MachO::x86_exception_state64_t es64;
9834         left = end - begin;
9835         if (left >= sizeof(MachO::x86_exception_state64_t)) {
9836           memcpy(&es64, begin, sizeof(MachO::x86_exception_state64_t));
9837           begin += sizeof(MachO::x86_exception_state64_t);
9838         } else {
9839           memset(&es64, '\0', sizeof(MachO::x86_exception_state64_t));
9840           memcpy(&es64, begin, left);
9841           begin += left;
9842         }
9843         if (isLittleEndian != sys::IsLittleEndianHost)
9844           swapStruct(es64);
9845         Print_x86_exception_state_t(es64);
9846       } else {
9847         outs() << "     flavor " << flavor << " (unknown)\n";
9848         outs() << "      count " << count << "\n";
9849         outs() << "      state (unknown)\n";
9850         begin += count * sizeof(uint32_t);
9851       }
9852     }
9853   } else if (cputype == MachO::CPU_TYPE_ARM) {
9854     while (begin < end) {
9855       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9856         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9857         begin += sizeof(uint32_t);
9858       } else {
9859         flavor = 0;
9860         begin = end;
9861       }
9862       if (isLittleEndian != sys::IsLittleEndianHost)
9863         sys::swapByteOrder(flavor);
9864       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9865         memcpy((char *)&count, begin, sizeof(uint32_t));
9866         begin += sizeof(uint32_t);
9867       } else {
9868         count = 0;
9869         begin = end;
9870       }
9871       if (isLittleEndian != sys::IsLittleEndianHost)
9872         sys::swapByteOrder(count);
9873       if (flavor == MachO::ARM_THREAD_STATE) {
9874         outs() << "     flavor ARM_THREAD_STATE\n";
9875         if (count == MachO::ARM_THREAD_STATE_COUNT)
9876           outs() << "      count ARM_THREAD_STATE_COUNT\n";
9877         else
9878           outs() << "      count " << count
9879                  << " (not ARM_THREAD_STATE_COUNT)\n";
9880         MachO::arm_thread_state32_t cpu32;
9881         left = end - begin;
9882         if (left >= sizeof(MachO::arm_thread_state32_t)) {
9883           memcpy(&cpu32, begin, sizeof(MachO::arm_thread_state32_t));
9884           begin += sizeof(MachO::arm_thread_state32_t);
9885         } else {
9886           memset(&cpu32, '\0', sizeof(MachO::arm_thread_state32_t));
9887           memcpy(&cpu32, begin, left);
9888           begin += left;
9889         }
9890         if (isLittleEndian != sys::IsLittleEndianHost)
9891           swapStruct(cpu32);
9892         Print_arm_thread_state32_t(cpu32);
9893       } else {
9894         outs() << "     flavor " << flavor << " (unknown)\n";
9895         outs() << "      count " << count << "\n";
9896         outs() << "      state (unknown)\n";
9897         begin += count * sizeof(uint32_t);
9898       }
9899     }
9900   } else if (cputype == MachO::CPU_TYPE_ARM64 ||
9901              cputype == MachO::CPU_TYPE_ARM64_32) {
9902     while (begin < end) {
9903       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9904         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9905         begin += sizeof(uint32_t);
9906       } else {
9907         flavor = 0;
9908         begin = end;
9909       }
9910       if (isLittleEndian != sys::IsLittleEndianHost)
9911         sys::swapByteOrder(flavor);
9912       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9913         memcpy((char *)&count, begin, sizeof(uint32_t));
9914         begin += sizeof(uint32_t);
9915       } else {
9916         count = 0;
9917         begin = end;
9918       }
9919       if (isLittleEndian != sys::IsLittleEndianHost)
9920         sys::swapByteOrder(count);
9921       if (flavor == MachO::ARM_THREAD_STATE64) {
9922         outs() << "     flavor ARM_THREAD_STATE64\n";
9923         if (count == MachO::ARM_THREAD_STATE64_COUNT)
9924           outs() << "      count ARM_THREAD_STATE64_COUNT\n";
9925         else
9926           outs() << "      count " << count
9927                  << " (not ARM_THREAD_STATE64_COUNT)\n";
9928         MachO::arm_thread_state64_t cpu64;
9929         left = end - begin;
9930         if (left >= sizeof(MachO::arm_thread_state64_t)) {
9931           memcpy(&cpu64, begin, sizeof(MachO::arm_thread_state64_t));
9932           begin += sizeof(MachO::arm_thread_state64_t);
9933         } else {
9934           memset(&cpu64, '\0', sizeof(MachO::arm_thread_state64_t));
9935           memcpy(&cpu64, begin, left);
9936           begin += left;
9937         }
9938         if (isLittleEndian != sys::IsLittleEndianHost)
9939           swapStruct(cpu64);
9940         Print_arm_thread_state64_t(cpu64);
9941       } else {
9942         outs() << "     flavor " << flavor << " (unknown)\n";
9943         outs() << "      count " << count << "\n";
9944         outs() << "      state (unknown)\n";
9945         begin += count * sizeof(uint32_t);
9946       }
9947     }
9948   } else {
9949     while (begin < end) {
9950       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9951         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9952         begin += sizeof(uint32_t);
9953       } else {
9954         flavor = 0;
9955         begin = end;
9956       }
9957       if (isLittleEndian != sys::IsLittleEndianHost)
9958         sys::swapByteOrder(flavor);
9959       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9960         memcpy((char *)&count, begin, sizeof(uint32_t));
9961         begin += sizeof(uint32_t);
9962       } else {
9963         count = 0;
9964         begin = end;
9965       }
9966       if (isLittleEndian != sys::IsLittleEndianHost)
9967         sys::swapByteOrder(count);
9968       outs() << "     flavor " << flavor << "\n";
9969       outs() << "      count " << count << "\n";
9970       outs() << "      state (Unknown cputype/cpusubtype)\n";
9971       begin += count * sizeof(uint32_t);
9972     }
9973   }
9974 }
9975 
9976 static void PrintDylibCommand(MachO::dylib_command dl, const char *Ptr) {
9977   if (dl.cmd == MachO::LC_ID_DYLIB)
9978     outs() << "          cmd LC_ID_DYLIB\n";
9979   else if (dl.cmd == MachO::LC_LOAD_DYLIB)
9980     outs() << "          cmd LC_LOAD_DYLIB\n";
9981   else if (dl.cmd == MachO::LC_LOAD_WEAK_DYLIB)
9982     outs() << "          cmd LC_LOAD_WEAK_DYLIB\n";
9983   else if (dl.cmd == MachO::LC_REEXPORT_DYLIB)
9984     outs() << "          cmd LC_REEXPORT_DYLIB\n";
9985   else if (dl.cmd == MachO::LC_LAZY_LOAD_DYLIB)
9986     outs() << "          cmd LC_LAZY_LOAD_DYLIB\n";
9987   else if (dl.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
9988     outs() << "          cmd LC_LOAD_UPWARD_DYLIB\n";
9989   else
9990     outs() << "          cmd " << dl.cmd << " (unknown)\n";
9991   outs() << "      cmdsize " << dl.cmdsize;
9992   if (dl.cmdsize < sizeof(struct MachO::dylib_command))
9993     outs() << " Incorrect size\n";
9994   else
9995     outs() << "\n";
9996   if (dl.dylib.name < dl.cmdsize) {
9997     const char *P = (const char *)(Ptr) + dl.dylib.name;
9998     outs() << "         name " << P << " (offset " << dl.dylib.name << ")\n";
9999   } else {
10000     outs() << "         name ?(bad offset " << dl.dylib.name << ")\n";
10001   }
10002   outs() << "   time stamp " << dl.dylib.timestamp << " ";
10003   time_t t = dl.dylib.timestamp;
10004   outs() << ctime(&t);
10005   outs() << "      current version ";
10006   if (dl.dylib.current_version == 0xffffffff)
10007     outs() << "n/a\n";
10008   else
10009     outs() << ((dl.dylib.current_version >> 16) & 0xffff) << "."
10010            << ((dl.dylib.current_version >> 8) & 0xff) << "."
10011            << (dl.dylib.current_version & 0xff) << "\n";
10012   outs() << "compatibility version ";
10013   if (dl.dylib.compatibility_version == 0xffffffff)
10014     outs() << "n/a\n";
10015   else
10016     outs() << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
10017            << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
10018            << (dl.dylib.compatibility_version & 0xff) << "\n";
10019 }
10020 
10021 static void PrintLinkEditDataCommand(MachO::linkedit_data_command ld,
10022                                      uint32_t object_size) {
10023   if (ld.cmd == MachO::LC_CODE_SIGNATURE)
10024     outs() << "      cmd LC_CODE_SIGNATURE\n";
10025   else if (ld.cmd == MachO::LC_SEGMENT_SPLIT_INFO)
10026     outs() << "      cmd LC_SEGMENT_SPLIT_INFO\n";
10027   else if (ld.cmd == MachO::LC_FUNCTION_STARTS)
10028     outs() << "      cmd LC_FUNCTION_STARTS\n";
10029   else if (ld.cmd == MachO::LC_DATA_IN_CODE)
10030     outs() << "      cmd LC_DATA_IN_CODE\n";
10031   else if (ld.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS)
10032     outs() << "      cmd LC_DYLIB_CODE_SIGN_DRS\n";
10033   else if (ld.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT)
10034     outs() << "      cmd LC_LINKER_OPTIMIZATION_HINT\n";
10035   else
10036     outs() << "      cmd " << ld.cmd << " (?)\n";
10037   outs() << "  cmdsize " << ld.cmdsize;
10038   if (ld.cmdsize != sizeof(struct MachO::linkedit_data_command))
10039     outs() << " Incorrect size\n";
10040   else
10041     outs() << "\n";
10042   outs() << "  dataoff " << ld.dataoff;
10043   if (ld.dataoff > object_size)
10044     outs() << " (past end of file)\n";
10045   else
10046     outs() << "\n";
10047   outs() << " datasize " << ld.datasize;
10048   uint64_t big_size = ld.dataoff;
10049   big_size += ld.datasize;
10050   if (big_size > object_size)
10051     outs() << " (past end of file)\n";
10052   else
10053     outs() << "\n";
10054 }
10055 
10056 static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t filetype,
10057                               uint32_t cputype, bool verbose) {
10058   StringRef Buf = Obj->getData();
10059   unsigned Index = 0;
10060   for (const auto &Command : Obj->load_commands()) {
10061     outs() << "Load command " << Index++ << "\n";
10062     if (Command.C.cmd == MachO::LC_SEGMENT) {
10063       MachO::segment_command SLC = Obj->getSegmentLoadCommand(Command);
10064       const char *sg_segname = SLC.segname;
10065       PrintSegmentCommand(SLC.cmd, SLC.cmdsize, SLC.segname, SLC.vmaddr,
10066                           SLC.vmsize, SLC.fileoff, SLC.filesize, SLC.maxprot,
10067                           SLC.initprot, SLC.nsects, SLC.flags, Buf.size(),
10068                           verbose);
10069       for (unsigned j = 0; j < SLC.nsects; j++) {
10070         MachO::section S = Obj->getSection(Command, j);
10071         PrintSection(S.sectname, S.segname, S.addr, S.size, S.offset, S.align,
10072                      S.reloff, S.nreloc, S.flags, S.reserved1, S.reserved2,
10073                      SLC.cmd, sg_segname, filetype, Buf.size(), verbose);
10074       }
10075     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
10076       MachO::segment_command_64 SLC_64 = Obj->getSegment64LoadCommand(Command);
10077       const char *sg_segname = SLC_64.segname;
10078       PrintSegmentCommand(SLC_64.cmd, SLC_64.cmdsize, SLC_64.segname,
10079                           SLC_64.vmaddr, SLC_64.vmsize, SLC_64.fileoff,
10080                           SLC_64.filesize, SLC_64.maxprot, SLC_64.initprot,
10081                           SLC_64.nsects, SLC_64.flags, Buf.size(), verbose);
10082       for (unsigned j = 0; j < SLC_64.nsects; j++) {
10083         MachO::section_64 S_64 = Obj->getSection64(Command, j);
10084         PrintSection(S_64.sectname, S_64.segname, S_64.addr, S_64.size,
10085                      S_64.offset, S_64.align, S_64.reloff, S_64.nreloc,
10086                      S_64.flags, S_64.reserved1, S_64.reserved2, SLC_64.cmd,
10087                      sg_segname, filetype, Buf.size(), verbose);
10088       }
10089     } else if (Command.C.cmd == MachO::LC_SYMTAB) {
10090       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
10091       PrintSymtabLoadCommand(Symtab, Obj->is64Bit(), Buf.size());
10092     } else if (Command.C.cmd == MachO::LC_DYSYMTAB) {
10093       MachO::dysymtab_command Dysymtab = Obj->getDysymtabLoadCommand();
10094       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
10095       PrintDysymtabLoadCommand(Dysymtab, Symtab.nsyms, Buf.size(),
10096                                Obj->is64Bit());
10097     } else if (Command.C.cmd == MachO::LC_DYLD_INFO ||
10098                Command.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
10099       MachO::dyld_info_command DyldInfo = Obj->getDyldInfoLoadCommand(Command);
10100       PrintDyldInfoLoadCommand(DyldInfo, Buf.size());
10101     } else if (Command.C.cmd == MachO::LC_LOAD_DYLINKER ||
10102                Command.C.cmd == MachO::LC_ID_DYLINKER ||
10103                Command.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
10104       MachO::dylinker_command Dyld = Obj->getDylinkerCommand(Command);
10105       PrintDyldLoadCommand(Dyld, Command.Ptr);
10106     } else if (Command.C.cmd == MachO::LC_UUID) {
10107       MachO::uuid_command Uuid = Obj->getUuidCommand(Command);
10108       PrintUuidLoadCommand(Uuid);
10109     } else if (Command.C.cmd == MachO::LC_RPATH) {
10110       MachO::rpath_command Rpath = Obj->getRpathCommand(Command);
10111       PrintRpathLoadCommand(Rpath, Command.Ptr);
10112     } else if (Command.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
10113                Command.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS ||
10114                Command.C.cmd == MachO::LC_VERSION_MIN_TVOS ||
10115                Command.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
10116       MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
10117       PrintVersionMinLoadCommand(Vd);
10118     } else if (Command.C.cmd == MachO::LC_NOTE) {
10119       MachO::note_command Nt = Obj->getNoteLoadCommand(Command);
10120       PrintNoteLoadCommand(Nt);
10121     } else if (Command.C.cmd == MachO::LC_BUILD_VERSION) {
10122       MachO::build_version_command Bv =
10123           Obj->getBuildVersionLoadCommand(Command);
10124       PrintBuildVersionLoadCommand(Obj, Bv);
10125     } else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
10126       MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
10127       PrintSourceVersionCommand(Sd);
10128     } else if (Command.C.cmd == MachO::LC_MAIN) {
10129       MachO::entry_point_command Ep = Obj->getEntryPointCommand(Command);
10130       PrintEntryPointCommand(Ep);
10131     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO) {
10132       MachO::encryption_info_command Ei =
10133           Obj->getEncryptionInfoCommand(Command);
10134       PrintEncryptionInfoCommand(Ei, Buf.size());
10135     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
10136       MachO::encryption_info_command_64 Ei =
10137           Obj->getEncryptionInfoCommand64(Command);
10138       PrintEncryptionInfoCommand64(Ei, Buf.size());
10139     } else if (Command.C.cmd == MachO::LC_LINKER_OPTION) {
10140       MachO::linker_option_command Lo =
10141           Obj->getLinkerOptionLoadCommand(Command);
10142       PrintLinkerOptionCommand(Lo, Command.Ptr);
10143     } else if (Command.C.cmd == MachO::LC_SUB_FRAMEWORK) {
10144       MachO::sub_framework_command Sf = Obj->getSubFrameworkCommand(Command);
10145       PrintSubFrameworkCommand(Sf, Command.Ptr);
10146     } else if (Command.C.cmd == MachO::LC_SUB_UMBRELLA) {
10147       MachO::sub_umbrella_command Sf = Obj->getSubUmbrellaCommand(Command);
10148       PrintSubUmbrellaCommand(Sf, Command.Ptr);
10149     } else if (Command.C.cmd == MachO::LC_SUB_LIBRARY) {
10150       MachO::sub_library_command Sl = Obj->getSubLibraryCommand(Command);
10151       PrintSubLibraryCommand(Sl, Command.Ptr);
10152     } else if (Command.C.cmd == MachO::LC_SUB_CLIENT) {
10153       MachO::sub_client_command Sc = Obj->getSubClientCommand(Command);
10154       PrintSubClientCommand(Sc, Command.Ptr);
10155     } else if (Command.C.cmd == MachO::LC_ROUTINES) {
10156       MachO::routines_command Rc = Obj->getRoutinesCommand(Command);
10157       PrintRoutinesCommand(Rc);
10158     } else if (Command.C.cmd == MachO::LC_ROUTINES_64) {
10159       MachO::routines_command_64 Rc = Obj->getRoutinesCommand64(Command);
10160       PrintRoutinesCommand64(Rc);
10161     } else if (Command.C.cmd == MachO::LC_THREAD ||
10162                Command.C.cmd == MachO::LC_UNIXTHREAD) {
10163       MachO::thread_command Tc = Obj->getThreadCommand(Command);
10164       PrintThreadCommand(Tc, Command.Ptr, Obj->isLittleEndian(), cputype);
10165     } else if (Command.C.cmd == MachO::LC_LOAD_DYLIB ||
10166                Command.C.cmd == MachO::LC_ID_DYLIB ||
10167                Command.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
10168                Command.C.cmd == MachO::LC_REEXPORT_DYLIB ||
10169                Command.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
10170                Command.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
10171       MachO::dylib_command Dl = Obj->getDylibIDLoadCommand(Command);
10172       PrintDylibCommand(Dl, Command.Ptr);
10173     } else if (Command.C.cmd == MachO::LC_CODE_SIGNATURE ||
10174                Command.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO ||
10175                Command.C.cmd == MachO::LC_FUNCTION_STARTS ||
10176                Command.C.cmd == MachO::LC_DATA_IN_CODE ||
10177                Command.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS ||
10178                Command.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
10179       MachO::linkedit_data_command Ld =
10180           Obj->getLinkeditDataLoadCommand(Command);
10181       PrintLinkEditDataCommand(Ld, Buf.size());
10182     } else {
10183       outs() << "      cmd ?(" << format("0x%08" PRIx32, Command.C.cmd)
10184              << ")\n";
10185       outs() << "  cmdsize " << Command.C.cmdsize << "\n";
10186       // TODO: get and print the raw bytes of the load command.
10187     }
10188     // TODO: print all the other kinds of load commands.
10189   }
10190 }
10191 
10192 static void PrintMachHeader(const MachOObjectFile *Obj, bool verbose) {
10193   if (Obj->is64Bit()) {
10194     MachO::mach_header_64 H_64;
10195     H_64 = Obj->getHeader64();
10196     PrintMachHeader(H_64.magic, H_64.cputype, H_64.cpusubtype, H_64.filetype,
10197                     H_64.ncmds, H_64.sizeofcmds, H_64.flags, verbose);
10198   } else {
10199     MachO::mach_header H;
10200     H = Obj->getHeader();
10201     PrintMachHeader(H.magic, H.cputype, H.cpusubtype, H.filetype, H.ncmds,
10202                     H.sizeofcmds, H.flags, verbose);
10203   }
10204 }
10205 
10206 void objdump::printMachOFileHeader(const object::ObjectFile *Obj) {
10207   const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
10208   PrintMachHeader(file, !NonVerbose);
10209 }
10210 
10211 void objdump::printMachOLoadCommands(const object::ObjectFile *Obj) {
10212   const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
10213   uint32_t filetype = 0;
10214   uint32_t cputype = 0;
10215   if (file->is64Bit()) {
10216     MachO::mach_header_64 H_64;
10217     H_64 = file->getHeader64();
10218     filetype = H_64.filetype;
10219     cputype = H_64.cputype;
10220   } else {
10221     MachO::mach_header H;
10222     H = file->getHeader();
10223     filetype = H.filetype;
10224     cputype = H.cputype;
10225   }
10226   PrintLoadCommands(file, filetype, cputype, !NonVerbose);
10227 }
10228 
10229 //===----------------------------------------------------------------------===//
10230 // export trie dumping
10231 //===----------------------------------------------------------------------===//
10232 
10233 static void printMachOExportsTrie(const object::MachOObjectFile *Obj) {
10234   uint64_t BaseSegmentAddress = 0;
10235   for (const auto &Command : Obj->load_commands()) {
10236     if (Command.C.cmd == MachO::LC_SEGMENT) {
10237       MachO::segment_command Seg = Obj->getSegmentLoadCommand(Command);
10238       if (Seg.fileoff == 0 && Seg.filesize != 0) {
10239         BaseSegmentAddress = Seg.vmaddr;
10240         break;
10241       }
10242     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
10243       MachO::segment_command_64 Seg = Obj->getSegment64LoadCommand(Command);
10244       if (Seg.fileoff == 0 && Seg.filesize != 0) {
10245         BaseSegmentAddress = Seg.vmaddr;
10246         break;
10247       }
10248     }
10249   }
10250   Error Err = Error::success();
10251   for (const object::ExportEntry &Entry : Obj->exports(Err)) {
10252     uint64_t Flags = Entry.flags();
10253     bool ReExport = (Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
10254     bool WeakDef = (Flags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
10255     bool ThreadLocal = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
10256                         MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL);
10257     bool Abs = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
10258                 MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
10259     bool Resolver = (Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
10260     if (ReExport)
10261       outs() << "[re-export] ";
10262     else
10263       outs() << format("0x%08llX  ",
10264                        Entry.address() + BaseSegmentAddress);
10265     outs() << Entry.name();
10266     if (WeakDef || ThreadLocal || Resolver || Abs) {
10267       bool NeedsComma = false;
10268       outs() << " [";
10269       if (WeakDef) {
10270         outs() << "weak_def";
10271         NeedsComma = true;
10272       }
10273       if (ThreadLocal) {
10274         if (NeedsComma)
10275           outs() << ", ";
10276         outs() << "per-thread";
10277         NeedsComma = true;
10278       }
10279       if (Abs) {
10280         if (NeedsComma)
10281           outs() << ", ";
10282         outs() << "absolute";
10283         NeedsComma = true;
10284       }
10285       if (Resolver) {
10286         if (NeedsComma)
10287           outs() << ", ";
10288         outs() << format("resolver=0x%08llX", Entry.other());
10289         NeedsComma = true;
10290       }
10291       outs() << "]";
10292     }
10293     if (ReExport) {
10294       StringRef DylibName = "unknown";
10295       int Ordinal = Entry.other() - 1;
10296       Obj->getLibraryShortNameByIndex(Ordinal, DylibName);
10297       if (Entry.otherName().empty())
10298         outs() << " (from " << DylibName << ")";
10299       else
10300         outs() << " (" << Entry.otherName() << " from " << DylibName << ")";
10301     }
10302     outs() << "\n";
10303   }
10304   if (Err)
10305     reportError(std::move(Err), Obj->getFileName());
10306 }
10307 
10308 //===----------------------------------------------------------------------===//
10309 // rebase table dumping
10310 //===----------------------------------------------------------------------===//
10311 
10312 static void printMachORebaseTable(object::MachOObjectFile *Obj) {
10313   outs() << "segment  section            address     type\n";
10314   Error Err = Error::success();
10315   for (const object::MachORebaseEntry &Entry : Obj->rebaseTable(Err)) {
10316     StringRef SegmentName = Entry.segmentName();
10317     StringRef SectionName = Entry.sectionName();
10318     uint64_t Address = Entry.address();
10319 
10320     // Table lines look like: __DATA  __nl_symbol_ptr  0x0000F00C  pointer
10321     outs() << format("%-8s %-18s 0x%08" PRIX64 "  %s\n",
10322                      SegmentName.str().c_str(), SectionName.str().c_str(),
10323                      Address, Entry.typeName().str().c_str());
10324   }
10325   if (Err)
10326     reportError(std::move(Err), Obj->getFileName());
10327 }
10328 
10329 static StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) {
10330   StringRef DylibName;
10331   switch (Ordinal) {
10332   case MachO::BIND_SPECIAL_DYLIB_SELF:
10333     return "this-image";
10334   case MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE:
10335     return "main-executable";
10336   case MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP:
10337     return "flat-namespace";
10338   default:
10339     if (Ordinal > 0) {
10340       std::error_code EC =
10341           Obj->getLibraryShortNameByIndex(Ordinal - 1, DylibName);
10342       if (EC)
10343         return "<<bad library ordinal>>";
10344       return DylibName;
10345     }
10346   }
10347   return "<<unknown special ordinal>>";
10348 }
10349 
10350 //===----------------------------------------------------------------------===//
10351 // bind table dumping
10352 //===----------------------------------------------------------------------===//
10353 
10354 static void printMachOBindTable(object::MachOObjectFile *Obj) {
10355   // Build table of sections so names can used in final output.
10356   outs() << "segment  section            address    type       "
10357             "addend dylib            symbol\n";
10358   Error Err = Error::success();
10359   for (const object::MachOBindEntry &Entry : Obj->bindTable(Err)) {
10360     StringRef SegmentName = Entry.segmentName();
10361     StringRef SectionName = Entry.sectionName();
10362     uint64_t Address = Entry.address();
10363 
10364     // Table lines look like:
10365     //  __DATA  __got  0x00012010    pointer   0 libSystem ___stack_chk_guard
10366     StringRef Attr;
10367     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT)
10368       Attr = " (weak_import)";
10369     outs() << left_justify(SegmentName, 8) << " "
10370            << left_justify(SectionName, 18) << " "
10371            << format_hex(Address, 10, true) << " "
10372            << left_justify(Entry.typeName(), 8) << " "
10373            << format_decimal(Entry.addend(), 8) << " "
10374            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
10375            << Entry.symbolName() << Attr << "\n";
10376   }
10377   if (Err)
10378     reportError(std::move(Err), Obj->getFileName());
10379 }
10380 
10381 //===----------------------------------------------------------------------===//
10382 // lazy bind table dumping
10383 //===----------------------------------------------------------------------===//
10384 
10385 static void printMachOLazyBindTable(object::MachOObjectFile *Obj) {
10386   outs() << "segment  section            address     "
10387             "dylib            symbol\n";
10388   Error Err = Error::success();
10389   for (const object::MachOBindEntry &Entry : Obj->lazyBindTable(Err)) {
10390     StringRef SegmentName = Entry.segmentName();
10391     StringRef SectionName = Entry.sectionName();
10392     uint64_t Address = Entry.address();
10393 
10394     // Table lines look like:
10395     //  __DATA  __got  0x00012010 libSystem ___stack_chk_guard
10396     outs() << left_justify(SegmentName, 8) << " "
10397            << left_justify(SectionName, 18) << " "
10398            << format_hex(Address, 10, true) << " "
10399            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
10400            << Entry.symbolName() << "\n";
10401   }
10402   if (Err)
10403     reportError(std::move(Err), Obj->getFileName());
10404 }
10405 
10406 //===----------------------------------------------------------------------===//
10407 // weak bind table dumping
10408 //===----------------------------------------------------------------------===//
10409 
10410 static void printMachOWeakBindTable(object::MachOObjectFile *Obj) {
10411   outs() << "segment  section            address     "
10412             "type       addend   symbol\n";
10413   Error Err = Error::success();
10414   for (const object::MachOBindEntry &Entry : Obj->weakBindTable(Err)) {
10415     // Strong symbols don't have a location to update.
10416     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
10417       outs() << "                                        strong              "
10418              << Entry.symbolName() << "\n";
10419       continue;
10420     }
10421     StringRef SegmentName = Entry.segmentName();
10422     StringRef SectionName = Entry.sectionName();
10423     uint64_t Address = Entry.address();
10424 
10425     // Table lines look like:
10426     // __DATA  __data  0x00001000  pointer    0   _foo
10427     outs() << left_justify(SegmentName, 8) << " "
10428            << left_justify(SectionName, 18) << " "
10429            << format_hex(Address, 10, true) << " "
10430            << left_justify(Entry.typeName(), 8) << " "
10431            << format_decimal(Entry.addend(), 8) << "   " << Entry.symbolName()
10432            << "\n";
10433   }
10434   if (Err)
10435     reportError(std::move(Err), Obj->getFileName());
10436 }
10437 
10438 // get_dyld_bind_info_symbolname() is used for disassembly and passed an
10439 // address, ReferenceValue, in the Mach-O file and looks in the dyld bind
10440 // information for that address. If the address is found its binding symbol
10441 // name is returned.  If not nullptr is returned.
10442 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
10443                                                  struct DisassembleInfo *info) {
10444   if (info->bindtable == nullptr) {
10445     info->bindtable = std::make_unique<SymbolAddressMap>();
10446     Error Err = Error::success();
10447     for (const object::MachOBindEntry &Entry : info->O->bindTable(Err)) {
10448       uint64_t Address = Entry.address();
10449       StringRef name = Entry.symbolName();
10450       if (!name.empty())
10451         (*info->bindtable)[Address] = name;
10452     }
10453     if (Err)
10454       reportError(std::move(Err), info->O->getFileName());
10455   }
10456   auto name = info->bindtable->lookup(ReferenceValue);
10457   return !name.empty() ? name.data() : nullptr;
10458 }
10459 
10460 void objdump::printLazyBindTable(ObjectFile *o) {
10461   outs() << "Lazy bind table:\n";
10462   if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10463     printMachOLazyBindTable(MachO);
10464   else
10465     WithColor::error()
10466         << "This operation is only currently supported "
10467            "for Mach-O executable files.\n";
10468 }
10469 
10470 void objdump::printWeakBindTable(ObjectFile *o) {
10471   outs() << "Weak bind table:\n";
10472   if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10473     printMachOWeakBindTable(MachO);
10474   else
10475     WithColor::error()
10476         << "This operation is only currently supported "
10477            "for Mach-O executable files.\n";
10478 }
10479 
10480 void objdump::printExportsTrie(const ObjectFile *o) {
10481   outs() << "Exports trie:\n";
10482   if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10483     printMachOExportsTrie(MachO);
10484   else
10485     WithColor::error()
10486         << "This operation is only currently supported "
10487            "for Mach-O executable files.\n";
10488 }
10489 
10490 void objdump::printRebaseTable(ObjectFile *o) {
10491   outs() << "Rebase table:\n";
10492   if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10493     printMachORebaseTable(MachO);
10494   else
10495     WithColor::error()
10496         << "This operation is only currently supported "
10497            "for Mach-O executable files.\n";
10498 }
10499 
10500 void objdump::printBindTable(ObjectFile *o) {
10501   outs() << "Bind table:\n";
10502   if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10503     printMachOBindTable(MachO);
10504   else
10505     WithColor::error()
10506         << "This operation is only currently supported "
10507            "for Mach-O executable files.\n";
10508 }
10509