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