df8ac09846c289f7e35f90d9e3fe1679d59ff460
[oota-llvm.git] / tools / llvm-objdump / MachODump.cpp
1 //===-- MachODump.cpp - Object file dumping utility for llvm --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the MachO-specific dumper for llvm-objdump.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm-objdump.h"
15 #include "llvm-c/Disassembler.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Config/config.h"
20 #include "llvm/DebugInfo/DIContext.h"
21 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
22 #include "llvm/MC/MCAsmInfo.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCDisassembler.h"
25 #include "llvm/MC/MCInst.h"
26 #include "llvm/MC/MCInstPrinter.h"
27 #include "llvm/MC/MCInstrDesc.h"
28 #include "llvm/MC/MCInstrInfo.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCSubtargetInfo.h"
31 #include "llvm/Object/MachO.h"
32 #include "llvm/Object/MachOUniversal.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/CommandLine.h"
35 #include "llvm/Support/Debug.h"
36 #include "llvm/Support/Endian.h"
37 #include "llvm/Support/Format.h"
38 #include "llvm/Support/FormattedStream.h"
39 #include "llvm/Support/GraphWriter.h"
40 #include "llvm/Support/LEB128.h"
41 #include "llvm/Support/MachO.h"
42 #include "llvm/Support/MemoryBuffer.h"
43 #include "llvm/Support/TargetRegistry.h"
44 #include "llvm/Support/TargetSelect.h"
45 #include "llvm/Support/raw_ostream.h"
46 #include <algorithm>
47 #include <cstring>
48 #include <system_error>
49
50 #if HAVE_CXXABI_H
51 #include <cxxabi.h>
52 #endif
53
54 using namespace llvm;
55 using namespace object;
56
57 static cl::opt<bool>
58     UseDbg("g",
59            cl::desc("Print line information from debug info if available"));
60
61 static cl::opt<std::string> DSYMFile("dsym",
62                                      cl::desc("Use .dSYM file for debug info"));
63
64 static cl::opt<bool> FullLeadingAddr("full-leading-addr",
65                                      cl::desc("Print full leading address"));
66
67 static cl::opt<bool> NoLeadingAddr("no-leading-addr",
68                                    cl::desc("Print no leading address"));
69
70 cl::opt<bool> llvm::UniversalHeaders("universal-headers",
71                                      cl::desc("Print Mach-O universal headers "
72                                               "(requires -macho)"));
73
74 cl::opt<bool>
75     llvm::ArchiveHeaders("archive-headers",
76                          cl::desc("Print archive headers for Mach-O archives "
77                                   "(requires -macho)"));
78
79 cl::opt<bool>
80     ArchiveMemberOffsets("archive-member-offsets",
81                          cl::desc("Print the offset to each archive member for "
82                                   "Mach-O archives (requires -macho and "
83                                   "-archive-headers)"));
84
85 cl::opt<bool>
86     llvm::IndirectSymbols("indirect-symbols",
87                           cl::desc("Print indirect symbol table for Mach-O "
88                                    "objects (requires -macho)"));
89
90 cl::opt<bool>
91     llvm::DataInCode("data-in-code",
92                      cl::desc("Print the data in code table for Mach-O objects "
93                               "(requires -macho)"));
94
95 cl::opt<bool>
96     llvm::LinkOptHints("link-opt-hints",
97                        cl::desc("Print the linker optimization hints for "
98                                 "Mach-O objects (requires -macho)"));
99
100 cl::opt<bool>
101     llvm::InfoPlist("info-plist",
102                     cl::desc("Print the info plist section as strings for "
103                              "Mach-O objects (requires -macho)"));
104
105 cl::opt<bool>
106     llvm::DylibsUsed("dylibs-used",
107                      cl::desc("Print the shared libraries used for linked "
108                               "Mach-O files (requires -macho)"));
109
110 cl::opt<bool>
111     llvm::DylibId("dylib-id",
112                   cl::desc("Print the shared library's id for the dylib Mach-O "
113                            "file (requires -macho)"));
114
115 cl::opt<bool>
116     llvm::NonVerbose("non-verbose",
117                      cl::desc("Print the info for Mach-O objects in "
118                               "non-verbose or numeric form (requires -macho)"));
119
120 cl::opt<bool>
121     llvm::ObjcMetaData("objc-meta-data",
122                        cl::desc("Print the Objective-C runtime meta data for "
123                                 "Mach-O files (requires -macho)"));
124
125 cl::opt<std::string> llvm::DisSymName(
126     "dis-symname",
127     cl::desc("disassemble just this symbol's instructions (requires -macho"));
128
129 static cl::opt<bool> NoSymbolicOperands(
130     "no-symbolic-operands",
131     cl::desc("do not symbolic operands when disassembling (requires -macho)"));
132
133 static cl::list<std::string>
134     ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
135               cl::ZeroOrMore);
136 bool ArchAll = false;
137
138 static std::string ThumbTripleName;
139
140 static const Target *GetTarget(const MachOObjectFile *MachOObj,
141                                const char **McpuDefault,
142                                const Target **ThumbTarget) {
143   // Figure out the target triple.
144   if (TripleName.empty()) {
145     llvm::Triple TT("unknown-unknown-unknown");
146     llvm::Triple ThumbTriple = Triple();
147     TT = MachOObj->getArch(McpuDefault, &ThumbTriple);
148     TripleName = TT.str();
149     ThumbTripleName = ThumbTriple.str();
150   }
151
152   // Get the target specific parser.
153   std::string Error;
154   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
155   if (TheTarget && ThumbTripleName.empty())
156     return TheTarget;
157
158   *ThumbTarget = TargetRegistry::lookupTarget(ThumbTripleName, Error);
159   if (*ThumbTarget)
160     return TheTarget;
161
162   errs() << "llvm-objdump: error: unable to get target for '";
163   if (!TheTarget)
164     errs() << TripleName;
165   else
166     errs() << ThumbTripleName;
167   errs() << "', see --version and --triple.\n";
168   return nullptr;
169 }
170
171 struct SymbolSorter {
172   bool operator()(const SymbolRef &A, const SymbolRef &B) {
173     uint64_t AAddr = (A.getType() != SymbolRef::ST_Function) ? 0 : A.getValue();
174     uint64_t BAddr = (B.getType() != SymbolRef::ST_Function) ? 0 : B.getValue();
175     return AAddr < BAddr;
176   }
177 };
178
179 // Types for the storted data in code table that is built before disassembly
180 // and the predicate function to sort them.
181 typedef std::pair<uint64_t, DiceRef> DiceTableEntry;
182 typedef std::vector<DiceTableEntry> DiceTable;
183 typedef DiceTable::iterator dice_table_iterator;
184
185 // This is used to search for a data in code table entry for the PC being
186 // disassembled.  The j parameter has the PC in j.first.  A single data in code
187 // table entry can cover many bytes for each of its Kind's.  So if the offset,
188 // aka the i.first value, of the data in code table entry plus its Length
189 // covers the PC being searched for this will return true.  If not it will
190 // return false.
191 static bool compareDiceTableEntries(const DiceTableEntry &i,
192                                     const DiceTableEntry &j) {
193   uint16_t Length;
194   i.second.getLength(Length);
195
196   return j.first >= i.first && j.first < i.first + Length;
197 }
198
199 static uint64_t DumpDataInCode(const uint8_t *bytes, uint64_t Length,
200                                unsigned short Kind) {
201   uint32_t Value, Size = 1;
202
203   switch (Kind) {
204   default:
205   case MachO::DICE_KIND_DATA:
206     if (Length >= 4) {
207       if (!NoShowRawInsn)
208         dumpBytes(ArrayRef<uint8_t>(bytes, 4), outs());
209       Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
210       outs() << "\t.long " << Value;
211       Size = 4;
212     } else if (Length >= 2) {
213       if (!NoShowRawInsn)
214         dumpBytes(ArrayRef<uint8_t>(bytes, 2), outs());
215       Value = bytes[1] << 8 | bytes[0];
216       outs() << "\t.short " << Value;
217       Size = 2;
218     } else {
219       if (!NoShowRawInsn)
220         dumpBytes(ArrayRef<uint8_t>(bytes, 2), outs());
221       Value = bytes[0];
222       outs() << "\t.byte " << Value;
223       Size = 1;
224     }
225     if (Kind == MachO::DICE_KIND_DATA)
226       outs() << "\t@ KIND_DATA\n";
227     else
228       outs() << "\t@ data in code kind = " << Kind << "\n";
229     break;
230   case MachO::DICE_KIND_JUMP_TABLE8:
231     if (!NoShowRawInsn)
232       dumpBytes(ArrayRef<uint8_t>(bytes, 1), outs());
233     Value = bytes[0];
234     outs() << "\t.byte " << format("%3u", Value) << "\t@ KIND_JUMP_TABLE8\n";
235     Size = 1;
236     break;
237   case MachO::DICE_KIND_JUMP_TABLE16:
238     if (!NoShowRawInsn)
239       dumpBytes(ArrayRef<uint8_t>(bytes, 2), outs());
240     Value = bytes[1] << 8 | bytes[0];
241     outs() << "\t.short " << format("%5u", Value & 0xffff)
242            << "\t@ KIND_JUMP_TABLE16\n";
243     Size = 2;
244     break;
245   case MachO::DICE_KIND_JUMP_TABLE32:
246   case MachO::DICE_KIND_ABS_JUMP_TABLE32:
247     if (!NoShowRawInsn)
248       dumpBytes(ArrayRef<uint8_t>(bytes, 4), outs());
249     Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
250     outs() << "\t.long " << Value;
251     if (Kind == MachO::DICE_KIND_JUMP_TABLE32)
252       outs() << "\t@ KIND_JUMP_TABLE32\n";
253     else
254       outs() << "\t@ KIND_ABS_JUMP_TABLE32\n";
255     Size = 4;
256     break;
257   }
258   return Size;
259 }
260
261 static void getSectionsAndSymbols(MachOObjectFile *MachOObj,
262                                   std::vector<SectionRef> &Sections,
263                                   std::vector<SymbolRef> &Symbols,
264                                   SmallVectorImpl<uint64_t> &FoundFns,
265                                   uint64_t &BaseSegmentAddress) {
266   for (const SymbolRef &Symbol : MachOObj->symbols()) {
267     ErrorOr<StringRef> SymName = Symbol.getName();
268     if (std::error_code EC = SymName.getError())
269       report_fatal_error(EC.message());
270     if (!SymName->startswith("ltmp"))
271       Symbols.push_back(Symbol);
272   }
273
274   for (const SectionRef &Section : MachOObj->sections()) {
275     StringRef SectName;
276     Section.getName(SectName);
277     Sections.push_back(Section);
278   }
279
280   bool BaseSegmentAddressSet = false;
281   for (const auto &Command : MachOObj->load_commands()) {
282     if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
283       // We found a function starts segment, parse the addresses for later
284       // consumption.
285       MachO::linkedit_data_command LLC =
286           MachOObj->getLinkeditDataLoadCommand(Command);
287
288       MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
289     } else if (Command.C.cmd == MachO::LC_SEGMENT) {
290       MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command);
291       StringRef SegName = SLC.segname;
292       if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
293         BaseSegmentAddressSet = true;
294         BaseSegmentAddress = SLC.vmaddr;
295       }
296     }
297   }
298 }
299
300 static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose,
301                                      uint32_t n, uint32_t count,
302                                      uint32_t stride, uint64_t addr) {
303   MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
304   uint32_t nindirectsyms = Dysymtab.nindirectsyms;
305   if (n > nindirectsyms)
306     outs() << " (entries start past the end of the indirect symbol "
307               "table) (reserved1 field greater than the table size)";
308   else if (n + count > nindirectsyms)
309     outs() << " (entries extends past the end of the indirect symbol "
310               "table)";
311   outs() << "\n";
312   uint32_t cputype = O->getHeader().cputype;
313   if (cputype & MachO::CPU_ARCH_ABI64)
314     outs() << "address            index";
315   else
316     outs() << "address    index";
317   if (verbose)
318     outs() << " name\n";
319   else
320     outs() << "\n";
321   for (uint32_t j = 0; j < count && n + j < nindirectsyms; j++) {
322     if (cputype & MachO::CPU_ARCH_ABI64)
323       outs() << format("0x%016" PRIx64, addr + j * stride) << " ";
324     else
325       outs() << format("0x%08" PRIx32, addr + j * stride) << " ";
326     MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
327     uint32_t indirect_symbol = O->getIndirectSymbolTableEntry(Dysymtab, n + j);
328     if (indirect_symbol == MachO::INDIRECT_SYMBOL_LOCAL) {
329       outs() << "LOCAL\n";
330       continue;
331     }
332     if (indirect_symbol ==
333         (MachO::INDIRECT_SYMBOL_LOCAL | MachO::INDIRECT_SYMBOL_ABS)) {
334       outs() << "LOCAL ABSOLUTE\n";
335       continue;
336     }
337     if (indirect_symbol == MachO::INDIRECT_SYMBOL_ABS) {
338       outs() << "ABSOLUTE\n";
339       continue;
340     }
341     outs() << format("%5u ", indirect_symbol);
342     if (verbose) {
343       MachO::symtab_command Symtab = O->getSymtabLoadCommand();
344       if (indirect_symbol < Symtab.nsyms) {
345         symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol);
346         SymbolRef Symbol = *Sym;
347         ErrorOr<StringRef> SymName = Symbol.getName();
348         if (std::error_code EC = SymName.getError())
349           report_fatal_error(EC.message());
350         outs() << *SymName;
351       } else {
352         outs() << "?";
353       }
354     }
355     outs() << "\n";
356   }
357 }
358
359 static void PrintIndirectSymbols(MachOObjectFile *O, bool verbose) {
360   for (const auto &Load : O->load_commands()) {
361     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
362       MachO::segment_command_64 Seg = O->getSegment64LoadCommand(Load);
363       for (unsigned J = 0; J < Seg.nsects; ++J) {
364         MachO::section_64 Sec = O->getSection64(Load, J);
365         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
366         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
367             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
368             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
369             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
370             section_type == MachO::S_SYMBOL_STUBS) {
371           uint32_t stride;
372           if (section_type == MachO::S_SYMBOL_STUBS)
373             stride = Sec.reserved2;
374           else
375             stride = 8;
376           if (stride == 0) {
377             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
378                    << Sec.sectname << ") "
379                    << "(size of stubs in reserved2 field is zero)\n";
380             continue;
381           }
382           uint32_t count = Sec.size / stride;
383           outs() << "Indirect symbols for (" << Sec.segname << ","
384                  << Sec.sectname << ") " << count << " entries";
385           uint32_t n = Sec.reserved1;
386           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
387         }
388       }
389     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
390       MachO::segment_command Seg = O->getSegmentLoadCommand(Load);
391       for (unsigned J = 0; J < Seg.nsects; ++J) {
392         MachO::section Sec = O->getSection(Load, J);
393         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
394         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
395             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
396             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
397             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
398             section_type == MachO::S_SYMBOL_STUBS) {
399           uint32_t stride;
400           if (section_type == MachO::S_SYMBOL_STUBS)
401             stride = Sec.reserved2;
402           else
403             stride = 4;
404           if (stride == 0) {
405             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
406                    << Sec.sectname << ") "
407                    << "(size of stubs in reserved2 field is zero)\n";
408             continue;
409           }
410           uint32_t count = Sec.size / stride;
411           outs() << "Indirect symbols for (" << Sec.segname << ","
412                  << Sec.sectname << ") " << count << " entries";
413           uint32_t n = Sec.reserved1;
414           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
415         }
416       }
417     }
418   }
419 }
420
421 static void PrintDataInCodeTable(MachOObjectFile *O, bool verbose) {
422   MachO::linkedit_data_command DIC = O->getDataInCodeLoadCommand();
423   uint32_t nentries = DIC.datasize / sizeof(struct MachO::data_in_code_entry);
424   outs() << "Data in code table (" << nentries << " entries)\n";
425   outs() << "offset     length kind\n";
426   for (dice_iterator DI = O->begin_dices(), DE = O->end_dices(); DI != DE;
427        ++DI) {
428     uint32_t Offset;
429     DI->getOffset(Offset);
430     outs() << format("0x%08" PRIx32, Offset) << " ";
431     uint16_t Length;
432     DI->getLength(Length);
433     outs() << format("%6u", Length) << " ";
434     uint16_t Kind;
435     DI->getKind(Kind);
436     if (verbose) {
437       switch (Kind) {
438       case MachO::DICE_KIND_DATA:
439         outs() << "DATA";
440         break;
441       case MachO::DICE_KIND_JUMP_TABLE8:
442         outs() << "JUMP_TABLE8";
443         break;
444       case MachO::DICE_KIND_JUMP_TABLE16:
445         outs() << "JUMP_TABLE16";
446         break;
447       case MachO::DICE_KIND_JUMP_TABLE32:
448         outs() << "JUMP_TABLE32";
449         break;
450       case MachO::DICE_KIND_ABS_JUMP_TABLE32:
451         outs() << "ABS_JUMP_TABLE32";
452         break;
453       default:
454         outs() << format("0x%04" PRIx32, Kind);
455         break;
456       }
457     } else
458       outs() << format("0x%04" PRIx32, Kind);
459     outs() << "\n";
460   }
461 }
462
463 static void PrintLinkOptHints(MachOObjectFile *O) {
464   MachO::linkedit_data_command LohLC = O->getLinkOptHintsLoadCommand();
465   const char *loh = O->getData().substr(LohLC.dataoff, 1).data();
466   uint32_t nloh = LohLC.datasize;
467   outs() << "Linker optimiztion hints (" << nloh << " total bytes)\n";
468   for (uint32_t i = 0; i < nloh;) {
469     unsigned n;
470     uint64_t identifier = decodeULEB128((const uint8_t *)(loh + i), &n);
471     i += n;
472     outs() << "    identifier " << identifier << " ";
473     if (i >= nloh)
474       return;
475     switch (identifier) {
476     case 1:
477       outs() << "AdrpAdrp\n";
478       break;
479     case 2:
480       outs() << "AdrpLdr\n";
481       break;
482     case 3:
483       outs() << "AdrpAddLdr\n";
484       break;
485     case 4:
486       outs() << "AdrpLdrGotLdr\n";
487       break;
488     case 5:
489       outs() << "AdrpAddStr\n";
490       break;
491     case 6:
492       outs() << "AdrpLdrGotStr\n";
493       break;
494     case 7:
495       outs() << "AdrpAdd\n";
496       break;
497     case 8:
498       outs() << "AdrpLdrGot\n";
499       break;
500     default:
501       outs() << "Unknown identifier value\n";
502       break;
503     }
504     uint64_t narguments = decodeULEB128((const uint8_t *)(loh + i), &n);
505     i += n;
506     outs() << "    narguments " << narguments << "\n";
507     if (i >= nloh)
508       return;
509
510     for (uint32_t j = 0; j < narguments; j++) {
511       uint64_t value = decodeULEB128((const uint8_t *)(loh + i), &n);
512       i += n;
513       outs() << "\tvalue " << format("0x%" PRIx64, value) << "\n";
514       if (i >= nloh)
515         return;
516     }
517   }
518 }
519
520 static void PrintDylibs(MachOObjectFile *O, bool JustId) {
521   unsigned Index = 0;
522   for (const auto &Load : O->load_commands()) {
523     if ((JustId && Load.C.cmd == MachO::LC_ID_DYLIB) ||
524         (!JustId && (Load.C.cmd == MachO::LC_ID_DYLIB ||
525                      Load.C.cmd == MachO::LC_LOAD_DYLIB ||
526                      Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
527                      Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
528                      Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
529                      Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB))) {
530       MachO::dylib_command dl = O->getDylibIDLoadCommand(Load);
531       if (dl.dylib.name < dl.cmdsize) {
532         const char *p = (const char *)(Load.Ptr) + dl.dylib.name;
533         if (JustId)
534           outs() << p << "\n";
535         else {
536           outs() << "\t" << p;
537           outs() << " (compatibility version "
538                  << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
539                  << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
540                  << (dl.dylib.compatibility_version & 0xff) << ",";
541           outs() << " current version "
542                  << ((dl.dylib.current_version >> 16) & 0xffff) << "."
543                  << ((dl.dylib.current_version >> 8) & 0xff) << "."
544                  << (dl.dylib.current_version & 0xff) << ")\n";
545         }
546       } else {
547         outs() << "\tBad offset (" << dl.dylib.name << ") for name of ";
548         if (Load.C.cmd == MachO::LC_ID_DYLIB)
549           outs() << "LC_ID_DYLIB ";
550         else if (Load.C.cmd == MachO::LC_LOAD_DYLIB)
551           outs() << "LC_LOAD_DYLIB ";
552         else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB)
553           outs() << "LC_LOAD_WEAK_DYLIB ";
554         else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB)
555           outs() << "LC_LAZY_LOAD_DYLIB ";
556         else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB)
557           outs() << "LC_REEXPORT_DYLIB ";
558         else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
559           outs() << "LC_LOAD_UPWARD_DYLIB ";
560         else
561           outs() << "LC_??? ";
562         outs() << "command " << Index++ << "\n";
563       }
564     }
565   }
566 }
567
568 typedef DenseMap<uint64_t, StringRef> SymbolAddressMap;
569
570 static void CreateSymbolAddressMap(MachOObjectFile *O,
571                                    SymbolAddressMap *AddrMap) {
572   // Create a map of symbol addresses to symbol names.
573   for (const SymbolRef &Symbol : O->symbols()) {
574     SymbolRef::Type ST = Symbol.getType();
575     if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
576         ST == SymbolRef::ST_Other) {
577       uint64_t Address = Symbol.getValue();
578       ErrorOr<StringRef> SymNameOrErr = Symbol.getName();
579       if (std::error_code EC = SymNameOrErr.getError())
580         report_fatal_error(EC.message());
581       StringRef SymName = *SymNameOrErr;
582       if (!SymName.startswith(".objc"))
583         (*AddrMap)[Address] = SymName;
584     }
585   }
586 }
587
588 // GuessSymbolName is passed the address of what might be a symbol and a
589 // pointer to the SymbolAddressMap.  It returns the name of a symbol
590 // with that address or nullptr if no symbol is found with that address.
591 static const char *GuessSymbolName(uint64_t value, SymbolAddressMap *AddrMap) {
592   const char *SymbolName = nullptr;
593   // A DenseMap can't lookup up some values.
594   if (value != 0xffffffffffffffffULL && value != 0xfffffffffffffffeULL) {
595     StringRef name = AddrMap->lookup(value);
596     if (!name.empty())
597       SymbolName = name.data();
598   }
599   return SymbolName;
600 }
601
602 static void DumpCstringChar(const char c) {
603   char p[2];
604   p[0] = c;
605   p[1] = '\0';
606   outs().write_escaped(p);
607 }
608
609 static void DumpCstringSection(MachOObjectFile *O, const char *sect,
610                                uint32_t sect_size, uint64_t sect_addr,
611                                bool print_addresses) {
612   for (uint32_t i = 0; i < sect_size; i++) {
613     if (print_addresses) {
614       if (O->is64Bit())
615         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
616       else
617         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
618     }
619     for (; i < sect_size && sect[i] != '\0'; i++)
620       DumpCstringChar(sect[i]);
621     if (i < sect_size && sect[i] == '\0')
622       outs() << "\n";
623   }
624 }
625
626 static void DumpLiteral4(uint32_t l, float f) {
627   outs() << format("0x%08" PRIx32, l);
628   if ((l & 0x7f800000) != 0x7f800000)
629     outs() << format(" (%.16e)\n", f);
630   else {
631     if (l == 0x7f800000)
632       outs() << " (+Infinity)\n";
633     else if (l == 0xff800000)
634       outs() << " (-Infinity)\n";
635     else if ((l & 0x00400000) == 0x00400000)
636       outs() << " (non-signaling Not-a-Number)\n";
637     else
638       outs() << " (signaling Not-a-Number)\n";
639   }
640 }
641
642 static void DumpLiteral4Section(MachOObjectFile *O, const char *sect,
643                                 uint32_t sect_size, uint64_t sect_addr,
644                                 bool print_addresses) {
645   for (uint32_t i = 0; i < sect_size; i += sizeof(float)) {
646     if (print_addresses) {
647       if (O->is64Bit())
648         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
649       else
650         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
651     }
652     float f;
653     memcpy(&f, sect + i, sizeof(float));
654     if (O->isLittleEndian() != sys::IsLittleEndianHost)
655       sys::swapByteOrder(f);
656     uint32_t l;
657     memcpy(&l, sect + i, sizeof(uint32_t));
658     if (O->isLittleEndian() != sys::IsLittleEndianHost)
659       sys::swapByteOrder(l);
660     DumpLiteral4(l, f);
661   }
662 }
663
664 static void DumpLiteral8(MachOObjectFile *O, uint32_t l0, uint32_t l1,
665                          double d) {
666   outs() << format("0x%08" PRIx32, l0) << " " << format("0x%08" PRIx32, l1);
667   uint32_t Hi, Lo;
668   if (O->isLittleEndian()) {
669     Hi = l1;
670     Lo = l0;
671   } else {
672     Hi = l0;
673     Lo = l1;
674   }
675   // Hi is the high word, so this is equivalent to if(isfinite(d))
676   if ((Hi & 0x7ff00000) != 0x7ff00000)
677     outs() << format(" (%.16e)\n", d);
678   else {
679     if (Hi == 0x7ff00000 && Lo == 0)
680       outs() << " (+Infinity)\n";
681     else if (Hi == 0xfff00000 && Lo == 0)
682       outs() << " (-Infinity)\n";
683     else if ((Hi & 0x00080000) == 0x00080000)
684       outs() << " (non-signaling Not-a-Number)\n";
685     else
686       outs() << " (signaling Not-a-Number)\n";
687   }
688 }
689
690 static void DumpLiteral8Section(MachOObjectFile *O, const char *sect,
691                                 uint32_t sect_size, uint64_t sect_addr,
692                                 bool print_addresses) {
693   for (uint32_t i = 0; i < sect_size; i += sizeof(double)) {
694     if (print_addresses) {
695       if (O->is64Bit())
696         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
697       else
698         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
699     }
700     double d;
701     memcpy(&d, sect + i, sizeof(double));
702     if (O->isLittleEndian() != sys::IsLittleEndianHost)
703       sys::swapByteOrder(d);
704     uint32_t l0, l1;
705     memcpy(&l0, sect + i, sizeof(uint32_t));
706     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
707     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
708       sys::swapByteOrder(l0);
709       sys::swapByteOrder(l1);
710     }
711     DumpLiteral8(O, l0, l1, d);
712   }
713 }
714
715 static void DumpLiteral16(uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3) {
716   outs() << format("0x%08" PRIx32, l0) << " ";
717   outs() << format("0x%08" PRIx32, l1) << " ";
718   outs() << format("0x%08" PRIx32, l2) << " ";
719   outs() << format("0x%08" PRIx32, l3) << "\n";
720 }
721
722 static void DumpLiteral16Section(MachOObjectFile *O, const char *sect,
723                                  uint32_t sect_size, uint64_t sect_addr,
724                                  bool print_addresses) {
725   for (uint32_t i = 0; i < sect_size; i += 16) {
726     if (print_addresses) {
727       if (O->is64Bit())
728         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
729       else
730         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
731     }
732     uint32_t l0, l1, l2, l3;
733     memcpy(&l0, sect + i, sizeof(uint32_t));
734     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
735     memcpy(&l2, sect + i + 2 * sizeof(uint32_t), sizeof(uint32_t));
736     memcpy(&l3, sect + i + 3 * sizeof(uint32_t), sizeof(uint32_t));
737     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
738       sys::swapByteOrder(l0);
739       sys::swapByteOrder(l1);
740       sys::swapByteOrder(l2);
741       sys::swapByteOrder(l3);
742     }
743     DumpLiteral16(l0, l1, l2, l3);
744   }
745 }
746
747 static void DumpLiteralPointerSection(MachOObjectFile *O,
748                                       const SectionRef &Section,
749                                       const char *sect, uint32_t sect_size,
750                                       uint64_t sect_addr,
751                                       bool print_addresses) {
752   // Collect the literal sections in this Mach-O file.
753   std::vector<SectionRef> LiteralSections;
754   for (const SectionRef &Section : O->sections()) {
755     DataRefImpl Ref = Section.getRawDataRefImpl();
756     uint32_t section_type;
757     if (O->is64Bit()) {
758       const MachO::section_64 Sec = O->getSection64(Ref);
759       section_type = Sec.flags & MachO::SECTION_TYPE;
760     } else {
761       const MachO::section Sec = O->getSection(Ref);
762       section_type = Sec.flags & MachO::SECTION_TYPE;
763     }
764     if (section_type == MachO::S_CSTRING_LITERALS ||
765         section_type == MachO::S_4BYTE_LITERALS ||
766         section_type == MachO::S_8BYTE_LITERALS ||
767         section_type == MachO::S_16BYTE_LITERALS)
768       LiteralSections.push_back(Section);
769   }
770
771   // Set the size of the literal pointer.
772   uint32_t lp_size = O->is64Bit() ? 8 : 4;
773
774   // Collect the external relocation symbols for the literal pointers.
775   std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
776   for (const RelocationRef &Reloc : Section.relocations()) {
777     DataRefImpl Rel;
778     MachO::any_relocation_info RE;
779     bool isExtern = false;
780     Rel = Reloc.getRawDataRefImpl();
781     RE = O->getRelocation(Rel);
782     isExtern = O->getPlainRelocationExternal(RE);
783     if (isExtern) {
784       uint64_t RelocOffset = Reloc.getOffset();
785       symbol_iterator RelocSym = Reloc.getSymbol();
786       Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
787     }
788   }
789   array_pod_sort(Relocs.begin(), Relocs.end());
790
791   // Dump each literal pointer.
792   for (uint32_t i = 0; i < sect_size; i += lp_size) {
793     if (print_addresses) {
794       if (O->is64Bit())
795         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
796       else
797         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
798     }
799     uint64_t lp;
800     if (O->is64Bit()) {
801       memcpy(&lp, sect + i, sizeof(uint64_t));
802       if (O->isLittleEndian() != sys::IsLittleEndianHost)
803         sys::swapByteOrder(lp);
804     } else {
805       uint32_t li;
806       memcpy(&li, sect + i, sizeof(uint32_t));
807       if (O->isLittleEndian() != sys::IsLittleEndianHost)
808         sys::swapByteOrder(li);
809       lp = li;
810     }
811
812     // First look for an external relocation entry for this literal pointer.
813     auto Reloc = std::find_if(
814         Relocs.begin(), Relocs.end(),
815         [&](const std::pair<uint64_t, SymbolRef> &P) { return P.first == i; });
816     if (Reloc != Relocs.end()) {
817       symbol_iterator RelocSym = Reloc->second;
818       ErrorOr<StringRef> SymName = RelocSym->getName();
819       if (std::error_code EC = SymName.getError())
820         report_fatal_error(EC.message());
821       outs() << "external relocation entry for symbol:" << *SymName << "\n";
822       continue;
823     }
824
825     // For local references see what the section the literal pointer points to.
826     auto Sect = std::find_if(LiteralSections.begin(), LiteralSections.end(),
827                              [&](const SectionRef &R) {
828                                return lp >= R.getAddress() &&
829                                       lp < R.getAddress() + R.getSize();
830                              });
831     if (Sect == LiteralSections.end()) {
832       outs() << format("0x%" PRIx64, lp) << " (not in a literal section)\n";
833       continue;
834     }
835
836     uint64_t SectAddress = Sect->getAddress();
837     uint64_t SectSize = Sect->getSize();
838
839     StringRef SectName;
840     Sect->getName(SectName);
841     DataRefImpl Ref = Sect->getRawDataRefImpl();
842     StringRef SegmentName = O->getSectionFinalSegmentName(Ref);
843     outs() << SegmentName << ":" << SectName << ":";
844
845     uint32_t section_type;
846     if (O->is64Bit()) {
847       const MachO::section_64 Sec = O->getSection64(Ref);
848       section_type = Sec.flags & MachO::SECTION_TYPE;
849     } else {
850       const MachO::section Sec = O->getSection(Ref);
851       section_type = Sec.flags & MachO::SECTION_TYPE;
852     }
853
854     StringRef BytesStr;
855     Sect->getContents(BytesStr);
856     const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
857
858     switch (section_type) {
859     case MachO::S_CSTRING_LITERALS:
860       for (uint64_t i = lp - SectAddress; i < SectSize && Contents[i] != '\0';
861            i++) {
862         DumpCstringChar(Contents[i]);
863       }
864       outs() << "\n";
865       break;
866     case MachO::S_4BYTE_LITERALS:
867       float f;
868       memcpy(&f, Contents + (lp - SectAddress), sizeof(float));
869       uint32_t l;
870       memcpy(&l, Contents + (lp - SectAddress), sizeof(uint32_t));
871       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
872         sys::swapByteOrder(f);
873         sys::swapByteOrder(l);
874       }
875       DumpLiteral4(l, f);
876       break;
877     case MachO::S_8BYTE_LITERALS: {
878       double d;
879       memcpy(&d, Contents + (lp - SectAddress), sizeof(double));
880       uint32_t l0, l1;
881       memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
882       memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
883              sizeof(uint32_t));
884       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
885         sys::swapByteOrder(f);
886         sys::swapByteOrder(l0);
887         sys::swapByteOrder(l1);
888       }
889       DumpLiteral8(O, l0, l1, d);
890       break;
891     }
892     case MachO::S_16BYTE_LITERALS: {
893       uint32_t l0, l1, l2, l3;
894       memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
895       memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
896              sizeof(uint32_t));
897       memcpy(&l2, Contents + (lp - SectAddress) + 2 * sizeof(uint32_t),
898              sizeof(uint32_t));
899       memcpy(&l3, Contents + (lp - SectAddress) + 3 * sizeof(uint32_t),
900              sizeof(uint32_t));
901       if (O->isLittleEndian() != sys::IsLittleEndianHost) {
902         sys::swapByteOrder(l0);
903         sys::swapByteOrder(l1);
904         sys::swapByteOrder(l2);
905         sys::swapByteOrder(l3);
906       }
907       DumpLiteral16(l0, l1, l2, l3);
908       break;
909     }
910     }
911   }
912 }
913
914 static void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect,
915                                        uint32_t sect_size, uint64_t sect_addr,
916                                        SymbolAddressMap *AddrMap,
917                                        bool verbose) {
918   uint32_t stride;
919   if (O->is64Bit())
920     stride = sizeof(uint64_t);
921   else
922     stride = sizeof(uint32_t);
923   for (uint32_t i = 0; i < sect_size; i += stride) {
924     const char *SymbolName = nullptr;
925     if (O->is64Bit()) {
926       outs() << format("0x%016" PRIx64, sect_addr + i * stride) << " ";
927       uint64_t pointer_value;
928       memcpy(&pointer_value, sect + i, stride);
929       if (O->isLittleEndian() != sys::IsLittleEndianHost)
930         sys::swapByteOrder(pointer_value);
931       outs() << format("0x%016" PRIx64, pointer_value);
932       if (verbose)
933         SymbolName = GuessSymbolName(pointer_value, AddrMap);
934     } else {
935       outs() << format("0x%08" PRIx64, sect_addr + i * stride) << " ";
936       uint32_t pointer_value;
937       memcpy(&pointer_value, sect + i, stride);
938       if (O->isLittleEndian() != sys::IsLittleEndianHost)
939         sys::swapByteOrder(pointer_value);
940       outs() << format("0x%08" PRIx32, pointer_value);
941       if (verbose)
942         SymbolName = GuessSymbolName(pointer_value, AddrMap);
943     }
944     if (SymbolName)
945       outs() << " " << SymbolName;
946     outs() << "\n";
947   }
948 }
949
950 static void DumpRawSectionContents(MachOObjectFile *O, const char *sect,
951                                    uint32_t size, uint64_t addr) {
952   uint32_t cputype = O->getHeader().cputype;
953   if (cputype == MachO::CPU_TYPE_I386 || cputype == MachO::CPU_TYPE_X86_64) {
954     uint32_t j;
955     for (uint32_t i = 0; i < size; i += j, addr += j) {
956       if (O->is64Bit())
957         outs() << format("%016" PRIx64, addr) << "\t";
958       else
959         outs() << format("%08" PRIx64, addr) << "\t";
960       for (j = 0; j < 16 && i + j < size; j++) {
961         uint8_t byte_word = *(sect + i + j);
962         outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
963       }
964       outs() << "\n";
965     }
966   } else {
967     uint32_t j;
968     for (uint32_t i = 0; i < size; i += j, addr += j) {
969       if (O->is64Bit())
970         outs() << format("%016" PRIx64, addr) << "\t";
971       else
972         outs() << format("%08" PRIx64, sect) << "\t";
973       for (j = 0; j < 4 * sizeof(int32_t) && i + j < size;
974            j += sizeof(int32_t)) {
975         if (i + j + sizeof(int32_t) < size) {
976           uint32_t long_word;
977           memcpy(&long_word, sect + i + j, sizeof(int32_t));
978           if (O->isLittleEndian() != sys::IsLittleEndianHost)
979             sys::swapByteOrder(long_word);
980           outs() << format("%08" PRIx32, long_word) << " ";
981         } else {
982           for (uint32_t k = 0; i + j + k < size; k++) {
983             uint8_t byte_word = *(sect + i + j);
984             outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
985           }
986         }
987       }
988       outs() << "\n";
989     }
990   }
991 }
992
993 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
994                              StringRef DisSegName, StringRef DisSectName);
995 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,
996                                 uint32_t size, uint32_t addr);
997
998 static void DumpSectionContents(StringRef Filename, MachOObjectFile *O,
999                                 bool verbose) {
1000   SymbolAddressMap AddrMap;
1001   if (verbose)
1002     CreateSymbolAddressMap(O, &AddrMap);
1003
1004   for (unsigned i = 0; i < FilterSections.size(); ++i) {
1005     StringRef DumpSection = FilterSections[i];
1006     std::pair<StringRef, StringRef> DumpSegSectName;
1007     DumpSegSectName = DumpSection.split(',');
1008     StringRef DumpSegName, DumpSectName;
1009     if (DumpSegSectName.second.size()) {
1010       DumpSegName = DumpSegSectName.first;
1011       DumpSectName = DumpSegSectName.second;
1012     } else {
1013       DumpSegName = "";
1014       DumpSectName = DumpSegSectName.first;
1015     }
1016     for (const SectionRef &Section : O->sections()) {
1017       StringRef SectName;
1018       Section.getName(SectName);
1019       DataRefImpl Ref = Section.getRawDataRefImpl();
1020       StringRef SegName = O->getSectionFinalSegmentName(Ref);
1021       if ((DumpSegName.empty() || SegName == DumpSegName) &&
1022           (SectName == DumpSectName)) {
1023
1024         uint32_t section_flags;
1025         if (O->is64Bit()) {
1026           const MachO::section_64 Sec = O->getSection64(Ref);
1027           section_flags = Sec.flags;
1028
1029         } else {
1030           const MachO::section Sec = O->getSection(Ref);
1031           section_flags = Sec.flags;
1032         }
1033         uint32_t section_type = section_flags & MachO::SECTION_TYPE;
1034
1035         StringRef BytesStr;
1036         Section.getContents(BytesStr);
1037         const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1038         uint32_t sect_size = BytesStr.size();
1039         uint64_t sect_addr = Section.getAddress();
1040
1041         outs() << "Contents of (" << SegName << "," << SectName
1042                << ") section\n";
1043
1044         if (verbose) {
1045           if ((section_flags & MachO::S_ATTR_PURE_INSTRUCTIONS) ||
1046               (section_flags & MachO::S_ATTR_SOME_INSTRUCTIONS)) {
1047             DisassembleMachO(Filename, O, SegName, SectName);
1048             continue;
1049           }
1050           if (SegName == "__TEXT" && SectName == "__info_plist") {
1051             outs() << sect;
1052             continue;
1053           }
1054           if (SegName == "__OBJC" && SectName == "__protocol") {
1055             DumpProtocolSection(O, sect, sect_size, sect_addr);
1056             continue;
1057           }
1058           switch (section_type) {
1059           case MachO::S_REGULAR:
1060             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1061             break;
1062           case MachO::S_ZEROFILL:
1063             outs() << "zerofill section and has no contents in the file\n";
1064             break;
1065           case MachO::S_CSTRING_LITERALS:
1066             DumpCstringSection(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1067             break;
1068           case MachO::S_4BYTE_LITERALS:
1069             DumpLiteral4Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1070             break;
1071           case MachO::S_8BYTE_LITERALS:
1072             DumpLiteral8Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1073             break;
1074           case MachO::S_16BYTE_LITERALS:
1075             DumpLiteral16Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1076             break;
1077           case MachO::S_LITERAL_POINTERS:
1078             DumpLiteralPointerSection(O, Section, sect, sect_size, sect_addr,
1079                                       !NoLeadingAddr);
1080             break;
1081           case MachO::S_MOD_INIT_FUNC_POINTERS:
1082           case MachO::S_MOD_TERM_FUNC_POINTERS:
1083             DumpInitTermPointerSection(O, sect, sect_size, sect_addr, &AddrMap,
1084                                        verbose);
1085             break;
1086           default:
1087             outs() << "Unknown section type ("
1088                    << format("0x%08" PRIx32, section_type) << ")\n";
1089             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1090             break;
1091           }
1092         } else {
1093           if (section_type == MachO::S_ZEROFILL)
1094             outs() << "zerofill section and has no contents in the file\n";
1095           else
1096             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1097         }
1098       }
1099     }
1100   }
1101 }
1102
1103 static void DumpInfoPlistSectionContents(StringRef Filename,
1104                                          MachOObjectFile *O) {
1105   for (const SectionRef &Section : O->sections()) {
1106     StringRef SectName;
1107     Section.getName(SectName);
1108     DataRefImpl Ref = Section.getRawDataRefImpl();
1109     StringRef SegName = O->getSectionFinalSegmentName(Ref);
1110     if (SegName == "__TEXT" && SectName == "__info_plist") {
1111       outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
1112       StringRef BytesStr;
1113       Section.getContents(BytesStr);
1114       const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1115       outs() << sect;
1116       return;
1117     }
1118   }
1119 }
1120
1121 // checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file
1122 // and if it is and there is a list of architecture flags is specified then
1123 // check to make sure this Mach-O file is one of those architectures or all
1124 // architectures were specified.  If not then an error is generated and this
1125 // routine returns false.  Else it returns true.
1126 static bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) {
1127   if (isa<MachOObjectFile>(O) && !ArchAll && ArchFlags.size() != 0) {
1128     MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O);
1129     bool ArchFound = false;
1130     MachO::mach_header H;
1131     MachO::mach_header_64 H_64;
1132     Triple T;
1133     if (MachO->is64Bit()) {
1134       H_64 = MachO->MachOObjectFile::getHeader64();
1135       T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype);
1136     } else {
1137       H = MachO->MachOObjectFile::getHeader();
1138       T = MachOObjectFile::getArch(H.cputype, H.cpusubtype);
1139     }
1140     unsigned i;
1141     for (i = 0; i < ArchFlags.size(); ++i) {
1142       if (ArchFlags[i] == T.getArchName())
1143         ArchFound = true;
1144       break;
1145     }
1146     if (!ArchFound) {
1147       errs() << "llvm-objdump: file: " + Filename + " does not contain "
1148              << "architecture: " + ArchFlags[i] + "\n";
1149       return false;
1150     }
1151   }
1152   return true;
1153 }
1154
1155 static void printObjcMetaData(MachOObjectFile *O, bool verbose);
1156
1157 // ProcessMachO() is passed a single opened Mach-O file, which may be an
1158 // archive member and or in a slice of a universal file.  It prints the
1159 // the file name and header info and then processes it according to the
1160 // command line options.
1161 static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF,
1162                          StringRef ArchiveMemberName = StringRef(),
1163                          StringRef ArchitectureName = StringRef()) {
1164   // If we are doing some processing here on the Mach-O file print the header
1165   // info.  And don't print it otherwise like in the case of printing the
1166   // UniversalHeaders or ArchiveHeaders.
1167   if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind ||
1168       LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints ||
1169       DylibsUsed || DylibId || ObjcMetaData || (FilterSections.size() != 0)) {
1170     outs() << Filename;
1171     if (!ArchiveMemberName.empty())
1172       outs() << '(' << ArchiveMemberName << ')';
1173     if (!ArchitectureName.empty())
1174       outs() << " (architecture " << ArchitectureName << ")";
1175     outs() << ":\n";
1176   }
1177
1178   if (Disassemble)
1179     DisassembleMachO(Filename, MachOOF, "__TEXT", "__text");
1180   if (IndirectSymbols)
1181     PrintIndirectSymbols(MachOOF, !NonVerbose);
1182   if (DataInCode)
1183     PrintDataInCodeTable(MachOOF, !NonVerbose);
1184   if (LinkOptHints)
1185     PrintLinkOptHints(MachOOF);
1186   if (Relocations)
1187     PrintRelocations(MachOOF);
1188   if (SectionHeaders)
1189     PrintSectionHeaders(MachOOF);
1190   if (SectionContents)
1191     PrintSectionContents(MachOOF);
1192   if (FilterSections.size() != 0)
1193     DumpSectionContents(Filename, MachOOF, !NonVerbose);
1194   if (InfoPlist)
1195     DumpInfoPlistSectionContents(Filename, MachOOF);
1196   if (DylibsUsed)
1197     PrintDylibs(MachOOF, false);
1198   if (DylibId)
1199     PrintDylibs(MachOOF, true);
1200   if (SymbolTable)
1201     PrintSymbolTable(MachOOF);
1202   if (UnwindInfo)
1203     printMachOUnwindInfo(MachOOF);
1204   if (PrivateHeaders)
1205     printMachOFileHeader(MachOOF);
1206   if (ObjcMetaData)
1207     printObjcMetaData(MachOOF, !NonVerbose);
1208   if (ExportsTrie)
1209     printExportsTrie(MachOOF);
1210   if (Rebase)
1211     printRebaseTable(MachOOF);
1212   if (Bind)
1213     printBindTable(MachOOF);
1214   if (LazyBind)
1215     printLazyBindTable(MachOOF);
1216   if (WeakBind)
1217     printWeakBindTable(MachOOF);
1218 }
1219
1220 // printUnknownCPUType() helps print_fat_headers for unknown CPU's.
1221 static void printUnknownCPUType(uint32_t cputype, uint32_t cpusubtype) {
1222   outs() << "    cputype (" << cputype << ")\n";
1223   outs() << "    cpusubtype (" << cpusubtype << ")\n";
1224 }
1225
1226 // printCPUType() helps print_fat_headers by printing the cputype and
1227 // pusubtype (symbolically for the one's it knows about).
1228 static void printCPUType(uint32_t cputype, uint32_t cpusubtype) {
1229   switch (cputype) {
1230   case MachO::CPU_TYPE_I386:
1231     switch (cpusubtype) {
1232     case MachO::CPU_SUBTYPE_I386_ALL:
1233       outs() << "    cputype CPU_TYPE_I386\n";
1234       outs() << "    cpusubtype CPU_SUBTYPE_I386_ALL\n";
1235       break;
1236     default:
1237       printUnknownCPUType(cputype, cpusubtype);
1238       break;
1239     }
1240     break;
1241   case MachO::CPU_TYPE_X86_64:
1242     switch (cpusubtype) {
1243     case MachO::CPU_SUBTYPE_X86_64_ALL:
1244       outs() << "    cputype CPU_TYPE_X86_64\n";
1245       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_ALL\n";
1246       break;
1247     case MachO::CPU_SUBTYPE_X86_64_H:
1248       outs() << "    cputype CPU_TYPE_X86_64\n";
1249       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_H\n";
1250       break;
1251     default:
1252       printUnknownCPUType(cputype, cpusubtype);
1253       break;
1254     }
1255     break;
1256   case MachO::CPU_TYPE_ARM:
1257     switch (cpusubtype) {
1258     case MachO::CPU_SUBTYPE_ARM_ALL:
1259       outs() << "    cputype CPU_TYPE_ARM\n";
1260       outs() << "    cpusubtype CPU_SUBTYPE_ARM_ALL\n";
1261       break;
1262     case MachO::CPU_SUBTYPE_ARM_V4T:
1263       outs() << "    cputype CPU_TYPE_ARM\n";
1264       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V4T\n";
1265       break;
1266     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1267       outs() << "    cputype CPU_TYPE_ARM\n";
1268       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n";
1269       break;
1270     case MachO::CPU_SUBTYPE_ARM_XSCALE:
1271       outs() << "    cputype CPU_TYPE_ARM\n";
1272       outs() << "    cpusubtype CPU_SUBTYPE_ARM_XSCALE\n";
1273       break;
1274     case MachO::CPU_SUBTYPE_ARM_V6:
1275       outs() << "    cputype CPU_TYPE_ARM\n";
1276       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6\n";
1277       break;
1278     case MachO::CPU_SUBTYPE_ARM_V6M:
1279       outs() << "    cputype CPU_TYPE_ARM\n";
1280       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6M\n";
1281       break;
1282     case MachO::CPU_SUBTYPE_ARM_V7:
1283       outs() << "    cputype CPU_TYPE_ARM\n";
1284       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7\n";
1285       break;
1286     case MachO::CPU_SUBTYPE_ARM_V7EM:
1287       outs() << "    cputype CPU_TYPE_ARM\n";
1288       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7EM\n";
1289       break;
1290     case MachO::CPU_SUBTYPE_ARM_V7K:
1291       outs() << "    cputype CPU_TYPE_ARM\n";
1292       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7K\n";
1293       break;
1294     case MachO::CPU_SUBTYPE_ARM_V7M:
1295       outs() << "    cputype CPU_TYPE_ARM\n";
1296       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7M\n";
1297       break;
1298     case MachO::CPU_SUBTYPE_ARM_V7S:
1299       outs() << "    cputype CPU_TYPE_ARM\n";
1300       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7S\n";
1301       break;
1302     default:
1303       printUnknownCPUType(cputype, cpusubtype);
1304       break;
1305     }
1306     break;
1307   case MachO::CPU_TYPE_ARM64:
1308     switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
1309     case MachO::CPU_SUBTYPE_ARM64_ALL:
1310       outs() << "    cputype CPU_TYPE_ARM64\n";
1311       outs() << "    cpusubtype CPU_SUBTYPE_ARM64_ALL\n";
1312       break;
1313     default:
1314       printUnknownCPUType(cputype, cpusubtype);
1315       break;
1316     }
1317     break;
1318   default:
1319     printUnknownCPUType(cputype, cpusubtype);
1320     break;
1321   }
1322 }
1323
1324 static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB,
1325                                        bool verbose) {
1326   outs() << "Fat headers\n";
1327   if (verbose)
1328     outs() << "fat_magic FAT_MAGIC\n";
1329   else
1330     outs() << "fat_magic " << format("0x%" PRIx32, MachO::FAT_MAGIC) << "\n";
1331
1332   uint32_t nfat_arch = UB->getNumberOfObjects();
1333   StringRef Buf = UB->getData();
1334   uint64_t size = Buf.size();
1335   uint64_t big_size = sizeof(struct MachO::fat_header) +
1336                       nfat_arch * sizeof(struct MachO::fat_arch);
1337   outs() << "nfat_arch " << UB->getNumberOfObjects();
1338   if (nfat_arch == 0)
1339     outs() << " (malformed, contains zero architecture types)\n";
1340   else if (big_size > size)
1341     outs() << " (malformed, architectures past end of file)\n";
1342   else
1343     outs() << "\n";
1344
1345   for (uint32_t i = 0; i < nfat_arch; ++i) {
1346     MachOUniversalBinary::ObjectForArch OFA(UB, i);
1347     uint32_t cputype = OFA.getCPUType();
1348     uint32_t cpusubtype = OFA.getCPUSubType();
1349     outs() << "architecture ";
1350     for (uint32_t j = 0; i != 0 && j <= i - 1; j++) {
1351       MachOUniversalBinary::ObjectForArch other_OFA(UB, j);
1352       uint32_t other_cputype = other_OFA.getCPUType();
1353       uint32_t other_cpusubtype = other_OFA.getCPUSubType();
1354       if (cputype != 0 && cpusubtype != 0 && cputype == other_cputype &&
1355           (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) ==
1356               (other_cpusubtype & ~MachO::CPU_SUBTYPE_MASK)) {
1357         outs() << "(illegal duplicate architecture) ";
1358         break;
1359       }
1360     }
1361     if (verbose) {
1362       outs() << OFA.getArchTypeName() << "\n";
1363       printCPUType(cputype, cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
1364     } else {
1365       outs() << i << "\n";
1366       outs() << "    cputype " << cputype << "\n";
1367       outs() << "    cpusubtype " << (cpusubtype & ~MachO::CPU_SUBTYPE_MASK)
1368              << "\n";
1369     }
1370     if (verbose &&
1371         (cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64)
1372       outs() << "    capabilities CPU_SUBTYPE_LIB64\n";
1373     else
1374       outs() << "    capabilities "
1375              << format("0x%" PRIx32,
1376                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24) << "\n";
1377     outs() << "    offset " << OFA.getOffset();
1378     if (OFA.getOffset() > size)
1379       outs() << " (past end of file)";
1380     if (OFA.getOffset() % (1 << OFA.getAlign()) != 0)
1381       outs() << " (not aligned on it's alignment (2^" << OFA.getAlign() << ")";
1382     outs() << "\n";
1383     outs() << "    size " << OFA.getSize();
1384     big_size = OFA.getOffset() + OFA.getSize();
1385     if (big_size > size)
1386       outs() << " (past end of file)";
1387     outs() << "\n";
1388     outs() << "    align 2^" << OFA.getAlign() << " (" << (1 << OFA.getAlign())
1389            << ")\n";
1390   }
1391 }
1392
1393 static void printArchiveChild(Archive::Child &C, bool verbose,
1394                               bool print_offset) {
1395   if (print_offset)
1396     outs() << C.getChildOffset() << "\t";
1397   sys::fs::perms Mode = C.getAccessMode();
1398   if (verbose) {
1399     // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
1400     // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
1401     outs() << "-";
1402     outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
1403     outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
1404     outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
1405     outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
1406     outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
1407     outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
1408     outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
1409     outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
1410     outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
1411   } else {
1412     outs() << format("0%o ", Mode);
1413   }
1414
1415   unsigned UID = C.getUID();
1416   outs() << format("%3d/", UID);
1417   unsigned GID = C.getGID();
1418   outs() << format("%-3d ", GID);
1419   uint64_t Size = C.getRawSize();
1420   outs() << format("%5" PRId64, Size) << " ";
1421
1422   StringRef RawLastModified = C.getRawLastModified();
1423   if (verbose) {
1424     unsigned Seconds;
1425     if (RawLastModified.getAsInteger(10, Seconds))
1426       outs() << "(date: \"%s\" contains non-decimal chars) " << RawLastModified;
1427     else {
1428       // Since cime(3) returns a 26 character string of the form:
1429       // "Sun Sep 16 01:03:52 1973\n\0"
1430       // just print 24 characters.
1431       time_t t = Seconds;
1432       outs() << format("%.24s ", ctime(&t));
1433     }
1434   } else {
1435     outs() << RawLastModified << " ";
1436   }
1437
1438   if (verbose) {
1439     ErrorOr<StringRef> NameOrErr = C.getName();
1440     if (NameOrErr.getError()) {
1441       StringRef RawName = C.getRawName();
1442       outs() << RawName << "\n";
1443     } else {
1444       StringRef Name = NameOrErr.get();
1445       outs() << Name << "\n";
1446     }
1447   } else {
1448     StringRef RawName = C.getRawName();
1449     outs() << RawName << "\n";
1450   }
1451 }
1452
1453 static void printArchiveHeaders(Archive *A, bool verbose, bool print_offset) {
1454   if (A->hasSymbolTable()) {
1455     Archive::child_iterator S = A->getSymbolTableChild();
1456     Archive::Child C = *S;
1457     printArchiveChild(C, verbose, print_offset);
1458   }
1459   for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E;
1460        ++I) {
1461     Archive::Child C = *I;
1462     printArchiveChild(C, verbose, print_offset);
1463   }
1464 }
1465
1466 // ParseInputMachO() parses the named Mach-O file in Filename and handles the
1467 // -arch flags selecting just those slices as specified by them and also parses
1468 // archive files.  Then for each individual Mach-O file ProcessMachO() is
1469 // called to process the file based on the command line options.
1470 void llvm::ParseInputMachO(StringRef Filename) {
1471   // Check for -arch all and verifiy the -arch flags are valid.
1472   for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1473     if (ArchFlags[i] == "all") {
1474       ArchAll = true;
1475     } else {
1476       if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
1477         errs() << "llvm-objdump: Unknown architecture named '" + ArchFlags[i] +
1478                       "'for the -arch option\n";
1479         return;
1480       }
1481     }
1482   }
1483
1484   // Attempt to open the binary.
1485   ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
1486   if (std::error_code EC = BinaryOrErr.getError()) {
1487     errs() << "llvm-objdump: '" << Filename << "': " << EC.message() << ".\n";
1488     return;
1489   }
1490   Binary &Bin = *BinaryOrErr.get().getBinary();
1491
1492   if (Archive *A = dyn_cast<Archive>(&Bin)) {
1493     outs() << "Archive : " << Filename << "\n";
1494     if (ArchiveHeaders)
1495       printArchiveHeaders(A, !NonVerbose, ArchiveMemberOffsets);
1496     for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
1497          I != E; ++I) {
1498       ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary();
1499       if (ChildOrErr.getError())
1500         continue;
1501       if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1502         if (!checkMachOAndArchFlags(O, Filename))
1503           return;
1504         ProcessMachO(Filename, O, O->getFileName());
1505       }
1506     }
1507     return;
1508   }
1509   if (UniversalHeaders) {
1510     if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin))
1511       printMachOUniversalHeaders(UB, !NonVerbose);
1512   }
1513   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
1514     // If we have a list of architecture flags specified dump only those.
1515     if (!ArchAll && ArchFlags.size() != 0) {
1516       // Look for a slice in the universal binary that matches each ArchFlag.
1517       bool ArchFound;
1518       for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1519         ArchFound = false;
1520         for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1521                                                    E = UB->end_objects();
1522              I != E; ++I) {
1523           if (ArchFlags[i] == I->getArchTypeName()) {
1524             ArchFound = true;
1525             ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
1526                 I->getAsObjectFile();
1527             std::string ArchitectureName = "";
1528             if (ArchFlags.size() > 1)
1529               ArchitectureName = I->getArchTypeName();
1530             if (ObjOrErr) {
1531               ObjectFile &O = *ObjOrErr.get();
1532               if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1533                 ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1534             } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
1535                            I->getAsArchive()) {
1536               std::unique_ptr<Archive> &A = *AOrErr;
1537               outs() << "Archive : " << Filename;
1538               if (!ArchitectureName.empty())
1539                 outs() << " (architecture " << ArchitectureName << ")";
1540               outs() << "\n";
1541               if (ArchiveHeaders)
1542                 printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
1543               for (Archive::child_iterator AI = A->child_begin(),
1544                                            AE = A->child_end();
1545                    AI != AE; ++AI) {
1546                 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
1547                 if (ChildOrErr.getError())
1548                   continue;
1549                 if (MachOObjectFile *O =
1550                         dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1551                   ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
1552               }
1553             }
1554           }
1555         }
1556         if (!ArchFound) {
1557           errs() << "llvm-objdump: file: " + Filename + " does not contain "
1558                  << "architecture: " + ArchFlags[i] + "\n";
1559           return;
1560         }
1561       }
1562       return;
1563     }
1564     // No architecture flags were specified so if this contains a slice that
1565     // matches the host architecture dump only that.
1566     if (!ArchAll) {
1567       for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1568                                                  E = UB->end_objects();
1569            I != E; ++I) {
1570         if (MachOObjectFile::getHostArch().getArchName() ==
1571             I->getArchTypeName()) {
1572           ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1573           std::string ArchiveName;
1574           ArchiveName.clear();
1575           if (ObjOrErr) {
1576             ObjectFile &O = *ObjOrErr.get();
1577             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1578               ProcessMachO(Filename, MachOOF);
1579           } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
1580                          I->getAsArchive()) {
1581             std::unique_ptr<Archive> &A = *AOrErr;
1582             outs() << "Archive : " << Filename << "\n";
1583             if (ArchiveHeaders)
1584               printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
1585             for (Archive::child_iterator AI = A->child_begin(),
1586                                          AE = A->child_end();
1587                  AI != AE; ++AI) {
1588               ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
1589               if (ChildOrErr.getError())
1590                 continue;
1591               if (MachOObjectFile *O =
1592                       dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1593                 ProcessMachO(Filename, O, O->getFileName());
1594             }
1595           }
1596           return;
1597         }
1598       }
1599     }
1600     // Either all architectures have been specified or none have been specified
1601     // and this does not contain the host architecture so dump all the slices.
1602     bool moreThanOneArch = UB->getNumberOfObjects() > 1;
1603     for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1604                                                E = UB->end_objects();
1605          I != E; ++I) {
1606       ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1607       std::string ArchitectureName = "";
1608       if (moreThanOneArch)
1609         ArchitectureName = I->getArchTypeName();
1610       if (ObjOrErr) {
1611         ObjectFile &Obj = *ObjOrErr.get();
1612         if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
1613           ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1614       } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
1615         std::unique_ptr<Archive> &A = *AOrErr;
1616         outs() << "Archive : " << Filename;
1617         if (!ArchitectureName.empty())
1618           outs() << " (architecture " << ArchitectureName << ")";
1619         outs() << "\n";
1620         if (ArchiveHeaders)
1621           printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
1622         for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
1623              AI != AE; ++AI) {
1624           ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
1625           if (ChildOrErr.getError())
1626             continue;
1627           if (MachOObjectFile *O =
1628                   dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1629             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
1630               ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
1631                            ArchitectureName);
1632           }
1633         }
1634       }
1635     }
1636     return;
1637   }
1638   if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
1639     if (!checkMachOAndArchFlags(O, Filename))
1640       return;
1641     if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
1642       ProcessMachO(Filename, MachOOF);
1643     } else
1644       errs() << "llvm-objdump: '" << Filename << "': "
1645              << "Object is not a Mach-O file type.\n";
1646   } else
1647     errs() << "llvm-objdump: '" << Filename << "': "
1648            << "Unrecognized file type.\n";
1649 }
1650
1651 typedef std::pair<uint64_t, const char *> BindInfoEntry;
1652 typedef std::vector<BindInfoEntry> BindTable;
1653 typedef BindTable::iterator bind_table_iterator;
1654
1655 // The block of info used by the Symbolizer call backs.
1656 struct DisassembleInfo {
1657   bool verbose;
1658   MachOObjectFile *O;
1659   SectionRef S;
1660   SymbolAddressMap *AddrMap;
1661   std::vector<SectionRef> *Sections;
1662   const char *class_name;
1663   const char *selector_name;
1664   char *method;
1665   char *demangled_name;
1666   uint64_t adrp_addr;
1667   uint32_t adrp_inst;
1668   BindTable *bindtable;
1669 };
1670
1671 // SymbolizerGetOpInfo() is the operand information call back function.
1672 // This is called to get the symbolic information for operand(s) of an
1673 // instruction when it is being done.  This routine does this from
1674 // the relocation information, symbol table, etc. That block of information
1675 // is a pointer to the struct DisassembleInfo that was passed when the
1676 // disassembler context was created and passed to back to here when
1677 // called back by the disassembler for instruction operands that could have
1678 // relocation information. The address of the instruction containing operand is
1679 // at the Pc parameter.  The immediate value the operand has is passed in
1680 // op_info->Value and is at Offset past the start of the instruction and has a
1681 // byte Size of 1, 2 or 4. The symbolc information is returned in TagBuf is the
1682 // LLVMOpInfo1 struct defined in the header "llvm-c/Disassembler.h" as symbol
1683 // names and addends of the symbolic expression to add for the operand.  The
1684 // value of TagType is currently 1 (for the LLVMOpInfo1 struct). If symbolic
1685 // information is returned then this function returns 1 else it returns 0.
1686 static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
1687                                uint64_t Size, int TagType, void *TagBuf) {
1688   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
1689   struct LLVMOpInfo1 *op_info = (struct LLVMOpInfo1 *)TagBuf;
1690   uint64_t value = op_info->Value;
1691
1692   // Make sure all fields returned are zero if we don't set them.
1693   memset((void *)op_info, '\0', sizeof(struct LLVMOpInfo1));
1694   op_info->Value = value;
1695
1696   // If the TagType is not the value 1 which it code knows about or if no
1697   // verbose symbolic information is wanted then just return 0, indicating no
1698   // information is being returned.
1699   if (TagType != 1 || !info->verbose)
1700     return 0;
1701
1702   unsigned int Arch = info->O->getArch();
1703   if (Arch == Triple::x86) {
1704     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
1705       return 0;
1706     // First search the section's relocation entries (if any) for an entry
1707     // for this section offset.
1708     uint32_t sect_addr = info->S.getAddress();
1709     uint32_t sect_offset = (Pc + Offset) - sect_addr;
1710     bool reloc_found = false;
1711     DataRefImpl Rel;
1712     MachO::any_relocation_info RE;
1713     bool isExtern = false;
1714     SymbolRef Symbol;
1715     bool r_scattered = false;
1716     uint32_t r_value, pair_r_value, r_type;
1717     for (const RelocationRef &Reloc : info->S.relocations()) {
1718       uint64_t RelocOffset = Reloc.getOffset();
1719       if (RelocOffset == sect_offset) {
1720         Rel = Reloc.getRawDataRefImpl();
1721         RE = info->O->getRelocation(Rel);
1722         r_type = info->O->getAnyRelocationType(RE);
1723         r_scattered = info->O->isRelocationScattered(RE);
1724         if (r_scattered) {
1725           r_value = info->O->getScatteredRelocationValue(RE);
1726           if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
1727               r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
1728             DataRefImpl RelNext = Rel;
1729             info->O->moveRelocationNext(RelNext);
1730             MachO::any_relocation_info RENext;
1731             RENext = info->O->getRelocation(RelNext);
1732             if (info->O->isRelocationScattered(RENext))
1733               pair_r_value = info->O->getScatteredRelocationValue(RENext);
1734             else
1735               return 0;
1736           }
1737         } else {
1738           isExtern = info->O->getPlainRelocationExternal(RE);
1739           if (isExtern) {
1740             symbol_iterator RelocSym = Reloc.getSymbol();
1741             Symbol = *RelocSym;
1742           }
1743         }
1744         reloc_found = true;
1745         break;
1746       }
1747     }
1748     if (reloc_found && isExtern) {
1749       ErrorOr<StringRef> SymName = Symbol.getName();
1750       if (std::error_code EC = SymName.getError())
1751         report_fatal_error(EC.message());
1752       const char *name = SymName->data();
1753       op_info->AddSymbol.Present = 1;
1754       op_info->AddSymbol.Name = name;
1755       // For i386 extern relocation entries the value in the instruction is
1756       // the offset from the symbol, and value is already set in op_info->Value.
1757       return 1;
1758     }
1759     if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
1760                         r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
1761       const char *add = GuessSymbolName(r_value, info->AddrMap);
1762       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
1763       uint32_t offset = value - (r_value - pair_r_value);
1764       op_info->AddSymbol.Present = 1;
1765       if (add != nullptr)
1766         op_info->AddSymbol.Name = add;
1767       else
1768         op_info->AddSymbol.Value = r_value;
1769       op_info->SubtractSymbol.Present = 1;
1770       if (sub != nullptr)
1771         op_info->SubtractSymbol.Name = sub;
1772       else
1773         op_info->SubtractSymbol.Value = pair_r_value;
1774       op_info->Value = offset;
1775       return 1;
1776     }
1777     // TODO:
1778     // Second search the external relocation entries of a fully linked image
1779     // (if any) for an entry that matches this segment offset.
1780     // uint32_t seg_offset = (Pc + Offset);
1781     return 0;
1782   }
1783   if (Arch == Triple::x86_64) {
1784     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
1785       return 0;
1786     // First search the section's relocation entries (if any) for an entry
1787     // for this section offset.
1788     uint64_t sect_addr = info->S.getAddress();
1789     uint64_t sect_offset = (Pc + Offset) - sect_addr;
1790     bool reloc_found = false;
1791     DataRefImpl Rel;
1792     MachO::any_relocation_info RE;
1793     bool isExtern = false;
1794     SymbolRef Symbol;
1795     for (const RelocationRef &Reloc : info->S.relocations()) {
1796       uint64_t RelocOffset = Reloc.getOffset();
1797       if (RelocOffset == sect_offset) {
1798         Rel = Reloc.getRawDataRefImpl();
1799         RE = info->O->getRelocation(Rel);
1800         // NOTE: Scattered relocations don't exist on x86_64.
1801         isExtern = info->O->getPlainRelocationExternal(RE);
1802         if (isExtern) {
1803           symbol_iterator RelocSym = Reloc.getSymbol();
1804           Symbol = *RelocSym;
1805         }
1806         reloc_found = true;
1807         break;
1808       }
1809     }
1810     if (reloc_found && isExtern) {
1811       // The Value passed in will be adjusted by the Pc if the instruction
1812       // adds the Pc.  But for x86_64 external relocation entries the Value
1813       // is the offset from the external symbol.
1814       if (info->O->getAnyRelocationPCRel(RE))
1815         op_info->Value -= Pc + Offset + Size;
1816       ErrorOr<StringRef> SymName = Symbol.getName();
1817       if (std::error_code EC = SymName.getError())
1818         report_fatal_error(EC.message());
1819       const char *name = SymName->data();
1820       unsigned Type = info->O->getAnyRelocationType(RE);
1821       if (Type == MachO::X86_64_RELOC_SUBTRACTOR) {
1822         DataRefImpl RelNext = Rel;
1823         info->O->moveRelocationNext(RelNext);
1824         MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
1825         unsigned TypeNext = info->O->getAnyRelocationType(RENext);
1826         bool isExternNext = info->O->getPlainRelocationExternal(RENext);
1827         unsigned SymbolNum = info->O->getPlainRelocationSymbolNum(RENext);
1828         if (TypeNext == MachO::X86_64_RELOC_UNSIGNED && isExternNext) {
1829           op_info->SubtractSymbol.Present = 1;
1830           op_info->SubtractSymbol.Name = name;
1831           symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum);
1832           Symbol = *RelocSymNext;
1833           ErrorOr<StringRef> SymNameNext = Symbol.getName();
1834           if (std::error_code EC = SymNameNext.getError())
1835             report_fatal_error(EC.message());
1836           name = SymNameNext->data();
1837         }
1838       }
1839       // TODO: add the VariantKinds to op_info->VariantKind for relocation types
1840       // like: X86_64_RELOC_TLV, X86_64_RELOC_GOT_LOAD and X86_64_RELOC_GOT.
1841       op_info->AddSymbol.Present = 1;
1842       op_info->AddSymbol.Name = name;
1843       return 1;
1844     }
1845     // TODO:
1846     // Second search the external relocation entries of a fully linked image
1847     // (if any) for an entry that matches this segment offset.
1848     // uint64_t seg_offset = (Pc + Offset);
1849     return 0;
1850   }
1851   if (Arch == Triple::arm) {
1852     if (Offset != 0 || (Size != 4 && Size != 2))
1853       return 0;
1854     // First search the section's relocation entries (if any) for an entry
1855     // for this section offset.
1856     uint32_t sect_addr = info->S.getAddress();
1857     uint32_t sect_offset = (Pc + Offset) - sect_addr;
1858     DataRefImpl Rel;
1859     MachO::any_relocation_info RE;
1860     bool isExtern = false;
1861     SymbolRef Symbol;
1862     bool r_scattered = false;
1863     uint32_t r_value, pair_r_value, r_type, r_length, other_half;
1864     auto Reloc =
1865         std::find_if(info->S.relocations().begin(), info->S.relocations().end(),
1866                      [&](const RelocationRef &Reloc) {
1867                        uint64_t RelocOffset = Reloc.getOffset();
1868                        return RelocOffset == sect_offset;
1869                      });
1870
1871     if (Reloc == info->S.relocations().end())
1872       return 0;
1873
1874     Rel = Reloc->getRawDataRefImpl();
1875     RE = info->O->getRelocation(Rel);
1876     r_length = info->O->getAnyRelocationLength(RE);
1877     r_scattered = info->O->isRelocationScattered(RE);
1878     if (r_scattered) {
1879       r_value = info->O->getScatteredRelocationValue(RE);
1880       r_type = info->O->getScatteredRelocationType(RE);
1881     } else {
1882       r_type = info->O->getAnyRelocationType(RE);
1883       isExtern = info->O->getPlainRelocationExternal(RE);
1884       if (isExtern) {
1885         symbol_iterator RelocSym = Reloc->getSymbol();
1886         Symbol = *RelocSym;
1887       }
1888     }
1889     if (r_type == MachO::ARM_RELOC_HALF ||
1890         r_type == MachO::ARM_RELOC_SECTDIFF ||
1891         r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
1892         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1893       DataRefImpl RelNext = Rel;
1894       info->O->moveRelocationNext(RelNext);
1895       MachO::any_relocation_info RENext;
1896       RENext = info->O->getRelocation(RelNext);
1897       other_half = info->O->getAnyRelocationAddress(RENext) & 0xffff;
1898       if (info->O->isRelocationScattered(RENext))
1899         pair_r_value = info->O->getScatteredRelocationValue(RENext);
1900     }
1901
1902     if (isExtern) {
1903       ErrorOr<StringRef> SymName = Symbol.getName();
1904       if (std::error_code EC = SymName.getError())
1905         report_fatal_error(EC.message());
1906       const char *name = SymName->data();
1907       op_info->AddSymbol.Present = 1;
1908       op_info->AddSymbol.Name = name;
1909       switch (r_type) {
1910       case MachO::ARM_RELOC_HALF:
1911         if ((r_length & 0x1) == 1) {
1912           op_info->Value = value << 16 | other_half;
1913           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
1914         } else {
1915           op_info->Value = other_half << 16 | value;
1916           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
1917         }
1918         break;
1919       default:
1920         break;
1921       }
1922       return 1;
1923     }
1924     // If we have a branch that is not an external relocation entry then
1925     // return 0 so the code in tryAddingSymbolicOperand() can use the
1926     // SymbolLookUp call back with the branch target address to look up the
1927     // symbol and possiblity add an annotation for a symbol stub.
1928     if (isExtern == 0 && (r_type == MachO::ARM_RELOC_BR24 ||
1929                           r_type == MachO::ARM_THUMB_RELOC_BR22))
1930       return 0;
1931
1932     uint32_t offset = 0;
1933     if (r_type == MachO::ARM_RELOC_HALF ||
1934         r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1935       if ((r_length & 0x1) == 1)
1936         value = value << 16 | other_half;
1937       else
1938         value = other_half << 16 | value;
1939     }
1940     if (r_scattered && (r_type != MachO::ARM_RELOC_HALF &&
1941                         r_type != MachO::ARM_RELOC_HALF_SECTDIFF)) {
1942       offset = value - r_value;
1943       value = r_value;
1944     }
1945
1946     if (r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1947       if ((r_length & 0x1) == 1)
1948         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
1949       else
1950         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
1951       const char *add = GuessSymbolName(r_value, info->AddrMap);
1952       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
1953       int32_t offset = value - (r_value - pair_r_value);
1954       op_info->AddSymbol.Present = 1;
1955       if (add != nullptr)
1956         op_info->AddSymbol.Name = add;
1957       else
1958         op_info->AddSymbol.Value = r_value;
1959       op_info->SubtractSymbol.Present = 1;
1960       if (sub != nullptr)
1961         op_info->SubtractSymbol.Name = sub;
1962       else
1963         op_info->SubtractSymbol.Value = pair_r_value;
1964       op_info->Value = offset;
1965       return 1;
1966     }
1967
1968     op_info->AddSymbol.Present = 1;
1969     op_info->Value = offset;
1970     if (r_type == MachO::ARM_RELOC_HALF) {
1971       if ((r_length & 0x1) == 1)
1972         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
1973       else
1974         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
1975     }
1976     const char *add = GuessSymbolName(value, info->AddrMap);
1977     if (add != nullptr) {
1978       op_info->AddSymbol.Name = add;
1979       return 1;
1980     }
1981     op_info->AddSymbol.Value = value;
1982     return 1;
1983   }
1984   if (Arch == Triple::aarch64) {
1985     if (Offset != 0 || Size != 4)
1986       return 0;
1987     // First search the section's relocation entries (if any) for an entry
1988     // for this section offset.
1989     uint64_t sect_addr = info->S.getAddress();
1990     uint64_t sect_offset = (Pc + Offset) - sect_addr;
1991     auto Reloc =
1992         std::find_if(info->S.relocations().begin(), info->S.relocations().end(),
1993                      [&](const RelocationRef &Reloc) {
1994                        uint64_t RelocOffset = Reloc.getOffset();
1995                        return RelocOffset == sect_offset;
1996                      });
1997
1998     if (Reloc == info->S.relocations().end())
1999       return 0;
2000
2001     DataRefImpl Rel = Reloc->getRawDataRefImpl();
2002     MachO::any_relocation_info RE = info->O->getRelocation(Rel);
2003     uint32_t r_type = info->O->getAnyRelocationType(RE);
2004     if (r_type == MachO::ARM64_RELOC_ADDEND) {
2005       DataRefImpl RelNext = Rel;
2006       info->O->moveRelocationNext(RelNext);
2007       MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
2008       if (value == 0) {
2009         value = info->O->getPlainRelocationSymbolNum(RENext);
2010         op_info->Value = value;
2011       }
2012     }
2013     // NOTE: Scattered relocations don't exist on arm64.
2014     if (!info->O->getPlainRelocationExternal(RE))
2015       return 0;
2016     ErrorOr<StringRef> SymName = Reloc->getSymbol()->getName();
2017     if (std::error_code EC = SymName.getError())
2018       report_fatal_error(EC.message());
2019     const char *name = SymName->data();
2020     op_info->AddSymbol.Present = 1;
2021     op_info->AddSymbol.Name = name;
2022
2023     switch (r_type) {
2024     case MachO::ARM64_RELOC_PAGE21:
2025       /* @page */
2026       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGE;
2027       break;
2028     case MachO::ARM64_RELOC_PAGEOFF12:
2029       /* @pageoff */
2030       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGEOFF;
2031       break;
2032     case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
2033       /* @gotpage */
2034       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGE;
2035       break;
2036     case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
2037       /* @gotpageoff */
2038       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF;
2039       break;
2040     case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
2041       /* @tvlppage is not implemented in llvm-mc */
2042       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVP;
2043       break;
2044     case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
2045       /* @tvlppageoff is not implemented in llvm-mc */
2046       op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVOFF;
2047       break;
2048     default:
2049     case MachO::ARM64_RELOC_BRANCH26:
2050       op_info->VariantKind = LLVMDisassembler_VariantKind_None;
2051       break;
2052     }
2053     return 1;
2054   }
2055   return 0;
2056 }
2057
2058 // GuessCstringPointer is passed the address of what might be a pointer to a
2059 // literal string in a cstring section.  If that address is in a cstring section
2060 // it returns a pointer to that string.  Else it returns nullptr.
2061 static const char *GuessCstringPointer(uint64_t ReferenceValue,
2062                                        struct DisassembleInfo *info) {
2063   for (const auto &Load : info->O->load_commands()) {
2064     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2065       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2066       for (unsigned J = 0; J < Seg.nsects; ++J) {
2067         MachO::section_64 Sec = info->O->getSection64(Load, J);
2068         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2069         if (section_type == MachO::S_CSTRING_LITERALS &&
2070             ReferenceValue >= Sec.addr &&
2071             ReferenceValue < Sec.addr + Sec.size) {
2072           uint64_t sect_offset = ReferenceValue - Sec.addr;
2073           uint64_t object_offset = Sec.offset + sect_offset;
2074           StringRef MachOContents = info->O->getData();
2075           uint64_t object_size = MachOContents.size();
2076           const char *object_addr = (const char *)MachOContents.data();
2077           if (object_offset < object_size) {
2078             const char *name = object_addr + object_offset;
2079             return name;
2080           } else {
2081             return nullptr;
2082           }
2083         }
2084       }
2085     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
2086       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
2087       for (unsigned J = 0; J < Seg.nsects; ++J) {
2088         MachO::section Sec = info->O->getSection(Load, J);
2089         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2090         if (section_type == MachO::S_CSTRING_LITERALS &&
2091             ReferenceValue >= Sec.addr &&
2092             ReferenceValue < Sec.addr + Sec.size) {
2093           uint64_t sect_offset = ReferenceValue - Sec.addr;
2094           uint64_t object_offset = Sec.offset + sect_offset;
2095           StringRef MachOContents = info->O->getData();
2096           uint64_t object_size = MachOContents.size();
2097           const char *object_addr = (const char *)MachOContents.data();
2098           if (object_offset < object_size) {
2099             const char *name = object_addr + object_offset;
2100             return name;
2101           } else {
2102             return nullptr;
2103           }
2104         }
2105       }
2106     }
2107   }
2108   return nullptr;
2109 }
2110
2111 // GuessIndirectSymbol returns the name of the indirect symbol for the
2112 // ReferenceValue passed in or nullptr.  This is used when ReferenceValue maybe
2113 // an address of a symbol stub or a lazy or non-lazy pointer to associate the
2114 // symbol name being referenced by the stub or pointer.
2115 static const char *GuessIndirectSymbol(uint64_t ReferenceValue,
2116                                        struct DisassembleInfo *info) {
2117   MachO::dysymtab_command Dysymtab = info->O->getDysymtabLoadCommand();
2118   MachO::symtab_command Symtab = info->O->getSymtabLoadCommand();
2119   for (const auto &Load : info->O->load_commands()) {
2120     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2121       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2122       for (unsigned J = 0; J < Seg.nsects; ++J) {
2123         MachO::section_64 Sec = info->O->getSection64(Load, J);
2124         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2125         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
2126              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
2127              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
2128              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
2129              section_type == MachO::S_SYMBOL_STUBS) &&
2130             ReferenceValue >= Sec.addr &&
2131             ReferenceValue < Sec.addr + Sec.size) {
2132           uint32_t stride;
2133           if (section_type == MachO::S_SYMBOL_STUBS)
2134             stride = Sec.reserved2;
2135           else
2136             stride = 8;
2137           if (stride == 0)
2138             return nullptr;
2139           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
2140           if (index < Dysymtab.nindirectsyms) {
2141             uint32_t indirect_symbol =
2142                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
2143             if (indirect_symbol < Symtab.nsyms) {
2144               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
2145               SymbolRef Symbol = *Sym;
2146               ErrorOr<StringRef> SymName = Symbol.getName();
2147               if (std::error_code EC = SymName.getError())
2148                 report_fatal_error(EC.message());
2149               const char *name = SymName->data();
2150               return name;
2151             }
2152           }
2153         }
2154       }
2155     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
2156       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
2157       for (unsigned J = 0; J < Seg.nsects; ++J) {
2158         MachO::section Sec = info->O->getSection(Load, J);
2159         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2160         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
2161              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
2162              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
2163              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
2164              section_type == MachO::S_SYMBOL_STUBS) &&
2165             ReferenceValue >= Sec.addr &&
2166             ReferenceValue < Sec.addr + Sec.size) {
2167           uint32_t stride;
2168           if (section_type == MachO::S_SYMBOL_STUBS)
2169             stride = Sec.reserved2;
2170           else
2171             stride = 4;
2172           if (stride == 0)
2173             return nullptr;
2174           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
2175           if (index < Dysymtab.nindirectsyms) {
2176             uint32_t indirect_symbol =
2177                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
2178             if (indirect_symbol < Symtab.nsyms) {
2179               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
2180               SymbolRef Symbol = *Sym;
2181               ErrorOr<StringRef> SymName = Symbol.getName();
2182               if (std::error_code EC = SymName.getError())
2183                 report_fatal_error(EC.message());
2184               const char *name = SymName->data();
2185               return name;
2186             }
2187           }
2188         }
2189       }
2190     }
2191   }
2192   return nullptr;
2193 }
2194
2195 // method_reference() is called passing it the ReferenceName that might be
2196 // a reference it to an Objective-C method call.  If so then it allocates and
2197 // assembles a method call string with the values last seen and saved in
2198 // the DisassembleInfo's class_name and selector_name fields.  This is saved
2199 // into the method field of the info and any previous string is free'ed.
2200 // Then the class_name field in the info is set to nullptr.  The method call
2201 // string is set into ReferenceName and ReferenceType is set to
2202 // LLVMDisassembler_ReferenceType_Out_Objc_Message.  If this not a method call
2203 // then both ReferenceType and ReferenceName are left unchanged.
2204 static void method_reference(struct DisassembleInfo *info,
2205                              uint64_t *ReferenceType,
2206                              const char **ReferenceName) {
2207   unsigned int Arch = info->O->getArch();
2208   if (*ReferenceName != nullptr) {
2209     if (strcmp(*ReferenceName, "_objc_msgSend") == 0) {
2210       if (info->selector_name != nullptr) {
2211         if (info->method != nullptr)
2212           free(info->method);
2213         if (info->class_name != nullptr) {
2214           info->method = (char *)malloc(5 + strlen(info->class_name) +
2215                                         strlen(info->selector_name));
2216           if (info->method != nullptr) {
2217             strcpy(info->method, "+[");
2218             strcat(info->method, info->class_name);
2219             strcat(info->method, " ");
2220             strcat(info->method, info->selector_name);
2221             strcat(info->method, "]");
2222             *ReferenceName = info->method;
2223             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2224           }
2225         } else {
2226           info->method = (char *)malloc(9 + strlen(info->selector_name));
2227           if (info->method != nullptr) {
2228             if (Arch == Triple::x86_64)
2229               strcpy(info->method, "-[%rdi ");
2230             else if (Arch == Triple::aarch64)
2231               strcpy(info->method, "-[x0 ");
2232             else
2233               strcpy(info->method, "-[r? ");
2234             strcat(info->method, info->selector_name);
2235             strcat(info->method, "]");
2236             *ReferenceName = info->method;
2237             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2238           }
2239         }
2240         info->class_name = nullptr;
2241       }
2242     } else if (strcmp(*ReferenceName, "_objc_msgSendSuper2") == 0) {
2243       if (info->selector_name != nullptr) {
2244         if (info->method != nullptr)
2245           free(info->method);
2246         info->method = (char *)malloc(17 + strlen(info->selector_name));
2247         if (info->method != nullptr) {
2248           if (Arch == Triple::x86_64)
2249             strcpy(info->method, "-[[%rdi super] ");
2250           else if (Arch == Triple::aarch64)
2251             strcpy(info->method, "-[[x0 super] ");
2252           else
2253             strcpy(info->method, "-[[r? super] ");
2254           strcat(info->method, info->selector_name);
2255           strcat(info->method, "]");
2256           *ReferenceName = info->method;
2257           *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2258         }
2259         info->class_name = nullptr;
2260       }
2261     }
2262   }
2263 }
2264
2265 // GuessPointerPointer() is passed the address of what might be a pointer to
2266 // a reference to an Objective-C class, selector, message ref or cfstring.
2267 // If so the value of the pointer is returned and one of the booleans are set
2268 // to true.  If not zero is returned and all the booleans are set to false.
2269 static uint64_t GuessPointerPointer(uint64_t ReferenceValue,
2270                                     struct DisassembleInfo *info,
2271                                     bool &classref, bool &selref, bool &msgref,
2272                                     bool &cfstring) {
2273   classref = false;
2274   selref = false;
2275   msgref = false;
2276   cfstring = false;
2277   for (const auto &Load : info->O->load_commands()) {
2278     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2279       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2280       for (unsigned J = 0; J < Seg.nsects; ++J) {
2281         MachO::section_64 Sec = info->O->getSection64(Load, J);
2282         if ((strncmp(Sec.sectname, "__objc_selrefs", 16) == 0 ||
2283              strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
2284              strncmp(Sec.sectname, "__objc_superrefs", 16) == 0 ||
2285              strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 ||
2286              strncmp(Sec.sectname, "__cfstring", 16) == 0) &&
2287             ReferenceValue >= Sec.addr &&
2288             ReferenceValue < Sec.addr + Sec.size) {
2289           uint64_t sect_offset = ReferenceValue - Sec.addr;
2290           uint64_t object_offset = Sec.offset + sect_offset;
2291           StringRef MachOContents = info->O->getData();
2292           uint64_t object_size = MachOContents.size();
2293           const char *object_addr = (const char *)MachOContents.data();
2294           if (object_offset < object_size) {
2295             uint64_t pointer_value;
2296             memcpy(&pointer_value, object_addr + object_offset,
2297                    sizeof(uint64_t));
2298             if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2299               sys::swapByteOrder(pointer_value);
2300             if (strncmp(Sec.sectname, "__objc_selrefs", 16) == 0)
2301               selref = true;
2302             else if (strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
2303                      strncmp(Sec.sectname, "__objc_superrefs", 16) == 0)
2304               classref = true;
2305             else if (strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 &&
2306                      ReferenceValue + 8 < Sec.addr + Sec.size) {
2307               msgref = true;
2308               memcpy(&pointer_value, object_addr + object_offset + 8,
2309                      sizeof(uint64_t));
2310               if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2311                 sys::swapByteOrder(pointer_value);
2312             } else if (strncmp(Sec.sectname, "__cfstring", 16) == 0)
2313               cfstring = true;
2314             return pointer_value;
2315           } else {
2316             return 0;
2317           }
2318         }
2319       }
2320     }
2321     // TODO: Look for LC_SEGMENT for 32-bit Mach-O files.
2322   }
2323   return 0;
2324 }
2325
2326 // get_pointer_64 returns a pointer to the bytes in the object file at the
2327 // Address from a section in the Mach-O file.  And indirectly returns the
2328 // offset into the section, number of bytes left in the section past the offset
2329 // and which section is was being referenced.  If the Address is not in a
2330 // section nullptr is returned.
2331 static const char *get_pointer_64(uint64_t Address, uint32_t &offset,
2332                                   uint32_t &left, SectionRef &S,
2333                                   DisassembleInfo *info,
2334                                   bool objc_only = false) {
2335   offset = 0;
2336   left = 0;
2337   S = SectionRef();
2338   for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) {
2339     uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress();
2340     uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize();
2341     if (objc_only) {
2342       StringRef SectName;
2343       ((*(info->Sections))[SectIdx]).getName(SectName);
2344       DataRefImpl Ref = ((*(info->Sections))[SectIdx]).getRawDataRefImpl();
2345       StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
2346       if (SegName != "__OBJC" && SectName != "__cstring")
2347         continue;
2348     }
2349     if (Address >= SectAddress && Address < SectAddress + SectSize) {
2350       S = (*(info->Sections))[SectIdx];
2351       offset = Address - SectAddress;
2352       left = SectSize - offset;
2353       StringRef SectContents;
2354       ((*(info->Sections))[SectIdx]).getContents(SectContents);
2355       return SectContents.data() + offset;
2356     }
2357   }
2358   return nullptr;
2359 }
2360
2361 static const char *get_pointer_32(uint32_t Address, uint32_t &offset,
2362                                   uint32_t &left, SectionRef &S,
2363                                   DisassembleInfo *info,
2364                                   bool objc_only = false) {
2365   return get_pointer_64(Address, offset, left, S, info, objc_only);
2366 }
2367
2368 // get_symbol_64() returns the name of a symbol (or nullptr) and the address of
2369 // the symbol indirectly through n_value. Based on the relocation information
2370 // for the specified section offset in the specified section reference.
2371 // If no relocation information is found and a non-zero ReferenceValue for the
2372 // symbol is passed, look up that address in the info's AddrMap.
2373 static const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
2374                                  DisassembleInfo *info, uint64_t &n_value,
2375                                  uint64_t ReferenceValue = 0) {
2376   n_value = 0;
2377   if (!info->verbose)
2378     return nullptr;
2379
2380   // See if there is an external relocation entry at the sect_offset.
2381   bool reloc_found = false;
2382   DataRefImpl Rel;
2383   MachO::any_relocation_info RE;
2384   bool isExtern = false;
2385   SymbolRef Symbol;
2386   for (const RelocationRef &Reloc : S.relocations()) {
2387     uint64_t RelocOffset = Reloc.getOffset();
2388     if (RelocOffset == sect_offset) {
2389       Rel = Reloc.getRawDataRefImpl();
2390       RE = info->O->getRelocation(Rel);
2391       if (info->O->isRelocationScattered(RE))
2392         continue;
2393       isExtern = info->O->getPlainRelocationExternal(RE);
2394       if (isExtern) {
2395         symbol_iterator RelocSym = Reloc.getSymbol();
2396         Symbol = *RelocSym;
2397       }
2398       reloc_found = true;
2399       break;
2400     }
2401   }
2402   // If there is an external relocation entry for a symbol in this section
2403   // at this section_offset then use that symbol's value for the n_value
2404   // and return its name.
2405   const char *SymbolName = nullptr;
2406   if (reloc_found && isExtern) {
2407     n_value = Symbol.getValue();
2408     ErrorOr<StringRef> NameOrError = Symbol.getName();
2409     if (std::error_code EC = NameOrError.getError())
2410       report_fatal_error(EC.message());
2411     StringRef Name = *NameOrError;
2412     if (!Name.empty()) {
2413       SymbolName = Name.data();
2414       return SymbolName;
2415     }
2416   }
2417
2418   // TODO: For fully linked images, look through the external relocation
2419   // entries off the dynamic symtab command. For these the r_offset is from the
2420   // start of the first writeable segment in the Mach-O file.  So the offset
2421   // to this section from that segment is passed to this routine by the caller,
2422   // as the database_offset. Which is the difference of the section's starting
2423   // address and the first writable segment.
2424   //
2425   // NOTE: need add passing the database_offset to this routine.
2426
2427   // We did not find an external relocation entry so look up the ReferenceValue
2428   // as an address of a symbol and if found return that symbol's name.
2429   SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
2430
2431   return SymbolName;
2432 }
2433
2434 static const char *get_symbol_32(uint32_t sect_offset, SectionRef S,
2435                                  DisassembleInfo *info,
2436                                  uint32_t ReferenceValue) {
2437   uint64_t n_value64;
2438   return get_symbol_64(sect_offset, S, info, n_value64, ReferenceValue);
2439 }
2440
2441 // These are structs in the Objective-C meta data and read to produce the
2442 // comments for disassembly.  While these are part of the ABI they are no
2443 // public defintions.  So the are here not in include/llvm/Support/MachO.h .
2444
2445 // The cfstring object in a 64-bit Mach-O file.
2446 struct cfstring64_t {
2447   uint64_t isa;        // class64_t * (64-bit pointer)
2448   uint64_t flags;      // flag bits
2449   uint64_t characters; // char * (64-bit pointer)
2450   uint64_t length;     // number of non-NULL characters in above
2451 };
2452
2453 // The class object in a 64-bit Mach-O file.
2454 struct class64_t {
2455   uint64_t isa;        // class64_t * (64-bit pointer)
2456   uint64_t superclass; // class64_t * (64-bit pointer)
2457   uint64_t cache;      // Cache (64-bit pointer)
2458   uint64_t vtable;     // IMP * (64-bit pointer)
2459   uint64_t data;       // class_ro64_t * (64-bit pointer)
2460 };
2461
2462 struct class32_t {
2463   uint32_t isa;        /* class32_t * (32-bit pointer) */
2464   uint32_t superclass; /* class32_t * (32-bit pointer) */
2465   uint32_t cache;      /* Cache (32-bit pointer) */
2466   uint32_t vtable;     /* IMP * (32-bit pointer) */
2467   uint32_t data;       /* class_ro32_t * (32-bit pointer) */
2468 };
2469
2470 struct class_ro64_t {
2471   uint32_t flags;
2472   uint32_t instanceStart;
2473   uint32_t instanceSize;
2474   uint32_t reserved;
2475   uint64_t ivarLayout;     // const uint8_t * (64-bit pointer)
2476   uint64_t name;           // const char * (64-bit pointer)
2477   uint64_t baseMethods;    // const method_list_t * (64-bit pointer)
2478   uint64_t baseProtocols;  // const protocol_list_t * (64-bit pointer)
2479   uint64_t ivars;          // const ivar_list_t * (64-bit pointer)
2480   uint64_t weakIvarLayout; // const uint8_t * (64-bit pointer)
2481   uint64_t baseProperties; // const struct objc_property_list (64-bit pointer)
2482 };
2483
2484 struct class_ro32_t {
2485   uint32_t flags;
2486   uint32_t instanceStart;
2487   uint32_t instanceSize;
2488   uint32_t ivarLayout;     /* const uint8_t * (32-bit pointer) */
2489   uint32_t name;           /* const char * (32-bit pointer) */
2490   uint32_t baseMethods;    /* const method_list_t * (32-bit pointer) */
2491   uint32_t baseProtocols;  /* const protocol_list_t * (32-bit pointer) */
2492   uint32_t ivars;          /* const ivar_list_t * (32-bit pointer) */
2493   uint32_t weakIvarLayout; /* const uint8_t * (32-bit pointer) */
2494   uint32_t baseProperties; /* const struct objc_property_list *
2495                                                    (32-bit pointer) */
2496 };
2497
2498 /* Values for class_ro{64,32}_t->flags */
2499 #define RO_META (1 << 0)
2500 #define RO_ROOT (1 << 1)
2501 #define RO_HAS_CXX_STRUCTORS (1 << 2)
2502
2503 struct method_list64_t {
2504   uint32_t entsize;
2505   uint32_t count;
2506   /* struct method64_t first;  These structures follow inline */
2507 };
2508
2509 struct method_list32_t {
2510   uint32_t entsize;
2511   uint32_t count;
2512   /* struct method32_t first;  These structures follow inline */
2513 };
2514
2515 struct method64_t {
2516   uint64_t name;  /* SEL (64-bit pointer) */
2517   uint64_t types; /* const char * (64-bit pointer) */
2518   uint64_t imp;   /* IMP (64-bit pointer) */
2519 };
2520
2521 struct method32_t {
2522   uint32_t name;  /* SEL (32-bit pointer) */
2523   uint32_t types; /* const char * (32-bit pointer) */
2524   uint32_t imp;   /* IMP (32-bit pointer) */
2525 };
2526
2527 struct protocol_list64_t {
2528   uint64_t count; /* uintptr_t (a 64-bit value) */
2529   /* struct protocol64_t * list[0];  These pointers follow inline */
2530 };
2531
2532 struct protocol_list32_t {
2533   uint32_t count; /* uintptr_t (a 32-bit value) */
2534   /* struct protocol32_t * list[0];  These pointers follow inline */
2535 };
2536
2537 struct protocol64_t {
2538   uint64_t isa;                     /* id * (64-bit pointer) */
2539   uint64_t name;                    /* const char * (64-bit pointer) */
2540   uint64_t protocols;               /* struct protocol_list64_t *
2541                                                     (64-bit pointer) */
2542   uint64_t instanceMethods;         /* method_list_t * (64-bit pointer) */
2543   uint64_t classMethods;            /* method_list_t * (64-bit pointer) */
2544   uint64_t optionalInstanceMethods; /* method_list_t * (64-bit pointer) */
2545   uint64_t optionalClassMethods;    /* method_list_t * (64-bit pointer) */
2546   uint64_t instanceProperties;      /* struct objc_property_list *
2547                                                        (64-bit pointer) */
2548 };
2549
2550 struct protocol32_t {
2551   uint32_t isa;                     /* id * (32-bit pointer) */
2552   uint32_t name;                    /* const char * (32-bit pointer) */
2553   uint32_t protocols;               /* struct protocol_list_t *
2554                                                     (32-bit pointer) */
2555   uint32_t instanceMethods;         /* method_list_t * (32-bit pointer) */
2556   uint32_t classMethods;            /* method_list_t * (32-bit pointer) */
2557   uint32_t optionalInstanceMethods; /* method_list_t * (32-bit pointer) */
2558   uint32_t optionalClassMethods;    /* method_list_t * (32-bit pointer) */
2559   uint32_t instanceProperties;      /* struct objc_property_list *
2560                                                        (32-bit pointer) */
2561 };
2562
2563 struct ivar_list64_t {
2564   uint32_t entsize;
2565   uint32_t count;
2566   /* struct ivar64_t first;  These structures follow inline */
2567 };
2568
2569 struct ivar_list32_t {
2570   uint32_t entsize;
2571   uint32_t count;
2572   /* struct ivar32_t first;  These structures follow inline */
2573 };
2574
2575 struct ivar64_t {
2576   uint64_t offset; /* uintptr_t * (64-bit pointer) */
2577   uint64_t name;   /* const char * (64-bit pointer) */
2578   uint64_t type;   /* const char * (64-bit pointer) */
2579   uint32_t alignment;
2580   uint32_t size;
2581 };
2582
2583 struct ivar32_t {
2584   uint32_t offset; /* uintptr_t * (32-bit pointer) */
2585   uint32_t name;   /* const char * (32-bit pointer) */
2586   uint32_t type;   /* const char * (32-bit pointer) */
2587   uint32_t alignment;
2588   uint32_t size;
2589 };
2590
2591 struct objc_property_list64 {
2592   uint32_t entsize;
2593   uint32_t count;
2594   /* struct objc_property64 first;  These structures follow inline */
2595 };
2596
2597 struct objc_property_list32 {
2598   uint32_t entsize;
2599   uint32_t count;
2600   /* struct objc_property32 first;  These structures follow inline */
2601 };
2602
2603 struct objc_property64 {
2604   uint64_t name;       /* const char * (64-bit pointer) */
2605   uint64_t attributes; /* const char * (64-bit pointer) */
2606 };
2607
2608 struct objc_property32 {
2609   uint32_t name;       /* const char * (32-bit pointer) */
2610   uint32_t attributes; /* const char * (32-bit pointer) */
2611 };
2612
2613 struct category64_t {
2614   uint64_t name;               /* const char * (64-bit pointer) */
2615   uint64_t cls;                /* struct class_t * (64-bit pointer) */
2616   uint64_t instanceMethods;    /* struct method_list_t * (64-bit pointer) */
2617   uint64_t classMethods;       /* struct method_list_t * (64-bit pointer) */
2618   uint64_t protocols;          /* struct protocol_list_t * (64-bit pointer) */
2619   uint64_t instanceProperties; /* struct objc_property_list *
2620                                   (64-bit pointer) */
2621 };
2622
2623 struct category32_t {
2624   uint32_t name;               /* const char * (32-bit pointer) */
2625   uint32_t cls;                /* struct class_t * (32-bit pointer) */
2626   uint32_t instanceMethods;    /* struct method_list_t * (32-bit pointer) */
2627   uint32_t classMethods;       /* struct method_list_t * (32-bit pointer) */
2628   uint32_t protocols;          /* struct protocol_list_t * (32-bit pointer) */
2629   uint32_t instanceProperties; /* struct objc_property_list *
2630                                   (32-bit pointer) */
2631 };
2632
2633 struct objc_image_info64 {
2634   uint32_t version;
2635   uint32_t flags;
2636 };
2637 struct objc_image_info32 {
2638   uint32_t version;
2639   uint32_t flags;
2640 };
2641 struct imageInfo_t {
2642   uint32_t version;
2643   uint32_t flags;
2644 };
2645 /* masks for objc_image_info.flags */
2646 #define OBJC_IMAGE_IS_REPLACEMENT (1 << 0)
2647 #define OBJC_IMAGE_SUPPORTS_GC (1 << 1)
2648
2649 struct message_ref64 {
2650   uint64_t imp; /* IMP (64-bit pointer) */
2651   uint64_t sel; /* SEL (64-bit pointer) */
2652 };
2653
2654 struct message_ref32 {
2655   uint32_t imp; /* IMP (32-bit pointer) */
2656   uint32_t sel; /* SEL (32-bit pointer) */
2657 };
2658
2659 // Objective-C 1 (32-bit only) meta data structs.
2660
2661 struct objc_module_t {
2662   uint32_t version;
2663   uint32_t size;
2664   uint32_t name;   /* char * (32-bit pointer) */
2665   uint32_t symtab; /* struct objc_symtab * (32-bit pointer) */
2666 };
2667
2668 struct objc_symtab_t {
2669   uint32_t sel_ref_cnt;
2670   uint32_t refs; /* SEL * (32-bit pointer) */
2671   uint16_t cls_def_cnt;
2672   uint16_t cat_def_cnt;
2673   // uint32_t defs[1];        /* void * (32-bit pointer) variable size */
2674 };
2675
2676 struct objc_class_t {
2677   uint32_t isa;         /* struct objc_class * (32-bit pointer) */
2678   uint32_t super_class; /* struct objc_class * (32-bit pointer) */
2679   uint32_t name;        /* const char * (32-bit pointer) */
2680   int32_t version;
2681   int32_t info;
2682   int32_t instance_size;
2683   uint32_t ivars;       /* struct objc_ivar_list * (32-bit pointer) */
2684   uint32_t methodLists; /* struct objc_method_list ** (32-bit pointer) */
2685   uint32_t cache;       /* struct objc_cache * (32-bit pointer) */
2686   uint32_t protocols;   /* struct objc_protocol_list * (32-bit pointer) */
2687 };
2688
2689 #define CLS_GETINFO(cls, infomask) ((cls)->info & (infomask))
2690 // class is not a metaclass
2691 #define CLS_CLASS 0x1
2692 // class is a metaclass
2693 #define CLS_META 0x2
2694
2695 struct objc_category_t {
2696   uint32_t category_name;    /* char * (32-bit pointer) */
2697   uint32_t class_name;       /* char * (32-bit pointer) */
2698   uint32_t instance_methods; /* struct objc_method_list * (32-bit pointer) */
2699   uint32_t class_methods;    /* struct objc_method_list * (32-bit pointer) */
2700   uint32_t protocols;        /* struct objc_protocol_list * (32-bit ptr) */
2701 };
2702
2703 struct objc_ivar_t {
2704   uint32_t ivar_name; /* char * (32-bit pointer) */
2705   uint32_t ivar_type; /* char * (32-bit pointer) */
2706   int32_t ivar_offset;
2707 };
2708
2709 struct objc_ivar_list_t {
2710   int32_t ivar_count;
2711   // struct objc_ivar_t ivar_list[1];          /* variable length structure */
2712 };
2713
2714 struct objc_method_list_t {
2715   uint32_t obsolete; /* struct objc_method_list * (32-bit pointer) */
2716   int32_t method_count;
2717   // struct objc_method_t method_list[1];      /* variable length structure */
2718 };
2719
2720 struct objc_method_t {
2721   uint32_t method_name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
2722   uint32_t method_types; /* char * (32-bit pointer) */
2723   uint32_t method_imp;   /* IMP, aka function pointer, (*IMP)(id, SEL, ...)
2724                             (32-bit pointer) */
2725 };
2726
2727 struct objc_protocol_list_t {
2728   uint32_t next; /* struct objc_protocol_list * (32-bit pointer) */
2729   int32_t count;
2730   // uint32_t list[1];   /* Protocol *, aka struct objc_protocol_t *
2731   //                        (32-bit pointer) */
2732 };
2733
2734 struct objc_protocol_t {
2735   uint32_t isa;              /* struct objc_class * (32-bit pointer) */
2736   uint32_t protocol_name;    /* char * (32-bit pointer) */
2737   uint32_t protocol_list;    /* struct objc_protocol_list * (32-bit pointer) */
2738   uint32_t instance_methods; /* struct objc_method_description_list *
2739                                 (32-bit pointer) */
2740   uint32_t class_methods;    /* struct objc_method_description_list *
2741                                 (32-bit pointer) */
2742 };
2743
2744 struct objc_method_description_list_t {
2745   int32_t count;
2746   // struct objc_method_description_t list[1];
2747 };
2748
2749 struct objc_method_description_t {
2750   uint32_t name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
2751   uint32_t types; /* char * (32-bit pointer) */
2752 };
2753
2754 inline void swapStruct(struct cfstring64_t &cfs) {
2755   sys::swapByteOrder(cfs.isa);
2756   sys::swapByteOrder(cfs.flags);
2757   sys::swapByteOrder(cfs.characters);
2758   sys::swapByteOrder(cfs.length);
2759 }
2760
2761 inline void swapStruct(struct class64_t &c) {
2762   sys::swapByteOrder(c.isa);
2763   sys::swapByteOrder(c.superclass);
2764   sys::swapByteOrder(c.cache);
2765   sys::swapByteOrder(c.vtable);
2766   sys::swapByteOrder(c.data);
2767 }
2768
2769 inline void swapStruct(struct class32_t &c) {
2770   sys::swapByteOrder(c.isa);
2771   sys::swapByteOrder(c.superclass);
2772   sys::swapByteOrder(c.cache);
2773   sys::swapByteOrder(c.vtable);
2774   sys::swapByteOrder(c.data);
2775 }
2776
2777 inline void swapStruct(struct class_ro64_t &cro) {
2778   sys::swapByteOrder(cro.flags);
2779   sys::swapByteOrder(cro.instanceStart);
2780   sys::swapByteOrder(cro.instanceSize);
2781   sys::swapByteOrder(cro.reserved);
2782   sys::swapByteOrder(cro.ivarLayout);
2783   sys::swapByteOrder(cro.name);
2784   sys::swapByteOrder(cro.baseMethods);
2785   sys::swapByteOrder(cro.baseProtocols);
2786   sys::swapByteOrder(cro.ivars);
2787   sys::swapByteOrder(cro.weakIvarLayout);
2788   sys::swapByteOrder(cro.baseProperties);
2789 }
2790
2791 inline void swapStruct(struct class_ro32_t &cro) {
2792   sys::swapByteOrder(cro.flags);
2793   sys::swapByteOrder(cro.instanceStart);
2794   sys::swapByteOrder(cro.instanceSize);
2795   sys::swapByteOrder(cro.ivarLayout);
2796   sys::swapByteOrder(cro.name);
2797   sys::swapByteOrder(cro.baseMethods);
2798   sys::swapByteOrder(cro.baseProtocols);
2799   sys::swapByteOrder(cro.ivars);
2800   sys::swapByteOrder(cro.weakIvarLayout);
2801   sys::swapByteOrder(cro.baseProperties);
2802 }
2803
2804 inline void swapStruct(struct method_list64_t &ml) {
2805   sys::swapByteOrder(ml.entsize);
2806   sys::swapByteOrder(ml.count);
2807 }
2808
2809 inline void swapStruct(struct method_list32_t &ml) {
2810   sys::swapByteOrder(ml.entsize);
2811   sys::swapByteOrder(ml.count);
2812 }
2813
2814 inline void swapStruct(struct method64_t &m) {
2815   sys::swapByteOrder(m.name);
2816   sys::swapByteOrder(m.types);
2817   sys::swapByteOrder(m.imp);
2818 }
2819
2820 inline void swapStruct(struct method32_t &m) {
2821   sys::swapByteOrder(m.name);
2822   sys::swapByteOrder(m.types);
2823   sys::swapByteOrder(m.imp);
2824 }
2825
2826 inline void swapStruct(struct protocol_list64_t &pl) {
2827   sys::swapByteOrder(pl.count);
2828 }
2829
2830 inline void swapStruct(struct protocol_list32_t &pl) {
2831   sys::swapByteOrder(pl.count);
2832 }
2833
2834 inline void swapStruct(struct protocol64_t &p) {
2835   sys::swapByteOrder(p.isa);
2836   sys::swapByteOrder(p.name);
2837   sys::swapByteOrder(p.protocols);
2838   sys::swapByteOrder(p.instanceMethods);
2839   sys::swapByteOrder(p.classMethods);
2840   sys::swapByteOrder(p.optionalInstanceMethods);
2841   sys::swapByteOrder(p.optionalClassMethods);
2842   sys::swapByteOrder(p.instanceProperties);
2843 }
2844
2845 inline void swapStruct(struct protocol32_t &p) {
2846   sys::swapByteOrder(p.isa);
2847   sys::swapByteOrder(p.name);
2848   sys::swapByteOrder(p.protocols);
2849   sys::swapByteOrder(p.instanceMethods);
2850   sys::swapByteOrder(p.classMethods);
2851   sys::swapByteOrder(p.optionalInstanceMethods);
2852   sys::swapByteOrder(p.optionalClassMethods);
2853   sys::swapByteOrder(p.instanceProperties);
2854 }
2855
2856 inline void swapStruct(struct ivar_list64_t &il) {
2857   sys::swapByteOrder(il.entsize);
2858   sys::swapByteOrder(il.count);
2859 }
2860
2861 inline void swapStruct(struct ivar_list32_t &il) {
2862   sys::swapByteOrder(il.entsize);
2863   sys::swapByteOrder(il.count);
2864 }
2865
2866 inline void swapStruct(struct ivar64_t &i) {
2867   sys::swapByteOrder(i.offset);
2868   sys::swapByteOrder(i.name);
2869   sys::swapByteOrder(i.type);
2870   sys::swapByteOrder(i.alignment);
2871   sys::swapByteOrder(i.size);
2872 }
2873
2874 inline void swapStruct(struct ivar32_t &i) {
2875   sys::swapByteOrder(i.offset);
2876   sys::swapByteOrder(i.name);
2877   sys::swapByteOrder(i.type);
2878   sys::swapByteOrder(i.alignment);
2879   sys::swapByteOrder(i.size);
2880 }
2881
2882 inline void swapStruct(struct objc_property_list64 &pl) {
2883   sys::swapByteOrder(pl.entsize);
2884   sys::swapByteOrder(pl.count);
2885 }
2886
2887 inline void swapStruct(struct objc_property_list32 &pl) {
2888   sys::swapByteOrder(pl.entsize);
2889   sys::swapByteOrder(pl.count);
2890 }
2891
2892 inline void swapStruct(struct objc_property64 &op) {
2893   sys::swapByteOrder(op.name);
2894   sys::swapByteOrder(op.attributes);
2895 }
2896
2897 inline void swapStruct(struct objc_property32 &op) {
2898   sys::swapByteOrder(op.name);
2899   sys::swapByteOrder(op.attributes);
2900 }
2901
2902 inline void swapStruct(struct category64_t &c) {
2903   sys::swapByteOrder(c.name);
2904   sys::swapByteOrder(c.cls);
2905   sys::swapByteOrder(c.instanceMethods);
2906   sys::swapByteOrder(c.classMethods);
2907   sys::swapByteOrder(c.protocols);
2908   sys::swapByteOrder(c.instanceProperties);
2909 }
2910
2911 inline void swapStruct(struct category32_t &c) {
2912   sys::swapByteOrder(c.name);
2913   sys::swapByteOrder(c.cls);
2914   sys::swapByteOrder(c.instanceMethods);
2915   sys::swapByteOrder(c.classMethods);
2916   sys::swapByteOrder(c.protocols);
2917   sys::swapByteOrder(c.instanceProperties);
2918 }
2919
2920 inline void swapStruct(struct objc_image_info64 &o) {
2921   sys::swapByteOrder(o.version);
2922   sys::swapByteOrder(o.flags);
2923 }
2924
2925 inline void swapStruct(struct objc_image_info32 &o) {
2926   sys::swapByteOrder(o.version);
2927   sys::swapByteOrder(o.flags);
2928 }
2929
2930 inline void swapStruct(struct imageInfo_t &o) {
2931   sys::swapByteOrder(o.version);
2932   sys::swapByteOrder(o.flags);
2933 }
2934
2935 inline void swapStruct(struct message_ref64 &mr) {
2936   sys::swapByteOrder(mr.imp);
2937   sys::swapByteOrder(mr.sel);
2938 }
2939
2940 inline void swapStruct(struct message_ref32 &mr) {
2941   sys::swapByteOrder(mr.imp);
2942   sys::swapByteOrder(mr.sel);
2943 }
2944
2945 inline void swapStruct(struct objc_module_t &module) {
2946   sys::swapByteOrder(module.version);
2947   sys::swapByteOrder(module.size);
2948   sys::swapByteOrder(module.name);
2949   sys::swapByteOrder(module.symtab);
2950 }
2951
2952 inline void swapStruct(struct objc_symtab_t &symtab) {
2953   sys::swapByteOrder(symtab.sel_ref_cnt);
2954   sys::swapByteOrder(symtab.refs);
2955   sys::swapByteOrder(symtab.cls_def_cnt);
2956   sys::swapByteOrder(symtab.cat_def_cnt);
2957 }
2958
2959 inline void swapStruct(struct objc_class_t &objc_class) {
2960   sys::swapByteOrder(objc_class.isa);
2961   sys::swapByteOrder(objc_class.super_class);
2962   sys::swapByteOrder(objc_class.name);
2963   sys::swapByteOrder(objc_class.version);
2964   sys::swapByteOrder(objc_class.info);
2965   sys::swapByteOrder(objc_class.instance_size);
2966   sys::swapByteOrder(objc_class.ivars);
2967   sys::swapByteOrder(objc_class.methodLists);
2968   sys::swapByteOrder(objc_class.cache);
2969   sys::swapByteOrder(objc_class.protocols);
2970 }
2971
2972 inline void swapStruct(struct objc_category_t &objc_category) {
2973   sys::swapByteOrder(objc_category.category_name);
2974   sys::swapByteOrder(objc_category.class_name);
2975   sys::swapByteOrder(objc_category.instance_methods);
2976   sys::swapByteOrder(objc_category.class_methods);
2977   sys::swapByteOrder(objc_category.protocols);
2978 }
2979
2980 inline void swapStruct(struct objc_ivar_list_t &objc_ivar_list) {
2981   sys::swapByteOrder(objc_ivar_list.ivar_count);
2982 }
2983
2984 inline void swapStruct(struct objc_ivar_t &objc_ivar) {
2985   sys::swapByteOrder(objc_ivar.ivar_name);
2986   sys::swapByteOrder(objc_ivar.ivar_type);
2987   sys::swapByteOrder(objc_ivar.ivar_offset);
2988 }
2989
2990 inline void swapStruct(struct objc_method_list_t &method_list) {
2991   sys::swapByteOrder(method_list.obsolete);
2992   sys::swapByteOrder(method_list.method_count);
2993 }
2994
2995 inline void swapStruct(struct objc_method_t &method) {
2996   sys::swapByteOrder(method.method_name);
2997   sys::swapByteOrder(method.method_types);
2998   sys::swapByteOrder(method.method_imp);
2999 }
3000
3001 inline void swapStruct(struct objc_protocol_list_t &protocol_list) {
3002   sys::swapByteOrder(protocol_list.next);
3003   sys::swapByteOrder(protocol_list.count);
3004 }
3005
3006 inline void swapStruct(struct objc_protocol_t &protocol) {
3007   sys::swapByteOrder(protocol.isa);
3008   sys::swapByteOrder(protocol.protocol_name);
3009   sys::swapByteOrder(protocol.protocol_list);
3010   sys::swapByteOrder(protocol.instance_methods);
3011   sys::swapByteOrder(protocol.class_methods);
3012 }
3013
3014 inline void swapStruct(struct objc_method_description_list_t &mdl) {
3015   sys::swapByteOrder(mdl.count);
3016 }
3017
3018 inline void swapStruct(struct objc_method_description_t &md) {
3019   sys::swapByteOrder(md.name);
3020   sys::swapByteOrder(md.types);
3021 }
3022
3023 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
3024                                                  struct DisassembleInfo *info);
3025
3026 // get_objc2_64bit_class_name() is used for disassembly and is passed a pointer
3027 // to an Objective-C class and returns the class name.  It is also passed the
3028 // address of the pointer, so when the pointer is zero as it can be in an .o
3029 // file, that is used to look for an external relocation entry with a symbol
3030 // name.
3031 static const char *get_objc2_64bit_class_name(uint64_t pointer_value,
3032                                               uint64_t ReferenceValue,
3033                                               struct DisassembleInfo *info) {
3034   const char *r;
3035   uint32_t offset, left;
3036   SectionRef S;
3037
3038   // The pointer_value can be 0 in an object file and have a relocation
3039   // entry for the class symbol at the ReferenceValue (the address of the
3040   // pointer).
3041   if (pointer_value == 0) {
3042     r = get_pointer_64(ReferenceValue, offset, left, S, info);
3043     if (r == nullptr || left < sizeof(uint64_t))
3044       return nullptr;
3045     uint64_t n_value;
3046     const char *symbol_name = get_symbol_64(offset, S, info, n_value);
3047     if (symbol_name == nullptr)
3048       return nullptr;
3049     const char *class_name = strrchr(symbol_name, '$');
3050     if (class_name != nullptr && class_name[1] == '_' && class_name[2] != '\0')
3051       return class_name + 2;
3052     else
3053       return nullptr;
3054   }
3055
3056   // The case were the pointer_value is non-zero and points to a class defined
3057   // in this Mach-O file.
3058   r = get_pointer_64(pointer_value, offset, left, S, info);
3059   if (r == nullptr || left < sizeof(struct class64_t))
3060     return nullptr;
3061   struct class64_t c;
3062   memcpy(&c, r, sizeof(struct class64_t));
3063   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3064     swapStruct(c);
3065   if (c.data == 0)
3066     return nullptr;
3067   r = get_pointer_64(c.data, offset, left, S, info);
3068   if (r == nullptr || left < sizeof(struct class_ro64_t))
3069     return nullptr;
3070   struct class_ro64_t cro;
3071   memcpy(&cro, r, sizeof(struct class_ro64_t));
3072   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3073     swapStruct(cro);
3074   if (cro.name == 0)
3075     return nullptr;
3076   const char *name = get_pointer_64(cro.name, offset, left, S, info);
3077   return name;
3078 }
3079
3080 // get_objc2_64bit_cfstring_name is used for disassembly and is passed a
3081 // pointer to a cfstring and returns its name or nullptr.
3082 static const char *get_objc2_64bit_cfstring_name(uint64_t ReferenceValue,
3083                                                  struct DisassembleInfo *info) {
3084   const char *r, *name;
3085   uint32_t offset, left;
3086   SectionRef S;
3087   struct cfstring64_t cfs;
3088   uint64_t cfs_characters;
3089
3090   r = get_pointer_64(ReferenceValue, offset, left, S, info);
3091   if (r == nullptr || left < sizeof(struct cfstring64_t))
3092     return nullptr;
3093   memcpy(&cfs, r, sizeof(struct cfstring64_t));
3094   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3095     swapStruct(cfs);
3096   if (cfs.characters == 0) {
3097     uint64_t n_value;
3098     const char *symbol_name = get_symbol_64(
3099         offset + offsetof(struct cfstring64_t, characters), S, info, n_value);
3100     if (symbol_name == nullptr)
3101       return nullptr;
3102     cfs_characters = n_value;
3103   } else
3104     cfs_characters = cfs.characters;
3105   name = get_pointer_64(cfs_characters, offset, left, S, info);
3106
3107   return name;
3108 }
3109
3110 // get_objc2_64bit_selref() is used for disassembly and is passed a the address
3111 // of a pointer to an Objective-C selector reference when the pointer value is
3112 // zero as in a .o file and is likely to have a external relocation entry with
3113 // who's symbol's n_value is the real pointer to the selector name.  If that is
3114 // the case the real pointer to the selector name is returned else 0 is
3115 // returned
3116 static uint64_t get_objc2_64bit_selref(uint64_t ReferenceValue,
3117                                        struct DisassembleInfo *info) {
3118   uint32_t offset, left;
3119   SectionRef S;
3120
3121   const char *r = get_pointer_64(ReferenceValue, offset, left, S, info);
3122   if (r == nullptr || left < sizeof(uint64_t))
3123     return 0;
3124   uint64_t n_value;
3125   const char *symbol_name = get_symbol_64(offset, S, info, n_value);
3126   if (symbol_name == nullptr)
3127     return 0;
3128   return n_value;
3129 }
3130
3131 static const SectionRef get_section(MachOObjectFile *O, const char *segname,
3132                                     const char *sectname) {
3133   for (const SectionRef &Section : O->sections()) {
3134     StringRef SectName;
3135     Section.getName(SectName);
3136     DataRefImpl Ref = Section.getRawDataRefImpl();
3137     StringRef SegName = O->getSectionFinalSegmentName(Ref);
3138     if (SegName == segname && SectName == sectname)
3139       return Section;
3140   }
3141   return SectionRef();
3142 }
3143
3144 static void
3145 walk_pointer_list_64(const char *listname, const SectionRef S,
3146                      MachOObjectFile *O, struct DisassembleInfo *info,
3147                      void (*func)(uint64_t, struct DisassembleInfo *info)) {
3148   if (S == SectionRef())
3149     return;
3150
3151   StringRef SectName;
3152   S.getName(SectName);
3153   DataRefImpl Ref = S.getRawDataRefImpl();
3154   StringRef SegName = O->getSectionFinalSegmentName(Ref);
3155   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
3156
3157   StringRef BytesStr;
3158   S.getContents(BytesStr);
3159   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
3160
3161   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint64_t)) {
3162     uint32_t left = S.getSize() - i;
3163     uint32_t size = left < sizeof(uint64_t) ? left : sizeof(uint64_t);
3164     uint64_t p = 0;
3165     memcpy(&p, Contents + i, size);
3166     if (i + sizeof(uint64_t) > S.getSize())
3167       outs() << listname << " list pointer extends past end of (" << SegName
3168              << "," << SectName << ") section\n";
3169     outs() << format("%016" PRIx64, S.getAddress() + i) << " ";
3170
3171     if (O->isLittleEndian() != sys::IsLittleEndianHost)
3172       sys::swapByteOrder(p);
3173
3174     uint64_t n_value = 0;
3175     const char *name = get_symbol_64(i, S, info, n_value, p);
3176     if (name == nullptr)
3177       name = get_dyld_bind_info_symbolname(S.getAddress() + i, info);
3178
3179     if (n_value != 0) {
3180       outs() << format("0x%" PRIx64, n_value);
3181       if (p != 0)
3182         outs() << " + " << format("0x%" PRIx64, p);
3183     } else
3184       outs() << format("0x%" PRIx64, p);
3185     if (name != nullptr)
3186       outs() << " " << name;
3187     outs() << "\n";
3188
3189     p += n_value;
3190     if (func)
3191       func(p, info);
3192   }
3193 }
3194
3195 static void
3196 walk_pointer_list_32(const char *listname, const SectionRef S,
3197                      MachOObjectFile *O, struct DisassembleInfo *info,
3198                      void (*func)(uint32_t, struct DisassembleInfo *info)) {
3199   if (S == SectionRef())
3200     return;
3201
3202   StringRef SectName;
3203   S.getName(SectName);
3204   DataRefImpl Ref = S.getRawDataRefImpl();
3205   StringRef SegName = O->getSectionFinalSegmentName(Ref);
3206   outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
3207
3208   StringRef BytesStr;
3209   S.getContents(BytesStr);
3210   const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
3211
3212   for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint32_t)) {
3213     uint32_t left = S.getSize() - i;
3214     uint32_t size = left < sizeof(uint32_t) ? left : sizeof(uint32_t);
3215     uint32_t p = 0;
3216     memcpy(&p, Contents + i, size);
3217     if (i + sizeof(uint32_t) > S.getSize())
3218       outs() << listname << " list pointer extends past end of (" << SegName
3219              << "," << SectName << ") section\n";
3220     uint32_t Address = S.getAddress() + i;
3221     outs() << format("%08" PRIx32, Address) << " ";
3222
3223     if (O->isLittleEndian() != sys::IsLittleEndianHost)
3224       sys::swapByteOrder(p);
3225     outs() << format("0x%" PRIx32, p);
3226
3227     const char *name = get_symbol_32(i, S, info, p);
3228     if (name != nullptr)
3229       outs() << " " << name;
3230     outs() << "\n";
3231
3232     if (func)
3233       func(p, info);
3234   }
3235 }
3236
3237 static void print_layout_map(const char *layout_map, uint32_t left) {
3238   outs() << "                layout map: ";
3239   do {
3240     outs() << format("0x%02" PRIx32, (*layout_map) & 0xff) << " ";
3241     left--;
3242     layout_map++;
3243   } while (*layout_map != '\0' && left != 0);
3244   outs() << "\n";
3245 }
3246
3247 static void print_layout_map64(uint64_t p, struct DisassembleInfo *info) {
3248   uint32_t offset, left;
3249   SectionRef S;
3250   const char *layout_map;
3251
3252   if (p == 0)
3253     return;
3254   layout_map = get_pointer_64(p, offset, left, S, info);
3255   print_layout_map(layout_map, left);
3256 }
3257
3258 static void print_layout_map32(uint32_t p, struct DisassembleInfo *info) {
3259   uint32_t offset, left;
3260   SectionRef S;
3261   const char *layout_map;
3262
3263   if (p == 0)
3264     return;
3265   layout_map = get_pointer_32(p, offset, left, S, info);
3266   print_layout_map(layout_map, left);
3267 }
3268
3269 static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
3270                                   const char *indent) {
3271   struct method_list64_t ml;
3272   struct method64_t m;
3273   const char *r;
3274   uint32_t offset, xoffset, left, i;
3275   SectionRef S, xS;
3276   const char *name, *sym_name;
3277   uint64_t n_value;
3278
3279   r = get_pointer_64(p, offset, left, S, info);
3280   if (r == nullptr)
3281     return;
3282   memset(&ml, '\0', sizeof(struct method_list64_t));
3283   if (left < sizeof(struct method_list64_t)) {
3284     memcpy(&ml, r, left);
3285     outs() << "   (method_list_t entends past the end of the section)\n";
3286   } else
3287     memcpy(&ml, r, sizeof(struct method_list64_t));
3288   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3289     swapStruct(ml);
3290   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
3291   outs() << indent << "\t\t     count " << ml.count << "\n";
3292
3293   p += sizeof(struct method_list64_t);
3294   offset += sizeof(struct method_list64_t);
3295   for (i = 0; i < ml.count; i++) {
3296     r = get_pointer_64(p, offset, left, S, info);
3297     if (r == nullptr)
3298       return;
3299     memset(&m, '\0', sizeof(struct method64_t));
3300     if (left < sizeof(struct method64_t)) {
3301       memcpy(&ml, r, left);
3302       outs() << indent << "   (method_t entends past the end of the section)\n";
3303     } else
3304       memcpy(&m, r, sizeof(struct method64_t));
3305     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3306       swapStruct(m);
3307
3308     outs() << indent << "\t\t      name ";
3309     sym_name = get_symbol_64(offset + offsetof(struct method64_t, name), S,
3310                              info, n_value, m.name);
3311     if (n_value != 0) {
3312       if (info->verbose && sym_name != nullptr)
3313         outs() << sym_name;
3314       else
3315         outs() << format("0x%" PRIx64, n_value);
3316       if (m.name != 0)
3317         outs() << " + " << format("0x%" PRIx64, m.name);
3318     } else
3319       outs() << format("0x%" PRIx64, m.name);
3320     name = get_pointer_64(m.name + n_value, xoffset, left, xS, info);
3321     if (name != nullptr)
3322       outs() << format(" %.*s", left, name);
3323     outs() << "\n";
3324
3325     outs() << indent << "\t\t     types ";
3326     sym_name = get_symbol_64(offset + offsetof(struct method64_t, types), S,
3327                              info, n_value, m.types);
3328     if (n_value != 0) {
3329       if (info->verbose && sym_name != nullptr)
3330         outs() << sym_name;
3331       else
3332         outs() << format("0x%" PRIx64, n_value);
3333       if (m.types != 0)
3334         outs() << " + " << format("0x%" PRIx64, m.types);
3335     } else
3336       outs() << format("0x%" PRIx64, m.types);
3337     name = get_pointer_64(m.types + n_value, xoffset, left, xS, info);
3338     if (name != nullptr)
3339       outs() << format(" %.*s", left, name);
3340     outs() << "\n";
3341
3342     outs() << indent << "\t\t       imp ";
3343     name = get_symbol_64(offset + offsetof(struct method64_t, imp), S, info,
3344                          n_value, m.imp);
3345     if (info->verbose && name == nullptr) {
3346       if (n_value != 0) {
3347         outs() << format("0x%" PRIx64, n_value) << " ";
3348         if (m.imp != 0)
3349           outs() << "+ " << format("0x%" PRIx64, m.imp) << " ";
3350       } else
3351         outs() << format("0x%" PRIx64, m.imp) << " ";
3352     }
3353     if (name != nullptr)
3354       outs() << name;
3355     outs() << "\n";
3356
3357     p += sizeof(struct method64_t);
3358     offset += sizeof(struct method64_t);
3359   }
3360 }
3361
3362 static void print_method_list32_t(uint64_t p, struct DisassembleInfo *info,
3363                                   const char *indent) {
3364   struct method_list32_t ml;
3365   struct method32_t m;
3366   const char *r, *name;
3367   uint32_t offset, xoffset, left, i;
3368   SectionRef S, xS;
3369
3370   r = get_pointer_32(p, offset, left, S, info);
3371   if (r == nullptr)
3372     return;
3373   memset(&ml, '\0', sizeof(struct method_list32_t));
3374   if (left < sizeof(struct method_list32_t)) {
3375     memcpy(&ml, r, left);
3376     outs() << "   (method_list_t entends past the end of the section)\n";
3377   } else
3378     memcpy(&ml, r, sizeof(struct method_list32_t));
3379   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3380     swapStruct(ml);
3381   outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
3382   outs() << indent << "\t\t     count " << ml.count << "\n";
3383
3384   p += sizeof(struct method_list32_t);
3385   offset += sizeof(struct method_list32_t);
3386   for (i = 0; i < ml.count; i++) {
3387     r = get_pointer_32(p, offset, left, S, info);
3388     if (r == nullptr)
3389       return;
3390     memset(&m, '\0', sizeof(struct method32_t));
3391     if (left < sizeof(struct method32_t)) {
3392       memcpy(&ml, r, left);
3393       outs() << indent << "   (method_t entends past the end of the section)\n";
3394     } else
3395       memcpy(&m, r, sizeof(struct method32_t));
3396     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3397       swapStruct(m);
3398
3399     outs() << indent << "\t\t      name " << format("0x%" PRIx32, m.name);
3400     name = get_pointer_32(m.name, xoffset, left, xS, info);
3401     if (name != nullptr)
3402       outs() << format(" %.*s", left, name);
3403     outs() << "\n";
3404
3405     outs() << indent << "\t\t     types " << format("0x%" PRIx32, m.types);
3406     name = get_pointer_32(m.types, xoffset, left, xS, info);
3407     if (name != nullptr)
3408       outs() << format(" %.*s", left, name);
3409     outs() << "\n";
3410
3411     outs() << indent << "\t\t       imp " << format("0x%" PRIx32, m.imp);
3412     name = get_symbol_32(offset + offsetof(struct method32_t, imp), S, info,
3413                          m.imp);
3414     if (name != nullptr)
3415       outs() << " " << name;
3416     outs() << "\n";
3417
3418     p += sizeof(struct method32_t);
3419     offset += sizeof(struct method32_t);
3420   }
3421 }
3422
3423 static bool print_method_list(uint32_t p, struct DisassembleInfo *info) {
3424   uint32_t offset, left, xleft;
3425   SectionRef S;
3426   struct objc_method_list_t method_list;
3427   struct objc_method_t method;
3428   const char *r, *methods, *name, *SymbolName;
3429   int32_t i;
3430
3431   r = get_pointer_32(p, offset, left, S, info, true);
3432   if (r == nullptr)
3433     return true;
3434
3435   outs() << "\n";
3436   if (left > sizeof(struct objc_method_list_t)) {
3437     memcpy(&method_list, r, sizeof(struct objc_method_list_t));
3438   } else {
3439     outs() << "\t\t objc_method_list extends past end of the section\n";
3440     memset(&method_list, '\0', sizeof(struct objc_method_list_t));
3441     memcpy(&method_list, r, left);
3442   }
3443   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3444     swapStruct(method_list);
3445
3446   outs() << "\t\t         obsolete "
3447          << format("0x%08" PRIx32, method_list.obsolete) << "\n";
3448   outs() << "\t\t     method_count " << method_list.method_count << "\n";
3449
3450   methods = r + sizeof(struct objc_method_list_t);
3451   for (i = 0; i < method_list.method_count; i++) {
3452     if ((i + 1) * sizeof(struct objc_method_t) > left) {
3453       outs() << "\t\t remaining method's extend past the of the section\n";
3454       break;
3455     }
3456     memcpy(&method, methods + i * sizeof(struct objc_method_t),
3457            sizeof(struct objc_method_t));
3458     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3459       swapStruct(method);
3460
3461     outs() << "\t\t      method_name "
3462            << format("0x%08" PRIx32, method.method_name);
3463     if (info->verbose) {
3464       name = get_pointer_32(method.method_name, offset, xleft, S, info, true);
3465       if (name != nullptr)
3466         outs() << format(" %.*s", xleft, name);
3467       else
3468         outs() << " (not in an __OBJC section)";
3469     }
3470     outs() << "\n";
3471
3472     outs() << "\t\t     method_types "
3473            << format("0x%08" PRIx32, method.method_types);
3474     if (info->verbose) {
3475       name = get_pointer_32(method.method_types, offset, xleft, S, info, true);
3476       if (name != nullptr)
3477         outs() << format(" %.*s", xleft, name);
3478       else
3479         outs() << " (not in an __OBJC section)";
3480     }
3481     outs() << "\n";
3482
3483     outs() << "\t\t       method_imp "
3484            << format("0x%08" PRIx32, method.method_imp) << " ";
3485     if (info->verbose) {
3486       SymbolName = GuessSymbolName(method.method_imp, info->AddrMap);
3487       if (SymbolName != nullptr)
3488         outs() << SymbolName;
3489     }
3490     outs() << "\n";
3491   }
3492   return false;
3493 }
3494
3495 static void print_protocol_list64_t(uint64_t p, struct DisassembleInfo *info) {
3496   struct protocol_list64_t pl;
3497   uint64_t q, n_value;
3498   struct protocol64_t pc;
3499   const char *r;
3500   uint32_t offset, xoffset, left, i;
3501   SectionRef S, xS;
3502   const char *name, *sym_name;
3503
3504   r = get_pointer_64(p, offset, left, S, info);
3505   if (r == nullptr)
3506     return;
3507   memset(&pl, '\0', sizeof(struct protocol_list64_t));
3508   if (left < sizeof(struct protocol_list64_t)) {
3509     memcpy(&pl, r, left);
3510     outs() << "   (protocol_list_t entends past the end of the section)\n";
3511   } else
3512     memcpy(&pl, r, sizeof(struct protocol_list64_t));
3513   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3514     swapStruct(pl);
3515   outs() << "                      count " << pl.count << "\n";
3516
3517   p += sizeof(struct protocol_list64_t);
3518   offset += sizeof(struct protocol_list64_t);
3519   for (i = 0; i < pl.count; i++) {
3520     r = get_pointer_64(p, offset, left, S, info);
3521     if (r == nullptr)
3522       return;
3523     q = 0;
3524     if (left < sizeof(uint64_t)) {
3525       memcpy(&q, r, left);
3526       outs() << "   (protocol_t * entends past the end of the section)\n";
3527     } else
3528       memcpy(&q, r, sizeof(uint64_t));
3529     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3530       sys::swapByteOrder(q);
3531
3532     outs() << "\t\t      list[" << i << "] ";
3533     sym_name = get_symbol_64(offset, S, info, n_value, q);
3534     if (n_value != 0) {
3535       if (info->verbose && sym_name != nullptr)
3536         outs() << sym_name;
3537       else
3538         outs() << format("0x%" PRIx64, n_value);
3539       if (q != 0)
3540         outs() << " + " << format("0x%" PRIx64, q);
3541     } else
3542       outs() << format("0x%" PRIx64, q);
3543     outs() << " (struct protocol_t *)\n";
3544
3545     r = get_pointer_64(q + n_value, offset, left, S, info);
3546     if (r == nullptr)
3547       return;
3548     memset(&pc, '\0', sizeof(struct protocol64_t));
3549     if (left < sizeof(struct protocol64_t)) {
3550       memcpy(&pc, r, left);
3551       outs() << "   (protocol_t entends past the end of the section)\n";
3552     } else
3553       memcpy(&pc, r, sizeof(struct protocol64_t));
3554     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3555       swapStruct(pc);
3556
3557     outs() << "\t\t\t      isa " << format("0x%" PRIx64, pc.isa) << "\n";
3558
3559     outs() << "\t\t\t     name ";
3560     sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, name), S,
3561                              info, n_value, pc.name);
3562     if (n_value != 0) {
3563       if (info->verbose && sym_name != nullptr)
3564         outs() << sym_name;
3565       else
3566         outs() << format("0x%" PRIx64, n_value);
3567       if (pc.name != 0)
3568         outs() << " + " << format("0x%" PRIx64, pc.name);
3569     } else
3570       outs() << format("0x%" PRIx64, pc.name);
3571     name = get_pointer_64(pc.name + n_value, xoffset, left, xS, info);
3572     if (name != nullptr)
3573       outs() << format(" %.*s", left, name);
3574     outs() << "\n";
3575
3576     outs() << "\t\t\tprotocols " << format("0x%" PRIx64, pc.protocols) << "\n";
3577
3578     outs() << "\t\t  instanceMethods ";
3579     sym_name =
3580         get_symbol_64(offset + offsetof(struct protocol64_t, instanceMethods),
3581                       S, info, n_value, pc.instanceMethods);
3582     if (n_value != 0) {
3583       if (info->verbose && sym_name != nullptr)
3584         outs() << sym_name;
3585       else
3586         outs() << format("0x%" PRIx64, n_value);
3587       if (pc.instanceMethods != 0)
3588         outs() << " + " << format("0x%" PRIx64, pc.instanceMethods);
3589     } else
3590       outs() << format("0x%" PRIx64, pc.instanceMethods);
3591     outs() << " (struct method_list_t *)\n";
3592     if (pc.instanceMethods + n_value != 0)
3593       print_method_list64_t(pc.instanceMethods + n_value, info, "\t");
3594
3595     outs() << "\t\t     classMethods ";
3596     sym_name =
3597         get_symbol_64(offset + offsetof(struct protocol64_t, classMethods), S,
3598                       info, n_value, pc.classMethods);
3599     if (n_value != 0) {
3600       if (info->verbose && sym_name != nullptr)
3601         outs() << sym_name;
3602       else
3603         outs() << format("0x%" PRIx64, n_value);
3604       if (pc.classMethods != 0)
3605         outs() << " + " << format("0x%" PRIx64, pc.classMethods);
3606     } else
3607       outs() << format("0x%" PRIx64, pc.classMethods);
3608     outs() << " (struct method_list_t *)\n";
3609     if (pc.classMethods + n_value != 0)
3610       print_method_list64_t(pc.classMethods + n_value, info, "\t");
3611
3612     outs() << "\t  optionalInstanceMethods "
3613            << format("0x%" PRIx64, pc.optionalInstanceMethods) << "\n";
3614     outs() << "\t     optionalClassMethods "
3615            << format("0x%" PRIx64, pc.optionalClassMethods) << "\n";
3616     outs() << "\t       instanceProperties "
3617            << format("0x%" PRIx64, pc.instanceProperties) << "\n";
3618
3619     p += sizeof(uint64_t);
3620     offset += sizeof(uint64_t);
3621   }
3622 }
3623
3624 static void print_protocol_list32_t(uint32_t p, struct DisassembleInfo *info) {
3625   struct protocol_list32_t pl;
3626   uint32_t q;
3627   struct protocol32_t pc;
3628   const char *r;
3629   uint32_t offset, xoffset, left, i;
3630   SectionRef S, xS;
3631   const char *name;
3632
3633   r = get_pointer_32(p, offset, left, S, info);
3634   if (r == nullptr)
3635     return;
3636   memset(&pl, '\0', sizeof(struct protocol_list32_t));
3637   if (left < sizeof(struct protocol_list32_t)) {
3638     memcpy(&pl, r, left);
3639     outs() << "   (protocol_list_t entends past the end of the section)\n";
3640   } else
3641     memcpy(&pl, r, sizeof(struct protocol_list32_t));
3642   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3643     swapStruct(pl);
3644   outs() << "                      count " << pl.count << "\n";
3645
3646   p += sizeof(struct protocol_list32_t);
3647   offset += sizeof(struct protocol_list32_t);
3648   for (i = 0; i < pl.count; i++) {
3649     r = get_pointer_32(p, offset, left, S, info);
3650     if (r == nullptr)
3651       return;
3652     q = 0;
3653     if (left < sizeof(uint32_t)) {
3654       memcpy(&q, r, left);
3655       outs() << "   (protocol_t * entends past the end of the section)\n";
3656     } else
3657       memcpy(&q, r, sizeof(uint32_t));
3658     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3659       sys::swapByteOrder(q);
3660     outs() << "\t\t      list[" << i << "] " << format("0x%" PRIx32, q)
3661            << " (struct protocol_t *)\n";
3662     r = get_pointer_32(q, offset, left, S, info);
3663     if (r == nullptr)
3664       return;
3665     memset(&pc, '\0', sizeof(struct protocol32_t));
3666     if (left < sizeof(struct protocol32_t)) {
3667       memcpy(&pc, r, left);
3668       outs() << "   (protocol_t entends past the end of the section)\n";
3669     } else
3670       memcpy(&pc, r, sizeof(struct protocol32_t));
3671     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3672       swapStruct(pc);
3673     outs() << "\t\t\t      isa " << format("0x%" PRIx32, pc.isa) << "\n";
3674     outs() << "\t\t\t     name " << format("0x%" PRIx32, pc.name);
3675     name = get_pointer_32(pc.name, xoffset, left, xS, info);
3676     if (name != nullptr)
3677       outs() << format(" %.*s", left, name);
3678     outs() << "\n";
3679     outs() << "\t\t\tprotocols " << format("0x%" PRIx32, pc.protocols) << "\n";
3680     outs() << "\t\t  instanceMethods "
3681            << format("0x%" PRIx32, pc.instanceMethods)
3682            << " (struct method_list_t *)\n";
3683     if (pc.instanceMethods != 0)
3684       print_method_list32_t(pc.instanceMethods, info, "\t");
3685     outs() << "\t\t     classMethods " << format("0x%" PRIx32, pc.classMethods)
3686            << " (struct method_list_t *)\n";
3687     if (pc.classMethods != 0)
3688       print_method_list32_t(pc.classMethods, info, "\t");
3689     outs() << "\t  optionalInstanceMethods "
3690            << format("0x%" PRIx32, pc.optionalInstanceMethods) << "\n";
3691     outs() << "\t     optionalClassMethods "
3692            << format("0x%" PRIx32, pc.optionalClassMethods) << "\n";
3693     outs() << "\t       instanceProperties "
3694            << format("0x%" PRIx32, pc.instanceProperties) << "\n";
3695     p += sizeof(uint32_t);
3696     offset += sizeof(uint32_t);
3697   }
3698 }
3699
3700 static void print_indent(uint32_t indent) {
3701   for (uint32_t i = 0; i < indent;) {
3702     if (indent - i >= 8) {
3703       outs() << "\t";
3704       i += 8;
3705     } else {
3706       for (uint32_t j = i; j < indent; j++)
3707         outs() << " ";
3708       return;
3709     }
3710   }
3711 }
3712
3713 static bool print_method_description_list(uint32_t p, uint32_t indent,
3714                                           struct DisassembleInfo *info) {
3715   uint32_t offset, left, xleft;
3716   SectionRef S;
3717   struct objc_method_description_list_t mdl;
3718   struct objc_method_description_t md;
3719   const char *r, *list, *name;
3720   int32_t i;
3721
3722   r = get_pointer_32(p, offset, left, S, info, true);
3723   if (r == nullptr)
3724     return true;
3725
3726   outs() << "\n";
3727   if (left > sizeof(struct objc_method_description_list_t)) {
3728     memcpy(&mdl, r, sizeof(struct objc_method_description_list_t));
3729   } else {
3730     print_indent(indent);
3731     outs() << " objc_method_description_list extends past end of the section\n";
3732     memset(&mdl, '\0', sizeof(struct objc_method_description_list_t));
3733     memcpy(&mdl, r, left);
3734   }
3735   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3736     swapStruct(mdl);
3737
3738   print_indent(indent);
3739   outs() << "        count " << mdl.count << "\n";
3740
3741   list = r + sizeof(struct objc_method_description_list_t);
3742   for (i = 0; i < mdl.count; i++) {
3743     if ((i + 1) * sizeof(struct objc_method_description_t) > left) {
3744       print_indent(indent);
3745       outs() << " remaining list entries extend past the of the section\n";
3746       break;
3747     }
3748     print_indent(indent);
3749     outs() << "        list[" << i << "]\n";
3750     memcpy(&md, list + i * sizeof(struct objc_method_description_t),
3751            sizeof(struct objc_method_description_t));
3752     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3753       swapStruct(md);
3754
3755     print_indent(indent);
3756     outs() << "             name " << format("0x%08" PRIx32, md.name);
3757     if (info->verbose) {
3758       name = get_pointer_32(md.name, offset, xleft, S, info, true);
3759       if (name != nullptr)
3760         outs() << format(" %.*s", xleft, name);
3761       else
3762         outs() << " (not in an __OBJC section)";
3763     }
3764     outs() << "\n";
3765
3766     print_indent(indent);
3767     outs() << "            types " << format("0x%08" PRIx32, md.types);
3768     if (info->verbose) {
3769       name = get_pointer_32(md.types, offset, xleft, S, info, true);
3770       if (name != nullptr)
3771         outs() << format(" %.*s", xleft, name);
3772       else
3773         outs() << " (not in an __OBJC section)";
3774     }
3775     outs() << "\n";
3776   }
3777   return false;
3778 }
3779
3780 static bool print_protocol_list(uint32_t p, uint32_t indent,
3781                                 struct DisassembleInfo *info);
3782
3783 static bool print_protocol(uint32_t p, uint32_t indent,
3784                            struct DisassembleInfo *info) {
3785   uint32_t offset, left;
3786   SectionRef S;
3787   struct objc_protocol_t protocol;
3788   const char *r, *name;
3789
3790   r = get_pointer_32(p, offset, left, S, info, true);
3791   if (r == nullptr)
3792     return true;
3793
3794   outs() << "\n";
3795   if (left >= sizeof(struct objc_protocol_t)) {
3796     memcpy(&protocol, r, sizeof(struct objc_protocol_t));
3797   } else {
3798     print_indent(indent);
3799     outs() << "            Protocol extends past end of the section\n";
3800     memset(&protocol, '\0', sizeof(struct objc_protocol_t));
3801     memcpy(&protocol, r, left);
3802   }
3803   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3804     swapStruct(protocol);
3805
3806   print_indent(indent);
3807   outs() << "              isa " << format("0x%08" PRIx32, protocol.isa)
3808          << "\n";
3809
3810   print_indent(indent);
3811   outs() << "    protocol_name "
3812          << format("0x%08" PRIx32, protocol.protocol_name);
3813   if (info->verbose) {
3814     name = get_pointer_32(protocol.protocol_name, offset, left, S, info, true);
3815     if (name != nullptr)
3816       outs() << format(" %.*s", left, name);
3817     else
3818       outs() << " (not in an __OBJC section)";
3819   }
3820   outs() << "\n";
3821
3822   print_indent(indent);
3823   outs() << "    protocol_list "
3824          << format("0x%08" PRIx32, protocol.protocol_list);
3825   if (print_protocol_list(protocol.protocol_list, indent + 4, info))
3826     outs() << " (not in an __OBJC section)\n";
3827
3828   print_indent(indent);
3829   outs() << " instance_methods "
3830          << format("0x%08" PRIx32, protocol.instance_methods);
3831   if (print_method_description_list(protocol.instance_methods, indent, info))
3832     outs() << " (not in an __OBJC section)\n";
3833
3834   print_indent(indent);
3835   outs() << "    class_methods "
3836          << format("0x%08" PRIx32, protocol.class_methods);
3837   if (print_method_description_list(protocol.class_methods, indent, info))
3838     outs() << " (not in an __OBJC section)\n";
3839
3840   return false;
3841 }
3842
3843 static bool print_protocol_list(uint32_t p, uint32_t indent,
3844                                 struct DisassembleInfo *info) {
3845   uint32_t offset, left, l;
3846   SectionRef S;
3847   struct objc_protocol_list_t protocol_list;
3848   const char *r, *list;
3849   int32_t i;
3850
3851   r = get_pointer_32(p, offset, left, S, info, true);
3852   if (r == nullptr)
3853     return true;
3854
3855   outs() << "\n";
3856   if (left > sizeof(struct objc_protocol_list_t)) {
3857     memcpy(&protocol_list, r, sizeof(struct objc_protocol_list_t));
3858   } else {
3859     outs() << "\t\t objc_protocol_list_t extends past end of the section\n";
3860     memset(&protocol_list, '\0', sizeof(struct objc_protocol_list_t));
3861     memcpy(&protocol_list, r, left);
3862   }
3863   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3864     swapStruct(protocol_list);
3865
3866   print_indent(indent);
3867   outs() << "         next " << format("0x%08" PRIx32, protocol_list.next)
3868          << "\n";
3869   print_indent(indent);
3870   outs() << "        count " << protocol_list.count << "\n";
3871
3872   list = r + sizeof(struct objc_protocol_list_t);
3873   for (i = 0; i < protocol_list.count; i++) {
3874     if ((i + 1) * sizeof(uint32_t) > left) {
3875       outs() << "\t\t remaining list entries extend past the of the section\n";
3876       break;
3877     }
3878     memcpy(&l, list + i * sizeof(uint32_t), sizeof(uint32_t));
3879     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3880       sys::swapByteOrder(l);
3881
3882     print_indent(indent);
3883     outs() << "      list[" << i << "] " << format("0x%08" PRIx32, l);
3884     if (print_protocol(l, indent, info))
3885       outs() << "(not in an __OBJC section)\n";
3886   }
3887   return false;
3888 }
3889
3890 static void print_ivar_list64_t(uint64_t p, struct DisassembleInfo *info) {
3891   struct ivar_list64_t il;
3892   struct ivar64_t i;
3893   const char *r;
3894   uint32_t offset, xoffset, left, j;
3895   SectionRef S, xS;
3896   const char *name, *sym_name, *ivar_offset_p;
3897   uint64_t ivar_offset, n_value;
3898
3899   r = get_pointer_64(p, offset, left, S, info);
3900   if (r == nullptr)
3901     return;
3902   memset(&il, '\0', sizeof(struct ivar_list64_t));
3903   if (left < sizeof(struct ivar_list64_t)) {
3904     memcpy(&il, r, left);
3905     outs() << "   (ivar_list_t entends past the end of the section)\n";
3906   } else
3907     memcpy(&il, r, sizeof(struct ivar_list64_t));
3908   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3909     swapStruct(il);
3910   outs() << "                    entsize " << il.entsize << "\n";
3911   outs() << "                      count " << il.count << "\n";
3912
3913   p += sizeof(struct ivar_list64_t);
3914   offset += sizeof(struct ivar_list64_t);
3915   for (j = 0; j < il.count; j++) {
3916     r = get_pointer_64(p, offset, left, S, info);
3917     if (r == nullptr)
3918       return;
3919     memset(&i, '\0', sizeof(struct ivar64_t));
3920     if (left < sizeof(struct ivar64_t)) {
3921       memcpy(&i, r, left);
3922       outs() << "   (ivar_t entends past the end of the section)\n";
3923     } else
3924       memcpy(&i, r, sizeof(struct ivar64_t));
3925     if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3926       swapStruct(i);
3927
3928     outs() << "\t\t\t   offset ";
3929     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, offset), S,
3930                              info, n_value, i.offset);
3931     if (n_value != 0) {
3932       if (info->verbose && sym_name != nullptr)
3933         outs() << sym_name;
3934       else
3935         outs() << format("0x%" PRIx64, n_value);
3936       if (i.offset != 0)
3937         outs() << " + " << format("0x%" PRIx64, i.offset);
3938     } else
3939       outs() << format("0x%" PRIx64, i.offset);
3940     ivar_offset_p = get_pointer_64(i.offset + n_value, xoffset, left, xS, info);
3941     if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
3942       memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
3943       if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
3944         sys::swapByteOrder(ivar_offset);
3945       outs() << " " << ivar_offset << "\n";
3946     } else
3947       outs() << "\n";
3948
3949     outs() << "\t\t\t     name ";
3950     sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, name), S, info,
3951                              n_value, i.name);
3952     if (n_value != 0) {
3953       if (info->verbose && sym_name != nullptr)
3954         outs() << sym_name;
3955       else
3956         outs() << format("0x%" PRIx64, n_value);
3957       if (i.name != 0)
3958         outs() << " + " << format("0x%" PRIx64, i.name);
3959     } else
3960       outs() << format("0x%" PRIx64, i.name);
3961     name = get_pointer_64(i.name + n_value, xoffset, left, xS, info);
3962     if (name != nullptr)
3963       outs() << format(" %.*s", left, name);
3964     outs() << "\n";
3965
3966