Add the option, -no-leading-addr llvm-objdump used with -macho and
[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/DWARF/DIContext.h"
21 #include "llvm/MC/MCAsmInfo.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCDisassembler.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstPrinter.h"
26 #include "llvm/MC/MCInstrDesc.h"
27 #include "llvm/MC/MCInstrInfo.h"
28 #include "llvm/MC/MCRegisterInfo.h"
29 #include "llvm/MC/MCSubtargetInfo.h"
30 #include "llvm/Object/MachO.h"
31 #include "llvm/Object/MachOUniversal.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/CommandLine.h"
34 #include "llvm/Support/Debug.h"
35 #include "llvm/Support/Endian.h"
36 #include "llvm/Support/Format.h"
37 #include "llvm/Support/FormattedStream.h"
38 #include "llvm/Support/GraphWriter.h"
39 #include "llvm/Support/LEB128.h"
40 #include "llvm/Support/MachO.h"
41 #include "llvm/Support/MemoryBuffer.h"
42 #include "llvm/Support/TargetRegistry.h"
43 #include "llvm/Support/TargetSelect.h"
44 #include "llvm/Support/raw_ostream.h"
45 #include <algorithm>
46 #include <cstring>
47 #include <system_error>
48
49 #if HAVE_CXXABI_H
50 #include <cxxabi.h>
51 #endif
52
53 using namespace llvm;
54 using namespace object;
55
56 static cl::opt<bool>
57     UseDbg("g",
58            cl::desc("Print line information from debug info if available"));
59
60 static cl::opt<std::string> DSYMFile("dsym",
61                                      cl::desc("Use .dSYM file for debug info"));
62
63 static cl::opt<bool> FullLeadingAddr("full-leading-addr",
64                                      cl::desc("Print full leading address"));
65
66 static cl::opt<bool> NoLeadingAddr("no-leading-addr",
67                                    cl::desc("Print no leading address"));
68
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>
104     llvm::InfoPlist("info-plist",
105                     cl::desc("Print the info plist section as strings for "
106                              "Mach-O objects (requires -macho)"));
107
108 cl::opt<bool>
109     llvm::DylibsUsed("dylibs-used",
110                      cl::desc("Print the shared libraries used for linked "
111                               "Mach-O files (requires -macho)"));
112
113 cl::opt<bool>
114     llvm::DylibId("dylib-id",
115                   cl::desc("Print the shared library's id for the dylib Mach-O "
116                            "file (requires -macho)"));
117
118 cl::opt<bool>
119     llvm::NonVerbose("non-verbose",
120                      cl::desc("Print the info for Mach-O objects in "
121                               "non-verbose or numeric form (requires -macho)"));
122
123 cl::opt<std::string> llvm::DisSymName(
124     "dis-symname",
125     cl::desc("disassemble just this symbol's instructions (requires -macho"));
126
127 static cl::list<std::string>
128     ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
129               cl::ZeroOrMore);
130 bool ArchAll = false;
131
132 static std::string ThumbTripleName;
133
134 static const Target *GetTarget(const MachOObjectFile *MachOObj,
135                                const char **McpuDefault,
136                                const Target **ThumbTarget) {
137   // Figure out the target triple.
138   if (TripleName.empty()) {
139     llvm::Triple TT("unknown-unknown-unknown");
140     llvm::Triple ThumbTriple = Triple();
141     TT = MachOObj->getArch(McpuDefault, &ThumbTriple);
142     TripleName = TT.str();
143     ThumbTripleName = ThumbTriple.str();
144   }
145
146   // Get the target specific parser.
147   std::string Error;
148   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
149   if (TheTarget && ThumbTripleName.empty())
150     return TheTarget;
151
152   *ThumbTarget = TargetRegistry::lookupTarget(ThumbTripleName, Error);
153   if (*ThumbTarget)
154     return TheTarget;
155
156   errs() << "llvm-objdump: error: unable to get target for '";
157   if (!TheTarget)
158     errs() << TripleName;
159   else
160     errs() << ThumbTripleName;
161   errs() << "', see --version and --triple.\n";
162   return nullptr;
163 }
164
165 struct SymbolSorter {
166   bool operator()(const SymbolRef &A, const SymbolRef &B) {
167     SymbolRef::Type AType, BType;
168     A.getType(AType);
169     B.getType(BType);
170
171     uint64_t AAddr, BAddr;
172     if (AType != SymbolRef::ST_Function)
173       AAddr = 0;
174     else
175       A.getAddress(AAddr);
176     if (BType != SymbolRef::ST_Function)
177       BAddr = 0;
178     else
179       B.getAddress(BAddr);
180     return AAddr < BAddr;
181   }
182 };
183
184 // Types for the storted data in code table that is built before disassembly
185 // and the predicate function to sort them.
186 typedef std::pair<uint64_t, DiceRef> DiceTableEntry;
187 typedef std::vector<DiceTableEntry> DiceTable;
188 typedef DiceTable::iterator dice_table_iterator;
189
190 // This is used to search for a data in code table entry for the PC being
191 // disassembled.  The j parameter has the PC in j.first.  A single data in code
192 // table entry can cover many bytes for each of its Kind's.  So if the offset,
193 // aka the i.first value, of the data in code table entry plus its Length
194 // covers the PC being searched for this will return true.  If not it will
195 // return false.
196 static bool compareDiceTableEntries(const DiceTableEntry &i,
197                                     const DiceTableEntry &j) {
198   uint16_t Length;
199   i.second.getLength(Length);
200
201   return j.first >= i.first && j.first < i.first + Length;
202 }
203
204 static uint64_t DumpDataInCode(const char *bytes, uint64_t Length,
205                                unsigned short Kind) {
206   uint32_t Value, Size = 1;
207
208   switch (Kind) {
209   default:
210   case MachO::DICE_KIND_DATA:
211     if (Length >= 4) {
212       if (!NoShowRawInsn)
213         DumpBytes(StringRef(bytes, 4));
214       Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
215       outs() << "\t.long " << Value;
216       Size = 4;
217     } else if (Length >= 2) {
218       if (!NoShowRawInsn)
219         DumpBytes(StringRef(bytes, 2));
220       Value = bytes[1] << 8 | bytes[0];
221       outs() << "\t.short " << Value;
222       Size = 2;
223     } else {
224       if (!NoShowRawInsn)
225         DumpBytes(StringRef(bytes, 2));
226       Value = bytes[0];
227       outs() << "\t.byte " << Value;
228       Size = 1;
229     }
230     if (Kind == MachO::DICE_KIND_DATA)
231       outs() << "\t@ KIND_DATA\n";
232     else
233       outs() << "\t@ data in code kind = " << Kind << "\n";
234     break;
235   case MachO::DICE_KIND_JUMP_TABLE8:
236     if (!NoShowRawInsn)
237       DumpBytes(StringRef(bytes, 1));
238     Value = bytes[0];
239     outs() << "\t.byte " << format("%3u", Value) << "\t@ KIND_JUMP_TABLE8\n";
240     Size = 1;
241     break;
242   case MachO::DICE_KIND_JUMP_TABLE16:
243     if (!NoShowRawInsn)
244       DumpBytes(StringRef(bytes, 2));
245     Value = bytes[1] << 8 | bytes[0];
246     outs() << "\t.short " << format("%5u", Value & 0xffff)
247            << "\t@ KIND_JUMP_TABLE16\n";
248     Size = 2;
249     break;
250   case MachO::DICE_KIND_JUMP_TABLE32:
251   case MachO::DICE_KIND_ABS_JUMP_TABLE32:
252     if (!NoShowRawInsn)
253       DumpBytes(StringRef(bytes, 4));
254     Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
255     outs() << "\t.long " << Value;
256     if (Kind == MachO::DICE_KIND_JUMP_TABLE32)
257       outs() << "\t@ KIND_JUMP_TABLE32\n";
258     else
259       outs() << "\t@ KIND_ABS_JUMP_TABLE32\n";
260     Size = 4;
261     break;
262   }
263   return Size;
264 }
265
266 static void getSectionsAndSymbols(const MachO::mach_header Header,
267                                   MachOObjectFile *MachOObj,
268                                   std::vector<SectionRef> &Sections,
269                                   std::vector<SymbolRef> &Symbols,
270                                   SmallVectorImpl<uint64_t> &FoundFns,
271                                   uint64_t &BaseSegmentAddress) {
272   for (const SymbolRef &Symbol : MachOObj->symbols()) {
273     StringRef SymName;
274     Symbol.getName(SymName);
275     if (!SymName.startswith("ltmp"))
276       Symbols.push_back(Symbol);
277   }
278
279   for (const SectionRef &Section : MachOObj->sections()) {
280     StringRef SectName;
281     Section.getName(SectName);
282     Sections.push_back(Section);
283   }
284
285   MachOObjectFile::LoadCommandInfo Command =
286       MachOObj->getFirstLoadCommandInfo();
287   bool BaseSegmentAddressSet = false;
288   for (unsigned i = 0;; ++i) {
289     if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
290       // We found a function starts segment, parse the addresses for later
291       // consumption.
292       MachO::linkedit_data_command LLC =
293           MachOObj->getLinkeditDataLoadCommand(Command);
294
295       MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
296     } else if (Command.C.cmd == MachO::LC_SEGMENT) {
297       MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command);
298       StringRef SegName = SLC.segname;
299       if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
300         BaseSegmentAddressSet = true;
301         BaseSegmentAddress = SLC.vmaddr;
302       }
303     }
304
305     if (i == Header.ncmds - 1)
306       break;
307     else
308       Command = MachOObj->getNextLoadCommandInfo(Command);
309   }
310 }
311
312 static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose,
313                                      uint32_t n, uint32_t count,
314                                      uint32_t stride, uint64_t addr) {
315   MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
316   uint32_t nindirectsyms = Dysymtab.nindirectsyms;
317   if (n > nindirectsyms)
318     outs() << " (entries start past the end of the indirect symbol "
319               "table) (reserved1 field greater than the table size)";
320   else if (n + count > nindirectsyms)
321     outs() << " (entries extends past the end of the indirect symbol "
322               "table)";
323   outs() << "\n";
324   uint32_t cputype = O->getHeader().cputype;
325   if (cputype & MachO::CPU_ARCH_ABI64)
326     outs() << "address            index";
327   else
328     outs() << "address    index";
329   if (verbose)
330     outs() << " name\n";
331   else
332     outs() << "\n";
333   for (uint32_t j = 0; j < count && n + j < nindirectsyms; j++) {
334     if (cputype & MachO::CPU_ARCH_ABI64)
335       outs() << format("0x%016" PRIx64, addr + j * stride) << " ";
336     else
337       outs() << format("0x%08" PRIx32, addr + j * stride) << " ";
338     MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
339     uint32_t indirect_symbol = O->getIndirectSymbolTableEntry(Dysymtab, n + j);
340     if (indirect_symbol == MachO::INDIRECT_SYMBOL_LOCAL) {
341       outs() << "LOCAL\n";
342       continue;
343     }
344     if (indirect_symbol ==
345         (MachO::INDIRECT_SYMBOL_LOCAL | MachO::INDIRECT_SYMBOL_ABS)) {
346       outs() << "LOCAL ABSOLUTE\n";
347       continue;
348     }
349     if (indirect_symbol == MachO::INDIRECT_SYMBOL_ABS) {
350       outs() << "ABSOLUTE\n";
351       continue;
352     }
353     outs() << format("%5u ", indirect_symbol);
354     if (verbose) {
355       MachO::symtab_command Symtab = O->getSymtabLoadCommand();
356       if (indirect_symbol < Symtab.nsyms) {
357         symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol);
358         SymbolRef Symbol = *Sym;
359         StringRef SymName;
360         Symbol.getName(SymName);
361         outs() << SymName;
362       } else {
363         outs() << "?";
364       }
365     }
366     outs() << "\n";
367   }
368 }
369
370 static void PrintIndirectSymbols(MachOObjectFile *O, bool verbose) {
371   uint32_t LoadCommandCount = O->getHeader().ncmds;
372   MachOObjectFile::LoadCommandInfo Load = O->getFirstLoadCommandInfo();
373   for (unsigned I = 0;; ++I) {
374     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
375       MachO::segment_command_64 Seg = O->getSegment64LoadCommand(Load);
376       for (unsigned J = 0; J < Seg.nsects; ++J) {
377         MachO::section_64 Sec = O->getSection64(Load, J);
378         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
379         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
380             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
381             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
382             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
383             section_type == MachO::S_SYMBOL_STUBS) {
384           uint32_t stride;
385           if (section_type == MachO::S_SYMBOL_STUBS)
386             stride = Sec.reserved2;
387           else
388             stride = 8;
389           if (stride == 0) {
390             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
391                    << Sec.sectname << ") "
392                    << "(size of stubs in reserved2 field is zero)\n";
393             continue;
394           }
395           uint32_t count = Sec.size / stride;
396           outs() << "Indirect symbols for (" << Sec.segname << ","
397                  << Sec.sectname << ") " << count << " entries";
398           uint32_t n = Sec.reserved1;
399           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
400         }
401       }
402     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
403       MachO::segment_command Seg = O->getSegmentLoadCommand(Load);
404       for (unsigned J = 0; J < Seg.nsects; ++J) {
405         MachO::section Sec = O->getSection(Load, J);
406         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
407         if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
408             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
409             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
410             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
411             section_type == MachO::S_SYMBOL_STUBS) {
412           uint32_t stride;
413           if (section_type == MachO::S_SYMBOL_STUBS)
414             stride = Sec.reserved2;
415           else
416             stride = 4;
417           if (stride == 0) {
418             outs() << "Can't print indirect symbols for (" << Sec.segname << ","
419                    << Sec.sectname << ") "
420                    << "(size of stubs in reserved2 field is zero)\n";
421             continue;
422           }
423           uint32_t count = Sec.size / stride;
424           outs() << "Indirect symbols for (" << Sec.segname << ","
425                  << Sec.sectname << ") " << count << " entries";
426           uint32_t n = Sec.reserved1;
427           PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
428         }
429       }
430     }
431     if (I == LoadCommandCount - 1)
432       break;
433     else
434       Load = O->getNextLoadCommandInfo(Load);
435   }
436 }
437
438 static void PrintDataInCodeTable(MachOObjectFile *O, bool verbose) {
439   MachO::linkedit_data_command DIC = O->getDataInCodeLoadCommand();
440   uint32_t nentries = DIC.datasize / sizeof(struct MachO::data_in_code_entry);
441   outs() << "Data in code table (" << nentries << " entries)\n";
442   outs() << "offset     length kind\n";
443   for (dice_iterator DI = O->begin_dices(), DE = O->end_dices(); DI != DE;
444        ++DI) {
445     uint32_t Offset;
446     DI->getOffset(Offset);
447     outs() << format("0x%08" PRIx32, Offset) << " ";
448     uint16_t Length;
449     DI->getLength(Length);
450     outs() << format("%6u", Length) << " ";
451     uint16_t Kind;
452     DI->getKind(Kind);
453     if (verbose) {
454       switch (Kind) {
455       case MachO::DICE_KIND_DATA:
456         outs() << "DATA";
457         break;
458       case MachO::DICE_KIND_JUMP_TABLE8:
459         outs() << "JUMP_TABLE8";
460         break;
461       case MachO::DICE_KIND_JUMP_TABLE16:
462         outs() << "JUMP_TABLE16";
463         break;
464       case MachO::DICE_KIND_JUMP_TABLE32:
465         outs() << "JUMP_TABLE32";
466         break;
467       case MachO::DICE_KIND_ABS_JUMP_TABLE32:
468         outs() << "ABS_JUMP_TABLE32";
469         break;
470       default:
471         outs() << format("0x%04" PRIx32, Kind);
472         break;
473       }
474     } else
475       outs() << format("0x%04" PRIx32, Kind);
476     outs() << "\n";
477   }
478 }
479
480 static void PrintLinkOptHints(MachOObjectFile *O) {
481   MachO::linkedit_data_command LohLC = O->getLinkOptHintsLoadCommand();
482   const char *loh = O->getData().substr(LohLC.dataoff, 1).data();
483   uint32_t nloh = LohLC.datasize;
484   outs() << "Linker optimiztion hints (" << nloh << " total bytes)\n";
485   for (uint32_t i = 0; i < nloh;) {
486     unsigned n;
487     uint64_t identifier = decodeULEB128((const uint8_t *)(loh + i), &n);
488     i += n;
489     outs() << "    identifier " << identifier << " ";
490     if (i >= nloh)
491       return;
492     switch (identifier) {
493     case 1:
494       outs() << "AdrpAdrp\n";
495       break;
496     case 2:
497       outs() << "AdrpLdr\n";
498       break;
499     case 3:
500       outs() << "AdrpAddLdr\n";
501       break;
502     case 4:
503       outs() << "AdrpLdrGotLdr\n";
504       break;
505     case 5:
506       outs() << "AdrpAddStr\n";
507       break;
508     case 6:
509       outs() << "AdrpLdrGotStr\n";
510       break;
511     case 7:
512       outs() << "AdrpAdd\n";
513       break;
514     case 8:
515       outs() << "AdrpLdrGot\n";
516       break;
517     default:
518       outs() << "Unknown identifier value\n";
519       break;
520     }
521     uint64_t narguments = decodeULEB128((const uint8_t *)(loh + i), &n);
522     i += n;
523     outs() << "    narguments " << narguments << "\n";
524     if (i >= nloh)
525       return;
526
527     for (uint32_t j = 0; j < narguments; j++) {
528       uint64_t value = decodeULEB128((const uint8_t *)(loh + i), &n);
529       i += n;
530       outs() << "\tvalue " << format("0x%" PRIx64, value) << "\n";
531       if (i >= nloh)
532         return;
533     }
534   }
535 }
536
537 static void PrintDylibs(MachOObjectFile *O, bool JustId) {
538   uint32_t LoadCommandCount = O->getHeader().ncmds;
539   MachOObjectFile::LoadCommandInfo Load = O->getFirstLoadCommandInfo();
540   for (unsigned I = 0;; ++I) {
541     if ((JustId && Load.C.cmd == MachO::LC_ID_DYLIB) ||
542         (!JustId && (Load.C.cmd == MachO::LC_ID_DYLIB ||
543                      Load.C.cmd == MachO::LC_LOAD_DYLIB ||
544                      Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
545                      Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
546                      Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
547                      Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB))) {
548       MachO::dylib_command dl = O->getDylibIDLoadCommand(Load);
549       if (dl.dylib.name < dl.cmdsize) {
550         const char *p = (const char *)(Load.Ptr) + dl.dylib.name;
551         if (JustId)
552           outs() << p << "\n";
553         else {
554           outs() << "\t" << p;
555           outs() << " (compatibility version "
556                  << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
557                  << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
558                  << (dl.dylib.compatibility_version & 0xff) << ",";
559           outs() << " current version "
560                  << ((dl.dylib.current_version >> 16) & 0xffff) << "."
561                  << ((dl.dylib.current_version >> 8) & 0xff) << "."
562                  << (dl.dylib.current_version & 0xff) << ")\n";
563         }
564       } else {
565         outs() << "\tBad offset (" << dl.dylib.name << ") for name of ";
566         if (Load.C.cmd == MachO::LC_ID_DYLIB)
567           outs() << "LC_ID_DYLIB ";
568         else if (Load.C.cmd == MachO::LC_LOAD_DYLIB)
569           outs() << "LC_LOAD_DYLIB ";
570         else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB)
571           outs() << "LC_LOAD_WEAK_DYLIB ";
572         else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB)
573           outs() << "LC_LAZY_LOAD_DYLIB ";
574         else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB)
575           outs() << "LC_REEXPORT_DYLIB ";
576         else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
577           outs() << "LC_LOAD_UPWARD_DYLIB ";
578         else
579           outs() << "LC_??? ";
580         outs() << "command " << I << "\n";
581       }
582     }
583     if (I == LoadCommandCount - 1)
584       break;
585     else
586       Load = O->getNextLoadCommandInfo(Load);
587   }
588 }
589
590 typedef DenseMap<uint64_t, StringRef> SymbolAddressMap;
591
592 static void CreateSymbolAddressMap(MachOObjectFile *O,
593                                    SymbolAddressMap *AddrMap) {
594   // Create a map of symbol addresses to symbol names.
595   for (const SymbolRef &Symbol : O->symbols()) {
596     SymbolRef::Type ST;
597     Symbol.getType(ST);
598     if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
599         ST == SymbolRef::ST_Other) {
600       uint64_t Address;
601       Symbol.getAddress(Address);
602       StringRef SymName;
603       Symbol.getName(SymName);
604       (*AddrMap)[Address] = SymName;
605     }
606   }
607 }
608
609 // GuessSymbolName is passed the address of what might be a symbol and a
610 // pointer to the SymbolAddressMap.  It returns the name of a symbol
611 // with that address or nullptr if no symbol is found with that address.
612 static const char *GuessSymbolName(uint64_t value, SymbolAddressMap *AddrMap) {
613   const char *SymbolName = nullptr;
614   // A DenseMap can't lookup up some values.
615   if (value != 0xffffffffffffffffULL && value != 0xfffffffffffffffeULL) {
616     StringRef name = AddrMap->lookup(value);
617     if (!name.empty())
618       SymbolName = name.data();
619   }
620   return SymbolName;
621 }
622
623 static void DumpCstringChar(const char c) {
624   char p[2];
625   p[0] = c;
626   p[1] = '\0';
627   outs().write_escaped(p);
628 }
629
630 static void DumpCstringSection(MachOObjectFile *O, const char *sect,
631                                uint32_t sect_size, uint64_t sect_addr,
632                                bool print_addresses) {
633   for (uint32_t i = 0; i < sect_size; i++) {
634     if (print_addresses) {
635       if (O->is64Bit())
636         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
637       else
638         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
639     }
640     for (; i < sect_size && sect[i] != '\0'; i++)
641       DumpCstringChar(sect[i]);
642     if (i < sect_size && sect[i] == '\0')
643       outs() << "\n";
644   }
645 }
646
647 static void DumpLiteral4(uint32_t l, float f) {
648   outs() << format("0x%08" PRIx32, l);
649   if ((l & 0x7f800000) != 0x7f800000)
650     outs() << format(" (%.16e)\n", f);
651   else {
652     if (l == 0x7f800000)
653       outs() << " (+Infinity)\n";
654     else if (l == 0xff800000)
655       outs() << " (-Infinity)\n";
656     else if ((l & 0x00400000) == 0x00400000)
657       outs() << " (non-signaling Not-a-Number)\n";
658     else
659       outs() << " (signaling Not-a-Number)\n";
660   }
661 }
662
663 static void DumpLiteral4Section(MachOObjectFile *O, const char *sect,
664                                 uint32_t sect_size, uint64_t sect_addr,
665                                 bool print_addresses) {
666   for (uint32_t i = 0; i < sect_size; i += sizeof(float)) {
667     if (print_addresses) {
668       if (O->is64Bit())
669         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
670       else
671         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
672     }
673     float f;
674     memcpy(&f, sect + i, sizeof(float));
675     if (O->isLittleEndian() != sys::IsLittleEndianHost)
676       sys::swapByteOrder(f);
677     uint32_t l;
678     memcpy(&l, sect + i, sizeof(uint32_t));
679     if (O->isLittleEndian() != sys::IsLittleEndianHost)
680       sys::swapByteOrder(l);
681     DumpLiteral4(l, f);
682   }
683 }
684
685 static void DumpLiteral8(MachOObjectFile *O, uint32_t l0, uint32_t l1,
686                          double d) {
687   outs() << format("0x%08" PRIx32, l0) << " " << format("0x%08" PRIx32, l1);
688   uint32_t Hi, Lo;
689   if (O->isLittleEndian()) {
690     Hi = l1;
691     Lo = l0;
692   } else {
693     Hi = l0;
694     Lo = l1;
695   }
696   // Hi is the high word, so this is equivalent to if(isfinite(d))
697   if ((Hi & 0x7ff00000) != 0x7ff00000)
698     outs() << format(" (%.16e)\n", d);
699   else {
700     if (Hi == 0x7ff00000 && Lo == 0)
701       outs() << " (+Infinity)\n";
702     else if (Hi == 0xfff00000 && Lo == 0)
703       outs() << " (-Infinity)\n";
704     else if ((Hi & 0x00080000) == 0x00080000)
705       outs() << " (non-signaling Not-a-Number)\n";
706     else
707       outs() << " (signaling Not-a-Number)\n";
708   }
709 }
710
711 static void DumpLiteral8Section(MachOObjectFile *O, const char *sect,
712                                 uint32_t sect_size, uint64_t sect_addr,
713                                 bool print_addresses) {
714   for (uint32_t i = 0; i < sect_size; i += sizeof(double)) {
715     if (print_addresses) {
716       if (O->is64Bit())
717         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
718       else
719         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
720     }
721     double d;
722     memcpy(&d, sect + i, sizeof(double));
723     if (O->isLittleEndian() != sys::IsLittleEndianHost)
724       sys::swapByteOrder(d);
725     uint32_t l0, l1;
726     memcpy(&l0, sect + i, sizeof(uint32_t));
727     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
728     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
729       sys::swapByteOrder(l0);
730       sys::swapByteOrder(l1);
731     }
732     DumpLiteral8(O, l0, l1, d);
733   }
734 }
735
736 static void DumpLiteral16(uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3) {
737   outs() << format("0x%08" PRIx32, l0) << " ";
738   outs() << format("0x%08" PRIx32, l1) << " ";
739   outs() << format("0x%08" PRIx32, l2) << " ";
740   outs() << format("0x%08" PRIx32, l3) << "\n";
741 }
742
743 static void DumpLiteral16Section(MachOObjectFile *O, const char *sect,
744                                  uint32_t sect_size, uint64_t sect_addr,
745                                  bool print_addresses) {
746   for (uint32_t i = 0; i < sect_size; i += 16) {
747     if (print_addresses) {
748       if (O->is64Bit())
749         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
750       else
751         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
752     }
753     uint32_t l0, l1, l2, l3;
754     memcpy(&l0, sect + i, sizeof(uint32_t));
755     memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
756     memcpy(&l2, sect + i + 2 * sizeof(uint32_t), sizeof(uint32_t));
757     memcpy(&l3, sect + i + 3 * sizeof(uint32_t), sizeof(uint32_t));
758     if (O->isLittleEndian() != sys::IsLittleEndianHost) {
759       sys::swapByteOrder(l0);
760       sys::swapByteOrder(l1);
761       sys::swapByteOrder(l2);
762       sys::swapByteOrder(l3);
763     }
764     DumpLiteral16(l0, l1, l2, l3);
765   }
766 }
767
768 static void DumpLiteralPointerSection(MachOObjectFile *O,
769                                       const SectionRef &Section,
770                                       const char *sect, uint32_t sect_size,
771                                       uint64_t sect_addr,
772                                       bool print_addresses) {
773   // Collect the literal sections in this Mach-O file.
774   std::vector<SectionRef> LiteralSections;
775   for (const SectionRef &Section : O->sections()) {
776     DataRefImpl Ref = Section.getRawDataRefImpl();
777     uint32_t section_type;
778     if (O->is64Bit()) {
779       const MachO::section_64 Sec = O->getSection64(Ref);
780       section_type = Sec.flags & MachO::SECTION_TYPE;
781     } else {
782       const MachO::section Sec = O->getSection(Ref);
783       section_type = Sec.flags & MachO::SECTION_TYPE;
784     }
785     if (section_type == MachO::S_CSTRING_LITERALS ||
786         section_type == MachO::S_4BYTE_LITERALS ||
787         section_type == MachO::S_8BYTE_LITERALS ||
788         section_type == MachO::S_16BYTE_LITERALS)
789       LiteralSections.push_back(Section);
790   }
791
792   // Set the size of the literal pointer.
793   uint32_t lp_size = O->is64Bit() ? 8 : 4;
794
795   // Collect the external relocation symbols for the the literal pointers.
796   std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
797   for (const RelocationRef &Reloc : Section.relocations()) {
798     DataRefImpl Rel;
799     MachO::any_relocation_info RE;
800     bool isExtern = false;
801     Rel = Reloc.getRawDataRefImpl();
802     RE = O->getRelocation(Rel);
803     isExtern = O->getPlainRelocationExternal(RE);
804     if (isExtern) {
805       uint64_t RelocOffset;
806       Reloc.getOffset(RelocOffset);
807       symbol_iterator RelocSym = Reloc.getSymbol();
808       Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
809     }
810   }
811   array_pod_sort(Relocs.begin(), Relocs.end());
812
813   // Dump each literal pointer.
814   for (uint32_t i = 0; i < sect_size; i += lp_size) {
815     if (print_addresses) {
816       if (O->is64Bit())
817         outs() << format("%016" PRIx64, sect_addr + i) << "  ";
818       else
819         outs() << format("%08" PRIx64, sect_addr + i) << "  ";
820     }
821     uint64_t lp;
822     if (O->is64Bit()) {
823       memcpy(&lp, sect + i, sizeof(uint64_t));
824       if (O->isLittleEndian() != sys::IsLittleEndianHost)
825         sys::swapByteOrder(lp);
826     } else {
827       uint32_t li;
828       memcpy(&li, sect + i, sizeof(uint32_t));
829       if (O->isLittleEndian() != sys::IsLittleEndianHost)
830         sys::swapByteOrder(li);
831       lp = li;
832     }
833
834     // First look for an external relocation entry for this literal pointer.
835     bool reloc_found = false;
836     for (unsigned j = 0, e = Relocs.size(); j != e; ++j) {
837       if (Relocs[i].first == i) {
838         symbol_iterator RelocSym = Relocs[j].second;
839         StringRef SymName;
840         RelocSym->getName(SymName);
841         outs() << "external relocation entry for symbol:" << SymName << "\n";
842         reloc_found = true;
843       }
844     }
845     if (reloc_found == true)
846       continue;
847
848     // For local references see what the section the literal pointer points to.
849     bool found = false;
850     for (unsigned SectIdx = 0; SectIdx != LiteralSections.size(); SectIdx++) {
851       uint64_t SectAddress = LiteralSections[SectIdx].getAddress();
852       uint64_t SectSize = LiteralSections[SectIdx].getSize();
853       if (lp >= SectAddress && lp < SectAddress + SectSize) {
854         found = true;
855
856         StringRef SectName;
857         LiteralSections[SectIdx].getName(SectName);
858         DataRefImpl Ref = LiteralSections[SectIdx].getRawDataRefImpl();
859         StringRef SegmentName = O->getSectionFinalSegmentName(Ref);
860         outs() << SegmentName << ":" << SectName << ":";
861
862         uint32_t section_type;
863         if (O->is64Bit()) {
864           const MachO::section_64 Sec = O->getSection64(Ref);
865           section_type = Sec.flags & MachO::SECTION_TYPE;
866         } else {
867           const MachO::section Sec = O->getSection(Ref);
868           section_type = Sec.flags & MachO::SECTION_TYPE;
869         }
870
871         StringRef BytesStr;
872         LiteralSections[SectIdx].getContents(BytesStr);
873         const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
874
875         switch (section_type) {
876         case MachO::S_CSTRING_LITERALS:
877           for (uint64_t i = lp - SectAddress;
878                i < SectSize && Contents[i] != '\0'; i++) {
879             DumpCstringChar(Contents[i]);
880           }
881           outs() << "\n";
882           break;
883         case MachO::S_4BYTE_LITERALS:
884           float f;
885           memcpy(&f, Contents + (lp - SectAddress), sizeof(float));
886           uint32_t l;
887           memcpy(&l, Contents + (lp - SectAddress), sizeof(uint32_t));
888           if (O->isLittleEndian() != sys::IsLittleEndianHost) {
889             sys::swapByteOrder(f);
890             sys::swapByteOrder(l);
891           }
892           DumpLiteral4(l, f);
893           break;
894         case MachO::S_8BYTE_LITERALS: {
895           double d;
896           memcpy(&d, Contents + (lp - SectAddress), sizeof(double));
897           uint32_t l0, l1;
898           memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
899           memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
900                  sizeof(uint32_t));
901           if (O->isLittleEndian() != sys::IsLittleEndianHost) {
902             sys::swapByteOrder(f);
903             sys::swapByteOrder(l0);
904             sys::swapByteOrder(l1);
905           }
906           DumpLiteral8(O, l0, l1, d);
907           break;
908         }
909         case MachO::S_16BYTE_LITERALS: {
910           uint32_t l0, l1, l2, l3;
911           memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
912           memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
913                  sizeof(uint32_t));
914           memcpy(&l2, Contents + (lp - SectAddress) + 2 * sizeof(uint32_t),
915                  sizeof(uint32_t));
916           memcpy(&l3, Contents + (lp - SectAddress) + 3 * sizeof(uint32_t),
917                  sizeof(uint32_t));
918           if (O->isLittleEndian() != sys::IsLittleEndianHost) {
919             sys::swapByteOrder(l0);
920             sys::swapByteOrder(l1);
921             sys::swapByteOrder(l2);
922             sys::swapByteOrder(l3);
923           }
924           DumpLiteral16(l0, l1, l2, l3);
925           break;
926         }
927         }
928       }
929     }
930     if (found == false)
931       outs() << format("0x%" PRIx64, lp) << " (not in a literal section)\n";
932   }
933 }
934
935 static void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect,
936                                        uint32_t sect_size, uint64_t sect_addr,
937                                        SymbolAddressMap *AddrMap,
938                                        bool verbose) {
939   uint32_t stride;
940   if (O->is64Bit())
941     stride = sizeof(uint64_t);
942   else
943     stride = sizeof(uint32_t);
944   for (uint32_t i = 0; i < sect_size; i += stride) {
945     const char *SymbolName = nullptr;
946     if (O->is64Bit()) {
947       outs() << format("0x%016" PRIx64, sect_addr + i * stride) << " ";
948       uint64_t pointer_value;
949       memcpy(&pointer_value, sect + i, stride);
950       if (O->isLittleEndian() != sys::IsLittleEndianHost)
951         sys::swapByteOrder(pointer_value);
952       outs() << format("0x%016" PRIx64, pointer_value);
953       if (verbose)
954         SymbolName = GuessSymbolName(pointer_value, AddrMap);
955     } else {
956       outs() << format("0x%08" PRIx64, sect_addr + i * stride) << " ";
957       uint32_t pointer_value;
958       memcpy(&pointer_value, sect + i, stride);
959       if (O->isLittleEndian() != sys::IsLittleEndianHost)
960         sys::swapByteOrder(pointer_value);
961       outs() << format("0x%08" PRIx32, pointer_value);
962       if (verbose)
963         SymbolName = GuessSymbolName(pointer_value, AddrMap);
964     }
965     if (SymbolName)
966       outs() << " " << SymbolName;
967     outs() << "\n";
968   }
969 }
970
971 static void DumpRawSectionContents(MachOObjectFile *O, const char *sect,
972                                    uint32_t size, uint64_t addr) {
973   uint32_t cputype = O->getHeader().cputype;
974   if (cputype == MachO::CPU_TYPE_I386 || cputype == MachO::CPU_TYPE_X86_64) {
975     uint32_t j;
976     for (uint32_t i = 0; i < size; i += j, addr += j) {
977       if (O->is64Bit())
978         outs() << format("%016" PRIx64, addr) << "\t";
979       else
980         outs() << format("%08" PRIx64, addr) << "\t";
981       for (j = 0; j < 16 && i + j < size; j++) {
982         uint8_t byte_word = *(sect + i + j);
983         outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
984       }
985       outs() << "\n";
986     }
987   } else {
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, sect) << "\t";
994       for (j = 0; j < 4 * sizeof(int32_t) && i + j < size;
995            j += sizeof(int32_t)) {
996         if (i + j + sizeof(int32_t) < size) {
997           uint32_t long_word;
998           memcpy(&long_word, sect + i + j, sizeof(int32_t));
999           if (O->isLittleEndian() != sys::IsLittleEndianHost)
1000             sys::swapByteOrder(long_word);
1001           outs() << format("%08" PRIx32, long_word) << " ";
1002         } else {
1003           for (uint32_t k = 0; i + j + k < size; k++) {
1004             uint8_t byte_word = *(sect + i + j);
1005             outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
1006           }
1007         }
1008       }
1009       outs() << "\n";
1010     }
1011   }
1012 }
1013
1014 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
1015                              StringRef DisSegName, StringRef DisSectName);
1016
1017 static void DumpSectionContents(StringRef Filename, MachOObjectFile *O,
1018                                 bool verbose) {
1019   SymbolAddressMap AddrMap;
1020   if (verbose)
1021     CreateSymbolAddressMap(O, &AddrMap);
1022
1023   for (unsigned i = 0; i < DumpSections.size(); ++i) {
1024     StringRef DumpSection = DumpSections[i];
1025     std::pair<StringRef, StringRef> DumpSegSectName;
1026     DumpSegSectName = DumpSection.split(',');
1027     StringRef DumpSegName, DumpSectName;
1028     if (DumpSegSectName.second.size()) {
1029       DumpSegName = DumpSegSectName.first;
1030       DumpSectName = DumpSegSectName.second;
1031     } else {
1032       DumpSegName = "";
1033       DumpSectName = DumpSegSectName.first;
1034     }
1035     for (const SectionRef &Section : O->sections()) {
1036       StringRef SectName;
1037       Section.getName(SectName);
1038       DataRefImpl Ref = Section.getRawDataRefImpl();
1039       StringRef SegName = O->getSectionFinalSegmentName(Ref);
1040       if ((DumpSegName.empty() || SegName == DumpSegName) &&
1041           (SectName == DumpSectName)) {
1042         outs() << "Contents of (" << SegName << "," << SectName
1043                << ") section\n";
1044         uint32_t section_flags;
1045         if (O->is64Bit()) {
1046           const MachO::section_64 Sec = O->getSection64(Ref);
1047           section_flags = Sec.flags;
1048
1049         } else {
1050           const MachO::section Sec = O->getSection(Ref);
1051           section_flags = Sec.flags;
1052         }
1053         uint32_t section_type = section_flags & MachO::SECTION_TYPE;
1054
1055         StringRef BytesStr;
1056         Section.getContents(BytesStr);
1057         const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1058         uint32_t sect_size = BytesStr.size();
1059         uint64_t sect_addr = Section.getAddress();
1060
1061         if (verbose) {
1062           if ((section_flags & MachO::S_ATTR_PURE_INSTRUCTIONS) ||
1063               (section_flags & MachO::S_ATTR_SOME_INSTRUCTIONS)) {
1064             DisassembleMachO(Filename, O, SegName, SectName);
1065             continue;
1066           }
1067           if (SegName == "__TEXT" && SectName == "__info_plist") {
1068             outs() << sect;
1069             continue;
1070           }
1071           switch (section_type) {
1072           case MachO::S_REGULAR:
1073             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1074             break;
1075           case MachO::S_ZEROFILL:
1076             outs() << "zerofill section and has no contents in the file\n";
1077             break;
1078           case MachO::S_CSTRING_LITERALS:
1079             DumpCstringSection(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1080             break;
1081           case MachO::S_4BYTE_LITERALS:
1082             DumpLiteral4Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1083             break;
1084           case MachO::S_8BYTE_LITERALS:
1085             DumpLiteral8Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1086             break;
1087           case MachO::S_16BYTE_LITERALS:
1088             DumpLiteral16Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1089             break;
1090           case MachO::S_LITERAL_POINTERS:
1091             DumpLiteralPointerSection(O, Section, sect, sect_size, sect_addr,
1092                                       !NoLeadingAddr);
1093             break;
1094           case MachO::S_MOD_INIT_FUNC_POINTERS:
1095           case MachO::S_MOD_TERM_FUNC_POINTERS:
1096             DumpInitTermPointerSection(O, sect, sect_size, sect_addr, &AddrMap,
1097                                        verbose);
1098             break;
1099           default:
1100             outs() << "Unknown section type ("
1101                    << format("0x%08" PRIx32, section_type) << ")\n";
1102             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1103             break;
1104           }
1105         } else {
1106           if (section_type == MachO::S_ZEROFILL)
1107             outs() << "zerofill section and has no contents in the file\n";
1108           else
1109             DumpRawSectionContents(O, sect, sect_size, sect_addr);
1110         }
1111       }
1112     }
1113   }
1114 }
1115
1116 static void DumpInfoPlistSectionContents(StringRef Filename,
1117                                          MachOObjectFile *O) {
1118   for (const SectionRef &Section : O->sections()) {
1119     StringRef SectName;
1120     Section.getName(SectName);
1121     DataRefImpl Ref = Section.getRawDataRefImpl();
1122     StringRef SegName = O->getSectionFinalSegmentName(Ref);
1123     if (SegName == "__TEXT" && SectName == "__info_plist") {
1124       outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
1125       StringRef BytesStr;
1126       Section.getContents(BytesStr);
1127       const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1128       outs() << sect;
1129       return;
1130     }
1131   }
1132 }
1133
1134 // checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file
1135 // and if it is and there is a list of architecture flags is specified then
1136 // check to make sure this Mach-O file is one of those architectures or all
1137 // architectures were specified.  If not then an error is generated and this
1138 // routine returns false.  Else it returns true.
1139 static bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) {
1140   if (isa<MachOObjectFile>(O) && !ArchAll && ArchFlags.size() != 0) {
1141     MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O);
1142     bool ArchFound = false;
1143     MachO::mach_header H;
1144     MachO::mach_header_64 H_64;
1145     Triple T;
1146     if (MachO->is64Bit()) {
1147       H_64 = MachO->MachOObjectFile::getHeader64();
1148       T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype);
1149     } else {
1150       H = MachO->MachOObjectFile::getHeader();
1151       T = MachOObjectFile::getArch(H.cputype, H.cpusubtype);
1152     }
1153     unsigned i;
1154     for (i = 0; i < ArchFlags.size(); ++i) {
1155       if (ArchFlags[i] == T.getArchName())
1156         ArchFound = true;
1157       break;
1158     }
1159     if (!ArchFound) {
1160       errs() << "llvm-objdump: file: " + Filename + " does not contain "
1161              << "architecture: " + ArchFlags[i] + "\n";
1162       return false;
1163     }
1164   }
1165   return true;
1166 }
1167
1168 // ProcessMachO() is passed a single opened Mach-O file, which may be an
1169 // archive member and or in a slice of a universal file.  It prints the
1170 // the file name and header info and then processes it according to the
1171 // command line options.
1172 static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF,
1173                          StringRef ArchiveMemberName = StringRef(),
1174                          StringRef ArchitectureName = StringRef()) {
1175   // If we are doing some processing here on the Mach-O file print the header
1176   // info.  And don't print it otherwise like in the case of printing the
1177   // UniversalHeaders or ArchiveHeaders.
1178   if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind ||
1179       LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints ||
1180       DylibsUsed || DylibId || DumpSections.size() != 0) {
1181     outs() << Filename;
1182     if (!ArchiveMemberName.empty())
1183       outs() << '(' << ArchiveMemberName << ')';
1184     if (!ArchitectureName.empty())
1185       outs() << " (architecture " << ArchitectureName << ")";
1186     outs() << ":\n";
1187   }
1188
1189   if (Disassemble)
1190     DisassembleMachO(Filename, MachOOF, "__TEXT", "__text");
1191   if (IndirectSymbols)
1192     PrintIndirectSymbols(MachOOF, !NonVerbose);
1193   if (DataInCode)
1194     PrintDataInCodeTable(MachOOF, !NonVerbose);
1195   if (LinkOptHints)
1196     PrintLinkOptHints(MachOOF);
1197   if (Relocations)
1198     PrintRelocations(MachOOF);
1199   if (SectionHeaders)
1200     PrintSectionHeaders(MachOOF);
1201   if (SectionContents)
1202     PrintSectionContents(MachOOF);
1203   if (DumpSections.size() != 0)
1204     DumpSectionContents(Filename, MachOOF, !NonVerbose);
1205   if (InfoPlist)
1206     DumpInfoPlistSectionContents(Filename, MachOOF);
1207   if (DylibsUsed)
1208     PrintDylibs(MachOOF, false);
1209   if (DylibId)
1210     PrintDylibs(MachOOF, true);
1211   if (SymbolTable)
1212     PrintSymbolTable(MachOOF);
1213   if (UnwindInfo)
1214     printMachOUnwindInfo(MachOOF);
1215   if (PrivateHeaders)
1216     printMachOFileHeader(MachOOF);
1217   if (ExportsTrie)
1218     printExportsTrie(MachOOF);
1219   if (Rebase)
1220     printRebaseTable(MachOOF);
1221   if (Bind)
1222     printBindTable(MachOOF);
1223   if (LazyBind)
1224     printLazyBindTable(MachOOF);
1225   if (WeakBind)
1226     printWeakBindTable(MachOOF);
1227 }
1228
1229 // printUnknownCPUType() helps print_fat_headers for unknown CPU's.
1230 static void printUnknownCPUType(uint32_t cputype, uint32_t cpusubtype) {
1231   outs() << "    cputype (" << cputype << ")\n";
1232   outs() << "    cpusubtype (" << cpusubtype << ")\n";
1233 }
1234
1235 // printCPUType() helps print_fat_headers by printing the cputype and
1236 // pusubtype (symbolically for the one's it knows about).
1237 static void printCPUType(uint32_t cputype, uint32_t cpusubtype) {
1238   switch (cputype) {
1239   case MachO::CPU_TYPE_I386:
1240     switch (cpusubtype) {
1241     case MachO::CPU_SUBTYPE_I386_ALL:
1242       outs() << "    cputype CPU_TYPE_I386\n";
1243       outs() << "    cpusubtype CPU_SUBTYPE_I386_ALL\n";
1244       break;
1245     default:
1246       printUnknownCPUType(cputype, cpusubtype);
1247       break;
1248     }
1249     break;
1250   case MachO::CPU_TYPE_X86_64:
1251     switch (cpusubtype) {
1252     case MachO::CPU_SUBTYPE_X86_64_ALL:
1253       outs() << "    cputype CPU_TYPE_X86_64\n";
1254       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_ALL\n";
1255       break;
1256     case MachO::CPU_SUBTYPE_X86_64_H:
1257       outs() << "    cputype CPU_TYPE_X86_64\n";
1258       outs() << "    cpusubtype CPU_SUBTYPE_X86_64_H\n";
1259       break;
1260     default:
1261       printUnknownCPUType(cputype, cpusubtype);
1262       break;
1263     }
1264     break;
1265   case MachO::CPU_TYPE_ARM:
1266     switch (cpusubtype) {
1267     case MachO::CPU_SUBTYPE_ARM_ALL:
1268       outs() << "    cputype CPU_TYPE_ARM\n";
1269       outs() << "    cpusubtype CPU_SUBTYPE_ARM_ALL\n";
1270       break;
1271     case MachO::CPU_SUBTYPE_ARM_V4T:
1272       outs() << "    cputype CPU_TYPE_ARM\n";
1273       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V4T\n";
1274       break;
1275     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1276       outs() << "    cputype CPU_TYPE_ARM\n";
1277       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n";
1278       break;
1279     case MachO::CPU_SUBTYPE_ARM_XSCALE:
1280       outs() << "    cputype CPU_TYPE_ARM\n";
1281       outs() << "    cpusubtype CPU_SUBTYPE_ARM_XSCALE\n";
1282       break;
1283     case MachO::CPU_SUBTYPE_ARM_V6:
1284       outs() << "    cputype CPU_TYPE_ARM\n";
1285       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6\n";
1286       break;
1287     case MachO::CPU_SUBTYPE_ARM_V6M:
1288       outs() << "    cputype CPU_TYPE_ARM\n";
1289       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6M\n";
1290       break;
1291     case MachO::CPU_SUBTYPE_ARM_V7:
1292       outs() << "    cputype CPU_TYPE_ARM\n";
1293       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7\n";
1294       break;
1295     case MachO::CPU_SUBTYPE_ARM_V7EM:
1296       outs() << "    cputype CPU_TYPE_ARM\n";
1297       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7EM\n";
1298       break;
1299     case MachO::CPU_SUBTYPE_ARM_V7K:
1300       outs() << "    cputype CPU_TYPE_ARM\n";
1301       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7K\n";
1302       break;
1303     case MachO::CPU_SUBTYPE_ARM_V7M:
1304       outs() << "    cputype CPU_TYPE_ARM\n";
1305       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7M\n";
1306       break;
1307     case MachO::CPU_SUBTYPE_ARM_V7S:
1308       outs() << "    cputype CPU_TYPE_ARM\n";
1309       outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7S\n";
1310       break;
1311     default:
1312       printUnknownCPUType(cputype, cpusubtype);
1313       break;
1314     }
1315     break;
1316   case MachO::CPU_TYPE_ARM64:
1317     switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
1318     case MachO::CPU_SUBTYPE_ARM64_ALL:
1319       outs() << "    cputype CPU_TYPE_ARM64\n";
1320       outs() << "    cpusubtype CPU_SUBTYPE_ARM64_ALL\n";
1321       break;
1322     default:
1323       printUnknownCPUType(cputype, cpusubtype);
1324       break;
1325     }
1326     break;
1327   default:
1328     printUnknownCPUType(cputype, cpusubtype);
1329     break;
1330   }
1331 }
1332
1333 static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB,
1334                                        bool verbose) {
1335   outs() << "Fat headers\n";
1336   if (verbose)
1337     outs() << "fat_magic FAT_MAGIC\n";
1338   else
1339     outs() << "fat_magic " << format("0x%" PRIx32, MachO::FAT_MAGIC) << "\n";
1340
1341   uint32_t nfat_arch = UB->getNumberOfObjects();
1342   StringRef Buf = UB->getData();
1343   uint64_t size = Buf.size();
1344   uint64_t big_size = sizeof(struct MachO::fat_header) +
1345                       nfat_arch * sizeof(struct MachO::fat_arch);
1346   outs() << "nfat_arch " << UB->getNumberOfObjects();
1347   if (nfat_arch == 0)
1348     outs() << " (malformed, contains zero architecture types)\n";
1349   else if (big_size > size)
1350     outs() << " (malformed, architectures past end of file)\n";
1351   else
1352     outs() << "\n";
1353
1354   for (uint32_t i = 0; i < nfat_arch; ++i) {
1355     MachOUniversalBinary::ObjectForArch OFA(UB, i);
1356     uint32_t cputype = OFA.getCPUType();
1357     uint32_t cpusubtype = OFA.getCPUSubType();
1358     outs() << "architecture ";
1359     for (uint32_t j = 0; i != 0 && j <= i - 1; j++) {
1360       MachOUniversalBinary::ObjectForArch other_OFA(UB, j);
1361       uint32_t other_cputype = other_OFA.getCPUType();
1362       uint32_t other_cpusubtype = other_OFA.getCPUSubType();
1363       if (cputype != 0 && cpusubtype != 0 && cputype == other_cputype &&
1364           (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) ==
1365               (other_cpusubtype & ~MachO::CPU_SUBTYPE_MASK)) {
1366         outs() << "(illegal duplicate architecture) ";
1367         break;
1368       }
1369     }
1370     if (verbose) {
1371       outs() << OFA.getArchTypeName() << "\n";
1372       printCPUType(cputype, cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
1373     } else {
1374       outs() << i << "\n";
1375       outs() << "    cputype " << cputype << "\n";
1376       outs() << "    cpusubtype " << (cpusubtype & ~MachO::CPU_SUBTYPE_MASK)
1377              << "\n";
1378     }
1379     if (verbose &&
1380         (cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64)
1381       outs() << "    capabilities CPU_SUBTYPE_LIB64\n";
1382     else
1383       outs() << "    capabilities "
1384              << format("0x%" PRIx32,
1385                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24) << "\n";
1386     outs() << "    offset " << OFA.getOffset();
1387     if (OFA.getOffset() > size)
1388       outs() << " (past end of file)";
1389     if (OFA.getOffset() % (1 << OFA.getAlign()) != 0)
1390       outs() << " (not aligned on it's alignment (2^" << OFA.getAlign() << ")";
1391     outs() << "\n";
1392     outs() << "    size " << OFA.getSize();
1393     big_size = OFA.getOffset() + OFA.getSize();
1394     if (big_size > size)
1395       outs() << " (past end of file)";
1396     outs() << "\n";
1397     outs() << "    align 2^" << OFA.getAlign() << " (" << (1 << OFA.getAlign())
1398            << ")\n";
1399   }
1400 }
1401
1402 static void printArchiveChild(Archive::Child &C, bool verbose,
1403                               bool print_offset) {
1404   if (print_offset)
1405     outs() << C.getChildOffset() << "\t";
1406   sys::fs::perms Mode = C.getAccessMode();
1407   if (verbose) {
1408     // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
1409     // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
1410     outs() << "-";
1411     if (Mode & sys::fs::owner_read)
1412       outs() << "r";
1413     else
1414       outs() << "-";
1415     if (Mode & sys::fs::owner_write)
1416       outs() << "w";
1417     else
1418       outs() << "-";
1419     if (Mode & sys::fs::owner_exe)
1420       outs() << "x";
1421     else
1422       outs() << "-";
1423     if (Mode & sys::fs::group_read)
1424       outs() << "r";
1425     else
1426       outs() << "-";
1427     if (Mode & sys::fs::group_write)
1428       outs() << "w";
1429     else
1430       outs() << "-";
1431     if (Mode & sys::fs::group_exe)
1432       outs() << "x";
1433     else
1434       outs() << "-";
1435     if (Mode & sys::fs::others_read)
1436       outs() << "r";
1437     else
1438       outs() << "-";
1439     if (Mode & sys::fs::others_write)
1440       outs() << "w";
1441     else
1442       outs() << "-";
1443     if (Mode & sys::fs::others_exe)
1444       outs() << "x";
1445     else
1446       outs() << "-";
1447   } else {
1448     outs() << format("0%o ", Mode);
1449   }
1450
1451   unsigned UID = C.getUID();
1452   outs() << format("%3d/", UID);
1453   unsigned GID = C.getGID();
1454   outs() << format("%-3d ", GID);
1455   uint64_t Size = C.getRawSize();
1456   outs() << format("%5" PRId64, Size) << " ";
1457
1458   StringRef RawLastModified = C.getRawLastModified();
1459   if (verbose) {
1460     unsigned Seconds;
1461     if (RawLastModified.getAsInteger(10, Seconds))
1462       outs() << "(date: \"%s\" contains non-decimal chars) " << RawLastModified;
1463     else {
1464       // Since cime(3) returns a 26 character string of the form:
1465       // "Sun Sep 16 01:03:52 1973\n\0"
1466       // just print 24 characters.
1467       time_t t = Seconds;
1468       outs() << format("%.24s ", ctime(&t));
1469     }
1470   } else {
1471     outs() << RawLastModified << " ";
1472   }
1473
1474   if (verbose) {
1475     ErrorOr<StringRef> NameOrErr = C.getName();
1476     if (NameOrErr.getError()) {
1477       StringRef RawName = C.getRawName();
1478       outs() << RawName << "\n";
1479     } else {
1480       StringRef Name = NameOrErr.get();
1481       outs() << Name << "\n";
1482     }
1483   } else {
1484     StringRef RawName = C.getRawName();
1485     outs() << RawName << "\n";
1486   }
1487 }
1488
1489 static void printArchiveHeaders(Archive *A, bool verbose, bool print_offset) {
1490   if (A->hasSymbolTable()) {
1491     Archive::child_iterator S = A->getSymbolTableChild();
1492     Archive::Child C = *S;
1493     printArchiveChild(C, verbose, print_offset);
1494   }
1495   for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E;
1496        ++I) {
1497     Archive::Child C = *I;
1498     printArchiveChild(C, verbose, print_offset);
1499   }
1500 }
1501
1502 // ParseInputMachO() parses the named Mach-O file in Filename and handles the
1503 // -arch flags selecting just those slices as specified by them and also parses
1504 // archive files.  Then for each individual Mach-O file ProcessMachO() is
1505 // called to process the file based on the command line options.
1506 void llvm::ParseInputMachO(StringRef Filename) {
1507   // Check for -arch all and verifiy the -arch flags are valid.
1508   for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1509     if (ArchFlags[i] == "all") {
1510       ArchAll = true;
1511     } else {
1512       if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
1513         errs() << "llvm-objdump: Unknown architecture named '" + ArchFlags[i] +
1514                       "'for the -arch option\n";
1515         return;
1516       }
1517     }
1518   }
1519
1520   // Attempt to open the binary.
1521   ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
1522   if (std::error_code EC = BinaryOrErr.getError()) {
1523     errs() << "llvm-objdump: '" << Filename << "': " << EC.message() << ".\n";
1524     return;
1525   }
1526   Binary &Bin = *BinaryOrErr.get().getBinary();
1527
1528   if (Archive *A = dyn_cast<Archive>(&Bin)) {
1529     outs() << "Archive : " << Filename << "\n";
1530     if (ArchiveHeaders)
1531       printArchiveHeaders(A, true, false);
1532     for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
1533          I != E; ++I) {
1534       ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary();
1535       if (ChildOrErr.getError())
1536         continue;
1537       if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1538         if (!checkMachOAndArchFlags(O, Filename))
1539           return;
1540         ProcessMachO(Filename, O, O->getFileName());
1541       }
1542     }
1543     return;
1544   }
1545   if (UniversalHeaders) {
1546     if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin))
1547       printMachOUniversalHeaders(UB, !NonVerbose);
1548   }
1549   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
1550     // If we have a list of architecture flags specified dump only those.
1551     if (!ArchAll && ArchFlags.size() != 0) {
1552       // Look for a slice in the universal binary that matches each ArchFlag.
1553       bool ArchFound;
1554       for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1555         ArchFound = false;
1556         for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1557                                                    E = UB->end_objects();
1558              I != E; ++I) {
1559           if (ArchFlags[i] == I->getArchTypeName()) {
1560             ArchFound = true;
1561             ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
1562                 I->getAsObjectFile();
1563             std::string ArchitectureName = "";
1564             if (ArchFlags.size() > 1)
1565               ArchitectureName = I->getArchTypeName();
1566             if (ObjOrErr) {
1567               ObjectFile &O = *ObjOrErr.get();
1568               if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1569                 ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1570             } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
1571                            I->getAsArchive()) {
1572               std::unique_ptr<Archive> &A = *AOrErr;
1573               outs() << "Archive : " << Filename;
1574               if (!ArchitectureName.empty())
1575                 outs() << " (architecture " << ArchitectureName << ")";
1576               outs() << "\n";
1577               if (ArchiveHeaders)
1578                 printArchiveHeaders(A.get(), true, false);
1579               for (Archive::child_iterator AI = A->child_begin(),
1580                                            AE = A->child_end();
1581                    AI != AE; ++AI) {
1582                 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
1583                 if (ChildOrErr.getError())
1584                   continue;
1585                 if (MachOObjectFile *O =
1586                         dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1587                   ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
1588               }
1589             }
1590           }
1591         }
1592         if (!ArchFound) {
1593           errs() << "llvm-objdump: file: " + Filename + " does not contain "
1594                  << "architecture: " + ArchFlags[i] + "\n";
1595           return;
1596         }
1597       }
1598       return;
1599     }
1600     // No architecture flags were specified so if this contains a slice that
1601     // matches the host architecture dump only that.
1602     if (!ArchAll) {
1603       for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1604                                                  E = UB->end_objects();
1605            I != E; ++I) {
1606         if (MachOObjectFile::getHostArch().getArchName() ==
1607             I->getArchTypeName()) {
1608           ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1609           std::string ArchiveName;
1610           ArchiveName.clear();
1611           if (ObjOrErr) {
1612             ObjectFile &O = *ObjOrErr.get();
1613             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1614               ProcessMachO(Filename, MachOOF);
1615           } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
1616                          I->getAsArchive()) {
1617             std::unique_ptr<Archive> &A = *AOrErr;
1618             outs() << "Archive : " << Filename << "\n";
1619             if (ArchiveHeaders)
1620               printArchiveHeaders(A.get(), true, false);
1621             for (Archive::child_iterator AI = A->child_begin(),
1622                                          AE = A->child_end();
1623                  AI != AE; ++AI) {
1624               ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
1625               if (ChildOrErr.getError())
1626                 continue;
1627               if (MachOObjectFile *O =
1628                       dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1629                 ProcessMachO(Filename, O, O->getFileName());
1630             }
1631           }
1632           return;
1633         }
1634       }
1635     }
1636     // Either all architectures have been specified or none have been specified
1637     // and this does not contain the host architecture so dump all the slices.
1638     bool moreThanOneArch = UB->getNumberOfObjects() > 1;
1639     for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1640                                                E = UB->end_objects();
1641          I != E; ++I) {
1642       ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1643       std::string ArchitectureName = "";
1644       if (moreThanOneArch)
1645         ArchitectureName = I->getArchTypeName();
1646       if (ObjOrErr) {
1647         ObjectFile &Obj = *ObjOrErr.get();
1648         if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
1649           ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1650       } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
1651         std::unique_ptr<Archive> &A = *AOrErr;
1652         outs() << "Archive : " << Filename;
1653         if (!ArchitectureName.empty())
1654           outs() << " (architecture " << ArchitectureName << ")";
1655         outs() << "\n";
1656         if (ArchiveHeaders)
1657           printArchiveHeaders(A.get(), true, false);
1658         for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
1659              AI != AE; ++AI) {
1660           ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
1661           if (ChildOrErr.getError())
1662             continue;
1663           if (MachOObjectFile *O =
1664                   dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1665             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
1666               ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
1667                            ArchitectureName);
1668           }
1669         }
1670       }
1671     }
1672     return;
1673   }
1674   if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
1675     if (!checkMachOAndArchFlags(O, Filename))
1676       return;
1677     if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
1678       ProcessMachO(Filename, MachOOF);
1679     } else
1680       errs() << "llvm-objdump: '" << Filename << "': "
1681              << "Object is not a Mach-O file type.\n";
1682   } else
1683     errs() << "llvm-objdump: '" << Filename << "': "
1684            << "Unrecognized file type.\n";
1685 }
1686
1687 typedef std::pair<uint64_t, const char *> BindInfoEntry;
1688 typedef std::vector<BindInfoEntry> BindTable;
1689 typedef BindTable::iterator bind_table_iterator;
1690
1691 // The block of info used by the Symbolizer call backs.
1692 struct DisassembleInfo {
1693   bool verbose;
1694   MachOObjectFile *O;
1695   SectionRef S;
1696   SymbolAddressMap *AddrMap;
1697   std::vector<SectionRef> *Sections;
1698   const char *class_name;
1699   const char *selector_name;
1700   char *method;
1701   char *demangled_name;
1702   uint64_t adrp_addr;
1703   uint32_t adrp_inst;
1704   BindTable *bindtable;
1705 };
1706
1707 // SymbolizerGetOpInfo() is the operand information call back function.
1708 // This is called to get the symbolic information for operand(s) of an
1709 // instruction when it is being done.  This routine does this from
1710 // the relocation information, symbol table, etc. That block of information
1711 // is a pointer to the struct DisassembleInfo that was passed when the
1712 // disassembler context was created and passed to back to here when
1713 // called back by the disassembler for instruction operands that could have
1714 // relocation information. The address of the instruction containing operand is
1715 // at the Pc parameter.  The immediate value the operand has is passed in
1716 // op_info->Value and is at Offset past the start of the instruction and has a
1717 // byte Size of 1, 2 or 4. The symbolc information is returned in TagBuf is the
1718 // LLVMOpInfo1 struct defined in the header "llvm-c/Disassembler.h" as symbol
1719 // names and addends of the symbolic expression to add for the operand.  The
1720 // value of TagType is currently 1 (for the LLVMOpInfo1 struct). If symbolic
1721 // information is returned then this function returns 1 else it returns 0.
1722 static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
1723                                uint64_t Size, int TagType, void *TagBuf) {
1724   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
1725   struct LLVMOpInfo1 *op_info = (struct LLVMOpInfo1 *)TagBuf;
1726   uint64_t value = op_info->Value;
1727
1728   // Make sure all fields returned are zero if we don't set them.
1729   memset((void *)op_info, '\0', sizeof(struct LLVMOpInfo1));
1730   op_info->Value = value;
1731
1732   // If the TagType is not the value 1 which it code knows about or if no
1733   // verbose symbolic information is wanted then just return 0, indicating no
1734   // information is being returned.
1735   if (TagType != 1 || info->verbose == false)
1736     return 0;
1737
1738   unsigned int Arch = info->O->getArch();
1739   if (Arch == Triple::x86) {
1740     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
1741       return 0;
1742     // First search the section's relocation entries (if any) for an entry
1743     // for this section offset.
1744     uint32_t sect_addr = info->S.getAddress();
1745     uint32_t sect_offset = (Pc + Offset) - sect_addr;
1746     bool reloc_found = false;
1747     DataRefImpl Rel;
1748     MachO::any_relocation_info RE;
1749     bool isExtern = false;
1750     SymbolRef Symbol;
1751     bool r_scattered = false;
1752     uint32_t r_value, pair_r_value, r_type;
1753     for (const RelocationRef &Reloc : info->S.relocations()) {
1754       uint64_t RelocOffset;
1755       Reloc.getOffset(RelocOffset);
1756       if (RelocOffset == sect_offset) {
1757         Rel = Reloc.getRawDataRefImpl();
1758         RE = info->O->getRelocation(Rel);
1759         r_type = info->O->getAnyRelocationType(RE);
1760         r_scattered = info->O->isRelocationScattered(RE);
1761         if (r_scattered) {
1762           r_value = info->O->getScatteredRelocationValue(RE);
1763           if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
1764               r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
1765             DataRefImpl RelNext = Rel;
1766             info->O->moveRelocationNext(RelNext);
1767             MachO::any_relocation_info RENext;
1768             RENext = info->O->getRelocation(RelNext);
1769             if (info->O->isRelocationScattered(RENext))
1770               pair_r_value = info->O->getScatteredRelocationValue(RENext);
1771             else
1772               return 0;
1773           }
1774         } else {
1775           isExtern = info->O->getPlainRelocationExternal(RE);
1776           if (isExtern) {
1777             symbol_iterator RelocSym = Reloc.getSymbol();
1778             Symbol = *RelocSym;
1779           }
1780         }
1781         reloc_found = true;
1782         break;
1783       }
1784     }
1785     if (reloc_found && isExtern) {
1786       StringRef SymName;
1787       Symbol.getName(SymName);
1788       const char *name = SymName.data();
1789       op_info->AddSymbol.Present = 1;
1790       op_info->AddSymbol.Name = name;
1791       // For i386 extern relocation entries the value in the instruction is
1792       // the offset from the symbol, and value is already set in op_info->Value.
1793       return 1;
1794     }
1795     if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
1796                         r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
1797       const char *add = GuessSymbolName(r_value, info->AddrMap);
1798       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
1799       uint32_t offset = value - (r_value - pair_r_value);
1800       op_info->AddSymbol.Present = 1;
1801       if (add != nullptr)
1802         op_info->AddSymbol.Name = add;
1803       else
1804         op_info->AddSymbol.Value = r_value;
1805       op_info->SubtractSymbol.Present = 1;
1806       if (sub != nullptr)
1807         op_info->SubtractSymbol.Name = sub;
1808       else
1809         op_info->SubtractSymbol.Value = pair_r_value;
1810       op_info->Value = offset;
1811       return 1;
1812     }
1813     // TODO:
1814     // Second search the external relocation entries of a fully linked image
1815     // (if any) for an entry that matches this segment offset.
1816     // uint32_t seg_offset = (Pc + Offset);
1817     return 0;
1818   } else if (Arch == Triple::x86_64) {
1819     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
1820       return 0;
1821     // First search the section's relocation entries (if any) for an entry
1822     // for this section offset.
1823     uint64_t sect_addr = info->S.getAddress();
1824     uint64_t sect_offset = (Pc + Offset) - sect_addr;
1825     bool reloc_found = false;
1826     DataRefImpl Rel;
1827     MachO::any_relocation_info RE;
1828     bool isExtern = false;
1829     SymbolRef Symbol;
1830     for (const RelocationRef &Reloc : info->S.relocations()) {
1831       uint64_t RelocOffset;
1832       Reloc.getOffset(RelocOffset);
1833       if (RelocOffset == sect_offset) {
1834         Rel = Reloc.getRawDataRefImpl();
1835         RE = info->O->getRelocation(Rel);
1836         // NOTE: Scattered relocations don't exist on x86_64.
1837         isExtern = info->O->getPlainRelocationExternal(RE);
1838         if (isExtern) {
1839           symbol_iterator RelocSym = Reloc.getSymbol();
1840           Symbol = *RelocSym;
1841         }
1842         reloc_found = true;
1843         break;
1844       }
1845     }
1846     if (reloc_found && isExtern) {
1847       // The Value passed in will be adjusted by the Pc if the instruction
1848       // adds the Pc.  But for x86_64 external relocation entries the Value
1849       // is the offset from the external symbol.
1850       if (info->O->getAnyRelocationPCRel(RE))
1851         op_info->Value -= Pc + Offset + Size;
1852       StringRef SymName;
1853       Symbol.getName(SymName);
1854       const char *name = SymName.data();
1855       unsigned Type = info->O->getAnyRelocationType(RE);
1856       if (Type == MachO::X86_64_RELOC_SUBTRACTOR) {
1857         DataRefImpl RelNext = Rel;
1858         info->O->moveRelocationNext(RelNext);
1859         MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
1860         unsigned TypeNext = info->O->getAnyRelocationType(RENext);
1861         bool isExternNext = info->O->getPlainRelocationExternal(RENext);
1862         unsigned SymbolNum = info->O->getPlainRelocationSymbolNum(RENext);
1863         if (TypeNext == MachO::X86_64_RELOC_UNSIGNED && isExternNext) {
1864           op_info->SubtractSymbol.Present = 1;
1865           op_info->SubtractSymbol.Name = name;
1866           symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum);
1867           Symbol = *RelocSymNext;
1868           StringRef SymNameNext;
1869           Symbol.getName(SymNameNext);
1870           name = SymNameNext.data();
1871         }
1872       }
1873       // TODO: add the VariantKinds to op_info->VariantKind for relocation types
1874       // like: X86_64_RELOC_TLV, X86_64_RELOC_GOT_LOAD and X86_64_RELOC_GOT.
1875       op_info->AddSymbol.Present = 1;
1876       op_info->AddSymbol.Name = name;
1877       return 1;
1878     }
1879     // TODO:
1880     // Second search the external relocation entries of a fully linked image
1881     // (if any) for an entry that matches this segment offset.
1882     // uint64_t seg_offset = (Pc + Offset);
1883     return 0;
1884   } else if (Arch == Triple::arm) {
1885     if (Offset != 0 || (Size != 4 && Size != 2))
1886       return 0;
1887     // First search the section's relocation entries (if any) for an entry
1888     // for this section offset.
1889     uint32_t sect_addr = info->S.getAddress();
1890     uint32_t sect_offset = (Pc + Offset) - sect_addr;
1891     bool reloc_found = false;
1892     DataRefImpl Rel;
1893     MachO::any_relocation_info RE;
1894     bool isExtern = false;
1895     SymbolRef Symbol;
1896     bool r_scattered = false;
1897     uint32_t r_value, pair_r_value, r_type, r_length, other_half;
1898     for (const RelocationRef &Reloc : info->S.relocations()) {
1899       uint64_t RelocOffset;
1900       Reloc.getOffset(RelocOffset);
1901       if (RelocOffset == sect_offset) {
1902         Rel = Reloc.getRawDataRefImpl();
1903         RE = info->O->getRelocation(Rel);
1904         r_length = info->O->getAnyRelocationLength(RE);
1905         r_scattered = info->O->isRelocationScattered(RE);
1906         if (r_scattered) {
1907           r_value = info->O->getScatteredRelocationValue(RE);
1908           r_type = info->O->getScatteredRelocationType(RE);
1909         } else {
1910           r_type = info->O->getAnyRelocationType(RE);
1911           isExtern = info->O->getPlainRelocationExternal(RE);
1912           if (isExtern) {
1913             symbol_iterator RelocSym = Reloc.getSymbol();
1914             Symbol = *RelocSym;
1915           }
1916         }
1917         if (r_type == MachO::ARM_RELOC_HALF ||
1918             r_type == MachO::ARM_RELOC_SECTDIFF ||
1919             r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
1920             r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1921           DataRefImpl RelNext = Rel;
1922           info->O->moveRelocationNext(RelNext);
1923           MachO::any_relocation_info RENext;
1924           RENext = info->O->getRelocation(RelNext);
1925           other_half = info->O->getAnyRelocationAddress(RENext) & 0xffff;
1926           if (info->O->isRelocationScattered(RENext))
1927             pair_r_value = info->O->getScatteredRelocationValue(RENext);
1928         }
1929         reloc_found = true;
1930         break;
1931       }
1932     }
1933     if (reloc_found && isExtern) {
1934       StringRef SymName;
1935       Symbol.getName(SymName);
1936       const char *name = SymName.data();
1937       op_info->AddSymbol.Present = 1;
1938       op_info->AddSymbol.Name = name;
1939       switch (r_type) {
1940       case MachO::ARM_RELOC_HALF:
1941         if ((r_length & 0x1) == 1) {
1942           op_info->Value = value << 16 | other_half;
1943           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
1944         } else {
1945           op_info->Value = other_half << 16 | value;
1946           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
1947         }
1948         break;
1949       default:
1950         break;
1951       }
1952       return 1;
1953     }
1954     // If we have a branch that is not an external relocation entry then
1955     // return 0 so the code in tryAddingSymbolicOperand() can use the
1956     // SymbolLookUp call back with the branch target address to look up the
1957     // symbol and possiblity add an annotation for a symbol stub.
1958     if (reloc_found && isExtern == 0 && (r_type == MachO::ARM_RELOC_BR24 ||
1959                                          r_type == MachO::ARM_THUMB_RELOC_BR22))
1960       return 0;
1961
1962     uint32_t offset = 0;
1963     if (reloc_found) {
1964       if (r_type == MachO::ARM_RELOC_HALF ||
1965           r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1966         if ((r_length & 0x1) == 1)
1967           value = value << 16 | other_half;
1968         else
1969           value = other_half << 16 | value;
1970       }
1971       if (r_scattered && (r_type != MachO::ARM_RELOC_HALF &&
1972                           r_type != MachO::ARM_RELOC_HALF_SECTDIFF)) {
1973         offset = value - r_value;
1974         value = r_value;
1975       }
1976     }
1977
1978     if (reloc_found && r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1979       if ((r_length & 0x1) == 1)
1980         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
1981       else
1982         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
1983       const char *add = GuessSymbolName(r_value, info->AddrMap);
1984       const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
1985       int32_t offset = value - (r_value - pair_r_value);
1986       op_info->AddSymbol.Present = 1;
1987       if (add != nullptr)
1988         op_info->AddSymbol.Name = add;
1989       else
1990         op_info->AddSymbol.Value = r_value;
1991       op_info->SubtractSymbol.Present = 1;
1992       if (sub != nullptr)
1993         op_info->SubtractSymbol.Name = sub;
1994       else
1995         op_info->SubtractSymbol.Value = pair_r_value;
1996       op_info->Value = offset;
1997       return 1;
1998     }
1999
2000     if (reloc_found == false)
2001       return 0;
2002
2003     op_info->AddSymbol.Present = 1;
2004     op_info->Value = offset;
2005     if (reloc_found) {
2006       if (r_type == MachO::ARM_RELOC_HALF) {
2007         if ((r_length & 0x1) == 1)
2008           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2009         else
2010           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2011       }
2012     }
2013     const char *add = GuessSymbolName(value, info->AddrMap);
2014     if (add != nullptr) {
2015       op_info->AddSymbol.Name = add;
2016       return 1;
2017     }
2018     op_info->AddSymbol.Value = value;
2019     return 1;
2020   } else if (Arch == Triple::aarch64) {
2021     if (Offset != 0 || Size != 4)
2022       return 0;
2023     // First search the section's relocation entries (if any) for an entry
2024     // for this section offset.
2025     uint64_t sect_addr = info->S.getAddress();
2026     uint64_t sect_offset = (Pc + Offset) - sect_addr;
2027     bool reloc_found = false;
2028     DataRefImpl Rel;
2029     MachO::any_relocation_info RE;
2030     bool isExtern = false;
2031     SymbolRef Symbol;
2032     uint32_t r_type = 0;
2033     for (const RelocationRef &Reloc : info->S.relocations()) {
2034       uint64_t RelocOffset;
2035       Reloc.getOffset(RelocOffset);
2036       if (RelocOffset == sect_offset) {
2037         Rel = Reloc.getRawDataRefImpl();
2038         RE = info->O->getRelocation(Rel);
2039         r_type = info->O->getAnyRelocationType(RE);
2040         if (r_type == MachO::ARM64_RELOC_ADDEND) {
2041           DataRefImpl RelNext = Rel;
2042           info->O->moveRelocationNext(RelNext);
2043           MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
2044           if (value == 0) {
2045             value = info->O->getPlainRelocationSymbolNum(RENext);
2046             op_info->Value = value;
2047           }
2048         }
2049         // NOTE: Scattered relocations don't exist on arm64.
2050         isExtern = info->O->getPlainRelocationExternal(RE);
2051         if (isExtern) {
2052           symbol_iterator RelocSym = Reloc.getSymbol();
2053           Symbol = *RelocSym;
2054         }
2055         reloc_found = true;
2056         break;
2057       }
2058     }
2059     if (reloc_found && isExtern) {
2060       StringRef SymName;
2061       Symbol.getName(SymName);
2062       const char *name = SymName.data();
2063       op_info->AddSymbol.Present = 1;
2064       op_info->AddSymbol.Name = name;
2065
2066       switch (r_type) {
2067       case MachO::ARM64_RELOC_PAGE21:
2068         /* @page */
2069         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGE;
2070         break;
2071       case MachO::ARM64_RELOC_PAGEOFF12:
2072         /* @pageoff */
2073         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGEOFF;
2074         break;
2075       case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
2076         /* @gotpage */
2077         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGE;
2078         break;
2079       case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
2080         /* @gotpageoff */
2081         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF;
2082         break;
2083       case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
2084         /* @tvlppage is not implemented in llvm-mc */
2085         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVP;
2086         break;
2087       case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
2088         /* @tvlppageoff is not implemented in llvm-mc */
2089         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVOFF;
2090         break;
2091       default:
2092       case MachO::ARM64_RELOC_BRANCH26:
2093         op_info->VariantKind = LLVMDisassembler_VariantKind_None;
2094         break;
2095       }
2096       return 1;
2097     }
2098     return 0;
2099   } else {
2100     return 0;
2101   }
2102 }
2103
2104 // GuessCstringPointer is passed the address of what might be a pointer to a
2105 // literal string in a cstring section.  If that address is in a cstring section
2106 // it returns a pointer to that string.  Else it returns nullptr.
2107 static const char *GuessCstringPointer(uint64_t ReferenceValue,
2108                                        struct DisassembleInfo *info) {
2109   uint32_t LoadCommandCount = info->O->getHeader().ncmds;
2110   MachOObjectFile::LoadCommandInfo Load = info->O->getFirstLoadCommandInfo();
2111   for (unsigned I = 0;; ++I) {
2112     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2113       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2114       for (unsigned J = 0; J < Seg.nsects; ++J) {
2115         MachO::section_64 Sec = info->O->getSection64(Load, J);
2116         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2117         if (section_type == MachO::S_CSTRING_LITERALS &&
2118             ReferenceValue >= Sec.addr &&
2119             ReferenceValue < Sec.addr + Sec.size) {
2120           uint64_t sect_offset = ReferenceValue - Sec.addr;
2121           uint64_t object_offset = Sec.offset + sect_offset;
2122           StringRef MachOContents = info->O->getData();
2123           uint64_t object_size = MachOContents.size();
2124           const char *object_addr = (const char *)MachOContents.data();
2125           if (object_offset < object_size) {
2126             const char *name = object_addr + object_offset;
2127             return name;
2128           } else {
2129             return nullptr;
2130           }
2131         }
2132       }
2133     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
2134       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
2135       for (unsigned J = 0; J < Seg.nsects; ++J) {
2136         MachO::section Sec = info->O->getSection(Load, J);
2137         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2138         if (section_type == MachO::S_CSTRING_LITERALS &&
2139             ReferenceValue >= Sec.addr &&
2140             ReferenceValue < Sec.addr + Sec.size) {
2141           uint64_t sect_offset = ReferenceValue - Sec.addr;
2142           uint64_t object_offset = Sec.offset + sect_offset;
2143           StringRef MachOContents = info->O->getData();
2144           uint64_t object_size = MachOContents.size();
2145           const char *object_addr = (const char *)MachOContents.data();
2146           if (object_offset < object_size) {
2147             const char *name = object_addr + object_offset;
2148             return name;
2149           } else {
2150             return nullptr;
2151           }
2152         }
2153       }
2154     }
2155     if (I == LoadCommandCount - 1)
2156       break;
2157     else
2158       Load = info->O->getNextLoadCommandInfo(Load);
2159   }
2160   return nullptr;
2161 }
2162
2163 // GuessIndirectSymbol returns the name of the indirect symbol for the
2164 // ReferenceValue passed in or nullptr.  This is used when ReferenceValue maybe
2165 // an address of a symbol stub or a lazy or non-lazy pointer to associate the
2166 // symbol name being referenced by the stub or pointer.
2167 static const char *GuessIndirectSymbol(uint64_t ReferenceValue,
2168                                        struct DisassembleInfo *info) {
2169   uint32_t LoadCommandCount = info->O->getHeader().ncmds;
2170   MachOObjectFile::LoadCommandInfo Load = info->O->getFirstLoadCommandInfo();
2171   MachO::dysymtab_command Dysymtab = info->O->getDysymtabLoadCommand();
2172   MachO::symtab_command Symtab = info->O->getSymtabLoadCommand();
2173   for (unsigned I = 0;; ++I) {
2174     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2175       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2176       for (unsigned J = 0; J < Seg.nsects; ++J) {
2177         MachO::section_64 Sec = info->O->getSection64(Load, J);
2178         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2179         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
2180              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
2181              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
2182              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
2183              section_type == MachO::S_SYMBOL_STUBS) &&
2184             ReferenceValue >= Sec.addr &&
2185             ReferenceValue < Sec.addr + Sec.size) {
2186           uint32_t stride;
2187           if (section_type == MachO::S_SYMBOL_STUBS)
2188             stride = Sec.reserved2;
2189           else
2190             stride = 8;
2191           if (stride == 0)
2192             return nullptr;
2193           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
2194           if (index < Dysymtab.nindirectsyms) {
2195             uint32_t indirect_symbol =
2196                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
2197             if (indirect_symbol < Symtab.nsyms) {
2198               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
2199               SymbolRef Symbol = *Sym;
2200               StringRef SymName;
2201               Symbol.getName(SymName);
2202               const char *name = SymName.data();
2203               return name;
2204             }
2205           }
2206         }
2207       }
2208     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
2209       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
2210       for (unsigned J = 0; J < Seg.nsects; ++J) {
2211         MachO::section Sec = info->O->getSection(Load, J);
2212         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
2213         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
2214              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
2215              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
2216              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
2217              section_type == MachO::S_SYMBOL_STUBS) &&
2218             ReferenceValue >= Sec.addr &&
2219             ReferenceValue < Sec.addr + Sec.size) {
2220           uint32_t stride;
2221           if (section_type == MachO::S_SYMBOL_STUBS)
2222             stride = Sec.reserved2;
2223           else
2224             stride = 4;
2225           if (stride == 0)
2226             return nullptr;
2227           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
2228           if (index < Dysymtab.nindirectsyms) {
2229             uint32_t indirect_symbol =
2230                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
2231             if (indirect_symbol < Symtab.nsyms) {
2232               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
2233               SymbolRef Symbol = *Sym;
2234               StringRef SymName;
2235               Symbol.getName(SymName);
2236               const char *name = SymName.data();
2237               return name;
2238             }
2239           }
2240         }
2241       }
2242     }
2243     if (I == LoadCommandCount - 1)
2244       break;
2245     else
2246       Load = info->O->getNextLoadCommandInfo(Load);
2247   }
2248   return nullptr;
2249 }
2250
2251 // method_reference() is called passing it the ReferenceName that might be
2252 // a reference it to an Objective-C method call.  If so then it allocates and
2253 // assembles a method call string with the values last seen and saved in
2254 // the DisassembleInfo's class_name and selector_name fields.  This is saved
2255 // into the method field of the info and any previous string is free'ed.
2256 // Then the class_name field in the info is set to nullptr.  The method call
2257 // string is set into ReferenceName and ReferenceType is set to
2258 // LLVMDisassembler_ReferenceType_Out_Objc_Message.  If this not a method call
2259 // then both ReferenceType and ReferenceName are left unchanged.
2260 static void method_reference(struct DisassembleInfo *info,
2261                              uint64_t *ReferenceType,
2262                              const char **ReferenceName) {
2263   unsigned int Arch = info->O->getArch();
2264   if (*ReferenceName != nullptr) {
2265     if (strcmp(*ReferenceName, "_objc_msgSend") == 0) {
2266       if (info->selector_name != nullptr) {
2267         if (info->method != nullptr)
2268           free(info->method);
2269         if (info->class_name != nullptr) {
2270           info->method = (char *)malloc(5 + strlen(info->class_name) +
2271                                         strlen(info->selector_name));
2272           if (info->method != nullptr) {
2273             strcpy(info->method, "+[");
2274             strcat(info->method, info->class_name);
2275             strcat(info->method, " ");
2276             strcat(info->method, info->selector_name);
2277             strcat(info->method, "]");
2278             *ReferenceName = info->method;
2279             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2280           }
2281         } else {
2282           info->method = (char *)malloc(9 + strlen(info->selector_name));
2283           if (info->method != nullptr) {
2284             if (Arch == Triple::x86_64)
2285               strcpy(info->method, "-[%rdi ");
2286             else if (Arch == Triple::aarch64)
2287               strcpy(info->method, "-[x0 ");
2288             else
2289               strcpy(info->method, "-[r? ");
2290             strcat(info->method, info->selector_name);
2291             strcat(info->method, "]");
2292             *ReferenceName = info->method;
2293             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2294           }
2295         }
2296         info->class_name = nullptr;
2297       }
2298     } else if (strcmp(*ReferenceName, "_objc_msgSendSuper2") == 0) {
2299       if (info->selector_name != nullptr) {
2300         if (info->method != nullptr)
2301           free(info->method);
2302         info->method = (char *)malloc(17 + strlen(info->selector_name));
2303         if (info->method != nullptr) {
2304           if (Arch == Triple::x86_64)
2305             strcpy(info->method, "-[[%rdi super] ");
2306           else if (Arch == Triple::aarch64)
2307             strcpy(info->method, "-[[x0 super] ");
2308           else
2309             strcpy(info->method, "-[[r? super] ");
2310           strcat(info->method, info->selector_name);
2311           strcat(info->method, "]");
2312           *ReferenceName = info->method;
2313           *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
2314         }
2315         info->class_name = nullptr;
2316       }
2317     }
2318   }
2319 }
2320
2321 // GuessPointerPointer() is passed the address of what might be a pointer to
2322 // a reference to an Objective-C class, selector, message ref or cfstring.
2323 // If so the value of the pointer is returned and one of the booleans are set
2324 // to true.  If not zero is returned and all the booleans are set to false.
2325 static uint64_t GuessPointerPointer(uint64_t ReferenceValue,
2326                                     struct DisassembleInfo *info,
2327                                     bool &classref, bool &selref, bool &msgref,
2328                                     bool &cfstring) {
2329   classref = false;
2330   selref = false;
2331   msgref = false;
2332   cfstring = false;
2333   uint32_t LoadCommandCount = info->O->getHeader().ncmds;
2334   MachOObjectFile::LoadCommandInfo Load = info->O->getFirstLoadCommandInfo();
2335   for (unsigned I = 0;; ++I) {
2336     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
2337       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
2338       for (unsigned J = 0; J < Seg.nsects; ++J) {
2339         MachO::section_64 Sec = info->O->getSection64(Load, J);
2340         if ((strncmp(Sec.sectname, "__objc_selrefs", 16) == 0 ||
2341              strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
2342              strncmp(Sec.sectname, "__objc_superrefs", 16) == 0 ||
2343              strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 ||
2344              strncmp(Sec.sectname, "__cfstring", 16) == 0) &&
2345             ReferenceValue >= Sec.addr &&
2346             ReferenceValue < Sec.addr + Sec.size) {
2347           uint64_t sect_offset = ReferenceValue - Sec.addr;
2348           uint64_t object_offset = Sec.offset + sect_offset;
2349           StringRef MachOContents = info->O->getData();
2350           uint64_t object_size = MachOContents.size();
2351           const char *object_addr = (const char *)MachOContents.data();
2352           if (object_offset < object_size) {
2353             uint64_t pointer_value;
2354             memcpy(&pointer_value, object_addr + object_offset,
2355                    sizeof(uint64_t));
2356             if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2357               sys::swapByteOrder(pointer_value);
2358             if (strncmp(Sec.sectname, "__objc_selrefs", 16) == 0)
2359               selref = true;
2360             else if (strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
2361                      strncmp(Sec.sectname, "__objc_superrefs", 16) == 0)
2362               classref = true;
2363             else if (strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 &&
2364                      ReferenceValue + 8 < Sec.addr + Sec.size) {
2365               msgref = true;
2366               memcpy(&pointer_value, object_addr + object_offset + 8,
2367                      sizeof(uint64_t));
2368               if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2369                 sys::swapByteOrder(pointer_value);
2370             } else if (strncmp(Sec.sectname, "__cfstring", 16) == 0)
2371               cfstring = true;
2372             return pointer_value;
2373           } else {
2374             return 0;
2375           }
2376         }
2377       }
2378     }
2379     // TODO: Look for LC_SEGMENT for 32-bit Mach-O files.
2380     if (I == LoadCommandCount - 1)
2381       break;
2382     else
2383       Load = info->O->getNextLoadCommandInfo(Load);
2384   }
2385   return 0;
2386 }
2387
2388 // get_pointer_64 returns a pointer to the bytes in the object file at the
2389 // Address from a section in the Mach-O file.  And indirectly returns the
2390 // offset into the section, number of bytes left in the section past the offset
2391 // and which section is was being referenced.  If the Address is not in a
2392 // section nullptr is returned.
2393 static const char *get_pointer_64(uint64_t Address, uint32_t &offset,
2394                                   uint32_t &left, SectionRef &S,
2395                                   DisassembleInfo *info) {
2396   offset = 0;
2397   left = 0;
2398   S = SectionRef();
2399   for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) {
2400     uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress();
2401     uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize();
2402     if (Address >= SectAddress && Address < SectAddress + SectSize) {
2403       S = (*(info->Sections))[SectIdx];
2404       offset = Address - SectAddress;
2405       left = SectSize - offset;
2406       StringRef SectContents;
2407       ((*(info->Sections))[SectIdx]).getContents(SectContents);
2408       return SectContents.data() + offset;
2409     }
2410   }
2411   return nullptr;
2412 }
2413
2414 // get_symbol_64() returns the name of a symbol (or nullptr) and the address of
2415 // the symbol indirectly through n_value. Based on the relocation information
2416 // for the specified section offset in the specified section reference.
2417 static const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
2418                                  DisassembleInfo *info, uint64_t &n_value) {
2419   n_value = 0;
2420   if (info->verbose == false)
2421     return nullptr;
2422
2423   // See if there is an external relocation entry at the sect_offset.
2424   bool reloc_found = false;
2425   DataRefImpl Rel;
2426   MachO::any_relocation_info RE;
2427   bool isExtern = false;
2428   SymbolRef Symbol;
2429   for (const RelocationRef &Reloc : S.relocations()) {
2430     uint64_t RelocOffset;
2431     Reloc.getOffset(RelocOffset);
2432     if (RelocOffset == sect_offset) {
2433       Rel = Reloc.getRawDataRefImpl();
2434       RE = info->O->getRelocation(Rel);
2435       if (info->O->isRelocationScattered(RE))
2436         continue;
2437       isExtern = info->O->getPlainRelocationExternal(RE);
2438       if (isExtern) {
2439         symbol_iterator RelocSym = Reloc.getSymbol();
2440         Symbol = *RelocSym;
2441       }
2442       reloc_found = true;
2443       break;
2444     }
2445   }
2446   // If there is an external relocation entry for a symbol in this section
2447   // at this section_offset then use that symbol's value for the n_value
2448   // and return its name.
2449   const char *SymbolName = nullptr;
2450   if (reloc_found && isExtern) {
2451     Symbol.getAddress(n_value);
2452     StringRef name;
2453     Symbol.getName(name);
2454     if (!name.empty()) {
2455       SymbolName = name.data();
2456       return SymbolName;
2457     }
2458   }
2459
2460   // TODO: For fully linked images, look through the external relocation
2461   // entries off the dynamic symtab command. For these the r_offset is from the
2462   // start of the first writeable segment in the Mach-O file.  So the offset
2463   // to this section from that segment is passed to this routine by the caller,
2464   // as the database_offset. Which is the difference of the section's starting
2465   // address and the first writable segment.
2466   //
2467   // NOTE: need add passing the database_offset to this routine.
2468
2469   // TODO: We did not find an external relocation entry so look up the
2470   // ReferenceValue as an address of a symbol and if found return that symbol's
2471   // name.
2472   //
2473   // NOTE: need add passing the ReferenceValue to this routine.  Then that code
2474   // would simply be this:
2475   // SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
2476
2477   return SymbolName;
2478 }
2479
2480 // These are structs in the Objective-C meta data and read to produce the
2481 // comments for disassembly.  While these are part of the ABI they are no
2482 // public defintions.  So the are here not in include/llvm/Support/MachO.h .
2483
2484 // The cfstring object in a 64-bit Mach-O file.
2485 struct cfstring64_t {
2486   uint64_t isa;        // class64_t * (64-bit pointer)
2487   uint64_t flags;      // flag bits
2488   uint64_t characters; // char * (64-bit pointer)
2489   uint64_t length;     // number of non-NULL characters in above
2490 };
2491
2492 // The class object in a 64-bit Mach-O file.
2493 struct class64_t {
2494   uint64_t isa;        // class64_t * (64-bit pointer)
2495   uint64_t superclass; // class64_t * (64-bit pointer)
2496   uint64_t cache;      // Cache (64-bit pointer)
2497   uint64_t vtable;     // IMP * (64-bit pointer)
2498   uint64_t data;       // class_ro64_t * (64-bit pointer)
2499 };
2500
2501 struct class_ro64_t {
2502   uint32_t flags;
2503   uint32_t instanceStart;
2504   uint32_t instanceSize;
2505   uint32_t reserved;
2506   uint64_t ivarLayout;     // const uint8_t * (64-bit pointer)
2507   uint64_t name;           // const char * (64-bit pointer)
2508   uint64_t baseMethods;    // const method_list_t * (64-bit pointer)
2509   uint64_t baseProtocols;  // const protocol_list_t * (64-bit pointer)
2510   uint64_t ivars;          // const ivar_list_t * (64-bit pointer)
2511   uint64_t weakIvarLayout; // const uint8_t * (64-bit pointer)
2512   uint64_t baseProperties; // const struct objc_property_list (64-bit pointer)
2513 };
2514
2515 inline void swapStruct(struct cfstring64_t &cfs) {
2516   sys::swapByteOrder(cfs.isa);
2517   sys::swapByteOrder(cfs.flags);
2518   sys::swapByteOrder(cfs.characters);
2519   sys::swapByteOrder(cfs.length);
2520 }
2521
2522 inline void swapStruct(struct class64_t &c) {
2523   sys::swapByteOrder(c.isa);
2524   sys::swapByteOrder(c.superclass);
2525   sys::swapByteOrder(c.cache);
2526   sys::swapByteOrder(c.vtable);
2527   sys::swapByteOrder(c.data);
2528 }
2529
2530 inline void swapStruct(struct class_ro64_t &cro) {
2531   sys::swapByteOrder(cro.flags);
2532   sys::swapByteOrder(cro.instanceStart);
2533   sys::swapByteOrder(cro.instanceSize);
2534   sys::swapByteOrder(cro.reserved);
2535   sys::swapByteOrder(cro.ivarLayout);
2536   sys::swapByteOrder(cro.name);
2537   sys::swapByteOrder(cro.baseMethods);
2538   sys::swapByteOrder(cro.baseProtocols);
2539   sys::swapByteOrder(cro.ivars);
2540   sys::swapByteOrder(cro.weakIvarLayout);
2541   sys::swapByteOrder(cro.baseProperties);
2542 }
2543
2544 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
2545                                                  struct DisassembleInfo *info);
2546
2547 // get_objc2_64bit_class_name() is used for disassembly and is passed a pointer
2548 // to an Objective-C class and returns the class name.  It is also passed the
2549 // address of the pointer, so when the pointer is zero as it can be in an .o
2550 // file, that is used to look for an external relocation entry with a symbol
2551 // name.
2552 static const char *get_objc2_64bit_class_name(uint64_t pointer_value,
2553                                               uint64_t ReferenceValue,
2554                                               struct DisassembleInfo *info) {
2555   const char *r;
2556   uint32_t offset, left;
2557   SectionRef S;
2558
2559   // The pointer_value can be 0 in an object file and have a relocation
2560   // entry for the class symbol at the ReferenceValue (the address of the
2561   // pointer).
2562   if (pointer_value == 0) {
2563     r = get_pointer_64(ReferenceValue, offset, left, S, info);
2564     if (r == nullptr || left < sizeof(uint64_t))
2565       return nullptr;
2566     uint64_t n_value;
2567     const char *symbol_name = get_symbol_64(offset, S, info, n_value);
2568     if (symbol_name == nullptr)
2569       return nullptr;
2570     const char *class_name = strrchr(symbol_name, '$');
2571     if (class_name != nullptr && class_name[1] == '_' && class_name[2] != '\0')
2572       return class_name + 2;
2573     else
2574       return nullptr;
2575   }
2576
2577   // The case were the pointer_value is non-zero and points to a class defined
2578   // in this Mach-O file.
2579   r = get_pointer_64(pointer_value, offset, left, S, info);
2580   if (r == nullptr || left < sizeof(struct class64_t))
2581     return nullptr;
2582   struct class64_t c;
2583   memcpy(&c, r, sizeof(struct class64_t));
2584   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2585     swapStruct(c);
2586   if (c.data == 0)
2587     return nullptr;
2588   r = get_pointer_64(c.data, offset, left, S, info);
2589   if (r == nullptr || left < sizeof(struct class_ro64_t))
2590     return nullptr;
2591   struct class_ro64_t cro;
2592   memcpy(&cro, r, sizeof(struct class_ro64_t));
2593   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2594     swapStruct(cro);
2595   if (cro.name == 0)
2596     return nullptr;
2597   const char *name = get_pointer_64(cro.name, offset, left, S, info);
2598   return name;
2599 }
2600
2601 // get_objc2_64bit_cfstring_name is used for disassembly and is passed a
2602 // pointer to a cfstring and returns its name or nullptr.
2603 static const char *get_objc2_64bit_cfstring_name(uint64_t ReferenceValue,
2604                                                  struct DisassembleInfo *info) {
2605   const char *r, *name;
2606   uint32_t offset, left;
2607   SectionRef S;
2608   struct cfstring64_t cfs;
2609   uint64_t cfs_characters;
2610
2611   r = get_pointer_64(ReferenceValue, offset, left, S, info);
2612   if (r == nullptr || left < sizeof(struct cfstring64_t))
2613     return nullptr;
2614   memcpy(&cfs, r, sizeof(struct cfstring64_t));
2615   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
2616     swapStruct(cfs);
2617   if (cfs.characters == 0) {
2618     uint64_t n_value;
2619     const char *symbol_name = get_symbol_64(
2620         offset + offsetof(struct cfstring64_t, characters), S, info, n_value);
2621     if (symbol_name == nullptr)
2622       return nullptr;
2623     cfs_characters = n_value;
2624   } else
2625     cfs_characters = cfs.characters;
2626   name = get_pointer_64(cfs_characters, offset, left, S, info);
2627
2628   return name;
2629 }
2630
2631 // get_objc2_64bit_selref() is used for disassembly and is passed a the address
2632 // of a pointer to an Objective-C selector reference when the pointer value is
2633 // zero as in a .o file and is likely to have a external relocation entry with
2634 // who's symbol's n_value is the real pointer to the selector name.  If that is
2635 // the case the real pointer to the selector name is returned else 0 is
2636 // returned
2637 static uint64_t get_objc2_64bit_selref(uint64_t ReferenceValue,
2638                                        struct DisassembleInfo *info) {
2639   uint32_t offset, left;
2640   SectionRef S;
2641
2642   const char *r = get_pointer_64(ReferenceValue, offset, left, S, info);
2643   if (r == nullptr || left < sizeof(uint64_t))
2644     return 0;
2645   uint64_t n_value;
2646   const char *symbol_name = get_symbol_64(offset, S, info, n_value);
2647   if (symbol_name == nullptr)
2648     return 0;
2649   return n_value;
2650 }
2651
2652 // GuessLiteralPointer returns a string which for the item in the Mach-O file
2653 // for the address passed in as ReferenceValue for printing as a comment with
2654 // the instruction and also returns the corresponding type of that item
2655 // indirectly through ReferenceType.
2656 //
2657 // If ReferenceValue is an address of literal cstring then a pointer to the
2658 // cstring is returned and ReferenceType is set to
2659 // LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr .
2660 //
2661 // If ReferenceValue is an address of an Objective-C CFString, Selector ref or
2662 // Class ref that name is returned and the ReferenceType is set accordingly.
2663 //
2664 // Lastly, literals which are Symbol address in a literal pool are looked for
2665 // and if found the symbol name is returned and ReferenceType is set to
2666 // LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr .
2667 //
2668 // If there is no item in the Mach-O file for the address passed in as
2669 // ReferenceValue nullptr is returned and ReferenceType is unchanged.
2670 static const char *GuessLiteralPointer(uint64_t ReferenceValue,
2671                                        uint64_t ReferencePC,
2672                                        uint64_t *ReferenceType,
2673                                        struct DisassembleInfo *info) {
2674   // First see if there is an external relocation entry at the ReferencePC.
2675   uint64_t sect_addr = info->S.getAddress();
2676   uint64_t sect_offset = ReferencePC - sect_addr;
2677   bool reloc_found = false;
2678   DataRefImpl Rel;
2679   MachO::any_relocation_info RE;
2680   bool isExtern = false;
2681   SymbolRef Symbol;
2682   for (const RelocationRef &Reloc : info->S.relocations()) {
2683     uint64_t RelocOffset;
2684     Reloc.getOffset(RelocOffset);
2685     if (RelocOffset == sect_offset) {
2686       Rel = Reloc.getRawDataRefImpl();
2687       RE = info->O->getRelocation(Rel);
2688       if (info->O->isRelocationScattered(RE))
2689         continue;
2690       isExtern = info->O->getPlainRelocationExternal(RE);
2691       if (isExtern) {
2692         symbol_iterator RelocSym = Reloc.getSymbol();
2693         Symbol = *RelocSym;
2694       }
2695       reloc_found = true;
2696       break;
2697     }
2698   }
2699   // If there is an external relocation entry for a symbol in a section
2700   // then used that symbol's value for the value of the reference.
2701   if (reloc_found && isExtern) {
2702     if (info->O->getAnyRelocationPCRel(RE)) {
2703       unsigned Type = info->O->getAnyRelocationType(RE);
2704       if (Type == MachO::X86_64_RELOC_SIGNED) {
2705         Symbol.getAddress(ReferenceValue);
2706       }
2707     }
2708   }
2709
2710   // Look for literals such as Objective-C CFStrings refs, Selector refs,
2711   // Message refs and Class refs.
2712   bool classref, selref, msgref, cfstring;
2713   uint64_t pointer_value = GuessPointerPointer(ReferenceValue, info, classref,
2714                                                selref, msgref, cfstring);
2715   if (classref == true && pointer_value == 0) {
2716     // Note the ReferenceValue is a pointer into the __objc_classrefs section.
2717     // And the pointer_value in that section is typically zero as it will be
2718     // set by dyld as part of the "bind information".
2719     const char *name = get_dyld_bind_info_symbolname(ReferenceValue, info);
2720     if (name != nullptr) {
2721       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
2722       const char *class_name = strrchr(name, '$');
2723       if (class_name != nullptr && class_name[1] == '_' &&
2724           class_name[2] != '\0') {
2725         info->class_name = class_name + 2;
2726         return name;
2727       }
2728     }
2729   }
2730
2731   if (classref == true) {
2732     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
2733     const char *name =
2734         get_objc2_64bit_class_name(pointer_value, ReferenceValue, info);
2735     if (name != nullptr)
2736       info->class_name = name;
2737     else
2738       name = "bad class ref";
2739     return name;
2740   }
2741
2742   if (cfstring == true) {
2743     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref;
2744     const char *name = get_objc2_64bit_cfstring_name(ReferenceValue, info);
2745     return name;
2746   }
2747
2748   if (selref == true && pointer_value == 0)
2749     pointer_value = get_objc2_64bit_selref(ReferenceValue, info);
2750
2751   if (pointer_value != 0)
2752     ReferenceValue = pointer_value;
2753
2754   const char *name = GuessCstringPointer(ReferenceValue, info);
2755   if (name) {
2756     if (pointer_value != 0 && selref == true) {
2757       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref;
2758       info->selector_name = name;
2759     } else if (pointer_value != 0 && msgref == true) {
2760       info->class_name = nullptr;
2761       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref;
2762       info->selector_name = name;
2763     } else
2764       *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr;
2765     return name;
2766   }
2767
2768   // Lastly look for an indirect symbol with this ReferenceValue which is in
2769   // a literal pool.  If found return that symbol name.
2770   name = GuessIndirectSymbol(ReferenceValue, info);
2771   if (name) {
2772     *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr;
2773     return name;
2774   }
2775
2776   return nullptr;
2777 }
2778
2779 // SymbolizerSymbolLookUp is the symbol lookup function passed when creating
2780 // the Symbolizer.  It looks up the ReferenceValue using the info passed via the
2781 // pointer to the struct DisassembleInfo that was passed when MCSymbolizer
2782 // is created and returns the symbol name that matches the ReferenceValue or
2783 // nullptr if none.  The ReferenceType is passed in for the IN type of
2784 // reference the instruction is making from the values in defined in the header
2785 // "llvm-c/Disassembler.h".  On return the ReferenceType can set to a specific
2786 // Out type and the ReferenceName will also be set which is added as a comment
2787 // to the disassembled instruction.
2788 //
2789 #if HAVE_CXXABI_H
2790 // If the symbol name is a C++ mangled name then the demangled name is
2791 // returned through ReferenceName and ReferenceType is set to
2792 // LLVMDisassembler_ReferenceType_DeMangled_Name .
2793 #endif
2794 //
2795 // When this is called to get a symbol name for a branch target then the
2796 // ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then
2797 // SymbolValue will be looked for in the indirect symbol table to determine if
2798 // it is an address for a symbol stub.  If so then the symbol name for that
2799 // stub is returned indirectly through ReferenceName and then ReferenceType is
2800 // set to LLVMDisassembler_ReferenceType_Out_SymbolStub.
2801 //
2802 // When this is called with an value loaded via a PC relative load then
2803 // ReferenceType will be LLVMDisassembler_ReferenceType_In_PCrel_Load then the
2804 // SymbolValue is checked to be an address of literal pointer, symbol pointer,
2805 // or an Objective-C meta data reference.  If so the output ReferenceType is
2806 // set to correspond to that as well as setting the ReferenceName.
2807 static const char *SymbolizerSymbolLookUp(void *DisInfo,
2808                                           uint64_t ReferenceValue,
2809                                           uint64_t *ReferenceType,
2810                                           uint64_t ReferencePC,
2811                                           const char **ReferenceName) {
2812   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
2813   // If no verbose symbolic information is wanted then just return nullptr.
2814   if (info->verbose == false) {
2815     *ReferenceName = nullptr;
2816     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
2817     return nullptr;
2818   }
2819
2820   const char *SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
2821
2822   if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
2823     *ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
2824     if (*ReferenceName != nullptr) {
2825       method_reference(info, ReferenceType, ReferenceName);
2826       if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message)
2827         *ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
2828     } else
2829 #if HAVE_CXXABI_H
2830         if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
2831       if (info->demangled_name != nullptr)
2832         free(info->demangled_name);
2833       int status;
2834       info->demangled_name =
2835           abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status);
2836       if (info->demangled_name != nullptr) {
2837         *ReferenceName = info->demangled_name;
2838         *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
2839       } else
2840         *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
2841     } else
2842 #endif
2843       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
2844   } else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
2845     *ReferenceName =
2846         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
2847     if (*ReferenceName)
2848       method_reference(info, ReferenceType, ReferenceName);
2849     else
2850       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
2851     // If this is arm64 and the reference is an adrp instruction save the
2852     // instruction, passed in ReferenceValue and the address of the instruction
2853     // for use later if we see and add immediate instruction.
2854   } else if (info->O->getArch() == Triple::aarch64 &&
2855              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
2856     info->adrp_inst = ReferenceValue;
2857     info->adrp_addr = ReferencePC;
2858     SymbolName = nullptr;
2859     *ReferenceName = nullptr;
2860     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
2861     // If this is arm64 and reference is an add immediate instruction and we
2862     // have
2863     // seen an adrp instruction just before it and the adrp's Xd register
2864     // matches
2865     // this add's Xn register reconstruct the value being referenced and look to
2866     // see if it is a literal pointer.  Note the add immediate instruction is
2867     // passed in ReferenceValue.
2868   } else if (info->O->getArch() == Triple::aarch64 &&
2869              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
2870              ReferencePC - 4 == info->adrp_addr &&
2871              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
2872              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
2873     uint32_t addxri_inst;
2874     uint64_t adrp_imm, addxri_imm;
2875
2876     adrp_imm =
2877         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
2878     if (info->adrp_inst & 0x0200000)
2879       adrp_imm |= 0xfffffffffc000000LL;
2880
2881     addxri_inst = ReferenceValue;
2882     addxri_imm = (addxri_inst >> 10) & 0xfff;
2883     if (((addxri_inst >> 22) & 0x3) == 1)
2884       addxri_imm <<= 12;
2885
2886     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
2887                      (adrp_imm << 12) + addxri_imm;
2888
2889     *ReferenceName =
2890         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
2891     if (*ReferenceName == nullptr)
2892       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
2893     // If this is arm64 and the reference is a load register instruction and we
2894     // have seen an adrp instruction just before it and the adrp's Xd register
2895     // matches this add's Xn register reconstruct the value being referenced and
2896     // look to see if it is a literal pointer.  Note the load register
2897     // instruction is passed in ReferenceValue.
2898   } else if (info->O->getArch() == Triple::aarch64 &&
2899              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXui &&
2900              ReferencePC - 4 == info->adrp_addr &&
2901              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
2902              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
2903     uint32_t ldrxui_inst;
2904     uint64_t adrp_imm, ldrxui_imm;
2905
2906     adrp_imm =
2907         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
2908     if (info->adrp_inst & 0x0200000)
2909       adrp_imm |= 0xfffffffffc000000LL;
2910
2911     ldrxui_inst = ReferenceValue;
2912     ldrxui_imm = (ldrxui_inst >> 10) & 0xfff;
2913
2914     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
2915                      (adrp_imm << 12) + (ldrxui_imm << 3);
2916
2917     *ReferenceName =
2918         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
2919     if (*ReferenceName == nullptr)
2920       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
2921   }
2922   // If this arm64 and is an load register (PC-relative) instruction the
2923   // ReferenceValue is the PC plus the immediate value.
2924   else if (info->O->getArch() == Triple::aarch64 &&
2925            (*ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXl ||
2926             *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADR)) {
2927     *ReferenceName =
2928         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
2929     if (*ReferenceName == nullptr)
2930       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
2931   }
2932 #if HAVE_CXXABI_H
2933   else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
2934     if (info->demangled_name != nullptr)
2935       free(info->demangled_name);
2936     int status;
2937     info->demangled_name =
2938         abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status);
2939     if (info->demangled_name != nullptr) {
2940       *ReferenceName = info->demangled_name;
2941       *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
2942     }
2943   }
2944 #endif
2945   else {
2946     *ReferenceName = nullptr;
2947     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
2948   }
2949
2950   return SymbolName;
2951 }
2952
2953 /// \brief Emits the comments that are stored in the CommentStream.
2954 /// Each comment in the CommentStream must end with a newline.
2955 static void emitComments(raw_svector_ostream &CommentStream,
2956                          SmallString<128> &CommentsToEmit,
2957                          formatted_raw_ostream &FormattedOS,
2958                          const MCAsmInfo &MAI) {
2959   // Flush the stream before taking its content.
2960   CommentStream.flush();
2961   StringRef Comments = CommentsToEmit.str();
2962   // Get the default information for printing a comment.
2963   const char *CommentBegin = MAI.getCommentString();
2964   unsigned CommentColumn = MAI.getCommentColumn();
2965   bool IsFirst = true;
2966   while (!Comments.empty()) {
2967     if (!IsFirst)
2968       FormattedOS << '\n';
2969     // Emit a line of comments.
2970     FormattedOS.PadToColumn(CommentColumn);
2971     size_t Position = Comments.find('\n');
2972     FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
2973     // Move after the newline character.
2974     Comments = Comments.substr(Position + 1);
2975     IsFirst = false;
2976   }
2977   FormattedOS.flush();
2978
2979   // Tell the comment stream that the vector changed underneath it.
2980   CommentsToEmit.clear();
2981   CommentStream.resync();
2982 }
2983
2984 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
2985                              StringRef DisSegName, StringRef DisSectName) {
2986   const char *McpuDefault = nullptr;
2987   const Target *ThumbTarget = nullptr;
2988   const Target *TheTarget = GetTarget(MachOOF, &McpuDefault, &ThumbTarget);
2989   if (!TheTarget) {
2990     // GetTarget prints out stuff.
2991     return;
2992   }
2993   if (MCPU.empty() && McpuDefault)
2994     MCPU = McpuDefault;
2995
2996   std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
2997   std::unique_ptr<const MCInstrInfo> ThumbInstrInfo;
2998   if (ThumbTarget)
2999     ThumbInstrInfo.reset(ThumbTarget->createMCInstrInfo());
3000
3001   // Package up features to be passed to target/subtarget
3002   std::string FeaturesStr;
3003   if (MAttrs.size()) {
3004     SubtargetFeatures Features;
3005     for (unsigned i = 0; i != MAttrs.size(); ++i)
3006       Features.AddFeature(MAttrs[i]);
3007     FeaturesStr = Features.getString();
3008   }
3009
3010   // Set up disassembler.
3011   std::unique_ptr<const MCRegisterInfo> MRI(
3012       TheTarget->createMCRegInfo(TripleName));
3013   std::unique_ptr<const MCAsmInfo> AsmInfo(
3014       TheTarget->createMCAsmInfo(*MRI, TripleName));
3015   std::unique_ptr<const MCSubtargetInfo> STI(
3016       TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
3017   MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr);
3018   std::unique_ptr<MCDisassembler> DisAsm(
3019       TheTarget->createMCDisassembler(*STI, Ctx));
3020   std::unique_ptr<MCSymbolizer> Symbolizer;
3021   struct DisassembleInfo SymbolizerInfo;
3022   std::unique_ptr<MCRelocationInfo> RelInfo(
3023       TheTarget->createMCRelocationInfo(TripleName, Ctx));
3024   if (RelInfo) {
3025     Symbolizer.reset(TheTarget->createMCSymbolizer(
3026         TripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
3027         &SymbolizerInfo, &Ctx, std::move(RelInfo)));
3028     DisAsm->setSymbolizer(std::move(Symbolizer));
3029   }
3030   int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
3031   std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
3032       AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI, *STI));
3033   // Set the display preference for hex vs. decimal immediates.
3034   IP->setPrintImmHex(PrintImmHex);
3035   // Comment stream and backing vector.
3036   SmallString<128> CommentsToEmit;
3037   raw_svector_ostream CommentStream(CommentsToEmit);
3038   // FIXME: Setting the CommentStream in the InstPrinter is problematic in that
3039   // if it is done then arm64 comments for string literals don't get printed
3040   // and some constant get printed instead and not setting it causes intel
3041   // (32-bit and 64-bit) comments printed with different spacing before the
3042   // comment causing different diffs with the 'C' disassembler library API.
3043   // IP->setCommentStream(CommentStream);
3044
3045   if (!AsmInfo || !STI || !DisAsm || !IP) {
3046     errs() << "error: couldn't initialize disassembler for target "
3047            << TripleName << '\n';
3048     return;
3049   }
3050
3051   // Set up thumb disassembler.
3052   std::unique_ptr<const MCRegisterInfo> ThumbMRI;
3053   std::unique_ptr<const MCAsmInfo> ThumbAsmInfo;
3054   std::unique_ptr<const MCSubtargetInfo> ThumbSTI;
3055   std::unique_ptr<MCDisassembler> ThumbDisAsm;
3056   std::unique_ptr<MCInstPrinter> ThumbIP;
3057   std::unique_ptr<MCContext> ThumbCtx;
3058   std::unique_ptr<MCSymbolizer> ThumbSymbolizer;
3059   struct DisassembleInfo ThumbSymbolizerInfo;
3060   std::unique_ptr<MCRelocationInfo> ThumbRelInfo;
3061   if (ThumbTarget) {
3062     ThumbMRI.reset(ThumbTarget->createMCRegInfo(ThumbTripleName));
3063     ThumbAsmInfo.reset(
3064         ThumbTarget->createMCAsmInfo(*ThumbMRI, ThumbTripleName));
3065     ThumbSTI.reset(
3066         ThumbTarget->createMCSubtargetInfo(ThumbTripleName, MCPU, FeaturesStr));
3067     ThumbCtx.reset(new MCContext(ThumbAsmInfo.get(), ThumbMRI.get(), nullptr));
3068     ThumbDisAsm.reset(ThumbTarget->createMCDisassembler(*ThumbSTI, *ThumbCtx));
3069     MCContext *PtrThumbCtx = ThumbCtx.get();
3070     ThumbRelInfo.reset(
3071         ThumbTarget->createMCRelocationInfo(ThumbTripleName, *PtrThumbCtx));
3072     if (ThumbRelInfo) {
3073       ThumbSymbolizer.reset(ThumbTarget->createMCSymbolizer(
3074           ThumbTripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
3075           &ThumbSymbolizerInfo, PtrThumbCtx, std::move(ThumbRelInfo)));
3076       ThumbDisAsm->setSymbolizer(std::move(ThumbSymbolizer));
3077     }
3078     int ThumbAsmPrinterVariant = ThumbAsmInfo->getAssemblerDialect();
3079     ThumbIP.reset(ThumbTarget->createMCInstPrinter(
3080         ThumbAsmPrinterVariant, *ThumbAsmInfo, *ThumbInstrInfo, *ThumbMRI,
3081         *ThumbSTI));
3082     // Set the display preference for hex vs. decimal immediates.
3083     ThumbIP->setPrintImmHex(PrintImmHex);
3084   }
3085
3086   if (ThumbTarget && (!ThumbAsmInfo || !ThumbSTI || !ThumbDisAsm || !ThumbIP)) {
3087     errs() << "error: couldn't initialize disassembler for target "
3088            << ThumbTripleName << '\n';
3089     return;
3090   }
3091
3092   MachO::mach_header Header = MachOOF->getHeader();
3093
3094   // FIXME: Using the -cfg command line option, this code used to be able to
3095   // annotate relocations with the referenced symbol's name, and if this was
3096   // inside a __[cf]string section, the data it points to. This is now replaced
3097   // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
3098   std::vector<SectionRef> Sections;
3099   std::vector<SymbolRef> Symbols;
3100   SmallVector<uint64_t, 8> FoundFns;
3101   uint64_t BaseSegmentAddress;
3102
3103   getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns,
3104                         BaseSegmentAddress);
3105
3106   // Sort the symbols by address, just in case they didn't come in that way.
3107   std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());
3108
3109   // Build a data in code table that is sorted on by the address of each entry.
3110   uint64_t BaseAddress = 0;
3111   if (Header.filetype == MachO::MH_OBJECT)
3112     BaseAddress = Sections[0].getAddress();
3113   else
3114     BaseAddress = BaseSegmentAddress;
3115   DiceTable Dices;
3116   for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
3117        DI != DE; ++DI) {
3118     uint32_t Offset;
3119     DI->getOffset(Offset);
3120     Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
3121   }
3122   array_pod_sort(Dices.begin(), Dices.end());
3123
3124 #ifndef NDEBUG
3125   raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
3126 #else
3127   raw_ostream &DebugOut = nulls();
3128 #endif
3129
3130   std::unique_ptr<DIContext> diContext;
3131   ObjectFile *DbgObj = MachOOF;
3132   // Try to find debug info and set up the DIContext for it.
3133   if (UseDbg) {
3134     // A separate DSym file path was specified, parse it as a macho file,
3135     // get the sections and supply it to the section name parsing machinery.
3136     if (!DSYMFile.empty()) {
3137       ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
3138           MemoryBuffer::getFileOrSTDIN(DSYMFile);
3139       if (std::error_code EC = BufOrErr.getError()) {
3140         errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n';
3141         return;
3142       }
3143       DbgObj =
3144           ObjectFile::createMachOObjectFile(BufOrErr.get()->getMemBufferRef())
3145               .get()
3146               .release();
3147     }
3148
3149     // Setup the DIContext
3150     diContext.reset(DIContext::getDWARFContext(*DbgObj));
3151   }
3152
3153   if (DumpSections.size() == 0)
3154     outs() << "(" << DisSegName << "," << DisSectName << ") section\n";
3155
3156   for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
3157     StringRef SectName;
3158     if (Sections[SectIdx].getName(SectName) || SectName != DisSectName)
3159       continue;
3160
3161     DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
3162
3163     StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
3164     if (SegmentName != DisSegName)
3165       continue;
3166
3167     StringRef BytesStr;
3168     Sections[SectIdx].getContents(BytesStr);
3169     ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
3170                             BytesStr.size());
3171     uint64_t SectAddress = Sections[SectIdx].getAddress();
3172
3173     bool symbolTableWorked = false;
3174
3175     // Parse relocations.
3176     std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
3177     for (const RelocationRef &Reloc : Sections[SectIdx].relocations()) {
3178       uint64_t RelocOffset;
3179       Reloc.getOffset(RelocOffset);
3180       uint64_t SectionAddress = Sections[SectIdx].getAddress();
3181       RelocOffset -= SectionAddress;
3182
3183       symbol_iterator RelocSym = Reloc.getSymbol();
3184
3185       Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
3186     }
3187     array_pod_sort(Relocs.begin(), Relocs.end());
3188
3189     // Create a map of symbol addresses to symbol names for use by
3190     // the SymbolizerSymbolLookUp() routine.
3191     SymbolAddressMap AddrMap;
3192     bool DisSymNameFound = false;
3193     for (const SymbolRef &Symbol : MachOOF->symbols()) {
3194       SymbolRef::Type ST;
3195       Symbol.getType(ST);
3196       if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
3197           ST == SymbolRef::ST_Other) {
3198         uint64_t Address;
3199         Symbol.getAddress(Address);
3200         StringRef SymName;
3201         Symbol.getName(SymName);
3202         AddrMap[Address] = SymName;
3203         if (!DisSymName.empty() && DisSymName == SymName)
3204           DisSymNameFound = true;
3205       }
3206     }
3207     if (!DisSymName.empty() && DisSymNameFound == false) {
3208       outs() << "Can't find -dis-symname: " << DisSymName << "\n";
3209       return;
3210     }
3211     // Set up the block of info used by the Symbolizer call backs.
3212     SymbolizerInfo.verbose = true;
3213     SymbolizerInfo.O = MachOOF;
3214     SymbolizerInfo.S = Sections[SectIdx];
3215     SymbolizerInfo.AddrMap = &AddrMap;
3216     SymbolizerInfo.Sections = &Sections;
3217     SymbolizerInfo.class_name = nullptr;
3218     SymbolizerInfo.selector_name = nullptr;
3219     SymbolizerInfo.method = nullptr;
3220     SymbolizerInfo.demangled_name = nullptr;
3221     SymbolizerInfo.bindtable = nullptr;
3222     SymbolizerInfo.adrp_addr = 0;
3223     SymbolizerInfo.adrp_inst = 0;
3224     // Same for the ThumbSymbolizer
3225     ThumbSymbolizerInfo.verbose = true;
3226     ThumbSymbolizerInfo.O = MachOOF;
3227     ThumbSymbolizerInfo.S = Sections[SectIdx];
3228     ThumbSymbolizerInfo.AddrMap = &AddrMap;
3229     ThumbSymbolizerInfo.Sections = &Sections;
3230     ThumbSymbolizerInfo.class_name = nullptr;
3231     ThumbSymbolizerInfo.selector_name = nullptr;
3232     ThumbSymbolizerInfo.method = nullptr;
3233     ThumbSymbolizerInfo.demangled_name = nullptr;
3234     ThumbSymbolizerInfo.bindtable = nullptr;
3235     ThumbSymbolizerInfo.adrp_addr = 0;
3236     ThumbSymbolizerInfo.adrp_inst = 0;
3237
3238     // Disassemble symbol by symbol.
3239     for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
3240       StringRef SymName;
3241       Symbols[SymIdx].getName(SymName);
3242
3243       SymbolRef::Type ST;
3244       Symbols[SymIdx].getType(ST);
3245       if (ST != SymbolRef::ST_Function)
3246         continue;
3247
3248       // Make sure the symbol is defined in this section.
3249       bool containsSym = Sections[SectIdx].containsSymbol(Symbols[SymIdx]);
3250       if (!containsSym)
3251         continue;
3252
3253       // If we are only disassembling one symbol see if this is that symbol.
3254       if (!DisSymName.empty() && DisSymName != SymName)
3255         continue;
3256
3257       // Start at the address of the symbol relative to the section's address.
3258       uint64_t Start = 0;
3259       uint64_t SectionAddress = Sections[SectIdx].getAddress();
3260       Symbols[SymIdx].getAddress(Start);
3261       Start -= SectionAddress;
3262
3263       // Stop disassembling either at the beginning of the next symbol or at
3264       // the end of the section.
3265       bool containsNextSym = false;
3266       uint64_t NextSym = 0;
3267       uint64_t NextSymIdx = SymIdx + 1;
3268       while (Symbols.size() > NextSymIdx) {
3269         SymbolRef::Type NextSymType;
3270         Symbols[NextSymIdx].getType(NextSymType);
3271         if (NextSymType == SymbolRef::ST_Function) {
3272           containsNextSym =
3273               Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]);
3274           Symbols[NextSymIdx].getAddress(NextSym);
3275           NextSym -= SectionAddress;
3276           break;
3277         }
3278         ++NextSymIdx;
3279       }
3280
3281       uint64_t SectSize = Sections[SectIdx].getSize();
3282       uint64_t End = containsNextSym ? NextSym : SectSize;
3283       uint64_t Size;
3284
3285       symbolTableWorked = true;
3286
3287       DataRefImpl Symb = Symbols[SymIdx].getRawDataRefImpl();
3288       bool isThumb =
3289           (MachOOF->getSymbolFlags(Symb) & SymbolRef::SF_Thumb) && ThumbTarget;
3290
3291       outs() << SymName << ":\n";
3292       DILineInfo lastLine;
3293       for (uint64_t Index = Start; Index < End; Index += Size) {
3294         MCInst Inst;
3295
3296         uint64_t PC = SectAddress + Index;
3297         if (!NoLeadingAddr) {
3298           if (FullLeadingAddr) {
3299             if (MachOOF->is64Bit())
3300               outs() << format("%016" PRIx64, PC);
3301             else
3302               outs() << format("%08" PRIx64, PC);
3303           } else {
3304             outs() << format("%8" PRIx64 ":", PC);
3305           }
3306         }
3307         if (!NoShowRawInsn)
3308           outs() << "\t";
3309
3310         // Check the data in code table here to see if this is data not an
3311         // instruction to be disassembled.
3312         DiceTable Dice;
3313         Dice.push_back(std::make_pair(PC, DiceRef()));
3314         dice_table_iterator DTI =
3315             std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(),
3316                         compareDiceTableEntries);
3317         if (DTI != Dices.end()) {
3318           uint16_t Length;
3319           DTI->second.getLength(Length);
3320           uint16_t Kind;
3321           DTI->second.getKind(Kind);
3322           Size = DumpDataInCode(reinterpret_cast<const char *>(Bytes.data()) +
3323                                     Index,
3324                                 Length, Kind);
3325           if ((Kind == MachO::DICE_KIND_JUMP_TABLE8) &&
3326               (PC == (DTI->first + Length - 1)) && (Length & 1))
3327             Size++;
3328           continue;
3329         }
3330
3331         SmallVector<char, 64> AnnotationsBytes;
3332         raw_svector_ostream Annotations(AnnotationsBytes);
3333
3334         bool gotInst;
3335         if (isThumb)
3336           gotInst = ThumbDisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
3337                                                 PC, DebugOut, Annotations);
3338         else
3339           gotInst = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index), PC,
3340                                            DebugOut, Annotations);
3341         if (gotInst) {
3342           if (!NoShowRawInsn) {
3343             DumpBytes(StringRef(
3344                 reinterpret_cast<const char *>(Bytes.data()) + Index, Size));
3345           }
3346           formatted_raw_ostream FormattedOS(outs());
3347           Annotations.flush();
3348           StringRef AnnotationsStr = Annotations.str();
3349           if (isThumb)
3350             ThumbIP->printInst(&Inst, FormattedOS, AnnotationsStr);
3351           else
3352             IP->printInst(&Inst, FormattedOS, AnnotationsStr);
3353           emitComments(CommentStream, CommentsToEmit, FormattedOS, *AsmInfo);
3354
3355           // Print debug info.
3356           if (diContext) {
3357             DILineInfo dli = diContext->getLineInfoForAddress(PC);
3358             // Print valid line info if it changed.
3359             if (dli != lastLine && dli.Line != 0)
3360               outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
3361                      << dli.Column;
3362             lastLine = dli;
3363           }
3364           outs() << "\n";
3365         } else {
3366           unsigned int Arch = MachOOF->getArch();
3367           if (Arch == Triple::x86_64 || Arch == Triple::x86) {
3368             outs() << format("\t.byte 0x%02x #bad opcode\n",
3369                              *(Bytes.data() + Index) & 0xff);
3370             Size = 1; // skip exactly one illegible byte and move on.
3371           } else if (Arch == Triple::aarch64) {
3372             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
3373                               (*(Bytes.data() + Index + 1) & 0xff) << 8 |
3374                               (*(Bytes.data() + Index + 2) & 0xff) << 16 |
3375                               (*(Bytes.data() + Index + 3) & 0xff) << 24;
3376             outs() << format("\t.long\t0x%08x\n", opcode);
3377             Size = 4;
3378           } else {
3379             errs() << "llvm-objdump: warning: invalid instruction encoding\n";
3380             if (Size == 0)
3381               Size = 1; // skip illegible bytes
3382           }
3383         }
3384       }
3385     }
3386     if (!symbolTableWorked) {
3387       // Reading the symbol table didn't work, disassemble the whole section.
3388       uint64_t SectAddress = Sections[SectIdx].getAddress();
3389       uint64_t SectSize = Sections[SectIdx].getSize();
3390       uint64_t InstSize;
3391       for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
3392         MCInst Inst;
3393
3394         uint64_t PC = SectAddress + Index;
3395         if (DisAsm->getInstruction(Inst, InstSize, Bytes.slice(Index), PC,
3396                                    DebugOut, nulls())) {
3397           if (!NoLeadingAddr) {
3398             if (FullLeadingAddr) {
3399               if (MachOOF->is64Bit())
3400                 outs() << format("%016" PRIx64, PC);
3401               else
3402                 outs() << format("%08" PRIx64, PC);
3403             } else {
3404               outs() << format("%8" PRIx64 ":", PC);
3405             }
3406           }
3407           if (!NoShowRawInsn) {
3408             outs() << "\t";
3409             DumpBytes(
3410                 StringRef(reinterpret_cast<const char *>(Bytes.data()) + Index,
3411                           InstSize));
3412           }
3413           IP->printInst(&Inst, outs(), "");
3414           outs() << "\n";
3415         } else {
3416           unsigned int Arch = MachOOF->getArch();
3417           if (Arch == Triple::x86_64 || Arch == Triple::x86) {
3418             outs() << format("\t.byte 0x%02x #bad opcode\n",
3419                              *(Bytes.data() + Index) & 0xff);
3420             InstSize = 1; // skip exactly one illegible byte and move on.
3421           } else {
3422             errs() << "llvm-objdump: warning: invalid instruction encoding\n";
3423             if (InstSize == 0)
3424               InstSize = 1; // skip illegible bytes
3425           }
3426         }
3427       }
3428     }
3429     // The TripleName's need to be reset if we are called again for a different
3430     // archtecture.
3431     TripleName = "";
3432     ThumbTripleName = "";
3433
3434     if (SymbolizerInfo.method != nullptr)
3435       free(SymbolizerInfo.method);
3436     if (SymbolizerInfo.demangled_name != nullptr)
3437       free(SymbolizerInfo.demangled_name);
3438     if (SymbolizerInfo.bindtable != nullptr)
3439       delete SymbolizerInfo.bindtable;
3440     if (ThumbSymbolizerInfo.method != nullptr)
3441       free(ThumbSymbolizerInfo.method);
3442     if (ThumbSymbolizerInfo.demangled_name != nullptr)
3443       free(ThumbSymbolizerInfo.demangled_name);
3444     if (ThumbSymbolizerInfo.bindtable != nullptr)
3445       delete ThumbSymbolizerInfo.bindtable;
3446   }
3447 }
3448
3449 //===----------------------------------------------------------------------===//
3450 // __compact_unwind section dumping
3451 //===----------------------------------------------------------------------===//
3452
3453 namespace {
3454
3455 template <typename T> static uint64_t readNext(const char *&Buf) {
3456   using llvm::support::little;
3457   using llvm::support::unaligned;
3458
3459   uint64_t Val = support::endian::read<T, little, unaligned>(Buf);
3460   Buf += sizeof(T);
3461   return Val;
3462 }
3463
3464 struct CompactUnwindEntry {
3465   uint32_t OffsetInSection;
3466
3467   uint64_t FunctionAddr;
3468   uint32_t Length;
3469   uint32_t CompactEncoding;
3470   uint64_t PersonalityAddr;
3471   uint64_t LSDAAddr;
3472
3473   RelocationRef FunctionReloc;
3474   RelocationRef PersonalityReloc;
3475   RelocationRef LSDAReloc;
3476
3477   CompactUnwindEntry(StringRef Contents, unsigned Offset, bool Is64)
3478       : OffsetInSection(Offset) {
3479     if (Is64)
3480       read<uint64_t>(Contents.data() + Offset);
3481     else
3482       read<uint32_t>(Contents.data() + Offset);
3483   }
3484
3485 private:
3486   template <typename UIntPtr> void read(const char *Buf) {
3487     FunctionAddr = readNext<UIntPtr>(Buf);
3488     Length = readNext<uint32_t>(Buf);
3489     CompactEncoding = readNext<uint32_t>(Buf);
3490     PersonalityAddr = readNext<UIntPtr>(Buf);
3491     LSDAAddr = readNext<UIntPtr>(Buf);
3492   }
3493 };
3494 }
3495
3496 /// Given a relocation from __compact_unwind, consisting of the RelocationRef
3497 /// and data being relocated, determine the best base Name and Addend to use for
3498 /// display purposes.
3499 ///
3500 /// 1. An Extern relocation will directly reference a symbol (and the data is
3501 ///    then already an addend), so use that.
3502 /// 2. Otherwise the data is an offset in the object file's layout; try to find
3503 //     a symbol before it in the same section, and use the offset from there.
3504 /// 3. Finally, if all that fails, fall back to an offset from the start of the
3505 ///    referenced section.
3506 static void findUnwindRelocNameAddend(const MachOObjectFile *Obj,
3507                                       std::map<uint64_t, SymbolRef> &Symbols,
3508                                       const RelocationRef &Reloc, uint64_t Addr,
3509                                       StringRef &Name, uint64_t &Addend) {
3510   if (Reloc.getSymbol() != Obj->symbol_end()) {
3511     Reloc.getSymbol()->getName(Name);
3512     Addend = Addr;
3513     return;
3514   }
3515
3516   auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl());
3517   SectionRef RelocSection = Obj->getRelocationSection(RE);
3518
3519   uint64_t SectionAddr = RelocSection.getAddress();
3520
3521   auto Sym = Symbols.upper_bound(Addr);
3522   if (Sym == Symbols.begin()) {
3523     // The first symbol in the object is after this reference, the best we can
3524     // do is section-relative notation.
3525     RelocSection.getName(Name);
3526     Addend = Addr - SectionAddr;
3527     return;
3528   }
3529
3530   // Go back one so that SymbolAddress <= Addr.
3531   --Sym;
3532
3533   section_iterator SymSection = Obj->section_end();
3534   Sym->second.getSection(SymSection);
3535   if (RelocSection == *SymSection) {
3536     // There's a valid symbol in the same section before this reference.
3537     Sym->second.getName(Name);
3538     Addend = Addr - Sym->first;
3539     return;
3540   }
3541
3542   // There is a symbol before this reference, but it's in a different
3543   // section. Probably not helpful to mention it, so use the section name.
3544   RelocSection.getName(Name);
3545   Addend = Addr - SectionAddr;
3546 }
3547
3548 static void printUnwindRelocDest(const MachOObjectFile *Obj,
3549                                  std::map<uint64_t, SymbolRef> &Symbols,
3550                                  const RelocationRef &Reloc, uint64_t Addr) {
3551   StringRef Name;
3552   uint64_t Addend;
3553
3554   if (!Reloc.getObjectFile())
3555     return;
3556
3557   findUnwindRelocNameAddend(Obj, Symbols, Reloc, Addr, Name, Addend);
3558
3559   outs() << Name;
3560   if (Addend)
3561     outs() << " + " << format("0x%" PRIx64, Addend);
3562 }
3563
3564 static void
3565 printMachOCompactUnwindSection(const MachOObjectFile *Obj,
3566                                std::map<uint64_t, SymbolRef> &Symbols,
3567                                const SectionRef &CompactUnwind) {
3568
3569   assert(Obj->isLittleEndian() &&
3570          "There should not be a big-endian .o with __compact_unwind");
3571
3572   bool Is64 = Obj->is64Bit();
3573   uint32_t PointerSize = Is64 ? sizeof(uint64_t) : sizeof(uint32_t);
3574   uint32_t EntrySize = 3 * PointerSize + 2 * sizeof(uint32_t);
3575
3576   StringRef Contents;
3577   CompactUnwind.getContents(Contents);
3578
3579   SmallVector<CompactUnwindEntry, 4> CompactUnwinds;
3580
3581   // First populate the initial raw offsets, encodings and so on from the entry.
3582   for (unsigned Offset = 0; Offset < Contents.size(); Offset += EntrySize) {
3583     CompactUnwindEntry Entry(Contents.data(), Offset, Is64);
3584     CompactUnwinds.push_back(Entry);
3585   }
3586
3587   // Next we need to look at the relocations to find out what objects are
3588   // actually being referred to.
3589   for (const RelocationRef &Reloc : CompactUnwind.relocations()) {
3590     uint64_t RelocAddress;
3591     Reloc.getOffset(RelocAddress);
3592
3593     uint32_t EntryIdx = RelocAddress / EntrySize;
3594     uint32_t OffsetInEntry = RelocAddress - EntryIdx * EntrySize;
3595     CompactUnwindEntry &Entry = CompactUnwinds[EntryIdx];
3596
3597     if (OffsetInEntry == 0)
3598       Entry.FunctionReloc = Reloc;
3599     else if (OffsetInEntry == PointerSize + 2 * sizeof(uint32_t))
3600       Entry.PersonalityReloc = Reloc;
3601     else if (OffsetInEntry == 2 * PointerSize + 2 * sizeof(uint32_t))
3602       Entry.LSDAReloc = Reloc;
3603     else
3604       llvm_unreachable("Unexpected relocation in __compact_unwind section");
3605   }
3606
3607   // Finally, we're ready to print the data we've gathered.
3608   outs() << "Contents of __compact_unwind section:\n";
3609   for (auto &Entry : CompactUnwinds) {
3610     outs() << "  Entry at offset "
3611            << format("0x%" PRIx32, Entry.OffsetInSection) << ":\n";
3612
3613     // 1. Start of the region this entry applies to.
3614     outs() << "    start:                " << format("0x%" PRIx64,
3615                                                      Entry.FunctionAddr) << ' ';
3616     printUnwindRelocDest(Obj, Symbols, Entry.FunctionReloc, Entry.FunctionAddr);
3617     outs() << '\n';
3618
3619     // 2. Length of the region this entry applies to.
3620     outs() << "    length:               " << format("0x%" PRIx32, Entry.Length)
3621            << '\n';
3622     // 3. The 32-bit compact encoding.
3623     outs() << "    compact encoding:     "
3624            << format("0x%08" PRIx32, Entry.CompactEncoding) << '\n';
3625
3626     // 4. The personality function, if present.
3627     if (Entry.PersonalityReloc.getObjectFile()) {
3628       outs() << "    personality function: "
3629              << format("0x%" PRIx64, Entry.PersonalityAddr) << ' ';
3630       printUnwindRelocDest(Obj, Symbols, Entry.PersonalityReloc,
3631                            Entry.PersonalityAddr);
3632       outs() << '\n';
3633     }
3634
3635     // 5. This entry's language-specific data area.
3636     if (Entry.LSDAReloc.getObjectFile()) {
3637       outs() << "    LSDA:                 " << format("0x%" PRIx64,
3638                                                        Entry.LSDAAddr) << ' ';
3639       printUnwindRelocDest(Obj, Symbols, Entry.LSDAReloc, Entry.LSDAAddr);
3640       outs() << '\n';
3641     }
3642   }
3643 }
3644
3645 //===----------------------------------------------------------------------===//
3646 // __unwind_info section dumping
3647 //===----------------------------------------------------------------------===//
3648
3649 static void printRegularSecondLevelUnwindPage(const char *PageStart) {
3650   const char *Pos = PageStart;
3651   uint32_t Kind = readNext<uint32_t>(Pos);
3652   (void)Kind;
3653   assert(Kind == 2 && "kind for a regular 2nd level index should be 2");
3654
3655   uint16_t EntriesStart = readNext<uint16_t>(Pos);
3656   uint16_t NumEntries = readNext<uint16_t>(Pos);
3657
3658   Pos = PageStart + EntriesStart;
3659   for (unsigned i = 0; i < NumEntries; ++i) {
3660     uint32_t FunctionOffset = readNext<uint32_t>(Pos);
3661     uint32_t Encoding = readNext<uint32_t>(Pos);
3662
3663     outs() << "      [" << i << "]: "
3664            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
3665            << ", "
3666            << "encoding=" << format("0x%08" PRIx32, Encoding) << '\n';
3667   }
3668 }
3669
3670 static void printCompressedSecondLevelUnwindPage(
3671     const char *PageStart, uint32_t FunctionBase,
3672     const SmallVectorImpl<uint32_t> &CommonEncodings) {
3673   const char *Pos = PageStart;
3674   uint32_t Kind = readNext<uint32_t>(Pos);
3675   (void)Kind;
3676   assert(Kind == 3 && "kind for a compressed 2nd level index should be 3");
3677
3678   uint16_t EntriesStart = readNext<uint16_t>(Pos);
3679   uint16_t NumEntries = readNext<uint16_t>(Pos);
3680
3681   uint16_t EncodingsStart = readNext<uint16_t>(Pos);
3682   readNext<uint16_t>(Pos);
3683   const auto *PageEncodings = reinterpret_cast<const support::ulittle32_t *>(
3684       PageStart + EncodingsStart);
3685
3686   Pos = PageStart + EntriesStart;
3687   for (unsigned i = 0; i < NumEntries; ++i) {
3688     uint32_t Entry = readNext<uint32_t>(Pos);
3689     uint32_t FunctionOffset = FunctionBase + (Entry & 0xffffff);
3690     uint32_t EncodingIdx = Entry >> 24;
3691
3692     uint32_t Encoding;
3693     if (EncodingIdx < CommonEncodings.size())
3694       Encoding = CommonEncodings[EncodingIdx];
3695     else
3696       Encoding = PageEncodings[EncodingIdx - CommonEncodings.size()];
3697
3698     outs() << "      [" << i << "]: "
3699            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
3700            << ", "
3701            << "encoding[" << EncodingIdx
3702            << "]=" << format("0x%08" PRIx32, Encoding) << '\n';
3703   }
3704 }
3705
3706 static void printMachOUnwindInfoSection(const MachOObjectFile *Obj,
3707                                         std::map<uint64_t, SymbolRef> &Symbols,
3708                                         const SectionRef &UnwindInfo) {
3709
3710   assert(Obj->isLittleEndian() &&
3711          "There should not be a big-endian .o with __unwind_info");
3712
3713   outs() << "Contents of __unwind_info section:\n";
3714
3715   StringRef Contents;
3716   UnwindInfo.getContents(Contents);
3717   const char *Pos = Contents.data();
3718
3719   //===----------------------------------
3720   // Section header
3721   //===----------------------------------
3722
3723   uint32_t Version = readNext<uint32_t>(Pos);
3724   outs() << "  Version:                                   "
3725          << format("0x%" PRIx32, Version) << '\n';
3726   assert(Version == 1 && "only understand version 1");
3727
3728   uint32_t CommonEncodingsStart = readNext<uint32_t>(Pos);
3729   outs() << "  Common encodings array section offset:     "
3730          << format("0x%" PRIx32, CommonEncodingsStart) << '\n';
3731   uint32_t NumCommonEncodings = readNext<uint32_t>(Pos);
3732   outs() << "  Number of common encodings in array:       "
3733          << format("0x%" PRIx32, NumCommonEncodings) << '\n';
3734
3735   uint32_t PersonalitiesStart = readNext<uint32_t>(Pos);
3736   outs() << "  Personality function array section offset: "
3737          << format("0x%" PRIx32, PersonalitiesStart) << '\n';
3738   uint32_t NumPersonalities = readNext<uint32_t>(Pos);
3739   outs() << "  Number of personality functions in array:  "
3740          << format("0x%" PRIx32, NumPersonalities) << '\n';
3741
3742   uint32_t IndicesStart = readNext<uint32_t>(Pos);
3743   outs() << "  Index array section offset:                "
3744          << format("0x%" PRIx32, IndicesStart) << '\n';
3745   uint32_t NumIndices = readNext<uint32_t>(Pos);
3746   outs() << "  Number of indices in array:                "
3747          << format("0x%" PRIx32, NumIndices) << '\n';
3748
3749   //===----------------------------------
3750   // A shared list of common encodings
3751   //===----------------------------------
3752
3753   // These occupy indices in the range [0, N] whenever an encoding is referenced
3754   // from a compressed 2nd level index table. In practice the linker only
3755   // creates ~128 of these, so that indices are available to embed encodings in
3756   // the 2nd level index.
3757
3758   SmallVector<uint32_t, 64> CommonEncodings;
3759   outs() << "  Common encodings: (count = " << NumCommonEncodings << ")\n";
3760   Pos = Contents.data() + CommonEncodingsStart;
3761   for (unsigned i = 0; i < NumCommonEncodings; ++i) {
3762     uint32_t Encoding = readNext<uint32_t>(Pos);
3763     CommonEncodings.push_back(Encoding);
3764
3765     outs() << "    encoding[" << i << "]: " << format("0x%08" PRIx32, Encoding)
3766            << '\n';
3767   }
3768
3769   //===----------------------------------
3770   // Personality functions used in this executable
3771   //===----------------------------------
3772
3773   // There should be only a handful of these (one per source language,
3774   // roughly). Particularly since they only get 2 bits in the compact encoding.
3775
3776   outs() << "  Personality functions: (count = " << NumPersonalities << ")\n";
3777   Pos = Contents.data() + PersonalitiesStart;
3778   for (unsigned i = 0; i < NumPersonalities; ++i) {
3779     uint32_t PersonalityFn = readNext<uint32_t>(Pos);
3780     outs() << "    personality[" << i + 1
3781            << "]: " << format("0x%08" PRIx32, PersonalityFn) << '\n';
3782   }
3783
3784   //===----------------------------------
3785   // The level 1 index entries
3786   //===----------------------------------
3787
3788   // These specify an approximate place to start searching for the more detailed
3789   // information, sorted by PC.
3790
3791   struct IndexEntry {
3792     uint32_t FunctionOffset;
3793     uint32_t SecondLevelPageStart;
3794     uint32_t LSDAStart;
3795   };
3796
3797   SmallVector<IndexEntry, 4> IndexEntries;
3798
3799   outs() << "  Top level indices: (count = " << NumIndices << ")\n";
3800   Pos = Contents.data() + IndicesStart;
3801   for (unsigned i = 0; i < NumIndices; ++i) {
3802     IndexEntry Entry;
3803
3804     Entry.FunctionOffset = readNext<uint32_t>(Pos);
3805     Entry.SecondLevelPageStart = readNext<uint32_t>(Pos);
3806     Entry.LSDAStart = readNext<uint32_t>(Pos);
3807     IndexEntries.push_back(Entry);
3808
3809     outs() << "    [" << i << "]: "
3810            << "function offset=" << format("0x%08" PRIx32, Entry.FunctionOffset)
3811            << ", "
3812            << "2nd level page offset="
3813            << format("0x%08" PRIx32, Entry.SecondLevelPageStart) << ", "
3814            << "LSDA offset=" << format("0x%08" PRIx32, Entry.LSDAStart) << '\n';
3815   }
3816
3817   //===----------------------------------
3818   // Next come the LSDA tables
3819   //===----------------------------------
3820
3821   // The LSDA layout is rather implicit: it's a contiguous array of entries from
3822   // the first top-level index's LSDAOffset to the last (sentinel).
3823
3824   outs() << "  LSDA descriptors:\n";
3825   Pos = Contents.data() + IndexEntries[0].LSDAStart;
3826   int NumLSDAs = (IndexEntries.back().LSDAStart - IndexEntries[0].LSDAStart) /
3827                  (2 * sizeof(uint32_t));
3828   for (int i = 0; i < NumLSDAs; ++i) {
3829     uint32_t FunctionOffset = readNext<uint32_t>(Pos);
3830     uint32_t LSDAOffset = readNext<uint32_t>(Pos);
3831     outs() << "    [" << i << "]: "
3832            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
3833            << ", "
3834            << "LSDA offset=" << format("0x%08" PRIx32, LSDAOffset) << '\n';
3835   }
3836
3837   //===----------------------------------
3838   // Finally, the 2nd level indices
3839   //===----------------------------------
3840
3841   // Generally these are 4K in size, and have 2 possible forms:
3842   //   + Regular stores up to 511 entries with disparate encodings
3843   //   + Compressed stores up to 1021 entries if few enough compact encoding
3844   //     values are used.
3845   outs() << "  Second level indices:\n";
3846   for (unsigned i = 0; i < IndexEntries.size() - 1; ++i) {
3847     // The final sentinel top-level index has no associated 2nd level page
3848     if (IndexEntries[i].SecondLevelPageStart == 0)
3849       break;
3850
3851     outs() << "    Second level index[" << i << "]: "
3852            << "offset in section="
3853            << format("0x%08" PRIx32, IndexEntries[i].SecondLevelPageStart)
3854            << ", "
3855            << "base function offset="
3856            << format("0x%08" PRIx32, IndexEntries[i].FunctionOffset) << '\n';
3857
3858     Pos = Contents.data() + IndexEntries[i].SecondLevelPageStart;
3859     uint32_t Kind = *reinterpret_cast<const support::ulittle32_t *>(Pos);
3860     if (Kind == 2)
3861       printRegularSecondLevelUnwindPage(Pos);
3862     else if (Kind == 3)
3863       printCompressedSecondLevelUnwindPage(Pos, IndexEntries[i].FunctionOffset,
3864                                            CommonEncodings);
3865     else
3866       llvm_unreachable("Do not know how to print this kind of 2nd level page");
3867   }
3868 }
3869
3870 void llvm::printMachOUnwindInfo(const MachOObjectFile *Obj) {
3871   std::map<uint64_t, SymbolRef> Symbols;
3872   for (const SymbolRef &SymRef : Obj->symbols()) {
3873     // Discard any undefined or absolute symbols. They're not going to take part
3874     // in the convenience lookup for unwind info and just take up resources.
3875     section_iterator Section = Obj->section_end();
3876     SymRef.getSection(Section);
3877     if (Section == Obj->section_end())
3878       continue;
3879
3880     uint64_t Addr;
3881     SymRef.getAddress(Addr);
3882     Symbols.insert(std::make_pair(Addr, SymRef));
3883   }
3884
3885   for (const SectionRef &Section : Obj->sections()) {
3886     StringRef SectName;
3887     Section.getName(SectName);
3888     if (SectName == "__compact_unwind")
3889       printMachOCompactUnwindSection(Obj, Symbols, Section);
3890     else if (SectName == "__unwind_info")
3891       printMachOUnwindInfoSection(Obj, Symbols, Section);
3892     else if (SectName == "__eh_frame")
3893       outs() << "llvm-objdump: warning: unhandled __eh_frame section\n";
3894   }
3895 }
3896
3897 static void PrintMachHeader(uint32_t magic, uint32_t cputype,
3898                             uint32_t cpusubtype, uint32_t filetype,
3899                             uint32_t ncmds, uint32_t sizeofcmds, uint32_t flags,
3900                             bool verbose) {
3901   outs() << "Mach header\n";
3902   outs() << "      magic cputype cpusubtype  caps    filetype ncmds "
3903             "sizeofcmds      flags\n";
3904   if (verbose) {
3905     if (magic == MachO::MH_MAGIC)
3906       outs() << "   MH_MAGIC";
3907     else if (magic == MachO::MH_MAGIC_64)
3908       outs() << "MH_MAGIC_64";
3909     else
3910       outs() << format(" 0x%08" PRIx32, magic);
3911     switch (cputype) {
3912     case MachO::CPU_TYPE_I386:
3913       outs() << "    I386";
3914       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
3915       case MachO::CPU_SUBTYPE_I386_ALL:
3916         outs() << "        ALL";
3917         break;
3918       default:
3919         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
3920         break;
3921       }
3922       break;
3923     case MachO::CPU_TYPE_X86_64:
3924       outs() << "  X86_64";
3925       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
3926       case MachO::CPU_SUBTYPE_X86_64_ALL:
3927         outs() << "        ALL";
3928         break;
3929       case MachO::CPU_SUBTYPE_X86_64_H:
3930         outs() << "    Haswell";
3931         break;
3932       default:
3933         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
3934         break;
3935       }
3936       break;
3937     case MachO::CPU_TYPE_ARM:
3938       outs() << "     ARM";
3939       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
3940       case MachO::CPU_SUBTYPE_ARM_ALL:
3941         outs() << "        ALL";
3942         break;
3943       case MachO::CPU_SUBTYPE_ARM_V4T:
3944         outs() << "        V4T";
3945         break;
3946       case MachO::CPU_SUBTYPE_ARM_V5TEJ:
3947         outs() << "      V5TEJ";
3948         break;
3949       case MachO::CPU_SUBTYPE_ARM_XSCALE:
3950         outs() << "     XSCALE";
3951         break;
3952       case MachO::CPU_SUBTYPE_ARM_V6:
3953         outs() << "         V6";
3954         break;
3955       case MachO::CPU_SUBTYPE_ARM_V6M:
3956         outs() << "        V6M";
3957         break;
3958       case MachO::CPU_SUBTYPE_ARM_V7:
3959         outs() << "         V7";
3960         break;
3961       case MachO::CPU_SUBTYPE_ARM_V7EM:
3962         outs() << "       V7EM";
3963         break;
3964       case MachO::CPU_SUBTYPE_ARM_V7K:
3965         outs() << "        V7K";
3966         break;
3967       case MachO::CPU_SUBTYPE_ARM_V7M:
3968         outs() << "        V7M";
3969         break;
3970       case MachO::CPU_SUBTYPE_ARM_V7S:
3971         outs() << "        V7S";
3972         break;
3973       default:
3974         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
3975         break;
3976       }
3977       break;
3978     case MachO::CPU_TYPE_ARM64:
3979       outs() << "   ARM64";
3980       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
3981       case MachO::CPU_SUBTYPE_ARM64_ALL:
3982         outs() << "        ALL";
3983         break;
3984       default:
3985         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
3986         break;
3987       }
3988       break;
3989     case MachO::CPU_TYPE_POWERPC:
3990       outs() << "     PPC";
3991       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
3992       case MachO::CPU_SUBTYPE_POWERPC_ALL:
3993         outs() << "        ALL";
3994         break;
3995       default:
3996         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
3997         break;
3998       }
3999       break;
4000     case MachO::CPU_TYPE_POWERPC64:
4001       outs() << "   PPC64";
4002       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
4003       case MachO::CPU_SUBTYPE_POWERPC_ALL:
4004         outs() << "        ALL";
4005         break;
4006       default:
4007         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
4008         break;
4009       }
4010       break;
4011     }
4012     if ((cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64) {
4013       outs() << " LIB64";
4014     } else {
4015       outs() << format("  0x%02" PRIx32,
4016                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
4017     }
4018     switch (filetype) {
4019     case MachO::MH_OBJECT:
4020       outs() << "      OBJECT";
4021       break;
4022     case MachO::MH_EXECUTE:
4023       outs() << "     EXECUTE";
4024       break;
4025     case MachO::MH_FVMLIB:
4026       outs() << "      FVMLIB";
4027       break;
4028     case MachO::MH_CORE:
4029       outs() << "        CORE";
4030       break;
4031     case MachO::MH_PRELOAD:
4032       outs() << "     PRELOAD";
4033       break;
4034     case MachO::MH_DYLIB:
4035       outs() << "       DYLIB";
4036       break;
4037     case MachO::MH_DYLIB_STUB:
4038       outs() << "  DYLIB_STUB";
4039       break;
4040     case MachO::MH_DYLINKER:
4041       outs() << "    DYLINKER";
4042       break;
4043     case MachO::MH_BUNDLE:
4044       outs() << "      BUNDLE";
4045       break;
4046     case MachO::MH_DSYM:
4047       outs() << "        DSYM";
4048       break;
4049     case MachO::MH_KEXT_BUNDLE:
4050       outs() << "  KEXTBUNDLE";
4051       break;
4052     default:
4053       outs() << format("  %10u", filetype);
4054       break;
4055     }
4056     outs() << format(" %5u", ncmds);
4057     outs() << format(" %10u", sizeofcmds);
4058     uint32_t f = flags;
4059     if (f & MachO::MH_NOUNDEFS) {
4060       outs() << "   NOUNDEFS";
4061       f &= ~MachO::MH_NOUNDEFS;
4062     }
4063     if (f & MachO::MH_INCRLINK) {
4064       outs() << " INCRLINK";
4065       f &= ~MachO::MH_INCRLINK;
4066     }
4067     if (f & MachO::MH_DYLDLINK) {
4068       outs() << " DYLDLINK";
4069       f &= ~MachO::MH_DYLDLINK;
4070     }
4071     if (f & MachO::MH_BINDATLOAD) {
4072       outs() << " BINDATLOAD";
4073       f &= ~MachO::MH_BINDATLOAD;
4074     }
4075     if (f & MachO::MH_PREBOUND) {
4076       outs() << " PREBOUND";
4077       f &= ~MachO::MH_PREBOUND;
4078     }
4079     if (f & MachO::MH_SPLIT_SEGS) {
4080       outs() << " SPLIT_SEGS";
4081       f &= ~MachO::MH_SPLIT_SEGS;
4082     }
4083     if (f & MachO::MH_LAZY_INIT) {
4084       outs() << " LAZY_INIT";
4085       f &= ~MachO::MH_LAZY_INIT;
4086     }
4087     if (f & MachO::MH_TWOLEVEL) {
4088       outs() << " TWOLEVEL";
4089       f &= ~MachO::MH_TWOLEVEL;
4090     }
4091     if (f & MachO::MH_FORCE_FLAT) {
4092       outs() << " FORCE_FLAT";
4093       f &= ~MachO::MH_FORCE_FLAT;
4094     }
4095     if (f & MachO::MH_NOMULTIDEFS) {
4096       outs() << " NOMULTIDEFS";
4097       f &= ~MachO::MH_NOMULTIDEFS;
4098     }
4099     if (f & MachO::MH_NOFIXPREBINDING) {
4100       outs() << " NOFIXPREBINDING";
4101       f &= ~MachO::MH_NOFIXPREBINDING;
4102     }
4103     if (f & MachO::MH_PREBINDABLE) {
4104       outs() << " PREBINDABLE";
4105       f &= ~MachO::MH_PREBINDABLE;
4106     }
4107     if (f & MachO::MH_ALLMODSBOUND) {
4108       outs() << " ALLMODSBOUND";
4109       f &= ~MachO::MH_ALLMODSBOUND;
4110     }
4111     if (f & MachO::MH_SUBSECTIONS_VIA_SYMBOLS) {
4112       outs() << " SUBSECTIONS_VIA_SYMBOLS";
4113       f &= ~MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
4114     }
4115     if (f & MachO::MH_CANONICAL) {
4116       outs() << " CANONICAL";
4117       f &= ~MachO::MH_CANONICAL;
4118     }
4119     if (f & MachO::MH_WEAK_DEFINES) {
4120       outs() << " WEAK_DEFINES";
4121       f &= ~MachO::MH_WEAK_DEFINES;
4122     }
4123     if (f & MachO::MH_BINDS_TO_WEAK) {
4124       outs() << " BINDS_TO_WEAK";
4125       f &= ~MachO::MH_BINDS_TO_WEAK;
4126     }
4127     if (f & MachO::MH_ALLOW_STACK_EXECUTION) {
4128       outs() << " ALLOW_STACK_EXECUTION";
4129       f &= ~MachO::MH_ALLOW_STACK_EXECUTION;
4130     }
4131     if (f & MachO::MH_DEAD_STRIPPABLE_DYLIB) {
4132       outs() << " DEAD_STRIPPABLE_DYLIB";
4133       f &= ~MachO::MH_DEAD_STRIPPABLE_DYLIB;
4134     }
4135     if (f & MachO::MH_PIE) {
4136       outs() << " PIE";
4137       f &= ~MachO::MH_PIE;
4138     }
4139     if (f & MachO::MH_NO_REEXPORTED_DYLIBS) {
4140       outs() << " NO_REEXPORTED_DYLIBS";
4141       f &= ~MachO::MH_NO_REEXPORTED_DYLIBS;
4142     }
4143     if (f & MachO::MH_HAS_TLV_DESCRIPTORS) {
4144       outs() << " MH_HAS_TLV_DESCRIPTORS";
4145       f &= ~MachO::MH_HAS_TLV_DESCRIPTORS;
4146     }
4147     if (f & MachO::MH_NO_HEAP_EXECUTION) {
4148       outs() << " MH_NO_HEAP_EXECUTION";
4149       f &= ~MachO::MH_NO_HEAP_EXECUTION;
4150     }
4151     if (f & MachO::MH_APP_EXTENSION_SAFE) {
4152       outs() << " APP_EXTENSION_SAFE";
4153       f &= ~MachO::MH_APP_EXTENSION_SAFE;
4154     }
4155     if (f != 0 || flags == 0)
4156       outs() << format(" 0x%08" PRIx32, f);
4157   } else {
4158     outs() << format(" 0x%08" PRIx32, magic);
4159     outs() << format(" %7d", cputype);
4160     outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
4161     outs() << format("  0x%02" PRIx32,
4162                      (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
4163     outs() << format("  %10u", filetype);
4164     outs() << format(" %5u", ncmds);
4165     outs() << format(" %10u", sizeofcmds);
4166     outs() << format(" 0x%08" PRIx32, flags);
4167   }
4168   outs() << "\n";
4169 }
4170
4171 static void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize,
4172                                 StringRef SegName, uint64_t vmaddr,
4173                                 uint64_t vmsize, uint64_t fileoff,
4174                                 uint64_t filesize, uint32_t maxprot,
4175                                 uint32_t initprot, uint32_t nsects,
4176                                 uint32_t flags, uint32_t object_size,
4177                                 bool verbose) {
4178   uint64_t expected_cmdsize;
4179   if (cmd == MachO::LC_SEGMENT) {
4180     outs() << "      cmd LC_SEGMENT\n";
4181     expected_cmdsize = nsects;
4182     expected_cmdsize *= sizeof(struct MachO::section);
4183     expected_cmdsize += sizeof(struct MachO::segment_command);
4184   } else {
4185     outs() << "      cmd LC_SEGMENT_64\n";
4186     expected_cmdsize = nsects;
4187     expected_cmdsize *= sizeof(struct MachO::section_64);
4188     expected_cmdsize += sizeof(struct MachO::segment_command_64);
4189   }
4190   outs() << "  cmdsize " << cmdsize;
4191   if (cmdsize != expected_cmdsize)
4192     outs() << " Inconsistent size\n";
4193   else
4194     outs() << "\n";
4195   outs() << "  segname " << SegName << "\n";
4196   if (cmd == MachO::LC_SEGMENT_64) {
4197     outs() << "   vmaddr " << format("0x%016" PRIx64, vmaddr) << "\n";
4198     outs() << "   vmsize " << format("0x%016" PRIx64, vmsize) << "\n";
4199   } else {
4200     outs() << "   vmaddr " << format("0x%08" PRIx64, vmaddr) << "\n";
4201     outs() << "   vmsize " << format("0x%08" PRIx64, vmsize) << "\n";
4202   }
4203   outs() << "  fileoff " << fileoff;
4204   if (fileoff > object_size)
4205     outs() << " (past end of file)\n";
4206   else
4207     outs() << "\n";
4208   outs() << " filesize " << filesize;
4209   if (fileoff + filesize > object_size)
4210     outs() << " (past end of file)\n";
4211   else
4212     outs() << "\n";
4213   if (verbose) {
4214     if ((maxprot &
4215          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
4216            MachO::VM_PROT_EXECUTE)) != 0)
4217       outs() << "  maxprot ?" << format("0x%08" PRIx32, maxprot) << "\n";
4218     else {
4219       if (maxprot & MachO::VM_PROT_READ)
4220         outs() << "  maxprot r";
4221       else
4222         outs() << "  maxprot -";
4223       if (maxprot & MachO::VM_PROT_WRITE)
4224         outs() << "w";
4225       else
4226         outs() << "-";
4227       if (maxprot & MachO::VM_PROT_EXECUTE)
4228         outs() << "x\n";
4229       else
4230         outs() << "-\n";
4231     }
4232     if ((initprot &
4233          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
4234            MachO::VM_PROT_EXECUTE)) != 0)
4235       outs() << "  initprot ?" << format("0x%08" PRIx32, initprot) << "\n";
4236     else {
4237       if (initprot & MachO::VM_PROT_READ)
4238         outs() << " initprot r";
4239       else
4240         outs() << " initprot -";
4241       if (initprot & MachO::VM_PROT_WRITE)
4242         outs() << "w";
4243       else
4244         outs() << "-";
4245       if (initprot & MachO::VM_PROT_EXECUTE)
4246         outs() << "x\n";
4247       else
4248         outs() << "-\n";
4249     }
4250   } else {
4251     outs() << "  maxprot " << format("0x%08" PRIx32, maxprot) << "\n";
4252     outs() << " initprot " << format("0x%08" PRIx32, initprot) << "\n";
4253   }
4254   outs() << "   nsects " << nsects << "\n";
4255   if (verbose) {
4256     outs() << "    flags";
4257     if (flags == 0)
4258       outs() << " (none)\n";
4259     else {
4260       if (flags & MachO::SG_HIGHVM) {
4261         outs() << " HIGHVM";
4262         flags &= ~MachO::SG_HIGHVM;
4263       }
4264       if (flags & MachO::SG_FVMLIB) {
4265         outs() << " FVMLIB";
4266         flags &= ~MachO::SG_FVMLIB;
4267       }
4268       if (flags & MachO::SG_NORELOC) {
4269         outs() << " NORELOC";
4270         flags &= ~MachO::SG_NORELOC;
4271       }
4272       if (flags & MachO::SG_PROTECTED_VERSION_1) {
4273         outs() << " PROTECTED_VERSION_1";
4274         flags &= ~MachO::SG_PROTECTED_VERSION_1;
4275       }
4276       if (flags)
4277         outs() << format(" 0x%08" PRIx32, flags) << " (unknown flags)\n";
4278       else
4279         outs() << "\n";
4280     }
4281   } else {
4282     outs() << "    flags " << format("0x%" PRIx32, flags) << "\n";
4283   }
4284 }
4285
4286 static void PrintSection(const char *sectname, const char *segname,
4287                          uint64_t addr, uint64_t size, uint32_t offset,
4288                          uint32_t align, uint32_t reloff, uint32_t nreloc,
4289                          uint32_t flags, uint32_t reserved1, uint32_t reserved2,
4290                          uint32_t cmd, const char *sg_segname,
4291                          uint32_t filetype, uint32_t object_size,
4292                          bool verbose) {
4293   outs() << "Section\n";
4294   outs() << "  sectname " << format("%.16s\n", sectname);
4295   outs() << "   segname " << format("%.16s", segname);
4296   if (filetype != MachO::MH_OBJECT && strncmp(sg_segname, segname, 16) != 0)
4297     outs() << " (does not match segment)\n";
4298   else
4299     outs() << "\n";
4300   if (cmd == MachO::LC_SEGMENT_64) {
4301     outs() << "      addr " << format("0x%016" PRIx64, addr) << "\n";
4302     outs() << "      size " << format("0x%016" PRIx64, size);
4303   } else {
4304     outs() << "      addr " << format("0x%08" PRIx64, addr) << "\n";
4305     outs() << "      size " << format("0x%08" PRIx64, size);
4306   }
4307   if ((flags & MachO::S_ZEROFILL) != 0 && offset + size > object_size)
4308     outs() << " (past end of file)\n";
4309   else
4310     outs() << "\n";
4311   outs() << "    offset " << offset;
4312   if (offset > object_size)
4313     outs() << " (past end of file)\n";
4314   else
4315     outs() << "\n";
4316   uint32_t align_shifted = 1 << align;
4317   outs() << "     align 2^" << align << " (" << align_shifted << ")\n";
4318   outs() << "    reloff " << reloff;
4319   if (reloff > object_size)
4320     outs() << " (past end of file)\n";
4321   else
4322     outs() << "\n";
4323   outs() << "    nreloc " << nreloc;
4324   if (reloff + nreloc * sizeof(struct MachO::relocation_info) > object_size)
4325     outs() << " (past end of file)\n";
4326   else
4327     outs() << "\n";
4328   uint32_t section_type = flags & MachO::SECTION_TYPE;
4329   if (verbose) {
4330     outs() << "      type";
4331     if (section_type == MachO::S_REGULAR)
4332       outs() << " S_REGULAR\n";
4333     else if (section_type == MachO::S_ZEROFILL)
4334       outs() << " S_ZEROFILL\n";
4335     else if (section_type == MachO::S_CSTRING_LITERALS)
4336       outs() << " S_CSTRING_LITERALS\n";
4337     else if (section_type == MachO::S_4BYTE_LITERALS)
4338       outs() << " S_4BYTE_LITERALS\n";
4339     else if (section_type == MachO::S_8BYTE_LITERALS)
4340       outs() << " S_8BYTE_LITERALS\n";
4341     else if (section_type == MachO::S_16BYTE_LITERALS)
4342       outs() << " S_16BYTE_LITERALS\n";
4343     else if (section_type == MachO::S_LITERAL_POINTERS)
4344       outs() << " S_LITERAL_POINTERS\n";
4345     else if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS)
4346       outs() << " S_NON_LAZY_SYMBOL_POINTERS\n";
4347     else if (section_type == MachO::S_LAZY_SYMBOL_POINTERS)
4348       outs() << " S_LAZY_SYMBOL_POINTERS\n";
4349     else if (section_type == MachO::S_SYMBOL_STUBS)
4350       outs() << " S_SYMBOL_STUBS\n";
4351     else if (section_type == MachO::S_MOD_INIT_FUNC_POINTERS)
4352       outs() << " S_MOD_INIT_FUNC_POINTERS\n";
4353     else if (section_type == MachO::S_MOD_TERM_FUNC_POINTERS)
4354       outs() << " S_MOD_TERM_FUNC_POINTERS\n";
4355     else if (section_type == MachO::S_COALESCED)
4356       outs() << " S_COALESCED\n";
4357     else if (section_type == MachO::S_INTERPOSING)
4358       outs() << " S_INTERPOSING\n";
4359     else if (section_type == MachO::S_DTRACE_DOF)
4360       outs() << " S_DTRACE_DOF\n";
4361     else if (section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS)
4362       outs() << " S_LAZY_DYLIB_SYMBOL_POINTERS\n";
4363     else if (section_type == MachO::S_THREAD_LOCAL_REGULAR)
4364       outs() << " S_THREAD_LOCAL_REGULAR\n";
4365     else if (section_type == MachO::S_THREAD_LOCAL_ZEROFILL)
4366       outs() << " S_THREAD_LOCAL_ZEROFILL\n";
4367     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLES)
4368       outs() << " S_THREAD_LOCAL_VARIABLES\n";
4369     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
4370       outs() << " S_THREAD_LOCAL_VARIABLE_POINTERS\n";
4371     else if (section_type == MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS)
4372       outs() << " S_THREAD_LOCAL_INIT_FUNCTION_POINTERS\n";
4373     else
4374       outs() << format("0x%08" PRIx32, section_type) << "\n";
4375     outs() << "attributes";
4376     uint32_t section_attributes = flags & MachO::SECTION_ATTRIBUTES;
4377     if (section_attributes & MachO::S_ATTR_PURE_INSTRUCTIONS)
4378       outs() << " PURE_INSTRUCTIONS";
4379     if (section_attributes & MachO::S_ATTR_NO_TOC)
4380       outs() << " NO_TOC";
4381     if (section_attributes & MachO::S_ATTR_STRIP_STATIC_SYMS)
4382       outs() << " STRIP_STATIC_SYMS";
4383     if (section_attributes & MachO::S_ATTR_NO_DEAD_STRIP)
4384       outs() << " NO_DEAD_STRIP";
4385     if (section_attributes & MachO::S_ATTR_LIVE_SUPPORT)
4386       outs() << " LIVE_SUPPORT";
4387     if (section_attributes & MachO::S_ATTR_SELF_MODIFYING_CODE)
4388       outs() << " SELF_MODIFYING_CODE";
4389     if (section_attributes & MachO::S_ATTR_DEBUG)
4390       outs() << " DEBUG";
4391     if (section_attributes & MachO::S_ATTR_SOME_INSTRUCTIONS)
4392       outs() << " SOME_INSTRUCTIONS";
4393     if (section_attributes & MachO::S_ATTR_EXT_RELOC)
4394       outs() << " EXT_RELOC";
4395     if (section_attributes & MachO::S_ATTR_LOC_RELOC)
4396       outs() << " LOC_RELOC";
4397     if (section_attributes == 0)
4398       outs() << " (none)";
4399     outs() << "\n";
4400   } else
4401     outs() << "     flags " << format("0x%08" PRIx32, flags) << "\n";
4402   outs() << " reserved1 " << reserved1;
4403   if (section_type == MachO::S_SYMBOL_STUBS ||
4404       section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
4405       section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
4406       section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
4407       section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
4408     outs() << " (index into indirect symbol table)\n";
4409   else
4410     outs() << "\n";
4411   outs() << " reserved2 " << reserved2;
4412   if (section_type == MachO::S_SYMBOL_STUBS)
4413     outs() << " (size of stubs)\n";
4414   else
4415     outs() << "\n";
4416 }
4417
4418 static void PrintSymtabLoadCommand(MachO::symtab_command st, bool Is64Bit,
4419                                    uint32_t object_size) {
4420   outs() << "     cmd LC_SYMTAB\n";
4421   outs() << " cmdsize " << st.cmdsize;
4422   if (st.cmdsize != sizeof(struct MachO::symtab_command))
4423     outs() << " Incorrect size\n";
4424   else
4425     outs() << "\n";
4426   outs() << "  symoff " << st.symoff;
4427   if (st.symoff > object_size)
4428     outs() << " (past end of file)\n";
4429   else
4430     outs() << "\n";
4431   outs() << "   nsyms " << st.nsyms;
4432   uint64_t big_size;
4433   if (Is64Bit) {
4434     big_size = st.nsyms;
4435     big_size *= sizeof(struct MachO::nlist_64);
4436     big_size += st.symoff;
4437     if (big_size > object_size)
4438       outs() << " (past end of file)\n";
4439     else
4440       outs() << "\n";
4441   } else {
4442     big_size = st.nsyms;
4443     big_size *= sizeof(struct MachO::nlist);
4444     big_size += st.symoff;
4445     if (big_size > object_size)
4446       outs() << " (past end of file)\n";
4447     else
4448       outs() << "\n";
4449   }
4450   outs() << "  stroff " << st.stroff;
4451   if (st.stroff > object_size)
4452     outs() << " (past end of file)\n";
4453   else
4454     outs() << "\n";
4455   outs() << " strsize " << st.strsize;
4456   big_size = st.stroff;
4457   big_size += st.strsize;
4458   if (big_size > object_size)
4459     outs() << " (past end of file)\n";
4460   else
4461     outs() << "\n";
4462 }
4463
4464 static void PrintDysymtabLoadCommand(MachO::dysymtab_command dyst,
4465                                      uint32_t nsyms, uint32_t object_size,
4466                                      bool Is64Bit) {
4467   outs() << "            cmd LC_DYSYMTAB\n";
4468   outs() << "        cmdsize " << dyst.cmdsize;
4469   if (dyst.cmdsize != sizeof(struct MachO::dysymtab_command))
4470     outs() << " Incorrect size\n";
4471   else
4472     outs() << "\n";
4473   outs() << "      ilocalsym " << dyst.ilocalsym;
4474   if (dyst.ilocalsym > nsyms)
4475     outs() << " (greater than the number of symbols)\n";
4476   else
4477     outs() << "\n";
4478   outs() << "      nlocalsym " << dyst.nlocalsym;
4479   uint64_t big_size;
4480   big_size = dyst.ilocalsym;
4481   big_size += dyst.nlocalsym;
4482   if (big_size > nsyms)
4483     outs() << " (past the end of the symbol table)\n";
4484   else
4485     outs() << "\n";
4486   outs() << "     iextdefsym " << dyst.iextdefsym;
4487   if (dyst.iextdefsym > nsyms)
4488     outs() << " (greater than the number of symbols)\n";
4489   else
4490     outs() << "\n";
4491   outs() << "     nextdefsym " << dyst.nextdefsym;
4492   big_size = dyst.iextdefsym;
4493   big_size += dyst.nextdefsym;
4494   if (big_size > nsyms)
4495     outs() << " (past the end of the symbol table)\n";
4496   else
4497     outs() << "\n";
4498   outs() << "      iundefsym " << dyst.iundefsym;
4499   if (dyst.iundefsym > nsyms)
4500     outs() << " (greater than the number of symbols)\n";
4501   else
4502     outs() << "\n";
4503   outs() << "      nundefsym " << dyst.nundefsym;
4504   big_size = dyst.iundefsym;
4505   big_size += dyst.nundefsym;
4506   if (big_size > nsyms)
4507     outs() << " (past the end of the symbol table)\n";
4508   else
4509     outs() << "\n";
4510   outs() << "         tocoff " << dyst.tocoff;
4511   if (dyst.tocoff > object_size)
4512     outs() << " (past end of file)\n";
4513   else
4514     outs() << "\n";
4515   outs() << "           ntoc " << dyst.ntoc;
4516   big_size = dyst.ntoc;
4517   big_size *= sizeof(struct MachO::dylib_table_of_contents);
4518   big_size += dyst.tocoff;
4519   if (big_size > object_size)
4520     outs() << " (past end of file)\n";
4521   else
4522     outs() << "\n";
4523   outs() << "      modtaboff " << dyst.modtaboff;
4524   if (dyst.modtaboff > object_size)
4525     outs() << " (past end of file)\n";
4526   else
4527     outs() << "\n";
4528   outs() << "        nmodtab " << dyst.nmodtab;
4529   uint64_t modtabend;
4530   if (Is64Bit) {
4531     modtabend = dyst.nmodtab;
4532     modtabend *= sizeof(struct MachO::dylib_module_64);
4533     modtabend += dyst.modtaboff;
4534   } else {
4535     modtabend = dyst.nmodtab;
4536     modtabend *= sizeof(struct MachO::dylib_module);
4537     modtabend += dyst.modtaboff;
4538   }
4539   if (modtabend > object_size)
4540     outs() << " (past end of file)\n";
4541   else
4542     outs() << "\n";
4543   outs() << "   extrefsymoff " << dyst.extrefsymoff;
4544   if (dyst.extrefsymoff > object_size)
4545     outs() << " (past end of file)\n";
4546   else
4547     outs() << "\n";
4548   outs() << "    nextrefsyms " << dyst.nextrefsyms;
4549   big_size = dyst.nextrefsyms;
4550   big_size *= sizeof(struct MachO::dylib_reference);
4551   big_size += dyst.extrefsymoff;
4552   if (big_size > object_size)
4553     outs() << " (past end of file)\n";
4554   else
4555     outs() << "\n";
4556   outs() << " indirectsymoff " << dyst.indirectsymoff;
4557   if (dyst.indirectsymoff > object_size)
4558     outs() << " (past end of file)\n";
4559   else
4560     outs() << "\n";
4561   outs() << "  nindirectsyms " << dyst.nindirectsyms;
4562   big_size = dyst.nindirectsyms;
4563   big_size *= sizeof(uint32_t);
4564   big_size += dyst.indirectsymoff;
4565   if (big_size > object_size)
4566     outs() << " (past end of file)\n";
4567   else
4568     outs() << "\n";
4569   outs() << "      extreloff " << dyst.extreloff;
4570   if (dyst.extreloff > object_size)
4571     outs() << " (past end of file)\n";
4572   else
4573     outs() << "\n";
4574   outs() << "        nextrel " << dyst.nextrel;
4575   big_size = dyst.nextrel;
4576   big_size *= sizeof(struct MachO::relocation_info);
4577   big_size += dyst.extreloff;
4578   if (big_size > object_size)
4579     outs() << " (past end of file)\n";
4580   else
4581     outs() << "\n";
4582   outs() << "      locreloff " << dyst.locreloff;
4583   if (dyst.locreloff > object_size)
4584     outs() << " (past end of file)\n";
4585   else
4586     outs() << "\n";
4587   outs() << "        nlocrel " << dyst.nlocrel;
4588   big_size = dyst.nlocrel;
4589   big_size *= sizeof(struct MachO::relocation_info);
4590   big_size += dyst.locreloff;
4591   if (big_size > object_size)
4592     outs() << " (past end of file)\n";
4593   else
4594     outs() << "\n";
4595 }
4596
4597 static void PrintDyldInfoLoadCommand(MachO::dyld_info_command dc,
4598                                      uint32_t object_size) {
4599   if (dc.cmd == MachO::LC_DYLD_INFO)
4600     outs() << "            cmd LC_DYLD_INFO\n";
4601   else
4602     outs() << "            cmd LC_DYLD_INFO_ONLY\n";
4603   outs() << "        cmdsize " << dc.cmdsize;
4604   if (dc.cmdsize != sizeof(struct MachO::dyld_info_command))
4605     outs() << " Incorrect size\n";
4606   else
4607     outs() << "\n";
4608   outs() << "     rebase_off " << dc.rebase_off;
4609   if (dc.rebase_off > object_size)
4610     outs() << " (past end of file)\n";
4611   else
4612     outs() << "\n";
4613   outs() << "    rebase_size " << dc.rebase_size;
4614   uint64_t big_size;
4615   big_size = dc.rebase_off;
4616   big_size += dc.rebase_size;
4617   if (big_size > object_size)
4618     outs() << " (past end of file)\n";
4619   else
4620     outs() << "\n";
4621   outs() << "       bind_off " << dc.bind_off;
4622   if (dc.bind_off > object_size)
4623     outs() << " (past end of file)\n";
4624   else
4625     outs() << "\n";
4626   outs() << "      bind_size " << dc.bind_size;
4627   big_size = dc.bind_off;
4628   big_size += dc.bind_size;
4629   if (big_size > object_size)
4630     outs() << " (past end of file)\n";
4631   else
4632     outs() << "\n";
4633   outs() << "  weak_bind_off " << dc.weak_bind_off;
4634   if (dc.weak_bind_off > object_size)
4635     outs() << " (past end of file)\n";
4636   else
4637     outs() << "\n";
4638   outs() << " weak_bind_size " << dc.weak_bind_size;
4639   big_size = dc.weak_bind_off;
4640   big_size += dc.weak_bind_size;
4641   if (big_size > object_size)
4642     outs() << " (past end of file)\n";
4643   else
4644     outs() << "\n";
4645   outs() << "  lazy_bind_off " << dc.lazy_bind_off;
4646   if (dc.lazy_bind_off > object_size)
4647     outs() << " (past end of file)\n";
4648   else
4649     outs() << "\n";
4650   outs() << " lazy_bind_size " << dc.lazy_bind_size;
4651   big_size = dc.lazy_bind_off;
4652   big_size += dc.lazy_bind_size;
4653   if (big_size > object_size)
4654     outs() << " (past end of file)\n";
4655   else
4656     outs() << "\n";
4657   outs() << "     export_off " << dc.export_off;
4658   if (dc.export_off > object_size)
4659     outs() << " (past end of file)\n";
4660   else
4661     outs() << "\n";
4662   outs() << "    export_size " << dc.export_size;
4663   big_size = dc.export_off;
4664   big_size += dc.export_size;
4665   if (big_size > object_size)
4666     outs() << " (past end of file)\n";
4667   else
4668     outs() << "\n";
4669 }
4670
4671 static void PrintDyldLoadCommand(MachO::dylinker_command dyld,
4672                                  const char *Ptr) {
4673   if (dyld.cmd == MachO::LC_ID_DYLINKER)
4674     outs() << "          cmd LC_ID_DYLINKER\n";
4675   else if (dyld.cmd == MachO::LC_LOAD_DYLINKER)
4676     outs() << "          cmd LC_LOAD_DYLINKER\n";
4677   else if (dyld.cmd == MachO::LC_DYLD_ENVIRONMENT)
4678     outs() << "          cmd LC_DYLD_ENVIRONMENT\n";
4679   else
4680     outs() << "          cmd ?(" << dyld.cmd << ")\n";
4681   outs() << "      cmdsize " << dyld.cmdsize;
4682   if (dyld.cmdsize < sizeof(struct MachO::dylinker_command))
4683     outs() << " Incorrect size\n";
4684   else
4685     outs() << "\n";
4686   if (dyld.name >= dyld.cmdsize)
4687     outs() << "         name ?(bad offset " << dyld.name << ")\n";
4688   else {
4689     const char *P = (const char *)(Ptr) + dyld.name;
4690     outs() << "         name " << P << " (offset " << dyld.name << ")\n";
4691   }
4692 }
4693
4694 static void PrintUuidLoadCommand(MachO::uuid_command uuid) {
4695   outs() << "     cmd LC_UUID\n";
4696   outs() << " cmdsize " << uuid.cmdsize;
4697   if (uuid.cmdsize != sizeof(struct MachO::uuid_command))
4698     outs() << " Incorrect size\n";
4699   else
4700     outs() << "\n";
4701   outs() << "    uuid ";
4702   outs() << format("%02" PRIX32, uuid.uuid[0]);
4703   outs() << format("%02" PRIX32, uuid.uuid[1]);
4704   outs() << format("%02" PRIX32, uuid.uuid[2]);
4705   outs() << format("%02" PRIX32, uuid.uuid[3]);
4706   outs() << "-";
4707   outs() << format("%02" PRIX32, uuid.uuid[4]);
4708   outs() << format("%02" PRIX32, uuid.uuid[5]);
4709   outs() << "-";
4710   outs() << format("%02" PRIX32, uuid.uuid[6]);
4711   outs() << format("%02" PRIX32, uuid.uuid[7]);
4712   outs() << "-";
4713   outs() << format("%02" PRIX32, uuid.uuid[8]);
4714   outs() << format("%02" PRIX32, uuid.uuid[9]);
4715   outs() << "-";
4716   outs() << format("%02" PRIX32, uuid.uuid[10]);
4717   outs() << format("%02" PRIX32, uuid.uuid[11]);
4718   outs() << format("%02" PRIX32, uuid.uuid[12]);
4719   outs() << format("%02" PRIX32, uuid.uuid[13]);
4720   outs() << format("%02" PRIX32, uuid.uuid[14]);
4721   outs() << format("%02" PRIX32, uuid.uuid[15]);
4722   outs() << "\n";
4723 }
4724
4725 static void PrintRpathLoadCommand(MachO::rpath_command rpath, const char *Ptr) {
4726   outs() << "          cmd LC_RPATH\n";
4727   outs() << "      cmdsize " << rpath.cmdsize;
4728   if (rpath.cmdsize < sizeof(struct MachO::rpath_command))
4729     outs() << " Incorrect size\n";
4730   else
4731     outs() << "\n";
4732   if (rpath.path >= rpath.cmdsize)
4733     outs() << "         path ?(bad offset " << rpath.path << ")\n";
4734   else {
4735     const char *P = (const char *)(Ptr) + rpath.path;
4736     outs() << "         path " << P << " (offset " << rpath.path << ")\n";
4737   }
4738 }
4739
4740 static void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
4741   if (vd.cmd == MachO::LC_VERSION_MIN_MACOSX)
4742     outs() << "      cmd LC_VERSION_MIN_MACOSX\n";
4743   else if (vd.cmd == MachO::LC_VERSION_MIN_IPHONEOS)
4744     outs() << "      cmd LC_VERSION_MIN_IPHONEOS\n";
4745   else
4746     outs() << "      cmd " << vd.cmd << " (?)\n";
4747   outs() << "  cmdsize " << vd.cmdsize;
4748   if (vd.cmdsize != sizeof(struct MachO::version_min_command))
4749     outs() << " Incorrect size\n";
4750   else
4751     outs() << "\n";
4752   outs() << "  version " << ((vd.version >> 16) & 0xffff) << "."
4753          << ((vd.version >> 8) & 0xff);
4754   if ((vd.version & 0xff) != 0)
4755     outs() << "." << (vd.version & 0xff);
4756   outs() << "\n";
4757   if (vd.sdk == 0)
4758     outs() << "      sdk n/a";
4759   else {
4760     outs() << "      sdk " << ((vd.sdk >> 16) & 0xffff) << "."
4761            << ((vd.sdk >> 8) & 0xff);
4762   }
4763   if ((vd.sdk & 0xff) != 0)
4764     outs() << "." << (vd.sdk & 0xff);
4765   outs() << "\n";
4766 }
4767
4768 static void PrintSourceVersionCommand(MachO::source_version_command sd) {
4769   outs() << "      cmd LC_SOURCE_VERSION\n";
4770   outs() << "  cmdsize " << sd.cmdsize;
4771   if (sd.cmdsize != sizeof(struct MachO::source_version_command))
4772     outs() << " Incorrect size\n";
4773   else
4774     outs() << "\n";
4775   uint64_t a = (sd.version >> 40) & 0xffffff;
4776   uint64_t b = (sd.version >> 30) & 0x3ff;
4777   uint64_t c = (sd.version >> 20) & 0x3ff;
4778   uint64_t d = (sd.version >> 10) & 0x3ff;
4779   uint64_t e = sd.version & 0x3ff;
4780   outs() << "  version " << a << "." << b;
4781   if (e != 0)
4782     outs() << "." << c << "." << d << "." << e;
4783   else if (d != 0)
4784     outs() << "." << c << "." << d;
4785   else if (c != 0)
4786     outs() << "." << c;
4787   outs() << "\n";
4788 }
4789
4790 static void PrintEntryPointCommand(MachO::entry_point_command ep) {
4791   outs() << "       cmd LC_MAIN\n";
4792   outs() << "   cmdsize " << ep.cmdsize;
4793   if (ep.cmdsize != sizeof(struct MachO::entry_point_command))
4794     outs() << " Incorrect size\n";
4795   else
4796     outs() << "\n";
4797   outs() << "  entryoff " << ep.entryoff << "\n";
4798   outs() << " stacksize " << ep.stacksize << "\n";
4799 }
4800
4801 static void PrintEncryptionInfoCommand(MachO::encryption_info_command ec,
4802                                        uint32_t object_size) {
4803   outs() << "          cmd LC_ENCRYPTION_INFO\n";
4804   outs() << "      cmdsize " << ec.cmdsize;
4805   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command))
4806     outs() << " Incorrect size\n";
4807   else
4808     outs() << "\n";
4809   outs() << "     cryptoff " << ec.cryptoff;
4810   if (ec.cryptoff > object_size)
4811     outs() << " (past end of file)\n";
4812   else
4813     outs() << "\n";
4814   outs() << "    cryptsize " << ec.cryptsize;
4815   if (ec.cryptsize > object_size)
4816     outs() << " (past end of file)\n";
4817   else
4818     outs() << "\n";
4819   outs() << "      cryptid " << ec.cryptid << "\n";
4820 }
4821
4822 static void PrintEncryptionInfoCommand64(MachO::encryption_info_command_64 ec,
4823                                          uint32_t object_size) {
4824   outs() << "          cmd LC_ENCRYPTION_INFO_64\n";
4825   outs() << "      cmdsize " << ec.cmdsize;
4826   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command_64))
4827     outs() << " Incorrect size\n";
4828   else
4829     outs() << "\n";
4830   outs() << "     cryptoff " << ec.cryptoff;
4831   if (ec.cryptoff > object_size)
4832     outs() << " (past end of file)\n";
4833   else
4834     outs() << "\n";
4835   outs() << "    cryptsize " << ec.cryptsize;
4836   if (ec.cryptsize > object_size)
4837     outs() << " (past end of file)\n";
4838   else
4839     outs() << "\n";
4840   outs() << "      cryptid " << ec.cryptid << "\n";
4841   outs() << "          pad " << ec.pad << "\n";
4842 }
4843
4844 static void PrintLinkerOptionCommand(MachO::linker_option_command lo,
4845                                      const char *Ptr) {
4846   outs() << "     cmd LC_LINKER_OPTION\n";
4847   outs() << " cmdsize " << lo.cmdsize;
4848   if (lo.cmdsize < sizeof(struct MachO::linker_option_command))
4849     outs() << " Incorrect size\n";
4850   else
4851     outs() << "\n";
4852   outs() << "   count " << lo.count << "\n";
4853   const char *string = Ptr + sizeof(struct MachO::linker_option_command);
4854   uint32_t left = lo.cmdsize - sizeof(struct MachO::linker_option_command);
4855   uint32_t i = 0;
4856   while (left > 0) {
4857     while (*string == '\0' && left > 0) {
4858       string++;
4859       left--;
4860     }
4861     if (left > 0) {
4862       i++;
4863       outs() << "  string #" << i << " " << format("%.*s\n", left, string);
4864       uint32_t NullPos = StringRef(string, left).find('\0');
4865       uint32_t len = std::min(NullPos, left) + 1;
4866       string += len;
4867       left -= len;
4868     }
4869   }
4870   if (lo.count != i)
4871     outs() << "   count " << lo.count << " does not match number of strings "
4872            << i << "\n";
4873 }
4874
4875 static void PrintSubFrameworkCommand(MachO::sub_framework_command sub,
4876                                      const char *Ptr) {
4877   outs() << "          cmd LC_SUB_FRAMEWORK\n";
4878   outs() << "      cmdsize " << sub.cmdsize;
4879   if (sub.cmdsize < sizeof(struct MachO::sub_framework_command))
4880     outs() << " Incorrect size\n";
4881   else
4882     outs() << "\n";
4883   if (sub.umbrella < sub.cmdsize) {
4884     const char *P = Ptr + sub.umbrella;
4885     outs() << "     umbrella " << P << " (offset " << sub.umbrella << ")\n";
4886   } else {
4887     outs() << "     umbrella ?(bad offset " << sub.umbrella << ")\n";
4888   }
4889 }
4890
4891 static void PrintSubUmbrellaCommand(MachO::sub_umbrella_command sub,
4892                                     const char *Ptr) {
4893   outs() << "          cmd LC_SUB_UMBRELLA\n";
4894   outs() << "      cmdsize " << sub.cmdsize;
4895   if (sub.cmdsize < sizeof(struct MachO::sub_umbrella_command))
4896     outs() << " Incorrect size\n";
4897   else
4898     outs() << "\n";
4899   if (sub.sub_umbrella < sub.cmdsize) {
4900     const char *P = Ptr + sub.sub_umbrella;
4901     outs() << " sub_umbrella " << P << " (offset " << sub.sub_umbrella << ")\n";
4902   } else {
4903     outs() << " sub_umbrella ?(bad offset " << sub.sub_umbrella << ")\n";
4904   }
4905 }
4906
4907 static void PrintSubLibraryCommand(MachO::sub_library_command sub,
4908                                    const char *Ptr) {
4909   outs() << "          cmd LC_SUB_LIBRARY\n";
4910   outs() << "      cmdsize " << sub.cmdsize;
4911   if (sub.cmdsize < sizeof(struct MachO::sub_library_command))
4912     outs() << " Incorrect size\n";
4913   else
4914     outs() << "\n";
4915   if (sub.sub_library < sub.cmdsize) {
4916     const char *P = Ptr + sub.sub_library;
4917     outs() << "  sub_library " << P << " (offset " << sub.sub_library << ")\n";
4918   } else {
4919     outs() << "  sub_library ?(bad offset " << sub.sub_library << ")\n";
4920   }
4921 }
4922
4923 static void PrintSubClientCommand(MachO::sub_client_command sub,
4924                                   const char *Ptr) {
4925   outs() << "          cmd LC_SUB_CLIENT\n";
4926   outs() << "      cmdsize " << sub.cmdsize;
4927   if (sub.cmdsize < sizeof(struct MachO::sub_client_command))
4928     outs() << " Incorrect size\n";
4929   else
4930     outs() << "\n";
4931   if (sub.client < sub.cmdsize) {
4932     const char *P = Ptr + sub.client;
4933     outs() << "       client " << P << " (offset " << sub.client << ")\n";
4934   } else {
4935     outs() << "       client ?(bad offset " << sub.client << ")\n";
4936   }
4937 }
4938
4939 static void PrintRoutinesCommand(MachO::routines_command r) {
4940   outs() << "          cmd LC_ROUTINES\n";
4941   outs() << "      cmdsize " << r.cmdsize;
4942   if (r.cmdsize != sizeof(struct MachO::routines_command))
4943     outs() << " Incorrect size\n";
4944   else
4945     outs() << "\n";
4946   outs() << " init_address " << format("0x%08" PRIx32, r.init_address) << "\n";
4947   outs() << "  init_module " << r.init_module << "\n";
4948   outs() << "    reserved1 " << r.reserved1 << "\n";
4949   outs() << "    reserved2 " << r.reserved2 << "\n";
4950   outs() << "    reserved3 " << r.reserved3 << "\n";
4951   outs() << "    reserved4 " << r.reserved4 << "\n";
4952   outs() << "    reserved5 " << r.reserved5 << "\n";
4953   outs() << "    reserved6 " << r.reserved6 << "\n";
4954 }
4955
4956 static void PrintRoutinesCommand64(MachO::routines_command_64 r) {
4957   outs() << "          cmd LC_ROUTINES_64\n";
4958   outs() << "      cmdsize " << r.cmdsize;
4959   if (r.cmdsize != sizeof(struct MachO::routines_command_64))
4960     outs() << " Incorrect size\n";
4961   else
4962     outs() << "\n";
4963   outs() << " init_address " << format("0x%016" PRIx64, r.init_address) << "\n";
4964   outs() << "  init_module " << r.init_module << "\n";
4965   outs() << "    reserved1 " << r.reserved1 << "\n";
4966   outs() << "    reserved2 " << r.reserved2 << "\n";
4967   outs() << "    reserved3 " << r.reserved3 << "\n";
4968   outs() << "    reserved4 " << r.reserved4 << "\n";
4969   outs() << "    reserved5 " << r.reserved5 << "\n";
4970   outs() << "    reserved6 " << r.reserved6 << "\n";
4971 }
4972
4973 static void Print_x86_thread_state64_t(MachO::x86_thread_state64_t &cpu64) {
4974   outs() << "   rax  " << format("0x%016" PRIx64, cpu64.rax);
4975   outs() << " rbx " << format("0x%016" PRIx64, cpu64.rbx);
4976   outs() << " rcx  " << format("0x%016" PRIx64, cpu64.rcx) << "\n";
4977   outs() << "   rdx  " << format("0x%016" PRIx64, cpu64.rdx);
4978   outs() << " rdi " << format("0x%016" PRIx64, cpu64.rdi);
4979   outs() << " rsi  " << format("0x%016" PRIx64, cpu64.rsi) << "\n";
4980   outs() << "   rbp  " << format("0x%016" PRIx64, cpu64.rbp);
4981   outs() << " rsp " << format("0x%016" PRIx64, cpu64.rsp);
4982   outs() << " r8   " << format("0x%016" PRIx64, cpu64.r8) << "\n";
4983   outs() << "    r9  " << format("0x%016" PRIx64, cpu64.r9);
4984   outs() << " r10 " << format("0x%016" PRIx64, cpu64.r10);
4985   outs() << " r11  " << format("0x%016" PRIx64, cpu64.r11) << "\n";
4986   outs() << "   r12  " << format("0x%016" PRIx64, cpu64.r12);
4987   outs() << " r13 " << format("0x%016" PRIx64, cpu64.r13);
4988   outs() << " r14  " << format("0x%016" PRIx64, cpu64.r14) << "\n";
4989   outs() << "   r15  " << format("0x%016" PRIx64, cpu64.r15);
4990   outs() << " rip " << format("0x%016" PRIx64, cpu64.rip) << "\n";
4991   outs() << "rflags  " << format("0x%016" PRIx64, cpu64.rflags);
4992   outs() << " cs  " << format("0x%016" PRIx64, cpu64.cs);
4993   outs() << " fs   " << format("0x%016" PRIx64, cpu64.fs) << "\n";
4994   outs() << "    gs  " << format("0x%016" PRIx64, cpu64.gs) << "\n";
4995 }
4996
4997 static void Print_mmst_reg(MachO::mmst_reg_t &r) {
4998   uint32_t f;
4999   outs() << "\t      mmst_reg  ";
5000   for (f = 0; f < 10; f++)
5001     outs() << format("%02" PRIx32, (r.mmst_reg[f] & 0xff)) << " ";
5002   outs() << "\n";
5003   outs() << "\t      mmst_rsrv ";
5004   for (f = 0; f < 6; f++)
5005     outs() << format("%02" PRIx32, (r.mmst_rsrv[f] & 0xff)) << " ";
5006   outs() << "\n";
5007 }
5008
5009 static void Print_xmm_reg(MachO::xmm_reg_t &r) {
5010   uint32_t f;
5011   outs() << "\t      xmm_reg ";
5012   for (f = 0; f < 16; f++)
5013     outs() << format("%02" PRIx32, (r.xmm_reg[f] & 0xff)) << " ";
5014   outs() << "\n";
5015 }
5016
5017 static void Print_x86_float_state_t(MachO::x86_float_state64_t &fpu) {
5018   outs() << "\t    fpu_reserved[0] " << fpu.fpu_reserved[0];
5019   outs() << " fpu_reserved[1] " << fpu.fpu_reserved[1] << "\n";
5020   outs() << "\t    control: invalid " << fpu.fpu_fcw.invalid;
5021   outs() << " denorm " << fpu.fpu_fcw.denorm;
5022   outs() << " zdiv " << fpu.fpu_fcw.zdiv;
5023   outs() << " ovrfl " << fpu.fpu_fcw.ovrfl;
5024   outs() << " undfl " << fpu.fpu_fcw.undfl;
5025   outs() << " precis " << fpu.fpu_fcw.precis << "\n";
5026   outs() << "\t\t     pc ";
5027   if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_24B)
5028     outs() << "FP_PREC_24B ";
5029   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_53B)
5030     outs() << "FP_PREC_53B ";
5031   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_64B)
5032     outs() << "FP_PREC_64B ";
5033   else
5034     outs() << fpu.fpu_fcw.pc << " ";
5035   outs() << "rc ";
5036   if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_NEAR)
5037     outs() << "FP_RND_NEAR ";
5038   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_DOWN)
5039     outs() << "FP_RND_DOWN ";
5040   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_UP)
5041     outs() << "FP_RND_UP ";
5042   else if (fpu.fpu_fcw.rc == MachO::x86_FP_CHOP)
5043     outs() << "FP_CHOP ";
5044   outs() << "\n";
5045   outs() << "\t    status: invalid " << fpu.fpu_fsw.invalid;
5046   outs() << " denorm " << fpu.fpu_fsw.denorm;
5047   outs() << " zdiv " << fpu.fpu_fsw.zdiv;
5048   outs() << " ovrfl " << fpu.fpu_fsw.ovrfl;
5049   outs() << " undfl " << fpu.fpu_fsw.undfl;
5050   outs() << " precis " << fpu.fpu_fsw.precis;
5051   outs() << " stkflt " << fpu.fpu_fsw.stkflt << "\n";
5052   outs() << "\t            errsumm " << fpu.fpu_fsw.errsumm;
5053   outs() << " c0 " << fpu.fpu_fsw.c0;
5054   outs() << " c1 " << fpu.fpu_fsw.c1;
5055   outs() << " c2 " << fpu.fpu_fsw.c2;
5056   outs() << " tos " << fpu.fpu_fsw.tos;
5057   outs() << " c3 " << fpu.fpu_fsw.c3;
5058   outs() << " busy " << fpu.fpu_fsw.busy << "\n";
5059   outs() << "\t    fpu_ftw " << format("0x%02" PRIx32, fpu.fpu_ftw);
5060   outs() << " fpu_rsrv1 " << format("0x%02" PRIx32, fpu.fpu_rsrv1);
5061   outs() << " fpu_fop " << format("0x%04" PRIx32, fpu.fpu_fop);
5062   outs() << " fpu_ip " << format("0x%08" PRIx32, fpu.fpu_ip) << "\n";
5063   outs() << "\t    fpu_cs " << format("0x%04" PRIx32, fpu.fpu_cs);
5064   outs() << " fpu_rsrv2 " << format("0x%04" PRIx32, fpu.fpu_rsrv2);
5065   outs() << " fpu_dp " << format("0x%08" PRIx32, fpu.fpu_dp);
5066   outs() << " fpu_ds " << format("0x%04" PRIx32, fpu.fpu_ds) << "\n";
5067   outs() << "\t    fpu_rsrv3 " << format("0x%04" PRIx32, fpu.fpu_rsrv3);
5068   outs() << " fpu_mxcsr " << format("0x%08" PRIx32, fpu.fpu_mxcsr);
5069   outs() << " fpu_mxcsrmask " << format("0x%08" PRIx32, fpu.fpu_mxcsrmask);
5070   outs() << "\n";
5071   outs() << "\t    fpu_stmm0:\n";
5072   Print_mmst_reg(fpu.fpu_stmm0);
5073   outs() << "\t    fpu_stmm1:\n";
5074   Print_mmst_reg(fpu.fpu_stmm1);
5075   outs() << "\t    fpu_stmm2:\n";
5076   Print_mmst_reg(fpu.fpu_stmm2);
5077   outs() << "\t    fpu_stmm3:\n";
5078   Print_mmst_reg(fpu.fpu_stmm3);
5079   outs() << "\t    fpu_stmm4:\n";
5080   Print_mmst_reg(fpu.fpu_stmm4);
5081   outs() << "\t    fpu_stmm5:\n";
5082   Print_mmst_reg(fpu.fpu_stmm5);
5083   outs() << "\t    fpu_stmm6:\n";
5084   Print_mmst_reg(fpu.fpu_stmm6);
5085   outs() << "\t    fpu_stmm7:\n";
5086   Print_mmst_reg(fpu.fpu_stmm7);
5087   outs() << "\t    fpu_xmm0:\n";
5088   Print_xmm_reg(fpu.fpu_xmm0);
5089   outs() << "\t    fpu_xmm1:\n";
5090   Print_xmm_reg(fpu.fpu_xmm1);
5091   outs() << "\t    fpu_xmm2:\n";
5092   Print_xmm_reg(fpu.fpu_xmm2);
5093   outs() << "\t    fpu_xmm3:\n";
5094   Print_xmm_reg(fpu.fpu_xmm3);
5095   outs() << "\t    fpu_xmm4:\n";
5096   Print_xmm_reg(fpu.fpu_xmm4);
5097   outs() << "\t    fpu_xmm5:\n";
5098   Print_xmm_reg(fpu.fpu_xmm5);
5099   outs() << "\t    fpu_xmm6:\n";
5100   Print_xmm_reg(fpu.fpu_xmm6);
5101   outs() << "\t    fpu_xmm7:\n";
5102   Print_xmm_reg(fpu.fpu_xmm7);
5103   outs() << "\t    fpu_xmm8:\n";
5104   Print_xmm_reg(fpu.fpu_xmm8);
5105   outs() << "\t    fpu_xmm9:\n";
5106   Print_xmm_reg(fpu.fpu_xmm9);
5107   outs() << "\t    fpu_xmm10:\n";
5108   Print_xmm_reg(fpu.fpu_xmm10);
5109   outs() << "\t    fpu_xmm11:\n";
5110   Print_xmm_reg(fpu.fpu_xmm11);
5111   outs() << "\t    fpu_xmm12:\n";
5112   Print_xmm_reg(fpu.fpu_xmm12);
5113   outs() << "\t    fpu_xmm13:\n";
5114   Print_xmm_reg(fpu.fpu_xmm13);
5115   outs() << "\t    fpu_xmm14:\n";
5116   Print_xmm_reg(fpu.fpu_xmm14);
5117   outs() << "\t    fpu_xmm15:\n";
5118   Print_xmm_reg(fpu.fpu_xmm15);
5119   outs() << "\t    fpu_rsrv4:\n";
5120   for (uint32_t f = 0; f < 6; f++) {
5121     outs() << "\t            ";
5122     for (uint32_t g = 0; g < 16; g++)
5123       outs() << format("%02" PRIx32, fpu.fpu_rsrv4[f * g]) << " ";
5124     outs() << "\n";
5125   }
5126   outs() << "\t    fpu_reserved1 " << format("0x%08" PRIx32, fpu.fpu_reserved1);
5127   outs() << "\n";
5128 }
5129
5130 static void Print_x86_exception_state_t(MachO::x86_exception_state64_t &exc64) {
5131   outs() << "\t    trapno " << format("0x%08" PRIx32, exc64.trapno);
5132   outs() << " err " << format("0x%08" PRIx32, exc64.err);
5133   outs() << " faultvaddr " << format("0x%016" PRIx64, exc64.faultvaddr) << "\n";
5134 }
5135
5136 static void PrintThreadCommand(MachO::thread_command t, const char *Ptr,
5137                                bool isLittleEndian, uint32_t cputype) {
5138   if (t.cmd == MachO::LC_THREAD)
5139     outs() << "        cmd LC_THREAD\n";
5140   else if (t.cmd == MachO::LC_UNIXTHREAD)
5141     outs() << "        cmd LC_UNIXTHREAD\n";
5142   else
5143     outs() << "        cmd " << t.cmd << " (unknown)\n";
5144   outs() << "    cmdsize " << t.cmdsize;
5145   if (t.cmdsize < sizeof(struct MachO::thread_command) + 2 * sizeof(uint32_t))
5146     outs() << " Incorrect size\n";
5147   else
5148     outs() << "\n";
5149
5150   const char *begin = Ptr + sizeof(struct MachO::thread_command);
5151   const char *end = Ptr + t.cmdsize;
5152   uint32_t flavor, count, left;
5153   if (cputype == MachO::CPU_TYPE_X86_64) {
5154     while (begin < end) {
5155       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
5156         memcpy((char *)&flavor, begin, sizeof(uint32_t));
5157         begin += sizeof(uint32_t);
5158       } else {
5159         flavor = 0;
5160         begin = end;
5161       }
5162       if (isLittleEndian != sys::IsLittleEndianHost)
5163         sys::swapByteOrder(flavor);
5164       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
5165         memcpy((char *)&count, begin, sizeof(uint32_t));
5166         begin += sizeof(uint32_t);
5167       } else {
5168         count = 0;
5169         begin = end;
5170       }
5171       if (isLittleEndian != sys::IsLittleEndianHost)
5172         sys::swapByteOrder(count);
5173       if (flavor == MachO::x86_THREAD_STATE64) {
5174         outs() << "     flavor x86_THREAD_STATE64\n";
5175         if (count == MachO::x86_THREAD_STATE64_COUNT)
5176           outs() << "      count x86_THREAD_STATE64_COUNT\n";
5177         else
5178           outs() << "      count " << count
5179                  << " (not x86_THREAD_STATE64_COUNT)\n";
5180         MachO::x86_thread_state64_t cpu64;
5181         left = end - begin;
5182         if (left >= sizeof(MachO::x86_thread_state64_t)) {
5183           memcpy(&cpu64, begin, sizeof(MachO::x86_thread_state64_t));
5184           begin += sizeof(MachO::x86_thread_state64_t);
5185         } else {
5186           memset(&cpu64, '\0', sizeof(MachO::x86_thread_state64_t));
5187           memcpy(&cpu64, begin, left);
5188           begin += left;
5189         }
5190         if (isLittleEndian != sys::IsLittleEndianHost)
5191           swapStruct(cpu64);
5192         Print_x86_thread_state64_t(cpu64);
5193       } else if (flavor == MachO::x86_THREAD_STATE) {
5194         outs() << "     flavor x86_THREAD_STATE\n";
5195         if (count == MachO::x86_THREAD_STATE_COUNT)
5196           outs() << "      count x86_THREAD_STATE_COUNT\n";
5197         else
5198           outs() << "      count " << count
5199                  << " (not x86_THREAD_STATE_COUNT)\n";
5200         struct MachO::x86_thread_state_t ts;
5201         left = end - begin;
5202         if (left >= sizeof(MachO::x86_thread_state_t)) {
5203           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
5204           begin += sizeof(MachO::x86_thread_state_t);
5205         } else {
5206           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
5207           memcpy(&ts, begin, left);
5208           begin += left;
5209         }
5210         if (isLittleEndian != sys::IsLittleEndianHost)
5211           swapStruct(ts);
5212         if (ts.tsh.flavor == MachO::x86_THREAD_STATE64) {
5213           outs() << "\t    tsh.flavor x86_THREAD_STATE64 ";
5214           if (ts.tsh.count == MachO::x86_THREAD_STATE64_COUNT)
5215             outs() << "tsh.count x86_THREAD_STATE64_COUNT\n";
5216           else
5217             outs() << "tsh.count " << ts.tsh.count
5218                    << " (not x86_THREAD_STATE64_COUNT\n";
5219           Print_x86_thread_state64_t(ts.uts.ts64);
5220         } else {
5221           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
5222                  << ts.tsh.count << "\n";
5223         }
5224       } else if (flavor == MachO::x86_FLOAT_STATE) {
5225         outs() << "     flavor x86_FLOAT_STATE\n";
5226         if (count == MachO::x86_FLOAT_STATE_COUNT)
5227           outs() << "      count x86_FLOAT_STATE_COUNT\n";
5228         else
5229           outs() << "      count " << count << " (not x86_FLOAT_STATE_COUNT)\n";
5230         struct MachO::x86_float_state_t fs;
5231         left = end - begin;
5232         if (left >= sizeof(MachO::x86_float_state_t)) {
5233           memcpy(&fs, begin, sizeof(MachO::x86_float_state_t));
5234           begin += sizeof(MachO::x86_float_state_t);
5235         } else {
5236           memset(&fs, '\0', sizeof(MachO::x86_float_state_t));
5237           memcpy(&fs, begin, left);
5238           begin += left;
5239         }
5240         if (isLittleEndian != sys::IsLittleEndianHost)
5241           swapStruct(fs);
5242         if (fs.fsh.flavor == MachO::x86_FLOAT_STATE64) {
5243           outs() << "\t    fsh.flavor x86_FLOAT_STATE64 ";
5244           if (fs.fsh.count == MachO::x86_FLOAT_STATE64_COUNT)
5245             outs() << "fsh.count x86_FLOAT_STATE64_COUNT\n";
5246           else
5247             outs() << "fsh.count " << fs.fsh.count
5248                    << " (not x86_FLOAT_STATE64_COUNT\n";
5249           Print_x86_float_state_t(fs.ufs.fs64);
5250         } else {
5251           outs() << "\t    fsh.flavor " << fs.fsh.flavor << "  fsh.count "
5252                  << fs.fsh.count << "\n";
5253         }
5254       } else if (flavor == MachO::x86_EXCEPTION_STATE) {
5255         outs() << "     flavor x86_EXCEPTION_STATE\n";
5256         if (count == MachO::x86_EXCEPTION_STATE_COUNT)
5257           outs() << "      count x86_EXCEPTION_STATE_COUNT\n";
5258         else
5259           outs() << "      count " << count
5260                  << " (not x86_EXCEPTION_STATE_COUNT)\n";
5261         struct MachO::x86_exception_state_t es;
5262         left = end - begin;
5263         if (left >= sizeof(MachO::x86_exception_state_t)) {
5264           memcpy(&es, begin, sizeof(MachO::x86_exception_state_t));
5265           begin += sizeof(MachO::x86_exception_state_t);
5266         } else {
5267           memset(&es, '\0', sizeof(MachO::x86_exception_state_t));
5268           memcpy(&es, begin, left);
5269           begin += left;
5270         }
5271         if (isLittleEndian != sys::IsLittleEndianHost)
5272           swapStruct(es);
5273         if (es.esh.flavor == MachO::x86_EXCEPTION_STATE64) {
5274           outs() << "\t    esh.flavor x86_EXCEPTION_STATE64\n";
5275           if (es.esh.count == MachO::x86_EXCEPTION_STATE64_COUNT)
5276             outs() << "\t    esh.count x86_EXCEPTION_STATE64_COUNT\n";
5277           else
5278             outs() << "\t    esh.count " << es.esh.count
5279                    << " (not x86_EXCEPTION_STATE64_COUNT\n";
5280           Print_x86_exception_state_t(es.ues.es64);
5281         } else {
5282           outs() << "\t    esh.flavor " << es.esh.flavor << "  esh.count "
5283                  << es.esh.count << "\n";
5284         }
5285       } else {
5286         outs() << "     flavor " << flavor << " (unknown)\n";
5287         outs() << "      count " << count << "\n";
5288         outs() << "      state (unknown)\n";
5289         begin += count * sizeof(uint32_t);
5290       }
5291     }
5292   } else {
5293     while (begin < end) {
5294       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
5295         memcpy((char *)&flavor, begin, sizeof(uint32_t));
5296         begin += sizeof(uint32_t);
5297       } else {
5298         flavor = 0;
5299         begin = end;
5300       }
5301       if (isLittleEndian != sys::IsLittleEndianHost)
5302         sys::swapByteOrder(flavor);
5303       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
5304         memcpy((char *)&count, begin, sizeof(uint32_t));
5305         begin += sizeof(uint32_t);
5306       } else {
5307         count = 0;
5308         begin = end;
5309       }
5310       if (isLittleEndian != sys::IsLittleEndianHost)
5311         sys::swapByteOrder(count);
5312       outs() << "     flavor " << flavor << "\n";
5313       outs() << "      count " << count << "\n";
5314       outs() << "      state (Unknown cputype/cpusubtype)\n";
5315       begin += count * sizeof(uint32_t);
5316     }
5317   }
5318 }
5319
5320 static void PrintDylibCommand(MachO::dylib_command dl, const char *Ptr) {
5321   if (dl.cmd == MachO::LC_ID_DYLIB)
5322     outs() << "          cmd LC_ID_DYLIB\n";
5323   else if (dl.cmd == MachO::LC_LOAD_DYLIB)
5324     outs() << "          cmd LC_LOAD_DYLIB\n";
5325   else if (dl.cmd == MachO::LC_LOAD_WEAK_DYLIB)
5326     outs() << "          cmd LC_LOAD_WEAK_DYLIB\n";
5327   else if (dl.cmd == MachO::LC_REEXPORT_DYLIB)
5328     outs() << "          cmd LC_REEXPORT_DYLIB\n";
5329   else if (dl.cmd == MachO::LC_LAZY_LOAD_DYLIB)
5330     outs() << "          cmd LC_LAZY_LOAD_DYLIB\n";
5331   else if (dl.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
5332     outs() << "          cmd LC_LOAD_UPWARD_DYLIB\n";
5333   else
5334     outs() << "          cmd " << dl.cmd << " (unknown)\n";
5335   outs() << "      cmdsize " << dl.cmdsize;
5336   if (dl.cmdsize < sizeof(struct MachO::dylib_command))
5337     outs() << " Incorrect size\n";
5338   else
5339     outs() << "\n";
5340   if (dl.dylib.name < dl.cmdsize) {
5341     const char *P = (const char *)(Ptr) + dl.dylib.name;
5342     outs() << "         name " << P << " (offset " << dl.dylib.name << ")\n";
5343   } else {
5344     outs() << "         name ?(bad offset " << dl.dylib.name << ")\n";
5345   }
5346   outs() << "   time stamp " << dl.dylib.timestamp << " ";
5347   time_t t = dl.dylib.timestamp;
5348   outs() << ctime(&t);
5349   outs() << "      current version ";
5350   if (dl.dylib.current_version == 0xffffffff)
5351     outs() << "n/a\n";
5352   else
5353     outs() << ((dl.dylib.current_version >> 16) & 0xffff) << "."
5354            << ((dl.dylib.current_version >> 8) & 0xff) << "."
5355            << (dl.dylib.current_version & 0xff) << "\n";
5356   outs() << "compatibility version ";
5357   if (dl.dylib.compatibility_version == 0xffffffff)
5358     outs() << "n/a\n";
5359   else
5360     outs() << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
5361            << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
5362            << (dl.dylib.compatibility_version & 0xff) << "\n";
5363 }
5364
5365 static void PrintLinkEditDataCommand(MachO::linkedit_data_command ld,
5366                                      uint32_t object_size) {
5367   if (ld.cmd == MachO::LC_CODE_SIGNATURE)
5368     outs() << "      cmd LC_FUNCTION_STARTS\n";
5369   else if (ld.cmd == MachO::LC_SEGMENT_SPLIT_INFO)
5370     outs() << "      cmd LC_SEGMENT_SPLIT_INFO\n";
5371   else if (ld.cmd == MachO::LC_FUNCTION_STARTS)
5372     outs() << "      cmd LC_FUNCTION_STARTS\n";
5373   else if (ld.cmd == MachO::LC_DATA_IN_CODE)
5374     outs() << "      cmd LC_DATA_IN_CODE\n";
5375   else if (ld.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS)
5376     outs() << "      cmd LC_DYLIB_CODE_SIGN_DRS\n";
5377   else if (ld.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT)
5378     outs() << "      cmd LC_LINKER_OPTIMIZATION_HINT\n";
5379   else
5380     outs() << "      cmd " << ld.cmd << " (?)\n";
5381   outs() << "  cmdsize " << ld.cmdsize;
5382   if (ld.cmdsize != sizeof(struct MachO::linkedit_data_command))
5383     outs() << " Incorrect size\n";
5384   else
5385     outs() << "\n";
5386   outs() << "  dataoff " << ld.dataoff;
5387   if (ld.dataoff > object_size)
5388     outs() << " (past end of file)\n";
5389   else
5390     outs() << "\n";
5391   outs() << " datasize " << ld.datasize;
5392   uint64_t big_size = ld.dataoff;
5393   big_size += ld.datasize;
5394   if (big_size > object_size)
5395     outs() << " (past end of file)\n";
5396   else
5397     outs() << "\n";
5398 }
5399
5400 static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t ncmds,
5401                               uint32_t filetype, uint32_t cputype,
5402                               bool verbose) {
5403   if (ncmds == 0)
5404     return;
5405   StringRef Buf = Obj->getData();
5406   MachOObjectFile::LoadCommandInfo Command = Obj->getFirstLoadCommandInfo();
5407   for (unsigned i = 0;; ++i) {
5408     outs() << "Load command " << i << "\n";
5409     if (Command.C.cmd == MachO::LC_SEGMENT) {
5410       MachO::segment_command SLC = Obj->getSegmentLoadCommand(Command);
5411       const char *sg_segname = SLC.segname;
5412       PrintSegmentCommand(SLC.cmd, SLC.cmdsize, SLC.segname, SLC.vmaddr,
5413                           SLC.vmsize, SLC.fileoff, SLC.filesize, SLC.maxprot,
5414                           SLC.initprot, SLC.nsects, SLC.flags, Buf.size(),
5415                           verbose);
5416       for (unsigned j = 0; j < SLC.nsects; j++) {
5417         MachO::section S = Obj->getSection(Command, j);
5418         PrintSection(S.sectname, S.segname, S.addr, S.size, S.offset, S.align,
5419                      S.reloff, S.nreloc, S.flags, S.reserved1, S.reserved2,
5420                      SLC.cmd, sg_segname, filetype, Buf.size(), verbose);
5421       }
5422     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
5423       MachO::segment_command_64 SLC_64 = Obj->getSegment64LoadCommand(Command);
5424       const char *sg_segname = SLC_64.segname;
5425       PrintSegmentCommand(SLC_64.cmd, SLC_64.cmdsize, SLC_64.segname,
5426                           SLC_64.vmaddr, SLC_64.vmsize, SLC_64.fileoff,
5427                           SLC_64.filesize, SLC_64.maxprot, SLC_64.initprot,
5428                           SLC_64.nsects, SLC_64.flags, Buf.size(), verbose);
5429       for (unsigned j = 0; j < SLC_64.nsects; j++) {
5430         MachO::section_64 S_64 = Obj->getSection64(Command, j);
5431         PrintSection(S_64.sectname, S_64.segname, S_64.addr, S_64.size,
5432                      S_64.offset, S_64.align, S_64.reloff, S_64.nreloc,
5433                      S_64.flags, S_64.reserved1, S_64.reserved2, SLC_64.cmd,
5434                      sg_segname, filetype, Buf.size(), verbose);
5435       }
5436     } else if (Command.C.cmd == MachO::LC_SYMTAB) {
5437       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
5438       PrintSymtabLoadCommand(Symtab, Obj->is64Bit(), Buf.size());
5439     } else if (Command.C.cmd == MachO::LC_DYSYMTAB) {
5440       MachO::dysymtab_command Dysymtab = Obj->getDysymtabLoadCommand();
5441       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
5442       PrintDysymtabLoadCommand(Dysymtab, Symtab.nsyms, Buf.size(),
5443                                Obj->is64Bit());
5444     } else if (Command.C.cmd == MachO::LC_DYLD_INFO ||
5445                Command.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
5446       MachO::dyld_info_command DyldInfo = Obj->getDyldInfoLoadCommand(Command);
5447       PrintDyldInfoLoadCommand(DyldInfo, Buf.size());
5448     } else if (Command.C.cmd == MachO::LC_LOAD_DYLINKER ||
5449                Command.C.cmd == MachO::LC_ID_DYLINKER ||
5450                Command.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
5451       MachO::dylinker_command Dyld = Obj->getDylinkerCommand(Command);
5452       PrintDyldLoadCommand(Dyld, Command.Ptr);
5453     } else if (Command.C.cmd == MachO::LC_UUID) {
5454       MachO::uuid_command Uuid = Obj->getUuidCommand(Command);
5455       PrintUuidLoadCommand(Uuid);
5456     } else if (Command.C.cmd == MachO::LC_RPATH) {
5457       MachO::rpath_command Rpath = Obj->getRpathCommand(Command);
5458       PrintRpathLoadCommand(Rpath, Command.Ptr);
5459     } else if (Command.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
5460                Command.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
5461       MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
5462       PrintVersionMinLoadCommand(Vd);
5463     } else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
5464       MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
5465       PrintSourceVersionCommand(Sd);
5466     } else if (Command.C.cmd == MachO::LC_MAIN) {
5467       MachO::entry_point_command Ep = Obj->getEntryPointCommand(Command);
5468       PrintEntryPointCommand(Ep);
5469     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO) {
5470       MachO::encryption_info_command Ei =
5471           Obj->getEncryptionInfoCommand(Command);
5472       PrintEncryptionInfoCommand(Ei, Buf.size());
5473     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
5474       MachO::encryption_info_command_64 Ei =
5475           Obj->getEncryptionInfoCommand64(Command);
5476       PrintEncryptionInfoCommand64(Ei, Buf.size());
5477     } else if (Command.C.cmd == MachO::LC_LINKER_OPTION) {
5478       MachO::linker_option_command Lo =
5479           Obj->getLinkerOptionLoadCommand(Command);
5480       PrintLinkerOptionCommand(Lo, Command.Ptr);
5481     } else if (Command.C.cmd == MachO::LC_SUB_FRAMEWORK) {
5482       MachO::sub_framework_command Sf = Obj->getSubFrameworkCommand(Command);
5483       PrintSubFrameworkCommand(Sf, Command.Ptr);
5484     } else if (Command.C.cmd == MachO::LC_SUB_UMBRELLA) {
5485       MachO::sub_umbrella_command Sf = Obj->getSubUmbrellaCommand(Command);
5486       PrintSubUmbrellaCommand(Sf, Command.Ptr);
5487     } else if (Command.C.cmd == MachO::LC_SUB_LIBRARY) {
5488       MachO::sub_library_command Sl = Obj->getSubLibraryCommand(Command);
5489       PrintSubLibraryCommand(Sl, Command.Ptr);
5490     } else if (Command.C.cmd == MachO::LC_SUB_CLIENT) {
5491       MachO::sub_client_command Sc = Obj->getSubClientCommand(Command);
5492       PrintSubClientCommand(Sc, Command.Ptr);
5493     } else if (Command.C.cmd == MachO::LC_ROUTINES) {
5494       MachO::routines_command Rc = Obj->getRoutinesCommand(Command);
5495       PrintRoutinesCommand(Rc);
5496     } else if (Command.C.cmd == MachO::LC_ROUTINES_64) {
5497       MachO::routines_command_64 Rc = Obj->getRoutinesCommand64(Command);
5498       PrintRoutinesCommand64(Rc);
5499     } else if (Command.C.cmd == MachO::LC_THREAD ||
5500                Command.C.cmd == MachO::LC_UNIXTHREAD) {
5501       MachO::thread_command Tc = Obj->getThreadCommand(Command);
5502       PrintThreadCommand(Tc, Command.Ptr, Obj->isLittleEndian(), cputype);
5503     } else if (Command.C.cmd == MachO::LC_LOAD_DYLIB ||
5504                Command.C.cmd == MachO::LC_ID_DYLIB ||
5505                Command.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
5506                Command.C.cmd == MachO::LC_REEXPORT_DYLIB ||
5507                Command.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
5508                Command.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
5509       MachO::dylib_command Dl = Obj->getDylibIDLoadCommand(Command);
5510       PrintDylibCommand(Dl, Command.Ptr);
5511     } else if (Command.C.cmd == MachO::LC_CODE_SIGNATURE ||
5512                Command.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO ||
5513                Command.C.cmd == MachO::LC_FUNCTION_STARTS ||
5514                Command.C.cmd == MachO::LC_DATA_IN_CODE ||
5515                Command.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS ||
5516                Command.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
5517       MachO::linkedit_data_command Ld =
5518           Obj->getLinkeditDataLoadCommand(Command);
5519       PrintLinkEditDataCommand(Ld, Buf.size());
5520     } else {
5521       outs() << "      cmd ?(" << format("0x%08" PRIx32, Command.C.cmd)
5522              << ")\n";
5523       outs() << "  cmdsize " << Command.C.cmdsize << "\n";
5524       // TODO: get and print the raw bytes of the load command.
5525     }
5526     // TODO: print all the other kinds of load commands.
5527     if (i == ncmds - 1)
5528       break;
5529     else
5530       Command = Obj->getNextLoadCommandInfo(Command);
5531   }
5532 }
5533
5534 static void getAndPrintMachHeader(const MachOObjectFile *Obj, uint32_t &ncmds,
5535                                   uint32_t &filetype, uint32_t &cputype,
5536                                   bool verbose) {
5537   if (Obj->is64Bit()) {
5538     MachO::mach_header_64 H_64;
5539     H_64 = Obj->getHeader64();
5540     PrintMachHeader(H_64.magic, H_64.cputype, H_64.cpusubtype, H_64.filetype,
5541                     H_64.ncmds, H_64.sizeofcmds, H_64.flags, verbose);
5542     ncmds = H_64.ncmds;
5543     filetype = H_64.filetype;
5544     cputype = H_64.cputype;
5545   } else {
5546     MachO::mach_header H;
5547     H = Obj->getHeader();
5548     PrintMachHeader(H.magic, H.cputype, H.cpusubtype, H.filetype, H.ncmds,
5549                     H.sizeofcmds, H.flags, verbose);
5550     ncmds = H.ncmds;
5551     filetype = H.filetype;
5552     cputype = H.cputype;
5553   }
5554 }
5555
5556 void llvm::printMachOFileHeader(const object::ObjectFile *Obj) {
5557   const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
5558   uint32_t ncmds = 0;
5559   uint32_t filetype = 0;
5560   uint32_t cputype = 0;
5561   getAndPrintMachHeader(file, ncmds, filetype, cputype, !NonVerbose);
5562   PrintLoadCommands(file, ncmds, filetype, cputype, !NonVerbose);
5563 }
5564
5565 //===----------------------------------------------------------------------===//
5566 // export trie dumping
5567 //===----------------------------------------------------------------------===//
5568
5569 void llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) {
5570   for (const llvm::object::ExportEntry &Entry : Obj->exports()) {
5571     uint64_t Flags = Entry.flags();
5572     bool ReExport = (Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
5573     bool WeakDef = (Flags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
5574     bool ThreadLocal = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
5575                         MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL);
5576     bool Abs = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
5577                 MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
5578     bool Resolver = (Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
5579     if (ReExport)
5580       outs() << "[re-export] ";
5581     else
5582       outs() << format("0x%08llX  ",
5583                        Entry.address()); // FIXME:add in base address
5584     outs() << Entry.name();
5585     if (WeakDef || ThreadLocal || Resolver || Abs) {
5586       bool NeedsComma = false;
5587       outs() << " [";
5588       if (WeakDef) {
5589         outs() << "weak_def";
5590         NeedsComma = true;
5591       }
5592       if (ThreadLocal) {
5593         if (NeedsComma)
5594           outs() << ", ";
5595         outs() << "per-thread";
5596         NeedsComma = true;
5597       }
5598       if (Abs) {
5599         if (NeedsComma)
5600           outs() << ", ";
5601         outs() << "absolute";
5602         NeedsComma = true;
5603       }
5604       if (Resolver) {
5605         if (NeedsComma)
5606           outs() << ", ";
5607         outs() << format("resolver=0x%08llX", Entry.other());
5608         NeedsComma = true;
5609       }
5610       outs() << "]";
5611     }
5612     if (ReExport) {
5613       StringRef DylibName = "unknown";
5614       int Ordinal = Entry.other() - 1;
5615       Obj->getLibraryShortNameByIndex(Ordinal, DylibName);
5616       if (Entry.otherName().empty())
5617         outs() << " (from " << DylibName << ")";
5618       else
5619         outs() << " (" << Entry.otherName() << " from " << DylibName << ")";
5620     }
5621     outs() << "\n";
5622   }
5623 }
5624
5625 //===----------------------------------------------------------------------===//
5626 // rebase table dumping
5627 //===----------------------------------------------------------------------===//
5628
5629 namespace {
5630 class SegInfo {
5631 public:
5632   SegInfo(const object::MachOObjectFile *Obj);
5633
5634   StringRef segmentName(uint32_t SegIndex);
5635   StringRef sectionName(uint32_t SegIndex, uint64_t SegOffset);
5636   uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
5637
5638 private:
5639   struct SectionInfo {
5640     uint64_t Address;
5641     uint64_t Size;
5642     StringRef SectionName;
5643     StringRef SegmentName;
5644     uint64_t OffsetInSegment;
5645     uint64_t SegmentStartAddress;
5646     uint32_t SegmentIndex;
5647   };
5648   const SectionInfo &findSection(uint32_t SegIndex, uint64_t SegOffset);
5649   SmallVector<SectionInfo, 32> Sections;
5650 };
5651 }
5652
5653 SegInfo::SegInfo(const object::MachOObjectFile *Obj) {
5654   // Build table of sections so segIndex/offset pairs can be translated.
5655   uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
5656   StringRef CurSegName;
5657   uint64_t CurSegAddress;
5658   for (const SectionRef &Section : Obj->sections()) {
5659     SectionInfo Info;
5660     if (error(Section.getName(Info.SectionName)))
5661       return;
5662     Info.Address = Section.getAddress();
5663     Info.Size = Section.getSize();
5664     Info.SegmentName =
5665         Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
5666     if (!Info.SegmentName.equals(CurSegName)) {
5667       ++CurSegIndex;
5668       CurSegName = Info.SegmentName;
5669       CurSegAddress = Info.Address;
5670     }
5671     Info.SegmentIndex = CurSegIndex - 1;
5672     Info.OffsetInSegment = Info.Address - CurSegAddress;
5673     Info.SegmentStartAddress = CurSegAddress;
5674     Sections.push_back(Info);
5675   }
5676 }
5677
5678 StringRef SegInfo::segmentName(uint32_t SegIndex) {
5679   for (const SectionInfo &SI : Sections) {
5680     if (SI.SegmentIndex == SegIndex)
5681       return SI.SegmentName;
5682   }
5683   llvm_unreachable("invalid segIndex");
5684 }
5685
5686 const SegInfo::SectionInfo &SegInfo::findSection(uint32_t SegIndex,
5687                                                  uint64_t OffsetInSeg) {
5688   for (const SectionInfo &SI : Sections) {
5689     if (SI.SegmentIndex != SegIndex)
5690       continue;
5691     if (SI.OffsetInSegment > OffsetInSeg)
5692       continue;
5693     if (OffsetInSeg >= (SI.OffsetInSegment + SI.Size))
5694       continue;
5695     return SI;
5696   }
5697   llvm_unreachable("segIndex and offset not in any section");
5698 }
5699
5700 StringRef SegInfo::sectionName(uint32_t SegIndex, uint64_t OffsetInSeg) {
5701   return findSection(SegIndex, OffsetInSeg).SectionName;
5702 }
5703
5704 uint64_t SegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
5705   const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
5706   return SI.SegmentStartAddress + OffsetInSeg;
5707 }
5708
5709 void llvm::printMachORebaseTable(const object::MachOObjectFile *Obj) {
5710   // Build table of sections so names can used in final output.
5711   SegInfo sectionTable(Obj);
5712
5713   outs() << "segment  section            address     type\n";
5714   for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable()) {
5715     uint32_t SegIndex = Entry.segmentIndex();
5716     uint64_t OffsetInSeg = Entry.segmentOffset();
5717     StringRef SegmentName = sectionTable.segmentName(SegIndex);
5718     StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
5719     uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
5720
5721     // Table lines look like: __DATA  __nl_symbol_ptr  0x0000F00C  pointer
5722     outs() << format("%-8s %-18s 0x%08" PRIX64 "  %s\n",
5723                      SegmentName.str().c_str(), SectionName.str().c_str(),
5724                      Address, Entry.typeName().str().c_str());
5725   }
5726 }
5727
5728 static StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) {
5729   StringRef DylibName;
5730   switch (Ordinal) {
5731   case MachO::BIND_SPECIAL_DYLIB_SELF:
5732     return "this-image";
5733   case MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE:
5734     return "main-executable";
5735   case MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP:
5736     return "flat-namespace";
5737   default:
5738     if (Ordinal > 0) {
5739       std::error_code EC =
5740           Obj->getLibraryShortNameByIndex(Ordinal - 1, DylibName);
5741       if (EC)
5742         return "<<bad library ordinal>>";
5743       return DylibName;
5744     }
5745   }
5746   return "<<unknown special ordinal>>";
5747 }
5748
5749 //===----------------------------------------------------------------------===//
5750 // bind table dumping
5751 //===----------------------------------------------------------------------===//
5752
5753 void llvm::printMachOBindTable(const object::MachOObjectFile *Obj) {
5754   // Build table of sections so names can used in final output.
5755   SegInfo sectionTable(Obj);
5756
5757   outs() << "segment  section            address    type       "
5758             "addend dylib            symbol\n";
5759   for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable()) {
5760     uint32_t SegIndex = Entry.segmentIndex();
5761     uint64_t OffsetInSeg = Entry.segmentOffset();
5762     StringRef SegmentName = sectionTable.segmentName(SegIndex);
5763     StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
5764     uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
5765
5766     // Table lines look like:
5767     //  __DATA  __got  0x00012010    pointer   0 libSystem ___stack_chk_guard
5768     StringRef Attr;
5769     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT)
5770       Attr = " (weak_import)";
5771     outs() << left_justify(SegmentName, 8) << " "
5772            << left_justify(SectionName, 18) << " "
5773            << format_hex(Address, 10, true) << " "
5774            << left_justify(Entry.typeName(), 8) << " "
5775            << format_decimal(Entry.addend(), 8) << " "
5776            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
5777            << Entry.symbolName() << Attr << "\n";
5778   }
5779 }
5780
5781 //===----------------------------------------------------------------------===//
5782 // lazy bind table dumping
5783 //===----------------------------------------------------------------------===//
5784
5785 void llvm::printMachOLazyBindTable(const object::MachOObjectFile *Obj) {
5786   // Build table of sections so names can used in final output.
5787   SegInfo sectionTable(Obj);
5788
5789   outs() << "segment  section            address     "
5790             "dylib            symbol\n";
5791   for (const llvm::object::MachOBindEntry &Entry : Obj->lazyBindTable()) {
5792     uint32_t SegIndex = Entry.segmentIndex();
5793     uint64_t OffsetInSeg = Entry.segmentOffset();
5794     StringRef SegmentName = sectionTable.segmentName(SegIndex);
5795     StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
5796     uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
5797
5798     // Table lines look like:
5799     //  __DATA  __got  0x00012010 libSystem ___stack_chk_guard
5800     outs() << left_justify(SegmentName, 8) << " "
5801            << left_justify(SectionName, 18) << " "
5802            << format_hex(Address, 10, true) << " "
5803            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
5804            << Entry.symbolName() << "\n";
5805   }
5806 }
5807
5808 //===----------------------------------------------------------------------===//
5809 // weak bind table dumping
5810 //===----------------------------------------------------------------------===//
5811
5812 void llvm::printMachOWeakBindTable(const object::MachOObjectFile *Obj) {
5813   // Build table of sections so names can used in final output.
5814   SegInfo sectionTable(Obj);
5815
5816   outs() << "segment  section            address     "
5817             "type       addend   symbol\n";
5818   for (const llvm::object::MachOBindEntry &Entry : Obj->weakBindTable()) {
5819     // Strong symbols don't have a location to update.
5820     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
5821       outs() << "                                        strong              "
5822              << Entry.symbolName() << "\n";
5823       continue;
5824     }
5825     uint32_t SegIndex = Entry.segmentIndex();
5826     uint64_t OffsetInSeg = Entry.segmentOffset();
5827     StringRef SegmentName = sectionTable.segmentName(SegIndex);
5828     StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
5829     uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
5830
5831     // Table lines look like:
5832     // __DATA  __data  0x00001000  pointer    0   _foo
5833     outs() << left_justify(SegmentName, 8) << " "
5834            << left_justify(SectionName, 18) << " "
5835            << format_hex(Address, 10, true) << " "
5836            << left_justify(Entry.typeName(), 8) << " "
5837            << format_decimal(Entry.addend(), 8) << "   " << Entry.symbolName()
5838            << "\n";
5839   }
5840 }
5841
5842 // get_dyld_bind_info_symbolname() is used for disassembly and passed an
5843 // address, ReferenceValue, in the Mach-O file and looks in the dyld bind
5844 // information for that address. If the address is found its binding symbol
5845 // name is returned.  If not nullptr is returned.
5846 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
5847                                                  struct DisassembleInfo *info) {
5848   if (info->bindtable == nullptr) {
5849     info->bindtable = new (BindTable);
5850     SegInfo sectionTable(info->O);
5851     for (const llvm::object::MachOBindEntry &Entry : info->O->bindTable()) {
5852       uint32_t SegIndex = Entry.segmentIndex();
5853       uint64_t OffsetInSeg = Entry.segmentOffset();
5854       uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
5855       const char *SymbolName = nullptr;
5856       StringRef name = Entry.symbolName();
5857       if (!name.empty())
5858         SymbolName = name.data();
5859       info->bindtable->push_back(std::make_pair(Address, SymbolName));
5860     }
5861   }
5862   for (bind_table_iterator BI = info->bindtable->begin(),
5863                            BE = info->bindtable->end();
5864        BI != BE; ++BI) {
5865     uint64_t Address = BI->first;
5866     if (ReferenceValue == Address) {
5867       const char *SymbolName = BI->second;
5868       return SymbolName;
5869     }
5870   }
5871   return nullptr;
5872 }