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 "ObjdumpOptID.h"
16 #include "llvm-objdump.h"
17 #include "llvm-c/Disassembler.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/BinaryFormat/MachO.h"
22 #include "llvm/Config/config.h"
23 #include "llvm/DebugInfo/DIContext.h"
24 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
25 #include "llvm/Demangle/Demangle.h"
26 #include "llvm/MC/MCAsmInfo.h"
27 #include "llvm/MC/MCContext.h"
28 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
29 #include "llvm/MC/MCInst.h"
30 #include "llvm/MC/MCInstPrinter.h"
31 #include "llvm/MC/MCInstrDesc.h"
32 #include "llvm/MC/MCInstrInfo.h"
33 #include "llvm/MC/MCRegisterInfo.h"
34 #include "llvm/MC/MCSubtargetInfo.h"
35 #include "llvm/MC/MCTargetOptions.h"
36 #include "llvm/MC/TargetRegistry.h"
37 #include "llvm/Object/MachO.h"
38 #include "llvm/Object/MachOUniversal.h"
39 #include "llvm/Option/ArgList.h"
40 #include "llvm/Support/Casting.h"
41 #include "llvm/Support/Debug.h"
42 #include "llvm/Support/Endian.h"
43 #include "llvm/Support/Format.h"
44 #include "llvm/Support/FormattedStream.h"
45 #include "llvm/Support/GraphWriter.h"
46 #include "llvm/Support/LEB128.h"
47 #include "llvm/Support/MemoryBuffer.h"
48 #include "llvm/Support/TargetSelect.h"
49 #include "llvm/Support/ToolOutputFile.h"
50 #include "llvm/Support/WithColor.h"
51 #include "llvm/Support/raw_ostream.h"
52 #include <algorithm>
53 #include <cstring>
54 #include <system_error>
55 
56 #ifdef LLVM_HAVE_LIBXAR
57 extern "C" {
58 #include <xar/xar.h>
59 }
60 #endif
61 
62 using namespace llvm;
63 using namespace llvm::object;
64 using namespace llvm::objdump;
65 
66 bool objdump::FirstPrivateHeader;
67 bool objdump::ExportsTrie;
68 bool objdump::Rebase;
69 bool objdump::Rpaths;
70 bool objdump::Bind;
71 bool objdump::LazyBind;
72 bool objdump::WeakBind;
73 static bool UseDbg;
74 static std::string DSYMFile;
75 bool objdump::FullLeadingAddr;
76 bool objdump::LeadingHeaders;
77 bool objdump::UniversalHeaders;
78 static bool ArchiveMemberOffsets;
79 bool objdump::IndirectSymbols;
80 bool objdump::DataInCode;
81 bool objdump::FunctionStarts;
82 bool objdump::LinkOptHints;
83 bool objdump::InfoPlist;
84 bool objdump::DylibsUsed;
85 bool objdump::DylibId;
86 bool objdump::Verbose;
87 bool objdump::ObjcMetaData;
88 std::string objdump::DisSymName;
89 bool objdump::SymbolicOperands;
90 static std::vector<std::string> ArchFlags;
91 
92 static bool ArchAll = false;
93 static std::string ThumbTripleName;
94 
95 void objdump::parseMachOOptions(const llvm::opt::InputArgList &InputArgs) {
96   FirstPrivateHeader = InputArgs.hasArg(OBJDUMP_private_header);
97   ExportsTrie = InputArgs.hasArg(OBJDUMP_exports_trie);
98   Rebase = InputArgs.hasArg(OBJDUMP_rebase);
99   Rpaths = InputArgs.hasArg(OBJDUMP_rpaths);
100   Bind = InputArgs.hasArg(OBJDUMP_bind);
101   LazyBind = InputArgs.hasArg(OBJDUMP_lazy_bind);
102   WeakBind = InputArgs.hasArg(OBJDUMP_weak_bind);
103   UseDbg = InputArgs.hasArg(OBJDUMP_g);
104   DSYMFile = InputArgs.getLastArgValue(OBJDUMP_dsym_EQ).str();
105   FullLeadingAddr = InputArgs.hasArg(OBJDUMP_full_leading_addr);
106   LeadingHeaders = !InputArgs.hasArg(OBJDUMP_no_leading_headers);
107   UniversalHeaders = InputArgs.hasArg(OBJDUMP_universal_headers);
108   ArchiveMemberOffsets = InputArgs.hasArg(OBJDUMP_archive_member_offsets);
109   IndirectSymbols = InputArgs.hasArg(OBJDUMP_indirect_symbols);
110   DataInCode = InputArgs.hasArg(OBJDUMP_data_in_code);
111   FunctionStarts = InputArgs.hasArg(OBJDUMP_function_starts);
112   LinkOptHints = InputArgs.hasArg(OBJDUMP_link_opt_hints);
113   InfoPlist = InputArgs.hasArg(OBJDUMP_info_plist);
114   DylibsUsed = InputArgs.hasArg(OBJDUMP_dylibs_used);
115   DylibId = InputArgs.hasArg(OBJDUMP_dylib_id);
116   Verbose = !InputArgs.hasArg(OBJDUMP_non_verbose);
117   ObjcMetaData = InputArgs.hasArg(OBJDUMP_objc_meta_data);
118   DisSymName = InputArgs.getLastArgValue(OBJDUMP_dis_symname).str();
119   SymbolicOperands = !InputArgs.hasArg(OBJDUMP_no_symbolic_operands);
120   ArchFlags = InputArgs.getAllArgValues(OBJDUMP_arch_EQ);
121 }
122 
123 static const Target *GetTarget(const MachOObjectFile *MachOObj,
124                                const char **McpuDefault,
125                                const Target **ThumbTarget) {
126   // Figure out the target triple.
127   Triple TT(TripleName);
128   if (TripleName.empty()) {
129     TT = MachOObj->getArchTriple(McpuDefault);
130     TripleName = TT.str();
131   }
132 
133   if (TT.getArch() == Triple::arm) {
134     // We've inferred a 32-bit ARM target from the object file. All MachO CPUs
135     // that support ARM are also capable of Thumb mode.
136     Triple ThumbTriple = TT;
137     std::string ThumbName = (Twine("thumb") + TT.getArchName().substr(3)).str();
138     ThumbTriple.setArchName(ThumbName);
139     ThumbTripleName = ThumbTriple.str();
140   }
141 
142   // Get the target specific parser.
143   std::string Error;
144   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
145   if (TheTarget && ThumbTripleName.empty())
146     return TheTarget;
147 
148   *ThumbTarget = TargetRegistry::lookupTarget(ThumbTripleName, Error);
149   if (*ThumbTarget)
150     return TheTarget;
151 
152   WithColor::error(errs(), "llvm-objdump") << "unable to get target for '";
153   if (!TheTarget)
154     errs() << TripleName;
155   else
156     errs() << ThumbTripleName;
157   errs() << "', see --version and --triple.\n";
158   return nullptr;
159 }
160 
161 namespace {
162 struct SymbolSorter {
163   bool operator()(const SymbolRef &A, const SymbolRef &B) {
164     Expected<SymbolRef::Type> ATypeOrErr = A.getType();
165     if (!ATypeOrErr)
166       reportError(ATypeOrErr.takeError(), A.getObject()->getFileName());
167     SymbolRef::Type AType = *ATypeOrErr;
168     Expected<SymbolRef::Type> BTypeOrErr = B.getType();
169     if (!BTypeOrErr)
170       reportError(BTypeOrErr.takeError(), B.getObject()->getFileName());
171     SymbolRef::Type BType = *BTypeOrErr;
172     uint64_t AAddr =
173         (AType != SymbolRef::ST_Function) ? 0 : cantFail(A.getValue());
174     uint64_t BAddr =
175         (BType != SymbolRef::ST_Function) ? 0 : cantFail(B.getValue());
176     return AAddr < BAddr;
177   }
178 };
179 } // namespace
180 
181 // Types for the storted data in code table that is built before disassembly
182 // and the predicate function to sort them.
183 typedef std::pair<uint64_t, DiceRef> DiceTableEntry;
184 typedef std::vector<DiceTableEntry> DiceTable;
185 typedef DiceTable::iterator dice_table_iterator;
186 
187 #ifdef LLVM_HAVE_LIBXAR
188 namespace {
189 struct ScopedXarFile {
190   xar_t xar;
191   ScopedXarFile(const char *filename, int32_t flags)
192       : xar(xar_open(filename, flags)) {}
193   ~ScopedXarFile() {
194     if (xar)
195       xar_close(xar);
196   }
197   ScopedXarFile(const ScopedXarFile &) = delete;
198   ScopedXarFile &operator=(const ScopedXarFile &) = delete;
199   operator xar_t() { return xar; }
200 };
201 
202 struct ScopedXarIter {
203   xar_iter_t iter;
204   ScopedXarIter() : iter(xar_iter_new()) {}
205   ~ScopedXarIter() {
206     if (iter)
207       xar_iter_free(iter);
208   }
209   ScopedXarIter(const ScopedXarIter &) = delete;
210   ScopedXarIter &operator=(const ScopedXarIter &) = delete;
211   operator xar_iter_t() { return iter; }
212 };
213 } // namespace
214 #endif // defined(LLVM_HAVE_LIBXAR)
215 
216 // This is used to search for a data in code table entry for the PC being
217 // disassembled.  The j parameter has the PC in j.first.  A single data in code
218 // table entry can cover many bytes for each of its Kind's.  So if the offset,
219 // aka the i.first value, of the data in code table entry plus its Length
220 // covers the PC being searched for this will return true.  If not it will
221 // return false.
222 static bool compareDiceTableEntries(const DiceTableEntry &i,
223                                     const DiceTableEntry &j) {
224   uint16_t Length;
225   i.second.getLength(Length);
226 
227   return j.first >= i.first && j.first < i.first + Length;
228 }
229 
230 static uint64_t DumpDataInCode(const uint8_t *bytes, uint64_t Length,
231                                unsigned short Kind) {
232   uint32_t Value, Size = 1;
233 
234   switch (Kind) {
235   default:
236   case MachO::DICE_KIND_DATA:
237     if (Length >= 4) {
238       if (ShowRawInsn)
239         dumpBytes(makeArrayRef(bytes, 4), outs());
240       Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
241       outs() << "\t.long " << Value;
242       Size = 4;
243     } else if (Length >= 2) {
244       if (ShowRawInsn)
245         dumpBytes(makeArrayRef(bytes, 2), outs());
246       Value = bytes[1] << 8 | bytes[0];
247       outs() << "\t.short " << Value;
248       Size = 2;
249     } else {
250       if (ShowRawInsn)
251         dumpBytes(makeArrayRef(bytes, 2), outs());
252       Value = bytes[0];
253       outs() << "\t.byte " << Value;
254       Size = 1;
255     }
256     if (Kind == MachO::DICE_KIND_DATA)
257       outs() << "\t@ KIND_DATA\n";
258     else
259       outs() << "\t@ data in code kind = " << Kind << "\n";
260     break;
261   case MachO::DICE_KIND_JUMP_TABLE8:
262     if (ShowRawInsn)
263       dumpBytes(makeArrayRef(bytes, 1), outs());
264     Value = bytes[0];
265     outs() << "\t.byte " << format("%3u", Value) << "\t@ KIND_JUMP_TABLE8\n";
266     Size = 1;
267     break;
268   case MachO::DICE_KIND_JUMP_TABLE16:
269     if (ShowRawInsn)
270       dumpBytes(makeArrayRef(bytes, 2), outs());
271     Value = bytes[1] << 8 | bytes[0];
272     outs() << "\t.short " << format("%5u", Value & 0xffff)
273            << "\t@ KIND_JUMP_TABLE16\n";
274     Size = 2;
275     break;
276   case MachO::DICE_KIND_JUMP_TABLE32:
277   case MachO::DICE_KIND_ABS_JUMP_TABLE32:
278     if (ShowRawInsn)
279       dumpBytes(makeArrayRef(bytes, 4), outs());
280     Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
281     outs() << "\t.long " << Value;
282     if (Kind == MachO::DICE_KIND_JUMP_TABLE32)
283       outs() << "\t@ KIND_JUMP_TABLE32\n";
284     else
285       outs() << "\t@ KIND_ABS_JUMP_TABLE32\n";
286     Size = 4;
287     break;
288   }
289   return Size;
290 }
291 
292 static void getSectionsAndSymbols(MachOObjectFile *MachOObj,
293                                   std::vector<SectionRef> &Sections,
294                                   std::vector<SymbolRef> &Symbols,
295                                   SmallVectorImpl<uint64_t> &FoundFns,
296                                   uint64_t &BaseSegmentAddress) {
297   const StringRef FileName = MachOObj->getFileName();
298   for (const SymbolRef &Symbol : MachOObj->symbols()) {
299     StringRef SymName = unwrapOrError(Symbol.getName(), FileName);
300     if (!SymName.startswith("ltmp"))
301       Symbols.push_back(Symbol);
302   }
303 
304   append_range(Sections, MachOObj->sections());
305 
306   bool BaseSegmentAddressSet = false;
307   for (const auto &Command : MachOObj->load_commands()) {
308     if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
309       // We found a function starts segment, parse the addresses for later
310       // consumption.
311       MachO::linkedit_data_command LLC =
312           MachOObj->getLinkeditDataLoadCommand(Command);
313 
314       MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
315     } else if (Command.C.cmd == MachO::LC_SEGMENT) {
316       MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command);
317       StringRef SegName = SLC.segname;
318       if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
319         BaseSegmentAddressSet = true;
320         BaseSegmentAddress = SLC.vmaddr;
321       }
322     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
323       MachO::segment_command_64 SLC = MachOObj->getSegment64LoadCommand(Command);
324       StringRef SegName = SLC.segname;
325       if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
326         BaseSegmentAddressSet = true;
327         BaseSegmentAddress = SLC.vmaddr;
328       }
329     }
330   }
331 }
332 
333 static bool DumpAndSkipDataInCode(uint64_t PC, const uint8_t *bytes,
334                                  DiceTable &Dices, uint64_t &InstSize) {
335   // Check the data in code table here to see if this is data not an
336   // instruction to be disassembled.
337   DiceTable Dice;
338   Dice.push_back(std::make_pair(PC, DiceRef()));
339   dice_table_iterator DTI =
340       std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(),
341                   compareDiceTableEntries);
342   if (DTI != Dices.end()) {
343     uint16_t Length;
344     DTI->second.getLength(Length);
345     uint16_t Kind;
346     DTI->second.getKind(Kind);
347     InstSize = DumpDataInCode(bytes, Length, Kind);
348     if ((Kind == MachO::DICE_KIND_JUMP_TABLE8) &&
349         (PC == (DTI->first + Length - 1)) && (Length & 1))
350       InstSize++;
351     return true;
352   }
353   return false;
354 }
355 
356 static void printRelocationTargetName(const MachOObjectFile *O,
357                                       const MachO::any_relocation_info &RE,
358                                       raw_string_ostream &Fmt) {
359   // Target of a scattered relocation is an address.  In the interest of
360   // generating pretty output, scan through the symbol table looking for a
361   // symbol that aligns with that address.  If we find one, print it.
362   // Otherwise, we just print the hex address of the target.
363   const StringRef FileName = O->getFileName();
364   if (O->isRelocationScattered(RE)) {
365     uint32_t Val = O->getPlainRelocationSymbolNum(RE);
366 
367     for (const SymbolRef &Symbol : O->symbols()) {
368       uint64_t Addr = unwrapOrError(Symbol.getAddress(), FileName);
369       if (Addr != Val)
370         continue;
371       Fmt << unwrapOrError(Symbol.getName(), FileName);
372       return;
373     }
374 
375     // If we couldn't find a symbol that this relocation refers to, try
376     // to find a section beginning instead.
377     for (const SectionRef &Section : ToolSectionFilter(*O)) {
378       uint64_t Addr = Section.getAddress();
379       if (Addr != Val)
380         continue;
381       StringRef NameOrErr = unwrapOrError(Section.getName(), O->getFileName());
382       Fmt << NameOrErr;
383       return;
384     }
385 
386     Fmt << format("0x%x", Val);
387     return;
388   }
389 
390   StringRef S;
391   bool isExtern = O->getPlainRelocationExternal(RE);
392   uint64_t Val = O->getPlainRelocationSymbolNum(RE);
393 
394   if (O->getAnyRelocationType(RE) == MachO::ARM64_RELOC_ADDEND &&
395       (O->getArch() == Triple::aarch64 || O->getArch() == Triple::aarch64_be)) {
396     Fmt << format("0x%0" PRIx64, Val);
397     return;
398   }
399 
400   if (isExtern) {
401     symbol_iterator SI = O->symbol_begin();
402     std::advance(SI, Val);
403     S = unwrapOrError(SI->getName(), FileName);
404   } else {
405     section_iterator SI = O->section_begin();
406     // Adjust for the fact that sections are 1-indexed.
407     if (Val == 0) {
408       Fmt << "0 (?,?)";
409       return;
410     }
411     uint32_t I = Val - 1;
412     while (I != 0 && SI != O->section_end()) {
413       --I;
414       std::advance(SI, 1);
415     }
416     if (SI == O->section_end()) {
417       Fmt << Val << " (?,?)";
418     } else {
419       if (Expected<StringRef> NameOrErr = SI->getName())
420         S = *NameOrErr;
421       else
422         consumeError(NameOrErr.takeError());
423     }
424   }
425 
426   Fmt << S;
427 }
428 
429 Error objdump::getMachORelocationValueString(const MachOObjectFile *Obj,
430                                              const RelocationRef &RelRef,
431                                              SmallVectorImpl<char> &Result) {
432   DataRefImpl Rel = RelRef.getRawDataRefImpl();
433   MachO::any_relocation_info RE = Obj->getRelocation(Rel);
434 
435   unsigned Arch = Obj->getArch();
436 
437   std::string FmtBuf;
438   raw_string_ostream Fmt(FmtBuf);
439   unsigned Type = Obj->getAnyRelocationType(RE);
440   bool IsPCRel = Obj->getAnyRelocationPCRel(RE);
441 
442   // Determine any addends that should be displayed with the relocation.
443   // These require decoding the relocation type, which is triple-specific.
444 
445   // X86_64 has entirely custom relocation types.
446   if (Arch == Triple::x86_64) {
447     switch (Type) {
448     case MachO::X86_64_RELOC_GOT_LOAD:
449     case MachO::X86_64_RELOC_GOT: {
450       printRelocationTargetName(Obj, RE, Fmt);
451       Fmt << "@GOT";
452       if (IsPCRel)
453         Fmt << "PCREL";
454       break;
455     }
456     case MachO::X86_64_RELOC_SUBTRACTOR: {
457       DataRefImpl RelNext = Rel;
458       Obj->moveRelocationNext(RelNext);
459       MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
460 
461       // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
462       // X86_64_RELOC_UNSIGNED.
463       // NOTE: Scattered relocations don't exist on x86_64.
464       unsigned RType = Obj->getAnyRelocationType(RENext);
465       if (RType != MachO::X86_64_RELOC_UNSIGNED)
466         reportError(Obj->getFileName(), "Expected X86_64_RELOC_UNSIGNED after "
467                                         "X86_64_RELOC_SUBTRACTOR.");
468 
469       // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
470       // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
471       printRelocationTargetName(Obj, RENext, Fmt);
472       Fmt << "-";
473       printRelocationTargetName(Obj, RE, Fmt);
474       break;
475     }
476     case MachO::X86_64_RELOC_TLV:
477       printRelocationTargetName(Obj, RE, Fmt);
478       Fmt << "@TLV";
479       if (IsPCRel)
480         Fmt << "P";
481       break;
482     case MachO::X86_64_RELOC_SIGNED_1:
483       printRelocationTargetName(Obj, RE, Fmt);
484       Fmt << "-1";
485       break;
486     case MachO::X86_64_RELOC_SIGNED_2:
487       printRelocationTargetName(Obj, RE, Fmt);
488       Fmt << "-2";
489       break;
490     case MachO::X86_64_RELOC_SIGNED_4:
491       printRelocationTargetName(Obj, RE, Fmt);
492       Fmt << "-4";
493       break;
494     default:
495       printRelocationTargetName(Obj, RE, Fmt);
496       break;
497     }
498     // X86 and ARM share some relocation types in common.
499   } else if (Arch == Triple::x86 || Arch == Triple::arm ||
500              Arch == Triple::ppc) {
501     // Generic relocation types...
502     switch (Type) {
503     case MachO::GENERIC_RELOC_PAIR: // prints no info
504       return Error::success();
505     case MachO::GENERIC_RELOC_SECTDIFF: {
506       DataRefImpl RelNext = Rel;
507       Obj->moveRelocationNext(RelNext);
508       MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
509 
510       // X86 sect diff's must be followed by a relocation of type
511       // GENERIC_RELOC_PAIR.
512       unsigned RType = Obj->getAnyRelocationType(RENext);
513 
514       if (RType != MachO::GENERIC_RELOC_PAIR)
515         reportError(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
516                                         "GENERIC_RELOC_SECTDIFF.");
517 
518       printRelocationTargetName(Obj, RE, Fmt);
519       Fmt << "-";
520       printRelocationTargetName(Obj, RENext, Fmt);
521       break;
522     }
523     }
524 
525     if (Arch == Triple::x86 || Arch == Triple::ppc) {
526       switch (Type) {
527       case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
528         DataRefImpl RelNext = Rel;
529         Obj->moveRelocationNext(RelNext);
530         MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
531 
532         // X86 sect diff's must be followed by a relocation of type
533         // GENERIC_RELOC_PAIR.
534         unsigned RType = Obj->getAnyRelocationType(RENext);
535         if (RType != MachO::GENERIC_RELOC_PAIR)
536           reportError(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
537                                           "GENERIC_RELOC_LOCAL_SECTDIFF.");
538 
539         printRelocationTargetName(Obj, RE, Fmt);
540         Fmt << "-";
541         printRelocationTargetName(Obj, RENext, Fmt);
542         break;
543       }
544       case MachO::GENERIC_RELOC_TLV: {
545         printRelocationTargetName(Obj, RE, Fmt);
546         Fmt << "@TLV";
547         if (IsPCRel)
548           Fmt << "P";
549         break;
550       }
551       default:
552         printRelocationTargetName(Obj, RE, Fmt);
553       }
554     } else { // ARM-specific relocations
555       switch (Type) {
556       case MachO::ARM_RELOC_HALF:
557       case MachO::ARM_RELOC_HALF_SECTDIFF: {
558         // Half relocations steal a bit from the length field to encode
559         // whether this is an upper16 or a lower16 relocation.
560         bool isUpper = (Obj->getAnyRelocationLength(RE) & 0x1) == 1;
561 
562         if (isUpper)
563           Fmt << ":upper16:(";
564         else
565           Fmt << ":lower16:(";
566         printRelocationTargetName(Obj, RE, Fmt);
567 
568         DataRefImpl RelNext = Rel;
569         Obj->moveRelocationNext(RelNext);
570         MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
571 
572         // ARM half relocs must be followed by a relocation of type
573         // ARM_RELOC_PAIR.
574         unsigned RType = Obj->getAnyRelocationType(RENext);
575         if (RType != MachO::ARM_RELOC_PAIR)
576           reportError(Obj->getFileName(), "Expected ARM_RELOC_PAIR after "
577                                           "ARM_RELOC_HALF");
578 
579         // NOTE: The half of the target virtual address is stashed in the
580         // address field of the secondary relocation, but we can't reverse
581         // engineer the constant offset from it without decoding the movw/movt
582         // instruction to find the other half in its immediate field.
583 
584         // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
585         // symbol/section pointer of the follow-on relocation.
586         if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
587           Fmt << "-";
588           printRelocationTargetName(Obj, RENext, Fmt);
589         }
590 
591         Fmt << ")";
592         break;
593       }
594       default: {
595         printRelocationTargetName(Obj, RE, Fmt);
596       }
597       }
598     }
599   } else
600     printRelocationTargetName(Obj, RE, Fmt);
601 
602   Fmt.flush();
603   Result.append(FmtBuf.begin(), FmtBuf.end());
604   return Error::success();
605 }
606 
607 static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose,
608                                      uint32_t n, uint32_t count,
609                                      uint32_t stride, uint64_t addr) {
610   MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
611   uint32_t nindirectsyms = Dysymtab.nindirectsyms;
612   if (n > nindirectsyms)
613     outs() << " (entries start past the end of the indirect symbol "
614               "table) (reserved1 field greater than the table size)";
615   else if (n + count > nindirectsyms)
616     outs() << " (entries extends past the end of the indirect symbol "
617               "table)";
618   outs() << "\n";
619   uint32_t cputype = O->getHeader().cputype;
620   if (cputype & MachO::CPU_ARCH_ABI64)
621     outs() << "address            index";
622   else
623     outs() << "address    index";
624   if (verbose)
625     outs() << " name\n";
626   else
627     outs() << "\n";
628   for (uint32_t j = 0; j < count && n + j < nindirectsyms; j++) {
629     if (cputype & MachO::CPU_ARCH_ABI64)
630       outs() << format("0x%016" PRIx64, addr + j * stride) << " ";
631     else
632       outs() << format("0x%08" PRIx32, (uint32_t)addr + j * stride) << " ";
633     MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
634     uint32_t indirect_symbol = O->getIndirectSymbolTableEntry(Dysymtab, n + j);
635     if (indirect_symbol == MachO::INDIRECT_SYMBOL_LOCAL) {
636       outs() << "LOCAL\n";
637       continue;
638     }
639     if (indirect_symbol ==
640         (MachO::INDIRECT_SYMBOL_LOCAL | MachO::INDIRECT_SYMBOL_ABS)) {
641       outs() << "LOCAL ABSOLUTE\n";
642       continue;
643     }
644     if (indirect_symbol == MachO::INDIRECT_SYMBOL_ABS) {
645       outs() << "ABSOLUTE\n";
646       continue;
647     }
648     outs() << format("%5u ", indirect_symbol);
649     if (verbose) {
650       MachO::symtab_command Symtab = O->getSymtabLoadCommand();
651       if (indirect_symbol < Symtab.nsyms) {
652         symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol);
653         SymbolRef Symbol = *Sym;
654         outs() << unwrapOrError(Symbol.getName(), O->getFileName());
655       } else {
656         outs() << "?";
657       }
658     }
659     outs() << "\n";
660   }
661 }
662 
663 static void PrintIndirectSymbols(MachOObjectFile *O, bool verbose) {
664   for (const auto &Load : O->load_commands()) {
665     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
666       MachO::segment_command_64 Seg = O->getSegment64LoadCommand(Load);
667       for (unsigned J = 0; J < Seg.nsects; ++J) {
668         MachO::section_64 Sec = O->getSection64(Load, J);
669         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
670         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
671             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
672             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
673             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
674             section_type == MachO::S_SYMBOL_STUBS) {
675           uint32_t stride;
676           if (section_type == MachO::S_SYMBOL_STUBS)
677             stride = Sec.reserved2;
678           else
679             stride = 8;
680           if (stride == 0) {
681             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
682                    << Sec.sectname << ") "
683                    << "(size of stubs in reserved2 field is zero)\n";
684             continue;
685           }
686           uint32_t count = Sec.size / stride;
687           outs() << "Indirect symbols for (" << Sec.segname << ","
688                  << Sec.sectname << ") " << count << " entries";
689           uint32_t n = Sec.reserved1;
690           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
691         }
692       }
693     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
694       MachO::segment_command Seg = O->getSegmentLoadCommand(Load);
695       for (unsigned J = 0; J < Seg.nsects; ++J) {
696         MachO::section Sec = O->getSection(Load, J);
697         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
698         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
699             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
700             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
701             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
702             section_type == MachO::S_SYMBOL_STUBS) {
703           uint32_t stride;
704           if (section_type == MachO::S_SYMBOL_STUBS)
705             stride = Sec.reserved2;
706           else
707             stride = 4;
708           if (stride == 0) {
709             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
710                    << Sec.sectname << ") "
711                    << "(size of stubs in reserved2 field is zero)\n";
712             continue;
713           }
714           uint32_t count = Sec.size / stride;
715           outs() << "Indirect symbols for (" << Sec.segname << ","
716                  << Sec.sectname << ") " << count << " entries";
717           uint32_t n = Sec.reserved1;
718           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
719         }
720       }
721     }
722   }
723 }
724 
725 static void PrintRType(const uint64_t cputype, const unsigned r_type) {
726   static char const *generic_r_types[] = {
727     "VANILLA ", "PAIR    ", "SECTDIF ", "PBLAPTR ", "LOCSDIF ", "TLV     ",
728     "  6 (?) ", "  7 (?) ", "  8 (?) ", "  9 (?) ", " 10 (?) ", " 11 (?) ",
729     " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) "
730   };
731   static char const *x86_64_r_types[] = {
732     "UNSIGND ", "SIGNED  ", "BRANCH  ", "GOT_LD  ", "GOT     ", "SUB     ",
733     "SIGNED1 ", "SIGNED2 ", "SIGNED4 ", "TLV     ", " 10 (?) ", " 11 (?) ",
734     " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) "
735   };
736   static char const *arm_r_types[] = {
737     "VANILLA ", "PAIR    ", "SECTDIFF", "LOCSDIF ", "PBLAPTR ",
738     "BR24    ", "T_BR22  ", "T_BR32  ", "HALF    ", "HALFDIF ",
739     " 10 (?) ", " 11 (?) ", " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) "
740   };
741   static char const *arm64_r_types[] = {
742     "UNSIGND ", "SUB     ", "BR26    ", "PAGE21  ", "PAGOF12 ",
743     "GOTLDP  ", "GOTLDPOF", "PTRTGOT ", "TLVLDP  ", "TLVLDPOF",
744     "ADDEND  ", " 11 (?) ", " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) "
745   };
746 
747   if (r_type > 0xf){
748     outs() << format("%-7u", r_type) << " ";
749     return;
750   }
751   switch (cputype) {
752     case MachO::CPU_TYPE_I386:
753       outs() << generic_r_types[r_type];
754       break;
755     case MachO::CPU_TYPE_X86_64:
756       outs() << x86_64_r_types[r_type];
757       break;
758     case MachO::CPU_TYPE_ARM:
759       outs() << arm_r_types[r_type];
760       break;
761     case MachO::CPU_TYPE_ARM64:
762     case MachO::CPU_TYPE_ARM64_32:
763       outs() << arm64_r_types[r_type];
764       break;
765     default:
766       outs() << format("%-7u ", r_type);
767   }
768 }
769 
770 static void PrintRLength(const uint64_t cputype, const unsigned r_type,
771                          const unsigned r_length, const bool previous_arm_half){
772   if (cputype == MachO::CPU_TYPE_ARM &&
773       (r_type == MachO::ARM_RELOC_HALF ||
774        r_type == MachO::ARM_RELOC_HALF_SECTDIFF || previous_arm_half == true)) {
775     if ((r_length & 0x1) == 0)
776       outs() << "lo/";
777     else
778       outs() << "hi/";
779     if ((r_length & 0x1) == 0)
780       outs() << "arm ";
781     else
782       outs() << "thm ";
783   } else {
784     switch (r_length) {
785       case 0:
786         outs() << "byte   ";
787         break;
788       case 1:
789         outs() << "word   ";
790         break;
791       case 2:
792         outs() << "long   ";
793         break;
794       case 3:
795         if (cputype == MachO::CPU_TYPE_X86_64)
796           outs() << "quad   ";
797         else
798           outs() << format("?(%2d)  ", r_length);
799         break;
800       default:
801         outs() << format("?(%2d)  ", r_length);
802     }
803   }
804 }
805 
806 static void PrintRelocationEntries(const MachOObjectFile *O,
807                                    const relocation_iterator Begin,
808                                    const relocation_iterator End,
809                                    const uint64_t cputype,
810                                    const bool verbose) {
811   const MachO::symtab_command Symtab = O->getSymtabLoadCommand();
812   bool previous_arm_half = false;
813   bool previous_sectdiff = false;
814   uint32_t sectdiff_r_type = 0;
815 
816   for (relocation_iterator Reloc = Begin; Reloc != End; ++Reloc) {
817     const DataRefImpl Rel = Reloc->getRawDataRefImpl();
818     const MachO::any_relocation_info RE = O->getRelocation(Rel);
819     const unsigned r_type = O->getAnyRelocationType(RE);
820     const bool r_scattered = O->isRelocationScattered(RE);
821     const unsigned r_pcrel = O->getAnyRelocationPCRel(RE);
822     const unsigned r_length = O->getAnyRelocationLength(RE);
823     const unsigned r_address = O->getAnyRelocationAddress(RE);
824     const bool r_extern = (r_scattered ? false :
825                            O->getPlainRelocationExternal(RE));
826     const uint32_t r_value = (r_scattered ?
827                               O->getScatteredRelocationValue(RE) : 0);
828     const unsigned r_symbolnum = (r_scattered ? 0 :
829                                   O->getPlainRelocationSymbolNum(RE));
830 
831     if (r_scattered && cputype != MachO::CPU_TYPE_X86_64) {
832       if (verbose) {
833         // scattered: address
834         if ((cputype == MachO::CPU_TYPE_I386 &&
835              r_type == MachO::GENERIC_RELOC_PAIR) ||
836             (cputype == MachO::CPU_TYPE_ARM && r_type == MachO::ARM_RELOC_PAIR))
837           outs() << "         ";
838         else
839           outs() << format("%08x ", (unsigned int)r_address);
840 
841         // scattered: pcrel
842         if (r_pcrel)
843           outs() << "True  ";
844         else
845           outs() << "False ";
846 
847         // scattered: length
848         PrintRLength(cputype, r_type, r_length, previous_arm_half);
849 
850         // scattered: extern & type
851         outs() << "n/a    ";
852         PrintRType(cputype, r_type);
853 
854         // scattered: scattered & value
855         outs() << format("True      0x%08x", (unsigned int)r_value);
856         if (previous_sectdiff == false) {
857           if ((cputype == MachO::CPU_TYPE_ARM &&
858                r_type == MachO::ARM_RELOC_PAIR))
859             outs() << format(" half = 0x%04x ", (unsigned int)r_address);
860         } else if (cputype == MachO::CPU_TYPE_ARM &&
861                    sectdiff_r_type == MachO::ARM_RELOC_HALF_SECTDIFF)
862           outs() << format(" other_half = 0x%04x ", (unsigned int)r_address);
863         if ((cputype == MachO::CPU_TYPE_I386 &&
864              (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
865               r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) ||
866             (cputype == MachO::CPU_TYPE_ARM &&
867              (sectdiff_r_type == MachO::ARM_RELOC_SECTDIFF ||
868               sectdiff_r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
869               sectdiff_r_type == MachO::ARM_RELOC_HALF_SECTDIFF))) {
870           previous_sectdiff = true;
871           sectdiff_r_type = r_type;
872         } else {
873           previous_sectdiff = false;
874           sectdiff_r_type = 0;
875         }
876         if (cputype == MachO::CPU_TYPE_ARM &&
877             (r_type == MachO::ARM_RELOC_HALF ||
878              r_type == MachO::ARM_RELOC_HALF_SECTDIFF))
879           previous_arm_half = true;
880         else
881           previous_arm_half = false;
882         outs() << "\n";
883       }
884       else {
885         // scattered: address pcrel length extern type scattered value
886         outs() << format("%08x %1d     %-2d     n/a    %-7d 1         0x%08x\n",
887                          (unsigned int)r_address, r_pcrel, r_length, r_type,
888                          (unsigned int)r_value);
889       }
890     }
891     else {
892       if (verbose) {
893         // plain: address
894         if (cputype == MachO::CPU_TYPE_ARM && r_type == MachO::ARM_RELOC_PAIR)
895           outs() << "         ";
896         else
897           outs() << format("%08x ", (unsigned int)r_address);
898 
899         // plain: pcrel
900         if (r_pcrel)
901           outs() << "True  ";
902         else
903           outs() << "False ";
904 
905         // plain: length
906         PrintRLength(cputype, r_type, r_length, previous_arm_half);
907 
908         if (r_extern) {
909           // plain: extern & type & scattered
910           outs() << "True   ";
911           PrintRType(cputype, r_type);
912           outs() << "False     ";
913 
914           // plain: symbolnum/value
915           if (r_symbolnum > Symtab.nsyms)
916             outs() << format("?(%d)\n", r_symbolnum);
917           else {
918             SymbolRef Symbol = *O->getSymbolByIndex(r_symbolnum);
919             Expected<StringRef> SymNameNext = Symbol.getName();
920             const char *name = nullptr;
921             if (SymNameNext)
922               name = SymNameNext->data();
923             if (name == nullptr)
924               outs() << format("?(%d)\n", r_symbolnum);
925             else
926               outs() << name << "\n";
927           }
928         }
929         else {
930           // plain: extern & type & scattered
931           outs() << "False  ";
932           PrintRType(cputype, r_type);
933           outs() << "False     ";
934 
935           // plain: symbolnum/value
936           if (cputype == MachO::CPU_TYPE_ARM && r_type == MachO::ARM_RELOC_PAIR)
937             outs() << format("other_half = 0x%04x\n", (unsigned int)r_address);
938           else if ((cputype == MachO::CPU_TYPE_ARM64 ||
939                     cputype == MachO::CPU_TYPE_ARM64_32) &&
940                    r_type == MachO::ARM64_RELOC_ADDEND)
941             outs() << format("addend = 0x%06x\n", (unsigned int)r_symbolnum);
942           else {
943             outs() << format("%d ", r_symbolnum);
944             if (r_symbolnum == MachO::R_ABS)
945               outs() << "R_ABS\n";
946             else {
947               // in this case, r_symbolnum is actually a 1-based section number
948               uint32_t nsects = O->section_end()->getRawDataRefImpl().d.a;
949               if (r_symbolnum > 0 && r_symbolnum <= nsects) {
950                 object::DataRefImpl DRI;
951                 DRI.d.a = r_symbolnum-1;
952                 StringRef SegName = O->getSectionFinalSegmentName(DRI);
953                 if (Expected<StringRef> NameOrErr = O->getSectionName(DRI))
954                   outs() << "(" << SegName << "," << *NameOrErr << ")\n";
955                 else
956                   outs() << "(?,?)\n";
957               }
958               else {
959                 outs() << "(?,?)\n";
960               }
961             }
962           }
963         }
964         if (cputype == MachO::CPU_TYPE_ARM &&
965             (r_type == MachO::ARM_RELOC_HALF ||
966              r_type == MachO::ARM_RELOC_HALF_SECTDIFF))
967           previous_arm_half = true;
968         else
969           previous_arm_half = false;
970       }
971       else {
972         // plain: address pcrel length extern type scattered symbolnum/section
973         outs() << format("%08x %1d     %-2d     %1d      %-7d 0         %d\n",
974                          (unsigned int)r_address, r_pcrel, r_length, r_extern,
975                          r_type, r_symbolnum);
976       }
977     }
978   }
979 }
980 
981 static void PrintRelocations(const MachOObjectFile *O, const bool verbose) {
982   const uint64_t cputype = O->getHeader().cputype;
983   const MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
984   if (Dysymtab.nextrel != 0) {
985     outs() << "External relocation information " << Dysymtab.nextrel
986            << " entries";
987     outs() << "\naddress  pcrel length extern type    scattered "
988               "symbolnum/value\n";
989     PrintRelocationEntries(O, O->extrel_begin(), O->extrel_end(), cputype,
990                            verbose);
991   }
992   if (Dysymtab.nlocrel != 0) {
993     outs() << format("Local relocation information %u entries",
994                      Dysymtab.nlocrel);
995     outs() << "\naddress  pcrel length extern type    scattered "
996               "symbolnum/value\n";
997     PrintRelocationEntries(O, O->locrel_begin(), O->locrel_end(), cputype,
998                            verbose);
999   }
1000   for (const auto &Load : O->load_commands()) {
1001     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1002       const MachO::segment_command_64 Seg = O->getSegment64LoadCommand(Load);
1003       for (unsigned J = 0; J < Seg.nsects; ++J) {
1004         const MachO::section_64 Sec = O->getSection64(Load, J);
1005         if (Sec.nreloc != 0) {
1006           DataRefImpl DRI;
1007           DRI.d.a = J;
1008           const StringRef SegName = O->getSectionFinalSegmentName(DRI);
1009           if (Expected<StringRef> NameOrErr = O->getSectionName(DRI))
1010             outs() << "Relocation information (" << SegName << "," << *NameOrErr
1011                    << format(") %u entries", Sec.nreloc);
1012           else
1013             outs() << "Relocation information (" << SegName << ",?) "
1014                    << format("%u entries", Sec.nreloc);
1015           outs() << "\naddress  pcrel length extern type    scattered "
1016                     "symbolnum/value\n";
1017           PrintRelocationEntries(O, O->section_rel_begin(DRI),
1018                                  O->section_rel_end(DRI), cputype, verbose);
1019         }
1020       }
1021     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1022       const MachO::segment_command Seg = O->getSegmentLoadCommand(Load);
1023       for (unsigned J = 0; J < Seg.nsects; ++J) {
1024         const MachO::section Sec = O->getSection(Load, J);
1025         if (Sec.nreloc != 0) {
1026           DataRefImpl DRI;
1027           DRI.d.a = J;
1028           const StringRef SegName = O->getSectionFinalSegmentName(DRI);
1029           if (Expected<StringRef> NameOrErr = O->getSectionName(DRI))
1030             outs() << "Relocation information (" << SegName << "," << *NameOrErr
1031                    << format(") %u entries", Sec.nreloc);
1032           else
1033             outs() << "Relocation information (" << SegName << ",?) "
1034                    << format("%u entries", Sec.nreloc);
1035           outs() << "\naddress  pcrel length extern type    scattered "
1036                     "symbolnum/value\n";
1037           PrintRelocationEntries(O, O->section_rel_begin(DRI),
1038                                  O->section_rel_end(DRI), cputype, verbose);
1039         }
1040       }
1041     }
1042   }
1043 }
1044 
1045 static void PrintFunctionStarts(MachOObjectFile *O) {
1046   uint64_t BaseSegmentAddress = 0;
1047   for (const MachOObjectFile::LoadCommandInfo &Command : O->load_commands()) {
1048     if (Command.C.cmd == MachO::LC_SEGMENT) {
1049       MachO::segment_command SLC = O->getSegmentLoadCommand(Command);
1050       if (StringRef(SLC.segname) == "__TEXT") {
1051         BaseSegmentAddress = SLC.vmaddr;
1052         break;
1053       }
1054     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
1055       MachO::segment_command_64 SLC = O->getSegment64LoadCommand(Command);
1056       if (StringRef(SLC.segname) == "__TEXT") {
1057         BaseSegmentAddress = SLC.vmaddr;
1058         break;
1059       }
1060     }
1061   }
1062 
1063   SmallVector<uint64_t, 8> FunctionStarts;
1064   for (const MachOObjectFile::LoadCommandInfo &LC : O->load_commands()) {
1065     if (LC.C.cmd == MachO::LC_FUNCTION_STARTS) {
1066       MachO::linkedit_data_command FunctionStartsLC =
1067           O->getLinkeditDataLoadCommand(LC);
1068       O->ReadULEB128s(FunctionStartsLC.dataoff, FunctionStarts);
1069       break;
1070     }
1071   }
1072 
1073   for (uint64_t S : FunctionStarts) {
1074     uint64_t Addr = BaseSegmentAddress + S;
1075     if (O->is64Bit())
1076       outs() << format("%016" PRIx64, Addr) << "\n";
1077     else
1078       outs() << format("%08" PRIx32, static_cast<uint32_t>(Addr)) << "\n";
1079   }
1080 }
1081 
1082 static void PrintDataInCodeTable(MachOObjectFile *O, bool verbose) {
1083   MachO::linkedit_data_command DIC = O->getDataInCodeLoadCommand();
1084   uint32_t nentries = DIC.datasize / sizeof(struct MachO::data_in_code_entry);
1085   outs() << "Data in code table (" << nentries << " entries)\n";
1086   outs() << "offset     length kind\n";
1087   for (dice_iterator DI = O->begin_dices(), DE = O->end_dices(); DI != DE;
1088        ++DI) {
1089     uint32_t Offset;
1090     DI->getOffset(Offset);
1091     outs() << format("0x%08" PRIx32, Offset) << " ";
1092     uint16_t Length;
1093     DI->getLength(Length);
1094     outs() << format("%6u", Length) << " ";
1095     uint16_t Kind;
1096     DI->getKind(Kind);
1097     if (verbose) {
1098       switch (Kind) {
1099       case MachO::DICE_KIND_DATA:
1100         outs() << "DATA";
1101         break;
1102       case MachO::DICE_KIND_JUMP_TABLE8:
1103         outs() << "JUMP_TABLE8";
1104         break;
1105       case MachO::DICE_KIND_JUMP_TABLE16:
1106         outs() << "JUMP_TABLE16";
1107         break;
1108       case MachO::DICE_KIND_JUMP_TABLE32:
1109         outs() << "JUMP_TABLE32";
1110         break;
1111       case MachO::DICE_KIND_ABS_JUMP_TABLE32:
1112         outs() << "ABS_JUMP_TABLE32";
1113         break;
1114       default:
1115         outs() << format("0x%04" PRIx32, Kind);
1116         break;
1117       }
1118     } else
1119       outs() << format("0x%04" PRIx32, Kind);
1120     outs() << "\n";
1121   }
1122 }
1123 
1124 static void PrintLinkOptHints(MachOObjectFile *O) {
1125   MachO::linkedit_data_command LohLC = O->getLinkOptHintsLoadCommand();
1126   const char *loh = O->getData().substr(LohLC.dataoff, 1).data();
1127   uint32_t nloh = LohLC.datasize;
1128   outs() << "Linker optimiztion hints (" << nloh << " total bytes)\n";
1129   for (uint32_t i = 0; i < nloh;) {
1130     unsigned n;
1131     uint64_t identifier = decodeULEB128((const uint8_t *)(loh + i), &n);
1132     i += n;
1133     outs() << "    identifier " << identifier << " ";
1134     if (i >= nloh)
1135       return;
1136     switch (identifier) {
1137     case 1:
1138       outs() << "AdrpAdrp\n";
1139       break;
1140     case 2:
1141       outs() << "AdrpLdr\n";
1142       break;
1143     case 3:
1144       outs() << "AdrpAddLdr\n";
1145       break;
1146     case 4:
1147       outs() << "AdrpLdrGotLdr\n";
1148       break;
1149     case 5:
1150       outs() << "AdrpAddStr\n";
1151       break;
1152     case 6:
1153       outs() << "AdrpLdrGotStr\n";
1154       break;
1155     case 7:
1156       outs() << "AdrpAdd\n";
1157       break;
1158     case 8:
1159       outs() << "AdrpLdrGot\n";
1160       break;
1161     default:
1162       outs() << "Unknown identifier value\n";
1163       break;
1164     }
1165     uint64_t narguments = decodeULEB128((const uint8_t *)(loh + i), &n);
1166     i += n;
1167     outs() << "    narguments " << narguments << "\n";
1168     if (i >= nloh)
1169       return;
1170 
1171     for (uint32_t j = 0; j < narguments; j++) {
1172       uint64_t value = decodeULEB128((const uint8_t *)(loh + i), &n);
1173       i += n;
1174       outs() << "\tvalue " << format("0x%" PRIx64, value) << "\n";
1175       if (i >= nloh)
1176         return;
1177     }
1178   }
1179 }
1180 
1181 static void PrintDylibs(MachOObjectFile *O, bool JustId) {
1182   unsigned Index = 0;
1183   for (const auto &Load : O->load_commands()) {
1184     if ((JustId && Load.C.cmd == MachO::LC_ID_DYLIB) ||
1185         (!JustId && (Load.C.cmd == MachO::LC_ID_DYLIB ||
1186                      Load.C.cmd == MachO::LC_LOAD_DYLIB ||
1187                      Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
1188                      Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
1189                      Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
1190                      Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB))) {
1191       MachO::dylib_command dl = O->getDylibIDLoadCommand(Load);
1192       if (dl.dylib.name < dl.cmdsize) {
1193         const char *p = (const char *)(Load.Ptr) + dl.dylib.name;
1194         if (JustId)
1195           outs() << p << "\n";
1196         else {
1197           outs() << "\t" << p;
1198           outs() << " (compatibility version "
1199                  << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
1200                  << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
1201                  << (dl.dylib.compatibility_version & 0xff) << ",";
1202           outs() << " current version "
1203                  << ((dl.dylib.current_version >> 16) & 0xffff) << "."
1204                  << ((dl.dylib.current_version >> 8) & 0xff) << "."
1205                  << (dl.dylib.current_version & 0xff);
1206           if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB)
1207             outs() << ", weak";
1208           if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB)
1209             outs() << ", reexport";
1210           if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
1211             outs() << ", upward";
1212           if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB)
1213             outs() << ", lazy";
1214           outs() << ")\n";
1215         }
1216       } else {
1217         outs() << "\tBad offset (" << dl.dylib.name << ") for name of ";
1218         if (Load.C.cmd == MachO::LC_ID_DYLIB)
1219           outs() << "LC_ID_DYLIB ";
1220         else if (Load.C.cmd == MachO::LC_LOAD_DYLIB)
1221           outs() << "LC_LOAD_DYLIB ";
1222         else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB)
1223           outs() << "LC_LOAD_WEAK_DYLIB ";
1224         else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB)
1225           outs() << "LC_LAZY_LOAD_DYLIB ";
1226         else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB)
1227           outs() << "LC_REEXPORT_DYLIB ";
1228         else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
1229           outs() << "LC_LOAD_UPWARD_DYLIB ";
1230         else
1231           outs() << "LC_??? ";
1232         outs() << "command " << Index++ << "\n";
1233       }
1234     }
1235   }
1236 }
1237 
1238 static void printRpaths(MachOObjectFile *O) {
1239   for (const auto &Command : O->load_commands()) {
1240     if (Command.C.cmd == MachO::LC_RPATH) {
1241       auto Rpath = O->getRpathCommand(Command);
1242       const char *P = (const char *)(Command.Ptr) + Rpath.path;
1243       outs() << P << "\n";
1244     }
1245   }
1246 }
1247 
1248 typedef DenseMap<uint64_t, StringRef> SymbolAddressMap;
1249 
1250 static void CreateSymbolAddressMap(MachOObjectFile *O,
1251                                    SymbolAddressMap *AddrMap) {
1252   // Create a map of symbol addresses to symbol names.
1253   const StringRef FileName = O->getFileName();
1254   for (const SymbolRef &Symbol : O->symbols()) {
1255     SymbolRef::Type ST = unwrapOrError(Symbol.getType(), FileName);
1256     if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
1257         ST == SymbolRef::ST_Other) {
1258       uint64_t Address = cantFail(Symbol.getValue());
1259       StringRef SymName = unwrapOrError(Symbol.getName(), FileName);
1260       if (!SymName.startswith(".objc"))
1261         (*AddrMap)[Address] = SymName;
1262     }
1263   }
1264 }
1265 
1266 // GuessSymbolName is passed the address of what might be a symbol and a
1267 // pointer to the SymbolAddressMap.  It returns the name of a symbol
1268 // with that address or nullptr if no symbol is found with that address.
1269 static const char *GuessSymbolName(uint64_t value, SymbolAddressMap *AddrMap) {
1270   const char *SymbolName = nullptr;
1271   // A DenseMap can't lookup up some values.
1272   if (value != 0xffffffffffffffffULL && value != 0xfffffffffffffffeULL) {
1273     StringRef name = AddrMap->lookup(value);
1274     if (!name.empty())
1275       SymbolName = name.data();
1276   }
1277   return SymbolName;
1278 }
1279 
1280 static void DumpCstringChar(const char c) {
1281   char p[2];
1282   p[0] = c;
1283   p[1] = '\0';
1284   outs().write_escaped(p);
1285 }
1286 
1287 static void DumpCstringSection(MachOObjectFile *O, const char *sect,
1288                                uint32_t sect_size, uint64_t sect_addr,
1289                                bool print_addresses) {
1290   for (uint32_t i = 0; i < sect_size; i++) {
1291     if (print_addresses) {
1292       if (O->is64Bit())
1293         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1294       else
1295         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1296     }
1297     for (; i < sect_size && sect[i] != '\0'; i++)
1298       DumpCstringChar(sect[i]);
1299     if (i < sect_size && sect[i] == '\0')
1300       outs() << "\n";
1301   }
1302 }
1303 
1304 static void DumpLiteral4(uint32_t l, float f) {
1305   outs() << format("0x%08" PRIx32, l);
1306   if ((l & 0x7f800000) != 0x7f800000)
1307     outs() << format(" (%.16e)\n", f);
1308   else {
1309     if (l == 0x7f800000)
1310       outs() << " (+Infinity)\n";
1311     else if (l == 0xff800000)
1312       outs() << " (-Infinity)\n";
1313     else if ((l & 0x00400000) == 0x00400000)
1314       outs() << " (non-signaling Not-a-Number)\n";
1315     else
1316       outs() << " (signaling Not-a-Number)\n";
1317   }
1318 }
1319 
1320 static void DumpLiteral4Section(MachOObjectFile *O, const char *sect,
1321                                 uint32_t sect_size, uint64_t sect_addr,
1322                                 bool print_addresses) {
1323   for (uint32_t i = 0; i < sect_size; i += sizeof(float)) {
1324     if (print_addresses) {
1325       if (O->is64Bit())
1326         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1327       else
1328         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1329     }
1330     float f;
1331     memcpy(&f, sect + i, sizeof(float));
1332     if (O->isLittleEndian() != sys::IsLittleEndianHost)
1333       sys::swapByteOrder(f);
1334     uint32_t l;
1335     memcpy(&l, sect + i, sizeof(uint32_t));
1336     if (O->isLittleEndian() != sys::IsLittleEndianHost)
1337       sys::swapByteOrder(l);
1338     DumpLiteral4(l, f);
1339   }
1340 }
1341 
1342 static void DumpLiteral8(MachOObjectFile *O, uint32_t l0, uint32_t l1,
1343                          double d) {
1344   outs() << format("0x%08" PRIx32, l0) << " " << format("0x%08" PRIx32, l1);
1345   uint32_t Hi, Lo;
1346   Hi = (O->isLittleEndian()) ? l1 : l0;
1347   Lo = (O->isLittleEndian()) ? l0 : l1;
1348 
1349   // Hi is the high word, so this is equivalent to if(isfinite(d))
1350   if ((Hi & 0x7ff00000) != 0x7ff00000)
1351     outs() << format(" (%.16e)\n", d);
1352   else {
1353     if (Hi == 0x7ff00000 && Lo == 0)
1354       outs() << " (+Infinity)\n";
1355     else if (Hi == 0xfff00000 && Lo == 0)
1356       outs() << " (-Infinity)\n";
1357     else if ((Hi & 0x00080000) == 0x00080000)
1358       outs() << " (non-signaling Not-a-Number)\n";
1359     else
1360       outs() << " (signaling Not-a-Number)\n";
1361   }
1362 }
1363 
1364 static void DumpLiteral8Section(MachOObjectFile *O, const char *sect,
1365                                 uint32_t sect_size, uint64_t sect_addr,
1366                                 bool print_addresses) {
1367   for (uint32_t i = 0; i < sect_size; i += sizeof(double)) {
1368     if (print_addresses) {
1369       if (O->is64Bit())
1370         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1371       else
1372         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1373     }
1374     double d;
1375     memcpy(&d, sect + i, sizeof(double));
1376     if (O->isLittleEndian() != sys::IsLittleEndianHost)
1377       sys::swapByteOrder(d);
1378     uint32_t l0, l1;
1379     memcpy(&l0, sect + i, sizeof(uint32_t));
1380     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
1381     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1382       sys::swapByteOrder(l0);
1383       sys::swapByteOrder(l1);
1384     }
1385     DumpLiteral8(O, l0, l1, d);
1386   }
1387 }
1388 
1389 static void DumpLiteral16(uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3) {
1390   outs() << format("0x%08" PRIx32, l0) << " ";
1391   outs() << format("0x%08" PRIx32, l1) << " ";
1392   outs() << format("0x%08" PRIx32, l2) << " ";
1393   outs() << format("0x%08" PRIx32, l3) << "\n";
1394 }
1395 
1396 static void DumpLiteral16Section(MachOObjectFile *O, const char *sect,
1397                                  uint32_t sect_size, uint64_t sect_addr,
1398                                  bool print_addresses) {
1399   for (uint32_t i = 0; i < sect_size; i += 16) {
1400     if (print_addresses) {
1401       if (O->is64Bit())
1402         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1403       else
1404         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1405     }
1406     uint32_t l0, l1, l2, l3;
1407     memcpy(&l0, sect + i, sizeof(uint32_t));
1408     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
1409     memcpy(&l2, sect + i + 2 * sizeof(uint32_t), sizeof(uint32_t));
1410     memcpy(&l3, sect + i + 3 * sizeof(uint32_t), sizeof(uint32_t));
1411     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1412       sys::swapByteOrder(l0);
1413       sys::swapByteOrder(l1);
1414       sys::swapByteOrder(l2);
1415       sys::swapByteOrder(l3);
1416     }
1417     DumpLiteral16(l0, l1, l2, l3);
1418   }
1419 }
1420 
1421 static void DumpLiteralPointerSection(MachOObjectFile *O,
1422                                       const SectionRef &Section,
1423                                       const char *sect, uint32_t sect_size,
1424                                       uint64_t sect_addr,
1425                                       bool print_addresses) {
1426   // Collect the literal sections in this Mach-O file.
1427   std::vector<SectionRef> LiteralSections;
1428   for (const SectionRef &Section : O->sections()) {
1429     DataRefImpl Ref = Section.getRawDataRefImpl();
1430     uint32_t section_type;
1431     if (O->is64Bit()) {
1432       const MachO::section_64 Sec = O->getSection64(Ref);
1433       section_type = Sec.flags & MachO::SECTION_TYPE;
1434     } else {
1435       const MachO::section Sec = O->getSection(Ref);
1436       section_type = Sec.flags & MachO::SECTION_TYPE;
1437     }
1438     if (section_type == MachO::S_CSTRING_LITERALS ||
1439         section_type == MachO::S_4BYTE_LITERALS ||
1440         section_type == MachO::S_8BYTE_LITERALS ||
1441         section_type == MachO::S_16BYTE_LITERALS)
1442       LiteralSections.push_back(Section);
1443   }
1444 
1445   // Set the size of the literal pointer.
1446   uint32_t lp_size = O->is64Bit() ? 8 : 4;
1447 
1448   // Collect the external relocation symbols for the literal pointers.
1449   std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
1450   for (const RelocationRef &Reloc : Section.relocations()) {
1451     DataRefImpl Rel;
1452     MachO::any_relocation_info RE;
1453     bool isExtern = false;
1454     Rel = Reloc.getRawDataRefImpl();
1455     RE = O->getRelocation(Rel);
1456     isExtern = O->getPlainRelocationExternal(RE);
1457     if (isExtern) {
1458       uint64_t RelocOffset = Reloc.getOffset();
1459       symbol_iterator RelocSym = Reloc.getSymbol();
1460       Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
1461     }
1462   }
1463   array_pod_sort(Relocs.begin(), Relocs.end());
1464 
1465   // Dump each literal pointer.
1466   for (uint32_t i = 0; i < sect_size; i += lp_size) {
1467     if (print_addresses) {
1468       if (O->is64Bit())
1469         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
1470       else
1471         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
1472     }
1473     uint64_t lp;
1474     if (O->is64Bit()) {
1475       memcpy(&lp, sect + i, sizeof(uint64_t));
1476       if (O->isLittleEndian() != sys::IsLittleEndianHost)
1477         sys::swapByteOrder(lp);
1478     } else {
1479       uint32_t li;
1480       memcpy(&li, sect + i, sizeof(uint32_t));
1481       if (O->isLittleEndian() != sys::IsLittleEndianHost)
1482         sys::swapByteOrder(li);
1483       lp = li;
1484     }
1485 
1486     // First look for an external relocation entry for this literal pointer.
1487     auto Reloc = find_if(Relocs, [&](const std::pair<uint64_t, SymbolRef> &P) {
1488       return P.first == i;
1489     });
1490     if (Reloc != Relocs.end()) {
1491       symbol_iterator RelocSym = Reloc->second;
1492       StringRef SymName = unwrapOrError(RelocSym->getName(), O->getFileName());
1493       outs() << "external relocation entry for symbol:" << SymName << "\n";
1494       continue;
1495     }
1496 
1497     // For local references see what the section the literal pointer points to.
1498     auto Sect = find_if(LiteralSections, [&](const SectionRef &R) {
1499       return lp >= R.getAddress() && lp < R.getAddress() + R.getSize();
1500     });
1501     if (Sect == LiteralSections.end()) {
1502       outs() << format("0x%" PRIx64, lp) << " (not in a literal section)\n";
1503       continue;
1504     }
1505 
1506     uint64_t SectAddress = Sect->getAddress();
1507     uint64_t SectSize = Sect->getSize();
1508 
1509     StringRef SectName;
1510     Expected<StringRef> SectNameOrErr = Sect->getName();
1511     if (SectNameOrErr)
1512       SectName = *SectNameOrErr;
1513     else
1514       consumeError(SectNameOrErr.takeError());
1515 
1516     DataRefImpl Ref = Sect->getRawDataRefImpl();
1517     StringRef SegmentName = O->getSectionFinalSegmentName(Ref);
1518     outs() << SegmentName << ":" << SectName << ":";
1519 
1520     uint32_t section_type;
1521     if (O->is64Bit()) {
1522       const MachO::section_64 Sec = O->getSection64(Ref);
1523       section_type = Sec.flags & MachO::SECTION_TYPE;
1524     } else {
1525       const MachO::section Sec = O->getSection(Ref);
1526       section_type = Sec.flags & MachO::SECTION_TYPE;
1527     }
1528 
1529     StringRef BytesStr = unwrapOrError(Sect->getContents(), O->getFileName());
1530 
1531     const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
1532 
1533     switch (section_type) {
1534     case MachO::S_CSTRING_LITERALS:
1535       for (uint64_t i = lp - SectAddress; i < SectSize && Contents[i] != '\0';
1536            i++) {
1537         DumpCstringChar(Contents[i]);
1538       }
1539       outs() << "\n";
1540       break;
1541     case MachO::S_4BYTE_LITERALS:
1542       float f;
1543       memcpy(&f, Contents + (lp - SectAddress), sizeof(float));
1544       uint32_t l;
1545       memcpy(&l, Contents + (lp - SectAddress), sizeof(uint32_t));
1546       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1547         sys::swapByteOrder(f);
1548         sys::swapByteOrder(l);
1549       }
1550       DumpLiteral4(l, f);
1551       break;
1552     case MachO::S_8BYTE_LITERALS: {
1553       double d;
1554       memcpy(&d, Contents + (lp - SectAddress), sizeof(double));
1555       uint32_t l0, l1;
1556       memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
1557       memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
1558              sizeof(uint32_t));
1559       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1560         sys::swapByteOrder(f);
1561         sys::swapByteOrder(l0);
1562         sys::swapByteOrder(l1);
1563       }
1564       DumpLiteral8(O, l0, l1, d);
1565       break;
1566     }
1567     case MachO::S_16BYTE_LITERALS: {
1568       uint32_t l0, l1, l2, l3;
1569       memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
1570       memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
1571              sizeof(uint32_t));
1572       memcpy(&l2, Contents + (lp - SectAddress) + 2 * sizeof(uint32_t),
1573              sizeof(uint32_t));
1574       memcpy(&l3, Contents + (lp - SectAddress) + 3 * sizeof(uint32_t),
1575              sizeof(uint32_t));
1576       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
1577         sys::swapByteOrder(l0);
1578         sys::swapByteOrder(l1);
1579         sys::swapByteOrder(l2);
1580         sys::swapByteOrder(l3);
1581       }
1582       DumpLiteral16(l0, l1, l2, l3);
1583       break;
1584     }
1585     }
1586   }
1587 }
1588 
1589 static void DumpInitTermPointerSection(MachOObjectFile *O,
1590                                        const SectionRef &Section,
1591                                        const char *sect,
1592                                        uint32_t sect_size, uint64_t sect_addr,
1593                                        SymbolAddressMap *AddrMap,
1594                                        bool verbose) {
1595   uint32_t stride;
1596   stride = (O->is64Bit()) ? sizeof(uint64_t) : sizeof(uint32_t);
1597 
1598   // Collect the external relocation symbols for the pointers.
1599   std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
1600   for (const RelocationRef &Reloc : Section.relocations()) {
1601     DataRefImpl Rel;
1602     MachO::any_relocation_info RE;
1603     bool isExtern = false;
1604     Rel = Reloc.getRawDataRefImpl();
1605     RE = O->getRelocation(Rel);
1606     isExtern = O->getPlainRelocationExternal(RE);
1607     if (isExtern) {
1608       uint64_t RelocOffset = Reloc.getOffset();
1609       symbol_iterator RelocSym = Reloc.getSymbol();
1610       Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
1611     }
1612   }
1613   array_pod_sort(Relocs.begin(), Relocs.end());
1614 
1615   for (uint32_t i = 0; i < sect_size; i += stride) {
1616     const char *SymbolName = nullptr;
1617     uint64_t p;
1618     if (O->is64Bit()) {
1619       outs() << format("0x%016" PRIx64, sect_addr + i * stride) << " ";
1620       uint64_t pointer_value;
1621       memcpy(&pointer_value, sect + i, stride);
1622       if (O->isLittleEndian() != sys::IsLittleEndianHost)
1623         sys::swapByteOrder(pointer_value);
1624       outs() << format("0x%016" PRIx64, pointer_value);
1625       p = pointer_value;
1626     } else {
1627       outs() << format("0x%08" PRIx64, sect_addr + i * stride) << " ";
1628       uint32_t pointer_value;
1629       memcpy(&pointer_value, sect + i, stride);
1630       if (O->isLittleEndian() != sys::IsLittleEndianHost)
1631         sys::swapByteOrder(pointer_value);
1632       outs() << format("0x%08" PRIx32, pointer_value);
1633       p = pointer_value;
1634     }
1635     if (verbose) {
1636       // First look for an external relocation entry for this pointer.
1637       auto Reloc = find_if(Relocs, [&](const std::pair<uint64_t, SymbolRef> &P) {
1638         return P.first == i;
1639       });
1640       if (Reloc != Relocs.end()) {
1641         symbol_iterator RelocSym = Reloc->second;
1642         outs() << " " << unwrapOrError(RelocSym->getName(), O->getFileName());
1643       } else {
1644         SymbolName = GuessSymbolName(p, AddrMap);
1645         if (SymbolName)
1646           outs() << " " << SymbolName;
1647       }
1648     }
1649     outs() << "\n";
1650   }
1651 }
1652 
1653 static void DumpRawSectionContents(MachOObjectFile *O, const char *sect,
1654                                    uint32_t size, uint64_t addr) {
1655   uint32_t cputype = O->getHeader().cputype;
1656   if (cputype == MachO::CPU_TYPE_I386 || cputype == MachO::CPU_TYPE_X86_64) {
1657     uint32_t j;
1658     for (uint32_t i = 0; i < size; i += j, addr += j) {
1659       if (O->is64Bit())
1660         outs() << format("%016" PRIx64, addr) << "\t";
1661       else
1662         outs() << format("%08" PRIx64, addr) << "\t";
1663       for (j = 0; j < 16 && i + j < size; j++) {
1664         uint8_t byte_word = *(sect + i + j);
1665         outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
1666       }
1667       outs() << "\n";
1668     }
1669   } else {
1670     uint32_t j;
1671     for (uint32_t i = 0; i < size; i += j, addr += j) {
1672       if (O->is64Bit())
1673         outs() << format("%016" PRIx64, addr) << "\t";
1674       else
1675         outs() << format("%08" PRIx64, addr) << "\t";
1676       for (j = 0; j < 4 * sizeof(int32_t) && i + j < size;
1677            j += sizeof(int32_t)) {
1678         if (i + j + sizeof(int32_t) <= size) {
1679           uint32_t long_word;
1680           memcpy(&long_word, sect + i + j, sizeof(int32_t));
1681           if (O->isLittleEndian() != sys::IsLittleEndianHost)
1682             sys::swapByteOrder(long_word);
1683           outs() << format("%08" PRIx32, long_word) << " ";
1684         } else {
1685           for (uint32_t k = 0; i + j + k < size; k++) {
1686             uint8_t byte_word = *(sect + i + j + k);
1687             outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
1688           }
1689         }
1690       }
1691       outs() << "\n";
1692     }
1693   }
1694 }
1695 
1696 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
1697                              StringRef DisSegName, StringRef DisSectName);
1698 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,
1699                                 uint32_t size, uint32_t addr);
1700 #ifdef LLVM_HAVE_LIBXAR
1701 static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
1702                                 uint32_t size, bool verbose,
1703                                 bool PrintXarHeader, bool PrintXarFileHeaders,
1704                                 std::string XarMemberName);
1705 #endif // defined(LLVM_HAVE_LIBXAR)
1706 
1707 static void DumpSectionContents(StringRef Filename, MachOObjectFile *O,
1708                                 bool verbose) {
1709   SymbolAddressMap AddrMap;
1710   if (verbose)
1711     CreateSymbolAddressMap(O, &AddrMap);
1712 
1713   for (unsigned i = 0; i < FilterSections.size(); ++i) {
1714     StringRef DumpSection = FilterSections[i];
1715     std::pair<StringRef, StringRef> DumpSegSectName;
1716     DumpSegSectName = DumpSection.split(',');
1717     StringRef DumpSegName, DumpSectName;
1718     if (!DumpSegSectName.second.empty()) {
1719       DumpSegName = DumpSegSectName.first;
1720       DumpSectName = DumpSegSectName.second;
1721     } else {
1722       DumpSegName = "";
1723       DumpSectName = DumpSegSectName.first;
1724     }
1725     for (const SectionRef &Section : O->sections()) {
1726       StringRef SectName;
1727       Expected<StringRef> SecNameOrErr = Section.getName();
1728       if (SecNameOrErr)
1729         SectName = *SecNameOrErr;
1730       else
1731         consumeError(SecNameOrErr.takeError());
1732 
1733       if (!DumpSection.empty())
1734         FoundSectionSet.insert(DumpSection);
1735 
1736       DataRefImpl Ref = Section.getRawDataRefImpl();
1737       StringRef SegName = O->getSectionFinalSegmentName(Ref);
1738       if ((DumpSegName.empty() || SegName == DumpSegName) &&
1739           (SectName == DumpSectName)) {
1740 
1741         uint32_t section_flags;
1742         if (O->is64Bit()) {
1743           const MachO::section_64 Sec = O->getSection64(Ref);
1744           section_flags = Sec.flags;
1745 
1746         } else {
1747           const MachO::section Sec = O->getSection(Ref);
1748           section_flags = Sec.flags;
1749         }
1750         uint32_t section_type = section_flags & MachO::SECTION_TYPE;
1751 
1752         StringRef BytesStr =
1753             unwrapOrError(Section.getContents(), O->getFileName());
1754         const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1755         uint32_t sect_size = BytesStr.size();
1756         uint64_t sect_addr = Section.getAddress();
1757 
1758         if (LeadingHeaders)
1759           outs() << "Contents of (" << SegName << "," << SectName
1760                  << ") section\n";
1761 
1762         if (verbose) {
1763           if ((section_flags & MachO::S_ATTR_PURE_INSTRUCTIONS) ||
1764               (section_flags & MachO::S_ATTR_SOME_INSTRUCTIONS)) {
1765             DisassembleMachO(Filename, O, SegName, SectName);
1766             continue;
1767           }
1768           if (SegName == "__TEXT" && SectName == "__info_plist") {
1769             outs() << sect;
1770             continue;
1771           }
1772           if (SegName == "__OBJC" && SectName == "__protocol") {
1773             DumpProtocolSection(O, sect, sect_size, sect_addr);
1774             continue;
1775           }
1776 #ifdef LLVM_HAVE_LIBXAR
1777           if (SegName == "__LLVM" && SectName == "__bundle") {
1778             DumpBitcodeSection(O, sect, sect_size, verbose, SymbolicOperands,
1779                                ArchiveHeaders, "");
1780             continue;
1781           }
1782 #endif // defined(LLVM_HAVE_LIBXAR)
1783           switch (section_type) {
1784           case MachO::S_REGULAR:
1785             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1786             break;
1787           case MachO::S_ZEROFILL:
1788             outs() << "zerofill section and has no contents in the file\n";
1789             break;
1790           case MachO::S_CSTRING_LITERALS:
1791             DumpCstringSection(O, sect, sect_size, sect_addr, LeadingAddr);
1792             break;
1793           case MachO::S_4BYTE_LITERALS:
1794             DumpLiteral4Section(O, sect, sect_size, sect_addr, LeadingAddr);
1795             break;
1796           case MachO::S_8BYTE_LITERALS:
1797             DumpLiteral8Section(O, sect, sect_size, sect_addr, LeadingAddr);
1798             break;
1799           case MachO::S_16BYTE_LITERALS:
1800             DumpLiteral16Section(O, sect, sect_size, sect_addr, LeadingAddr);
1801             break;
1802           case MachO::S_LITERAL_POINTERS:
1803             DumpLiteralPointerSection(O, Section, sect, sect_size, sect_addr,
1804                                       LeadingAddr);
1805             break;
1806           case MachO::S_MOD_INIT_FUNC_POINTERS:
1807           case MachO::S_MOD_TERM_FUNC_POINTERS:
1808             DumpInitTermPointerSection(O, Section, sect, sect_size, sect_addr,
1809                                        &AddrMap, verbose);
1810             break;
1811           default:
1812             outs() << "Unknown section type ("
1813                    << format("0x%08" PRIx32, section_type) << ")\n";
1814             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1815             break;
1816           }
1817         } else {
1818           if (section_type == MachO::S_ZEROFILL)
1819             outs() << "zerofill section and has no contents in the file\n";
1820           else
1821             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1822         }
1823       }
1824     }
1825   }
1826 }
1827 
1828 static void DumpInfoPlistSectionContents(StringRef Filename,
1829                                          MachOObjectFile *O) {
1830   for (const SectionRef &Section : O->sections()) {
1831     StringRef SectName;
1832     Expected<StringRef> SecNameOrErr = Section.getName();
1833     if (SecNameOrErr)
1834       SectName = *SecNameOrErr;
1835     else
1836       consumeError(SecNameOrErr.takeError());
1837 
1838     DataRefImpl Ref = Section.getRawDataRefImpl();
1839     StringRef SegName = O->getSectionFinalSegmentName(Ref);
1840     if (SegName == "__TEXT" && SectName == "__info_plist") {
1841       if (LeadingHeaders)
1842         outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
1843       StringRef BytesStr =
1844           unwrapOrError(Section.getContents(), O->getFileName());
1845       const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1846       outs() << format("%.*s", BytesStr.size(), sect) << "\n";
1847       return;
1848     }
1849   }
1850 }
1851 
1852 // checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file
1853 // and if it is and there is a list of architecture flags is specified then
1854 // check to make sure this Mach-O file is one of those architectures or all
1855 // architectures were specified.  If not then an error is generated and this
1856 // routine returns false.  Else it returns true.
1857 static bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) {
1858   auto *MachO = dyn_cast<MachOObjectFile>(O);
1859 
1860   if (!MachO || ArchAll || ArchFlags.empty())
1861     return true;
1862 
1863   MachO::mach_header H;
1864   MachO::mach_header_64 H_64;
1865   Triple T;
1866   const char *McpuDefault, *ArchFlag;
1867   if (MachO->is64Bit()) {
1868     H_64 = MachO->MachOObjectFile::getHeader64();
1869     T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype,
1870                                        &McpuDefault, &ArchFlag);
1871   } else {
1872     H = MachO->MachOObjectFile::getHeader();
1873     T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype,
1874                                        &McpuDefault, &ArchFlag);
1875   }
1876   const std::string ArchFlagName(ArchFlag);
1877   if (!llvm::is_contained(ArchFlags, ArchFlagName)) {
1878     WithColor::error(errs(), "llvm-objdump")
1879         << Filename << ": no architecture specified.\n";
1880     return false;
1881   }
1882   return true;
1883 }
1884 
1885 static void printObjcMetaData(MachOObjectFile *O, bool verbose);
1886 
1887 // ProcessMachO() is passed a single opened Mach-O file, which may be an
1888 // archive member and or in a slice of a universal file.  It prints the
1889 // the file name and header info and then processes it according to the
1890 // command line options.
1891 static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
1892                          StringRef ArchiveMemberName = StringRef(),
1893                          StringRef ArchitectureName = StringRef()) {
1894   // If we are doing some processing here on the Mach-O file print the header
1895   // info.  And don't print it otherwise like in the case of printing the
1896   // UniversalHeaders or ArchiveHeaders.
1897   if (Disassemble || Relocations || PrivateHeaders || ExportsTrie || Rebase ||
1898       Bind || SymbolTable || LazyBind || WeakBind || IndirectSymbols ||
1899       DataInCode || FunctionStarts || LinkOptHints || DylibsUsed || DylibId ||
1900       Rpaths || ObjcMetaData || (!FilterSections.empty())) {
1901     if (LeadingHeaders) {
1902       outs() << Name;
1903       if (!ArchiveMemberName.empty())
1904         outs() << '(' << ArchiveMemberName << ')';
1905       if (!ArchitectureName.empty())
1906         outs() << " (architecture " << ArchitectureName << ")";
1907       outs() << ":\n";
1908     }
1909   }
1910   // To use the report_error() form with an ArchiveName and FileName set
1911   // these up based on what is passed for Name and ArchiveMemberName.
1912   StringRef ArchiveName;
1913   StringRef FileName;
1914   if (!ArchiveMemberName.empty()) {
1915     ArchiveName = Name;
1916     FileName = ArchiveMemberName;
1917   } else {
1918     ArchiveName = StringRef();
1919     FileName = Name;
1920   }
1921 
1922   // If we need the symbol table to do the operation then check it here to
1923   // produce a good error message as to where the Mach-O file comes from in
1924   // the error message.
1925   if (Disassemble || IndirectSymbols || !FilterSections.empty() || UnwindInfo)
1926     if (Error Err = MachOOF->checkSymbolTable())
1927       reportError(std::move(Err), FileName, ArchiveName, ArchitectureName);
1928 
1929   if (DisassembleAll) {
1930     for (const SectionRef &Section : MachOOF->sections()) {
1931       StringRef SectName;
1932       if (Expected<StringRef> NameOrErr = Section.getName())
1933         SectName = *NameOrErr;
1934       else
1935         consumeError(NameOrErr.takeError());
1936 
1937       if (SectName.equals("__text")) {
1938         DataRefImpl Ref = Section.getRawDataRefImpl();
1939         StringRef SegName = MachOOF->getSectionFinalSegmentName(Ref);
1940         DisassembleMachO(FileName, MachOOF, SegName, SectName);
1941       }
1942     }
1943   }
1944   else if (Disassemble) {
1945     if (MachOOF->getHeader().filetype == MachO::MH_KEXT_BUNDLE &&
1946         MachOOF->getHeader().cputype == MachO::CPU_TYPE_ARM64)
1947       DisassembleMachO(FileName, MachOOF, "__TEXT_EXEC", "__text");
1948     else
1949       DisassembleMachO(FileName, MachOOF, "__TEXT", "__text");
1950   }
1951   if (IndirectSymbols)
1952     PrintIndirectSymbols(MachOOF, Verbose);
1953   if (DataInCode)
1954     PrintDataInCodeTable(MachOOF, Verbose);
1955   if (FunctionStarts)
1956     PrintFunctionStarts(MachOOF);
1957   if (LinkOptHints)
1958     PrintLinkOptHints(MachOOF);
1959   if (Relocations)
1960     PrintRelocations(MachOOF, Verbose);
1961   if (SectionHeaders)
1962     printSectionHeaders(MachOOF);
1963   if (SectionContents)
1964     printSectionContents(MachOOF);
1965   if (!FilterSections.empty())
1966     DumpSectionContents(FileName, MachOOF, Verbose);
1967   if (InfoPlist)
1968     DumpInfoPlistSectionContents(FileName, MachOOF);
1969   if (DylibsUsed)
1970     PrintDylibs(MachOOF, false);
1971   if (DylibId)
1972     PrintDylibs(MachOOF, true);
1973   if (SymbolTable)
1974     printSymbolTable(MachOOF, ArchiveName, ArchitectureName);
1975   if (UnwindInfo)
1976     printMachOUnwindInfo(MachOOF);
1977   if (PrivateHeaders) {
1978     printMachOFileHeader(MachOOF);
1979     printMachOLoadCommands(MachOOF);
1980   }
1981   if (FirstPrivateHeader)
1982     printMachOFileHeader(MachOOF);
1983   if (ObjcMetaData)
1984     printObjcMetaData(MachOOF, Verbose);
1985   if (ExportsTrie)
1986     printExportsTrie(MachOOF);
1987   if (Rebase)
1988     printRebaseTable(MachOOF);
1989   if (Rpaths)
1990     printRpaths(MachOOF);
1991   if (Bind)
1992     printBindTable(MachOOF);
1993   if (LazyBind)
1994     printLazyBindTable(MachOOF);
1995   if (WeakBind)
1996     printWeakBindTable(MachOOF);
1997 
1998   if (DwarfDumpType != DIDT_Null) {
1999     std::unique_ptr<DIContext> DICtx = DWARFContext::create(*MachOOF);
2000     // Dump the complete DWARF structure.
2001     DIDumpOptions DumpOpts;
2002     DumpOpts.DumpType = DwarfDumpType;
2003     DICtx->dump(outs(), DumpOpts);
2004   }
2005 }
2006 
2007 // printUnknownCPUType() helps print_fat_headers for unknown CPU's.
2008 static void printUnknownCPUType(uint32_t cputype, uint32_t cpusubtype) {
2009   outs() << "    cputype (" << cputype << ")\n";
2010   outs() << "    cpusubtype (" << cpusubtype << ")\n";
2011 }
2012 
2013 // printCPUType() helps print_fat_headers by printing the cputype and
2014 // pusubtype (symbolically for the one's it knows about).
2015 static void printCPUType(uint32_t cputype, uint32_t cpusubtype) {
2016   switch (cputype) {
2017   case MachO::CPU_TYPE_I386:
2018     switch (cpusubtype) {
2019     case MachO::CPU_SUBTYPE_I386_ALL:
2020       outs() << "    cputype CPU_TYPE_I386\n";
2021       outs() << "    cpusubtype CPU_SUBTYPE_I386_ALL\n";
2022       break;
2023     default:
2024       printUnknownCPUType(cputype, cpusubtype);
2025       break;
2026     }
2027     break;
2028   case MachO::CPU_TYPE_X86_64:
2029     switch (cpusubtype) {
2030     case MachO::CPU_SUBTYPE_X86_64_ALL:
2031       outs() << "    cputype CPU_TYPE_X86_64\n";
2032       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_ALL\n";
2033       break;
2034     case MachO::CPU_SUBTYPE_X86_64_H:
2035       outs() << "    cputype CPU_TYPE_X86_64\n";
2036       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_H\n";
2037       break;
2038     default:
2039       printUnknownCPUType(cputype, cpusubtype);
2040       break;
2041     }
2042     break;
2043   case MachO::CPU_TYPE_ARM:
2044     switch (cpusubtype) {
2045     case MachO::CPU_SUBTYPE_ARM_ALL:
2046       outs() << "    cputype CPU_TYPE_ARM\n";
2047       outs() << "    cpusubtype CPU_SUBTYPE_ARM_ALL\n";
2048       break;
2049     case MachO::CPU_SUBTYPE_ARM_V4T:
2050       outs() << "    cputype CPU_TYPE_ARM\n";
2051       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V4T\n";
2052       break;
2053     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
2054       outs() << "    cputype CPU_TYPE_ARM\n";
2055       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n";
2056       break;
2057     case MachO::CPU_SUBTYPE_ARM_XSCALE:
2058       outs() << "    cputype CPU_TYPE_ARM\n";
2059       outs() << "    cpusubtype CPU_SUBTYPE_ARM_XSCALE\n";
2060       break;
2061     case MachO::CPU_SUBTYPE_ARM_V6:
2062       outs() << "    cputype CPU_TYPE_ARM\n";
2063       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6\n";
2064       break;
2065     case MachO::CPU_SUBTYPE_ARM_V6M:
2066       outs() << "    cputype CPU_TYPE_ARM\n";
2067       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6M\n";
2068       break;
2069     case MachO::CPU_SUBTYPE_ARM_V7:
2070       outs() << "    cputype CPU_TYPE_ARM\n";
2071       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7\n";
2072       break;
2073     case MachO::CPU_SUBTYPE_ARM_V7EM:
2074       outs() << "    cputype CPU_TYPE_ARM\n";
2075       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7EM\n";
2076       break;
2077     case MachO::CPU_SUBTYPE_ARM_V7K:
2078       outs() << "    cputype CPU_TYPE_ARM\n";
2079       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7K\n";
2080       break;
2081     case MachO::CPU_SUBTYPE_ARM_V7M:
2082       outs() << "    cputype CPU_TYPE_ARM\n";
2083       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7M\n";
2084       break;
2085     case MachO::CPU_SUBTYPE_ARM_V7S:
2086       outs() << "    cputype CPU_TYPE_ARM\n";
2087       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7S\n";
2088       break;
2089     default:
2090       printUnknownCPUType(cputype, cpusubtype);
2091       break;
2092     }
2093     break;
2094   case MachO::CPU_TYPE_ARM64:
2095     switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
2096     case MachO::CPU_SUBTYPE_ARM64_ALL:
2097       outs() << "    cputype CPU_TYPE_ARM64\n";
2098       outs() << "    cpusubtype CPU_SUBTYPE_ARM64_ALL\n";
2099       break;
2100     case MachO::CPU_SUBTYPE_ARM64_V8:
2101       outs() << "    cputype CPU_TYPE_ARM64\n";
2102       outs() << "    cpusubtype CPU_SUBTYPE_ARM64_V8\n";
2103       break;
2104     case MachO::CPU_SUBTYPE_ARM64E:
2105       outs() << "    cputype CPU_TYPE_ARM64\n";
2106       outs() << "    cpusubtype CPU_SUBTYPE_ARM64E\n";
2107       break;
2108     default:
2109       printUnknownCPUType(cputype, cpusubtype);
2110       break;
2111     }
2112     break;
2113   case MachO::CPU_TYPE_ARM64_32:
2114     switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
2115     case MachO::CPU_SUBTYPE_ARM64_32_V8:
2116       outs() << "    cputype CPU_TYPE_ARM64_32\n";
2117       outs() << "    cpusubtype CPU_SUBTYPE_ARM64_32_V8\n";
2118       break;
2119     default:
2120       printUnknownCPUType(cputype, cpusubtype);
2121       break;
2122     }
2123     break;
2124   default:
2125     printUnknownCPUType(cputype, cpusubtype);
2126     break;
2127   }
2128 }
2129 
2130 static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB,
2131                                        bool verbose) {
2132   outs() << "Fat headers\n";
2133   if (verbose) {
2134     if (UB->getMagic() == MachO::FAT_MAGIC)
2135       outs() << "fat_magic FAT_MAGIC\n";
2136     else // UB->getMagic() == MachO::FAT_MAGIC_64
2137       outs() << "fat_magic FAT_MAGIC_64\n";
2138   } else
2139     outs() << "fat_magic " << format("0x%" PRIx32, MachO::FAT_MAGIC) << "\n";
2140 
2141   uint32_t nfat_arch = UB->getNumberOfObjects();
2142   StringRef Buf = UB->getData();
2143   uint64_t size = Buf.size();
2144   uint64_t big_size = sizeof(struct MachO::fat_header) +
2145                       nfat_arch * sizeof(struct MachO::fat_arch);
2146   outs() << "nfat_arch " << UB->getNumberOfObjects();
2147   if (nfat_arch == 0)
2148     outs() << " (malformed, contains zero architecture types)\n";
2149   else if (big_size > size)
2150     outs() << " (malformed, architectures past end of file)\n";
2151   else
2152     outs() << "\n";
2153 
2154   for (uint32_t i = 0; i < nfat_arch; ++i) {
2155     MachOUniversalBinary::ObjectForArch OFA(UB, i);
2156     uint32_t cputype = OFA.getCPUType();
2157     uint32_t cpusubtype = OFA.getCPUSubType();
2158     outs() << "architecture ";
2159     for (uint32_t j = 0; i != 0 && j <= i - 1; j++) {
2160       MachOUniversalBinary::ObjectForArch other_OFA(UB, j);
2161       uint32_t other_cputype = other_OFA.getCPUType();
2162       uint32_t other_cpusubtype = other_OFA.getCPUSubType();
2163       if (cputype != 0 && cpusubtype != 0 && cputype == other_cputype &&
2164           (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) ==
2165               (other_cpusubtype & ~MachO::CPU_SUBTYPE_MASK)) {
2166         outs() << "(illegal duplicate architecture) ";
2167         break;
2168       }
2169     }
2170     if (verbose) {
2171       outs() << OFA.getArchFlagName() << "\n";
2172       printCPUType(cputype, cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
2173     } else {
2174       outs() << i << "\n";
2175       outs() << "    cputype " << cputype << "\n";
2176       outs() << "    cpusubtype " << (cpusubtype & ~MachO::CPU_SUBTYPE_MASK)
2177              << "\n";
2178     }
2179     if (verbose &&
2180         (cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64)
2181       outs() << "    capabilities CPU_SUBTYPE_LIB64\n";
2182     else
2183       outs() << "    capabilities "
2184              << format("0x%" PRIx32,
2185                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24) << "\n";
2186     outs() << "    offset " << OFA.getOffset();
2187     if (OFA.getOffset() > size)
2188       outs() << " (past end of file)";
2189     if (OFA.getOffset() % (1ull << OFA.getAlign()) != 0)
2190       outs() << " (not aligned on it's alignment (2^" << OFA.getAlign() << ")";
2191     outs() << "\n";
2192     outs() << "    size " << OFA.getSize();
2193     big_size = OFA.getOffset() + OFA.getSize();
2194     if (big_size > size)
2195       outs() << " (past end of file)";
2196     outs() << "\n";
2197     outs() << "    align 2^" << OFA.getAlign() << " (" << (1 << OFA.getAlign())
2198            << ")\n";
2199   }
2200 }
2201 
2202 static void printArchiveChild(StringRef Filename, const Archive::Child &C,
2203                               size_t ChildIndex, bool verbose,
2204                               bool print_offset,
2205                               StringRef ArchitectureName = StringRef()) {
2206   if (print_offset)
2207     outs() << C.getChildOffset() << "\t";
2208   sys::fs::perms Mode =
2209       unwrapOrError(C.getAccessMode(), getFileNameForError(C, ChildIndex),
2210                     Filename, ArchitectureName);
2211   if (verbose) {
2212     // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
2213     // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
2214     outs() << "-";
2215     outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
2216     outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
2217     outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
2218     outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
2219     outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
2220     outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
2221     outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
2222     outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
2223     outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
2224   } else {
2225     outs() << format("0%o ", Mode);
2226   }
2227 
2228   outs() << format("%3d/%-3d %5" PRId64 " ",
2229                    unwrapOrError(C.getUID(), getFileNameForError(C, ChildIndex),
2230                                  Filename, ArchitectureName),
2231                    unwrapOrError(C.getGID(), getFileNameForError(C, ChildIndex),
2232                                  Filename, ArchitectureName),
2233                    unwrapOrError(C.getRawSize(),
2234                                  getFileNameForError(C, ChildIndex), Filename,
2235                                  ArchitectureName));
2236 
2237   StringRef RawLastModified = C.getRawLastModified();
2238   if (verbose) {
2239     unsigned Seconds;
2240     if (RawLastModified.getAsInteger(10, Seconds))
2241       outs() << "(date: \"" << RawLastModified
2242              << "\" contains non-decimal chars) ";
2243     else {
2244       // Since cime(3) returns a 26 character string of the form:
2245       // "Sun Sep 16 01:03:52 1973\n\0"
2246       // just print 24 characters.
2247       time_t t = Seconds;
2248       outs() << format("%.24s ", ctime(&t));
2249     }
2250   } else {
2251     outs() << RawLastModified << " ";
2252   }
2253 
2254   if (verbose) {
2255     Expected<StringRef> NameOrErr = C.getName();
2256     if (!NameOrErr) {
2257       consumeError(NameOrErr.takeError());
2258       outs() << unwrapOrError(C.getRawName(),
2259                               getFileNameForError(C, ChildIndex), Filename,
2260                               ArchitectureName)
2261              << "\n";
2262     } else {
2263       StringRef Name = NameOrErr.get();
2264       outs() << Name << "\n";
2265     }
2266   } else {
2267     outs() << unwrapOrError(C.getRawName(), getFileNameForError(C, ChildIndex),
2268                             Filename, ArchitectureName)
2269            << "\n";
2270   }
2271 }
2272 
2273 static void printArchiveHeaders(StringRef Filename, Archive *A, bool verbose,
2274                                 bool print_offset,
2275                                 StringRef ArchitectureName = StringRef()) {
2276   Error Err = Error::success();
2277   size_t I = 0;
2278   for (const auto &C : A->children(Err, false))
2279     printArchiveChild(Filename, C, I++, verbose, print_offset,
2280                       ArchitectureName);
2281 
2282   if (Err)
2283     reportError(std::move(Err), Filename, "", ArchitectureName);
2284 }
2285 
2286 static bool ValidateArchFlags() {
2287   // Check for -arch all and verifiy the -arch flags are valid.
2288   for (unsigned i = 0; i < ArchFlags.size(); ++i) {
2289     if (ArchFlags[i] == "all") {
2290       ArchAll = true;
2291     } else {
2292       if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
2293         WithColor::error(errs(), "llvm-objdump")
2294             << "unknown architecture named '" + ArchFlags[i] +
2295                    "'for the -arch option\n";
2296         return false;
2297       }
2298     }
2299   }
2300   return true;
2301 }
2302 
2303 // ParseInputMachO() parses the named Mach-O file in Filename and handles the
2304 // -arch flags selecting just those slices as specified by them and also parses
2305 // archive files.  Then for each individual Mach-O file ProcessMachO() is
2306 // called to process the file based on the command line options.
2307 void objdump::parseInputMachO(StringRef Filename) {
2308   if (!ValidateArchFlags())
2309     return;
2310 
2311   // Attempt to open the binary.
2312   Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
2313   if (!BinaryOrErr) {
2314     if (Error E = isNotObjectErrorInvalidFileType(BinaryOrErr.takeError()))
2315       reportError(std::move(E), Filename);
2316     else
2317       outs() << Filename << ": is not an object file\n";
2318     return;
2319   }
2320   Binary &Bin = *BinaryOrErr.get().getBinary();
2321 
2322   if (Archive *A = dyn_cast<Archive>(&Bin)) {
2323     outs() << "Archive : " << Filename << "\n";
2324     if (ArchiveHeaders)
2325       printArchiveHeaders(Filename, A, Verbose, ArchiveMemberOffsets);
2326 
2327     Error Err = Error::success();
2328     unsigned I = -1;
2329     for (auto &C : A->children(Err)) {
2330       ++I;
2331       Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2332       if (!ChildOrErr) {
2333         if (Error E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2334           reportError(std::move(E), getFileNameForError(C, I), Filename);
2335         continue;
2336       }
2337       if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
2338         if (!checkMachOAndArchFlags(O, Filename))
2339           return;
2340         ProcessMachO(Filename, O, O->getFileName());
2341       }
2342     }
2343     if (Err)
2344       reportError(std::move(Err), Filename);
2345     return;
2346   }
2347   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
2348     parseInputMachO(UB);
2349     return;
2350   }
2351   if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
2352     if (!checkMachOAndArchFlags(O, Filename))
2353       return;
2354     if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O))
2355       ProcessMachO(Filename, MachOOF);
2356     else
2357       WithColor::error(errs(), "llvm-objdump")
2358           << Filename << "': "
2359           << "object is not a Mach-O file type.\n";
2360     return;
2361   }
2362   llvm_unreachable("Input object can't be invalid at this point");
2363 }
2364 
2365 void objdump::parseInputMachO(MachOUniversalBinary *UB) {
2366   if (!ValidateArchFlags())
2367     return;
2368 
2369   auto Filename = UB->getFileName();
2370 
2371   if (UniversalHeaders)
2372     printMachOUniversalHeaders(UB, Verbose);
2373 
2374   // If we have a list of architecture flags specified dump only those.
2375   if (!ArchAll && !ArchFlags.empty()) {
2376     // Look for a slice in the universal binary that matches each ArchFlag.
2377     bool ArchFound;
2378     for (unsigned i = 0; i < ArchFlags.size(); ++i) {
2379       ArchFound = false;
2380       for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
2381                                                   E = UB->end_objects();
2382             I != E; ++I) {
2383         if (ArchFlags[i] == I->getArchFlagName()) {
2384           ArchFound = true;
2385           Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
2386               I->getAsObjectFile();
2387           std::string ArchitectureName;
2388           if (ArchFlags.size() > 1)
2389             ArchitectureName = I->getArchFlagName();
2390           if (ObjOrErr) {
2391             ObjectFile &O = *ObjOrErr.get();
2392             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
2393               ProcessMachO(Filename, MachOOF, "", ArchitectureName);
2394           } else if (Error E = isNotObjectErrorInvalidFileType(
2395                          ObjOrErr.takeError())) {
2396             reportError(std::move(E), "", Filename, ArchitectureName);
2397             continue;
2398           } else if (Expected<std::unique_ptr<Archive>> AOrErr =
2399                          I->getAsArchive()) {
2400             std::unique_ptr<Archive> &A = *AOrErr;
2401             outs() << "Archive : " << Filename;
2402             if (!ArchitectureName.empty())
2403               outs() << " (architecture " << ArchitectureName << ")";
2404             outs() << "\n";
2405             if (ArchiveHeaders)
2406               printArchiveHeaders(Filename, A.get(), Verbose,
2407                                   ArchiveMemberOffsets, ArchitectureName);
2408             Error Err = Error::success();
2409             unsigned I = -1;
2410             for (auto &C : A->children(Err)) {
2411               ++I;
2412               Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2413               if (!ChildOrErr) {
2414                 if (Error E =
2415                         isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2416                   reportError(std::move(E), getFileNameForError(C, I), Filename,
2417                               ArchitectureName);
2418                 continue;
2419               }
2420               if (MachOObjectFile *O =
2421                       dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
2422                 ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
2423             }
2424             if (Err)
2425               reportError(std::move(Err), Filename);
2426           } else {
2427             consumeError(AOrErr.takeError());
2428             reportError(Filename,
2429                         "Mach-O universal file for architecture " +
2430                             StringRef(I->getArchFlagName()) +
2431                             " is not a Mach-O file or an archive file");
2432           }
2433         }
2434       }
2435       if (!ArchFound) {
2436         WithColor::error(errs(), "llvm-objdump")
2437             << "file: " + Filename + " does not contain "
2438             << "architecture: " + ArchFlags[i] + "\n";
2439         return;
2440       }
2441     }
2442     return;
2443   }
2444   // No architecture flags were specified so if this contains a slice that
2445   // matches the host architecture dump only that.
2446   if (!ArchAll) {
2447     for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
2448                                                 E = UB->end_objects();
2449           I != E; ++I) {
2450       if (MachOObjectFile::getHostArch().getArchName() ==
2451           I->getArchFlagName()) {
2452         Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
2453         std::string ArchiveName;
2454         ArchiveName.clear();
2455         if (ObjOrErr) {
2456           ObjectFile &O = *ObjOrErr.get();
2457           if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
2458             ProcessMachO(Filename, MachOOF);
2459         } else if (Error E =
2460                        isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
2461           reportError(std::move(E), Filename);
2462         } else if (Expected<std::unique_ptr<Archive>> AOrErr =
2463                        I->getAsArchive()) {
2464           std::unique_ptr<Archive> &A = *AOrErr;
2465           outs() << "Archive : " << Filename << "\n";
2466           if (ArchiveHeaders)
2467             printArchiveHeaders(Filename, A.get(), Verbose,
2468                                 ArchiveMemberOffsets);
2469           Error Err = Error::success();
2470           unsigned I = -1;
2471           for (auto &C : A->children(Err)) {
2472             ++I;
2473             Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2474             if (!ChildOrErr) {
2475               if (Error E =
2476                       isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2477                 reportError(std::move(E), getFileNameForError(C, I), Filename);
2478               continue;
2479             }
2480             if (MachOObjectFile *O =
2481                     dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
2482               ProcessMachO(Filename, O, O->getFileName());
2483           }
2484           if (Err)
2485             reportError(std::move(Err), Filename);
2486         } else {
2487           consumeError(AOrErr.takeError());
2488           reportError(Filename, "Mach-O universal file for architecture " +
2489                                     StringRef(I->getArchFlagName()) +
2490                                     " is not a Mach-O file or an archive file");
2491         }
2492         return;
2493       }
2494     }
2495   }
2496   // Either all architectures have been specified or none have been specified
2497   // and this does not contain the host architecture so dump all the slices.
2498   bool moreThanOneArch = UB->getNumberOfObjects() > 1;
2499   for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
2500                                               E = UB->end_objects();
2501         I != E; ++I) {
2502     Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
2503     std::string ArchitectureName;
2504     if (moreThanOneArch)
2505       ArchitectureName = I->getArchFlagName();
2506     if (ObjOrErr) {
2507       ObjectFile &Obj = *ObjOrErr.get();
2508       if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
2509         ProcessMachO(Filename, MachOOF, "", ArchitectureName);
2510     } else if (Error E =
2511                    isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
2512       reportError(std::move(E), Filename, "", ArchitectureName);
2513     } else if (Expected<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
2514       std::unique_ptr<Archive> &A = *AOrErr;
2515       outs() << "Archive : " << Filename;
2516       if (!ArchitectureName.empty())
2517         outs() << " (architecture " << ArchitectureName << ")";
2518       outs() << "\n";
2519       if (ArchiveHeaders)
2520         printArchiveHeaders(Filename, A.get(), Verbose, ArchiveMemberOffsets,
2521                             ArchitectureName);
2522       Error Err = Error::success();
2523       unsigned I = -1;
2524       for (auto &C : A->children(Err)) {
2525         ++I;
2526         Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2527         if (!ChildOrErr) {
2528           if (Error E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2529             reportError(std::move(E), getFileNameForError(C, I), Filename,
2530                         ArchitectureName);
2531           continue;
2532         }
2533         if (MachOObjectFile *O =
2534                 dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
2535           if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
2536             ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
2537                           ArchitectureName);
2538         }
2539       }
2540       if (Err)
2541         reportError(std::move(Err), Filename);
2542     } else {
2543       consumeError(AOrErr.takeError());
2544       reportError(Filename, "Mach-O universal file for architecture " +
2545                                 StringRef(I->getArchFlagName()) +
2546                                 " is not a Mach-O file or an archive file");
2547     }
2548   }
2549 }
2550 
2551 namespace {
2552 // The block of info used by the Symbolizer call backs.
2553 struct DisassembleInfo {
2554   DisassembleInfo(MachOObjectFile *O, SymbolAddressMap *AddrMap,
2555                   std::vector<SectionRef> *Sections, bool verbose)
2556     : verbose(verbose), O(O), AddrMap(AddrMap), Sections(Sections) {}
2557   bool verbose;
2558   MachOObjectFile *O;
2559   SectionRef S;
2560   SymbolAddressMap *AddrMap;
2561   std::vector<SectionRef> *Sections;
2562   const char *class_name = nullptr;
2563   const char *selector_name = nullptr;
2564   std::unique_ptr<char[]> method = nullptr;
2565   char *demangled_name = nullptr;
2566   uint64_t adrp_addr = 0;
2567   uint32_t adrp_inst = 0;
2568   std::unique_ptr<SymbolAddressMap> bindtable;
2569   uint32_t depth = 0;
2570 };
2571 } // namespace
2572 
2573 // SymbolizerGetOpInfo() is the operand information call back function.
2574 // This is called to get the symbolic information for operand(s) of an
2575 // instruction when it is being done.  This routine does this from
2576 // the relocation information, symbol table, etc. That block of information
2577 // is a pointer to the struct DisassembleInfo that was passed when the
2578 // disassembler context was created and passed to back to here when
2579 // called back by the disassembler for instruction operands that could have
2580 // relocation information. The address of the instruction containing operand is
2581 // at the Pc parameter.  The immediate value the operand has is passed in
2582 // op_info->Value and is at Offset past the start of the instruction and has a
2583 // byte Size of 1, 2 or 4. The symbolc information is returned in TagBuf is the
2584 // LLVMOpInfo1 struct defined in the header "llvm-c/Disassembler.h" as symbol
2585 // names and addends of the symbolic expression to add for the operand.  The
2586 // value of TagType is currently 1 (for the LLVMOpInfo1 struct). If symbolic
2587 // information is returned then this function returns 1 else it returns 0.
2588 static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
2589                                uint64_t Size, int TagType, void *TagBuf) {
2590   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
2591   struct LLVMOpInfo1 *op_info = (struct LLVMOpInfo1 *)TagBuf;
2592   uint64_t value = op_info->Value;
2593 
2594   // Make sure all fields returned are zero if we don't set them.
2595   memset((void *)op_info, '\0', sizeof(struct LLVMOpInfo1));
2596   op_info->Value = value;
2597 
2598   // If the TagType is not the value 1 which it code knows about or if no
2599   // verbose symbolic information is wanted then just return 0, indicating no
2600   // information is being returned.
2601   if (TagType != 1 || !info->verbose)
2602     return 0;
2603 
2604   unsigned int Arch = info->O->getArch();
2605   if (Arch == Triple::x86) {
2606     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
2607       return 0;
2608     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2609       // TODO:
2610       // Search the external relocation entries of a fully linked image
2611       // (if any) for an entry that matches this segment offset.
2612       // uint32_t seg_offset = (Pc + Offset);
2613       return 0;
2614     }
2615     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2616     // for an entry for this section offset.
2617     uint32_t sect_addr = info->S.getAddress();
2618     uint32_t sect_offset = (Pc + Offset) - sect_addr;
2619     bool reloc_found = false;
2620     DataRefImpl Rel;
2621     MachO::any_relocation_info RE;
2622     bool isExtern = false;
2623     SymbolRef Symbol;
2624     bool r_scattered = false;
2625     uint32_t r_value, pair_r_value, r_type;
2626     for (const RelocationRef &Reloc : info->S.relocations()) {
2627       uint64_t RelocOffset = Reloc.getOffset();
2628       if (RelocOffset == sect_offset) {
2629         Rel = Reloc.getRawDataRefImpl();
2630         RE = info->O->getRelocation(Rel);
2631         r_type = info->O->getAnyRelocationType(RE);
2632         r_scattered = info->O->isRelocationScattered(RE);
2633         if (r_scattered) {
2634           r_value = info->O->getScatteredRelocationValue(RE);
2635           if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
2636               r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
2637             DataRefImpl RelNext = Rel;
2638             info->O->moveRelocationNext(RelNext);
2639             MachO::any_relocation_info RENext;
2640             RENext = info->O->getRelocation(RelNext);
2641             if (info->O->isRelocationScattered(RENext))
2642               pair_r_value = info->O->getScatteredRelocationValue(RENext);
2643             else
2644               return 0;
2645           }
2646         } else {
2647           isExtern = info->O->getPlainRelocationExternal(RE);
2648           if (isExtern) {
2649             symbol_iterator RelocSym = Reloc.getSymbol();
2650             Symbol = *RelocSym;
2651           }
2652         }
2653         reloc_found = true;
2654         break;
2655       }
2656     }
2657     if (reloc_found && isExtern) {
2658       op_info->AddSymbol.Present = 1;
2659       op_info->AddSymbol.Name =
2660           unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2661       // For i386 extern relocation entries the value in the instruction is
2662       // the offset from the symbol, and value is already set in op_info->Value.
2663       return 1;
2664     }
2665     if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
2666                         r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
2667       const char *add = GuessSymbolName(r_value, info->AddrMap);
2668       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
2669       uint32_t offset = value - (r_value - pair_r_value);
2670       op_info->AddSymbol.Present = 1;
2671       if (add != nullptr)
2672         op_info->AddSymbol.Name = add;
2673       else
2674         op_info->AddSymbol.Value = r_value;
2675       op_info->SubtractSymbol.Present = 1;
2676       if (sub != nullptr)
2677         op_info->SubtractSymbol.Name = sub;
2678       else
2679         op_info->SubtractSymbol.Value = pair_r_value;
2680       op_info->Value = offset;
2681       return 1;
2682     }
2683     return 0;
2684   }
2685   if (Arch == Triple::x86_64) {
2686     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
2687       return 0;
2688     // For non MH_OBJECT types, like MH_KEXT_BUNDLE, Search the external
2689     // relocation entries of a linked image (if any) for an entry that matches
2690     // this segment offset.
2691     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2692       uint64_t seg_offset = Pc + Offset;
2693       bool reloc_found = false;
2694       DataRefImpl Rel;
2695       MachO::any_relocation_info RE;
2696       bool isExtern = false;
2697       SymbolRef Symbol;
2698       for (const RelocationRef &Reloc : info->O->external_relocations()) {
2699         uint64_t RelocOffset = Reloc.getOffset();
2700         if (RelocOffset == seg_offset) {
2701           Rel = Reloc.getRawDataRefImpl();
2702           RE = info->O->getRelocation(Rel);
2703           // external relocation entries should always be external.
2704           isExtern = info->O->getPlainRelocationExternal(RE);
2705           if (isExtern) {
2706             symbol_iterator RelocSym = Reloc.getSymbol();
2707             Symbol = *RelocSym;
2708           }
2709           reloc_found = true;
2710           break;
2711         }
2712       }
2713       if (reloc_found && isExtern) {
2714         // The Value passed in will be adjusted by the Pc if the instruction
2715         // adds the Pc.  But for x86_64 external relocation entries the Value
2716         // is the offset from the external symbol.
2717         if (info->O->getAnyRelocationPCRel(RE))
2718           op_info->Value -= Pc + Offset + Size;
2719         const char *name =
2720             unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2721         op_info->AddSymbol.Present = 1;
2722         op_info->AddSymbol.Name = name;
2723         return 1;
2724       }
2725       return 0;
2726     }
2727     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2728     // for an entry for this section offset.
2729     uint64_t sect_addr = info->S.getAddress();
2730     uint64_t sect_offset = (Pc + Offset) - sect_addr;
2731     bool reloc_found = false;
2732     DataRefImpl Rel;
2733     MachO::any_relocation_info RE;
2734     bool isExtern = false;
2735     SymbolRef Symbol;
2736     for (const RelocationRef &Reloc : info->S.relocations()) {
2737       uint64_t RelocOffset = Reloc.getOffset();
2738       if (RelocOffset == sect_offset) {
2739         Rel = Reloc.getRawDataRefImpl();
2740         RE = info->O->getRelocation(Rel);
2741         // NOTE: Scattered relocations don't exist on x86_64.
2742         isExtern = info->O->getPlainRelocationExternal(RE);
2743         if (isExtern) {
2744           symbol_iterator RelocSym = Reloc.getSymbol();
2745           Symbol = *RelocSym;
2746         }
2747         reloc_found = true;
2748         break;
2749       }
2750     }
2751     if (reloc_found && isExtern) {
2752       // The Value passed in will be adjusted by the Pc if the instruction
2753       // adds the Pc.  But for x86_64 external relocation entries the Value
2754       // is the offset from the external symbol.
2755       if (info->O->getAnyRelocationPCRel(RE))
2756         op_info->Value -= Pc + Offset + Size;
2757       const char *name =
2758           unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2759       unsigned Type = info->O->getAnyRelocationType(RE);
2760       if (Type == MachO::X86_64_RELOC_SUBTRACTOR) {
2761         DataRefImpl RelNext = Rel;
2762         info->O->moveRelocationNext(RelNext);
2763         MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
2764         unsigned TypeNext = info->O->getAnyRelocationType(RENext);
2765         bool isExternNext = info->O->getPlainRelocationExternal(RENext);
2766         unsigned SymbolNum = info->O->getPlainRelocationSymbolNum(RENext);
2767         if (TypeNext == MachO::X86_64_RELOC_UNSIGNED && isExternNext) {
2768           op_info->SubtractSymbol.Present = 1;
2769           op_info->SubtractSymbol.Name = name;
2770           symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum);
2771           Symbol = *RelocSymNext;
2772           name = unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2773         }
2774       }
2775       // TODO: add the VariantKinds to op_info->VariantKind for relocation types
2776       // like: X86_64_RELOC_TLV, X86_64_RELOC_GOT_LOAD and X86_64_RELOC_GOT.
2777       op_info->AddSymbol.Present = 1;
2778       op_info->AddSymbol.Name = name;
2779       return 1;
2780     }
2781     return 0;
2782   }
2783   if (Arch == Triple::arm) {
2784     if (Offset != 0 || (Size != 4 && Size != 2))
2785       return 0;
2786     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2787       // TODO:
2788       // Search the external relocation entries of a fully linked image
2789       // (if any) for an entry that matches this segment offset.
2790       // uint32_t seg_offset = (Pc + Offset);
2791       return 0;
2792     }
2793     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2794     // for an entry for this section offset.
2795     uint32_t sect_addr = info->S.getAddress();
2796     uint32_t sect_offset = (Pc + Offset) - sect_addr;
2797     DataRefImpl Rel;
2798     MachO::any_relocation_info RE;
2799     bool isExtern = false;
2800     SymbolRef Symbol;
2801     bool r_scattered = false;
2802     uint32_t r_value, pair_r_value, r_type, r_length, other_half;
2803     auto Reloc =
2804         find_if(info->S.relocations(), [&](const RelocationRef &Reloc) {
2805           uint64_t RelocOffset = Reloc.getOffset();
2806           return RelocOffset == sect_offset;
2807         });
2808 
2809     if (Reloc == info->S.relocations().end())
2810       return 0;
2811 
2812     Rel = Reloc->getRawDataRefImpl();
2813     RE = info->O->getRelocation(Rel);
2814     r_length = info->O->getAnyRelocationLength(RE);
2815     r_scattered = info->O->isRelocationScattered(RE);
2816     if (r_scattered) {
2817       r_value = info->O->getScatteredRelocationValue(RE);
2818       r_type = info->O->getScatteredRelocationType(RE);
2819     } else {
2820       r_type = info->O->getAnyRelocationType(RE);
2821       isExtern = info->O->getPlainRelocationExternal(RE);
2822       if (isExtern) {
2823         symbol_iterator RelocSym = Reloc->getSymbol();
2824         Symbol = *RelocSym;
2825       }
2826     }
2827     if (r_type == MachO::ARM_RELOC_HALF ||
2828         r_type == MachO::ARM_RELOC_SECTDIFF ||
2829         r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
2830         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2831       DataRefImpl RelNext = Rel;
2832       info->O->moveRelocationNext(RelNext);
2833       MachO::any_relocation_info RENext;
2834       RENext = info->O->getRelocation(RelNext);
2835       other_half = info->O->getAnyRelocationAddress(RENext) & 0xffff;
2836       if (info->O->isRelocationScattered(RENext))
2837         pair_r_value = info->O->getScatteredRelocationValue(RENext);
2838     }
2839 
2840     if (isExtern) {
2841       const char *name =
2842           unwrapOrError(Symbol.getName(), info->O->getFileName()).data();
2843       op_info->AddSymbol.Present = 1;
2844       op_info->AddSymbol.Name = name;
2845       switch (r_type) {
2846       case MachO::ARM_RELOC_HALF:
2847         if ((r_length & 0x1) == 1) {
2848           op_info->Value = value << 16 | other_half;
2849           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2850         } else {
2851           op_info->Value = other_half << 16 | value;
2852           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2853         }
2854         break;
2855       default:
2856         break;
2857       }
2858       return 1;
2859     }
2860     // If we have a branch that is not an external relocation entry then
2861     // return 0 so the code in tryAddingSymbolicOperand() can use the
2862     // SymbolLookUp call back with the branch target address to look up the
2863     // symbol and possibility add an annotation for a symbol stub.
2864     if (isExtern == 0 && (r_type == MachO::ARM_RELOC_BR24 ||
2865                           r_type == MachO::ARM_THUMB_RELOC_BR22))
2866       return 0;
2867 
2868     uint32_t offset = 0;
2869     if (r_type == MachO::ARM_RELOC_HALF ||
2870         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2871       if ((r_length & 0x1) == 1)
2872         value = value << 16 | other_half;
2873       else
2874         value = other_half << 16 | value;
2875     }
2876     if (r_scattered && (r_type != MachO::ARM_RELOC_HALF &&
2877                         r_type != MachO::ARM_RELOC_HALF_SECTDIFF)) {
2878       offset = value - r_value;
2879       value = r_value;
2880     }
2881 
2882     if (r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
2883       if ((r_length & 0x1) == 1)
2884         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2885       else
2886         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2887       const char *add = GuessSymbolName(r_value, info->AddrMap);
2888       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
2889       int32_t offset = value - (r_value - pair_r_value);
2890       op_info->AddSymbol.Present = 1;
2891       if (add != nullptr)
2892         op_info->AddSymbol.Name = add;
2893       else
2894         op_info->AddSymbol.Value = r_value;
2895       op_info->SubtractSymbol.Present = 1;
2896       if (sub != nullptr)
2897         op_info->SubtractSymbol.Name = sub;
2898       else
2899         op_info->SubtractSymbol.Value = pair_r_value;
2900       op_info->Value = offset;
2901       return 1;
2902     }
2903 
2904     op_info->AddSymbol.Present = 1;
2905     op_info->Value = offset;
2906     if (r_type == MachO::ARM_RELOC_HALF) {
2907       if ((r_length & 0x1) == 1)
2908         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2909       else
2910         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2911     }
2912     const char *add = GuessSymbolName(value, info->AddrMap);
2913     if (add != nullptr) {
2914       op_info->AddSymbol.Name = add;
2915       return 1;
2916     }
2917     op_info->AddSymbol.Value = value;
2918     return 1;
2919   }
2920   if (Arch == Triple::aarch64) {
2921     if (Offset != 0 || Size != 4)
2922       return 0;
2923     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2924       // TODO:
2925       // Search the external relocation entries of a fully linked image
2926       // (if any) for an entry that matches this segment offset.
2927       // uint64_t seg_offset = (Pc + Offset);
2928       return 0;
2929     }
2930     // In MH_OBJECT filetypes search the section's relocation entries (if any)
2931     // for an entry for this section offset.
2932     uint64_t sect_addr = info->S.getAddress();
2933     uint64_t sect_offset = (Pc + Offset) - sect_addr;
2934     auto Reloc =
2935         find_if(info->S.relocations(), [&](const RelocationRef &Reloc) {
2936           uint64_t RelocOffset = Reloc.getOffset();
2937           return RelocOffset == sect_offset;
2938         });
2939 
2940     if (Reloc == info->S.relocations().end())
2941       return 0;
2942 
2943     DataRefImpl Rel = Reloc->getRawDataRefImpl();
2944     MachO::any_relocation_info RE = info->O->getRelocation(Rel);
2945     uint32_t r_type = info->O->getAnyRelocationType(RE);
2946     if (r_type == MachO::ARM64_RELOC_ADDEND) {
2947       DataRefImpl RelNext = Rel;
2948       info->O->moveRelocationNext(RelNext);
2949       MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
2950       if (value == 0) {
2951         value = info->O->getPlainRelocationSymbolNum(RENext);
2952         op_info->Value = value;
2953       }
2954     }
2955     // NOTE: Scattered relocations don't exist on arm64.
2956     if (!info->O->getPlainRelocationExternal(RE))
2957       return 0;
2958     const char *name =
2959         unwrapOrError(Reloc->getSymbol()->getName(), info->O->getFileName())
2960             .data();
2961     op_info->AddSymbol.Present = 1;
2962     op_info->AddSymbol.Name = name;
2963 
2964     switch (r_type) {
2965     case MachO::ARM64_RELOC_PAGE21:
2966       /* @page */
2967       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGE;
2968       break;
2969     case MachO::ARM64_RELOC_PAGEOFF12:
2970       /* @pageoff */
2971       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGEOFF;
2972       break;
2973     case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
2974       /* @gotpage */
2975       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGE;
2976       break;
2977     case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
2978       /* @gotpageoff */
2979       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF;
2980       break;
2981     case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
2982       /* @tvlppage is not implemented in llvm-mc */
2983       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVP;
2984       break;
2985     case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
2986       /* @tvlppageoff is not implemented in llvm-mc */
2987       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVOFF;
2988       break;
2989     default:
2990     case MachO::ARM64_RELOC_BRANCH26:
2991       op_info->VariantKind = LLVMDisassembler_VariantKind_None;
2992       break;
2993     }
2994     return 1;
2995   }
2996   return 0;
2997 }
2998 
2999 // GuessCstringPointer is passed the address of what might be a pointer to a
3000 // literal string in a cstring section.  If that address is in a cstring section
3001 // it returns a pointer to that string.  Else it returns nullptr.
3002 static const char *GuessCstringPointer(uint64_t ReferenceValue,
3003                                        struct DisassembleInfo *info) {
3004   for (const auto &Load : info->O->load_commands()) {
3005     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
3006       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
3007       for (unsigned J = 0; J < Seg.nsects; ++J) {
3008         MachO::section_64 Sec = info->O->getSection64(Load, J);
3009         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
3010         if (section_type == MachO::S_CSTRING_LITERALS &&
3011             ReferenceValue >= Sec.addr &&
3012             ReferenceValue < Sec.addr + Sec.size) {
3013           uint64_t sect_offset = ReferenceValue - Sec.addr;
3014           uint64_t object_offset = Sec.offset + sect_offset;
3015           StringRef MachOContents = info->O->getData();
3016           uint64_t object_size = MachOContents.size();
3017           const char *object_addr = (const char *)MachOContents.data();
3018           if (object_offset < object_size) {
3019             const char *name = object_addr + object_offset;
3020             return name;
3021           } else {
3022             return nullptr;
3023           }
3024         }
3025       }
3026     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
3027       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
3028       for (unsigned J = 0; J < Seg.nsects; ++J) {
3029         MachO::section Sec = info->O->getSection(Load, J);
3030         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
3031         if (section_type == MachO::S_CSTRING_LITERALS &&
3032             ReferenceValue >= Sec.addr &&
3033             ReferenceValue < Sec.addr + Sec.size) {
3034           uint64_t sect_offset = ReferenceValue - Sec.addr;
3035           uint64_t object_offset = Sec.offset + sect_offset;
3036           StringRef MachOContents = info->O->getData();
3037           uint64_t object_size = MachOContents.size();
3038           const char *object_addr = (const char *)MachOContents.data();
3039           if (object_offset < object_size) {
3040             const char *name = object_addr + object_offset;
3041             return name;
3042           } else {
3043             return nullptr;
3044           }
3045         }
3046       }
3047     }
3048   }
3049   return nullptr;
3050 }
3051 
3052 // GuessIndirectSymbol returns the name of the indirect symbol for the
3053 // ReferenceValue passed in or nullptr.  This is used when ReferenceValue maybe
3054 // an address of a symbol stub or a lazy or non-lazy pointer to associate the
3055 // symbol name being referenced by the stub or pointer.
3056 static const char *GuessIndirectSymbol(uint64_t ReferenceValue,
3057                                        struct DisassembleInfo *info) {
3058   MachO::dysymtab_command Dysymtab = info->O->getDysymtabLoadCommand();
3059   MachO::symtab_command Symtab = info->O->getSymtabLoadCommand();
3060   for (const auto &Load : info->O->load_commands()) {
3061     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
3062       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
3063       for (unsigned J = 0; J < Seg.nsects; ++J) {
3064         MachO::section_64 Sec = info->O->getSection64(Load, J);
3065         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
3066         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
3067              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
3068              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
3069              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
3070              section_type == MachO::S_SYMBOL_STUBS) &&
3071             ReferenceValue >= Sec.addr &&
3072             ReferenceValue < Sec.addr + Sec.size) {
3073           uint32_t stride;
3074           if (section_type == MachO::S_SYMBOL_STUBS)
3075             stride = Sec.reserved2;
3076           else
3077             stride = 8;
3078           if (stride == 0)
3079             return nullptr;
3080           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
3081           if (index < Dysymtab.nindirectsyms) {
3082             uint32_t indirect_symbol =
3083                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
3084             if (indirect_symbol < Symtab.nsyms) {
3085               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
3086               return unwrapOrError(Sym->getName(), info->O->getFileName())
3087                   .data();
3088             }
3089           }
3090         }
3091       }
3092     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
3093       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
3094       for (unsigned J = 0; J < Seg.nsects; ++J) {
3095         MachO::section Sec = info->O->getSection(Load, J);
3096         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
3097         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
3098              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
3099              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
3100              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
3101              section_type == MachO::S_SYMBOL_STUBS) &&
3102             ReferenceValue >= Sec.addr &&
3103             ReferenceValue < Sec.addr + Sec.size) {
3104           uint32_t stride;
3105           if (section_type == MachO::S_SYMBOL_STUBS)
3106             stride = Sec.reserved2;
3107           else
3108             stride = 4;
3109           if (stride == 0)
3110             return nullptr;
3111           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
3112           if (index < Dysymtab.nindirectsyms) {
3113             uint32_t indirect_symbol =
3114                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
3115             if (indirect_symbol < Symtab.nsyms) {
3116               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
3117               return unwrapOrError(Sym->getName(), info->O->getFileName())
3118                   .data();
3119             }
3120           }
3121         }
3122       }
3123     }
3124   }
3125   return nullptr;
3126 }
3127 
3128 // method_reference() is called passing it the ReferenceName that might be
3129 // a reference it to an Objective-C method call.  If so then it allocates and
3130 // assembles a method call string with the values last seen and saved in
3131 // the DisassembleInfo's class_name and selector_name fields.  This is saved
3132 // into the method field of the info and any previous string is free'ed.
3133 // Then the class_name field in the info is set to nullptr.  The method call
3134 // string is set into ReferenceName and ReferenceType is set to
3135 // LLVMDisassembler_ReferenceType_Out_Objc_Message.  If this not a method call
3136 // then both ReferenceType and ReferenceName are left unchanged.
3137 static void method_reference(struct DisassembleInfo *info,
3138                              uint64_t *ReferenceType,
3139                              const char **ReferenceName) {
3140   unsigned int Arch = info->O->getArch();
3141   if (*ReferenceName != nullptr) {
3142     if (strcmp(*ReferenceName, "_objc_msgSend") == 0) {
3143       if (info->selector_name != nullptr) {
3144         if (info->class_name != nullptr) {
3145           info->method = std::make_unique<char[]>(
3146               5 + strlen(info->class_name) + strlen(info->selector_name));
3147           char *method = info->method.get();
3148           if (method != nullptr) {
3149             strcpy(method, "+[");
3150             strcat(method, info->class_name);
3151             strcat(method, " ");
3152             strcat(method, info->selector_name);
3153             strcat(method, "]");
3154             *ReferenceName = method;
3155             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
3156           }
3157         } else {
3158           info->method =
3159               std::make_unique<char[]>(9 + strlen(info->selector_name));
3160           char *method = info->method.get();
3161           if (method != nullptr) {
3162             if (Arch == Triple::x86_64)
3163               strcpy(method, "-[%rdi ");
3164             else if (Arch == Triple::aarch64)
3165               strcpy(method, "-[x0 ");
3166             else
3167               strcpy(method, "-[r? ");
3168             strcat(method, info->selector_name);
3169             strcat(method, "]");
3170             *ReferenceName = method;
3171             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
3172           }
3173         }
3174         info->class_name = nullptr;
3175       }
3176     } else if (strcmp(*ReferenceName, "_objc_msgSendSuper2") == 0) {
3177       if (info->selector_name != nullptr) {
3178         info->method =
3179             std::make_unique<char[]>(17 + strlen(info->selector_name));
3180         char *method = info->method.get();
3181         if (method != nullptr) {
3182           if (Arch == Triple::x86_64)
3183             strcpy(method, "-[[%rdi super] ");
3184           else if (Arch == Triple::aarch64)
3185             strcpy(method, "-[[x0 super] ");
3186           else
3187             strcpy(method, "-[[r? super] ");
3188           strcat(method, info->selector_name);
3189           strcat(method, "]");
3190           *ReferenceName = method;
3191           *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
3192         }
3193         info->class_name = nullptr;
3194       }
3195     }
3196   }
3197 }
3198 
3199 // GuessPointerPointer() is passed the address of what might be a pointer to
3200 // a reference to an Objective-C class, selector, message ref or cfstring.
3201 // If so the value of the pointer is returned and one of the booleans are set
3202 // to true.  If not zero is returned and all the booleans are set to false.
3203 static uint64_t GuessPointerPointer(uint64_t ReferenceValue,
3204                                     struct DisassembleInfo *info,
3205                                     bool &classref, bool &selref, bool &msgref,
3206                                     bool &cfstring) {
3207   classref = false;
3208   selref = false;
3209   msgref = false;
3210   cfstring = false;
3211   for (const auto &Load : info->O->load_commands()) {
3212     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
3213       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
3214       for (unsigned J = 0; J < Seg.nsects; ++J) {
3215         MachO::section_64 Sec = info->O->getSection64(Load, J);
3216         if ((strncmp(Sec.sectname, "__objc_selrefs", 16) == 0 ||
3217              strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
3218              strncmp(Sec.sectname, "__objc_superrefs", 16) == 0 ||
3219              strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 ||
3220              strncmp(Sec.sectname, "__cfstring", 16) == 0) &&
3221             ReferenceValue >= Sec.addr &&
3222             ReferenceValue < Sec.addr + Sec.size) {
3223           uint64_t sect_offset = ReferenceValue - Sec.addr;
3224           uint64_t object_offset = Sec.offset + sect_offset;
3225           StringRef MachOContents = info->O->getData();
3226           uint64_t object_size = MachOContents.size();
3227           const char *object_addr = (const char *)MachOContents.data();
3228           if (object_offset < object_size) {
3229             uint64_t pointer_value;
3230             memcpy(&pointer_value, object_addr + object_offset,
3231                    sizeof(uint64_t));
3232             if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3233               sys::swapByteOrder(pointer_value);
3234             if (strncmp(Sec.sectname, "__objc_selrefs", 16) == 0)
3235               selref = true;
3236             else if (strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
3237                      strncmp(Sec.sectname, "__objc_superrefs", 16) == 0)
3238               classref = true;
3239             else if (strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 &&
3240                      ReferenceValue + 8 < Sec.addr + Sec.size) {
3241               msgref = true;
3242               memcpy(&pointer_value, object_addr + object_offset + 8,
3243                      sizeof(uint64_t));
3244               if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3245                 sys::swapByteOrder(pointer_value);
3246             } else if (strncmp(Sec.sectname, "__cfstring", 16) == 0)
3247               cfstring = true;
3248             return pointer_value;
3249           } else {
3250             return 0;
3251           }
3252         }
3253       }
3254     }
3255     // TODO: Look for LC_SEGMENT for 32-bit Mach-O files.
3256   }
3257   return 0;
3258 }
3259 
3260 // get_pointer_64 returns a pointer to the bytes in the object file at the
3261 // Address from a section in the Mach-O file.  And indirectly returns the
3262 // offset into the section, number of bytes left in the section past the offset
3263 // and which section is was being referenced.  If the Address is not in a
3264 // section nullptr is returned.
3265 static const char *get_pointer_64(uint64_t Address, uint32_t &offset,
3266                                   uint32_t &left, SectionRef &S,
3267                                   DisassembleInfo *info,
3268                                   bool objc_only = false) {
3269   offset = 0;
3270   left = 0;
3271   S = SectionRef();
3272   for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) {
3273     uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress();
3274     uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize();
3275     if (SectSize == 0)
3276       continue;
3277     if (objc_only) {
3278       StringRef SectName;
3279       Expected<StringRef> SecNameOrErr =
3280           ((*(info->Sections))[SectIdx]).getName();
3281       if (SecNameOrErr)
3282         SectName = *SecNameOrErr;
3283       else
3284         consumeError(SecNameOrErr.takeError());
3285 
3286       DataRefImpl Ref = ((*(info->Sections))[SectIdx]).getRawDataRefImpl();
3287       StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
3288       if (SegName != "__OBJC" && SectName != "__cstring")
3289         continue;
3290     }
3291     if (Address >= SectAddress && Address < SectAddress + SectSize) {
3292       S = (*(info->Sections))[SectIdx];
3293       offset = Address - SectAddress;
3294       left = SectSize - offset;
3295       StringRef SectContents = unwrapOrError(
3296           ((*(info->Sections))[SectIdx]).getContents(), info->O->getFileName());
3297       return SectContents.data() + offset;
3298     }
3299   }
3300   return nullptr;
3301 }
3302 
3303 static const char *get_pointer_32(uint32_t Address, uint32_t &offset,
3304                                   uint32_t &left, SectionRef &S,
3305                                   DisassembleInfo *info,
3306                                   bool objc_only = false) {
3307   return get_pointer_64(Address, offset, left, S, info, objc_only);
3308 }
3309 
3310 // get_symbol_64() returns the name of a symbol (or nullptr) and the address of
3311 // the symbol indirectly through n_value. Based on the relocation information
3312 // for the specified section offset in the specified section reference.
3313 // If no relocation information is found and a non-zero ReferenceValue for the
3314 // symbol is passed, look up that address in the info's AddrMap.
3315 static const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
3316                                  DisassembleInfo *info, uint64_t &n_value,
3317                                  uint64_t ReferenceValue = 0) {
3318   n_value = 0;
3319   if (!info->verbose)
3320     return nullptr;
3321 
3322   // See if there is an external relocation entry at the sect_offset.
3323   bool reloc_found = false;
3324   DataRefImpl Rel;
3325   MachO::any_relocation_info RE;
3326   bool isExtern = false;
3327   SymbolRef Symbol;
3328   for (const RelocationRef &Reloc : S.relocations()) {
3329     uint64_t RelocOffset = Reloc.getOffset();
3330     if (RelocOffset == sect_offset) {
3331       Rel = Reloc.getRawDataRefImpl();
3332       RE = info->O->getRelocation(Rel);
3333       if (info->O->isRelocationScattered(RE))
3334         continue;
3335       isExtern = info->O->getPlainRelocationExternal(RE);
3336       if (isExtern) {
3337         symbol_iterator RelocSym = Reloc.getSymbol();
3338         Symbol = *RelocSym;
3339       }
3340       reloc_found = true;
3341       break;
3342     }
3343   }
3344   // If there is an external relocation entry for a symbol in this section
3345   // at this section_offset then use that symbol's value for the n_value
3346   // and return its name.
3347   const char *SymbolName = nullptr;
3348   if (reloc_found && isExtern) {
3349     n_value = cantFail(Symbol.getValue());
3350     StringRef Name = unwrapOrError(Symbol.getName(), info->O->getFileName());
3351     if (!Name.empty()) {
3352       SymbolName = Name.data();
3353       return SymbolName;
3354     }
3355   }
3356 
3357   // TODO: For fully linked images, look through the external relocation
3358   // entries off the dynamic symtab command. For these the r_offset is from the
3359   // start of the first writeable segment in the Mach-O file.  So the offset
3360   // to this section from that segment is passed to this routine by the caller,
3361   // as the database_offset. Which is the difference of the section's starting
3362   // address and the first writable segment.
3363   //
3364   // NOTE: need add passing the database_offset to this routine.
3365 
3366   // We did not find an external relocation entry so look up the ReferenceValue
3367   // as an address of a symbol and if found return that symbol's name.
3368   SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
3369 
3370   return SymbolName;
3371 }
3372 
3373 static const char *get_symbol_32(uint32_t sect_offset, SectionRef S,
3374                                  DisassembleInfo *info,
3375                                  uint32_t ReferenceValue) {
3376   uint64_t n_value64;
3377   return get_symbol_64(sect_offset, S, info, n_value64, ReferenceValue);
3378 }
3379 
3380 namespace {
3381 
3382 // These are structs in the Objective-C meta data and read to produce the
3383 // comments for disassembly.  While these are part of the ABI they are no
3384 // public defintions.  So the are here not in include/llvm/BinaryFormat/MachO.h
3385 // .
3386 
3387 // The cfstring object in a 64-bit Mach-O file.
3388 struct cfstring64_t {
3389   uint64_t isa;        // class64_t * (64-bit pointer)
3390   uint64_t flags;      // flag bits
3391   uint64_t characters; // char * (64-bit pointer)
3392   uint64_t length;     // number of non-NULL characters in above
3393 };
3394 
3395 // The class object in a 64-bit Mach-O file.
3396 struct class64_t {
3397   uint64_t isa;        // class64_t * (64-bit pointer)
3398   uint64_t superclass; // class64_t * (64-bit pointer)
3399   uint64_t cache;      // Cache (64-bit pointer)
3400   uint64_t vtable;     // IMP * (64-bit pointer)
3401   uint64_t data;       // class_ro64_t * (64-bit pointer)
3402 };
3403 
3404 struct class32_t {
3405   uint32_t isa;        /* class32_t * (32-bit pointer) */
3406   uint32_t superclass; /* class32_t * (32-bit pointer) */
3407   uint32_t cache;      /* Cache (32-bit pointer) */
3408   uint32_t vtable;     /* IMP * (32-bit pointer) */
3409   uint32_t data;       /* class_ro32_t * (32-bit pointer) */
3410 };
3411 
3412 struct class_ro64_t {
3413   uint32_t flags;
3414   uint32_t instanceStart;
3415   uint32_t instanceSize;
3416   uint32_t reserved;
3417   uint64_t ivarLayout;     // const uint8_t * (64-bit pointer)
3418   uint64_t name;           // const char * (64-bit pointer)
3419   uint64_t baseMethods;    // const method_list_t * (64-bit pointer)
3420   uint64_t baseProtocols;  // const protocol_list_t * (64-bit pointer)
3421   uint64_t ivars;          // const ivar_list_t * (64-bit pointer)
3422   uint64_t weakIvarLayout; // const uint8_t * (64-bit pointer)
3423   uint64_t baseProperties; // const struct objc_property_list (64-bit pointer)
3424 };
3425 
3426 struct class_ro32_t {
3427   uint32_t flags;
3428   uint32_t instanceStart;
3429   uint32_t instanceSize;
3430   uint32_t ivarLayout;     /* const uint8_t * (32-bit pointer) */
3431   uint32_t name;           /* const char * (32-bit pointer) */
3432   uint32_t baseMethods;    /* const method_list_t * (32-bit pointer) */
3433   uint32_t baseProtocols;  /* const protocol_list_t * (32-bit pointer) */
3434   uint32_t ivars;          /* const ivar_list_t * (32-bit pointer) */
3435   uint32_t weakIvarLayout; /* const uint8_t * (32-bit pointer) */
3436   uint32_t baseProperties; /* const struct objc_property_list *
3437                                                    (32-bit pointer) */
3438 };
3439 
3440 /* Values for class_ro{64,32}_t->flags */
3441 #define RO_META (1 << 0)
3442 #define RO_ROOT (1 << 1)
3443 #define RO_HAS_CXX_STRUCTORS (1 << 2)
3444 
3445 struct method_list64_t {
3446   uint32_t entsize;
3447   uint32_t count;
3448   /* struct method64_t first;  These structures follow inline */
3449 };
3450 
3451 struct method_list32_t {
3452   uint32_t entsize;
3453   uint32_t count;
3454   /* struct method32_t first;  These structures follow inline */
3455 };
3456 
3457 struct method64_t {
3458   uint64_t name;  /* SEL (64-bit pointer) */
3459   uint64_t types; /* const char * (64-bit pointer) */
3460   uint64_t imp;   /* IMP (64-bit pointer) */
3461 };
3462 
3463 struct method32_t {
3464   uint32_t name;  /* SEL (32-bit pointer) */
3465   uint32_t types; /* const char * (32-bit pointer) */
3466   uint32_t imp;   /* IMP (32-bit pointer) */
3467 };
3468 
3469 struct protocol_list64_t {
3470   uint64_t count; /* uintptr_t (a 64-bit value) */
3471   /* struct protocol64_t * list[0];  These pointers follow inline */
3472 };
3473 
3474 struct protocol_list32_t {
3475   uint32_t count; /* uintptr_t (a 32-bit value) */
3476   /* struct protocol32_t * list[0];  These pointers follow inline */
3477 };
3478 
3479 struct protocol64_t {
3480   uint64_t isa;                     /* id * (64-bit pointer) */
3481   uint64_t name;                    /* const char * (64-bit pointer) */
3482   uint64_t protocols;               /* struct protocol_list64_t *
3483                                                     (64-bit pointer) */
3484   uint64_t instanceMethods;         /* method_list_t * (64-bit pointer) */
3485   uint64_t classMethods;            /* method_list_t * (64-bit pointer) */
3486   uint64_t optionalInstanceMethods; /* method_list_t * (64-bit pointer) */
3487   uint64_t optionalClassMethods;    /* method_list_t * (64-bit pointer) */
3488   uint64_t instanceProperties;      /* struct objc_property_list *
3489                                                        (64-bit pointer) */
3490 };
3491 
3492 struct protocol32_t {
3493   uint32_t isa;                     /* id * (32-bit pointer) */
3494   uint32_t name;                    /* const char * (32-bit pointer) */
3495   uint32_t protocols;               /* struct protocol_list_t *
3496                                                     (32-bit pointer) */
3497   uint32_t instanceMethods;         /* method_list_t * (32-bit pointer) */
3498   uint32_t classMethods;            /* method_list_t * (32-bit pointer) */
3499   uint32_t optionalInstanceMethods; /* method_list_t * (32-bit pointer) */
3500   uint32_t optionalClassMethods;    /* method_list_t * (32-bit pointer) */
3501   uint32_t instanceProperties;      /* struct objc_property_list *
3502                                                        (32-bit pointer) */
3503 };
3504 
3505 struct ivar_list64_t {
3506   uint32_t entsize;
3507   uint32_t count;
3508   /* struct ivar64_t first;  These structures follow inline */
3509 };
3510 
3511 struct ivar_list32_t {
3512   uint32_t entsize;
3513   uint32_t count;
3514   /* struct ivar32_t first;  These structures follow inline */
3515 };
3516 
3517 struct ivar64_t {
3518   uint64_t offset; /* uintptr_t * (64-bit pointer) */
3519   uint64_t name;   /* const char * (64-bit pointer) */
3520   uint64_t type;   /* const char * (64-bit pointer) */
3521   uint32_t alignment;
3522   uint32_t size;
3523 };
3524 
3525 struct ivar32_t {
3526   uint32_t offset; /* uintptr_t * (32-bit pointer) */
3527   uint32_t name;   /* const char * (32-bit pointer) */
3528   uint32_t type;   /* const char * (32-bit pointer) */
3529   uint32_t alignment;
3530   uint32_t size;
3531 };
3532 
3533 struct objc_property_list64 {
3534   uint32_t entsize;
3535   uint32_t count;
3536   /* struct objc_property64 first;  These structures follow inline */
3537 };
3538 
3539 struct objc_property_list32 {
3540   uint32_t entsize;
3541   uint32_t count;
3542   /* struct objc_property32 first;  These structures follow inline */
3543 };
3544 
3545 struct objc_property64 {
3546   uint64_t name;       /* const char * (64-bit pointer) */
3547   uint64_t attributes; /* const char * (64-bit pointer) */
3548 };
3549 
3550 struct objc_property32 {
3551   uint32_t name;       /* const char * (32-bit pointer) */
3552   uint32_t attributes; /* const char * (32-bit pointer) */
3553 };
3554 
3555 struct category64_t {
3556   uint64_t name;               /* const char * (64-bit pointer) */
3557   uint64_t cls;                /* struct class_t * (64-bit pointer) */
3558   uint64_t instanceMethods;    /* struct method_list_t * (64-bit pointer) */
3559   uint64_t classMethods;       /* struct method_list_t * (64-bit pointer) */
3560   uint64_t protocols;          /* struct protocol_list_t * (64-bit pointer) */
3561   uint64_t instanceProperties; /* struct objc_property_list *
3562                                   (64-bit pointer) */
3563 };
3564 
3565 struct category32_t {
3566   uint32_t name;               /* const char * (32-bit pointer) */
3567   uint32_t cls;                /* struct class_t * (32-bit pointer) */
3568   uint32_t instanceMethods;    /* struct method_list_t * (32-bit pointer) */
3569   uint32_t classMethods;       /* struct method_list_t * (32-bit pointer) */
3570   uint32_t protocols;          /* struct protocol_list_t * (32-bit pointer) */
3571   uint32_t instanceProperties; /* struct objc_property_list *
3572                                   (32-bit pointer) */
3573 };
3574 
3575 struct objc_image_info64 {
3576   uint32_t version;
3577   uint32_t flags;
3578 };
3579 struct objc_image_info32 {
3580   uint32_t version;
3581   uint32_t flags;
3582 };
3583 struct imageInfo_t {
3584   uint32_t version;
3585   uint32_t flags;
3586 };
3587 /* masks for objc_image_info.flags */
3588 #define OBJC_IMAGE_IS_REPLACEMENT (1 << 0)
3589 #define OBJC_IMAGE_SUPPORTS_GC (1 << 1)
3590 #define OBJC_IMAGE_IS_SIMULATED (1 << 5)
3591 #define OBJC_IMAGE_HAS_CATEGORY_CLASS_PROPERTIES (1 << 6)
3592 
3593 struct message_ref64 {
3594   uint64_t imp; /* IMP (64-bit pointer) */
3595   uint64_t sel; /* SEL (64-bit pointer) */
3596 };
3597 
3598 struct message_ref32 {
3599   uint32_t imp; /* IMP (32-bit pointer) */
3600   uint32_t sel; /* SEL (32-bit pointer) */
3601 };
3602 
3603 // Objective-C 1 (32-bit only) meta data structs.
3604 
3605 struct objc_module_t {
3606   uint32_t version;
3607   uint32_t size;
3608   uint32_t name;   /* char * (32-bit pointer) */
3609   uint32_t symtab; /* struct objc_symtab * (32-bit pointer) */
3610 };
3611 
3612 struct objc_symtab_t {
3613   uint32_t sel_ref_cnt;
3614   uint32_t refs; /* SEL * (32-bit pointer) */
3615   uint16_t cls_def_cnt;
3616   uint16_t cat_def_cnt;
3617   // uint32_t defs[1];        /* void * (32-bit pointer) variable size */
3618 };
3619 
3620 struct objc_class_t {
3621   uint32_t isa;         /* struct objc_class * (32-bit pointer) */
3622   uint32_t super_class; /* struct objc_class * (32-bit pointer) */
3623   uint32_t name;        /* const char * (32-bit pointer) */
3624   int32_t version;
3625   int32_t info;
3626   int32_t instance_size;
3627   uint32_t ivars;       /* struct objc_ivar_list * (32-bit pointer) */
3628   uint32_t methodLists; /* struct objc_method_list ** (32-bit pointer) */
3629   uint32_t cache;       /* struct objc_cache * (32-bit pointer) */
3630   uint32_t protocols;   /* struct objc_protocol_list * (32-bit pointer) */
3631 };
3632 
3633 #define CLS_GETINFO(cls, infomask) ((cls)->info & (infomask))
3634 // class is not a metaclass
3635 #define CLS_CLASS 0x1
3636 // class is a metaclass
3637 #define CLS_META 0x2
3638 
3639 struct objc_category_t {
3640   uint32_t category_name;    /* char * (32-bit pointer) */
3641   uint32_t class_name;       /* char * (32-bit pointer) */
3642   uint32_t instance_methods; /* struct objc_method_list * (32-bit pointer) */
3643   uint32_t class_methods;    /* struct objc_method_list * (32-bit pointer) */
3644   uint32_t protocols;        /* struct objc_protocol_list * (32-bit ptr) */
3645 };
3646 
3647 struct objc_ivar_t {
3648   uint32_t ivar_name; /* char * (32-bit pointer) */
3649   uint32_t ivar_type; /* char * (32-bit pointer) */
3650   int32_t ivar_offset;
3651 };
3652 
3653 struct objc_ivar_list_t {
3654   int32_t ivar_count;
3655   // struct objc_ivar_t ivar_list[1];          /* variable length structure */
3656 };
3657 
3658 struct objc_method_list_t {
3659   uint32_t obsolete; /* struct objc_method_list * (32-bit pointer) */
3660   int32_t method_count;
3661   // struct objc_method_t method_list[1];      /* variable length structure */
3662 };
3663 
3664 struct objc_method_t {
3665   uint32_t method_name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
3666   uint32_t method_types; /* char * (32-bit pointer) */
3667   uint32_t method_imp;   /* IMP, aka function pointer, (*IMP)(id, SEL, ...)
3668                             (32-bit pointer) */
3669 };
3670 
3671 struct objc_protocol_list_t {
3672   uint32_t next; /* struct objc_protocol_list * (32-bit pointer) */
3673   int32_t count;
3674   // uint32_t list[1];   /* Protocol *, aka struct objc_protocol_t *
3675   //                        (32-bit pointer) */
3676 };
3677 
3678 struct objc_protocol_t {
3679   uint32_t isa;              /* struct objc_class * (32-bit pointer) */
3680   uint32_t protocol_name;    /* char * (32-bit pointer) */
3681   uint32_t protocol_list;    /* struct objc_protocol_list * (32-bit pointer) */
3682   uint32_t instance_methods; /* struct objc_method_description_list *
3683                                 (32-bit pointer) */
3684   uint32_t class_methods;    /* struct objc_method_description_list *
3685                                 (32-bit pointer) */
3686 };
3687 
3688 struct objc_method_description_list_t {
3689   int32_t count;
3690   // struct objc_method_description_t list[1];
3691 };
3692 
3693 struct objc_method_description_t {
3694   uint32_t name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
3695   uint32_t types; /* char * (32-bit pointer) */
3696 };
3697 
3698 inline void swapStruct(struct cfstring64_t &cfs) {
3699   sys::swapByteOrder(cfs.isa);
3700   sys::swapByteOrder(cfs.flags);
3701   sys::swapByteOrder(cfs.characters);
3702   sys::swapByteOrder(cfs.length);
3703 }
3704 
3705 inline void swapStruct(struct class64_t &c) {
3706   sys::swapByteOrder(c.isa);
3707   sys::swapByteOrder(c.superclass);
3708   sys::swapByteOrder(c.cache);
3709   sys::swapByteOrder(c.vtable);
3710   sys::swapByteOrder(c.data);
3711 }
3712 
3713 inline void swapStruct(struct class32_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 class_ro64_t &cro) {
3722   sys::swapByteOrder(cro.flags);
3723   sys::swapByteOrder(cro.instanceStart);
3724   sys::swapByteOrder(cro.instanceSize);
3725   sys::swapByteOrder(cro.reserved);
3726   sys::swapByteOrder(cro.ivarLayout);
3727   sys::swapByteOrder(cro.name);
3728   sys::swapByteOrder(cro.baseMethods);
3729   sys::swapByteOrder(cro.baseProtocols);
3730   sys::swapByteOrder(cro.ivars);
3731   sys::swapByteOrder(cro.weakIvarLayout);
3732   sys::swapByteOrder(cro.baseProperties);
3733 }
3734 
3735 inline void swapStruct(struct class_ro32_t &cro) {
3736   sys::swapByteOrder(cro.flags);
3737   sys::swapByteOrder(cro.instanceStart);
3738   sys::swapByteOrder(cro.instanceSize);
3739   sys::swapByteOrder(cro.ivarLayout);
3740   sys::swapByteOrder(cro.name);
3741   sys::swapByteOrder(cro.baseMethods);
3742   sys::swapByteOrder(cro.baseProtocols);
3743   sys::swapByteOrder(cro.ivars);
3744   sys::swapByteOrder(cro.weakIvarLayout);
3745   sys::swapByteOrder(cro.baseProperties);
3746 }
3747 
3748 inline void swapStruct(struct method_list64_t &ml) {
3749   sys::swapByteOrder(ml.entsize);
3750   sys::swapByteOrder(ml.count);
3751 }
3752 
3753 inline void swapStruct(struct method_list32_t &ml) {
3754   sys::swapByteOrder(ml.entsize);
3755   sys::swapByteOrder(ml.count);
3756 }
3757 
3758 inline void swapStruct(struct method64_t &m) {
3759   sys::swapByteOrder(m.name);
3760   sys::swapByteOrder(m.types);
3761   sys::swapByteOrder(m.imp);
3762 }
3763 
3764 inline void swapStruct(struct method32_t &m) {
3765   sys::swapByteOrder(m.name);
3766   sys::swapByteOrder(m.types);
3767   sys::swapByteOrder(m.imp);
3768 }
3769 
3770 inline void swapStruct(struct protocol_list64_t &pl) {
3771   sys::swapByteOrder(pl.count);
3772 }
3773 
3774 inline void swapStruct(struct protocol_list32_t &pl) {
3775   sys::swapByteOrder(pl.count);
3776 }
3777 
3778 inline void swapStruct(struct protocol64_t &p) {
3779   sys::swapByteOrder(p.isa);
3780   sys::swapByteOrder(p.name);
3781   sys::swapByteOrder(p.protocols);
3782   sys::swapByteOrder(p.instanceMethods);
3783   sys::swapByteOrder(p.classMethods);
3784   sys::swapByteOrder(p.optionalInstanceMethods);
3785   sys::swapByteOrder(p.optionalClassMethods);
3786   sys::swapByteOrder(p.instanceProperties);
3787 }
3788 
3789 inline void swapStruct(struct protocol32_t &p) {
3790   sys::swapByteOrder(p.isa);
3791   sys::swapByteOrder(p.name);
3792   sys::swapByteOrder(p.protocols);
3793   sys::swapByteOrder(p.instanceMethods);
3794   sys::swapByteOrder(p.classMethods);
3795   sys::swapByteOrder(p.optionalInstanceMethods);
3796   sys::swapByteOrder(p.optionalClassMethods);
3797   sys::swapByteOrder(p.instanceProperties);
3798 }
3799 
3800 inline void swapStruct(struct ivar_list64_t &il) {
3801   sys::swapByteOrder(il.entsize);
3802   sys::swapByteOrder(il.count);
3803 }
3804 
3805 inline void swapStruct(struct ivar_list32_t &il) {
3806   sys::swapByteOrder(il.entsize);
3807   sys::swapByteOrder(il.count);
3808 }
3809 
3810 inline void swapStruct(struct ivar64_t &i) {
3811   sys::swapByteOrder(i.offset);
3812   sys::swapByteOrder(i.name);
3813   sys::swapByteOrder(i.type);
3814   sys::swapByteOrder(i.alignment);
3815   sys::swapByteOrder(i.size);
3816 }
3817 
3818 inline void swapStruct(struct ivar32_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 objc_property_list64 &pl) {
3827   sys::swapByteOrder(pl.entsize);
3828   sys::swapByteOrder(pl.count);
3829 }
3830 
3831 inline void swapStruct(struct objc_property_list32 &pl) {
3832   sys::swapByteOrder(pl.entsize);
3833   sys::swapByteOrder(pl.count);
3834 }
3835 
3836 inline void swapStruct(struct objc_property64 &op) {
3837   sys::swapByteOrder(op.name);
3838   sys::swapByteOrder(op.attributes);
3839 }
3840 
3841 inline void swapStruct(struct objc_property32 &op) {
3842   sys::swapByteOrder(op.name);
3843   sys::swapByteOrder(op.attributes);
3844 }
3845 
3846 inline void swapStruct(struct category64_t &c) {
3847   sys::swapByteOrder(c.name);
3848   sys::swapByteOrder(c.cls);
3849   sys::swapByteOrder(c.instanceMethods);
3850   sys::swapByteOrder(c.classMethods);
3851   sys::swapByteOrder(c.protocols);
3852   sys::swapByteOrder(c.instanceProperties);
3853 }
3854 
3855 inline void swapStruct(struct category32_t &c) {
3856   sys::swapByteOrder(c.name);
3857   sys::swapByteOrder(c.cls);
3858   sys::swapByteOrder(c.instanceMethods);
3859   sys::swapByteOrder(c.classMethods);
3860   sys::swapByteOrder(c.protocols);
3861   sys::swapByteOrder(c.instanceProperties);
3862 }
3863 
3864 inline void swapStruct(struct objc_image_info64 &o) {
3865   sys::swapByteOrder(o.version);
3866   sys::swapByteOrder(o.flags);
3867 }
3868 
3869 inline void swapStruct(struct objc_image_info32 &o) {
3870   sys::swapByteOrder(o.version);
3871   sys::swapByteOrder(o.flags);
3872 }
3873 
3874 inline void swapStruct(struct imageInfo_t &o) {
3875   sys::swapByteOrder(o.version);
3876   sys::swapByteOrder(o.flags);
3877 }
3878 
3879 inline void swapStruct(struct message_ref64 &mr) {
3880   sys::swapByteOrder(mr.imp);
3881   sys::swapByteOrder(mr.sel);
3882 }
3883 
3884 inline void swapStruct(struct message_ref32 &mr) {
3885   sys::swapByteOrder(mr.imp);
3886   sys::swapByteOrder(mr.sel);
3887 }
3888 
3889 inline void swapStruct(struct objc_module_t &module) {
3890   sys::swapByteOrder(module.version);
3891   sys::swapByteOrder(module.size);
3892   sys::swapByteOrder(module.name);
3893   sys::swapByteOrder(module.symtab);
3894 }
3895 
3896 inline void swapStruct(struct objc_symtab_t &symtab) {
3897   sys::swapByteOrder(symtab.sel_ref_cnt);
3898   sys::swapByteOrder(symtab.refs);
3899   sys::swapByteOrder(symtab.cls_def_cnt);
3900   sys::swapByteOrder(symtab.cat_def_cnt);
3901 }
3902 
3903 inline void swapStruct(struct objc_class_t &objc_class) {
3904   sys::swapByteOrder(objc_class.isa);
3905   sys::swapByteOrder(objc_class.super_class);
3906   sys::swapByteOrder(objc_class.name);
3907   sys::swapByteOrder(objc_class.version);
3908   sys::swapByteOrder(objc_class.info);
3909   sys::swapByteOrder(objc_class.instance_size);
3910   sys::swapByteOrder(objc_class.ivars);
3911   sys::swapByteOrder(objc_class.methodLists);
3912   sys::swapByteOrder(objc_class.cache);
3913   sys::swapByteOrder(objc_class.protocols);
3914 }
3915 
3916 inline void swapStruct(struct objc_category_t &objc_category) {
3917   sys::swapByteOrder(objc_category.category_name);
3918   sys::swapByteOrder(objc_category.class_name);
3919   sys::swapByteOrder(objc_category.instance_methods);
3920   sys::swapByteOrder(objc_category.class_methods);
3921   sys::swapByteOrder(objc_category.protocols);
3922 }
3923 
3924 inline void swapStruct(struct objc_ivar_list_t &objc_ivar_list) {
3925   sys::swapByteOrder(objc_ivar_list.ivar_count);
3926 }
3927 
3928 inline void swapStruct(struct objc_ivar_t &objc_ivar) {
3929   sys::swapByteOrder(objc_ivar.ivar_name);
3930   sys::swapByteOrder(objc_ivar.ivar_type);
3931   sys::swapByteOrder(objc_ivar.ivar_offset);
3932 }
3933 
3934 inline void swapStruct(struct objc_method_list_t &method_list) {
3935   sys::swapByteOrder(method_list.obsolete);
3936   sys::swapByteOrder(method_list.method_count);
3937 }
3938 
3939 inline void swapStruct(struct objc_method_t &method) {
3940   sys::swapByteOrder(method.method_name);
3941   sys::swapByteOrder(method.method_types);
3942   sys::swapByteOrder(method.method_imp);
3943 }
3944 
3945 inline void swapStruct(struct objc_protocol_list_t &protocol_list) {
3946   sys::swapByteOrder(protocol_list.next);
3947   sys::swapByteOrder(protocol_list.count);
3948 }
3949 
3950 inline void swapStruct(struct objc_protocol_t &protocol) {
3951   sys::swapByteOrder(protocol.isa);
3952   sys::swapByteOrder(protocol.protocol_name);
3953   sys::swapByteOrder(protocol.protocol_list);
3954   sys::swapByteOrder(protocol.instance_methods);
3955   sys::swapByteOrder(protocol.class_methods);
3956 }
3957 
3958 inline void swapStruct(struct objc_method_description_list_t &mdl) {
3959   sys::swapByteOrder(mdl.count);
3960 }
3961 
3962 inline void swapStruct(struct objc_method_description_t &md) {
3963   sys::swapByteOrder(md.name);
3964   sys::swapByteOrder(md.types);
3965 }
3966 
3967 } // namespace
3968 
3969 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
3970                                                  struct DisassembleInfo *info);
3971 
3972 // get_objc2_64bit_class_name() is used for disassembly and is passed a pointer
3973 // to an Objective-C class and returns the class name.  It is also passed the
3974 // address of the pointer, so when the pointer is zero as it can be in an .o
3975 // file, that is used to look for an external relocation entry with a symbol
3976 // name.
3977 static const char *get_objc2_64bit_class_name(uint64_t pointer_value,
3978                                               uint64_t ReferenceValue,
3979                                               struct DisassembleInfo *info) {
3980   const char *r;
3981   uint32_t offset, left;
3982   SectionRef S;
3983 
3984   // The pointer_value can be 0 in an object file and have a relocation
3985   // entry for the class symbol at the ReferenceValue (the address of the
3986   // pointer).
3987   if (pointer_value == 0) {
3988     r = get_pointer_64(ReferenceValue, offset, left, S, info);
3989     if (r == nullptr || left < sizeof(uint64_t))
3990       return nullptr;
3991     uint64_t n_value;
3992     const char *symbol_name = get_symbol_64(offset, S, info, n_value);
3993     if (symbol_name == nullptr)
3994       return nullptr;
3995     const char *class_name = strrchr(symbol_name, '$');
3996     if (class_name != nullptr && class_name[1] == '_' && class_name[2] != '\0')
3997       return class_name + 2;
3998     else
3999       return nullptr;
4000   }
4001 
4002   // The case were the pointer_value is non-zero and points to a class defined
4003   // in this Mach-O file.
4004   r = get_pointer_64(pointer_value, offset, left, S, info);
4005   if (r == nullptr || left < sizeof(struct class64_t))
4006     return nullptr;
4007   struct class64_t c;
4008   memcpy(&c, r, sizeof(struct class64_t));
4009   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4010     swapStruct(c);
4011   if (c.data == 0)
4012     return nullptr;
4013   r = get_pointer_64(c.data, offset, left, S, info);
4014   if (r == nullptr || left < sizeof(struct class_ro64_t))
4015     return nullptr;
4016   struct class_ro64_t cro;
4017   memcpy(&cro, r, sizeof(struct class_ro64_t));
4018   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4019     swapStruct(cro);
4020   if (cro.name == 0)
4021     return nullptr;
4022   const char *name = get_pointer_64(cro.name, offset, left, S, info);
4023   return name;
4024 }
4025 
4026 // get_objc2_64bit_cfstring_name is used for disassembly and is passed a
4027 // pointer to a cfstring and returns its name or nullptr.
4028 static const char *get_objc2_64bit_cfstring_name(uint64_t ReferenceValue,
4029                                                  struct DisassembleInfo *info) {
4030   const char *r, *name;
4031   uint32_t offset, left;
4032   SectionRef S;
4033   struct cfstring64_t cfs;
4034   uint64_t cfs_characters;
4035 
4036   r = get_pointer_64(ReferenceValue, offset, left, S, info);
4037   if (r == nullptr || left < sizeof(struct cfstring64_t))
4038     return nullptr;
4039   memcpy(&cfs, r, sizeof(struct cfstring64_t));
4040   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4041     swapStruct(cfs);
4042   if (cfs.characters == 0) {
4043     uint64_t n_value;
4044     const char *symbol_name = get_symbol_64(
4045         offset + offsetof(struct cfstring64_t, characters), S, info, n_value);
4046     if (symbol_name == nullptr)
4047       return nullptr;
4048     cfs_characters = n_value;
4049   } else
4050     cfs_characters = cfs.characters;
4051   name = get_pointer_64(cfs_characters, offset, left, S, info);
4052 
4053   return name;
4054 }
4055 
4056 // get_objc2_64bit_selref() is used for disassembly and is passed a the address
4057 // of a pointer to an Objective-C selector reference when the pointer value is
4058 // zero as in a .o file and is likely to have a external relocation entry with
4059 // who's symbol's n_value is the real pointer to the selector name.  If that is
4060 // the case the real pointer to the selector name is returned else 0 is
4061 // returned
4062 static uint64_t get_objc2_64bit_selref(uint64_t ReferenceValue,
4063                                        struct DisassembleInfo *info) {
4064   uint32_t offset, left;
4065   SectionRef S;
4066 
4067   const char *r = get_pointer_64(ReferenceValue, offset, left, S, info);
4068   if (r == nullptr || left < sizeof(uint64_t))
4069     return 0;
4070   uint64_t n_value;
4071   const char *symbol_name = get_symbol_64(offset, S, info, n_value);
4072   if (symbol_name == nullptr)
4073     return 0;
4074   return n_value;
4075 }
4076 
4077 static const SectionRef get_section(MachOObjectFile *O, const char *segname,
4078                                     const char *sectname) {
4079   for (const SectionRef &Section : O->sections()) {
4080     StringRef SectName;
4081     Expected<StringRef> SecNameOrErr = Section.getName();
4082     if (SecNameOrErr)
4083       SectName = *SecNameOrErr;
4084     else
4085       consumeError(SecNameOrErr.takeError());
4086 
4087     DataRefImpl Ref = Section.getRawDataRefImpl();
4088     StringRef SegName = O->getSectionFinalSegmentName(Ref);
4089     if (SegName == segname && SectName == sectname)
4090       return Section;
4091   }
4092   return SectionRef();
4093 }
4094 
4095 static void
4096 walk_pointer_list_64(const char *listname, const SectionRef S,
4097                      MachOObjectFile *O, struct DisassembleInfo *info,
4098                      void (*func)(uint64_t, struct DisassembleInfo *info)) {
4099   if (S == SectionRef())
4100     return;
4101 
4102   StringRef SectName;
4103   Expected<StringRef> SecNameOrErr = S.getName();
4104   if (SecNameOrErr)
4105     SectName = *SecNameOrErr;
4106   else
4107     consumeError(SecNameOrErr.takeError());
4108 
4109   DataRefImpl Ref = S.getRawDataRefImpl();
4110   StringRef SegName = O->getSectionFinalSegmentName(Ref);
4111   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
4112 
4113   StringRef BytesStr = unwrapOrError(S.getContents(), O->getFileName());
4114   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
4115 
4116   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint64_t)) {
4117     uint32_t left = S.getSize() - i;
4118     uint32_t size = left < sizeof(uint64_t) ? left : sizeof(uint64_t);
4119     uint64_t p = 0;
4120     memcpy(&p, Contents + i, size);
4121     if (i + sizeof(uint64_t) > S.getSize())
4122       outs() << listname << " list pointer extends past end of (" << SegName
4123              << "," << SectName << ") section\n";
4124     outs() << format("%016" PRIx64, S.getAddress() + i) << " ";
4125 
4126     if (O->isLittleEndian() != sys::IsLittleEndianHost)
4127       sys::swapByteOrder(p);
4128 
4129     uint64_t n_value = 0;
4130     const char *name = get_symbol_64(i, S, info, n_value, p);
4131     if (name == nullptr)
4132       name = get_dyld_bind_info_symbolname(S.getAddress() + i, info);
4133 
4134     if (n_value != 0) {
4135       outs() << format("0x%" PRIx64, n_value);
4136       if (p != 0)
4137         outs() << " + " << format("0x%" PRIx64, p);
4138     } else
4139       outs() << format("0x%" PRIx64, p);
4140     if (name != nullptr)
4141       outs() << " " << name;
4142     outs() << "\n";
4143 
4144     p += n_value;
4145     if (func)
4146       func(p, info);
4147   }
4148 }
4149 
4150 static void
4151 walk_pointer_list_32(const char *listname, const SectionRef S,
4152                      MachOObjectFile *O, struct DisassembleInfo *info,
4153                      void (*func)(uint32_t, struct DisassembleInfo *info)) {
4154   if (S == SectionRef())
4155     return;
4156 
4157   StringRef SectName = unwrapOrError(S.getName(), O->getFileName());
4158   DataRefImpl Ref = S.getRawDataRefImpl();
4159   StringRef SegName = O->getSectionFinalSegmentName(Ref);
4160   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
4161 
4162   StringRef BytesStr = unwrapOrError(S.getContents(), O->getFileName());
4163   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
4164 
4165   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint32_t)) {
4166     uint32_t left = S.getSize() - i;
4167     uint32_t size = left < sizeof(uint32_t) ? left : sizeof(uint32_t);
4168     uint32_t p = 0;
4169     memcpy(&p, Contents + i, size);
4170     if (i + sizeof(uint32_t) > S.getSize())
4171       outs() << listname << " list pointer extends past end of (" << SegName
4172              << "," << SectName << ") section\n";
4173     uint32_t Address = S.getAddress() + i;
4174     outs() << format("%08" PRIx32, Address) << " ";
4175 
4176     if (O->isLittleEndian() != sys::IsLittleEndianHost)
4177       sys::swapByteOrder(p);
4178     outs() << format("0x%" PRIx32, p);
4179 
4180     const char *name = get_symbol_32(i, S, info, p);
4181     if (name != nullptr)
4182       outs() << " " << name;
4183     outs() << "\n";
4184 
4185     if (func)
4186       func(p, info);
4187   }
4188 }
4189 
4190 static void print_layout_map(const char *layout_map, uint32_t left) {
4191   if (layout_map == nullptr)
4192     return;
4193   outs() << "                layout map: ";
4194   do {
4195     outs() << format("0x%02" PRIx32, (*layout_map) & 0xff) << " ";
4196     left--;
4197     layout_map++;
4198   } while (*layout_map != '\0' && left != 0);
4199   outs() << "\n";
4200 }
4201 
4202 static void print_layout_map64(uint64_t p, struct DisassembleInfo *info) {
4203   uint32_t offset, left;
4204   SectionRef S;
4205   const char *layout_map;
4206 
4207   if (p == 0)
4208     return;
4209   layout_map = get_pointer_64(p, offset, left, S, info);
4210   print_layout_map(layout_map, left);
4211 }
4212 
4213 static void print_layout_map32(uint32_t p, struct DisassembleInfo *info) {
4214   uint32_t offset, left;
4215   SectionRef S;
4216   const char *layout_map;
4217 
4218   if (p == 0)
4219     return;
4220   layout_map = get_pointer_32(p, offset, left, S, info);
4221   print_layout_map(layout_map, left);
4222 }
4223 
4224 static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
4225                                   const char *indent) {
4226   struct method_list64_t ml;
4227   struct method64_t m;
4228   const char *r;
4229   uint32_t offset, xoffset, left, i;
4230   SectionRef S, xS;
4231   const char *name, *sym_name;
4232   uint64_t n_value;
4233 
4234   r = get_pointer_64(p, offset, left, S, info);
4235   if (r == nullptr)
4236     return;
4237   memset(&ml, '\0', sizeof(struct method_list64_t));
4238   if (left < sizeof(struct method_list64_t)) {
4239     memcpy(&ml, r, left);
4240     outs() << "   (method_list_t entends past the end of the section)\n";
4241   } else
4242     memcpy(&ml, r, sizeof(struct method_list64_t));
4243   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4244     swapStruct(ml);
4245   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
4246   outs() << indent << "\t\t     count " << ml.count << "\n";
4247 
4248   p += sizeof(struct method_list64_t);
4249   offset += sizeof(struct method_list64_t);
4250   for (i = 0; i < ml.count; i++) {
4251     r = get_pointer_64(p, offset, left, S, info);
4252     if (r == nullptr)
4253       return;
4254     memset(&m, '\0', sizeof(struct method64_t));
4255     if (left < sizeof(struct method64_t)) {
4256       memcpy(&m, r, left);
4257       outs() << indent << "   (method_t extends past the end of the section)\n";
4258     } else
4259       memcpy(&m, r, sizeof(struct method64_t));
4260     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4261       swapStruct(m);
4262 
4263     outs() << indent << "\t\t      name ";
4264     sym_name = get_symbol_64(offset + offsetof(struct method64_t, name), S,
4265                              info, n_value, m.name);
4266     if (n_value != 0) {
4267       if (info->verbose && sym_name != nullptr)
4268         outs() << sym_name;
4269       else
4270         outs() << format("0x%" PRIx64, n_value);
4271       if (m.name != 0)
4272         outs() << " + " << format("0x%" PRIx64, m.name);
4273     } else
4274       outs() << format("0x%" PRIx64, m.name);
4275     name = get_pointer_64(m.name + n_value, xoffset, left, xS, info);
4276     if (name != nullptr)
4277       outs() << format(" %.*s", left, name);
4278     outs() << "\n";
4279 
4280     outs() << indent << "\t\t     types ";
4281     sym_name = get_symbol_64(offset + offsetof(struct method64_t, types), S,
4282                              info, n_value, m.types);
4283     if (n_value != 0) {
4284       if (info->verbose && sym_name != nullptr)
4285         outs() << sym_name;
4286       else
4287         outs() << format("0x%" PRIx64, n_value);
4288       if (m.types != 0)
4289         outs() << " + " << format("0x%" PRIx64, m.types);
4290     } else
4291       outs() << format("0x%" PRIx64, m.types);
4292     name = get_pointer_64(m.types + n_value, xoffset, left, xS, info);
4293     if (name != nullptr)
4294       outs() << format(" %.*s", left, name);
4295     outs() << "\n";
4296 
4297     outs() << indent << "\t\t       imp ";
4298     name = get_symbol_64(offset + offsetof(struct method64_t, imp), S, info,
4299                          n_value, m.imp);
4300     if (info->verbose && name == nullptr) {
4301       if (n_value != 0) {
4302         outs() << format("0x%" PRIx64, n_value) << " ";
4303         if (m.imp != 0)
4304           outs() << "+ " << format("0x%" PRIx64, m.imp) << " ";
4305       } else
4306         outs() << format("0x%" PRIx64, m.imp) << " ";
4307     }
4308     if (name != nullptr)
4309       outs() << name;
4310     outs() << "\n";
4311 
4312     p += sizeof(struct method64_t);
4313     offset += sizeof(struct method64_t);
4314   }
4315 }
4316 
4317 static void print_method_list32_t(uint64_t p, struct DisassembleInfo *info,
4318                                   const char *indent) {
4319   struct method_list32_t ml;
4320   struct method32_t m;
4321   const char *r, *name;
4322   uint32_t offset, xoffset, left, i;
4323   SectionRef S, xS;
4324 
4325   r = get_pointer_32(p, offset, left, S, info);
4326   if (r == nullptr)
4327     return;
4328   memset(&ml, '\0', sizeof(struct method_list32_t));
4329   if (left < sizeof(struct method_list32_t)) {
4330     memcpy(&ml, r, left);
4331     outs() << "   (method_list_t entends past the end of the section)\n";
4332   } else
4333     memcpy(&ml, r, sizeof(struct method_list32_t));
4334   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4335     swapStruct(ml);
4336   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
4337   outs() << indent << "\t\t     count " << ml.count << "\n";
4338 
4339   p += sizeof(struct method_list32_t);
4340   offset += sizeof(struct method_list32_t);
4341   for (i = 0; i < ml.count; i++) {
4342     r = get_pointer_32(p, offset, left, S, info);
4343     if (r == nullptr)
4344       return;
4345     memset(&m, '\0', sizeof(struct method32_t));
4346     if (left < sizeof(struct method32_t)) {
4347       memcpy(&ml, r, left);
4348       outs() << indent << "   (method_t entends past the end of the section)\n";
4349     } else
4350       memcpy(&m, r, sizeof(struct method32_t));
4351     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4352       swapStruct(m);
4353 
4354     outs() << indent << "\t\t      name " << format("0x%" PRIx32, m.name);
4355     name = get_pointer_32(m.name, xoffset, left, xS, info);
4356     if (name != nullptr)
4357       outs() << format(" %.*s", left, name);
4358     outs() << "\n";
4359 
4360     outs() << indent << "\t\t     types " << format("0x%" PRIx32, m.types);
4361     name = get_pointer_32(m.types, xoffset, left, xS, info);
4362     if (name != nullptr)
4363       outs() << format(" %.*s", left, name);
4364     outs() << "\n";
4365 
4366     outs() << indent << "\t\t       imp " << format("0x%" PRIx32, m.imp);
4367     name = get_symbol_32(offset + offsetof(struct method32_t, imp), S, info,
4368                          m.imp);
4369     if (name != nullptr)
4370       outs() << " " << name;
4371     outs() << "\n";
4372 
4373     p += sizeof(struct method32_t);
4374     offset += sizeof(struct method32_t);
4375   }
4376 }
4377 
4378 static bool print_method_list(uint32_t p, struct DisassembleInfo *info) {
4379   uint32_t offset, left, xleft;
4380   SectionRef S;
4381   struct objc_method_list_t method_list;
4382   struct objc_method_t method;
4383   const char *r, *methods, *name, *SymbolName;
4384   int32_t i;
4385 
4386   r = get_pointer_32(p, offset, left, S, info, true);
4387   if (r == nullptr)
4388     return true;
4389 
4390   outs() << "\n";
4391   if (left > sizeof(struct objc_method_list_t)) {
4392     memcpy(&method_list, r, sizeof(struct objc_method_list_t));
4393   } else {
4394     outs() << "\t\t objc_method_list extends past end of the section\n";
4395     memset(&method_list, '\0', sizeof(struct objc_method_list_t));
4396     memcpy(&method_list, r, left);
4397   }
4398   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4399     swapStruct(method_list);
4400 
4401   outs() << "\t\t         obsolete "
4402          << format("0x%08" PRIx32, method_list.obsolete) << "\n";
4403   outs() << "\t\t     method_count " << method_list.method_count << "\n";
4404 
4405   methods = r + sizeof(struct objc_method_list_t);
4406   for (i = 0; i < method_list.method_count; i++) {
4407     if ((i + 1) * sizeof(struct objc_method_t) > left) {
4408       outs() << "\t\t remaining method's extend past the of the section\n";
4409       break;
4410     }
4411     memcpy(&method, methods + i * sizeof(struct objc_method_t),
4412            sizeof(struct objc_method_t));
4413     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4414       swapStruct(method);
4415 
4416     outs() << "\t\t      method_name "
4417            << format("0x%08" PRIx32, method.method_name);
4418     if (info->verbose) {
4419       name = get_pointer_32(method.method_name, offset, xleft, S, info, true);
4420       if (name != nullptr)
4421         outs() << format(" %.*s", xleft, name);
4422       else
4423         outs() << " (not in an __OBJC section)";
4424     }
4425     outs() << "\n";
4426 
4427     outs() << "\t\t     method_types "
4428            << format("0x%08" PRIx32, method.method_types);
4429     if (info->verbose) {
4430       name = get_pointer_32(method.method_types, offset, xleft, S, info, true);
4431       if (name != nullptr)
4432         outs() << format(" %.*s", xleft, name);
4433       else
4434         outs() << " (not in an __OBJC section)";
4435     }
4436     outs() << "\n";
4437 
4438     outs() << "\t\t       method_imp "
4439            << format("0x%08" PRIx32, method.method_imp) << " ";
4440     if (info->verbose) {
4441       SymbolName = GuessSymbolName(method.method_imp, info->AddrMap);
4442       if (SymbolName != nullptr)
4443         outs() << SymbolName;
4444     }
4445     outs() << "\n";
4446   }
4447   return false;
4448 }
4449 
4450 static void print_protocol_list64_t(uint64_t p, struct DisassembleInfo *info) {
4451   struct protocol_list64_t pl;
4452   uint64_t q, n_value;
4453   struct protocol64_t pc;
4454   const char *r;
4455   uint32_t offset, xoffset, left, i;
4456   SectionRef S, xS;
4457   const char *name, *sym_name;
4458 
4459   r = get_pointer_64(p, offset, left, S, info);
4460   if (r == nullptr)
4461     return;
4462   memset(&pl, '\0', sizeof(struct protocol_list64_t));
4463   if (left < sizeof(struct protocol_list64_t)) {
4464     memcpy(&pl, r, left);
4465     outs() << "   (protocol_list_t entends past the end of the section)\n";
4466   } else
4467     memcpy(&pl, r, sizeof(struct protocol_list64_t));
4468   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4469     swapStruct(pl);
4470   outs() << "                      count " << pl.count << "\n";
4471 
4472   p += sizeof(struct protocol_list64_t);
4473   offset += sizeof(struct protocol_list64_t);
4474   for (i = 0; i < pl.count; i++) {
4475     r = get_pointer_64(p, offset, left, S, info);
4476     if (r == nullptr)
4477       return;
4478     q = 0;
4479     if (left < sizeof(uint64_t)) {
4480       memcpy(&q, r, left);
4481       outs() << "   (protocol_t * entends past the end of the section)\n";
4482     } else
4483       memcpy(&q, r, sizeof(uint64_t));
4484     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4485       sys::swapByteOrder(q);
4486 
4487     outs() << "\t\t      list[" << i << "] ";
4488     sym_name = get_symbol_64(offset, S, info, n_value, q);
4489     if (n_value != 0) {
4490       if (info->verbose && sym_name != nullptr)
4491         outs() << sym_name;
4492       else
4493         outs() << format("0x%" PRIx64, n_value);
4494       if (q != 0)
4495         outs() << " + " << format("0x%" PRIx64, q);
4496     } else
4497       outs() << format("0x%" PRIx64, q);
4498     outs() << " (struct protocol_t *)\n";
4499 
4500     r = get_pointer_64(q + n_value, offset, left, S, info);
4501     if (r == nullptr)
4502       return;
4503     memset(&pc, '\0', sizeof(struct protocol64_t));
4504     if (left < sizeof(struct protocol64_t)) {
4505       memcpy(&pc, r, left);
4506       outs() << "   (protocol_t entends past the end of the section)\n";
4507     } else
4508       memcpy(&pc, r, sizeof(struct protocol64_t));
4509     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4510       swapStruct(pc);
4511 
4512     outs() << "\t\t\t      isa " << format("0x%" PRIx64, pc.isa) << "\n";
4513 
4514     outs() << "\t\t\t     name ";
4515     sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, name), S,
4516                              info, n_value, pc.name);
4517     if (n_value != 0) {
4518       if (info->verbose && sym_name != nullptr)
4519         outs() << sym_name;
4520       else
4521         outs() << format("0x%" PRIx64, n_value);
4522       if (pc.name != 0)
4523         outs() << " + " << format("0x%" PRIx64, pc.name);
4524     } else
4525       outs() << format("0x%" PRIx64, pc.name);
4526     name = get_pointer_64(pc.name + n_value, xoffset, left, xS, info);
4527     if (name != nullptr)
4528       outs() << format(" %.*s", left, name);
4529     outs() << "\n";
4530 
4531     outs() << "\t\t\tprotocols " << format("0x%" PRIx64, pc.protocols) << "\n";
4532 
4533     outs() << "\t\t  instanceMethods ";
4534     sym_name =
4535         get_symbol_64(offset + offsetof(struct protocol64_t, instanceMethods),
4536                       S, info, n_value, pc.instanceMethods);
4537     if (n_value != 0) {
4538       if (info->verbose && sym_name != nullptr)
4539         outs() << sym_name;
4540       else
4541         outs() << format("0x%" PRIx64, n_value);
4542       if (pc.instanceMethods != 0)
4543         outs() << " + " << format("0x%" PRIx64, pc.instanceMethods);
4544     } else
4545       outs() << format("0x%" PRIx64, pc.instanceMethods);
4546     outs() << " (struct method_list_t *)\n";
4547     if (pc.instanceMethods + n_value != 0)
4548       print_method_list64_t(pc.instanceMethods + n_value, info, "\t");
4549 
4550     outs() << "\t\t     classMethods ";
4551     sym_name =
4552         get_symbol_64(offset + offsetof(struct protocol64_t, classMethods), S,
4553                       info, n_value, pc.classMethods);
4554     if (n_value != 0) {
4555       if (info->verbose && sym_name != nullptr)
4556         outs() << sym_name;
4557       else
4558         outs() << format("0x%" PRIx64, n_value);
4559       if (pc.classMethods != 0)
4560         outs() << " + " << format("0x%" PRIx64, pc.classMethods);
4561     } else
4562       outs() << format("0x%" PRIx64, pc.classMethods);
4563     outs() << " (struct method_list_t *)\n";
4564     if (pc.classMethods + n_value != 0)
4565       print_method_list64_t(pc.classMethods + n_value, info, "\t");
4566 
4567     outs() << "\t  optionalInstanceMethods "
4568            << format("0x%" PRIx64, pc.optionalInstanceMethods) << "\n";
4569     outs() << "\t     optionalClassMethods "
4570            << format("0x%" PRIx64, pc.optionalClassMethods) << "\n";
4571     outs() << "\t       instanceProperties "
4572            << format("0x%" PRIx64, pc.instanceProperties) << "\n";
4573 
4574     p += sizeof(uint64_t);
4575     offset += sizeof(uint64_t);
4576   }
4577 }
4578 
4579 static void print_protocol_list32_t(uint32_t p, struct DisassembleInfo *info) {
4580   struct protocol_list32_t pl;
4581   uint32_t q;
4582   struct protocol32_t pc;
4583   const char *r;
4584   uint32_t offset, xoffset, left, i;
4585   SectionRef S, xS;
4586   const char *name;
4587 
4588   r = get_pointer_32(p, offset, left, S, info);
4589   if (r == nullptr)
4590     return;
4591   memset(&pl, '\0', sizeof(struct protocol_list32_t));
4592   if (left < sizeof(struct protocol_list32_t)) {
4593     memcpy(&pl, r, left);
4594     outs() << "   (protocol_list_t entends past the end of the section)\n";
4595   } else
4596     memcpy(&pl, r, sizeof(struct protocol_list32_t));
4597   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4598     swapStruct(pl);
4599   outs() << "                      count " << pl.count << "\n";
4600 
4601   p += sizeof(struct protocol_list32_t);
4602   offset += sizeof(struct protocol_list32_t);
4603   for (i = 0; i < pl.count; i++) {
4604     r = get_pointer_32(p, offset, left, S, info);
4605     if (r == nullptr)
4606       return;
4607     q = 0;
4608     if (left < sizeof(uint32_t)) {
4609       memcpy(&q, r, left);
4610       outs() << "   (protocol_t * entends past the end of the section)\n";
4611     } else
4612       memcpy(&q, r, sizeof(uint32_t));
4613     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4614       sys::swapByteOrder(q);
4615     outs() << "\t\t      list[" << i << "] " << format("0x%" PRIx32, q)
4616            << " (struct protocol_t *)\n";
4617     r = get_pointer_32(q, offset, left, S, info);
4618     if (r == nullptr)
4619       return;
4620     memset(&pc, '\0', sizeof(struct protocol32_t));
4621     if (left < sizeof(struct protocol32_t)) {
4622       memcpy(&pc, r, left);
4623       outs() << "   (protocol_t entends past the end of the section)\n";
4624     } else
4625       memcpy(&pc, r, sizeof(struct protocol32_t));
4626     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4627       swapStruct(pc);
4628     outs() << "\t\t\t      isa " << format("0x%" PRIx32, pc.isa) << "\n";
4629     outs() << "\t\t\t     name " << format("0x%" PRIx32, pc.name);
4630     name = get_pointer_32(pc.name, xoffset, left, xS, info);
4631     if (name != nullptr)
4632       outs() << format(" %.*s", left, name);
4633     outs() << "\n";
4634     outs() << "\t\t\tprotocols " << format("0x%" PRIx32, pc.protocols) << "\n";
4635     outs() << "\t\t  instanceMethods "
4636            << format("0x%" PRIx32, pc.instanceMethods)
4637            << " (struct method_list_t *)\n";
4638     if (pc.instanceMethods != 0)
4639       print_method_list32_t(pc.instanceMethods, info, "\t");
4640     outs() << "\t\t     classMethods " << format("0x%" PRIx32, pc.classMethods)
4641            << " (struct method_list_t *)\n";
4642     if (pc.classMethods != 0)
4643       print_method_list32_t(pc.classMethods, info, "\t");
4644     outs() << "\t  optionalInstanceMethods "
4645            << format("0x%" PRIx32, pc.optionalInstanceMethods) << "\n";
4646     outs() << "\t     optionalClassMethods "
4647            << format("0x%" PRIx32, pc.optionalClassMethods) << "\n";
4648     outs() << "\t       instanceProperties "
4649            << format("0x%" PRIx32, pc.instanceProperties) << "\n";
4650     p += sizeof(uint32_t);
4651     offset += sizeof(uint32_t);
4652   }
4653 }
4654 
4655 static void print_indent(uint32_t indent) {
4656   for (uint32_t i = 0; i < indent;) {
4657     if (indent - i >= 8) {
4658       outs() << "\t";
4659       i += 8;
4660     } else {
4661       for (uint32_t j = i; j < indent; j++)
4662         outs() << " ";
4663       return;
4664     }
4665   }
4666 }
4667 
4668 static bool print_method_description_list(uint32_t p, uint32_t indent,
4669                                           struct DisassembleInfo *info) {
4670   uint32_t offset, left, xleft;
4671   SectionRef S;
4672   struct objc_method_description_list_t mdl;
4673   struct objc_method_description_t md;
4674   const char *r, *list, *name;
4675   int32_t i;
4676 
4677   r = get_pointer_32(p, offset, left, S, info, true);
4678   if (r == nullptr)
4679     return true;
4680 
4681   outs() << "\n";
4682   if (left > sizeof(struct objc_method_description_list_t)) {
4683     memcpy(&mdl, r, sizeof(struct objc_method_description_list_t));
4684   } else {
4685     print_indent(indent);
4686     outs() << " objc_method_description_list extends past end of the section\n";
4687     memset(&mdl, '\0', sizeof(struct objc_method_description_list_t));
4688     memcpy(&mdl, r, left);
4689   }
4690   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4691     swapStruct(mdl);
4692 
4693   print_indent(indent);
4694   outs() << "        count " << mdl.count << "\n";
4695 
4696   list = r + sizeof(struct objc_method_description_list_t);
4697   for (i = 0; i < mdl.count; i++) {
4698     if ((i + 1) * sizeof(struct objc_method_description_t) > left) {
4699       print_indent(indent);
4700       outs() << " remaining list entries extend past the of the section\n";
4701       break;
4702     }
4703     print_indent(indent);
4704     outs() << "        list[" << i << "]\n";
4705     memcpy(&md, list + i * sizeof(struct objc_method_description_t),
4706            sizeof(struct objc_method_description_t));
4707     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4708       swapStruct(md);
4709 
4710     print_indent(indent);
4711     outs() << "             name " << format("0x%08" PRIx32, md.name);
4712     if (info->verbose) {
4713       name = get_pointer_32(md.name, offset, xleft, S, info, true);
4714       if (name != nullptr)
4715         outs() << format(" %.*s", xleft, name);
4716       else
4717         outs() << " (not in an __OBJC section)";
4718     }
4719     outs() << "\n";
4720 
4721     print_indent(indent);
4722     outs() << "            types " << format("0x%08" PRIx32, md.types);
4723     if (info->verbose) {
4724       name = get_pointer_32(md.types, offset, xleft, S, info, true);
4725       if (name != nullptr)
4726         outs() << format(" %.*s", xleft, name);
4727       else
4728         outs() << " (not in an __OBJC section)";
4729     }
4730     outs() << "\n";
4731   }
4732   return false;
4733 }
4734 
4735 static bool print_protocol_list(uint32_t p, uint32_t indent,
4736                                 struct DisassembleInfo *info);
4737 
4738 static bool print_protocol(uint32_t p, uint32_t indent,
4739                            struct DisassembleInfo *info) {
4740   uint32_t offset, left;
4741   SectionRef S;
4742   struct objc_protocol_t protocol;
4743   const char *r, *name;
4744 
4745   r = get_pointer_32(p, offset, left, S, info, true);
4746   if (r == nullptr)
4747     return true;
4748 
4749   outs() << "\n";
4750   if (left >= sizeof(struct objc_protocol_t)) {
4751     memcpy(&protocol, r, sizeof(struct objc_protocol_t));
4752   } else {
4753     print_indent(indent);
4754     outs() << "            Protocol extends past end of the section\n";
4755     memset(&protocol, '\0', sizeof(struct objc_protocol_t));
4756     memcpy(&protocol, r, left);
4757   }
4758   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4759     swapStruct(protocol);
4760 
4761   print_indent(indent);
4762   outs() << "              isa " << format("0x%08" PRIx32, protocol.isa)
4763          << "\n";
4764 
4765   print_indent(indent);
4766   outs() << "    protocol_name "
4767          << format("0x%08" PRIx32, protocol.protocol_name);
4768   if (info->verbose) {
4769     name = get_pointer_32(protocol.protocol_name, offset, left, S, info, true);
4770     if (name != nullptr)
4771       outs() << format(" %.*s", left, name);
4772     else
4773       outs() << " (not in an __OBJC section)";
4774   }
4775   outs() << "\n";
4776 
4777   print_indent(indent);
4778   outs() << "    protocol_list "
4779          << format("0x%08" PRIx32, protocol.protocol_list);
4780   if (print_protocol_list(protocol.protocol_list, indent + 4, info))
4781     outs() << " (not in an __OBJC section)\n";
4782 
4783   print_indent(indent);
4784   outs() << " instance_methods "
4785          << format("0x%08" PRIx32, protocol.instance_methods);
4786   if (print_method_description_list(protocol.instance_methods, indent, info))
4787     outs() << " (not in an __OBJC section)\n";
4788 
4789   print_indent(indent);
4790   outs() << "    class_methods "
4791          << format("0x%08" PRIx32, protocol.class_methods);
4792   if (print_method_description_list(protocol.class_methods, indent, info))
4793     outs() << " (not in an __OBJC section)\n";
4794 
4795   return false;
4796 }
4797 
4798 static bool print_protocol_list(uint32_t p, uint32_t indent,
4799                                 struct DisassembleInfo *info) {
4800   uint32_t offset, left, l;
4801   SectionRef S;
4802   struct objc_protocol_list_t protocol_list;
4803   const char *r, *list;
4804   int32_t i;
4805 
4806   r = get_pointer_32(p, offset, left, S, info, true);
4807   if (r == nullptr)
4808     return true;
4809 
4810   outs() << "\n";
4811   if (left > sizeof(struct objc_protocol_list_t)) {
4812     memcpy(&protocol_list, r, sizeof(struct objc_protocol_list_t));
4813   } else {
4814     outs() << "\t\t objc_protocol_list_t extends past end of the section\n";
4815     memset(&protocol_list, '\0', sizeof(struct objc_protocol_list_t));
4816     memcpy(&protocol_list, r, left);
4817   }
4818   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4819     swapStruct(protocol_list);
4820 
4821   print_indent(indent);
4822   outs() << "         next " << format("0x%08" PRIx32, protocol_list.next)
4823          << "\n";
4824   print_indent(indent);
4825   outs() << "        count " << protocol_list.count << "\n";
4826 
4827   list = r + sizeof(struct objc_protocol_list_t);
4828   for (i = 0; i < protocol_list.count; i++) {
4829     if ((i + 1) * sizeof(uint32_t) > left) {
4830       outs() << "\t\t remaining list entries extend past the of the section\n";
4831       break;
4832     }
4833     memcpy(&l, list + i * sizeof(uint32_t), sizeof(uint32_t));
4834     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4835       sys::swapByteOrder(l);
4836 
4837     print_indent(indent);
4838     outs() << "      list[" << i << "] " << format("0x%08" PRIx32, l);
4839     if (print_protocol(l, indent, info))
4840       outs() << "(not in an __OBJC section)\n";
4841   }
4842   return false;
4843 }
4844 
4845 static void print_ivar_list64_t(uint64_t p, struct DisassembleInfo *info) {
4846   struct ivar_list64_t il;
4847   struct ivar64_t i;
4848   const char *r;
4849   uint32_t offset, xoffset, left, j;
4850   SectionRef S, xS;
4851   const char *name, *sym_name, *ivar_offset_p;
4852   uint64_t ivar_offset, n_value;
4853 
4854   r = get_pointer_64(p, offset, left, S, info);
4855   if (r == nullptr)
4856     return;
4857   memset(&il, '\0', sizeof(struct ivar_list64_t));
4858   if (left < sizeof(struct ivar_list64_t)) {
4859     memcpy(&il, r, left);
4860     outs() << "   (ivar_list_t entends past the end of the section)\n";
4861   } else
4862     memcpy(&il, r, sizeof(struct ivar_list64_t));
4863   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4864     swapStruct(il);
4865   outs() << "                    entsize " << il.entsize << "\n";
4866   outs() << "                      count " << il.count << "\n";
4867 
4868   p += sizeof(struct ivar_list64_t);
4869   offset += sizeof(struct ivar_list64_t);
4870   for (j = 0; j < il.count; j++) {
4871     r = get_pointer_64(p, offset, left, S, info);
4872     if (r == nullptr)
4873       return;
4874     memset(&i, '\0', sizeof(struct ivar64_t));
4875     if (left < sizeof(struct ivar64_t)) {
4876       memcpy(&i, r, left);
4877       outs() << "   (ivar_t entends past the end of the section)\n";
4878     } else
4879       memcpy(&i, r, sizeof(struct ivar64_t));
4880     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4881       swapStruct(i);
4882 
4883     outs() << "\t\t\t   offset ";
4884     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, offset), S,
4885                              info, n_value, i.offset);
4886     if (n_value != 0) {
4887       if (info->verbose && sym_name != nullptr)
4888         outs() << sym_name;
4889       else
4890         outs() << format("0x%" PRIx64, n_value);
4891       if (i.offset != 0)
4892         outs() << " + " << format("0x%" PRIx64, i.offset);
4893     } else
4894       outs() << format("0x%" PRIx64, i.offset);
4895     ivar_offset_p = get_pointer_64(i.offset + n_value, xoffset, left, xS, info);
4896     if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
4897       memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
4898       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4899         sys::swapByteOrder(ivar_offset);
4900       outs() << " " << ivar_offset << "\n";
4901     } else
4902       outs() << "\n";
4903 
4904     outs() << "\t\t\t     name ";
4905     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, name), S, info,
4906                              n_value, i.name);
4907     if (n_value != 0) {
4908       if (info->verbose && sym_name != nullptr)
4909         outs() << sym_name;
4910       else
4911         outs() << format("0x%" PRIx64, n_value);
4912       if (i.name != 0)
4913         outs() << " + " << format("0x%" PRIx64, i.name);
4914     } else
4915       outs() << format("0x%" PRIx64, i.name);
4916     name = get_pointer_64(i.name + n_value, xoffset, left, xS, info);
4917     if (name != nullptr)
4918       outs() << format(" %.*s", left, name);
4919     outs() << "\n";
4920 
4921     outs() << "\t\t\t     type ";
4922     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, type), S, info,
4923                              n_value, i.name);
4924     name = get_pointer_64(i.type + n_value, xoffset, left, xS, info);
4925     if (n_value != 0) {
4926       if (info->verbose && sym_name != nullptr)
4927         outs() << sym_name;
4928       else
4929         outs() << format("0x%" PRIx64, n_value);
4930       if (i.type != 0)
4931         outs() << " + " << format("0x%" PRIx64, i.type);
4932     } else
4933       outs() << format("0x%" PRIx64, i.type);
4934     if (name != nullptr)
4935       outs() << format(" %.*s", left, name);
4936     outs() << "\n";
4937 
4938     outs() << "\t\t\talignment " << i.alignment << "\n";
4939     outs() << "\t\t\t     size " << i.size << "\n";
4940 
4941     p += sizeof(struct ivar64_t);
4942     offset += sizeof(struct ivar64_t);
4943   }
4944 }
4945 
4946 static void print_ivar_list32_t(uint32_t p, struct DisassembleInfo *info) {
4947   struct ivar_list32_t il;
4948   struct ivar32_t i;
4949   const char *r;
4950   uint32_t offset, xoffset, left, j;
4951   SectionRef S, xS;
4952   const char *name, *ivar_offset_p;
4953   uint32_t ivar_offset;
4954 
4955   r = get_pointer_32(p, offset, left, S, info);
4956   if (r == nullptr)
4957     return;
4958   memset(&il, '\0', sizeof(struct ivar_list32_t));
4959   if (left < sizeof(struct ivar_list32_t)) {
4960     memcpy(&il, r, left);
4961     outs() << "   (ivar_list_t entends past the end of the section)\n";
4962   } else
4963     memcpy(&il, r, sizeof(struct ivar_list32_t));
4964   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4965     swapStruct(il);
4966   outs() << "                    entsize " << il.entsize << "\n";
4967   outs() << "                      count " << il.count << "\n";
4968 
4969   p += sizeof(struct ivar_list32_t);
4970   offset += sizeof(struct ivar_list32_t);
4971   for (j = 0; j < il.count; j++) {
4972     r = get_pointer_32(p, offset, left, S, info);
4973     if (r == nullptr)
4974       return;
4975     memset(&i, '\0', sizeof(struct ivar32_t));
4976     if (left < sizeof(struct ivar32_t)) {
4977       memcpy(&i, r, left);
4978       outs() << "   (ivar_t entends past the end of the section)\n";
4979     } else
4980       memcpy(&i, r, sizeof(struct ivar32_t));
4981     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4982       swapStruct(i);
4983 
4984     outs() << "\t\t\t   offset " << format("0x%" PRIx32, i.offset);
4985     ivar_offset_p = get_pointer_32(i.offset, xoffset, left, xS, info);
4986     if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
4987       memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
4988       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
4989         sys::swapByteOrder(ivar_offset);
4990       outs() << " " << ivar_offset << "\n";
4991     } else
4992       outs() << "\n";
4993 
4994     outs() << "\t\t\t     name " << format("0x%" PRIx32, i.name);
4995     name = get_pointer_32(i.name, xoffset, left, xS, info);
4996     if (name != nullptr)
4997       outs() << format(" %.*s", left, name);
4998     outs() << "\n";
4999 
5000     outs() << "\t\t\t     type " << format("0x%" PRIx32, i.type);
5001     name = get_pointer_32(i.type, xoffset, left, xS, info);
5002     if (name != nullptr)
5003       outs() << format(" %.*s", left, name);
5004     outs() << "\n";
5005 
5006     outs() << "\t\t\talignment " << i.alignment << "\n";
5007     outs() << "\t\t\t     size " << i.size << "\n";
5008 
5009     p += sizeof(struct ivar32_t);
5010     offset += sizeof(struct ivar32_t);
5011   }
5012 }
5013 
5014 static void print_objc_property_list64(uint64_t p,
5015                                        struct DisassembleInfo *info) {
5016   struct objc_property_list64 opl;
5017   struct objc_property64 op;
5018   const char *r;
5019   uint32_t offset, xoffset, left, j;
5020   SectionRef S, xS;
5021   const char *name, *sym_name;
5022   uint64_t n_value;
5023 
5024   r = get_pointer_64(p, offset, left, S, info);
5025   if (r == nullptr)
5026     return;
5027   memset(&opl, '\0', sizeof(struct objc_property_list64));
5028   if (left < sizeof(struct objc_property_list64)) {
5029     memcpy(&opl, r, left);
5030     outs() << "   (objc_property_list entends past the end of the section)\n";
5031   } else
5032     memcpy(&opl, r, sizeof(struct objc_property_list64));
5033   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5034     swapStruct(opl);
5035   outs() << "                    entsize " << opl.entsize << "\n";
5036   outs() << "                      count " << opl.count << "\n";
5037 
5038   p += sizeof(struct objc_property_list64);
5039   offset += sizeof(struct objc_property_list64);
5040   for (j = 0; j < opl.count; j++) {
5041     r = get_pointer_64(p, offset, left, S, info);
5042     if (r == nullptr)
5043       return;
5044     memset(&op, '\0', sizeof(struct objc_property64));
5045     if (left < sizeof(struct objc_property64)) {
5046       memcpy(&op, r, left);
5047       outs() << "   (objc_property entends past the end of the section)\n";
5048     } else
5049       memcpy(&op, r, sizeof(struct objc_property64));
5050     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5051       swapStruct(op);
5052 
5053     outs() << "\t\t\t     name ";
5054     sym_name = get_symbol_64(offset + offsetof(struct objc_property64, name), S,
5055                              info, n_value, op.name);
5056     if (n_value != 0) {
5057       if (info->verbose && sym_name != nullptr)
5058         outs() << sym_name;
5059       else
5060         outs() << format("0x%" PRIx64, n_value);
5061       if (op.name != 0)
5062         outs() << " + " << format("0x%" PRIx64, op.name);
5063     } else
5064       outs() << format("0x%" PRIx64, op.name);
5065     name = get_pointer_64(op.name + n_value, xoffset, left, xS, info);
5066     if (name != nullptr)
5067       outs() << format(" %.*s", left, name);
5068     outs() << "\n";
5069 
5070     outs() << "\t\t\tattributes ";
5071     sym_name =
5072         get_symbol_64(offset + offsetof(struct objc_property64, attributes), S,
5073                       info, n_value, op.attributes);
5074     if (n_value != 0) {
5075       if (info->verbose && sym_name != nullptr)
5076         outs() << sym_name;
5077       else
5078         outs() << format("0x%" PRIx64, n_value);
5079       if (op.attributes != 0)
5080         outs() << " + " << format("0x%" PRIx64, op.attributes);
5081     } else
5082       outs() << format("0x%" PRIx64, op.attributes);
5083     name = get_pointer_64(op.attributes + n_value, xoffset, left, xS, info);
5084     if (name != nullptr)
5085       outs() << format(" %.*s", left, name);
5086     outs() << "\n";
5087 
5088     p += sizeof(struct objc_property64);
5089     offset += sizeof(struct objc_property64);
5090   }
5091 }
5092 
5093 static void print_objc_property_list32(uint32_t p,
5094                                        struct DisassembleInfo *info) {
5095   struct objc_property_list32 opl;
5096   struct objc_property32 op;
5097   const char *r;
5098   uint32_t offset, xoffset, left, j;
5099   SectionRef S, xS;
5100   const char *name;
5101 
5102   r = get_pointer_32(p, offset, left, S, info);
5103   if (r == nullptr)
5104     return;
5105   memset(&opl, '\0', sizeof(struct objc_property_list32));
5106   if (left < sizeof(struct objc_property_list32)) {
5107     memcpy(&opl, r, left);
5108     outs() << "   (objc_property_list entends past the end of the section)\n";
5109   } else
5110     memcpy(&opl, r, sizeof(struct objc_property_list32));
5111   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5112     swapStruct(opl);
5113   outs() << "                    entsize " << opl.entsize << "\n";
5114   outs() << "                      count " << opl.count << "\n";
5115 
5116   p += sizeof(struct objc_property_list32);
5117   offset += sizeof(struct objc_property_list32);
5118   for (j = 0; j < opl.count; j++) {
5119     r = get_pointer_32(p, offset, left, S, info);
5120     if (r == nullptr)
5121       return;
5122     memset(&op, '\0', sizeof(struct objc_property32));
5123     if (left < sizeof(struct objc_property32)) {
5124       memcpy(&op, r, left);
5125       outs() << "   (objc_property entends past the end of the section)\n";
5126     } else
5127       memcpy(&op, r, sizeof(struct objc_property32));
5128     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5129       swapStruct(op);
5130 
5131     outs() << "\t\t\t     name " << format("0x%" PRIx32, op.name);
5132     name = get_pointer_32(op.name, xoffset, left, xS, info);
5133     if (name != nullptr)
5134       outs() << format(" %.*s", left, name);
5135     outs() << "\n";
5136 
5137     outs() << "\t\t\tattributes " << format("0x%" PRIx32, op.attributes);
5138     name = get_pointer_32(op.attributes, xoffset, left, xS, info);
5139     if (name != nullptr)
5140       outs() << format(" %.*s", left, name);
5141     outs() << "\n";
5142 
5143     p += sizeof(struct objc_property32);
5144     offset += sizeof(struct objc_property32);
5145   }
5146 }
5147 
5148 static bool print_class_ro64_t(uint64_t p, struct DisassembleInfo *info,
5149                                bool &is_meta_class) {
5150   struct class_ro64_t cro;
5151   const char *r;
5152   uint32_t offset, xoffset, left;
5153   SectionRef S, xS;
5154   const char *name, *sym_name;
5155   uint64_t n_value;
5156 
5157   r = get_pointer_64(p, offset, left, S, info);
5158   if (r == nullptr || left < sizeof(struct class_ro64_t))
5159     return false;
5160   memcpy(&cro, r, sizeof(struct class_ro64_t));
5161   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5162     swapStruct(cro);
5163   outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
5164   if (cro.flags & RO_META)
5165     outs() << " RO_META";
5166   if (cro.flags & RO_ROOT)
5167     outs() << " RO_ROOT";
5168   if (cro.flags & RO_HAS_CXX_STRUCTORS)
5169     outs() << " RO_HAS_CXX_STRUCTORS";
5170   outs() << "\n";
5171   outs() << "            instanceStart " << cro.instanceStart << "\n";
5172   outs() << "             instanceSize " << cro.instanceSize << "\n";
5173   outs() << "                 reserved " << format("0x%" PRIx32, cro.reserved)
5174          << "\n";
5175   outs() << "               ivarLayout " << format("0x%" PRIx64, cro.ivarLayout)
5176          << "\n";
5177   print_layout_map64(cro.ivarLayout, info);
5178 
5179   outs() << "                     name ";
5180   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, name), S,
5181                            info, n_value, cro.name);
5182   if (n_value != 0) {
5183     if (info->verbose && sym_name != nullptr)
5184       outs() << sym_name;
5185     else
5186       outs() << format("0x%" PRIx64, n_value);
5187     if (cro.name != 0)
5188       outs() << " + " << format("0x%" PRIx64, cro.name);
5189   } else
5190     outs() << format("0x%" PRIx64, cro.name);
5191   name = get_pointer_64(cro.name + n_value, xoffset, left, xS, info);
5192   if (name != nullptr)
5193     outs() << format(" %.*s", left, name);
5194   outs() << "\n";
5195 
5196   outs() << "              baseMethods ";
5197   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, baseMethods),
5198                            S, info, n_value, cro.baseMethods);
5199   if (n_value != 0) {
5200     if (info->verbose && sym_name != nullptr)
5201       outs() << sym_name;
5202     else
5203       outs() << format("0x%" PRIx64, n_value);
5204     if (cro.baseMethods != 0)
5205       outs() << " + " << format("0x%" PRIx64, cro.baseMethods);
5206   } else
5207     outs() << format("0x%" PRIx64, cro.baseMethods);
5208   outs() << " (struct method_list_t *)\n";
5209   if (cro.baseMethods + n_value != 0)
5210     print_method_list64_t(cro.baseMethods + n_value, info, "");
5211 
5212   outs() << "            baseProtocols ";
5213   sym_name =
5214       get_symbol_64(offset + offsetof(struct class_ro64_t, baseProtocols), S,
5215                     info, n_value, cro.baseProtocols);
5216   if (n_value != 0) {
5217     if (info->verbose && sym_name != nullptr)
5218       outs() << sym_name;
5219     else
5220       outs() << format("0x%" PRIx64, n_value);
5221     if (cro.baseProtocols != 0)
5222       outs() << " + " << format("0x%" PRIx64, cro.baseProtocols);
5223   } else
5224     outs() << format("0x%" PRIx64, cro.baseProtocols);
5225   outs() << "\n";
5226   if (cro.baseProtocols + n_value != 0)
5227     print_protocol_list64_t(cro.baseProtocols + n_value, info);
5228 
5229   outs() << "                    ivars ";
5230   sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, ivars), S,
5231                            info, n_value, cro.ivars);
5232   if (n_value != 0) {
5233     if (info->verbose && sym_name != nullptr)
5234       outs() << sym_name;
5235     else
5236       outs() << format("0x%" PRIx64, n_value);
5237     if (cro.ivars != 0)
5238       outs() << " + " << format("0x%" PRIx64, cro.ivars);
5239   } else
5240     outs() << format("0x%" PRIx64, cro.ivars);
5241   outs() << "\n";
5242   if (cro.ivars + n_value != 0)
5243     print_ivar_list64_t(cro.ivars + n_value, info);
5244 
5245   outs() << "           weakIvarLayout ";
5246   sym_name =
5247       get_symbol_64(offset + offsetof(struct class_ro64_t, weakIvarLayout), S,
5248                     info, n_value, cro.weakIvarLayout);
5249   if (n_value != 0) {
5250     if (info->verbose && sym_name != nullptr)
5251       outs() << sym_name;
5252     else
5253       outs() << format("0x%" PRIx64, n_value);
5254     if (cro.weakIvarLayout != 0)
5255       outs() << " + " << format("0x%" PRIx64, cro.weakIvarLayout);
5256   } else
5257     outs() << format("0x%" PRIx64, cro.weakIvarLayout);
5258   outs() << "\n";
5259   print_layout_map64(cro.weakIvarLayout + n_value, info);
5260 
5261   outs() << "           baseProperties ";
5262   sym_name =
5263       get_symbol_64(offset + offsetof(struct class_ro64_t, baseProperties), S,
5264                     info, n_value, cro.baseProperties);
5265   if (n_value != 0) {
5266     if (info->verbose && sym_name != nullptr)
5267       outs() << sym_name;
5268     else
5269       outs() << format("0x%" PRIx64, n_value);
5270     if (cro.baseProperties != 0)
5271       outs() << " + " << format("0x%" PRIx64, cro.baseProperties);
5272   } else
5273     outs() << format("0x%" PRIx64, cro.baseProperties);
5274   outs() << "\n";
5275   if (cro.baseProperties + n_value != 0)
5276     print_objc_property_list64(cro.baseProperties + n_value, info);
5277 
5278   is_meta_class = (cro.flags & RO_META) != 0;
5279   return true;
5280 }
5281 
5282 static bool print_class_ro32_t(uint32_t p, struct DisassembleInfo *info,
5283                                bool &is_meta_class) {
5284   struct class_ro32_t cro;
5285   const char *r;
5286   uint32_t offset, xoffset, left;
5287   SectionRef S, xS;
5288   const char *name;
5289 
5290   r = get_pointer_32(p, offset, left, S, info);
5291   if (r == nullptr)
5292     return false;
5293   memset(&cro, '\0', sizeof(struct class_ro32_t));
5294   if (left < sizeof(struct class_ro32_t)) {
5295     memcpy(&cro, r, left);
5296     outs() << "   (class_ro_t entends past the end of the section)\n";
5297   } else
5298     memcpy(&cro, r, sizeof(struct class_ro32_t));
5299   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5300     swapStruct(cro);
5301   outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
5302   if (cro.flags & RO_META)
5303     outs() << " RO_META";
5304   if (cro.flags & RO_ROOT)
5305     outs() << " RO_ROOT";
5306   if (cro.flags & RO_HAS_CXX_STRUCTORS)
5307     outs() << " RO_HAS_CXX_STRUCTORS";
5308   outs() << "\n";
5309   outs() << "            instanceStart " << cro.instanceStart << "\n";
5310   outs() << "             instanceSize " << cro.instanceSize << "\n";
5311   outs() << "               ivarLayout " << format("0x%" PRIx32, cro.ivarLayout)
5312          << "\n";
5313   print_layout_map32(cro.ivarLayout, info);
5314 
5315   outs() << "                     name " << format("0x%" PRIx32, cro.name);
5316   name = get_pointer_32(cro.name, xoffset, left, xS, info);
5317   if (name != nullptr)
5318     outs() << format(" %.*s", left, name);
5319   outs() << "\n";
5320 
5321   outs() << "              baseMethods "
5322          << format("0x%" PRIx32, cro.baseMethods)
5323          << " (struct method_list_t *)\n";
5324   if (cro.baseMethods != 0)
5325     print_method_list32_t(cro.baseMethods, info, "");
5326 
5327   outs() << "            baseProtocols "
5328          << format("0x%" PRIx32, cro.baseProtocols) << "\n";
5329   if (cro.baseProtocols != 0)
5330     print_protocol_list32_t(cro.baseProtocols, info);
5331   outs() << "                    ivars " << format("0x%" PRIx32, cro.ivars)
5332          << "\n";
5333   if (cro.ivars != 0)
5334     print_ivar_list32_t(cro.ivars, info);
5335   outs() << "           weakIvarLayout "
5336          << format("0x%" PRIx32, cro.weakIvarLayout) << "\n";
5337   print_layout_map32(cro.weakIvarLayout, info);
5338   outs() << "           baseProperties "
5339          << format("0x%" PRIx32, cro.baseProperties) << "\n";
5340   if (cro.baseProperties != 0)
5341     print_objc_property_list32(cro.baseProperties, info);
5342   is_meta_class = (cro.flags & RO_META) != 0;
5343   return true;
5344 }
5345 
5346 static void print_class64_t(uint64_t p, struct DisassembleInfo *info) {
5347   struct class64_t c;
5348   const char *r;
5349   uint32_t offset, left;
5350   SectionRef S;
5351   const char *name;
5352   uint64_t isa_n_value, n_value;
5353 
5354   r = get_pointer_64(p, offset, left, S, info);
5355   if (r == nullptr || left < sizeof(struct class64_t))
5356     return;
5357   memcpy(&c, r, sizeof(struct class64_t));
5358   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5359     swapStruct(c);
5360 
5361   outs() << "           isa " << format("0x%" PRIx64, c.isa);
5362   name = get_symbol_64(offset + offsetof(struct class64_t, isa), S, info,
5363                        isa_n_value, c.isa);
5364   if (name != nullptr)
5365     outs() << " " << name;
5366   outs() << "\n";
5367 
5368   outs() << "    superclass " << format("0x%" PRIx64, c.superclass);
5369   name = get_symbol_64(offset + offsetof(struct class64_t, superclass), S, info,
5370                        n_value, c.superclass);
5371   if (name != nullptr)
5372     outs() << " " << name;
5373   else {
5374     name = get_dyld_bind_info_symbolname(S.getAddress() +
5375              offset + offsetof(struct class64_t, superclass), info);
5376     if (name != nullptr)
5377       outs() << " " << name;
5378   }
5379   outs() << "\n";
5380 
5381   outs() << "         cache " << format("0x%" PRIx64, c.cache);
5382   name = get_symbol_64(offset + offsetof(struct class64_t, cache), S, info,
5383                        n_value, c.cache);
5384   if (name != nullptr)
5385     outs() << " " << name;
5386   outs() << "\n";
5387 
5388   outs() << "        vtable " << format("0x%" PRIx64, c.vtable);
5389   name = get_symbol_64(offset + offsetof(struct class64_t, vtable), S, info,
5390                        n_value, c.vtable);
5391   if (name != nullptr)
5392     outs() << " " << name;
5393   outs() << "\n";
5394 
5395   name = get_symbol_64(offset + offsetof(struct class64_t, data), S, info,
5396                        n_value, c.data);
5397   outs() << "          data ";
5398   if (n_value != 0) {
5399     if (info->verbose && name != nullptr)
5400       outs() << name;
5401     else
5402       outs() << format("0x%" PRIx64, n_value);
5403     if (c.data != 0)
5404       outs() << " + " << format("0x%" PRIx64, c.data);
5405   } else
5406     outs() << format("0x%" PRIx64, c.data);
5407   outs() << " (struct class_ro_t *)";
5408 
5409   // This is a Swift class if some of the low bits of the pointer are set.
5410   if ((c.data + n_value) & 0x7)
5411     outs() << " Swift class";
5412   outs() << "\n";
5413   bool is_meta_class;
5414   if (!print_class_ro64_t((c.data + n_value) & ~0x7, info, is_meta_class))
5415     return;
5416 
5417   if (!is_meta_class &&
5418       c.isa + isa_n_value != p &&
5419       c.isa + isa_n_value != 0 &&
5420       info->depth < 100) {
5421       info->depth++;
5422       outs() << "Meta Class\n";
5423       print_class64_t(c.isa + isa_n_value, info);
5424   }
5425 }
5426 
5427 static void print_class32_t(uint32_t p, struct DisassembleInfo *info) {
5428   struct class32_t c;
5429   const char *r;
5430   uint32_t offset, left;
5431   SectionRef S;
5432   const char *name;
5433 
5434   r = get_pointer_32(p, offset, left, S, info);
5435   if (r == nullptr)
5436     return;
5437   memset(&c, '\0', sizeof(struct class32_t));
5438   if (left < sizeof(struct class32_t)) {
5439     memcpy(&c, r, left);
5440     outs() << "   (class_t entends past the end of the section)\n";
5441   } else
5442     memcpy(&c, r, sizeof(struct class32_t));
5443   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5444     swapStruct(c);
5445 
5446   outs() << "           isa " << format("0x%" PRIx32, c.isa);
5447   name =
5448       get_symbol_32(offset + offsetof(struct class32_t, isa), S, info, c.isa);
5449   if (name != nullptr)
5450     outs() << " " << name;
5451   outs() << "\n";
5452 
5453   outs() << "    superclass " << format("0x%" PRIx32, c.superclass);
5454   name = get_symbol_32(offset + offsetof(struct class32_t, superclass), S, info,
5455                        c.superclass);
5456   if (name != nullptr)
5457     outs() << " " << name;
5458   outs() << "\n";
5459 
5460   outs() << "         cache " << format("0x%" PRIx32, c.cache);
5461   name = get_symbol_32(offset + offsetof(struct class32_t, cache), S, info,
5462                        c.cache);
5463   if (name != nullptr)
5464     outs() << " " << name;
5465   outs() << "\n";
5466 
5467   outs() << "        vtable " << format("0x%" PRIx32, c.vtable);
5468   name = get_symbol_32(offset + offsetof(struct class32_t, vtable), S, info,
5469                        c.vtable);
5470   if (name != nullptr)
5471     outs() << " " << name;
5472   outs() << "\n";
5473 
5474   name =
5475       get_symbol_32(offset + offsetof(struct class32_t, data), S, info, c.data);
5476   outs() << "          data " << format("0x%" PRIx32, c.data)
5477          << " (struct class_ro_t *)";
5478 
5479   // This is a Swift class if some of the low bits of the pointer are set.
5480   if (c.data & 0x3)
5481     outs() << " Swift class";
5482   outs() << "\n";
5483   bool is_meta_class;
5484   if (!print_class_ro32_t(c.data & ~0x3, info, is_meta_class))
5485     return;
5486 
5487   if (!is_meta_class) {
5488     outs() << "Meta Class\n";
5489     print_class32_t(c.isa, info);
5490   }
5491 }
5492 
5493 static void print_objc_class_t(struct objc_class_t *objc_class,
5494                                struct DisassembleInfo *info) {
5495   uint32_t offset, left, xleft;
5496   const char *name, *p, *ivar_list;
5497   SectionRef S;
5498   int32_t i;
5499   struct objc_ivar_list_t objc_ivar_list;
5500   struct objc_ivar_t ivar;
5501 
5502   outs() << "\t\t      isa " << format("0x%08" PRIx32, objc_class->isa);
5503   if (info->verbose && CLS_GETINFO(objc_class, CLS_META)) {
5504     name = get_pointer_32(objc_class->isa, offset, left, S, info, true);
5505     if (name != nullptr)
5506       outs() << format(" %.*s", left, name);
5507     else
5508       outs() << " (not in an __OBJC section)";
5509   }
5510   outs() << "\n";
5511 
5512   outs() << "\t      super_class "
5513          << format("0x%08" PRIx32, objc_class->super_class);
5514   if (info->verbose) {
5515     name = get_pointer_32(objc_class->super_class, offset, left, S, info, true);
5516     if (name != nullptr)
5517       outs() << format(" %.*s", left, name);
5518     else
5519       outs() << " (not in an __OBJC section)";
5520   }
5521   outs() << "\n";
5522 
5523   outs() << "\t\t     name " << format("0x%08" PRIx32, objc_class->name);
5524   if (info->verbose) {
5525     name = get_pointer_32(objc_class->name, offset, left, S, info, true);
5526     if (name != nullptr)
5527       outs() << format(" %.*s", left, name);
5528     else
5529       outs() << " (not in an __OBJC section)";
5530   }
5531   outs() << "\n";
5532 
5533   outs() << "\t\t  version " << format("0x%08" PRIx32, objc_class->version)
5534          << "\n";
5535 
5536   outs() << "\t\t     info " << format("0x%08" PRIx32, objc_class->info);
5537   if (info->verbose) {
5538     if (CLS_GETINFO(objc_class, CLS_CLASS))
5539       outs() << " CLS_CLASS";
5540     else if (CLS_GETINFO(objc_class, CLS_META))
5541       outs() << " CLS_META";
5542   }
5543   outs() << "\n";
5544 
5545   outs() << "\t    instance_size "
5546          << format("0x%08" PRIx32, objc_class->instance_size) << "\n";
5547 
5548   p = get_pointer_32(objc_class->ivars, offset, left, S, info, true);
5549   outs() << "\t\t    ivars " << format("0x%08" PRIx32, objc_class->ivars);
5550   if (p != nullptr) {
5551     if (left > sizeof(struct objc_ivar_list_t)) {
5552       outs() << "\n";
5553       memcpy(&objc_ivar_list, p, sizeof(struct objc_ivar_list_t));
5554     } else {
5555       outs() << " (entends past the end of the section)\n";
5556       memset(&objc_ivar_list, '\0', sizeof(struct objc_ivar_list_t));
5557       memcpy(&objc_ivar_list, p, left);
5558     }
5559     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5560       swapStruct(objc_ivar_list);
5561     outs() << "\t\t       ivar_count " << objc_ivar_list.ivar_count << "\n";
5562     ivar_list = p + sizeof(struct objc_ivar_list_t);
5563     for (i = 0; i < objc_ivar_list.ivar_count; i++) {
5564       if ((i + 1) * sizeof(struct objc_ivar_t) > left) {
5565         outs() << "\t\t remaining ivar's extend past the of the section\n";
5566         break;
5567       }
5568       memcpy(&ivar, ivar_list + i * sizeof(struct objc_ivar_t),
5569              sizeof(struct objc_ivar_t));
5570       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5571         swapStruct(ivar);
5572 
5573       outs() << "\t\t\tivar_name " << format("0x%08" PRIx32, ivar.ivar_name);
5574       if (info->verbose) {
5575         name = get_pointer_32(ivar.ivar_name, offset, xleft, S, info, true);
5576         if (name != nullptr)
5577           outs() << format(" %.*s", xleft, name);
5578         else
5579           outs() << " (not in an __OBJC section)";
5580       }
5581       outs() << "\n";
5582 
5583       outs() << "\t\t\tivar_type " << format("0x%08" PRIx32, ivar.ivar_type);
5584       if (info->verbose) {
5585         name = get_pointer_32(ivar.ivar_type, offset, xleft, S, info, true);
5586         if (name != nullptr)
5587           outs() << format(" %.*s", xleft, name);
5588         else
5589           outs() << " (not in an __OBJC section)";
5590       }
5591       outs() << "\n";
5592 
5593       outs() << "\t\t      ivar_offset "
5594              << format("0x%08" PRIx32, ivar.ivar_offset) << "\n";
5595     }
5596   } else {
5597     outs() << " (not in an __OBJC section)\n";
5598   }
5599 
5600   outs() << "\t\t  methods " << format("0x%08" PRIx32, objc_class->methodLists);
5601   if (print_method_list(objc_class->methodLists, info))
5602     outs() << " (not in an __OBJC section)\n";
5603 
5604   outs() << "\t\t    cache " << format("0x%08" PRIx32, objc_class->cache)
5605          << "\n";
5606 
5607   outs() << "\t\tprotocols " << format("0x%08" PRIx32, objc_class->protocols);
5608   if (print_protocol_list(objc_class->protocols, 16, info))
5609     outs() << " (not in an __OBJC section)\n";
5610 }
5611 
5612 static void print_objc_objc_category_t(struct objc_category_t *objc_category,
5613                                        struct DisassembleInfo *info) {
5614   uint32_t offset, left;
5615   const char *name;
5616   SectionRef S;
5617 
5618   outs() << "\t       category name "
5619          << format("0x%08" PRIx32, objc_category->category_name);
5620   if (info->verbose) {
5621     name = get_pointer_32(objc_category->category_name, offset, left, S, info,
5622                           true);
5623     if (name != nullptr)
5624       outs() << format(" %.*s", left, name);
5625     else
5626       outs() << " (not in an __OBJC section)";
5627   }
5628   outs() << "\n";
5629 
5630   outs() << "\t\t  class name "
5631          << format("0x%08" PRIx32, objc_category->class_name);
5632   if (info->verbose) {
5633     name =
5634         get_pointer_32(objc_category->class_name, offset, left, S, info, true);
5635     if (name != nullptr)
5636       outs() << format(" %.*s", left, name);
5637     else
5638       outs() << " (not in an __OBJC section)";
5639   }
5640   outs() << "\n";
5641 
5642   outs() << "\t    instance methods "
5643          << format("0x%08" PRIx32, objc_category->instance_methods);
5644   if (print_method_list(objc_category->instance_methods, info))
5645     outs() << " (not in an __OBJC section)\n";
5646 
5647   outs() << "\t       class methods "
5648          << format("0x%08" PRIx32, objc_category->class_methods);
5649   if (print_method_list(objc_category->class_methods, info))
5650     outs() << " (not in an __OBJC section)\n";
5651 }
5652 
5653 static void print_category64_t(uint64_t p, struct DisassembleInfo *info) {
5654   struct category64_t c;
5655   const char *r;
5656   uint32_t offset, xoffset, left;
5657   SectionRef S, xS;
5658   const char *name, *sym_name;
5659   uint64_t n_value;
5660 
5661   r = get_pointer_64(p, offset, left, S, info);
5662   if (r == nullptr)
5663     return;
5664   memset(&c, '\0', sizeof(struct category64_t));
5665   if (left < sizeof(struct category64_t)) {
5666     memcpy(&c, r, left);
5667     outs() << "   (category_t entends past the end of the section)\n";
5668   } else
5669     memcpy(&c, r, sizeof(struct category64_t));
5670   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5671     swapStruct(c);
5672 
5673   outs() << "              name ";
5674   sym_name = get_symbol_64(offset + offsetof(struct category64_t, name), S,
5675                            info, n_value, c.name);
5676   if (n_value != 0) {
5677     if (info->verbose && sym_name != nullptr)
5678       outs() << sym_name;
5679     else
5680       outs() << format("0x%" PRIx64, n_value);
5681     if (c.name != 0)
5682       outs() << " + " << format("0x%" PRIx64, c.name);
5683   } else
5684     outs() << format("0x%" PRIx64, c.name);
5685   name = get_pointer_64(c.name + n_value, xoffset, left, xS, info);
5686   if (name != nullptr)
5687     outs() << format(" %.*s", left, name);
5688   outs() << "\n";
5689 
5690   outs() << "               cls ";
5691   sym_name = get_symbol_64(offset + offsetof(struct category64_t, cls), S, info,
5692                            n_value, c.cls);
5693   if (n_value != 0) {
5694     if (info->verbose && sym_name != nullptr)
5695       outs() << sym_name;
5696     else
5697       outs() << format("0x%" PRIx64, n_value);
5698     if (c.cls != 0)
5699       outs() << " + " << format("0x%" PRIx64, c.cls);
5700   } else
5701     outs() << format("0x%" PRIx64, c.cls);
5702   outs() << "\n";
5703   if (c.cls + n_value != 0)
5704     print_class64_t(c.cls + n_value, info);
5705 
5706   outs() << "   instanceMethods ";
5707   sym_name =
5708       get_symbol_64(offset + offsetof(struct category64_t, instanceMethods), S,
5709                     info, n_value, c.instanceMethods);
5710   if (n_value != 0) {
5711     if (info->verbose && sym_name != nullptr)
5712       outs() << sym_name;
5713     else
5714       outs() << format("0x%" PRIx64, n_value);
5715     if (c.instanceMethods != 0)
5716       outs() << " + " << format("0x%" PRIx64, c.instanceMethods);
5717   } else
5718     outs() << format("0x%" PRIx64, c.instanceMethods);
5719   outs() << "\n";
5720   if (c.instanceMethods + n_value != 0)
5721     print_method_list64_t(c.instanceMethods + n_value, info, "");
5722 
5723   outs() << "      classMethods ";
5724   sym_name = get_symbol_64(offset + offsetof(struct category64_t, classMethods),
5725                            S, info, n_value, c.classMethods);
5726   if (n_value != 0) {
5727     if (info->verbose && sym_name != nullptr)
5728       outs() << sym_name;
5729     else
5730       outs() << format("0x%" PRIx64, n_value);
5731     if (c.classMethods != 0)
5732       outs() << " + " << format("0x%" PRIx64, c.classMethods);
5733   } else
5734     outs() << format("0x%" PRIx64, c.classMethods);
5735   outs() << "\n";
5736   if (c.classMethods + n_value != 0)
5737     print_method_list64_t(c.classMethods + n_value, info, "");
5738 
5739   outs() << "         protocols ";
5740   sym_name = get_symbol_64(offset + offsetof(struct category64_t, protocols), S,
5741                            info, n_value, c.protocols);
5742   if (n_value != 0) {
5743     if (info->verbose && sym_name != nullptr)
5744       outs() << sym_name;
5745     else
5746       outs() << format("0x%" PRIx64, n_value);
5747     if (c.protocols != 0)
5748       outs() << " + " << format("0x%" PRIx64, c.protocols);
5749   } else
5750     outs() << format("0x%" PRIx64, c.protocols);
5751   outs() << "\n";
5752   if (c.protocols + n_value != 0)
5753     print_protocol_list64_t(c.protocols + n_value, info);
5754 
5755   outs() << "instanceProperties ";
5756   sym_name =
5757       get_symbol_64(offset + offsetof(struct category64_t, instanceProperties),
5758                     S, info, n_value, c.instanceProperties);
5759   if (n_value != 0) {
5760     if (info->verbose && sym_name != nullptr)
5761       outs() << sym_name;
5762     else
5763       outs() << format("0x%" PRIx64, n_value);
5764     if (c.instanceProperties != 0)
5765       outs() << " + " << format("0x%" PRIx64, c.instanceProperties);
5766   } else
5767     outs() << format("0x%" PRIx64, c.instanceProperties);
5768   outs() << "\n";
5769   if (c.instanceProperties + n_value != 0)
5770     print_objc_property_list64(c.instanceProperties + n_value, info);
5771 }
5772 
5773 static void print_category32_t(uint32_t p, struct DisassembleInfo *info) {
5774   struct category32_t c;
5775   const char *r;
5776   uint32_t offset, left;
5777   SectionRef S, xS;
5778   const char *name;
5779 
5780   r = get_pointer_32(p, offset, left, S, info);
5781   if (r == nullptr)
5782     return;
5783   memset(&c, '\0', sizeof(struct category32_t));
5784   if (left < sizeof(struct category32_t)) {
5785     memcpy(&c, r, left);
5786     outs() << "   (category_t entends past the end of the section)\n";
5787   } else
5788     memcpy(&c, r, sizeof(struct category32_t));
5789   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5790     swapStruct(c);
5791 
5792   outs() << "              name " << format("0x%" PRIx32, c.name);
5793   name = get_symbol_32(offset + offsetof(struct category32_t, name), S, info,
5794                        c.name);
5795   if (name)
5796     outs() << " " << name;
5797   outs() << "\n";
5798 
5799   outs() << "               cls " << format("0x%" PRIx32, c.cls) << "\n";
5800   if (c.cls != 0)
5801     print_class32_t(c.cls, info);
5802   outs() << "   instanceMethods " << format("0x%" PRIx32, c.instanceMethods)
5803          << "\n";
5804   if (c.instanceMethods != 0)
5805     print_method_list32_t(c.instanceMethods, info, "");
5806   outs() << "      classMethods " << format("0x%" PRIx32, c.classMethods)
5807          << "\n";
5808   if (c.classMethods != 0)
5809     print_method_list32_t(c.classMethods, info, "");
5810   outs() << "         protocols " << format("0x%" PRIx32, c.protocols) << "\n";
5811   if (c.protocols != 0)
5812     print_protocol_list32_t(c.protocols, info);
5813   outs() << "instanceProperties " << format("0x%" PRIx32, c.instanceProperties)
5814          << "\n";
5815   if (c.instanceProperties != 0)
5816     print_objc_property_list32(c.instanceProperties, info);
5817 }
5818 
5819 static void print_message_refs64(SectionRef S, struct DisassembleInfo *info) {
5820   uint32_t i, left, offset, xoffset;
5821   uint64_t p, n_value;
5822   struct message_ref64 mr;
5823   const char *name, *sym_name;
5824   const char *r;
5825   SectionRef xS;
5826 
5827   if (S == SectionRef())
5828     return;
5829 
5830   StringRef SectName;
5831   Expected<StringRef> SecNameOrErr = S.getName();
5832   if (SecNameOrErr)
5833     SectName = *SecNameOrErr;
5834   else
5835     consumeError(SecNameOrErr.takeError());
5836 
5837   DataRefImpl Ref = S.getRawDataRefImpl();
5838   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5839   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5840   offset = 0;
5841   for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
5842     p = S.getAddress() + i;
5843     r = get_pointer_64(p, offset, left, S, info);
5844     if (r == nullptr)
5845       return;
5846     memset(&mr, '\0', sizeof(struct message_ref64));
5847     if (left < sizeof(struct message_ref64)) {
5848       memcpy(&mr, r, left);
5849       outs() << "   (message_ref entends past the end of the section)\n";
5850     } else
5851       memcpy(&mr, r, sizeof(struct message_ref64));
5852     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5853       swapStruct(mr);
5854 
5855     outs() << "  imp ";
5856     name = get_symbol_64(offset + offsetof(struct message_ref64, imp), S, info,
5857                          n_value, mr.imp);
5858     if (n_value != 0) {
5859       outs() << format("0x%" PRIx64, n_value) << " ";
5860       if (mr.imp != 0)
5861         outs() << "+ " << format("0x%" PRIx64, mr.imp) << " ";
5862     } else
5863       outs() << format("0x%" PRIx64, mr.imp) << " ";
5864     if (name != nullptr)
5865       outs() << " " << name;
5866     outs() << "\n";
5867 
5868     outs() << "  sel ";
5869     sym_name = get_symbol_64(offset + offsetof(struct message_ref64, sel), S,
5870                              info, n_value, mr.sel);
5871     if (n_value != 0) {
5872       if (info->verbose && sym_name != nullptr)
5873         outs() << sym_name;
5874       else
5875         outs() << format("0x%" PRIx64, n_value);
5876       if (mr.sel != 0)
5877         outs() << " + " << format("0x%" PRIx64, mr.sel);
5878     } else
5879       outs() << format("0x%" PRIx64, mr.sel);
5880     name = get_pointer_64(mr.sel + n_value, xoffset, left, xS, info);
5881     if (name != nullptr)
5882       outs() << format(" %.*s", left, name);
5883     outs() << "\n";
5884 
5885     offset += sizeof(struct message_ref64);
5886   }
5887 }
5888 
5889 static void print_message_refs32(SectionRef S, struct DisassembleInfo *info) {
5890   uint32_t i, left, offset, xoffset, p;
5891   struct message_ref32 mr;
5892   const char *name, *r;
5893   SectionRef xS;
5894 
5895   if (S == SectionRef())
5896     return;
5897 
5898   StringRef SectName;
5899   Expected<StringRef> SecNameOrErr = S.getName();
5900   if (SecNameOrErr)
5901     SectName = *SecNameOrErr;
5902   else
5903     consumeError(SecNameOrErr.takeError());
5904 
5905   DataRefImpl Ref = S.getRawDataRefImpl();
5906   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5907   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5908   offset = 0;
5909   for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
5910     p = S.getAddress() + i;
5911     r = get_pointer_32(p, offset, left, S, info);
5912     if (r == nullptr)
5913       return;
5914     memset(&mr, '\0', sizeof(struct message_ref32));
5915     if (left < sizeof(struct message_ref32)) {
5916       memcpy(&mr, r, left);
5917       outs() << "   (message_ref entends past the end of the section)\n";
5918     } else
5919       memcpy(&mr, r, sizeof(struct message_ref32));
5920     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5921       swapStruct(mr);
5922 
5923     outs() << "  imp " << format("0x%" PRIx32, mr.imp);
5924     name = get_symbol_32(offset + offsetof(struct message_ref32, imp), S, info,
5925                          mr.imp);
5926     if (name != nullptr)
5927       outs() << " " << name;
5928     outs() << "\n";
5929 
5930     outs() << "  sel " << format("0x%" PRIx32, mr.sel);
5931     name = get_pointer_32(mr.sel, xoffset, left, xS, info);
5932     if (name != nullptr)
5933       outs() << " " << name;
5934     outs() << "\n";
5935 
5936     offset += sizeof(struct message_ref32);
5937   }
5938 }
5939 
5940 static void print_image_info64(SectionRef S, struct DisassembleInfo *info) {
5941   uint32_t left, offset, swift_version;
5942   uint64_t p;
5943   struct objc_image_info64 o;
5944   const char *r;
5945 
5946   if (S == SectionRef())
5947     return;
5948 
5949   StringRef SectName;
5950   Expected<StringRef> SecNameOrErr = S.getName();
5951   if (SecNameOrErr)
5952     SectName = *SecNameOrErr;
5953   else
5954     consumeError(SecNameOrErr.takeError());
5955 
5956   DataRefImpl Ref = S.getRawDataRefImpl();
5957   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
5958   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
5959   p = S.getAddress();
5960   r = get_pointer_64(p, offset, left, S, info);
5961   if (r == nullptr)
5962     return;
5963   memset(&o, '\0', sizeof(struct objc_image_info64));
5964   if (left < sizeof(struct objc_image_info64)) {
5965     memcpy(&o, r, left);
5966     outs() << "   (objc_image_info entends past the end of the section)\n";
5967   } else
5968     memcpy(&o, r, sizeof(struct objc_image_info64));
5969   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
5970     swapStruct(o);
5971   outs() << "  version " << o.version << "\n";
5972   outs() << "    flags " << format("0x%" PRIx32, o.flags);
5973   if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
5974     outs() << " OBJC_IMAGE_IS_REPLACEMENT";
5975   if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
5976     outs() << " OBJC_IMAGE_SUPPORTS_GC";
5977   if (o.flags & OBJC_IMAGE_IS_SIMULATED)
5978     outs() << " OBJC_IMAGE_IS_SIMULATED";
5979   if (o.flags & OBJC_IMAGE_HAS_CATEGORY_CLASS_PROPERTIES)
5980     outs() << " OBJC_IMAGE_HAS_CATEGORY_CLASS_PROPERTIES";
5981   swift_version = (o.flags >> 8) & 0xff;
5982   if (swift_version != 0) {
5983     if (swift_version == 1)
5984       outs() << " Swift 1.0";
5985     else if (swift_version == 2)
5986       outs() << " Swift 1.1";
5987     else if(swift_version == 3)
5988       outs() << " Swift 2.0";
5989     else if(swift_version == 4)
5990       outs() << " Swift 3.0";
5991     else if(swift_version == 5)
5992       outs() << " Swift 4.0";
5993     else if(swift_version == 6)
5994       outs() << " Swift 4.1/Swift 4.2";
5995     else if(swift_version == 7)
5996       outs() << " Swift 5 or later";
5997     else
5998       outs() << " unknown future Swift version (" << swift_version << ")";
5999   }
6000   outs() << "\n";
6001 }
6002 
6003 static void print_image_info32(SectionRef S, struct DisassembleInfo *info) {
6004   uint32_t left, offset, swift_version, p;
6005   struct objc_image_info32 o;
6006   const char *r;
6007 
6008   if (S == SectionRef())
6009     return;
6010 
6011   StringRef SectName;
6012   Expected<StringRef> SecNameOrErr = S.getName();
6013   if (SecNameOrErr)
6014     SectName = *SecNameOrErr;
6015   else
6016     consumeError(SecNameOrErr.takeError());
6017 
6018   DataRefImpl Ref = S.getRawDataRefImpl();
6019   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
6020   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
6021   p = S.getAddress();
6022   r = get_pointer_32(p, offset, left, S, info);
6023   if (r == nullptr)
6024     return;
6025   memset(&o, '\0', sizeof(struct objc_image_info32));
6026   if (left < sizeof(struct objc_image_info32)) {
6027     memcpy(&o, r, left);
6028     outs() << "   (objc_image_info entends past the end of the section)\n";
6029   } else
6030     memcpy(&o, r, sizeof(struct objc_image_info32));
6031   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
6032     swapStruct(o);
6033   outs() << "  version " << o.version << "\n";
6034   outs() << "    flags " << format("0x%" PRIx32, o.flags);
6035   if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
6036     outs() << " OBJC_IMAGE_IS_REPLACEMENT";
6037   if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
6038     outs() << " OBJC_IMAGE_SUPPORTS_GC";
6039   swift_version = (o.flags >> 8) & 0xff;
6040   if (swift_version != 0) {
6041     if (swift_version == 1)
6042       outs() << " Swift 1.0";
6043     else if (swift_version == 2)
6044       outs() << " Swift 1.1";
6045     else if(swift_version == 3)
6046       outs() << " Swift 2.0";
6047     else if(swift_version == 4)
6048       outs() << " Swift 3.0";
6049     else if(swift_version == 5)
6050       outs() << " Swift 4.0";
6051     else if(swift_version == 6)
6052       outs() << " Swift 4.1/Swift 4.2";
6053     else if(swift_version == 7)
6054       outs() << " Swift 5 or later";
6055     else
6056       outs() << " unknown future Swift version (" << swift_version << ")";
6057   }
6058   outs() << "\n";
6059 }
6060 
6061 static void print_image_info(SectionRef S, struct DisassembleInfo *info) {
6062   uint32_t left, offset, p;
6063   struct imageInfo_t o;
6064   const char *r;
6065 
6066   StringRef SectName;
6067   Expected<StringRef> SecNameOrErr = S.getName();
6068   if (SecNameOrErr)
6069     SectName = *SecNameOrErr;
6070   else
6071     consumeError(SecNameOrErr.takeError());
6072 
6073   DataRefImpl Ref = S.getRawDataRefImpl();
6074   StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
6075   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
6076   p = S.getAddress();
6077   r = get_pointer_32(p, offset, left, S, info);
6078   if (r == nullptr)
6079     return;
6080   memset(&o, '\0', sizeof(struct imageInfo_t));
6081   if (left < sizeof(struct imageInfo_t)) {
6082     memcpy(&o, r, left);
6083     outs() << " (imageInfo entends past the end of the section)\n";
6084   } else
6085     memcpy(&o, r, sizeof(struct imageInfo_t));
6086   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
6087     swapStruct(o);
6088   outs() << "  version " << o.version << "\n";
6089   outs() << "    flags " << format("0x%" PRIx32, o.flags);
6090   if (o.flags & 0x1)
6091     outs() << "  F&C";
6092   if (o.flags & 0x2)
6093     outs() << " GC";
6094   if (o.flags & 0x4)
6095     outs() << " GC-only";
6096   else
6097     outs() << " RR";
6098   outs() << "\n";
6099 }
6100 
6101 static void printObjc2_64bit_MetaData(MachOObjectFile *O, bool verbose) {
6102   SymbolAddressMap AddrMap;
6103   if (verbose)
6104     CreateSymbolAddressMap(O, &AddrMap);
6105 
6106   std::vector<SectionRef> Sections;
6107   append_range(Sections, O->sections());
6108 
6109   struct DisassembleInfo info(O, &AddrMap, &Sections, verbose);
6110 
6111   SectionRef CL = get_section(O, "__OBJC2", "__class_list");
6112   if (CL == SectionRef())
6113     CL = get_section(O, "__DATA", "__objc_classlist");
6114   if (CL == SectionRef())
6115     CL = get_section(O, "__DATA_CONST", "__objc_classlist");
6116   if (CL == SectionRef())
6117     CL = get_section(O, "__DATA_DIRTY", "__objc_classlist");
6118   info.S = CL;
6119   walk_pointer_list_64("class", CL, O, &info, print_class64_t);
6120 
6121   SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
6122   if (CR == SectionRef())
6123     CR = get_section(O, "__DATA", "__objc_classrefs");
6124   if (CR == SectionRef())
6125     CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
6126   if (CR == SectionRef())
6127     CR = get_section(O, "__DATA_DIRTY", "__objc_classrefs");
6128   info.S = CR;
6129   walk_pointer_list_64("class refs", CR, O, &info, nullptr);
6130 
6131   SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
6132   if (SR == SectionRef())
6133     SR = get_section(O, "__DATA", "__objc_superrefs");
6134   if (SR == SectionRef())
6135     SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
6136   if (SR == SectionRef())
6137     SR = get_section(O, "__DATA_DIRTY", "__objc_superrefs");
6138   info.S = SR;
6139   walk_pointer_list_64("super refs", SR, O, &info, nullptr);
6140 
6141   SectionRef CA = get_section(O, "__OBJC2", "__category_list");
6142   if (CA == SectionRef())
6143     CA = get_section(O, "__DATA", "__objc_catlist");
6144   if (CA == SectionRef())
6145     CA = get_section(O, "__DATA_CONST", "__objc_catlist");
6146   if (CA == SectionRef())
6147     CA = get_section(O, "__DATA_DIRTY", "__objc_catlist");
6148   info.S = CA;
6149   walk_pointer_list_64("category", CA, O, &info, print_category64_t);
6150 
6151   SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
6152   if (PL == SectionRef())
6153     PL = get_section(O, "__DATA", "__objc_protolist");
6154   if (PL == SectionRef())
6155     PL = get_section(O, "__DATA_CONST", "__objc_protolist");
6156   if (PL == SectionRef())
6157     PL = get_section(O, "__DATA_DIRTY", "__objc_protolist");
6158   info.S = PL;
6159   walk_pointer_list_64("protocol", PL, O, &info, nullptr);
6160 
6161   SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
6162   if (MR == SectionRef())
6163     MR = get_section(O, "__DATA", "__objc_msgrefs");
6164   if (MR == SectionRef())
6165     MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
6166   if (MR == SectionRef())
6167     MR = get_section(O, "__DATA_DIRTY", "__objc_msgrefs");
6168   info.S = MR;
6169   print_message_refs64(MR, &info);
6170 
6171   SectionRef II = get_section(O, "__OBJC2", "__image_info");
6172   if (II == SectionRef())
6173     II = get_section(O, "__DATA", "__objc_imageinfo");
6174   if (II == SectionRef())
6175     II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
6176   if (II == SectionRef())
6177     II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
6178   info.S = II;
6179   print_image_info64(II, &info);
6180 }
6181 
6182 static void printObjc2_32bit_MetaData(MachOObjectFile *O, bool verbose) {
6183   SymbolAddressMap AddrMap;
6184   if (verbose)
6185     CreateSymbolAddressMap(O, &AddrMap);
6186 
6187   std::vector<SectionRef> Sections;
6188   append_range(Sections, O->sections());
6189 
6190   struct DisassembleInfo info(O, &AddrMap, &Sections, verbose);
6191 
6192   SectionRef CL = get_section(O, "__OBJC2", "__class_list");
6193   if (CL == SectionRef())
6194     CL = get_section(O, "__DATA", "__objc_classlist");
6195   if (CL == SectionRef())
6196     CL = get_section(O, "__DATA_CONST", "__objc_classlist");
6197   if (CL == SectionRef())
6198     CL = get_section(O, "__DATA_DIRTY", "__objc_classlist");
6199   info.S = CL;
6200   walk_pointer_list_32("class", CL, O, &info, print_class32_t);
6201 
6202   SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
6203   if (CR == SectionRef())
6204     CR = get_section(O, "__DATA", "__objc_classrefs");
6205   if (CR == SectionRef())
6206     CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
6207   if (CR == SectionRef())
6208     CR = get_section(O, "__DATA_DIRTY", "__objc_classrefs");
6209   info.S = CR;
6210   walk_pointer_list_32("class refs", CR, O, &info, nullptr);
6211 
6212   SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
6213   if (SR == SectionRef())
6214     SR = get_section(O, "__DATA", "__objc_superrefs");
6215   if (SR == SectionRef())
6216     SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
6217   if (SR == SectionRef())
6218     SR = get_section(O, "__DATA_DIRTY", "__objc_superrefs");
6219   info.S = SR;
6220   walk_pointer_list_32("super refs", SR, O, &info, nullptr);
6221 
6222   SectionRef CA = get_section(O, "__OBJC2", "__category_list");
6223   if (CA == SectionRef())
6224     CA = get_section(O, "__DATA", "__objc_catlist");
6225   if (CA == SectionRef())
6226     CA = get_section(O, "__DATA_CONST", "__objc_catlist");
6227   if (CA == SectionRef())
6228     CA = get_section(O, "__DATA_DIRTY", "__objc_catlist");
6229   info.S = CA;
6230   walk_pointer_list_32("category", CA, O, &info, print_category32_t);
6231 
6232   SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
6233   if (PL == SectionRef())
6234     PL = get_section(O, "__DATA", "__objc_protolist");
6235   if (PL == SectionRef())
6236     PL = get_section(O, "__DATA_CONST", "__objc_protolist");
6237   if (PL == SectionRef())
6238     PL = get_section(O, "__DATA_DIRTY", "__objc_protolist");
6239   info.S = PL;
6240   walk_pointer_list_32("protocol", PL, O, &info, nullptr);
6241 
6242   SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
6243   if (MR == SectionRef())
6244     MR = get_section(O, "__DATA", "__objc_msgrefs");
6245   if (MR == SectionRef())
6246     MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
6247   if (MR == SectionRef())
6248     MR = get_section(O, "__DATA_DIRTY", "__objc_msgrefs");
6249   info.S = MR;
6250   print_message_refs32(MR, &info);
6251 
6252   SectionRef II = get_section(O, "__OBJC2", "__image_info");
6253   if (II == SectionRef())
6254     II = get_section(O, "__DATA", "__objc_imageinfo");
6255   if (II == SectionRef())
6256     II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
6257   if (II == SectionRef())
6258     II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
6259   info.S = II;
6260   print_image_info32(II, &info);
6261 }
6262 
6263 static bool printObjc1_32bit_MetaData(MachOObjectFile *O, bool verbose) {
6264   uint32_t i, j, p, offset, xoffset, left, defs_left, def;
6265   const char *r, *name, *defs;
6266   struct objc_module_t module;
6267   SectionRef S, xS;
6268   struct objc_symtab_t symtab;
6269   struct objc_class_t objc_class;
6270   struct objc_category_t objc_category;
6271 
6272   outs() << "Objective-C segment\n";
6273   S = get_section(O, "__OBJC", "__module_info");
6274   if (S == SectionRef())
6275     return false;
6276 
6277   SymbolAddressMap AddrMap;
6278   if (verbose)
6279     CreateSymbolAddressMap(O, &AddrMap);
6280 
6281   std::vector<SectionRef> Sections;
6282   append_range(Sections, O->sections());
6283 
6284   struct DisassembleInfo info(O, &AddrMap, &Sections, verbose);
6285 
6286   for (i = 0; i < S.getSize(); i += sizeof(struct objc_module_t)) {
6287     p = S.getAddress() + i;
6288     r = get_pointer_32(p, offset, left, S, &info, true);
6289     if (r == nullptr)
6290       return true;
6291     memset(&module, '\0', sizeof(struct objc_module_t));
6292     if (left < sizeof(struct objc_module_t)) {
6293       memcpy(&module, r, left);
6294       outs() << "   (module extends past end of __module_info section)\n";
6295     } else
6296       memcpy(&module, r, sizeof(struct objc_module_t));
6297     if (O->isLittleEndian() != sys::IsLittleEndianHost)
6298       swapStruct(module);
6299 
6300     outs() << "Module " << format("0x%" PRIx32, p) << "\n";
6301     outs() << "    version " << module.version << "\n";
6302     outs() << "       size " << module.size << "\n";
6303     outs() << "       name ";
6304     name = get_pointer_32(module.name, xoffset, left, xS, &info, true);
6305     if (name != nullptr)
6306       outs() << format("%.*s", left, name);
6307     else
6308       outs() << format("0x%08" PRIx32, module.name)
6309              << "(not in an __OBJC section)";
6310     outs() << "\n";
6311 
6312     r = get_pointer_32(module.symtab, xoffset, left, xS, &info, true);
6313     if (module.symtab == 0 || r == nullptr) {
6314       outs() << "     symtab " << format("0x%08" PRIx32, module.symtab)
6315              << " (not in an __OBJC section)\n";
6316       continue;
6317     }
6318     outs() << "     symtab " << format("0x%08" PRIx32, module.symtab) << "\n";
6319     memset(&symtab, '\0', sizeof(struct objc_symtab_t));
6320     defs_left = 0;
6321     defs = nullptr;
6322     if (left < sizeof(struct objc_symtab_t)) {
6323       memcpy(&symtab, r, left);
6324       outs() << "\tsymtab extends past end of an __OBJC section)\n";
6325     } else {
6326       memcpy(&symtab, r, sizeof(struct objc_symtab_t));
6327       if (left > sizeof(struct objc_symtab_t)) {
6328         defs_left = left - sizeof(struct objc_symtab_t);
6329         defs = r + sizeof(struct objc_symtab_t);
6330       }
6331     }
6332     if (O->isLittleEndian() != sys::IsLittleEndianHost)
6333       swapStruct(symtab);
6334 
6335     outs() << "\tsel_ref_cnt " << symtab.sel_ref_cnt << "\n";
6336     r = get_pointer_32(symtab.refs, xoffset, left, xS, &info, true);
6337     outs() << "\trefs " << format("0x%08" PRIx32, symtab.refs);
6338     if (r == nullptr)
6339       outs() << " (not in an __OBJC section)";
6340     outs() << "\n";
6341     outs() << "\tcls_def_cnt " << symtab.cls_def_cnt << "\n";
6342     outs() << "\tcat_def_cnt " << symtab.cat_def_cnt << "\n";
6343     if (symtab.cls_def_cnt > 0)
6344       outs() << "\tClass Definitions\n";
6345     for (j = 0; j < symtab.cls_def_cnt; j++) {
6346       if ((j + 1) * sizeof(uint32_t) > defs_left) {
6347         outs() << "\t(remaining class defs entries entends past the end of the "
6348                << "section)\n";
6349         break;
6350       }
6351       memcpy(&def, defs + j * sizeof(uint32_t), sizeof(uint32_t));
6352       if (O->isLittleEndian() != sys::IsLittleEndianHost)
6353         sys::swapByteOrder(def);
6354 
6355       r = get_pointer_32(def, xoffset, left, xS, &info, true);
6356       outs() << "\tdefs[" << j << "] " << format("0x%08" PRIx32, def);
6357       if (r != nullptr) {
6358         if (left > sizeof(struct objc_class_t)) {
6359           outs() << "\n";
6360           memcpy(&objc_class, r, sizeof(struct objc_class_t));
6361         } else {
6362           outs() << " (entends past the end of the section)\n";
6363           memset(&objc_class, '\0', sizeof(struct objc_class_t));
6364           memcpy(&objc_class, r, left);
6365         }
6366         if (O->isLittleEndian() != sys::IsLittleEndianHost)
6367           swapStruct(objc_class);
6368         print_objc_class_t(&objc_class, &info);
6369       } else {
6370         outs() << "(not in an __OBJC section)\n";
6371       }
6372 
6373       if (CLS_GETINFO(&objc_class, CLS_CLASS)) {
6374         outs() << "\tMeta Class";
6375         r = get_pointer_32(objc_class.isa, xoffset, left, xS, &info, true);
6376         if (r != nullptr) {
6377           if (left > sizeof(struct objc_class_t)) {
6378             outs() << "\n";
6379             memcpy(&objc_class, r, sizeof(struct objc_class_t));
6380           } else {
6381             outs() << " (entends past the end of the section)\n";
6382             memset(&objc_class, '\0', sizeof(struct objc_class_t));
6383             memcpy(&objc_class, r, left);
6384           }
6385           if (O->isLittleEndian() != sys::IsLittleEndianHost)
6386             swapStruct(objc_class);
6387           print_objc_class_t(&objc_class, &info);
6388         } else {
6389           outs() << "(not in an __OBJC section)\n";
6390         }
6391       }
6392     }
6393     if (symtab.cat_def_cnt > 0)
6394       outs() << "\tCategory Definitions\n";
6395     for (j = 0; j < symtab.cat_def_cnt; j++) {
6396       if ((j + symtab.cls_def_cnt + 1) * sizeof(uint32_t) > defs_left) {
6397         outs() << "\t(remaining category defs entries entends past the end of "
6398                << "the section)\n";
6399         break;
6400       }
6401       memcpy(&def, defs + (j + symtab.cls_def_cnt) * sizeof(uint32_t),
6402              sizeof(uint32_t));
6403       if (O->isLittleEndian() != sys::IsLittleEndianHost)
6404         sys::swapByteOrder(def);
6405 
6406       r = get_pointer_32(def, xoffset, left, xS, &info, true);
6407       outs() << "\tdefs[" << j + symtab.cls_def_cnt << "] "
6408              << format("0x%08" PRIx32, def);
6409       if (r != nullptr) {
6410         if (left > sizeof(struct objc_category_t)) {
6411           outs() << "\n";
6412           memcpy(&objc_category, r, sizeof(struct objc_category_t));
6413         } else {
6414           outs() << " (entends past the end of the section)\n";
6415           memset(&objc_category, '\0', sizeof(struct objc_category_t));
6416           memcpy(&objc_category, r, left);
6417         }
6418         if (O->isLittleEndian() != sys::IsLittleEndianHost)
6419           swapStruct(objc_category);
6420         print_objc_objc_category_t(&objc_category, &info);
6421       } else {
6422         outs() << "(not in an __OBJC section)\n";
6423       }
6424     }
6425   }
6426   const SectionRef II = get_section(O, "__OBJC", "__image_info");
6427   if (II != SectionRef())
6428     print_image_info(II, &info);
6429 
6430   return true;
6431 }
6432 
6433 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,
6434                                 uint32_t size, uint32_t addr) {
6435   SymbolAddressMap AddrMap;
6436   CreateSymbolAddressMap(O, &AddrMap);
6437 
6438   std::vector<SectionRef> Sections;
6439   append_range(Sections, O->sections());
6440 
6441   struct DisassembleInfo info(O, &AddrMap, &Sections, true);
6442 
6443   const char *p;
6444   struct objc_protocol_t protocol;
6445   uint32_t left, paddr;
6446   for (p = sect; p < sect + size; p += sizeof(struct objc_protocol_t)) {
6447     memset(&protocol, '\0', sizeof(struct objc_protocol_t));
6448     left = size - (p - sect);
6449     if (left < sizeof(struct objc_protocol_t)) {
6450       outs() << "Protocol extends past end of __protocol section\n";
6451       memcpy(&protocol, p, left);
6452     } else
6453       memcpy(&protocol, p, sizeof(struct objc_protocol_t));
6454     if (O->isLittleEndian() != sys::IsLittleEndianHost)
6455       swapStruct(protocol);
6456     paddr = addr + (p - sect);
6457     outs() << "Protocol " << format("0x%" PRIx32, paddr);
6458     if (print_protocol(paddr, 0, &info))
6459       outs() << "(not in an __OBJC section)\n";
6460   }
6461 }
6462 
6463 #ifdef LLVM_HAVE_LIBXAR
6464 static inline void swapStruct(struct xar_header &xar) {
6465   sys::swapByteOrder(xar.magic);
6466   sys::swapByteOrder(xar.size);
6467   sys::swapByteOrder(xar.version);
6468   sys::swapByteOrder(xar.toc_length_compressed);
6469   sys::swapByteOrder(xar.toc_length_uncompressed);
6470   sys::swapByteOrder(xar.cksum_alg);
6471 }
6472 
6473 static void PrintModeVerbose(uint32_t mode) {
6474   switch(mode & S_IFMT){
6475   case S_IFDIR:
6476     outs() << "d";
6477     break;
6478   case S_IFCHR:
6479     outs() << "c";
6480     break;
6481   case S_IFBLK:
6482     outs() << "b";
6483     break;
6484   case S_IFREG:
6485     outs() << "-";
6486     break;
6487   case S_IFLNK:
6488     outs() << "l";
6489     break;
6490   case S_IFSOCK:
6491     outs() << "s";
6492     break;
6493   default:
6494     outs() << "?";
6495     break;
6496   }
6497 
6498   /* owner permissions */
6499   if(mode & S_IREAD)
6500     outs() << "r";
6501   else
6502     outs() << "-";
6503   if(mode & S_IWRITE)
6504     outs() << "w";
6505   else
6506     outs() << "-";
6507   if(mode & S_ISUID)
6508     outs() << "s";
6509   else if(mode & S_IEXEC)
6510     outs() << "x";
6511   else
6512     outs() << "-";
6513 
6514   /* group permissions */
6515   if(mode & (S_IREAD >> 3))
6516     outs() << "r";
6517   else
6518     outs() << "-";
6519   if(mode & (S_IWRITE >> 3))
6520     outs() << "w";
6521   else
6522     outs() << "-";
6523   if(mode & S_ISGID)
6524     outs() << "s";
6525   else if(mode & (S_IEXEC >> 3))
6526     outs() << "x";
6527   else
6528     outs() << "-";
6529 
6530   /* other permissions */
6531   if(mode & (S_IREAD >> 6))
6532     outs() << "r";
6533   else
6534     outs() << "-";
6535   if(mode & (S_IWRITE >> 6))
6536     outs() << "w";
6537   else
6538     outs() << "-";
6539   if(mode & S_ISVTX)
6540     outs() << "t";
6541   else if(mode & (S_IEXEC >> 6))
6542     outs() << "x";
6543   else
6544     outs() << "-";
6545 }
6546 
6547 static void PrintXarFilesSummary(const char *XarFilename, xar_t xar) {
6548   xar_file_t xf;
6549   const char *key, *type, *mode, *user, *group, *size, *mtime, *name, *m;
6550   char *endp;
6551   uint32_t mode_value;
6552 
6553   ScopedXarIter xi;
6554   if (!xi) {
6555     WithColor::error(errs(), "llvm-objdump")
6556         << "can't obtain an xar iterator for xar archive " << XarFilename
6557         << "\n";
6558     return;
6559   }
6560 
6561   // Go through the xar's files.
6562   for (xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)) {
6563     ScopedXarIter xp;
6564     if(!xp){
6565       WithColor::error(errs(), "llvm-objdump")
6566           << "can't obtain an xar iterator for xar archive " << XarFilename
6567           << "\n";
6568       return;
6569     }
6570     type = nullptr;
6571     mode = nullptr;
6572     user = nullptr;
6573     group = nullptr;
6574     size = nullptr;
6575     mtime = nullptr;
6576     name = nullptr;
6577     for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
6578       const char *val = nullptr;
6579       xar_prop_get(xf, key, &val);
6580 #if 0 // Useful for debugging.
6581       outs() << "key: " << key << " value: " << val << "\n";
6582 #endif
6583       if(strcmp(key, "type") == 0)
6584         type = val;
6585       if(strcmp(key, "mode") == 0)
6586         mode = val;
6587       if(strcmp(key, "user") == 0)
6588         user = val;
6589       if(strcmp(key, "group") == 0)
6590         group = val;
6591       if(strcmp(key, "data/size") == 0)
6592         size = val;
6593       if(strcmp(key, "mtime") == 0)
6594         mtime = val;
6595       if(strcmp(key, "name") == 0)
6596         name = val;
6597     }
6598     if(mode != nullptr){
6599       mode_value = strtoul(mode, &endp, 8);
6600       if(*endp != '\0')
6601         outs() << "(mode: \"" << mode << "\" contains non-octal chars) ";
6602       if(strcmp(type, "file") == 0)
6603         mode_value |= S_IFREG;
6604       PrintModeVerbose(mode_value);
6605       outs() << " ";
6606     }
6607     if(user != nullptr)
6608       outs() << format("%10s/", user);
6609     if(group != nullptr)
6610       outs() << format("%-10s ", group);
6611     if(size != nullptr)
6612       outs() << format("%7s ", size);
6613     if(mtime != nullptr){
6614       for(m = mtime; *m != 'T' && *m != '\0'; m++)
6615         outs() << *m;
6616       if(*m == 'T')
6617         m++;
6618       outs() << " ";
6619       for( ; *m != 'Z' && *m != '\0'; m++)
6620         outs() << *m;
6621       outs() << " ";
6622     }
6623     if(name != nullptr)
6624       outs() << name;
6625     outs() << "\n";
6626   }
6627 }
6628 
6629 static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
6630                                 uint32_t size, bool verbose,
6631                                 bool PrintXarHeader, bool PrintXarFileHeaders,
6632                                 std::string XarMemberName) {
6633   if(size < sizeof(struct xar_header)) {
6634     outs() << "size of (__LLVM,__bundle) section too small (smaller than size "
6635               "of struct xar_header)\n";
6636     return;
6637   }
6638   struct xar_header XarHeader;
6639   memcpy(&XarHeader, sect, sizeof(struct xar_header));
6640   if (sys::IsLittleEndianHost)
6641     swapStruct(XarHeader);
6642   if (PrintXarHeader) {
6643     if (!XarMemberName.empty())
6644       outs() << "In xar member " << XarMemberName << ": ";
6645     else
6646       outs() << "For (__LLVM,__bundle) section: ";
6647     outs() << "xar header\n";
6648     if (XarHeader.magic == XAR_HEADER_MAGIC)
6649       outs() << "                  magic XAR_HEADER_MAGIC\n";
6650     else
6651       outs() << "                  magic "
6652              << format_hex(XarHeader.magic, 10, true)
6653              << " (not XAR_HEADER_MAGIC)\n";
6654     outs() << "                   size " << XarHeader.size << "\n";
6655     outs() << "                version " << XarHeader.version << "\n";
6656     outs() << "  toc_length_compressed " << XarHeader.toc_length_compressed
6657            << "\n";
6658     outs() << "toc_length_uncompressed " << XarHeader.toc_length_uncompressed
6659            << "\n";
6660     outs() << "              cksum_alg ";
6661     switch (XarHeader.cksum_alg) {
6662       case XAR_CKSUM_NONE:
6663         outs() << "XAR_CKSUM_NONE\n";
6664         break;
6665       case XAR_CKSUM_SHA1:
6666         outs() << "XAR_CKSUM_SHA1\n";
6667         break;
6668       case XAR_CKSUM_MD5:
6669         outs() << "XAR_CKSUM_MD5\n";
6670         break;
6671 #ifdef XAR_CKSUM_SHA256
6672       case XAR_CKSUM_SHA256:
6673         outs() << "XAR_CKSUM_SHA256\n";
6674         break;
6675 #endif
6676 #ifdef XAR_CKSUM_SHA512
6677       case XAR_CKSUM_SHA512:
6678         outs() << "XAR_CKSUM_SHA512\n";
6679         break;
6680 #endif
6681       default:
6682         outs() << XarHeader.cksum_alg << "\n";
6683     }
6684   }
6685 
6686   SmallString<128> XarFilename;
6687   int FD;
6688   std::error_code XarEC =
6689       sys::fs::createTemporaryFile("llvm-objdump", "xar", FD, XarFilename);
6690   if (XarEC) {
6691     WithColor::error(errs(), "llvm-objdump") << XarEC.message() << "\n";
6692     return;
6693   }
6694   ToolOutputFile XarFile(XarFilename, FD);
6695   raw_fd_ostream &XarOut = XarFile.os();
6696   StringRef XarContents(sect, size);
6697   XarOut << XarContents;
6698   XarOut.close();
6699   if (XarOut.has_error())
6700     return;
6701 
6702   ScopedXarFile xar(XarFilename.c_str(), READ);
6703   if (!xar) {
6704     WithColor::error(errs(), "llvm-objdump")
6705         << "can't create temporary xar archive " << XarFilename << "\n";
6706     return;
6707   }
6708 
6709   SmallString<128> TocFilename;
6710   std::error_code TocEC =
6711       sys::fs::createTemporaryFile("llvm-objdump", "toc", TocFilename);
6712   if (TocEC) {
6713     WithColor::error(errs(), "llvm-objdump") << TocEC.message() << "\n";
6714     return;
6715   }
6716   xar_serialize(xar, TocFilename.c_str());
6717 
6718   if (PrintXarFileHeaders) {
6719     if (!XarMemberName.empty())
6720       outs() << "In xar member " << XarMemberName << ": ";
6721     else
6722       outs() << "For (__LLVM,__bundle) section: ";
6723     outs() << "xar archive files:\n";
6724     PrintXarFilesSummary(XarFilename.c_str(), xar);
6725   }
6726 
6727   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
6728     MemoryBuffer::getFileOrSTDIN(TocFilename.c_str());
6729   if (std::error_code EC = FileOrErr.getError()) {
6730     WithColor::error(errs(), "llvm-objdump") << EC.message() << "\n";
6731     return;
6732   }
6733   std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
6734 
6735   if (!XarMemberName.empty())
6736     outs() << "In xar member " << XarMemberName << ": ";
6737   else
6738     outs() << "For (__LLVM,__bundle) section: ";
6739   outs() << "xar table of contents:\n";
6740   outs() << Buffer->getBuffer() << "\n";
6741 
6742   // TODO: Go through the xar's files.
6743   ScopedXarIter xi;
6744   if(!xi){
6745     WithColor::error(errs(), "llvm-objdump")
6746         << "can't obtain an xar iterator for xar archive "
6747         << XarFilename.c_str() << "\n";
6748     return;
6749   }
6750   for(xar_file_t xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)){
6751     const char *key;
6752     const char *member_name, *member_type, *member_size_string;
6753     size_t member_size;
6754 
6755     ScopedXarIter xp;
6756     if(!xp){
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     member_name = NULL;
6763     member_type = NULL;
6764     member_size_string = NULL;
6765     for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
6766       const char *val = nullptr;
6767       xar_prop_get(xf, key, &val);
6768 #if 0 // Useful for debugging.
6769       outs() << "key: " << key << " value: " << val << "\n";
6770 #endif
6771       if (strcmp(key, "name") == 0)
6772         member_name = val;
6773       if (strcmp(key, "type") == 0)
6774         member_type = val;
6775       if (strcmp(key, "data/size") == 0)
6776         member_size_string = val;
6777     }
6778     /*
6779      * If we find a file with a name, date/size and type properties
6780      * and with the type being "file" see if that is a xar file.
6781      */
6782     if (member_name != NULL && member_type != NULL &&
6783         strcmp(member_type, "file") == 0 &&
6784         member_size_string != NULL){
6785       // Extract the file into a buffer.
6786       char *endptr;
6787       member_size = strtoul(member_size_string, &endptr, 10);
6788       if (*endptr == '\0' && member_size != 0) {
6789         char *buffer;
6790         if (xar_extract_tobuffersz(xar, xf, &buffer, &member_size) == 0) {
6791 #if 0 // Useful for debugging.
6792           outs() << "xar member: " << member_name << " extracted\n";
6793 #endif
6794           // Set the XarMemberName we want to see printed in the header.
6795           std::string OldXarMemberName;
6796           // If XarMemberName is already set this is nested. So
6797           // save the old name and create the nested name.
6798           if (!XarMemberName.empty()) {
6799             OldXarMemberName = XarMemberName;
6800             XarMemberName =
6801                 (Twine("[") + XarMemberName + "]" + member_name).str();
6802           } else {
6803             OldXarMemberName = "";
6804             XarMemberName = member_name;
6805           }
6806           // See if this is could be a xar file (nested).
6807           if (member_size >= sizeof(struct xar_header)) {
6808 #if 0 // Useful for debugging.
6809             outs() << "could be a xar file: " << member_name << "\n";
6810 #endif
6811             memcpy((char *)&XarHeader, buffer, sizeof(struct xar_header));
6812             if (sys::IsLittleEndianHost)
6813               swapStruct(XarHeader);
6814             if (XarHeader.magic == XAR_HEADER_MAGIC)
6815               DumpBitcodeSection(O, buffer, member_size, verbose,
6816                                  PrintXarHeader, PrintXarFileHeaders,
6817                                  XarMemberName);
6818           }
6819           XarMemberName = OldXarMemberName;
6820           delete buffer;
6821         }
6822       }
6823     }
6824   }
6825 }
6826 #endif // defined(LLVM_HAVE_LIBXAR)
6827 
6828 static void printObjcMetaData(MachOObjectFile *O, bool verbose) {
6829   if (O->is64Bit())
6830     printObjc2_64bit_MetaData(O, verbose);
6831   else {
6832     MachO::mach_header H;
6833     H = O->getHeader();
6834     if (H.cputype == MachO::CPU_TYPE_ARM)
6835       printObjc2_32bit_MetaData(O, verbose);
6836     else {
6837       // This is the 32-bit non-arm cputype case.  Which is normally
6838       // the first Objective-C ABI.  But it may be the case of a
6839       // binary for the iOS simulator which is the second Objective-C
6840       // ABI.  In that case printObjc1_32bit_MetaData() will determine that
6841       // and return false.
6842       if (!printObjc1_32bit_MetaData(O, verbose))
6843         printObjc2_32bit_MetaData(O, verbose);
6844     }
6845   }
6846 }
6847 
6848 // GuessLiteralPointer returns a string which for the item in the Mach-O file
6849 // for the address passed in as ReferenceValue for printing as a comment with
6850 // the instruction and also returns the corresponding type of that item
6851 // indirectly through ReferenceType.
6852 //
6853 // If ReferenceValue is an address of literal cstring then a pointer to the
6854 // cstring is returned and ReferenceType is set to
6855 // LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr .
6856 //
6857 // If ReferenceValue is an address of an Objective-C CFString, Selector ref or
6858 // Class ref that name is returned and the ReferenceType is set accordingly.
6859 //
6860 // Lastly, literals which are Symbol address in a literal pool are looked for
6861 // and if found the symbol name is returned and ReferenceType is set to
6862 // LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr .
6863 //
6864 // If there is no item in the Mach-O file for the address passed in as
6865 // ReferenceValue nullptr is returned and ReferenceType is unchanged.
6866 static const char *GuessLiteralPointer(uint64_t ReferenceValue,
6867                                        uint64_t ReferencePC,
6868                                        uint64_t *ReferenceType,
6869                                        struct DisassembleInfo *info) {
6870   // First see if there is an external relocation entry at the ReferencePC.
6871   if (info->O->getHeader().filetype == MachO::MH_OBJECT) {
6872     uint64_t sect_addr = info->S.getAddress();
6873     uint64_t sect_offset = ReferencePC - sect_addr;
6874     bool reloc_found = false;
6875     DataRefImpl Rel;
6876     MachO::any_relocation_info RE;
6877     bool isExtern = false;
6878     SymbolRef Symbol;
6879     for (const RelocationRef &Reloc : info->S.relocations()) {
6880       uint64_t RelocOffset = Reloc.getOffset();
6881       if (RelocOffset == sect_offset) {
6882         Rel = Reloc.getRawDataRefImpl();
6883         RE = info->O->getRelocation(Rel);
6884         if (info->O->isRelocationScattered(RE))
6885           continue;
6886         isExtern = info->O->getPlainRelocationExternal(RE);
6887         if (isExtern) {
6888           symbol_iterator RelocSym = Reloc.getSymbol();
6889           Symbol = *RelocSym;
6890         }
6891         reloc_found = true;
6892         break;
6893       }
6894     }
6895     // If there is an external relocation entry for a symbol in a section
6896     // then used that symbol's value for the value of the reference.
6897     if (reloc_found && isExtern) {
6898       if (info->O->getAnyRelocationPCRel(RE)) {
6899         unsigned Type = info->O->getAnyRelocationType(RE);
6900         if (Type == MachO::X86_64_RELOC_SIGNED) {
6901           ReferenceValue = cantFail(Symbol.getValue());
6902         }
6903       }
6904     }
6905   }
6906 
6907   // Look for literals such as Objective-C CFStrings refs, Selector refs,
6908   // Message refs and Class refs.
6909   bool classref, selref, msgref, cfstring;
6910   uint64_t pointer_value = GuessPointerPointer(ReferenceValue, info, classref,
6911                                                selref, msgref, cfstring);
6912   if (classref && pointer_value == 0) {
6913     // Note the ReferenceValue is a pointer into the __objc_classrefs section.
6914     // And the pointer_value in that section is typically zero as it will be
6915     // set by dyld as part of the "bind information".
6916     const char *name = get_dyld_bind_info_symbolname(ReferenceValue, info);
6917     if (name != nullptr) {
6918       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
6919       const char *class_name = strrchr(name, '$');
6920       if (class_name != nullptr && class_name[1] == '_' &&
6921           class_name[2] != '\0') {
6922         info->class_name = class_name + 2;
6923         return name;
6924       }
6925     }
6926   }
6927 
6928   if (classref) {
6929     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
6930     const char *name =
6931         get_objc2_64bit_class_name(pointer_value, ReferenceValue, info);
6932     if (name != nullptr)
6933       info->class_name = name;
6934     else
6935       name = "bad class ref";
6936     return name;
6937   }
6938 
6939   if (cfstring) {
6940     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref;
6941     const char *name = get_objc2_64bit_cfstring_name(ReferenceValue, info);
6942     return name;
6943   }
6944 
6945   if (selref && pointer_value == 0)
6946     pointer_value = get_objc2_64bit_selref(ReferenceValue, info);
6947 
6948   if (pointer_value != 0)
6949     ReferenceValue = pointer_value;
6950 
6951   const char *name = GuessCstringPointer(ReferenceValue, info);
6952   if (name) {
6953     if (pointer_value != 0 && selref) {
6954       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref;
6955       info->selector_name = name;
6956     } else if (pointer_value != 0 && msgref) {
6957       info->class_name = nullptr;
6958       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref;
6959       info->selector_name = name;
6960     } else
6961       *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr;
6962     return name;
6963   }
6964 
6965   // Lastly look for an indirect symbol with this ReferenceValue which is in
6966   // a literal pool.  If found return that symbol name.
6967   name = GuessIndirectSymbol(ReferenceValue, info);
6968   if (name) {
6969     *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr;
6970     return name;
6971   }
6972 
6973   return nullptr;
6974 }
6975 
6976 // SymbolizerSymbolLookUp is the symbol lookup function passed when creating
6977 // the Symbolizer.  It looks up the ReferenceValue using the info passed via the
6978 // pointer to the struct DisassembleInfo that was passed when MCSymbolizer
6979 // is created and returns the symbol name that matches the ReferenceValue or
6980 // nullptr if none.  The ReferenceType is passed in for the IN type of
6981 // reference the instruction is making from the values in defined in the header
6982 // "llvm-c/Disassembler.h".  On return the ReferenceType can set to a specific
6983 // Out type and the ReferenceName will also be set which is added as a comment
6984 // to the disassembled instruction.
6985 //
6986 // If the symbol name is a C++ mangled name then the demangled name is
6987 // returned through ReferenceName and ReferenceType is set to
6988 // LLVMDisassembler_ReferenceType_DeMangled_Name .
6989 //
6990 // When this is called to get a symbol name for a branch target then the
6991 // ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then
6992 // SymbolValue will be looked for in the indirect symbol table to determine if
6993 // it is an address for a symbol stub.  If so then the symbol name for that
6994 // stub is returned indirectly through ReferenceName and then ReferenceType is
6995 // set to LLVMDisassembler_ReferenceType_Out_SymbolStub.
6996 //
6997 // When this is called with an value loaded via a PC relative load then
6998 // ReferenceType will be LLVMDisassembler_ReferenceType_In_PCrel_Load then the
6999 // SymbolValue is checked to be an address of literal pointer, symbol pointer,
7000 // or an Objective-C meta data reference.  If so the output ReferenceType is
7001 // set to correspond to that as well as setting the ReferenceName.
7002 static const char *SymbolizerSymbolLookUp(void *DisInfo,
7003                                           uint64_t ReferenceValue,
7004                                           uint64_t *ReferenceType,
7005                                           uint64_t ReferencePC,
7006                                           const char **ReferenceName) {
7007   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
7008   // If no verbose symbolic information is wanted then just return nullptr.
7009   if (!info->verbose) {
7010     *ReferenceName = nullptr;
7011     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7012     return nullptr;
7013   }
7014 
7015   const char *SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
7016 
7017   if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
7018     *ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
7019     if (*ReferenceName != nullptr) {
7020       method_reference(info, ReferenceType, ReferenceName);
7021       if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message)
7022         *ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
7023     } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
7024       if (info->demangled_name != nullptr)
7025         free(info->demangled_name);
7026       int status;
7027       info->demangled_name =
7028           itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
7029       if (info->demangled_name != nullptr) {
7030         *ReferenceName = info->demangled_name;
7031         *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
7032       } else
7033         *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7034     } else
7035       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7036   } else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
7037     *ReferenceName =
7038         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
7039     if (*ReferenceName)
7040       method_reference(info, ReferenceType, ReferenceName);
7041     else
7042       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7043     // If this is arm64 and the reference is an adrp instruction save the
7044     // instruction, passed in ReferenceValue and the address of the instruction
7045     // for use later if we see and add immediate instruction.
7046   } else if (info->O->getArch() == Triple::aarch64 &&
7047              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
7048     info->adrp_inst = ReferenceValue;
7049     info->adrp_addr = ReferencePC;
7050     SymbolName = nullptr;
7051     *ReferenceName = nullptr;
7052     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7053     // If this is arm64 and reference is an add immediate instruction and we
7054     // have
7055     // seen an adrp instruction just before it and the adrp's Xd register
7056     // matches
7057     // this add's Xn register reconstruct the value being referenced and look to
7058     // see if it is a literal pointer.  Note the add immediate instruction is
7059     // passed in ReferenceValue.
7060   } else if (info->O->getArch() == Triple::aarch64 &&
7061              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
7062              ReferencePC - 4 == info->adrp_addr &&
7063              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
7064              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
7065     uint32_t addxri_inst;
7066     uint64_t adrp_imm, addxri_imm;
7067 
7068     adrp_imm =
7069         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
7070     if (info->adrp_inst & 0x0200000)
7071       adrp_imm |= 0xfffffffffc000000LL;
7072 
7073     addxri_inst = ReferenceValue;
7074     addxri_imm = (addxri_inst >> 10) & 0xfff;
7075     if (((addxri_inst >> 22) & 0x3) == 1)
7076       addxri_imm <<= 12;
7077 
7078     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
7079                      (adrp_imm << 12) + addxri_imm;
7080 
7081     *ReferenceName =
7082         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
7083     if (*ReferenceName == nullptr)
7084       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7085     // If this is arm64 and the reference is a load register instruction and we
7086     // have seen an adrp instruction just before it and the adrp's Xd register
7087     // matches this add's Xn register reconstruct the value being referenced and
7088     // look to see if it is a literal pointer.  Note the load register
7089     // instruction is passed in ReferenceValue.
7090   } else if (info->O->getArch() == Triple::aarch64 &&
7091              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXui &&
7092              ReferencePC - 4 == info->adrp_addr &&
7093              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
7094              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
7095     uint32_t ldrxui_inst;
7096     uint64_t adrp_imm, ldrxui_imm;
7097 
7098     adrp_imm =
7099         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
7100     if (info->adrp_inst & 0x0200000)
7101       adrp_imm |= 0xfffffffffc000000LL;
7102 
7103     ldrxui_inst = ReferenceValue;
7104     ldrxui_imm = (ldrxui_inst >> 10) & 0xfff;
7105 
7106     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
7107                      (adrp_imm << 12) + (ldrxui_imm << 3);
7108 
7109     *ReferenceName =
7110         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
7111     if (*ReferenceName == nullptr)
7112       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7113   }
7114   // If this arm64 and is an load register (PC-relative) instruction the
7115   // ReferenceValue is the PC plus the immediate value.
7116   else if (info->O->getArch() == Triple::aarch64 &&
7117            (*ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXl ||
7118             *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADR)) {
7119     *ReferenceName =
7120         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
7121     if (*ReferenceName == nullptr)
7122       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7123   } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
7124     if (info->demangled_name != nullptr)
7125       free(info->demangled_name);
7126     int status;
7127     info->demangled_name =
7128         itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
7129     if (info->demangled_name != nullptr) {
7130       *ReferenceName = info->demangled_name;
7131       *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
7132     }
7133   }
7134   else {
7135     *ReferenceName = nullptr;
7136     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
7137   }
7138 
7139   return SymbolName;
7140 }
7141 
7142 /// Emits the comments that are stored in the CommentStream.
7143 /// Each comment in the CommentStream must end with a newline.
7144 static void emitComments(raw_svector_ostream &CommentStream,
7145                          SmallString<128> &CommentsToEmit,
7146                          formatted_raw_ostream &FormattedOS,
7147                          const MCAsmInfo &MAI) {
7148   // Flush the stream before taking its content.
7149   StringRef Comments = CommentsToEmit.str();
7150   // Get the default information for printing a comment.
7151   StringRef CommentBegin = MAI.getCommentString();
7152   unsigned CommentColumn = MAI.getCommentColumn();
7153   ListSeparator LS("\n");
7154   while (!Comments.empty()) {
7155     FormattedOS << LS;
7156     // Emit a line of comments.
7157     FormattedOS.PadToColumn(CommentColumn);
7158     size_t Position = Comments.find('\n');
7159     FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
7160     // Move after the newline character.
7161     Comments = Comments.substr(Position + 1);
7162   }
7163   FormattedOS.flush();
7164 
7165   // Tell the comment stream that the vector changed underneath it.
7166   CommentsToEmit.clear();
7167 }
7168 
7169 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
7170                              StringRef DisSegName, StringRef DisSectName) {
7171   const char *McpuDefault = nullptr;
7172   const Target *ThumbTarget = nullptr;
7173   const Target *TheTarget = GetTarget(MachOOF, &McpuDefault, &ThumbTarget);
7174   if (!TheTarget) {
7175     // GetTarget prints out stuff.
7176     return;
7177   }
7178   std::string MachOMCPU;
7179   if (MCPU.empty() && McpuDefault)
7180     MachOMCPU = McpuDefault;
7181   else
7182     MachOMCPU = MCPU;
7183 
7184 #define CHECK_TARGET_INFO_CREATION(NAME)                                       \
7185   do {                                                                         \
7186     if (!NAME) {                                                               \
7187       WithColor::error(errs(), "llvm-objdump")                                 \
7188           << "couldn't initialize disassembler for target " << TripleName      \
7189           << '\n';                                                             \
7190       return;                                                                  \
7191     }                                                                          \
7192   } while (false)
7193 #define CHECK_THUMB_TARGET_INFO_CREATION(NAME)                                 \
7194   do {                                                                         \
7195     if (!NAME) {                                                               \
7196       WithColor::error(errs(), "llvm-objdump")                                 \
7197           << "couldn't initialize disassembler for target " << ThumbTripleName \
7198           << '\n';                                                             \
7199       return;                                                                  \
7200     }                                                                          \
7201   } while (false)
7202 
7203   std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
7204   CHECK_TARGET_INFO_CREATION(InstrInfo);
7205   std::unique_ptr<const MCInstrInfo> ThumbInstrInfo;
7206   if (ThumbTarget) {
7207     ThumbInstrInfo.reset(ThumbTarget->createMCInstrInfo());
7208     CHECK_THUMB_TARGET_INFO_CREATION(ThumbInstrInfo);
7209   }
7210 
7211   // Package up features to be passed to target/subtarget
7212   std::string FeaturesStr;
7213   if (!MAttrs.empty()) {
7214     SubtargetFeatures Features;
7215     for (unsigned i = 0; i != MAttrs.size(); ++i)
7216       Features.AddFeature(MAttrs[i]);
7217     FeaturesStr = Features.getString();
7218   }
7219 
7220   MCTargetOptions MCOptions;
7221   // Set up disassembler.
7222   std::unique_ptr<const MCRegisterInfo> MRI(
7223       TheTarget->createMCRegInfo(TripleName));
7224   CHECK_TARGET_INFO_CREATION(MRI);
7225   std::unique_ptr<const MCAsmInfo> AsmInfo(
7226       TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
7227   CHECK_TARGET_INFO_CREATION(AsmInfo);
7228   std::unique_ptr<const MCSubtargetInfo> STI(
7229       TheTarget->createMCSubtargetInfo(TripleName, MachOMCPU, FeaturesStr));
7230   CHECK_TARGET_INFO_CREATION(STI);
7231   MCContext Ctx(Triple(TripleName), AsmInfo.get(), MRI.get(), STI.get());
7232   std::unique_ptr<MCDisassembler> DisAsm(
7233       TheTarget->createMCDisassembler(*STI, Ctx));
7234   CHECK_TARGET_INFO_CREATION(DisAsm);
7235   std::unique_ptr<MCSymbolizer> Symbolizer;
7236   struct DisassembleInfo SymbolizerInfo(nullptr, nullptr, nullptr, false);
7237   std::unique_ptr<MCRelocationInfo> RelInfo(
7238       TheTarget->createMCRelocationInfo(TripleName, Ctx));
7239   if (RelInfo) {
7240     Symbolizer.reset(TheTarget->createMCSymbolizer(
7241         TripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
7242         &SymbolizerInfo, &Ctx, std::move(RelInfo)));
7243     DisAsm->setSymbolizer(std::move(Symbolizer));
7244   }
7245   int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
7246   std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
7247       Triple(TripleName), AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI));
7248   CHECK_TARGET_INFO_CREATION(IP);
7249   // Set the display preference for hex vs. decimal immediates.
7250   IP->setPrintImmHex(PrintImmHex);
7251   // Comment stream and backing vector.
7252   SmallString<128> CommentsToEmit;
7253   raw_svector_ostream CommentStream(CommentsToEmit);
7254   // FIXME: Setting the CommentStream in the InstPrinter is problematic in that
7255   // if it is done then arm64 comments for string literals don't get printed
7256   // and some constant get printed instead and not setting it causes intel
7257   // (32-bit and 64-bit) comments printed with different spacing before the
7258   // comment causing different diffs with the 'C' disassembler library API.
7259   // IP->setCommentStream(CommentStream);
7260 
7261   // Set up separate thumb disassembler if needed.
7262   std::unique_ptr<const MCRegisterInfo> ThumbMRI;
7263   std::unique_ptr<const MCAsmInfo> ThumbAsmInfo;
7264   std::unique_ptr<const MCSubtargetInfo> ThumbSTI;
7265   std::unique_ptr<MCDisassembler> ThumbDisAsm;
7266   std::unique_ptr<MCInstPrinter> ThumbIP;
7267   std::unique_ptr<MCContext> ThumbCtx;
7268   std::unique_ptr<MCSymbolizer> ThumbSymbolizer;
7269   struct DisassembleInfo ThumbSymbolizerInfo(nullptr, nullptr, nullptr, false);
7270   std::unique_ptr<MCRelocationInfo> ThumbRelInfo;
7271   if (ThumbTarget) {
7272     ThumbMRI.reset(ThumbTarget->createMCRegInfo(ThumbTripleName));
7273     CHECK_THUMB_TARGET_INFO_CREATION(ThumbMRI);
7274     ThumbAsmInfo.reset(
7275         ThumbTarget->createMCAsmInfo(*ThumbMRI, ThumbTripleName, MCOptions));
7276     CHECK_THUMB_TARGET_INFO_CREATION(ThumbAsmInfo);
7277     ThumbSTI.reset(
7278         ThumbTarget->createMCSubtargetInfo(ThumbTripleName, MachOMCPU,
7279                                            FeaturesStr));
7280     CHECK_THUMB_TARGET_INFO_CREATION(ThumbSTI);
7281     ThumbCtx.reset(new MCContext(Triple(ThumbTripleName), ThumbAsmInfo.get(),
7282                                  ThumbMRI.get(), ThumbSTI.get()));
7283     ThumbDisAsm.reset(ThumbTarget->createMCDisassembler(*ThumbSTI, *ThumbCtx));
7284     CHECK_THUMB_TARGET_INFO_CREATION(ThumbDisAsm);
7285     MCContext *PtrThumbCtx = ThumbCtx.get();
7286     ThumbRelInfo.reset(
7287         ThumbTarget->createMCRelocationInfo(ThumbTripleName, *PtrThumbCtx));
7288     if (ThumbRelInfo) {
7289       ThumbSymbolizer.reset(ThumbTarget->createMCSymbolizer(
7290           ThumbTripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
7291           &ThumbSymbolizerInfo, PtrThumbCtx, std::move(ThumbRelInfo)));
7292       ThumbDisAsm->setSymbolizer(std::move(ThumbSymbolizer));
7293     }
7294     int ThumbAsmPrinterVariant = ThumbAsmInfo->getAssemblerDialect();
7295     ThumbIP.reset(ThumbTarget->createMCInstPrinter(
7296         Triple(ThumbTripleName), ThumbAsmPrinterVariant, *ThumbAsmInfo,
7297         *ThumbInstrInfo, *ThumbMRI));
7298     CHECK_THUMB_TARGET_INFO_CREATION(ThumbIP);
7299     // Set the display preference for hex vs. decimal immediates.
7300     ThumbIP->setPrintImmHex(PrintImmHex);
7301   }
7302 
7303 #undef CHECK_TARGET_INFO_CREATION
7304 #undef CHECK_THUMB_TARGET_INFO_CREATION
7305 
7306   MachO::mach_header Header = MachOOF->getHeader();
7307 
7308   // FIXME: Using the -cfg command line option, this code used to be able to
7309   // annotate relocations with the referenced symbol's name, and if this was
7310   // inside a __[cf]string section, the data it points to. This is now replaced
7311   // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
7312   std::vector<SectionRef> Sections;
7313   std::vector<SymbolRef> Symbols;
7314   SmallVector<uint64_t, 8> FoundFns;
7315   uint64_t BaseSegmentAddress = 0;
7316 
7317   getSectionsAndSymbols(MachOOF, Sections, Symbols, FoundFns,
7318                         BaseSegmentAddress);
7319 
7320   // Sort the symbols by address, just in case they didn't come in that way.
7321   llvm::stable_sort(Symbols, SymbolSorter());
7322 
7323   // Build a data in code table that is sorted on by the address of each entry.
7324   uint64_t BaseAddress = 0;
7325   if (Header.filetype == MachO::MH_OBJECT)
7326     BaseAddress = Sections[0].getAddress();
7327   else
7328     BaseAddress = BaseSegmentAddress;
7329   DiceTable Dices;
7330   for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
7331        DI != DE; ++DI) {
7332     uint32_t Offset;
7333     DI->getOffset(Offset);
7334     Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
7335   }
7336   array_pod_sort(Dices.begin(), Dices.end());
7337 
7338   // Try to find debug info and set up the DIContext for it.
7339   std::unique_ptr<DIContext> diContext;
7340   std::unique_ptr<Binary> DSYMBinary;
7341   std::unique_ptr<MemoryBuffer> DSYMBuf;
7342   if (UseDbg) {
7343     ObjectFile *DbgObj = MachOOF;
7344 
7345     // A separate DSym file path was specified, parse it as a macho file,
7346     // get the sections and supply it to the section name parsing machinery.
7347     if (!DSYMFile.empty()) {
7348       std::string DSYMPath(DSYMFile);
7349 
7350       // If DSYMPath is a .dSYM directory, append the Mach-O file.
7351       if (llvm::sys::fs::is_directory(DSYMPath) &&
7352           llvm::sys::path::extension(DSYMPath) == ".dSYM") {
7353         SmallString<128> ShortName(llvm::sys::path::filename(DSYMPath));
7354         llvm::sys::path::replace_extension(ShortName, "");
7355         SmallString<1024> FullPath(DSYMPath);
7356         llvm::sys::path::append(FullPath, "Contents", "Resources", "DWARF",
7357                                 ShortName);
7358         DSYMPath = std::string(FullPath.str());
7359       }
7360 
7361       // Load the file.
7362       ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
7363           MemoryBuffer::getFileOrSTDIN(DSYMPath);
7364       if (std::error_code EC = BufOrErr.getError()) {
7365         reportError(errorCodeToError(EC), DSYMPath);
7366         return;
7367       }
7368 
7369       // We need to keep the file alive, because we're replacing DbgObj with it.
7370       DSYMBuf = std::move(BufOrErr.get());
7371 
7372       Expected<std::unique_ptr<Binary>> BinaryOrErr =
7373       createBinary(DSYMBuf.get()->getMemBufferRef());
7374       if (!BinaryOrErr) {
7375         reportError(BinaryOrErr.takeError(), DSYMPath);
7376         return;
7377       }
7378 
7379       // We need to keep the Binary alive with the buffer
7380       DSYMBinary = std::move(BinaryOrErr.get());
7381       if (ObjectFile *O = dyn_cast<ObjectFile>(DSYMBinary.get())) {
7382         // this is a Mach-O object file, use it
7383         if (MachOObjectFile *MachDSYM = dyn_cast<MachOObjectFile>(&*O)) {
7384           DbgObj = MachDSYM;
7385         }
7386         else {
7387           WithColor::error(errs(), "llvm-objdump")
7388             << DSYMPath << " is not a Mach-O file type.\n";
7389           return;
7390         }
7391       }
7392       else if (auto UB = dyn_cast<MachOUniversalBinary>(DSYMBinary.get())){
7393         // this is a Universal Binary, find a Mach-O for this architecture
7394         uint32_t CPUType, CPUSubType;
7395         const char *ArchFlag;
7396         if (MachOOF->is64Bit()) {
7397           const MachO::mach_header_64 H_64 = MachOOF->getHeader64();
7398           CPUType = H_64.cputype;
7399           CPUSubType = H_64.cpusubtype;
7400         } else {
7401           const MachO::mach_header H = MachOOF->getHeader();
7402           CPUType = H.cputype;
7403           CPUSubType = H.cpusubtype;
7404         }
7405         Triple T = MachOObjectFile::getArchTriple(CPUType, CPUSubType, nullptr,
7406                                                   &ArchFlag);
7407         Expected<std::unique_ptr<MachOObjectFile>> MachDSYM =
7408             UB->getMachOObjectForArch(ArchFlag);
7409         if (!MachDSYM) {
7410           reportError(MachDSYM.takeError(), DSYMPath);
7411           return;
7412         }
7413 
7414         // We need to keep the Binary alive with the buffer
7415         DbgObj = &*MachDSYM.get();
7416         DSYMBinary = std::move(*MachDSYM);
7417       }
7418       else {
7419         WithColor::error(errs(), "llvm-objdump")
7420           << DSYMPath << " is not a Mach-O or Universal file type.\n";
7421         return;
7422       }
7423     }
7424 
7425     // Setup the DIContext
7426     diContext = DWARFContext::create(*DbgObj);
7427   }
7428 
7429   if (FilterSections.empty())
7430     outs() << "(" << DisSegName << "," << DisSectName << ") section\n";
7431 
7432   for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
7433     Expected<StringRef> SecNameOrErr = Sections[SectIdx].getName();
7434     if (!SecNameOrErr) {
7435       consumeError(SecNameOrErr.takeError());
7436       continue;
7437     }
7438     if (*SecNameOrErr != DisSectName)
7439       continue;
7440 
7441     DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
7442 
7443     StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
7444     if (SegmentName != DisSegName)
7445       continue;
7446 
7447     StringRef BytesStr =
7448         unwrapOrError(Sections[SectIdx].getContents(), Filename);
7449     ArrayRef<uint8_t> Bytes = arrayRefFromStringRef(BytesStr);
7450     uint64_t SectAddress = Sections[SectIdx].getAddress();
7451 
7452     bool symbolTableWorked = false;
7453 
7454     // Create a map of symbol addresses to symbol names for use by
7455     // the SymbolizerSymbolLookUp() routine.
7456     SymbolAddressMap AddrMap;
7457     bool DisSymNameFound = false;
7458     for (const SymbolRef &Symbol : MachOOF->symbols()) {
7459       SymbolRef::Type ST =
7460           unwrapOrError(Symbol.getType(), MachOOF->getFileName());
7461       if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
7462           ST == SymbolRef::ST_Other) {
7463         uint64_t Address = cantFail(Symbol.getValue());
7464         StringRef SymName =
7465             unwrapOrError(Symbol.getName(), MachOOF->getFileName());
7466         AddrMap[Address] = SymName;
7467         if (!DisSymName.empty() && DisSymName == SymName)
7468           DisSymNameFound = true;
7469       }
7470     }
7471     if (!DisSymName.empty() && !DisSymNameFound) {
7472       outs() << "Can't find -dis-symname: " << DisSymName << "\n";
7473       return;
7474     }
7475     // Set up the block of info used by the Symbolizer call backs.
7476     SymbolizerInfo.verbose = SymbolicOperands;
7477     SymbolizerInfo.O = MachOOF;
7478     SymbolizerInfo.S = Sections[SectIdx];
7479     SymbolizerInfo.AddrMap = &AddrMap;
7480     SymbolizerInfo.Sections = &Sections;
7481     // Same for the ThumbSymbolizer
7482     ThumbSymbolizerInfo.verbose = SymbolicOperands;
7483     ThumbSymbolizerInfo.O = MachOOF;
7484     ThumbSymbolizerInfo.S = Sections[SectIdx];
7485     ThumbSymbolizerInfo.AddrMap = &AddrMap;
7486     ThumbSymbolizerInfo.Sections = &Sections;
7487 
7488     unsigned int Arch = MachOOF->getArch();
7489 
7490     // Skip all symbols if this is a stubs file.
7491     if (Bytes.empty())
7492       return;
7493 
7494     // If the section has symbols but no symbol at the start of the section
7495     // these are used to make sure the bytes before the first symbol are
7496     // disassembled.
7497     bool FirstSymbol = true;
7498     bool FirstSymbolAtSectionStart = true;
7499 
7500     // Disassemble symbol by symbol.
7501     for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
7502       StringRef SymName =
7503           unwrapOrError(Symbols[SymIdx].getName(), MachOOF->getFileName());
7504       SymbolRef::Type ST =
7505           unwrapOrError(Symbols[SymIdx].getType(), MachOOF->getFileName());
7506       if (ST != SymbolRef::ST_Function && ST != SymbolRef::ST_Data)
7507         continue;
7508 
7509       // Make sure the symbol is defined in this section.
7510       bool containsSym = Sections[SectIdx].containsSymbol(Symbols[SymIdx]);
7511       if (!containsSym) {
7512         if (!DisSymName.empty() && DisSymName == SymName) {
7513           outs() << "-dis-symname: " << DisSymName << " not in the section\n";
7514           return;
7515         }
7516         continue;
7517       }
7518       // The __mh_execute_header is special and we need to deal with that fact
7519       // this symbol is before the start of the (__TEXT,__text) section and at the
7520       // address of the start of the __TEXT segment.  This is because this symbol
7521       // is an N_SECT symbol in the (__TEXT,__text) but its address is before the
7522       // start of the section in a standard MH_EXECUTE filetype.
7523       if (!DisSymName.empty() && DisSymName == "__mh_execute_header") {
7524         outs() << "-dis-symname: __mh_execute_header not in any section\n";
7525         return;
7526       }
7527       // When this code is trying to disassemble a symbol at a time and in the
7528       // case there is only the __mh_execute_header symbol left as in a stripped
7529       // executable, we need to deal with this by ignoring this symbol so the
7530       // whole section is disassembled and this symbol is then not displayed.
7531       if (SymName == "__mh_execute_header" || SymName == "__mh_dylib_header" ||
7532           SymName == "__mh_bundle_header" || SymName == "__mh_object_header" ||
7533           SymName == "__mh_preload_header" || SymName == "__mh_dylinker_header")
7534         continue;
7535 
7536       // If we are only disassembling one symbol see if this is that symbol.
7537       if (!DisSymName.empty() && DisSymName != SymName)
7538         continue;
7539 
7540       // Start at the address of the symbol relative to the section's address.
7541       uint64_t SectSize = Sections[SectIdx].getSize();
7542       uint64_t Start = cantFail(Symbols[SymIdx].getValue());
7543       uint64_t SectionAddress = Sections[SectIdx].getAddress();
7544       Start -= SectionAddress;
7545 
7546       if (Start > SectSize) {
7547         outs() << "section data ends, " << SymName
7548                << " lies outside valid range\n";
7549         return;
7550       }
7551 
7552       // Stop disassembling either at the beginning of the next symbol or at
7553       // the end of the section.
7554       bool containsNextSym = false;
7555       uint64_t NextSym = 0;
7556       uint64_t NextSymIdx = SymIdx + 1;
7557       while (Symbols.size() > NextSymIdx) {
7558         SymbolRef::Type NextSymType = unwrapOrError(
7559             Symbols[NextSymIdx].getType(), MachOOF->getFileName());
7560         if (NextSymType == SymbolRef::ST_Function) {
7561           containsNextSym =
7562               Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]);
7563           NextSym = cantFail(Symbols[NextSymIdx].getValue());
7564           NextSym -= SectionAddress;
7565           break;
7566         }
7567         ++NextSymIdx;
7568       }
7569 
7570       uint64_t End = containsNextSym ? std::min(NextSym, SectSize) : SectSize;
7571       uint64_t Size;
7572 
7573       symbolTableWorked = true;
7574 
7575       DataRefImpl Symb = Symbols[SymIdx].getRawDataRefImpl();
7576       uint32_t SymbolFlags = cantFail(MachOOF->getSymbolFlags(Symb));
7577       bool IsThumb = SymbolFlags & SymbolRef::SF_Thumb;
7578 
7579       // We only need the dedicated Thumb target if there's a real choice
7580       // (i.e. we're not targeting M-class) and the function is Thumb.
7581       bool UseThumbTarget = IsThumb && ThumbTarget;
7582 
7583       // If we are not specifying a symbol to start disassembly with and this
7584       // is the first symbol in the section but not at the start of the section
7585       // then move the disassembly index to the start of the section and
7586       // don't print the symbol name just yet.  This is so the bytes before the
7587       // first symbol are disassembled.
7588       uint64_t SymbolStart = Start;
7589       if (DisSymName.empty() && FirstSymbol && Start != 0) {
7590         FirstSymbolAtSectionStart = false;
7591         Start = 0;
7592       }
7593       else
7594         outs() << SymName << ":\n";
7595 
7596       DILineInfo lastLine;
7597       for (uint64_t Index = Start; Index < End; Index += Size) {
7598         MCInst Inst;
7599 
7600         // If this is the first symbol in the section and it was not at the
7601         // start of the section, see if we are at its Index now and if so print
7602         // the symbol name.
7603         if (FirstSymbol && !FirstSymbolAtSectionStart && Index == SymbolStart)
7604           outs() << SymName << ":\n";
7605 
7606         uint64_t PC = SectAddress + Index;
7607         if (LeadingAddr) {
7608           if (FullLeadingAddr) {
7609             if (MachOOF->is64Bit())
7610               outs() << format("%016" PRIx64, PC);
7611             else
7612               outs() << format("%08" PRIx64, PC);
7613           } else {
7614             outs() << format("%8" PRIx64 ":", PC);
7615           }
7616         }
7617         if (ShowRawInsn || Arch == Triple::arm)
7618           outs() << "\t";
7619 
7620         if (DumpAndSkipDataInCode(PC, Bytes.data() + Index, Dices, Size))
7621           continue;
7622 
7623         SmallVector<char, 64> AnnotationsBytes;
7624         raw_svector_ostream Annotations(AnnotationsBytes);
7625 
7626         bool gotInst;
7627         if (UseThumbTarget)
7628           gotInst = ThumbDisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
7629                                                 PC, Annotations);
7630         else
7631           gotInst = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index), PC,
7632                                            Annotations);
7633         if (gotInst) {
7634           if (ShowRawInsn || Arch == Triple::arm) {
7635             dumpBytes(makeArrayRef(Bytes.data() + Index, Size), outs());
7636           }
7637           formatted_raw_ostream FormattedOS(outs());
7638           StringRef AnnotationsStr = Annotations.str();
7639           if (UseThumbTarget)
7640             ThumbIP->printInst(&Inst, PC, AnnotationsStr, *ThumbSTI,
7641                                FormattedOS);
7642           else
7643             IP->printInst(&Inst, PC, AnnotationsStr, *STI, FormattedOS);
7644           emitComments(CommentStream, CommentsToEmit, FormattedOS, *AsmInfo);
7645 
7646           // Print debug info.
7647           if (diContext) {
7648             DILineInfo dli = diContext->getLineInfoForAddress({PC, SectIdx});
7649             // Print valid line info if it changed.
7650             if (dli != lastLine && dli.Line != 0)
7651               outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
7652                      << dli.Column;
7653             lastLine = dli;
7654           }
7655           outs() << "\n";
7656         } else {
7657           if (MachOOF->getArchTriple().isX86()) {
7658             outs() << format("\t.byte 0x%02x #bad opcode\n",
7659                              *(Bytes.data() + Index) & 0xff);
7660             Size = 1; // skip exactly one illegible byte and move on.
7661           } else if (Arch == Triple::aarch64 ||
7662                      (Arch == Triple::arm && !IsThumb)) {
7663             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
7664                               (*(Bytes.data() + Index + 1) & 0xff) << 8 |
7665                               (*(Bytes.data() + Index + 2) & 0xff) << 16 |
7666                               (*(Bytes.data() + Index + 3) & 0xff) << 24;
7667             outs() << format("\t.long\t0x%08x\n", opcode);
7668             Size = 4;
7669           } else if (Arch == Triple::arm) {
7670             assert(IsThumb && "ARM mode should have been dealt with above");
7671             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
7672                               (*(Bytes.data() + Index + 1) & 0xff) << 8;
7673             outs() << format("\t.short\t0x%04x\n", opcode);
7674             Size = 2;
7675           } else{
7676             WithColor::warning(errs(), "llvm-objdump")
7677                 << "invalid instruction encoding\n";
7678             if (Size == 0)
7679               Size = 1; // skip illegible bytes
7680           }
7681         }
7682       }
7683       // Now that we are done disassembled the first symbol set the bool that
7684       // were doing this to false.
7685       FirstSymbol = false;
7686     }
7687     if (!symbolTableWorked) {
7688       // Reading the symbol table didn't work, disassemble the whole section.
7689       uint64_t SectAddress = Sections[SectIdx].getAddress();
7690       uint64_t SectSize = Sections[SectIdx].getSize();
7691       uint64_t InstSize;
7692       for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
7693         MCInst Inst;
7694 
7695         uint64_t PC = SectAddress + Index;
7696 
7697         if (DumpAndSkipDataInCode(PC, Bytes.data() + Index, Dices, InstSize))
7698           continue;
7699 
7700         SmallVector<char, 64> AnnotationsBytes;
7701         raw_svector_ostream Annotations(AnnotationsBytes);
7702         if (DisAsm->getInstruction(Inst, InstSize, Bytes.slice(Index), PC,
7703                                    Annotations)) {
7704           if (LeadingAddr) {
7705             if (FullLeadingAddr) {
7706               if (MachOOF->is64Bit())
7707                 outs() << format("%016" PRIx64, PC);
7708               else
7709                 outs() << format("%08" PRIx64, PC);
7710             } else {
7711               outs() << format("%8" PRIx64 ":", PC);
7712             }
7713           }
7714           if (ShowRawInsn || Arch == Triple::arm) {
7715             outs() << "\t";
7716             dumpBytes(makeArrayRef(Bytes.data() + Index, InstSize), outs());
7717           }
7718           StringRef AnnotationsStr = Annotations.str();
7719           IP->printInst(&Inst, PC, AnnotationsStr, *STI, outs());
7720           outs() << "\n";
7721         } else {
7722           if (MachOOF->getArchTriple().isX86()) {
7723             outs() << format("\t.byte 0x%02x #bad opcode\n",
7724                              *(Bytes.data() + Index) & 0xff);
7725             InstSize = 1; // skip exactly one illegible byte and move on.
7726           } else {
7727             WithColor::warning(errs(), "llvm-objdump")
7728                 << "invalid instruction encoding\n";
7729             if (InstSize == 0)
7730               InstSize = 1; // skip illegible bytes
7731           }
7732         }
7733       }
7734     }
7735     // The TripleName's need to be reset if we are called again for a different
7736     // architecture.
7737     TripleName = "";
7738     ThumbTripleName = "";
7739 
7740     if (SymbolizerInfo.demangled_name != nullptr)
7741       free(SymbolizerInfo.demangled_name);
7742     if (ThumbSymbolizerInfo.demangled_name != nullptr)
7743       free(ThumbSymbolizerInfo.demangled_name);
7744   }
7745 }
7746 
7747 //===----------------------------------------------------------------------===//
7748 // __compact_unwind section dumping
7749 //===----------------------------------------------------------------------===//
7750 
7751 namespace {
7752 
7753 template <typename T>
7754 static uint64_t read(StringRef Contents, ptrdiff_t Offset) {
7755   using llvm::support::little;
7756   using llvm::support::unaligned;
7757 
7758   if (Offset + sizeof(T) > Contents.size()) {
7759     outs() << "warning: attempt to read past end of buffer\n";
7760     return T();
7761   }
7762 
7763   uint64_t Val =
7764       support::endian::read<T, little, unaligned>(Contents.data() + Offset);
7765   return Val;
7766 }
7767 
7768 template <typename T>
7769 static uint64_t readNext(StringRef Contents, ptrdiff_t &Offset) {
7770   T Val = read<T>(Contents, Offset);
7771   Offset += sizeof(T);
7772   return Val;
7773 }
7774 
7775 struct CompactUnwindEntry {
7776   uint32_t OffsetInSection;
7777 
7778   uint64_t FunctionAddr;
7779   uint32_t Length;
7780   uint32_t CompactEncoding;
7781   uint64_t PersonalityAddr;
7782   uint64_t LSDAAddr;
7783 
7784   RelocationRef FunctionReloc;
7785   RelocationRef PersonalityReloc;
7786   RelocationRef LSDAReloc;
7787 
7788   CompactUnwindEntry(StringRef Contents, unsigned Offset, bool Is64)
7789       : OffsetInSection(Offset) {
7790     if (Is64)
7791       read<uint64_t>(Contents, Offset);
7792     else
7793       read<uint32_t>(Contents, Offset);
7794   }
7795 
7796 private:
7797   template <typename UIntPtr> void read(StringRef Contents, ptrdiff_t Offset) {
7798     FunctionAddr = readNext<UIntPtr>(Contents, Offset);
7799     Length = readNext<uint32_t>(Contents, Offset);
7800     CompactEncoding = readNext<uint32_t>(Contents, Offset);
7801     PersonalityAddr = readNext<UIntPtr>(Contents, Offset);
7802     LSDAAddr = readNext<UIntPtr>(Contents, Offset);
7803   }
7804 };
7805 }
7806 
7807 /// Given a relocation from __compact_unwind, consisting of the RelocationRef
7808 /// and data being relocated, determine the best base Name and Addend to use for
7809 /// display purposes.
7810 ///
7811 /// 1. An Extern relocation will directly reference a symbol (and the data is
7812 ///    then already an addend), so use that.
7813 /// 2. Otherwise the data is an offset in the object file's layout; try to find
7814 //     a symbol before it in the same section, and use the offset from there.
7815 /// 3. Finally, if all that fails, fall back to an offset from the start of the
7816 ///    referenced section.
7817 static void findUnwindRelocNameAddend(const MachOObjectFile *Obj,
7818                                       std::map<uint64_t, SymbolRef> &Symbols,
7819                                       const RelocationRef &Reloc, uint64_t Addr,
7820                                       StringRef &Name, uint64_t &Addend) {
7821   if (Reloc.getSymbol() != Obj->symbol_end()) {
7822     Name = unwrapOrError(Reloc.getSymbol()->getName(), Obj->getFileName());
7823     Addend = Addr;
7824     return;
7825   }
7826 
7827   auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl());
7828   SectionRef RelocSection = Obj->getAnyRelocationSection(RE);
7829 
7830   uint64_t SectionAddr = RelocSection.getAddress();
7831 
7832   auto Sym = Symbols.upper_bound(Addr);
7833   if (Sym == Symbols.begin()) {
7834     // The first symbol in the object is after this reference, the best we can
7835     // do is section-relative notation.
7836     if (Expected<StringRef> NameOrErr = RelocSection.getName())
7837       Name = *NameOrErr;
7838     else
7839       consumeError(NameOrErr.takeError());
7840 
7841     Addend = Addr - SectionAddr;
7842     return;
7843   }
7844 
7845   // Go back one so that SymbolAddress <= Addr.
7846   --Sym;
7847 
7848   section_iterator SymSection =
7849       unwrapOrError(Sym->second.getSection(), Obj->getFileName());
7850   if (RelocSection == *SymSection) {
7851     // There's a valid symbol in the same section before this reference.
7852     Name = unwrapOrError(Sym->second.getName(), Obj->getFileName());
7853     Addend = Addr - Sym->first;
7854     return;
7855   }
7856 
7857   // There is a symbol before this reference, but it's in a different
7858   // section. Probably not helpful to mention it, so use the section name.
7859   if (Expected<StringRef> NameOrErr = RelocSection.getName())
7860     Name = *NameOrErr;
7861   else
7862     consumeError(NameOrErr.takeError());
7863 
7864   Addend = Addr - SectionAddr;
7865 }
7866 
7867 static void printUnwindRelocDest(const MachOObjectFile *Obj,
7868                                  std::map<uint64_t, SymbolRef> &Symbols,
7869                                  const RelocationRef &Reloc, uint64_t Addr) {
7870   StringRef Name;
7871   uint64_t Addend;
7872 
7873   if (!Reloc.getObject())
7874     return;
7875 
7876   findUnwindRelocNameAddend(Obj, Symbols, Reloc, Addr, Name, Addend);
7877 
7878   outs() << Name;
7879   if (Addend)
7880     outs() << " + " << format("0x%" PRIx64, Addend);
7881 }
7882 
7883 static void
7884 printMachOCompactUnwindSection(const MachOObjectFile *Obj,
7885                                std::map<uint64_t, SymbolRef> &Symbols,
7886                                const SectionRef &CompactUnwind) {
7887 
7888   if (!Obj->isLittleEndian()) {
7889     outs() << "Skipping big-endian __compact_unwind section\n";
7890     return;
7891   }
7892 
7893   bool Is64 = Obj->is64Bit();
7894   uint32_t PointerSize = Is64 ? sizeof(uint64_t) : sizeof(uint32_t);
7895   uint32_t EntrySize = 3 * PointerSize + 2 * sizeof(uint32_t);
7896 
7897   StringRef Contents =
7898       unwrapOrError(CompactUnwind.getContents(), Obj->getFileName());
7899   SmallVector<CompactUnwindEntry, 4> CompactUnwinds;
7900 
7901   // First populate the initial raw offsets, encodings and so on from the entry.
7902   for (unsigned Offset = 0; Offset < Contents.size(); Offset += EntrySize) {
7903     CompactUnwindEntry Entry(Contents, Offset, Is64);
7904     CompactUnwinds.push_back(Entry);
7905   }
7906 
7907   // Next we need to look at the relocations to find out what objects are
7908   // actually being referred to.
7909   for (const RelocationRef &Reloc : CompactUnwind.relocations()) {
7910     uint64_t RelocAddress = Reloc.getOffset();
7911 
7912     uint32_t EntryIdx = RelocAddress / EntrySize;
7913     uint32_t OffsetInEntry = RelocAddress - EntryIdx * EntrySize;
7914     CompactUnwindEntry &Entry = CompactUnwinds[EntryIdx];
7915 
7916     if (OffsetInEntry == 0)
7917       Entry.FunctionReloc = Reloc;
7918     else if (OffsetInEntry == PointerSize + 2 * sizeof(uint32_t))
7919       Entry.PersonalityReloc = Reloc;
7920     else if (OffsetInEntry == 2 * PointerSize + 2 * sizeof(uint32_t))
7921       Entry.LSDAReloc = Reloc;
7922     else {
7923       outs() << "Invalid relocation in __compact_unwind section\n";
7924       return;
7925     }
7926   }
7927 
7928   // Finally, we're ready to print the data we've gathered.
7929   outs() << "Contents of __compact_unwind section:\n";
7930   for (auto &Entry : CompactUnwinds) {
7931     outs() << "  Entry at offset "
7932            << format("0x%" PRIx32, Entry.OffsetInSection) << ":\n";
7933 
7934     // 1. Start of the region this entry applies to.
7935     outs() << "    start:                " << format("0x%" PRIx64,
7936                                                      Entry.FunctionAddr) << ' ';
7937     printUnwindRelocDest(Obj, Symbols, Entry.FunctionReloc, Entry.FunctionAddr);
7938     outs() << '\n';
7939 
7940     // 2. Length of the region this entry applies to.
7941     outs() << "    length:               " << format("0x%" PRIx32, Entry.Length)
7942            << '\n';
7943     // 3. The 32-bit compact encoding.
7944     outs() << "    compact encoding:     "
7945            << format("0x%08" PRIx32, Entry.CompactEncoding) << '\n';
7946 
7947     // 4. The personality function, if present.
7948     if (Entry.PersonalityReloc.getObject()) {
7949       outs() << "    personality function: "
7950              << format("0x%" PRIx64, Entry.PersonalityAddr) << ' ';
7951       printUnwindRelocDest(Obj, Symbols, Entry.PersonalityReloc,
7952                            Entry.PersonalityAddr);
7953       outs() << '\n';
7954     }
7955 
7956     // 5. This entry's language-specific data area.
7957     if (Entry.LSDAReloc.getObject()) {
7958       outs() << "    LSDA:                 " << format("0x%" PRIx64,
7959                                                        Entry.LSDAAddr) << ' ';
7960       printUnwindRelocDest(Obj, Symbols, Entry.LSDAReloc, Entry.LSDAAddr);
7961       outs() << '\n';
7962     }
7963   }
7964 }
7965 
7966 //===----------------------------------------------------------------------===//
7967 // __unwind_info section dumping
7968 //===----------------------------------------------------------------------===//
7969 
7970 static void printRegularSecondLevelUnwindPage(StringRef PageData) {
7971   ptrdiff_t Pos = 0;
7972   uint32_t Kind = readNext<uint32_t>(PageData, Pos);
7973   (void)Kind;
7974   assert(Kind == 2 && "kind for a regular 2nd level index should be 2");
7975 
7976   uint16_t EntriesStart = readNext<uint16_t>(PageData, Pos);
7977   uint16_t NumEntries = readNext<uint16_t>(PageData, Pos);
7978 
7979   Pos = EntriesStart;
7980   for (unsigned i = 0; i < NumEntries; ++i) {
7981     uint32_t FunctionOffset = readNext<uint32_t>(PageData, Pos);
7982     uint32_t Encoding = readNext<uint32_t>(PageData, Pos);
7983 
7984     outs() << "      [" << i << "]: "
7985            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
7986            << ", "
7987            << "encoding=" << format("0x%08" PRIx32, Encoding) << '\n';
7988   }
7989 }
7990 
7991 static void printCompressedSecondLevelUnwindPage(
7992     StringRef PageData, uint32_t FunctionBase,
7993     const SmallVectorImpl<uint32_t> &CommonEncodings) {
7994   ptrdiff_t Pos = 0;
7995   uint32_t Kind = readNext<uint32_t>(PageData, Pos);
7996   (void)Kind;
7997   assert(Kind == 3 && "kind for a compressed 2nd level index should be 3");
7998 
7999   uint32_t NumCommonEncodings = CommonEncodings.size();
8000   uint16_t EntriesStart = readNext<uint16_t>(PageData, Pos);
8001   uint16_t NumEntries = readNext<uint16_t>(PageData, Pos);
8002 
8003   uint16_t PageEncodingsStart = readNext<uint16_t>(PageData, Pos);
8004   uint16_t NumPageEncodings = readNext<uint16_t>(PageData, Pos);
8005   SmallVector<uint32_t, 64> PageEncodings;
8006   if (NumPageEncodings) {
8007     outs() << "      Page encodings: (count = " << NumPageEncodings << ")\n";
8008     Pos = PageEncodingsStart;
8009     for (unsigned i = 0; i < NumPageEncodings; ++i) {
8010       uint32_t Encoding = readNext<uint32_t>(PageData, Pos);
8011       PageEncodings.push_back(Encoding);
8012       outs() << "        encoding[" << (i + NumCommonEncodings)
8013              << "]: " << format("0x%08" PRIx32, Encoding) << '\n';
8014     }
8015   }
8016 
8017   Pos = EntriesStart;
8018   for (unsigned i = 0; i < NumEntries; ++i) {
8019     uint32_t Entry = readNext<uint32_t>(PageData, Pos);
8020     uint32_t FunctionOffset = FunctionBase + (Entry & 0xffffff);
8021     uint32_t EncodingIdx = Entry >> 24;
8022 
8023     uint32_t Encoding;
8024     if (EncodingIdx < NumCommonEncodings)
8025       Encoding = CommonEncodings[EncodingIdx];
8026     else
8027       Encoding = PageEncodings[EncodingIdx - NumCommonEncodings];
8028 
8029     outs() << "      [" << i << "]: "
8030            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
8031            << ", "
8032            << "encoding[" << EncodingIdx
8033            << "]=" << format("0x%08" PRIx32, Encoding) << '\n';
8034   }
8035 }
8036 
8037 static void printMachOUnwindInfoSection(const MachOObjectFile *Obj,
8038                                         std::map<uint64_t, SymbolRef> &Symbols,
8039                                         const SectionRef &UnwindInfo) {
8040 
8041   if (!Obj->isLittleEndian()) {
8042     outs() << "Skipping big-endian __unwind_info section\n";
8043     return;
8044   }
8045 
8046   outs() << "Contents of __unwind_info section:\n";
8047 
8048   StringRef Contents =
8049       unwrapOrError(UnwindInfo.getContents(), Obj->getFileName());
8050   ptrdiff_t Pos = 0;
8051 
8052   //===----------------------------------
8053   // Section header
8054   //===----------------------------------
8055 
8056   uint32_t Version = readNext<uint32_t>(Contents, Pos);
8057   outs() << "  Version:                                   "
8058          << format("0x%" PRIx32, Version) << '\n';
8059   if (Version != 1) {
8060     outs() << "    Skipping section with unknown version\n";
8061     return;
8062   }
8063 
8064   uint32_t CommonEncodingsStart = readNext<uint32_t>(Contents, Pos);
8065   outs() << "  Common encodings array section offset:     "
8066          << format("0x%" PRIx32, CommonEncodingsStart) << '\n';
8067   uint32_t NumCommonEncodings = readNext<uint32_t>(Contents, Pos);
8068   outs() << "  Number of common encodings in array:       "
8069          << format("0x%" PRIx32, NumCommonEncodings) << '\n';
8070 
8071   uint32_t PersonalitiesStart = readNext<uint32_t>(Contents, Pos);
8072   outs() << "  Personality function array section offset: "
8073          << format("0x%" PRIx32, PersonalitiesStart) << '\n';
8074   uint32_t NumPersonalities = readNext<uint32_t>(Contents, Pos);
8075   outs() << "  Number of personality functions in array:  "
8076          << format("0x%" PRIx32, NumPersonalities) << '\n';
8077 
8078   uint32_t IndicesStart = readNext<uint32_t>(Contents, Pos);
8079   outs() << "  Index array section offset:                "
8080          << format("0x%" PRIx32, IndicesStart) << '\n';
8081   uint32_t NumIndices = readNext<uint32_t>(Contents, Pos);
8082   outs() << "  Number of indices in array:                "
8083          << format("0x%" PRIx32, NumIndices) << '\n';
8084 
8085   //===----------------------------------
8086   // A shared list of common encodings
8087   //===----------------------------------
8088 
8089   // These occupy indices in the range [0, N] whenever an encoding is referenced
8090   // from a compressed 2nd level index table. In practice the linker only
8091   // creates ~128 of these, so that indices are available to embed encodings in
8092   // the 2nd level index.
8093 
8094   SmallVector<uint32_t, 64> CommonEncodings;
8095   outs() << "  Common encodings: (count = " << NumCommonEncodings << ")\n";
8096   Pos = CommonEncodingsStart;
8097   for (unsigned i = 0; i < NumCommonEncodings; ++i) {
8098     uint32_t Encoding = readNext<uint32_t>(Contents, Pos);
8099     CommonEncodings.push_back(Encoding);
8100 
8101     outs() << "    encoding[" << i << "]: " << format("0x%08" PRIx32, Encoding)
8102            << '\n';
8103   }
8104 
8105   //===----------------------------------
8106   // Personality functions used in this executable
8107   //===----------------------------------
8108 
8109   // There should be only a handful of these (one per source language,
8110   // roughly). Particularly since they only get 2 bits in the compact encoding.
8111 
8112   outs() << "  Personality functions: (count = " << NumPersonalities << ")\n";
8113   Pos = PersonalitiesStart;
8114   for (unsigned i = 0; i < NumPersonalities; ++i) {
8115     uint32_t PersonalityFn = readNext<uint32_t>(Contents, Pos);
8116     outs() << "    personality[" << i + 1
8117            << "]: " << format("0x%08" PRIx32, PersonalityFn) << '\n';
8118   }
8119 
8120   //===----------------------------------
8121   // The level 1 index entries
8122   //===----------------------------------
8123 
8124   // These specify an approximate place to start searching for the more detailed
8125   // information, sorted by PC.
8126 
8127   struct IndexEntry {
8128     uint32_t FunctionOffset;
8129     uint32_t SecondLevelPageStart;
8130     uint32_t LSDAStart;
8131   };
8132 
8133   SmallVector<IndexEntry, 4> IndexEntries;
8134 
8135   outs() << "  Top level indices: (count = " << NumIndices << ")\n";
8136   Pos = IndicesStart;
8137   for (unsigned i = 0; i < NumIndices; ++i) {
8138     IndexEntry Entry;
8139 
8140     Entry.FunctionOffset = readNext<uint32_t>(Contents, Pos);
8141     Entry.SecondLevelPageStart = readNext<uint32_t>(Contents, Pos);
8142     Entry.LSDAStart = readNext<uint32_t>(Contents, Pos);
8143     IndexEntries.push_back(Entry);
8144 
8145     outs() << "    [" << i << "]: "
8146            << "function offset=" << format("0x%08" PRIx32, Entry.FunctionOffset)
8147            << ", "
8148            << "2nd level page offset="
8149            << format("0x%08" PRIx32, Entry.SecondLevelPageStart) << ", "
8150            << "LSDA offset=" << format("0x%08" PRIx32, Entry.LSDAStart) << '\n';
8151   }
8152 
8153   //===----------------------------------
8154   // Next come the LSDA tables
8155   //===----------------------------------
8156 
8157   // The LSDA layout is rather implicit: it's a contiguous array of entries from
8158   // the first top-level index's LSDAOffset to the last (sentinel).
8159 
8160   outs() << "  LSDA descriptors:\n";
8161   Pos = IndexEntries[0].LSDAStart;
8162   const uint32_t LSDASize = 2 * sizeof(uint32_t);
8163   int NumLSDAs =
8164       (IndexEntries.back().LSDAStart - IndexEntries[0].LSDAStart) / LSDASize;
8165 
8166   for (int i = 0; i < NumLSDAs; ++i) {
8167     uint32_t FunctionOffset = readNext<uint32_t>(Contents, Pos);
8168     uint32_t LSDAOffset = readNext<uint32_t>(Contents, Pos);
8169     outs() << "    [" << i << "]: "
8170            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
8171            << ", "
8172            << "LSDA offset=" << format("0x%08" PRIx32, LSDAOffset) << '\n';
8173   }
8174 
8175   //===----------------------------------
8176   // Finally, the 2nd level indices
8177   //===----------------------------------
8178 
8179   // Generally these are 4K in size, and have 2 possible forms:
8180   //   + Regular stores up to 511 entries with disparate encodings
8181   //   + Compressed stores up to 1021 entries if few enough compact encoding
8182   //     values are used.
8183   outs() << "  Second level indices:\n";
8184   for (unsigned i = 0; i < IndexEntries.size() - 1; ++i) {
8185     // The final sentinel top-level index has no associated 2nd level page
8186     if (IndexEntries[i].SecondLevelPageStart == 0)
8187       break;
8188 
8189     outs() << "    Second level index[" << i << "]: "
8190            << "offset in section="
8191            << format("0x%08" PRIx32, IndexEntries[i].SecondLevelPageStart)
8192            << ", "
8193            << "base function offset="
8194            << format("0x%08" PRIx32, IndexEntries[i].FunctionOffset) << '\n';
8195 
8196     Pos = IndexEntries[i].SecondLevelPageStart;
8197     if (Pos + sizeof(uint32_t) > Contents.size()) {
8198       outs() << "warning: invalid offset for second level page: " << Pos << '\n';
8199       continue;
8200     }
8201 
8202     uint32_t Kind =
8203         *reinterpret_cast<const support::ulittle32_t *>(Contents.data() + Pos);
8204     if (Kind == 2)
8205       printRegularSecondLevelUnwindPage(Contents.substr(Pos, 4096));
8206     else if (Kind == 3)
8207       printCompressedSecondLevelUnwindPage(Contents.substr(Pos, 4096),
8208                                            IndexEntries[i].FunctionOffset,
8209                                            CommonEncodings);
8210     else
8211       outs() << "    Skipping 2nd level page with unknown kind " << Kind
8212              << '\n';
8213   }
8214 }
8215 
8216 void objdump::printMachOUnwindInfo(const MachOObjectFile *Obj) {
8217   std::map<uint64_t, SymbolRef> Symbols;
8218   for (const SymbolRef &SymRef : Obj->symbols()) {
8219     // Discard any undefined or absolute symbols. They're not going to take part
8220     // in the convenience lookup for unwind info and just take up resources.
8221     auto SectOrErr = SymRef.getSection();
8222     if (!SectOrErr) {
8223       // TODO: Actually report errors helpfully.
8224       consumeError(SectOrErr.takeError());
8225       continue;
8226     }
8227     section_iterator Section = *SectOrErr;
8228     if (Section == Obj->section_end())
8229       continue;
8230 
8231     uint64_t Addr = cantFail(SymRef.getValue());
8232     Symbols.insert(std::make_pair(Addr, SymRef));
8233   }
8234 
8235   for (const SectionRef &Section : Obj->sections()) {
8236     StringRef SectName;
8237     if (Expected<StringRef> NameOrErr = Section.getName())
8238       SectName = *NameOrErr;
8239     else
8240       consumeError(NameOrErr.takeError());
8241 
8242     if (SectName == "__compact_unwind")
8243       printMachOCompactUnwindSection(Obj, Symbols, Section);
8244     else if (SectName == "__unwind_info")
8245       printMachOUnwindInfoSection(Obj, Symbols, Section);
8246   }
8247 }
8248 
8249 static void PrintMachHeader(uint32_t magic, uint32_t cputype,
8250                             uint32_t cpusubtype, uint32_t filetype,
8251                             uint32_t ncmds, uint32_t sizeofcmds, uint32_t flags,
8252                             bool verbose) {
8253   outs() << "Mach header\n";
8254   outs() << "      magic cputype cpusubtype  caps    filetype ncmds "
8255             "sizeofcmds      flags\n";
8256   if (verbose) {
8257     if (magic == MachO::MH_MAGIC)
8258       outs() << "   MH_MAGIC";
8259     else if (magic == MachO::MH_MAGIC_64)
8260       outs() << "MH_MAGIC_64";
8261     else
8262       outs() << format(" 0x%08" PRIx32, magic);
8263     switch (cputype) {
8264     case MachO::CPU_TYPE_I386:
8265       outs() << "    I386";
8266       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8267       case MachO::CPU_SUBTYPE_I386_ALL:
8268         outs() << "        ALL";
8269         break;
8270       default:
8271         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8272         break;
8273       }
8274       break;
8275     case MachO::CPU_TYPE_X86_64:
8276       outs() << "  X86_64";
8277       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8278       case MachO::CPU_SUBTYPE_X86_64_ALL:
8279         outs() << "        ALL";
8280         break;
8281       case MachO::CPU_SUBTYPE_X86_64_H:
8282         outs() << "    Haswell";
8283         break;
8284       default:
8285         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8286         break;
8287       }
8288       break;
8289     case MachO::CPU_TYPE_ARM:
8290       outs() << "     ARM";
8291       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8292       case MachO::CPU_SUBTYPE_ARM_ALL:
8293         outs() << "        ALL";
8294         break;
8295       case MachO::CPU_SUBTYPE_ARM_V4T:
8296         outs() << "        V4T";
8297         break;
8298       case MachO::CPU_SUBTYPE_ARM_V5TEJ:
8299         outs() << "      V5TEJ";
8300         break;
8301       case MachO::CPU_SUBTYPE_ARM_XSCALE:
8302         outs() << "     XSCALE";
8303         break;
8304       case MachO::CPU_SUBTYPE_ARM_V6:
8305         outs() << "         V6";
8306         break;
8307       case MachO::CPU_SUBTYPE_ARM_V6M:
8308         outs() << "        V6M";
8309         break;
8310       case MachO::CPU_SUBTYPE_ARM_V7:
8311         outs() << "         V7";
8312         break;
8313       case MachO::CPU_SUBTYPE_ARM_V7EM:
8314         outs() << "       V7EM";
8315         break;
8316       case MachO::CPU_SUBTYPE_ARM_V7K:
8317         outs() << "        V7K";
8318         break;
8319       case MachO::CPU_SUBTYPE_ARM_V7M:
8320         outs() << "        V7M";
8321         break;
8322       case MachO::CPU_SUBTYPE_ARM_V7S:
8323         outs() << "        V7S";
8324         break;
8325       default:
8326         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8327         break;
8328       }
8329       break;
8330     case MachO::CPU_TYPE_ARM64:
8331       outs() << "   ARM64";
8332       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8333       case MachO::CPU_SUBTYPE_ARM64_ALL:
8334         outs() << "        ALL";
8335         break;
8336       case MachO::CPU_SUBTYPE_ARM64_V8:
8337         outs() << "         V8";
8338         break;
8339       case MachO::CPU_SUBTYPE_ARM64E:
8340         outs() << "          E";
8341         break;
8342       default:
8343         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8344         break;
8345       }
8346       break;
8347     case MachO::CPU_TYPE_ARM64_32:
8348       outs() << " ARM64_32";
8349       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8350       case MachO::CPU_SUBTYPE_ARM64_32_V8:
8351         outs() << "        V8";
8352         break;
8353       default:
8354         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8355         break;
8356       }
8357       break;
8358     case MachO::CPU_TYPE_POWERPC:
8359       outs() << "     PPC";
8360       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8361       case MachO::CPU_SUBTYPE_POWERPC_ALL:
8362         outs() << "        ALL";
8363         break;
8364       default:
8365         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8366         break;
8367       }
8368       break;
8369     case MachO::CPU_TYPE_POWERPC64:
8370       outs() << "   PPC64";
8371       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
8372       case MachO::CPU_SUBTYPE_POWERPC_ALL:
8373         outs() << "        ALL";
8374         break;
8375       default:
8376         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8377         break;
8378       }
8379       break;
8380     default:
8381       outs() << format(" %7d", cputype);
8382       outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8383       break;
8384     }
8385     if ((cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64) {
8386       outs() << " LIB64";
8387     } else {
8388       outs() << format("  0x%02" PRIx32,
8389                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
8390     }
8391     switch (filetype) {
8392     case MachO::MH_OBJECT:
8393       outs() << "      OBJECT";
8394       break;
8395     case MachO::MH_EXECUTE:
8396       outs() << "     EXECUTE";
8397       break;
8398     case MachO::MH_FVMLIB:
8399       outs() << "      FVMLIB";
8400       break;
8401     case MachO::MH_CORE:
8402       outs() << "        CORE";
8403       break;
8404     case MachO::MH_PRELOAD:
8405       outs() << "     PRELOAD";
8406       break;
8407     case MachO::MH_DYLIB:
8408       outs() << "       DYLIB";
8409       break;
8410     case MachO::MH_DYLIB_STUB:
8411       outs() << "  DYLIB_STUB";
8412       break;
8413     case MachO::MH_DYLINKER:
8414       outs() << "    DYLINKER";
8415       break;
8416     case MachO::MH_BUNDLE:
8417       outs() << "      BUNDLE";
8418       break;
8419     case MachO::MH_DSYM:
8420       outs() << "        DSYM";
8421       break;
8422     case MachO::MH_KEXT_BUNDLE:
8423       outs() << "  KEXTBUNDLE";
8424       break;
8425     default:
8426       outs() << format("  %10u", filetype);
8427       break;
8428     }
8429     outs() << format(" %5u", ncmds);
8430     outs() << format(" %10u", sizeofcmds);
8431     uint32_t f = flags;
8432     if (f & MachO::MH_NOUNDEFS) {
8433       outs() << "   NOUNDEFS";
8434       f &= ~MachO::MH_NOUNDEFS;
8435     }
8436     if (f & MachO::MH_INCRLINK) {
8437       outs() << " INCRLINK";
8438       f &= ~MachO::MH_INCRLINK;
8439     }
8440     if (f & MachO::MH_DYLDLINK) {
8441       outs() << " DYLDLINK";
8442       f &= ~MachO::MH_DYLDLINK;
8443     }
8444     if (f & MachO::MH_BINDATLOAD) {
8445       outs() << " BINDATLOAD";
8446       f &= ~MachO::MH_BINDATLOAD;
8447     }
8448     if (f & MachO::MH_PREBOUND) {
8449       outs() << " PREBOUND";
8450       f &= ~MachO::MH_PREBOUND;
8451     }
8452     if (f & MachO::MH_SPLIT_SEGS) {
8453       outs() << " SPLIT_SEGS";
8454       f &= ~MachO::MH_SPLIT_SEGS;
8455     }
8456     if (f & MachO::MH_LAZY_INIT) {
8457       outs() << " LAZY_INIT";
8458       f &= ~MachO::MH_LAZY_INIT;
8459     }
8460     if (f & MachO::MH_TWOLEVEL) {
8461       outs() << " TWOLEVEL";
8462       f &= ~MachO::MH_TWOLEVEL;
8463     }
8464     if (f & MachO::MH_FORCE_FLAT) {
8465       outs() << " FORCE_FLAT";
8466       f &= ~MachO::MH_FORCE_FLAT;
8467     }
8468     if (f & MachO::MH_NOMULTIDEFS) {
8469       outs() << " NOMULTIDEFS";
8470       f &= ~MachO::MH_NOMULTIDEFS;
8471     }
8472     if (f & MachO::MH_NOFIXPREBINDING) {
8473       outs() << " NOFIXPREBINDING";
8474       f &= ~MachO::MH_NOFIXPREBINDING;
8475     }
8476     if (f & MachO::MH_PREBINDABLE) {
8477       outs() << " PREBINDABLE";
8478       f &= ~MachO::MH_PREBINDABLE;
8479     }
8480     if (f & MachO::MH_ALLMODSBOUND) {
8481       outs() << " ALLMODSBOUND";
8482       f &= ~MachO::MH_ALLMODSBOUND;
8483     }
8484     if (f & MachO::MH_SUBSECTIONS_VIA_SYMBOLS) {
8485       outs() << " SUBSECTIONS_VIA_SYMBOLS";
8486       f &= ~MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
8487     }
8488     if (f & MachO::MH_CANONICAL) {
8489       outs() << " CANONICAL";
8490       f &= ~MachO::MH_CANONICAL;
8491     }
8492     if (f & MachO::MH_WEAK_DEFINES) {
8493       outs() << " WEAK_DEFINES";
8494       f &= ~MachO::MH_WEAK_DEFINES;
8495     }
8496     if (f & MachO::MH_BINDS_TO_WEAK) {
8497       outs() << " BINDS_TO_WEAK";
8498       f &= ~MachO::MH_BINDS_TO_WEAK;
8499     }
8500     if (f & MachO::MH_ALLOW_STACK_EXECUTION) {
8501       outs() << " ALLOW_STACK_EXECUTION";
8502       f &= ~MachO::MH_ALLOW_STACK_EXECUTION;
8503     }
8504     if (f & MachO::MH_DEAD_STRIPPABLE_DYLIB) {
8505       outs() << " DEAD_STRIPPABLE_DYLIB";
8506       f &= ~MachO::MH_DEAD_STRIPPABLE_DYLIB;
8507     }
8508     if (f & MachO::MH_PIE) {
8509       outs() << " PIE";
8510       f &= ~MachO::MH_PIE;
8511     }
8512     if (f & MachO::MH_NO_REEXPORTED_DYLIBS) {
8513       outs() << " NO_REEXPORTED_DYLIBS";
8514       f &= ~MachO::MH_NO_REEXPORTED_DYLIBS;
8515     }
8516     if (f & MachO::MH_HAS_TLV_DESCRIPTORS) {
8517       outs() << " MH_HAS_TLV_DESCRIPTORS";
8518       f &= ~MachO::MH_HAS_TLV_DESCRIPTORS;
8519     }
8520     if (f & MachO::MH_NO_HEAP_EXECUTION) {
8521       outs() << " MH_NO_HEAP_EXECUTION";
8522       f &= ~MachO::MH_NO_HEAP_EXECUTION;
8523     }
8524     if (f & MachO::MH_APP_EXTENSION_SAFE) {
8525       outs() << " APP_EXTENSION_SAFE";
8526       f &= ~MachO::MH_APP_EXTENSION_SAFE;
8527     }
8528     if (f & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) {
8529       outs() << " NLIST_OUTOFSYNC_WITH_DYLDINFO";
8530       f &= ~MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO;
8531     }
8532     if (f != 0 || flags == 0)
8533       outs() << format(" 0x%08" PRIx32, f);
8534   } else {
8535     outs() << format(" 0x%08" PRIx32, magic);
8536     outs() << format(" %7d", cputype);
8537     outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
8538     outs() << format("  0x%02" PRIx32,
8539                      (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
8540     outs() << format("  %10u", filetype);
8541     outs() << format(" %5u", ncmds);
8542     outs() << format(" %10u", sizeofcmds);
8543     outs() << format(" 0x%08" PRIx32, flags);
8544   }
8545   outs() << "\n";
8546 }
8547 
8548 static void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize,
8549                                 StringRef SegName, uint64_t vmaddr,
8550                                 uint64_t vmsize, uint64_t fileoff,
8551                                 uint64_t filesize, uint32_t maxprot,
8552                                 uint32_t initprot, uint32_t nsects,
8553                                 uint32_t flags, uint32_t object_size,
8554                                 bool verbose) {
8555   uint64_t expected_cmdsize;
8556   if (cmd == MachO::LC_SEGMENT) {
8557     outs() << "      cmd LC_SEGMENT\n";
8558     expected_cmdsize = nsects;
8559     expected_cmdsize *= sizeof(struct MachO::section);
8560     expected_cmdsize += sizeof(struct MachO::segment_command);
8561   } else {
8562     outs() << "      cmd LC_SEGMENT_64\n";
8563     expected_cmdsize = nsects;
8564     expected_cmdsize *= sizeof(struct MachO::section_64);
8565     expected_cmdsize += sizeof(struct MachO::segment_command_64);
8566   }
8567   outs() << "  cmdsize " << cmdsize;
8568   if (cmdsize != expected_cmdsize)
8569     outs() << " Inconsistent size\n";
8570   else
8571     outs() << "\n";
8572   outs() << "  segname " << SegName << "\n";
8573   if (cmd == MachO::LC_SEGMENT_64) {
8574     outs() << "   vmaddr " << format("0x%016" PRIx64, vmaddr) << "\n";
8575     outs() << "   vmsize " << format("0x%016" PRIx64, vmsize) << "\n";
8576   } else {
8577     outs() << "   vmaddr " << format("0x%08" PRIx64, vmaddr) << "\n";
8578     outs() << "   vmsize " << format("0x%08" PRIx64, vmsize) << "\n";
8579   }
8580   outs() << "  fileoff " << fileoff;
8581   if (fileoff > object_size)
8582     outs() << " (past end of file)\n";
8583   else
8584     outs() << "\n";
8585   outs() << " filesize " << filesize;
8586   if (fileoff + filesize > object_size)
8587     outs() << " (past end of file)\n";
8588   else
8589     outs() << "\n";
8590   if (verbose) {
8591     if ((maxprot &
8592          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
8593            MachO::VM_PROT_EXECUTE)) != 0)
8594       outs() << "  maxprot ?" << format("0x%08" PRIx32, maxprot) << "\n";
8595     else {
8596       outs() << "  maxprot ";
8597       outs() << ((maxprot & MachO::VM_PROT_READ) ? "r" : "-");
8598       outs() << ((maxprot & MachO::VM_PROT_WRITE) ? "w" : "-");
8599       outs() << ((maxprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
8600     }
8601     if ((initprot &
8602          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
8603            MachO::VM_PROT_EXECUTE)) != 0)
8604       outs() << " initprot ?" << format("0x%08" PRIx32, initprot) << "\n";
8605     else {
8606       outs() << " initprot ";
8607       outs() << ((initprot & MachO::VM_PROT_READ) ? "r" : "-");
8608       outs() << ((initprot & MachO::VM_PROT_WRITE) ? "w" : "-");
8609       outs() << ((initprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
8610     }
8611   } else {
8612     outs() << "  maxprot " << format("0x%08" PRIx32, maxprot) << "\n";
8613     outs() << " initprot " << format("0x%08" PRIx32, initprot) << "\n";
8614   }
8615   outs() << "   nsects " << nsects << "\n";
8616   if (verbose) {
8617     outs() << "    flags";
8618     if (flags == 0)
8619       outs() << " (none)\n";
8620     else {
8621       if (flags & MachO::SG_HIGHVM) {
8622         outs() << " HIGHVM";
8623         flags &= ~MachO::SG_HIGHVM;
8624       }
8625       if (flags & MachO::SG_FVMLIB) {
8626         outs() << " FVMLIB";
8627         flags &= ~MachO::SG_FVMLIB;
8628       }
8629       if (flags & MachO::SG_NORELOC) {
8630         outs() << " NORELOC";
8631         flags &= ~MachO::SG_NORELOC;
8632       }
8633       if (flags & MachO::SG_PROTECTED_VERSION_1) {
8634         outs() << " PROTECTED_VERSION_1";
8635         flags &= ~MachO::SG_PROTECTED_VERSION_1;
8636       }
8637       if (flags)
8638         outs() << format(" 0x%08" PRIx32, flags) << " (unknown flags)\n";
8639       else
8640         outs() << "\n";
8641     }
8642   } else {
8643     outs() << "    flags " << format("0x%" PRIx32, flags) << "\n";
8644   }
8645 }
8646 
8647 static void PrintSection(const char *sectname, const char *segname,
8648                          uint64_t addr, uint64_t size, uint32_t offset,
8649                          uint32_t align, uint32_t reloff, uint32_t nreloc,
8650                          uint32_t flags, uint32_t reserved1, uint32_t reserved2,
8651                          uint32_t cmd, const char *sg_segname,
8652                          uint32_t filetype, uint32_t object_size,
8653                          bool verbose) {
8654   outs() << "Section\n";
8655   outs() << "  sectname " << format("%.16s\n", sectname);
8656   outs() << "   segname " << format("%.16s", segname);
8657   if (filetype != MachO::MH_OBJECT && strncmp(sg_segname, segname, 16) != 0)
8658     outs() << " (does not match segment)\n";
8659   else
8660     outs() << "\n";
8661   if (cmd == MachO::LC_SEGMENT_64) {
8662     outs() << "      addr " << format("0x%016" PRIx64, addr) << "\n";
8663     outs() << "      size " << format("0x%016" PRIx64, size);
8664   } else {
8665     outs() << "      addr " << format("0x%08" PRIx64, addr) << "\n";
8666     outs() << "      size " << format("0x%08" PRIx64, size);
8667   }
8668   if ((flags & MachO::S_ZEROFILL) != 0 && offset + size > object_size)
8669     outs() << " (past end of file)\n";
8670   else
8671     outs() << "\n";
8672   outs() << "    offset " << offset;
8673   if (offset > object_size)
8674     outs() << " (past end of file)\n";
8675   else
8676     outs() << "\n";
8677   uint32_t align_shifted = 1 << align;
8678   outs() << "     align 2^" << align << " (" << align_shifted << ")\n";
8679   outs() << "    reloff " << reloff;
8680   if (reloff > object_size)
8681     outs() << " (past end of file)\n";
8682   else
8683     outs() << "\n";
8684   outs() << "    nreloc " << nreloc;
8685   if (reloff + nreloc * sizeof(struct MachO::relocation_info) > object_size)
8686     outs() << " (past end of file)\n";
8687   else
8688     outs() << "\n";
8689   uint32_t section_type = flags & MachO::SECTION_TYPE;
8690   if (verbose) {
8691     outs() << "      type";
8692     if (section_type == MachO::S_REGULAR)
8693       outs() << " S_REGULAR\n";
8694     else if (section_type == MachO::S_ZEROFILL)
8695       outs() << " S_ZEROFILL\n";
8696     else if (section_type == MachO::S_CSTRING_LITERALS)
8697       outs() << " S_CSTRING_LITERALS\n";
8698     else if (section_type == MachO::S_4BYTE_LITERALS)
8699       outs() << " S_4BYTE_LITERALS\n";
8700     else if (section_type == MachO::S_8BYTE_LITERALS)
8701       outs() << " S_8BYTE_LITERALS\n";
8702     else if (section_type == MachO::S_16BYTE_LITERALS)
8703       outs() << " S_16BYTE_LITERALS\n";
8704     else if (section_type == MachO::S_LITERAL_POINTERS)
8705       outs() << " S_LITERAL_POINTERS\n";
8706     else if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS)
8707       outs() << " S_NON_LAZY_SYMBOL_POINTERS\n";
8708     else if (section_type == MachO::S_LAZY_SYMBOL_POINTERS)
8709       outs() << " S_LAZY_SYMBOL_POINTERS\n";
8710     else if (section_type == MachO::S_SYMBOL_STUBS)
8711       outs() << " S_SYMBOL_STUBS\n";
8712     else if (section_type == MachO::S_MOD_INIT_FUNC_POINTERS)
8713       outs() << " S_MOD_INIT_FUNC_POINTERS\n";
8714     else if (section_type == MachO::S_MOD_TERM_FUNC_POINTERS)
8715       outs() << " S_MOD_TERM_FUNC_POINTERS\n";
8716     else if (section_type == MachO::S_COALESCED)
8717       outs() << " S_COALESCED\n";
8718     else if (section_type == MachO::S_INTERPOSING)
8719       outs() << " S_INTERPOSING\n";
8720     else if (section_type == MachO::S_DTRACE_DOF)
8721       outs() << " S_DTRACE_DOF\n";
8722     else if (section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS)
8723       outs() << " S_LAZY_DYLIB_SYMBOL_POINTERS\n";
8724     else if (section_type == MachO::S_THREAD_LOCAL_REGULAR)
8725       outs() << " S_THREAD_LOCAL_REGULAR\n";
8726     else if (section_type == MachO::S_THREAD_LOCAL_ZEROFILL)
8727       outs() << " S_THREAD_LOCAL_ZEROFILL\n";
8728     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLES)
8729       outs() << " S_THREAD_LOCAL_VARIABLES\n";
8730     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
8731       outs() << " S_THREAD_LOCAL_VARIABLE_POINTERS\n";
8732     else if (section_type == MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS)
8733       outs() << " S_THREAD_LOCAL_INIT_FUNCTION_POINTERS\n";
8734     else
8735       outs() << format("0x%08" PRIx32, section_type) << "\n";
8736     outs() << "attributes";
8737     uint32_t section_attributes = flags & MachO::SECTION_ATTRIBUTES;
8738     if (section_attributes & MachO::S_ATTR_PURE_INSTRUCTIONS)
8739       outs() << " PURE_INSTRUCTIONS";
8740     if (section_attributes & MachO::S_ATTR_NO_TOC)
8741       outs() << " NO_TOC";
8742     if (section_attributes & MachO::S_ATTR_STRIP_STATIC_SYMS)
8743       outs() << " STRIP_STATIC_SYMS";
8744     if (section_attributes & MachO::S_ATTR_NO_DEAD_STRIP)
8745       outs() << " NO_DEAD_STRIP";
8746     if (section_attributes & MachO::S_ATTR_LIVE_SUPPORT)
8747       outs() << " LIVE_SUPPORT";
8748     if (section_attributes & MachO::S_ATTR_SELF_MODIFYING_CODE)
8749       outs() << " SELF_MODIFYING_CODE";
8750     if (section_attributes & MachO::S_ATTR_DEBUG)
8751       outs() << " DEBUG";
8752     if (section_attributes & MachO::S_ATTR_SOME_INSTRUCTIONS)
8753       outs() << " SOME_INSTRUCTIONS";
8754     if (section_attributes & MachO::S_ATTR_EXT_RELOC)
8755       outs() << " EXT_RELOC";
8756     if (section_attributes & MachO::S_ATTR_LOC_RELOC)
8757       outs() << " LOC_RELOC";
8758     if (section_attributes == 0)
8759       outs() << " (none)";
8760     outs() << "\n";
8761   } else
8762     outs() << "     flags " << format("0x%08" PRIx32, flags) << "\n";
8763   outs() << " reserved1 " << reserved1;
8764   if (section_type == MachO::S_SYMBOL_STUBS ||
8765       section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
8766       section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
8767       section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
8768       section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
8769     outs() << " (index into indirect symbol table)\n";
8770   else
8771     outs() << "\n";
8772   outs() << " reserved2 " << reserved2;
8773   if (section_type == MachO::S_SYMBOL_STUBS)
8774     outs() << " (size of stubs)\n";
8775   else
8776     outs() << "\n";
8777 }
8778 
8779 static void PrintSymtabLoadCommand(MachO::symtab_command st, bool Is64Bit,
8780                                    uint32_t object_size) {
8781   outs() << "     cmd LC_SYMTAB\n";
8782   outs() << " cmdsize " << st.cmdsize;
8783   if (st.cmdsize != sizeof(struct MachO::symtab_command))
8784     outs() << " Incorrect size\n";
8785   else
8786     outs() << "\n";
8787   outs() << "  symoff " << st.symoff;
8788   if (st.symoff > object_size)
8789     outs() << " (past end of file)\n";
8790   else
8791     outs() << "\n";
8792   outs() << "   nsyms " << st.nsyms;
8793   uint64_t big_size;
8794   if (Is64Bit) {
8795     big_size = st.nsyms;
8796     big_size *= sizeof(struct MachO::nlist_64);
8797     big_size += st.symoff;
8798     if (big_size > object_size)
8799       outs() << " (past end of file)\n";
8800     else
8801       outs() << "\n";
8802   } else {
8803     big_size = st.nsyms;
8804     big_size *= sizeof(struct MachO::nlist);
8805     big_size += st.symoff;
8806     if (big_size > object_size)
8807       outs() << " (past end of file)\n";
8808     else
8809       outs() << "\n";
8810   }
8811   outs() << "  stroff " << st.stroff;
8812   if (st.stroff > object_size)
8813     outs() << " (past end of file)\n";
8814   else
8815     outs() << "\n";
8816   outs() << " strsize " << st.strsize;
8817   big_size = st.stroff;
8818   big_size += st.strsize;
8819   if (big_size > object_size)
8820     outs() << " (past end of file)\n";
8821   else
8822     outs() << "\n";
8823 }
8824 
8825 static void PrintDysymtabLoadCommand(MachO::dysymtab_command dyst,
8826                                      uint32_t nsyms, uint32_t object_size,
8827                                      bool Is64Bit) {
8828   outs() << "            cmd LC_DYSYMTAB\n";
8829   outs() << "        cmdsize " << dyst.cmdsize;
8830   if (dyst.cmdsize != sizeof(struct MachO::dysymtab_command))
8831     outs() << " Incorrect size\n";
8832   else
8833     outs() << "\n";
8834   outs() << "      ilocalsym " << dyst.ilocalsym;
8835   if (dyst.ilocalsym > nsyms)
8836     outs() << " (greater than the number of symbols)\n";
8837   else
8838     outs() << "\n";
8839   outs() << "      nlocalsym " << dyst.nlocalsym;
8840   uint64_t big_size;
8841   big_size = dyst.ilocalsym;
8842   big_size += dyst.nlocalsym;
8843   if (big_size > nsyms)
8844     outs() << " (past the end of the symbol table)\n";
8845   else
8846     outs() << "\n";
8847   outs() << "     iextdefsym " << dyst.iextdefsym;
8848   if (dyst.iextdefsym > nsyms)
8849     outs() << " (greater than the number of symbols)\n";
8850   else
8851     outs() << "\n";
8852   outs() << "     nextdefsym " << dyst.nextdefsym;
8853   big_size = dyst.iextdefsym;
8854   big_size += dyst.nextdefsym;
8855   if (big_size > nsyms)
8856     outs() << " (past the end of the symbol table)\n";
8857   else
8858     outs() << "\n";
8859   outs() << "      iundefsym " << dyst.iundefsym;
8860   if (dyst.iundefsym > nsyms)
8861     outs() << " (greater than the number of symbols)\n";
8862   else
8863     outs() << "\n";
8864   outs() << "      nundefsym " << dyst.nundefsym;
8865   big_size = dyst.iundefsym;
8866   big_size += dyst.nundefsym;
8867   if (big_size > nsyms)
8868     outs() << " (past the end of the symbol table)\n";
8869   else
8870     outs() << "\n";
8871   outs() << "         tocoff " << dyst.tocoff;
8872   if (dyst.tocoff > object_size)
8873     outs() << " (past end of file)\n";
8874   else
8875     outs() << "\n";
8876   outs() << "           ntoc " << dyst.ntoc;
8877   big_size = dyst.ntoc;
8878   big_size *= sizeof(struct MachO::dylib_table_of_contents);
8879   big_size += dyst.tocoff;
8880   if (big_size > object_size)
8881     outs() << " (past end of file)\n";
8882   else
8883     outs() << "\n";
8884   outs() << "      modtaboff " << dyst.modtaboff;
8885   if (dyst.modtaboff > object_size)
8886     outs() << " (past end of file)\n";
8887   else
8888     outs() << "\n";
8889   outs() << "        nmodtab " << dyst.nmodtab;
8890   uint64_t modtabend;
8891   if (Is64Bit) {
8892     modtabend = dyst.nmodtab;
8893     modtabend *= sizeof(struct MachO::dylib_module_64);
8894     modtabend += dyst.modtaboff;
8895   } else {
8896     modtabend = dyst.nmodtab;
8897     modtabend *= sizeof(struct MachO::dylib_module);
8898     modtabend += dyst.modtaboff;
8899   }
8900   if (modtabend > object_size)
8901     outs() << " (past end of file)\n";
8902   else
8903     outs() << "\n";
8904   outs() << "   extrefsymoff " << dyst.extrefsymoff;
8905   if (dyst.extrefsymoff > object_size)
8906     outs() << " (past end of file)\n";
8907   else
8908     outs() << "\n";
8909   outs() << "    nextrefsyms " << dyst.nextrefsyms;
8910   big_size = dyst.nextrefsyms;
8911   big_size *= sizeof(struct MachO::dylib_reference);
8912   big_size += dyst.extrefsymoff;
8913   if (big_size > object_size)
8914     outs() << " (past end of file)\n";
8915   else
8916     outs() << "\n";
8917   outs() << " indirectsymoff " << dyst.indirectsymoff;
8918   if (dyst.indirectsymoff > object_size)
8919     outs() << " (past end of file)\n";
8920   else
8921     outs() << "\n";
8922   outs() << "  nindirectsyms " << dyst.nindirectsyms;
8923   big_size = dyst.nindirectsyms;
8924   big_size *= sizeof(uint32_t);
8925   big_size += dyst.indirectsymoff;
8926   if (big_size > object_size)
8927     outs() << " (past end of file)\n";
8928   else
8929     outs() << "\n";
8930   outs() << "      extreloff " << dyst.extreloff;
8931   if (dyst.extreloff > object_size)
8932     outs() << " (past end of file)\n";
8933   else
8934     outs() << "\n";
8935   outs() << "        nextrel " << dyst.nextrel;
8936   big_size = dyst.nextrel;
8937   big_size *= sizeof(struct MachO::relocation_info);
8938   big_size += dyst.extreloff;
8939   if (big_size > object_size)
8940     outs() << " (past end of file)\n";
8941   else
8942     outs() << "\n";
8943   outs() << "      locreloff " << dyst.locreloff;
8944   if (dyst.locreloff > object_size)
8945     outs() << " (past end of file)\n";
8946   else
8947     outs() << "\n";
8948   outs() << "        nlocrel " << dyst.nlocrel;
8949   big_size = dyst.nlocrel;
8950   big_size *= sizeof(struct MachO::relocation_info);
8951   big_size += dyst.locreloff;
8952   if (big_size > object_size)
8953     outs() << " (past end of file)\n";
8954   else
8955     outs() << "\n";
8956 }
8957 
8958 static void PrintDyldInfoLoadCommand(MachO::dyld_info_command dc,
8959                                      uint32_t object_size) {
8960   if (dc.cmd == MachO::LC_DYLD_INFO)
8961     outs() << "            cmd LC_DYLD_INFO\n";
8962   else
8963     outs() << "            cmd LC_DYLD_INFO_ONLY\n";
8964   outs() << "        cmdsize " << dc.cmdsize;
8965   if (dc.cmdsize != sizeof(struct MachO::dyld_info_command))
8966     outs() << " Incorrect size\n";
8967   else
8968     outs() << "\n";
8969   outs() << "     rebase_off " << dc.rebase_off;
8970   if (dc.rebase_off > object_size)
8971     outs() << " (past end of file)\n";
8972   else
8973     outs() << "\n";
8974   outs() << "    rebase_size " << dc.rebase_size;
8975   uint64_t big_size;
8976   big_size = dc.rebase_off;
8977   big_size += dc.rebase_size;
8978   if (big_size > object_size)
8979     outs() << " (past end of file)\n";
8980   else
8981     outs() << "\n";
8982   outs() << "       bind_off " << dc.bind_off;
8983   if (dc.bind_off > object_size)
8984     outs() << " (past end of file)\n";
8985   else
8986     outs() << "\n";
8987   outs() << "      bind_size " << dc.bind_size;
8988   big_size = dc.bind_off;
8989   big_size += dc.bind_size;
8990   if (big_size > object_size)
8991     outs() << " (past end of file)\n";
8992   else
8993     outs() << "\n";
8994   outs() << "  weak_bind_off " << dc.weak_bind_off;
8995   if (dc.weak_bind_off > object_size)
8996     outs() << " (past end of file)\n";
8997   else
8998     outs() << "\n";
8999   outs() << " weak_bind_size " << dc.weak_bind_size;
9000   big_size = dc.weak_bind_off;
9001   big_size += dc.weak_bind_size;
9002   if (big_size > object_size)
9003     outs() << " (past end of file)\n";
9004   else
9005     outs() << "\n";
9006   outs() << "  lazy_bind_off " << dc.lazy_bind_off;
9007   if (dc.lazy_bind_off > object_size)
9008     outs() << " (past end of file)\n";
9009   else
9010     outs() << "\n";
9011   outs() << " lazy_bind_size " << dc.lazy_bind_size;
9012   big_size = dc.lazy_bind_off;
9013   big_size += dc.lazy_bind_size;
9014   if (big_size > object_size)
9015     outs() << " (past end of file)\n";
9016   else
9017     outs() << "\n";
9018   outs() << "     export_off " << dc.export_off;
9019   if (dc.export_off > object_size)
9020     outs() << " (past end of file)\n";
9021   else
9022     outs() << "\n";
9023   outs() << "    export_size " << dc.export_size;
9024   big_size = dc.export_off;
9025   big_size += dc.export_size;
9026   if (big_size > object_size)
9027     outs() << " (past end of file)\n";
9028   else
9029     outs() << "\n";
9030 }
9031 
9032 static void PrintDyldLoadCommand(MachO::dylinker_command dyld,
9033                                  const char *Ptr) {
9034   if (dyld.cmd == MachO::LC_ID_DYLINKER)
9035     outs() << "          cmd LC_ID_DYLINKER\n";
9036   else if (dyld.cmd == MachO::LC_LOAD_DYLINKER)
9037     outs() << "          cmd LC_LOAD_DYLINKER\n";
9038   else if (dyld.cmd == MachO::LC_DYLD_ENVIRONMENT)
9039     outs() << "          cmd LC_DYLD_ENVIRONMENT\n";
9040   else
9041     outs() << "          cmd ?(" << dyld.cmd << ")\n";
9042   outs() << "      cmdsize " << dyld.cmdsize;
9043   if (dyld.cmdsize < sizeof(struct MachO::dylinker_command))
9044     outs() << " Incorrect size\n";
9045   else
9046     outs() << "\n";
9047   if (dyld.name >= dyld.cmdsize)
9048     outs() << "         name ?(bad offset " << dyld.name << ")\n";
9049   else {
9050     const char *P = (const char *)(Ptr) + dyld.name;
9051     outs() << "         name " << P << " (offset " << dyld.name << ")\n";
9052   }
9053 }
9054 
9055 static void PrintUuidLoadCommand(MachO::uuid_command uuid) {
9056   outs() << "     cmd LC_UUID\n";
9057   outs() << " cmdsize " << uuid.cmdsize;
9058   if (uuid.cmdsize != sizeof(struct MachO::uuid_command))
9059     outs() << " Incorrect size\n";
9060   else
9061     outs() << "\n";
9062   outs() << "    uuid ";
9063   for (int i = 0; i < 16; ++i) {
9064     outs() << format("%02" PRIX32, uuid.uuid[i]);
9065     if (i == 3 || i == 5 || i == 7 || i == 9)
9066       outs() << "-";
9067   }
9068   outs() << "\n";
9069 }
9070 
9071 static void PrintRpathLoadCommand(MachO::rpath_command rpath, const char *Ptr) {
9072   outs() << "          cmd LC_RPATH\n";
9073   outs() << "      cmdsize " << rpath.cmdsize;
9074   if (rpath.cmdsize < sizeof(struct MachO::rpath_command))
9075     outs() << " Incorrect size\n";
9076   else
9077     outs() << "\n";
9078   if (rpath.path >= rpath.cmdsize)
9079     outs() << "         path ?(bad offset " << rpath.path << ")\n";
9080   else {
9081     const char *P = (const char *)(Ptr) + rpath.path;
9082     outs() << "         path " << P << " (offset " << rpath.path << ")\n";
9083   }
9084 }
9085 
9086 static void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
9087   StringRef LoadCmdName;
9088   switch (vd.cmd) {
9089   case MachO::LC_VERSION_MIN_MACOSX:
9090     LoadCmdName = "LC_VERSION_MIN_MACOSX";
9091     break;
9092   case MachO::LC_VERSION_MIN_IPHONEOS:
9093     LoadCmdName = "LC_VERSION_MIN_IPHONEOS";
9094     break;
9095   case MachO::LC_VERSION_MIN_TVOS:
9096     LoadCmdName = "LC_VERSION_MIN_TVOS";
9097     break;
9098   case MachO::LC_VERSION_MIN_WATCHOS:
9099     LoadCmdName = "LC_VERSION_MIN_WATCHOS";
9100     break;
9101   default:
9102     llvm_unreachable("Unknown version min load command");
9103   }
9104 
9105   outs() << "      cmd " << LoadCmdName << '\n';
9106   outs() << "  cmdsize " << vd.cmdsize;
9107   if (vd.cmdsize != sizeof(struct MachO::version_min_command))
9108     outs() << " Incorrect size\n";
9109   else
9110     outs() << "\n";
9111   outs() << "  version "
9112          << MachOObjectFile::getVersionMinMajor(vd, false) << "."
9113          << MachOObjectFile::getVersionMinMinor(vd, false);
9114   uint32_t Update = MachOObjectFile::getVersionMinUpdate(vd, false);
9115   if (Update != 0)
9116     outs() << "." << Update;
9117   outs() << "\n";
9118   if (vd.sdk == 0)
9119     outs() << "      sdk n/a";
9120   else {
9121     outs() << "      sdk "
9122            << MachOObjectFile::getVersionMinMajor(vd, true) << "."
9123            << MachOObjectFile::getVersionMinMinor(vd, true);
9124   }
9125   Update = MachOObjectFile::getVersionMinUpdate(vd, true);
9126   if (Update != 0)
9127     outs() << "." << Update;
9128   outs() << "\n";
9129 }
9130 
9131 static void PrintNoteLoadCommand(MachO::note_command Nt) {
9132   outs() << "       cmd LC_NOTE\n";
9133   outs() << "   cmdsize " << Nt.cmdsize;
9134   if (Nt.cmdsize != sizeof(struct MachO::note_command))
9135     outs() << " Incorrect size\n";
9136   else
9137     outs() << "\n";
9138   const char *d = Nt.data_owner;
9139   outs() << "data_owner " << format("%.16s\n", d);
9140   outs() << "    offset " << Nt.offset << "\n";
9141   outs() << "      size " << Nt.size << "\n";
9142 }
9143 
9144 static void PrintBuildToolVersion(MachO::build_tool_version bv) {
9145   outs() << "      tool " << MachOObjectFile::getBuildTool(bv.tool) << "\n";
9146   outs() << "   version " << MachOObjectFile::getVersionString(bv.version)
9147          << "\n";
9148 }
9149 
9150 static void PrintBuildVersionLoadCommand(const MachOObjectFile *obj,
9151                                          MachO::build_version_command bd) {
9152   outs() << "       cmd LC_BUILD_VERSION\n";
9153   outs() << "   cmdsize " << bd.cmdsize;
9154   if (bd.cmdsize !=
9155       sizeof(struct MachO::build_version_command) +
9156           bd.ntools * sizeof(struct MachO::build_tool_version))
9157     outs() << " Incorrect size\n";
9158   else
9159     outs() << "\n";
9160   outs() << "  platform " << MachOObjectFile::getBuildPlatform(bd.platform)
9161          << "\n";
9162   if (bd.sdk)
9163     outs() << "       sdk " << MachOObjectFile::getVersionString(bd.sdk)
9164            << "\n";
9165   else
9166     outs() << "       sdk n/a\n";
9167   outs() << "     minos " << MachOObjectFile::getVersionString(bd.minos)
9168          << "\n";
9169   outs() << "    ntools " << bd.ntools << "\n";
9170   for (unsigned i = 0; i < bd.ntools; ++i) {
9171     MachO::build_tool_version bv = obj->getBuildToolVersion(i);
9172     PrintBuildToolVersion(bv);
9173   }
9174 }
9175 
9176 static void PrintSourceVersionCommand(MachO::source_version_command sd) {
9177   outs() << "      cmd LC_SOURCE_VERSION\n";
9178   outs() << "  cmdsize " << sd.cmdsize;
9179   if (sd.cmdsize != sizeof(struct MachO::source_version_command))
9180     outs() << " Incorrect size\n";
9181   else
9182     outs() << "\n";
9183   uint64_t a = (sd.version >> 40) & 0xffffff;
9184   uint64_t b = (sd.version >> 30) & 0x3ff;
9185   uint64_t c = (sd.version >> 20) & 0x3ff;
9186   uint64_t d = (sd.version >> 10) & 0x3ff;
9187   uint64_t e = sd.version & 0x3ff;
9188   outs() << "  version " << a << "." << b;
9189   if (e != 0)
9190     outs() << "." << c << "." << d << "." << e;
9191   else if (d != 0)
9192     outs() << "." << c << "." << d;
9193   else if (c != 0)
9194     outs() << "." << c;
9195   outs() << "\n";
9196 }
9197 
9198 static void PrintEntryPointCommand(MachO::entry_point_command ep) {
9199   outs() << "       cmd LC_MAIN\n";
9200   outs() << "   cmdsize " << ep.cmdsize;
9201   if (ep.cmdsize != sizeof(struct MachO::entry_point_command))
9202     outs() << " Incorrect size\n";
9203   else
9204     outs() << "\n";
9205   outs() << "  entryoff " << ep.entryoff << "\n";
9206   outs() << " stacksize " << ep.stacksize << "\n";
9207 }
9208 
9209 static void PrintEncryptionInfoCommand(MachO::encryption_info_command ec,
9210                                        uint32_t object_size) {
9211   outs() << "          cmd LC_ENCRYPTION_INFO\n";
9212   outs() << "      cmdsize " << ec.cmdsize;
9213   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command))
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 }
9229 
9230 static void PrintEncryptionInfoCommand64(MachO::encryption_info_command_64 ec,
9231                                          uint32_t object_size) {
9232   outs() << "          cmd LC_ENCRYPTION_INFO_64\n";
9233   outs() << "      cmdsize " << ec.cmdsize;
9234   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command_64))
9235     outs() << " Incorrect size\n";
9236   else
9237     outs() << "\n";
9238   outs() << "     cryptoff " << ec.cryptoff;
9239   if (ec.cryptoff > object_size)
9240     outs() << " (past end of file)\n";
9241   else
9242     outs() << "\n";
9243   outs() << "    cryptsize " << ec.cryptsize;
9244   if (ec.cryptsize > object_size)
9245     outs() << " (past end of file)\n";
9246   else
9247     outs() << "\n";
9248   outs() << "      cryptid " << ec.cryptid << "\n";
9249   outs() << "          pad " << ec.pad << "\n";
9250 }
9251 
9252 static void PrintLinkerOptionCommand(MachO::linker_option_command lo,
9253                                      const char *Ptr) {
9254   outs() << "     cmd LC_LINKER_OPTION\n";
9255   outs() << " cmdsize " << lo.cmdsize;
9256   if (lo.cmdsize < sizeof(struct MachO::linker_option_command))
9257     outs() << " Incorrect size\n";
9258   else
9259     outs() << "\n";
9260   outs() << "   count " << lo.count << "\n";
9261   const char *string = Ptr + sizeof(struct MachO::linker_option_command);
9262   uint32_t left = lo.cmdsize - sizeof(struct MachO::linker_option_command);
9263   uint32_t i = 0;
9264   while (left > 0) {
9265     while (*string == '\0' && left > 0) {
9266       string++;
9267       left--;
9268     }
9269     if (left > 0) {
9270       i++;
9271       outs() << "  string #" << i << " " << format("%.*s\n", left, string);
9272       uint32_t NullPos = StringRef(string, left).find('\0');
9273       uint32_t len = std::min(NullPos, left) + 1;
9274       string += len;
9275       left -= len;
9276     }
9277   }
9278   if (lo.count != i)
9279     outs() << "   count " << lo.count << " does not match number of strings "
9280            << i << "\n";
9281 }
9282 
9283 static void PrintSubFrameworkCommand(MachO::sub_framework_command sub,
9284                                      const char *Ptr) {
9285   outs() << "          cmd LC_SUB_FRAMEWORK\n";
9286   outs() << "      cmdsize " << sub.cmdsize;
9287   if (sub.cmdsize < sizeof(struct MachO::sub_framework_command))
9288     outs() << " Incorrect size\n";
9289   else
9290     outs() << "\n";
9291   if (sub.umbrella < sub.cmdsize) {
9292     const char *P = Ptr + sub.umbrella;
9293     outs() << "     umbrella " << P << " (offset " << sub.umbrella << ")\n";
9294   } else {
9295     outs() << "     umbrella ?(bad offset " << sub.umbrella << ")\n";
9296   }
9297 }
9298 
9299 static void PrintSubUmbrellaCommand(MachO::sub_umbrella_command sub,
9300                                     const char *Ptr) {
9301   outs() << "          cmd LC_SUB_UMBRELLA\n";
9302   outs() << "      cmdsize " << sub.cmdsize;
9303   if (sub.cmdsize < sizeof(struct MachO::sub_umbrella_command))
9304     outs() << " Incorrect size\n";
9305   else
9306     outs() << "\n";
9307   if (sub.sub_umbrella < sub.cmdsize) {
9308     const char *P = Ptr + sub.sub_umbrella;
9309     outs() << " sub_umbrella " << P << " (offset " << sub.sub_umbrella << ")\n";
9310   } else {
9311     outs() << " sub_umbrella ?(bad offset " << sub.sub_umbrella << ")\n";
9312   }
9313 }
9314 
9315 static void PrintSubLibraryCommand(MachO::sub_library_command sub,
9316                                    const char *Ptr) {
9317   outs() << "          cmd LC_SUB_LIBRARY\n";
9318   outs() << "      cmdsize " << sub.cmdsize;
9319   if (sub.cmdsize < sizeof(struct MachO::sub_library_command))
9320     outs() << " Incorrect size\n";
9321   else
9322     outs() << "\n";
9323   if (sub.sub_library < sub.cmdsize) {
9324     const char *P = Ptr + sub.sub_library;
9325     outs() << "  sub_library " << P << " (offset " << sub.sub_library << ")\n";
9326   } else {
9327     outs() << "  sub_library ?(bad offset " << sub.sub_library << ")\n";
9328   }
9329 }
9330 
9331 static void PrintSubClientCommand(MachO::sub_client_command sub,
9332                                   const char *Ptr) {
9333   outs() << "          cmd LC_SUB_CLIENT\n";
9334   outs() << "      cmdsize " << sub.cmdsize;
9335   if (sub.cmdsize < sizeof(struct MachO::sub_client_command))
9336     outs() << " Incorrect size\n";
9337   else
9338     outs() << "\n";
9339   if (sub.client < sub.cmdsize) {
9340     const char *P = Ptr + sub.client;
9341     outs() << "       client " << P << " (offset " << sub.client << ")\n";
9342   } else {
9343     outs() << "       client ?(bad offset " << sub.client << ")\n";
9344   }
9345 }
9346 
9347 static void PrintRoutinesCommand(MachO::routines_command r) {
9348   outs() << "          cmd LC_ROUTINES\n";
9349   outs() << "      cmdsize " << r.cmdsize;
9350   if (r.cmdsize != sizeof(struct MachO::routines_command))
9351     outs() << " Incorrect size\n";
9352   else
9353     outs() << "\n";
9354   outs() << " init_address " << format("0x%08" PRIx32, r.init_address) << "\n";
9355   outs() << "  init_module " << r.init_module << "\n";
9356   outs() << "    reserved1 " << r.reserved1 << "\n";
9357   outs() << "    reserved2 " << r.reserved2 << "\n";
9358   outs() << "    reserved3 " << r.reserved3 << "\n";
9359   outs() << "    reserved4 " << r.reserved4 << "\n";
9360   outs() << "    reserved5 " << r.reserved5 << "\n";
9361   outs() << "    reserved6 " << r.reserved6 << "\n";
9362 }
9363 
9364 static void PrintRoutinesCommand64(MachO::routines_command_64 r) {
9365   outs() << "          cmd LC_ROUTINES_64\n";
9366   outs() << "      cmdsize " << r.cmdsize;
9367   if (r.cmdsize != sizeof(struct MachO::routines_command_64))
9368     outs() << " Incorrect size\n";
9369   else
9370     outs() << "\n";
9371   outs() << " init_address " << format("0x%016" PRIx64, r.init_address) << "\n";
9372   outs() << "  init_module " << r.init_module << "\n";
9373   outs() << "    reserved1 " << r.reserved1 << "\n";
9374   outs() << "    reserved2 " << r.reserved2 << "\n";
9375   outs() << "    reserved3 " << r.reserved3 << "\n";
9376   outs() << "    reserved4 " << r.reserved4 << "\n";
9377   outs() << "    reserved5 " << r.reserved5 << "\n";
9378   outs() << "    reserved6 " << r.reserved6 << "\n";
9379 }
9380 
9381 static void Print_x86_thread_state32_t(MachO::x86_thread_state32_t &cpu32) {
9382   outs() << "\t    eax " << format("0x%08" PRIx32, cpu32.eax);
9383   outs() << " ebx    " << format("0x%08" PRIx32, cpu32.ebx);
9384   outs() << " ecx " << format("0x%08" PRIx32, cpu32.ecx);
9385   outs() << " edx " << format("0x%08" PRIx32, cpu32.edx) << "\n";
9386   outs() << "\t    edi " << format("0x%08" PRIx32, cpu32.edi);
9387   outs() << " esi    " << format("0x%08" PRIx32, cpu32.esi);
9388   outs() << " ebp " << format("0x%08" PRIx32, cpu32.ebp);
9389   outs() << " esp " << format("0x%08" PRIx32, cpu32.esp) << "\n";
9390   outs() << "\t    ss  " << format("0x%08" PRIx32, cpu32.ss);
9391   outs() << " eflags " << format("0x%08" PRIx32, cpu32.eflags);
9392   outs() << " eip " << format("0x%08" PRIx32, cpu32.eip);
9393   outs() << " cs  " << format("0x%08" PRIx32, cpu32.cs) << "\n";
9394   outs() << "\t    ds  " << format("0x%08" PRIx32, cpu32.ds);
9395   outs() << " es     " << format("0x%08" PRIx32, cpu32.es);
9396   outs() << " fs  " << format("0x%08" PRIx32, cpu32.fs);
9397   outs() << " gs  " << format("0x%08" PRIx32, cpu32.gs) << "\n";
9398 }
9399 
9400 static void Print_x86_thread_state64_t(MachO::x86_thread_state64_t &cpu64) {
9401   outs() << "   rax  " << format("0x%016" PRIx64, cpu64.rax);
9402   outs() << " rbx " << format("0x%016" PRIx64, cpu64.rbx);
9403   outs() << " rcx  " << format("0x%016" PRIx64, cpu64.rcx) << "\n";
9404   outs() << "   rdx  " << format("0x%016" PRIx64, cpu64.rdx);
9405   outs() << " rdi " << format("0x%016" PRIx64, cpu64.rdi);
9406   outs() << " rsi  " << format("0x%016" PRIx64, cpu64.rsi) << "\n";
9407   outs() << "   rbp  " << format("0x%016" PRIx64, cpu64.rbp);
9408   outs() << " rsp " << format("0x%016" PRIx64, cpu64.rsp);
9409   outs() << " r8   " << format("0x%016" PRIx64, cpu64.r8) << "\n";
9410   outs() << "    r9  " << format("0x%016" PRIx64, cpu64.r9);
9411   outs() << " r10 " << format("0x%016" PRIx64, cpu64.r10);
9412   outs() << " r11  " << format("0x%016" PRIx64, cpu64.r11) << "\n";
9413   outs() << "   r12  " << format("0x%016" PRIx64, cpu64.r12);
9414   outs() << " r13 " << format("0x%016" PRIx64, cpu64.r13);
9415   outs() << " r14  " << format("0x%016" PRIx64, cpu64.r14) << "\n";
9416   outs() << "   r15  " << format("0x%016" PRIx64, cpu64.r15);
9417   outs() << " rip " << format("0x%016" PRIx64, cpu64.rip) << "\n";
9418   outs() << "rflags  " << format("0x%016" PRIx64, cpu64.rflags);
9419   outs() << " cs  " << format("0x%016" PRIx64, cpu64.cs);
9420   outs() << " fs   " << format("0x%016" PRIx64, cpu64.fs) << "\n";
9421   outs() << "    gs  " << format("0x%016" PRIx64, cpu64.gs) << "\n";
9422 }
9423 
9424 static void Print_mmst_reg(MachO::mmst_reg_t &r) {
9425   uint32_t f;
9426   outs() << "\t      mmst_reg  ";
9427   for (f = 0; f < 10; f++)
9428     outs() << format("%02" PRIx32, (r.mmst_reg[f] & 0xff)) << " ";
9429   outs() << "\n";
9430   outs() << "\t      mmst_rsrv ";
9431   for (f = 0; f < 6; f++)
9432     outs() << format("%02" PRIx32, (r.mmst_rsrv[f] & 0xff)) << " ";
9433   outs() << "\n";
9434 }
9435 
9436 static void Print_xmm_reg(MachO::xmm_reg_t &r) {
9437   uint32_t f;
9438   outs() << "\t      xmm_reg ";
9439   for (f = 0; f < 16; f++)
9440     outs() << format("%02" PRIx32, (r.xmm_reg[f] & 0xff)) << " ";
9441   outs() << "\n";
9442 }
9443 
9444 static void Print_x86_float_state_t(MachO::x86_float_state64_t &fpu) {
9445   outs() << "\t    fpu_reserved[0] " << fpu.fpu_reserved[0];
9446   outs() << " fpu_reserved[1] " << fpu.fpu_reserved[1] << "\n";
9447   outs() << "\t    control: invalid " << fpu.fpu_fcw.invalid;
9448   outs() << " denorm " << fpu.fpu_fcw.denorm;
9449   outs() << " zdiv " << fpu.fpu_fcw.zdiv;
9450   outs() << " ovrfl " << fpu.fpu_fcw.ovrfl;
9451   outs() << " undfl " << fpu.fpu_fcw.undfl;
9452   outs() << " precis " << fpu.fpu_fcw.precis << "\n";
9453   outs() << "\t\t     pc ";
9454   if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_24B)
9455     outs() << "FP_PREC_24B ";
9456   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_53B)
9457     outs() << "FP_PREC_53B ";
9458   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_64B)
9459     outs() << "FP_PREC_64B ";
9460   else
9461     outs() << fpu.fpu_fcw.pc << " ";
9462   outs() << "rc ";
9463   if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_NEAR)
9464     outs() << "FP_RND_NEAR ";
9465   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_DOWN)
9466     outs() << "FP_RND_DOWN ";
9467   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_UP)
9468     outs() << "FP_RND_UP ";
9469   else if (fpu.fpu_fcw.rc == MachO::x86_FP_CHOP)
9470     outs() << "FP_CHOP ";
9471   outs() << "\n";
9472   outs() << "\t    status: invalid " << fpu.fpu_fsw.invalid;
9473   outs() << " denorm " << fpu.fpu_fsw.denorm;
9474   outs() << " zdiv " << fpu.fpu_fsw.zdiv;
9475   outs() << " ovrfl " << fpu.fpu_fsw.ovrfl;
9476   outs() << " undfl " << fpu.fpu_fsw.undfl;
9477   outs() << " precis " << fpu.fpu_fsw.precis;
9478   outs() << " stkflt " << fpu.fpu_fsw.stkflt << "\n";
9479   outs() << "\t            errsumm " << fpu.fpu_fsw.errsumm;
9480   outs() << " c0 " << fpu.fpu_fsw.c0;
9481   outs() << " c1 " << fpu.fpu_fsw.c1;
9482   outs() << " c2 " << fpu.fpu_fsw.c2;
9483   outs() << " tos " << fpu.fpu_fsw.tos;
9484   outs() << " c3 " << fpu.fpu_fsw.c3;
9485   outs() << " busy " << fpu.fpu_fsw.busy << "\n";
9486   outs() << "\t    fpu_ftw " << format("0x%02" PRIx32, fpu.fpu_ftw);
9487   outs() << " fpu_rsrv1 " << format("0x%02" PRIx32, fpu.fpu_rsrv1);
9488   outs() << " fpu_fop " << format("0x%04" PRIx32, fpu.fpu_fop);
9489   outs() << " fpu_ip " << format("0x%08" PRIx32, fpu.fpu_ip) << "\n";
9490   outs() << "\t    fpu_cs " << format("0x%04" PRIx32, fpu.fpu_cs);
9491   outs() << " fpu_rsrv2 " << format("0x%04" PRIx32, fpu.fpu_rsrv2);
9492   outs() << " fpu_dp " << format("0x%08" PRIx32, fpu.fpu_dp);
9493   outs() << " fpu_ds " << format("0x%04" PRIx32, fpu.fpu_ds) << "\n";
9494   outs() << "\t    fpu_rsrv3 " << format("0x%04" PRIx32, fpu.fpu_rsrv3);
9495   outs() << " fpu_mxcsr " << format("0x%08" PRIx32, fpu.fpu_mxcsr);
9496   outs() << " fpu_mxcsrmask " << format("0x%08" PRIx32, fpu.fpu_mxcsrmask);
9497   outs() << "\n";
9498   outs() << "\t    fpu_stmm0:\n";
9499   Print_mmst_reg(fpu.fpu_stmm0);
9500   outs() << "\t    fpu_stmm1:\n";
9501   Print_mmst_reg(fpu.fpu_stmm1);
9502   outs() << "\t    fpu_stmm2:\n";
9503   Print_mmst_reg(fpu.fpu_stmm2);
9504   outs() << "\t    fpu_stmm3:\n";
9505   Print_mmst_reg(fpu.fpu_stmm3);
9506   outs() << "\t    fpu_stmm4:\n";
9507   Print_mmst_reg(fpu.fpu_stmm4);
9508   outs() << "\t    fpu_stmm5:\n";
9509   Print_mmst_reg(fpu.fpu_stmm5);
9510   outs() << "\t    fpu_stmm6:\n";
9511   Print_mmst_reg(fpu.fpu_stmm6);
9512   outs() << "\t    fpu_stmm7:\n";
9513   Print_mmst_reg(fpu.fpu_stmm7);
9514   outs() << "\t    fpu_xmm0:\n";
9515   Print_xmm_reg(fpu.fpu_xmm0);
9516   outs() << "\t    fpu_xmm1:\n";
9517   Print_xmm_reg(fpu.fpu_xmm1);
9518   outs() << "\t    fpu_xmm2:\n";
9519   Print_xmm_reg(fpu.fpu_xmm2);
9520   outs() << "\t    fpu_xmm3:\n";
9521   Print_xmm_reg(fpu.fpu_xmm3);
9522   outs() << "\t    fpu_xmm4:\n";
9523   Print_xmm_reg(fpu.fpu_xmm4);
9524   outs() << "\t    fpu_xmm5:\n";
9525   Print_xmm_reg(fpu.fpu_xmm5);
9526   outs() << "\t    fpu_xmm6:\n";
9527   Print_xmm_reg(fpu.fpu_xmm6);
9528   outs() << "\t    fpu_xmm7:\n";
9529   Print_xmm_reg(fpu.fpu_xmm7);
9530   outs() << "\t    fpu_xmm8:\n";
9531   Print_xmm_reg(fpu.fpu_xmm8);
9532   outs() << "\t    fpu_xmm9:\n";
9533   Print_xmm_reg(fpu.fpu_xmm9);
9534   outs() << "\t    fpu_xmm10:\n";
9535   Print_xmm_reg(fpu.fpu_xmm10);
9536   outs() << "\t    fpu_xmm11:\n";
9537   Print_xmm_reg(fpu.fpu_xmm11);
9538   outs() << "\t    fpu_xmm12:\n";
9539   Print_xmm_reg(fpu.fpu_xmm12);
9540   outs() << "\t    fpu_xmm13:\n";
9541   Print_xmm_reg(fpu.fpu_xmm13);
9542   outs() << "\t    fpu_xmm14:\n";
9543   Print_xmm_reg(fpu.fpu_xmm14);
9544   outs() << "\t    fpu_xmm15:\n";
9545   Print_xmm_reg(fpu.fpu_xmm15);
9546   outs() << "\t    fpu_rsrv4:\n";
9547   for (uint32_t f = 0; f < 6; f++) {
9548     outs() << "\t            ";
9549     for (uint32_t g = 0; g < 16; g++)
9550       outs() << format("%02" PRIx32, fpu.fpu_rsrv4[f * g]) << " ";
9551     outs() << "\n";
9552   }
9553   outs() << "\t    fpu_reserved1 " << format("0x%08" PRIx32, fpu.fpu_reserved1);
9554   outs() << "\n";
9555 }
9556 
9557 static void Print_x86_exception_state_t(MachO::x86_exception_state64_t &exc64) {
9558   outs() << "\t    trapno " << format("0x%08" PRIx32, exc64.trapno);
9559   outs() << " err " << format("0x%08" PRIx32, exc64.err);
9560   outs() << " faultvaddr " << format("0x%016" PRIx64, exc64.faultvaddr) << "\n";
9561 }
9562 
9563 static void Print_arm_thread_state32_t(MachO::arm_thread_state32_t &cpu32) {
9564   outs() << "\t    r0  " << format("0x%08" PRIx32, cpu32.r[0]);
9565   outs() << " r1     "   << format("0x%08" PRIx32, cpu32.r[1]);
9566   outs() << " r2  "      << format("0x%08" PRIx32, cpu32.r[2]);
9567   outs() << " r3  "      << format("0x%08" PRIx32, cpu32.r[3]) << "\n";
9568   outs() << "\t    r4  " << format("0x%08" PRIx32, cpu32.r[4]);
9569   outs() << " r5     "   << format("0x%08" PRIx32, cpu32.r[5]);
9570   outs() << " r6  "      << format("0x%08" PRIx32, cpu32.r[6]);
9571   outs() << " r7  "      << format("0x%08" PRIx32, cpu32.r[7]) << "\n";
9572   outs() << "\t    r8  " << format("0x%08" PRIx32, cpu32.r[8]);
9573   outs() << " r9     "   << format("0x%08" PRIx32, cpu32.r[9]);
9574   outs() << " r10 "      << format("0x%08" PRIx32, cpu32.r[10]);
9575   outs() << " r11 "      << format("0x%08" PRIx32, cpu32.r[11]) << "\n";
9576   outs() << "\t    r12 " << format("0x%08" PRIx32, cpu32.r[12]);
9577   outs() << " sp     "   << format("0x%08" PRIx32, cpu32.sp);
9578   outs() << " lr  "      << format("0x%08" PRIx32, cpu32.lr);
9579   outs() << " pc  "      << format("0x%08" PRIx32, cpu32.pc) << "\n";
9580   outs() << "\t   cpsr " << format("0x%08" PRIx32, cpu32.cpsr) << "\n";
9581 }
9582 
9583 static void Print_arm_thread_state64_t(MachO::arm_thread_state64_t &cpu64) {
9584   outs() << "\t    x0  " << format("0x%016" PRIx64, cpu64.x[0]);
9585   outs() << " x1  "      << format("0x%016" PRIx64, cpu64.x[1]);
9586   outs() << " x2  "      << format("0x%016" PRIx64, cpu64.x[2]) << "\n";
9587   outs() << "\t    x3  " << format("0x%016" PRIx64, cpu64.x[3]);
9588   outs() << " x4  "      << format("0x%016" PRIx64, cpu64.x[4]);
9589   outs() << " x5  "      << format("0x%016" PRIx64, cpu64.x[5]) << "\n";
9590   outs() << "\t    x6  " << format("0x%016" PRIx64, cpu64.x[6]);
9591   outs() << " x7  "      << format("0x%016" PRIx64, cpu64.x[7]);
9592   outs() << " x8  "      << format("0x%016" PRIx64, cpu64.x[8]) << "\n";
9593   outs() << "\t    x9  " << format("0x%016" PRIx64, cpu64.x[9]);
9594   outs() << " x10 "      << format("0x%016" PRIx64, cpu64.x[10]);
9595   outs() << " x11 "      << format("0x%016" PRIx64, cpu64.x[11]) << "\n";
9596   outs() << "\t    x12 " << format("0x%016" PRIx64, cpu64.x[12]);
9597   outs() << " x13 "      << format("0x%016" PRIx64, cpu64.x[13]);
9598   outs() << " x14 "      << format("0x%016" PRIx64, cpu64.x[14]) << "\n";
9599   outs() << "\t    x15 " << format("0x%016" PRIx64, cpu64.x[15]);
9600   outs() << " x16 "      << format("0x%016" PRIx64, cpu64.x[16]);
9601   outs() << " x17 "      << format("0x%016" PRIx64, cpu64.x[17]) << "\n";
9602   outs() << "\t    x18 " << format("0x%016" PRIx64, cpu64.x[18]);
9603   outs() << " x19 "      << format("0x%016" PRIx64, cpu64.x[19]);
9604   outs() << " x20 "      << format("0x%016" PRIx64, cpu64.x[20]) << "\n";
9605   outs() << "\t    x21 " << format("0x%016" PRIx64, cpu64.x[21]);
9606   outs() << " x22 "      << format("0x%016" PRIx64, cpu64.x[22]);
9607   outs() << " x23 "      << format("0x%016" PRIx64, cpu64.x[23]) << "\n";
9608   outs() << "\t    x24 " << format("0x%016" PRIx64, cpu64.x[24]);
9609   outs() << " x25 "      << format("0x%016" PRIx64, cpu64.x[25]);
9610   outs() << " x26 "      << format("0x%016" PRIx64, cpu64.x[26]) << "\n";
9611   outs() << "\t    x27 " << format("0x%016" PRIx64, cpu64.x[27]);
9612   outs() << " x28 "      << format("0x%016" PRIx64, cpu64.x[28]);
9613   outs() << "  fp "      << format("0x%016" PRIx64, cpu64.fp) << "\n";
9614   outs() << "\t     lr " << format("0x%016" PRIx64, cpu64.lr);
9615   outs() << " sp  "      << format("0x%016" PRIx64, cpu64.sp);
9616   outs() << "  pc "      << format("0x%016" PRIx64, cpu64.pc) << "\n";
9617   outs() << "\t   cpsr " << format("0x%08"  PRIx32, cpu64.cpsr) << "\n";
9618 }
9619 
9620 static void PrintThreadCommand(MachO::thread_command t, const char *Ptr,
9621                                bool isLittleEndian, uint32_t cputype) {
9622   if (t.cmd == MachO::LC_THREAD)
9623     outs() << "        cmd LC_THREAD\n";
9624   else if (t.cmd == MachO::LC_UNIXTHREAD)
9625     outs() << "        cmd LC_UNIXTHREAD\n";
9626   else
9627     outs() << "        cmd " << t.cmd << " (unknown)\n";
9628   outs() << "    cmdsize " << t.cmdsize;
9629   if (t.cmdsize < sizeof(struct MachO::thread_command) + 2 * sizeof(uint32_t))
9630     outs() << " Incorrect size\n";
9631   else
9632     outs() << "\n";
9633 
9634   const char *begin = Ptr + sizeof(struct MachO::thread_command);
9635   const char *end = Ptr + t.cmdsize;
9636   uint32_t flavor, count, left;
9637   if (cputype == MachO::CPU_TYPE_I386) {
9638     while (begin < end) {
9639       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9640         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9641         begin += sizeof(uint32_t);
9642       } else {
9643         flavor = 0;
9644         begin = end;
9645       }
9646       if (isLittleEndian != sys::IsLittleEndianHost)
9647         sys::swapByteOrder(flavor);
9648       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9649         memcpy((char *)&count, begin, sizeof(uint32_t));
9650         begin += sizeof(uint32_t);
9651       } else {
9652         count = 0;
9653         begin = end;
9654       }
9655       if (isLittleEndian != sys::IsLittleEndianHost)
9656         sys::swapByteOrder(count);
9657       if (flavor == MachO::x86_THREAD_STATE32) {
9658         outs() << "     flavor i386_THREAD_STATE\n";
9659         if (count == MachO::x86_THREAD_STATE32_COUNT)
9660           outs() << "      count i386_THREAD_STATE_COUNT\n";
9661         else
9662           outs() << "      count " << count
9663                  << " (not x86_THREAD_STATE32_COUNT)\n";
9664         MachO::x86_thread_state32_t cpu32;
9665         left = end - begin;
9666         if (left >= sizeof(MachO::x86_thread_state32_t)) {
9667           memcpy(&cpu32, begin, sizeof(MachO::x86_thread_state32_t));
9668           begin += sizeof(MachO::x86_thread_state32_t);
9669         } else {
9670           memset(&cpu32, '\0', sizeof(MachO::x86_thread_state32_t));
9671           memcpy(&cpu32, begin, left);
9672           begin += left;
9673         }
9674         if (isLittleEndian != sys::IsLittleEndianHost)
9675           swapStruct(cpu32);
9676         Print_x86_thread_state32_t(cpu32);
9677       } else if (flavor == MachO::x86_THREAD_STATE) {
9678         outs() << "     flavor x86_THREAD_STATE\n";
9679         if (count == MachO::x86_THREAD_STATE_COUNT)
9680           outs() << "      count x86_THREAD_STATE_COUNT\n";
9681         else
9682           outs() << "      count " << count
9683                  << " (not x86_THREAD_STATE_COUNT)\n";
9684         struct MachO::x86_thread_state_t ts;
9685         left = end - begin;
9686         if (left >= sizeof(MachO::x86_thread_state_t)) {
9687           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
9688           begin += sizeof(MachO::x86_thread_state_t);
9689         } else {
9690           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
9691           memcpy(&ts, begin, left);
9692           begin += left;
9693         }
9694         if (isLittleEndian != sys::IsLittleEndianHost)
9695           swapStruct(ts);
9696         if (ts.tsh.flavor == MachO::x86_THREAD_STATE32) {
9697           outs() << "\t    tsh.flavor x86_THREAD_STATE32 ";
9698           if (ts.tsh.count == MachO::x86_THREAD_STATE32_COUNT)
9699             outs() << "tsh.count x86_THREAD_STATE32_COUNT\n";
9700           else
9701             outs() << "tsh.count " << ts.tsh.count
9702                    << " (not x86_THREAD_STATE32_COUNT\n";
9703           Print_x86_thread_state32_t(ts.uts.ts32);
9704         } else {
9705           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
9706                  << ts.tsh.count << "\n";
9707         }
9708       } else {
9709         outs() << "     flavor " << flavor << " (unknown)\n";
9710         outs() << "      count " << count << "\n";
9711         outs() << "      state (unknown)\n";
9712         begin += count * sizeof(uint32_t);
9713       }
9714     }
9715   } else if (cputype == MachO::CPU_TYPE_X86_64) {
9716     while (begin < end) {
9717       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9718         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9719         begin += sizeof(uint32_t);
9720       } else {
9721         flavor = 0;
9722         begin = end;
9723       }
9724       if (isLittleEndian != sys::IsLittleEndianHost)
9725         sys::swapByteOrder(flavor);
9726       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9727         memcpy((char *)&count, begin, sizeof(uint32_t));
9728         begin += sizeof(uint32_t);
9729       } else {
9730         count = 0;
9731         begin = end;
9732       }
9733       if (isLittleEndian != sys::IsLittleEndianHost)
9734         sys::swapByteOrder(count);
9735       if (flavor == MachO::x86_THREAD_STATE64) {
9736         outs() << "     flavor x86_THREAD_STATE64\n";
9737         if (count == MachO::x86_THREAD_STATE64_COUNT)
9738           outs() << "      count x86_THREAD_STATE64_COUNT\n";
9739         else
9740           outs() << "      count " << count
9741                  << " (not x86_THREAD_STATE64_COUNT)\n";
9742         MachO::x86_thread_state64_t cpu64;
9743         left = end - begin;
9744         if (left >= sizeof(MachO::x86_thread_state64_t)) {
9745           memcpy(&cpu64, begin, sizeof(MachO::x86_thread_state64_t));
9746           begin += sizeof(MachO::x86_thread_state64_t);
9747         } else {
9748           memset(&cpu64, '\0', sizeof(MachO::x86_thread_state64_t));
9749           memcpy(&cpu64, begin, left);
9750           begin += left;
9751         }
9752         if (isLittleEndian != sys::IsLittleEndianHost)
9753           swapStruct(cpu64);
9754         Print_x86_thread_state64_t(cpu64);
9755       } else if (flavor == MachO::x86_THREAD_STATE) {
9756         outs() << "     flavor x86_THREAD_STATE\n";
9757         if (count == MachO::x86_THREAD_STATE_COUNT)
9758           outs() << "      count x86_THREAD_STATE_COUNT\n";
9759         else
9760           outs() << "      count " << count
9761                  << " (not x86_THREAD_STATE_COUNT)\n";
9762         struct MachO::x86_thread_state_t ts;
9763         left = end - begin;
9764         if (left >= sizeof(MachO::x86_thread_state_t)) {
9765           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
9766           begin += sizeof(MachO::x86_thread_state_t);
9767         } else {
9768           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
9769           memcpy(&ts, begin, left);
9770           begin += left;
9771         }
9772         if (isLittleEndian != sys::IsLittleEndianHost)
9773           swapStruct(ts);
9774         if (ts.tsh.flavor == MachO::x86_THREAD_STATE64) {
9775           outs() << "\t    tsh.flavor x86_THREAD_STATE64 ";
9776           if (ts.tsh.count == MachO::x86_THREAD_STATE64_COUNT)
9777             outs() << "tsh.count x86_THREAD_STATE64_COUNT\n";
9778           else
9779             outs() << "tsh.count " << ts.tsh.count
9780                    << " (not x86_THREAD_STATE64_COUNT\n";
9781           Print_x86_thread_state64_t(ts.uts.ts64);
9782         } else {
9783           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
9784                  << ts.tsh.count << "\n";
9785         }
9786       } else if (flavor == MachO::x86_FLOAT_STATE) {
9787         outs() << "     flavor x86_FLOAT_STATE\n";
9788         if (count == MachO::x86_FLOAT_STATE_COUNT)
9789           outs() << "      count x86_FLOAT_STATE_COUNT\n";
9790         else
9791           outs() << "      count " << count << " (not x86_FLOAT_STATE_COUNT)\n";
9792         struct MachO::x86_float_state_t fs;
9793         left = end - begin;
9794         if (left >= sizeof(MachO::x86_float_state_t)) {
9795           memcpy(&fs, begin, sizeof(MachO::x86_float_state_t));
9796           begin += sizeof(MachO::x86_float_state_t);
9797         } else {
9798           memset(&fs, '\0', sizeof(MachO::x86_float_state_t));
9799           memcpy(&fs, begin, left);
9800           begin += left;
9801         }
9802         if (isLittleEndian != sys::IsLittleEndianHost)
9803           swapStruct(fs);
9804         if (fs.fsh.flavor == MachO::x86_FLOAT_STATE64) {
9805           outs() << "\t    fsh.flavor x86_FLOAT_STATE64 ";
9806           if (fs.fsh.count == MachO::x86_FLOAT_STATE64_COUNT)
9807             outs() << "fsh.count x86_FLOAT_STATE64_COUNT\n";
9808           else
9809             outs() << "fsh.count " << fs.fsh.count
9810                    << " (not x86_FLOAT_STATE64_COUNT\n";
9811           Print_x86_float_state_t(fs.ufs.fs64);
9812         } else {
9813           outs() << "\t    fsh.flavor " << fs.fsh.flavor << "  fsh.count "
9814                  << fs.fsh.count << "\n";
9815         }
9816       } else if (flavor == MachO::x86_EXCEPTION_STATE) {
9817         outs() << "     flavor x86_EXCEPTION_STATE\n";
9818         if (count == MachO::x86_EXCEPTION_STATE_COUNT)
9819           outs() << "      count x86_EXCEPTION_STATE_COUNT\n";
9820         else
9821           outs() << "      count " << count
9822                  << " (not x86_EXCEPTION_STATE_COUNT)\n";
9823         struct MachO::x86_exception_state_t es;
9824         left = end - begin;
9825         if (left >= sizeof(MachO::x86_exception_state_t)) {
9826           memcpy(&es, begin, sizeof(MachO::x86_exception_state_t));
9827           begin += sizeof(MachO::x86_exception_state_t);
9828         } else {
9829           memset(&es, '\0', sizeof(MachO::x86_exception_state_t));
9830           memcpy(&es, begin, left);
9831           begin += left;
9832         }
9833         if (isLittleEndian != sys::IsLittleEndianHost)
9834           swapStruct(es);
9835         if (es.esh.flavor == MachO::x86_EXCEPTION_STATE64) {
9836           outs() << "\t    esh.flavor x86_EXCEPTION_STATE64\n";
9837           if (es.esh.count == MachO::x86_EXCEPTION_STATE64_COUNT)
9838             outs() << "\t    esh.count x86_EXCEPTION_STATE64_COUNT\n";
9839           else
9840             outs() << "\t    esh.count " << es.esh.count
9841                    << " (not x86_EXCEPTION_STATE64_COUNT\n";
9842           Print_x86_exception_state_t(es.ues.es64);
9843         } else {
9844           outs() << "\t    esh.flavor " << es.esh.flavor << "  esh.count "
9845                  << es.esh.count << "\n";
9846         }
9847       } else if (flavor == MachO::x86_EXCEPTION_STATE64) {
9848         outs() << "     flavor x86_EXCEPTION_STATE64\n";
9849         if (count == MachO::x86_EXCEPTION_STATE64_COUNT)
9850           outs() << "      count x86_EXCEPTION_STATE64_COUNT\n";
9851         else
9852           outs() << "      count " << count
9853                  << " (not x86_EXCEPTION_STATE64_COUNT)\n";
9854         struct MachO::x86_exception_state64_t es64;
9855         left = end - begin;
9856         if (left >= sizeof(MachO::x86_exception_state64_t)) {
9857           memcpy(&es64, begin, sizeof(MachO::x86_exception_state64_t));
9858           begin += sizeof(MachO::x86_exception_state64_t);
9859         } else {
9860           memset(&es64, '\0', sizeof(MachO::x86_exception_state64_t));
9861           memcpy(&es64, begin, left);
9862           begin += left;
9863         }
9864         if (isLittleEndian != sys::IsLittleEndianHost)
9865           swapStruct(es64);
9866         Print_x86_exception_state_t(es64);
9867       } else {
9868         outs() << "     flavor " << flavor << " (unknown)\n";
9869         outs() << "      count " << count << "\n";
9870         outs() << "      state (unknown)\n";
9871         begin += count * sizeof(uint32_t);
9872       }
9873     }
9874   } else if (cputype == MachO::CPU_TYPE_ARM) {
9875     while (begin < end) {
9876       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9877         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9878         begin += sizeof(uint32_t);
9879       } else {
9880         flavor = 0;
9881         begin = end;
9882       }
9883       if (isLittleEndian != sys::IsLittleEndianHost)
9884         sys::swapByteOrder(flavor);
9885       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9886         memcpy((char *)&count, begin, sizeof(uint32_t));
9887         begin += sizeof(uint32_t);
9888       } else {
9889         count = 0;
9890         begin = end;
9891       }
9892       if (isLittleEndian != sys::IsLittleEndianHost)
9893         sys::swapByteOrder(count);
9894       if (flavor == MachO::ARM_THREAD_STATE) {
9895         outs() << "     flavor ARM_THREAD_STATE\n";
9896         if (count == MachO::ARM_THREAD_STATE_COUNT)
9897           outs() << "      count ARM_THREAD_STATE_COUNT\n";
9898         else
9899           outs() << "      count " << count
9900                  << " (not ARM_THREAD_STATE_COUNT)\n";
9901         MachO::arm_thread_state32_t cpu32;
9902         left = end - begin;
9903         if (left >= sizeof(MachO::arm_thread_state32_t)) {
9904           memcpy(&cpu32, begin, sizeof(MachO::arm_thread_state32_t));
9905           begin += sizeof(MachO::arm_thread_state32_t);
9906         } else {
9907           memset(&cpu32, '\0', sizeof(MachO::arm_thread_state32_t));
9908           memcpy(&cpu32, begin, left);
9909           begin += left;
9910         }
9911         if (isLittleEndian != sys::IsLittleEndianHost)
9912           swapStruct(cpu32);
9913         Print_arm_thread_state32_t(cpu32);
9914       } else {
9915         outs() << "     flavor " << flavor << " (unknown)\n";
9916         outs() << "      count " << count << "\n";
9917         outs() << "      state (unknown)\n";
9918         begin += count * sizeof(uint32_t);
9919       }
9920     }
9921   } else if (cputype == MachO::CPU_TYPE_ARM64 ||
9922              cputype == MachO::CPU_TYPE_ARM64_32) {
9923     while (begin < end) {
9924       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9925         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9926         begin += sizeof(uint32_t);
9927       } else {
9928         flavor = 0;
9929         begin = end;
9930       }
9931       if (isLittleEndian != sys::IsLittleEndianHost)
9932         sys::swapByteOrder(flavor);
9933       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9934         memcpy((char *)&count, begin, sizeof(uint32_t));
9935         begin += sizeof(uint32_t);
9936       } else {
9937         count = 0;
9938         begin = end;
9939       }
9940       if (isLittleEndian != sys::IsLittleEndianHost)
9941         sys::swapByteOrder(count);
9942       if (flavor == MachO::ARM_THREAD_STATE64) {
9943         outs() << "     flavor ARM_THREAD_STATE64\n";
9944         if (count == MachO::ARM_THREAD_STATE64_COUNT)
9945           outs() << "      count ARM_THREAD_STATE64_COUNT\n";
9946         else
9947           outs() << "      count " << count
9948                  << " (not ARM_THREAD_STATE64_COUNT)\n";
9949         MachO::arm_thread_state64_t cpu64;
9950         left = end - begin;
9951         if (left >= sizeof(MachO::arm_thread_state64_t)) {
9952           memcpy(&cpu64, begin, sizeof(MachO::arm_thread_state64_t));
9953           begin += sizeof(MachO::arm_thread_state64_t);
9954         } else {
9955           memset(&cpu64, '\0', sizeof(MachO::arm_thread_state64_t));
9956           memcpy(&cpu64, begin, left);
9957           begin += left;
9958         }
9959         if (isLittleEndian != sys::IsLittleEndianHost)
9960           swapStruct(cpu64);
9961         Print_arm_thread_state64_t(cpu64);
9962       } else {
9963         outs() << "     flavor " << flavor << " (unknown)\n";
9964         outs() << "      count " << count << "\n";
9965         outs() << "      state (unknown)\n";
9966         begin += count * sizeof(uint32_t);
9967       }
9968     }
9969   } else {
9970     while (begin < end) {
9971       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9972         memcpy((char *)&flavor, begin, sizeof(uint32_t));
9973         begin += sizeof(uint32_t);
9974       } else {
9975         flavor = 0;
9976         begin = end;
9977       }
9978       if (isLittleEndian != sys::IsLittleEndianHost)
9979         sys::swapByteOrder(flavor);
9980       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
9981         memcpy((char *)&count, begin, sizeof(uint32_t));
9982         begin += sizeof(uint32_t);
9983       } else {
9984         count = 0;
9985         begin = end;
9986       }
9987       if (isLittleEndian != sys::IsLittleEndianHost)
9988         sys::swapByteOrder(count);
9989       outs() << "     flavor " << flavor << "\n";
9990       outs() << "      count " << count << "\n";
9991       outs() << "      state (Unknown cputype/cpusubtype)\n";
9992       begin += count * sizeof(uint32_t);
9993     }
9994   }
9995 }
9996 
9997 static void PrintDylibCommand(MachO::dylib_command dl, const char *Ptr) {
9998   if (dl.cmd == MachO::LC_ID_DYLIB)
9999     outs() << "          cmd LC_ID_DYLIB\n";
10000   else if (dl.cmd == MachO::LC_LOAD_DYLIB)
10001     outs() << "          cmd LC_LOAD_DYLIB\n";
10002   else if (dl.cmd == MachO::LC_LOAD_WEAK_DYLIB)
10003     outs() << "          cmd LC_LOAD_WEAK_DYLIB\n";
10004   else if (dl.cmd == MachO::LC_REEXPORT_DYLIB)
10005     outs() << "          cmd LC_REEXPORT_DYLIB\n";
10006   else if (dl.cmd == MachO::LC_LAZY_LOAD_DYLIB)
10007     outs() << "          cmd LC_LAZY_LOAD_DYLIB\n";
10008   else if (dl.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
10009     outs() << "          cmd LC_LOAD_UPWARD_DYLIB\n";
10010   else
10011     outs() << "          cmd " << dl.cmd << " (unknown)\n";
10012   outs() << "      cmdsize " << dl.cmdsize;
10013   if (dl.cmdsize < sizeof(struct MachO::dylib_command))
10014     outs() << " Incorrect size\n";
10015   else
10016     outs() << "\n";
10017   if (dl.dylib.name < dl.cmdsize) {
10018     const char *P = (const char *)(Ptr) + dl.dylib.name;
10019     outs() << "         name " << P << " (offset " << dl.dylib.name << ")\n";
10020   } else {
10021     outs() << "         name ?(bad offset " << dl.dylib.name << ")\n";
10022   }
10023   outs() << "   time stamp " << dl.dylib.timestamp << " ";
10024   time_t t = dl.dylib.timestamp;
10025   outs() << ctime(&t);
10026   outs() << "      current version ";
10027   if (dl.dylib.current_version == 0xffffffff)
10028     outs() << "n/a\n";
10029   else
10030     outs() << ((dl.dylib.current_version >> 16) & 0xffff) << "."
10031            << ((dl.dylib.current_version >> 8) & 0xff) << "."
10032            << (dl.dylib.current_version & 0xff) << "\n";
10033   outs() << "compatibility version ";
10034   if (dl.dylib.compatibility_version == 0xffffffff)
10035     outs() << "n/a\n";
10036   else
10037     outs() << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
10038            << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
10039            << (dl.dylib.compatibility_version & 0xff) << "\n";
10040 }
10041 
10042 static void PrintLinkEditDataCommand(MachO::linkedit_data_command ld,
10043                                      uint32_t object_size) {
10044   if (ld.cmd == MachO::LC_CODE_SIGNATURE)
10045     outs() << "      cmd LC_CODE_SIGNATURE\n";
10046   else if (ld.cmd == MachO::LC_SEGMENT_SPLIT_INFO)
10047     outs() << "      cmd LC_SEGMENT_SPLIT_INFO\n";
10048   else if (ld.cmd == MachO::LC_FUNCTION_STARTS)
10049     outs() << "      cmd LC_FUNCTION_STARTS\n";
10050   else if (ld.cmd == MachO::LC_DATA_IN_CODE)
10051     outs() << "      cmd LC_DATA_IN_CODE\n";
10052   else if (ld.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS)
10053     outs() << "      cmd LC_DYLIB_CODE_SIGN_DRS\n";
10054   else if (ld.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT)
10055     outs() << "      cmd LC_LINKER_OPTIMIZATION_HINT\n";
10056   else if (ld.cmd == MachO::LC_DYLD_EXPORTS_TRIE)
10057     outs() << "      cmd LC_DYLD_EXPORTS_TRIE\n";
10058   else if (ld.cmd == MachO::LC_DYLD_CHAINED_FIXUPS)
10059     outs() << "      cmd LC_DYLD_CHAINED_FIXUPS\n";
10060   else
10061     outs() << "      cmd " << ld.cmd << " (?)\n";
10062   outs() << "  cmdsize " << ld.cmdsize;
10063   if (ld.cmdsize != sizeof(struct MachO::linkedit_data_command))
10064     outs() << " Incorrect size\n";
10065   else
10066     outs() << "\n";
10067   outs() << "  dataoff " << ld.dataoff;
10068   if (ld.dataoff > object_size)
10069     outs() << " (past end of file)\n";
10070   else
10071     outs() << "\n";
10072   outs() << " datasize " << ld.datasize;
10073   uint64_t big_size = ld.dataoff;
10074   big_size += ld.datasize;
10075   if (big_size > object_size)
10076     outs() << " (past end of file)\n";
10077   else
10078     outs() << "\n";
10079 }
10080 
10081 static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t filetype,
10082                               uint32_t cputype, bool verbose) {
10083   StringRef Buf = Obj->getData();
10084   unsigned Index = 0;
10085   for (const auto &Command : Obj->load_commands()) {
10086     outs() << "Load command " << Index++ << "\n";
10087     if (Command.C.cmd == MachO::LC_SEGMENT) {
10088       MachO::segment_command SLC = Obj->getSegmentLoadCommand(Command);
10089       const char *sg_segname = SLC.segname;
10090       PrintSegmentCommand(SLC.cmd, SLC.cmdsize, SLC.segname, SLC.vmaddr,
10091                           SLC.vmsize, SLC.fileoff, SLC.filesize, SLC.maxprot,
10092                           SLC.initprot, SLC.nsects, SLC.flags, Buf.size(),
10093                           verbose);
10094       for (unsigned j = 0; j < SLC.nsects; j++) {
10095         MachO::section S = Obj->getSection(Command, j);
10096         PrintSection(S.sectname, S.segname, S.addr, S.size, S.offset, S.align,
10097                      S.reloff, S.nreloc, S.flags, S.reserved1, S.reserved2,
10098                      SLC.cmd, sg_segname, filetype, Buf.size(), verbose);
10099       }
10100     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
10101       MachO::segment_command_64 SLC_64 = Obj->getSegment64LoadCommand(Command);
10102       const char *sg_segname = SLC_64.segname;
10103       PrintSegmentCommand(SLC_64.cmd, SLC_64.cmdsize, SLC_64.segname,
10104                           SLC_64.vmaddr, SLC_64.vmsize, SLC_64.fileoff,
10105                           SLC_64.filesize, SLC_64.maxprot, SLC_64.initprot,
10106                           SLC_64.nsects, SLC_64.flags, Buf.size(), verbose);
10107       for (unsigned j = 0; j < SLC_64.nsects; j++) {
10108         MachO::section_64 S_64 = Obj->getSection64(Command, j);
10109         PrintSection(S_64.sectname, S_64.segname, S_64.addr, S_64.size,
10110                      S_64.offset, S_64.align, S_64.reloff, S_64.nreloc,
10111                      S_64.flags, S_64.reserved1, S_64.reserved2, SLC_64.cmd,
10112                      sg_segname, filetype, Buf.size(), verbose);
10113       }
10114     } else if (Command.C.cmd == MachO::LC_SYMTAB) {
10115       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
10116       PrintSymtabLoadCommand(Symtab, Obj->is64Bit(), Buf.size());
10117     } else if (Command.C.cmd == MachO::LC_DYSYMTAB) {
10118       MachO::dysymtab_command Dysymtab = Obj->getDysymtabLoadCommand();
10119       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
10120       PrintDysymtabLoadCommand(Dysymtab, Symtab.nsyms, Buf.size(),
10121                                Obj->is64Bit());
10122     } else if (Command.C.cmd == MachO::LC_DYLD_INFO ||
10123                Command.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
10124       MachO::dyld_info_command DyldInfo = Obj->getDyldInfoLoadCommand(Command);
10125       PrintDyldInfoLoadCommand(DyldInfo, Buf.size());
10126     } else if (Command.C.cmd == MachO::LC_LOAD_DYLINKER ||
10127                Command.C.cmd == MachO::LC_ID_DYLINKER ||
10128                Command.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
10129       MachO::dylinker_command Dyld = Obj->getDylinkerCommand(Command);
10130       PrintDyldLoadCommand(Dyld, Command.Ptr);
10131     } else if (Command.C.cmd == MachO::LC_UUID) {
10132       MachO::uuid_command Uuid = Obj->getUuidCommand(Command);
10133       PrintUuidLoadCommand(Uuid);
10134     } else if (Command.C.cmd == MachO::LC_RPATH) {
10135       MachO::rpath_command Rpath = Obj->getRpathCommand(Command);
10136       PrintRpathLoadCommand(Rpath, Command.Ptr);
10137     } else if (Command.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
10138                Command.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS ||
10139                Command.C.cmd == MachO::LC_VERSION_MIN_TVOS ||
10140                Command.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
10141       MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
10142       PrintVersionMinLoadCommand(Vd);
10143     } else if (Command.C.cmd == MachO::LC_NOTE) {
10144       MachO::note_command Nt = Obj->getNoteLoadCommand(Command);
10145       PrintNoteLoadCommand(Nt);
10146     } else if (Command.C.cmd == MachO::LC_BUILD_VERSION) {
10147       MachO::build_version_command Bv =
10148           Obj->getBuildVersionLoadCommand(Command);
10149       PrintBuildVersionLoadCommand(Obj, Bv);
10150     } else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
10151       MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
10152       PrintSourceVersionCommand(Sd);
10153     } else if (Command.C.cmd == MachO::LC_MAIN) {
10154       MachO::entry_point_command Ep = Obj->getEntryPointCommand(Command);
10155       PrintEntryPointCommand(Ep);
10156     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO) {
10157       MachO::encryption_info_command Ei =
10158           Obj->getEncryptionInfoCommand(Command);
10159       PrintEncryptionInfoCommand(Ei, Buf.size());
10160     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
10161       MachO::encryption_info_command_64 Ei =
10162           Obj->getEncryptionInfoCommand64(Command);
10163       PrintEncryptionInfoCommand64(Ei, Buf.size());
10164     } else if (Command.C.cmd == MachO::LC_LINKER_OPTION) {
10165       MachO::linker_option_command Lo =
10166           Obj->getLinkerOptionLoadCommand(Command);
10167       PrintLinkerOptionCommand(Lo, Command.Ptr);
10168     } else if (Command.C.cmd == MachO::LC_SUB_FRAMEWORK) {
10169       MachO::sub_framework_command Sf = Obj->getSubFrameworkCommand(Command);
10170       PrintSubFrameworkCommand(Sf, Command.Ptr);
10171     } else if (Command.C.cmd == MachO::LC_SUB_UMBRELLA) {
10172       MachO::sub_umbrella_command Sf = Obj->getSubUmbrellaCommand(Command);
10173       PrintSubUmbrellaCommand(Sf, Command.Ptr);
10174     } else if (Command.C.cmd == MachO::LC_SUB_LIBRARY) {
10175       MachO::sub_library_command Sl = Obj->getSubLibraryCommand(Command);
10176       PrintSubLibraryCommand(Sl, Command.Ptr);
10177     } else if (Command.C.cmd == MachO::LC_SUB_CLIENT) {
10178       MachO::sub_client_command Sc = Obj->getSubClientCommand(Command);
10179       PrintSubClientCommand(Sc, Command.Ptr);
10180     } else if (Command.C.cmd == MachO::LC_ROUTINES) {
10181       MachO::routines_command Rc = Obj->getRoutinesCommand(Command);
10182       PrintRoutinesCommand(Rc);
10183     } else if (Command.C.cmd == MachO::LC_ROUTINES_64) {
10184       MachO::routines_command_64 Rc = Obj->getRoutinesCommand64(Command);
10185       PrintRoutinesCommand64(Rc);
10186     } else if (Command.C.cmd == MachO::LC_THREAD ||
10187                Command.C.cmd == MachO::LC_UNIXTHREAD) {
10188       MachO::thread_command Tc = Obj->getThreadCommand(Command);
10189       PrintThreadCommand(Tc, Command.Ptr, Obj->isLittleEndian(), cputype);
10190     } else if (Command.C.cmd == MachO::LC_LOAD_DYLIB ||
10191                Command.C.cmd == MachO::LC_ID_DYLIB ||
10192                Command.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
10193                Command.C.cmd == MachO::LC_REEXPORT_DYLIB ||
10194                Command.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
10195                Command.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
10196       MachO::dylib_command Dl = Obj->getDylibIDLoadCommand(Command);
10197       PrintDylibCommand(Dl, Command.Ptr);
10198     } else if (Command.C.cmd == MachO::LC_CODE_SIGNATURE ||
10199                Command.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO ||
10200                Command.C.cmd == MachO::LC_FUNCTION_STARTS ||
10201                Command.C.cmd == MachO::LC_DATA_IN_CODE ||
10202                Command.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS ||
10203                Command.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT ||
10204                Command.C.cmd == MachO::LC_DYLD_EXPORTS_TRIE ||
10205                Command.C.cmd == MachO::LC_DYLD_CHAINED_FIXUPS) {
10206       MachO::linkedit_data_command Ld =
10207           Obj->getLinkeditDataLoadCommand(Command);
10208       PrintLinkEditDataCommand(Ld, Buf.size());
10209     } else {
10210       outs() << "      cmd ?(" << format("0x%08" PRIx32, Command.C.cmd)
10211              << ")\n";
10212       outs() << "  cmdsize " << Command.C.cmdsize << "\n";
10213       // TODO: get and print the raw bytes of the load command.
10214     }
10215     // TODO: print all the other kinds of load commands.
10216   }
10217 }
10218 
10219 static void PrintMachHeader(const MachOObjectFile *Obj, bool verbose) {
10220   if (Obj->is64Bit()) {
10221     MachO::mach_header_64 H_64;
10222     H_64 = Obj->getHeader64();
10223     PrintMachHeader(H_64.magic, H_64.cputype, H_64.cpusubtype, H_64.filetype,
10224                     H_64.ncmds, H_64.sizeofcmds, H_64.flags, verbose);
10225   } else {
10226     MachO::mach_header H;
10227     H = Obj->getHeader();
10228     PrintMachHeader(H.magic, H.cputype, H.cpusubtype, H.filetype, H.ncmds,
10229                     H.sizeofcmds, H.flags, verbose);
10230   }
10231 }
10232 
10233 void objdump::printMachOFileHeader(const object::ObjectFile *Obj) {
10234   const MachOObjectFile *file = cast<const MachOObjectFile>(Obj);
10235   PrintMachHeader(file, Verbose);
10236 }
10237 
10238 void objdump::printMachOLoadCommands(const object::ObjectFile *Obj) {
10239   const MachOObjectFile *file = cast<const MachOObjectFile>(Obj);
10240   uint32_t filetype = 0;
10241   uint32_t cputype = 0;
10242   if (file->is64Bit()) {
10243     MachO::mach_header_64 H_64;
10244     H_64 = file->getHeader64();
10245     filetype = H_64.filetype;
10246     cputype = H_64.cputype;
10247   } else {
10248     MachO::mach_header H;
10249     H = file->getHeader();
10250     filetype = H.filetype;
10251     cputype = H.cputype;
10252   }
10253   PrintLoadCommands(file, filetype, cputype, Verbose);
10254 }
10255 
10256 //===----------------------------------------------------------------------===//
10257 // export trie dumping
10258 //===----------------------------------------------------------------------===//
10259 
10260 static void printMachOExportsTrie(const object::MachOObjectFile *Obj) {
10261   uint64_t BaseSegmentAddress = 0;
10262   for (const auto &Command : Obj->load_commands()) {
10263     if (Command.C.cmd == MachO::LC_SEGMENT) {
10264       MachO::segment_command Seg = Obj->getSegmentLoadCommand(Command);
10265       if (Seg.fileoff == 0 && Seg.filesize != 0) {
10266         BaseSegmentAddress = Seg.vmaddr;
10267         break;
10268       }
10269     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
10270       MachO::segment_command_64 Seg = Obj->getSegment64LoadCommand(Command);
10271       if (Seg.fileoff == 0 && Seg.filesize != 0) {
10272         BaseSegmentAddress = Seg.vmaddr;
10273         break;
10274       }
10275     }
10276   }
10277   Error Err = Error::success();
10278   for (const object::ExportEntry &Entry : Obj->exports(Err)) {
10279     uint64_t Flags = Entry.flags();
10280     bool ReExport = (Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
10281     bool WeakDef = (Flags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
10282     bool ThreadLocal = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
10283                         MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL);
10284     bool Abs = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
10285                 MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
10286     bool Resolver = (Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
10287     if (ReExport)
10288       outs() << "[re-export] ";
10289     else
10290       outs() << format("0x%08llX  ",
10291                        Entry.address() + BaseSegmentAddress);
10292     outs() << Entry.name();
10293     if (WeakDef || ThreadLocal || Resolver || Abs) {
10294       ListSeparator LS;
10295       outs() << " [";
10296       if (WeakDef)
10297         outs() << LS << "weak_def";
10298       if (ThreadLocal)
10299         outs() << LS << "per-thread";
10300       if (Abs)
10301         outs() << LS << "absolute";
10302       if (Resolver)
10303         outs() << LS << format("resolver=0x%08llX", Entry.other());
10304       outs() << "]";
10305     }
10306     if (ReExport) {
10307       StringRef DylibName = "unknown";
10308       int Ordinal = Entry.other() - 1;
10309       Obj->getLibraryShortNameByIndex(Ordinal, DylibName);
10310       if (Entry.otherName().empty())
10311         outs() << " (from " << DylibName << ")";
10312       else
10313         outs() << " (" << Entry.otherName() << " from " << DylibName << ")";
10314     }
10315     outs() << "\n";
10316   }
10317   if (Err)
10318     reportError(std::move(Err), Obj->getFileName());
10319 }
10320 
10321 //===----------------------------------------------------------------------===//
10322 // rebase table dumping
10323 //===----------------------------------------------------------------------===//
10324 
10325 static void printMachORebaseTable(object::MachOObjectFile *Obj) {
10326   outs() << "segment  section            address     type\n";
10327   Error Err = Error::success();
10328   for (const object::MachORebaseEntry &Entry : Obj->rebaseTable(Err)) {
10329     StringRef SegmentName = Entry.segmentName();
10330     StringRef SectionName = Entry.sectionName();
10331     uint64_t Address = Entry.address();
10332 
10333     // Table lines look like: __DATA  __nl_symbol_ptr  0x0000F00C  pointer
10334     outs() << format("%-8s %-18s 0x%08" PRIX64 "  %s\n",
10335                      SegmentName.str().c_str(), SectionName.str().c_str(),
10336                      Address, Entry.typeName().str().c_str());
10337   }
10338   if (Err)
10339     reportError(std::move(Err), Obj->getFileName());
10340 }
10341 
10342 static StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) {
10343   StringRef DylibName;
10344   switch (Ordinal) {
10345   case MachO::BIND_SPECIAL_DYLIB_SELF:
10346     return "this-image";
10347   case MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE:
10348     return "main-executable";
10349   case MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP:
10350     return "flat-namespace";
10351   default:
10352     if (Ordinal > 0) {
10353       std::error_code EC =
10354           Obj->getLibraryShortNameByIndex(Ordinal - 1, DylibName);
10355       if (EC)
10356         return "<<bad library ordinal>>";
10357       return DylibName;
10358     }
10359   }
10360   return "<<unknown special ordinal>>";
10361 }
10362 
10363 //===----------------------------------------------------------------------===//
10364 // bind table dumping
10365 //===----------------------------------------------------------------------===//
10366 
10367 static void printMachOBindTable(object::MachOObjectFile *Obj) {
10368   // Build table of sections so names can used in final output.
10369   outs() << "segment  section            address    type       "
10370             "addend dylib            symbol\n";
10371   Error Err = Error::success();
10372   for (const object::MachOBindEntry &Entry : Obj->bindTable(Err)) {
10373     StringRef SegmentName = Entry.segmentName();
10374     StringRef SectionName = Entry.sectionName();
10375     uint64_t Address = Entry.address();
10376 
10377     // Table lines look like:
10378     //  __DATA  __got  0x00012010    pointer   0 libSystem ___stack_chk_guard
10379     StringRef Attr;
10380     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT)
10381       Attr = " (weak_import)";
10382     outs() << left_justify(SegmentName, 8) << " "
10383            << left_justify(SectionName, 18) << " "
10384            << format_hex(Address, 10, true) << " "
10385            << left_justify(Entry.typeName(), 8) << " "
10386            << format_decimal(Entry.addend(), 8) << " "
10387            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
10388            << Entry.symbolName() << Attr << "\n";
10389   }
10390   if (Err)
10391     reportError(std::move(Err), Obj->getFileName());
10392 }
10393 
10394 //===----------------------------------------------------------------------===//
10395 // lazy bind table dumping
10396 //===----------------------------------------------------------------------===//
10397 
10398 static void printMachOLazyBindTable(object::MachOObjectFile *Obj) {
10399   outs() << "segment  section            address     "
10400             "dylib            symbol\n";
10401   Error Err = Error::success();
10402   for (const object::MachOBindEntry &Entry : Obj->lazyBindTable(Err)) {
10403     StringRef SegmentName = Entry.segmentName();
10404     StringRef SectionName = Entry.sectionName();
10405     uint64_t Address = Entry.address();
10406 
10407     // Table lines look like:
10408     //  __DATA  __got  0x00012010 libSystem ___stack_chk_guard
10409     outs() << left_justify(SegmentName, 8) << " "
10410            << left_justify(SectionName, 18) << " "
10411            << format_hex(Address, 10, true) << " "
10412            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
10413            << Entry.symbolName() << "\n";
10414   }
10415   if (Err)
10416     reportError(std::move(Err), Obj->getFileName());
10417 }
10418 
10419 //===----------------------------------------------------------------------===//
10420 // weak bind table dumping
10421 //===----------------------------------------------------------------------===//
10422 
10423 static void printMachOWeakBindTable(object::MachOObjectFile *Obj) {
10424   outs() << "segment  section            address     "
10425             "type       addend   symbol\n";
10426   Error Err = Error::success();
10427   for (const object::MachOBindEntry &Entry : Obj->weakBindTable(Err)) {
10428     // Strong symbols don't have a location to update.
10429     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
10430       outs() << "                                        strong              "
10431              << Entry.symbolName() << "\n";
10432       continue;
10433     }
10434     StringRef SegmentName = Entry.segmentName();
10435     StringRef SectionName = Entry.sectionName();
10436     uint64_t Address = Entry.address();
10437 
10438     // Table lines look like:
10439     // __DATA  __data  0x00001000  pointer    0   _foo
10440     outs() << left_justify(SegmentName, 8) << " "
10441            << left_justify(SectionName, 18) << " "
10442            << format_hex(Address, 10, true) << " "
10443            << left_justify(Entry.typeName(), 8) << " "
10444            << format_decimal(Entry.addend(), 8) << "   " << Entry.symbolName()
10445            << "\n";
10446   }
10447   if (Err)
10448     reportError(std::move(Err), Obj->getFileName());
10449 }
10450 
10451 // get_dyld_bind_info_symbolname() is used for disassembly and passed an
10452 // address, ReferenceValue, in the Mach-O file and looks in the dyld bind
10453 // information for that address. If the address is found its binding symbol
10454 // name is returned.  If not nullptr is returned.
10455 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
10456                                                  struct DisassembleInfo *info) {
10457   if (info->bindtable == nullptr) {
10458     info->bindtable = std::make_unique<SymbolAddressMap>();
10459     Error Err = Error::success();
10460     for (const object::MachOBindEntry &Entry : info->O->bindTable(Err)) {
10461       uint64_t Address = Entry.address();
10462       StringRef name = Entry.symbolName();
10463       if (!name.empty())
10464         (*info->bindtable)[Address] = name;
10465     }
10466     if (Err)
10467       reportError(std::move(Err), info->O->getFileName());
10468   }
10469   auto name = info->bindtable->lookup(ReferenceValue);
10470   return !name.empty() ? name.data() : nullptr;
10471 }
10472 
10473 void objdump::printLazyBindTable(ObjectFile *o) {
10474   outs() << "\nLazy bind table:\n";
10475   if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10476     printMachOLazyBindTable(MachO);
10477   else
10478     WithColor::error()
10479         << "This operation is only currently supported "
10480            "for Mach-O executable files.\n";
10481 }
10482 
10483 void objdump::printWeakBindTable(ObjectFile *o) {
10484   outs() << "\nWeak bind table:\n";
10485   if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10486     printMachOWeakBindTable(MachO);
10487   else
10488     WithColor::error()
10489         << "This operation is only currently supported "
10490            "for Mach-O executable files.\n";
10491 }
10492 
10493 void objdump::printExportsTrie(const ObjectFile *o) {
10494   outs() << "\nExports trie:\n";
10495   if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10496     printMachOExportsTrie(MachO);
10497   else
10498     WithColor::error()
10499         << "This operation is only currently supported "
10500            "for Mach-O executable files.\n";
10501 }
10502 
10503 void objdump::printRebaseTable(ObjectFile *o) {
10504   outs() << "\nRebase table:\n";
10505   if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10506     printMachORebaseTable(MachO);
10507   else
10508     WithColor::error()
10509         << "This operation is only currently supported "
10510            "for Mach-O executable files.\n";
10511 }
10512 
10513 void objdump::printBindTable(ObjectFile *o) {
10514   outs() << "\nBind table:\n";
10515   if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
10516     printMachOBindTable(MachO);
10517   else
10518     WithColor::error()
10519         << "This operation is only currently supported "
10520            "for Mach-O executable files.\n";
10521 }
10522