]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/blob - tools/llvm-objdump/MachODump.cpp
Run clang-format on tools/llvm-objdump/MachODump.cpp again as some of my
[opencl/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 //===----------------------------------------------------------------------===//
14 #include "llvm-objdump.h"
15 #include "llvm-c/Disassembler.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Config/config.h"
20 #include "llvm/DebugInfo/DIContext.h"
21 #include "llvm/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/GraphWriter.h"
38 #include "llvm/Support/MachO.h"
39 #include "llvm/Support/MemoryBuffer.h"
40 #include "llvm/Support/FormattedStream.h"
41 #include "llvm/Support/TargetRegistry.h"
42 #include "llvm/Support/TargetSelect.h"
43 #include "llvm/Support/raw_ostream.h"
44 #include <algorithm>
45 #include <cstring>
46 #include <system_error>
48 #if HAVE_CXXABI_H
49 #include <cxxabi.h>
50 #endif
52 using namespace llvm;
53 using namespace object;
55 static cl::opt<bool>
56     UseDbg("g",
57            cl::desc("Print line information from debug info if available"));
59 static cl::opt<std::string> DSYMFile("dsym",
60                                      cl::desc("Use .dSYM file for debug info"));
62 static cl::opt<bool> FullLeadingAddr("full-leading-addr",
63                                      cl::desc("Print full leading address"));
65 static cl::opt<bool>
66     PrintImmHex("print-imm-hex",
67                 cl::desc("Use hex format for immediate values"));
69 static cl::list<std::string>
70     ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
71               cl::ZeroOrMore);
72 bool ArchAll = false;
74 static std::string ThumbTripleName;
76 static const Target *GetTarget(const MachOObjectFile *MachOObj,
77                                const char **McpuDefault,
78                                const Target **ThumbTarget) {
79   // Figure out the target triple.
80   if (TripleName.empty()) {
81     llvm::Triple TT("unknown-unknown-unknown");
82     llvm::Triple ThumbTriple = Triple();
83     TT = MachOObj->getArch(McpuDefault, &ThumbTriple);
84     TripleName = TT.str();
85     ThumbTripleName = ThumbTriple.str();
86   }
88   // Get the target specific parser.
89   std::string Error;
90   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
91   if (TheTarget && ThumbTripleName.empty())
92     return TheTarget;
94   *ThumbTarget = TargetRegistry::lookupTarget(ThumbTripleName, Error);
95   if (*ThumbTarget)
96     return TheTarget;
98   errs() << "llvm-objdump: error: unable to get target for '";
99   if (!TheTarget)
100     errs() << TripleName;
101   else
102     errs() << ThumbTripleName;
103   errs() << "', see --version and --triple.\n";
104   return nullptr;
107 struct SymbolSorter {
108   bool operator()(const SymbolRef &A, const SymbolRef &B) {
109     SymbolRef::Type AType, BType;
110     A.getType(AType);
111     B.getType(BType);
113     uint64_t AAddr, BAddr;
114     if (AType != SymbolRef::ST_Function)
115       AAddr = 0;
116     else
117       A.getAddress(AAddr);
118     if (BType != SymbolRef::ST_Function)
119       BAddr = 0;
120     else
121       B.getAddress(BAddr);
122     return AAddr < BAddr;
123   }
124 };
126 // Types for the storted data in code table that is built before disassembly
127 // and the predicate function to sort them.
128 typedef std::pair<uint64_t, DiceRef> DiceTableEntry;
129 typedef std::vector<DiceTableEntry> DiceTable;
130 typedef DiceTable::iterator dice_table_iterator;
132 // This is used to search for a data in code table entry for the PC being
133 // disassembled.  The j parameter has the PC in j.first.  A single data in code
134 // table entry can cover many bytes for each of its Kind's.  So if the offset,
135 // aka the i.first value, of the data in code table entry plus its Length
136 // covers the PC being searched for this will return true.  If not it will
137 // return false.
138 static bool compareDiceTableEntries(const DiceTableEntry &i,
139                                     const DiceTableEntry &j) {
140   uint16_t Length;
141   i.second.getLength(Length);
143   return j.first >= i.first && j.first < i.first + Length;
146 static uint64_t DumpDataInCode(const char *bytes, uint64_t Length,
147                                unsigned short Kind) {
148   uint32_t Value, Size = 1;
150   switch (Kind) {
151   default:
152   case MachO::DICE_KIND_DATA:
153     if (Length >= 4) {
154       if (!NoShowRawInsn)
155         DumpBytes(StringRef(bytes, 4));
156       Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
157       outs() << "\t.long " << Value;
158       Size = 4;
159     } else if (Length >= 2) {
160       if (!NoShowRawInsn)
161         DumpBytes(StringRef(bytes, 2));
162       Value = bytes[1] << 8 | bytes[0];
163       outs() << "\t.short " << Value;
164       Size = 2;
165     } else {
166       if (!NoShowRawInsn)
167         DumpBytes(StringRef(bytes, 2));
168       Value = bytes[0];
169       outs() << "\t.byte " << Value;
170       Size = 1;
171     }
172     if (Kind == MachO::DICE_KIND_DATA)
173       outs() << "\t@ KIND_DATA\n";
174     else
175       outs() << "\t@ data in code kind = " << Kind << "\n";
176     break;
177   case MachO::DICE_KIND_JUMP_TABLE8:
178     if (!NoShowRawInsn)
179       DumpBytes(StringRef(bytes, 1));
180     Value = bytes[0];
181     outs() << "\t.byte " << format("%3u", Value) << "\t@ KIND_JUMP_TABLE8\n";
182     Size = 1;
183     break;
184   case MachO::DICE_KIND_JUMP_TABLE16:
185     if (!NoShowRawInsn)
186       DumpBytes(StringRef(bytes, 2));
187     Value = bytes[1] << 8 | bytes[0];
188     outs() << "\t.short " << format("%5u", Value & 0xffff)
189            << "\t@ KIND_JUMP_TABLE16\n";
190     Size = 2;
191     break;
192   case MachO::DICE_KIND_JUMP_TABLE32:
193   case MachO::DICE_KIND_ABS_JUMP_TABLE32:
194     if (!NoShowRawInsn)
195       DumpBytes(StringRef(bytes, 4));
196     Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
197     outs() << "\t.long " << Value;
198     if (Kind == MachO::DICE_KIND_JUMP_TABLE32)
199       outs() << "\t@ KIND_JUMP_TABLE32\n";
200     else
201       outs() << "\t@ KIND_ABS_JUMP_TABLE32\n";
202     Size = 4;
203     break;
204   }
205   return Size;
208 static void getSectionsAndSymbols(const MachO::mach_header Header,
209                                   MachOObjectFile *MachOObj,
210                                   std::vector<SectionRef> &Sections,
211                                   std::vector<SymbolRef> &Symbols,
212                                   SmallVectorImpl<uint64_t> &FoundFns,
213                                   uint64_t &BaseSegmentAddress) {
214   for (const SymbolRef &Symbol : MachOObj->symbols()) {
215     StringRef SymName;
216     Symbol.getName(SymName);
217     if (!SymName.startswith("ltmp"))
218       Symbols.push_back(Symbol);
219   }
221   for (const SectionRef &Section : MachOObj->sections()) {
222     StringRef SectName;
223     Section.getName(SectName);
224     Sections.push_back(Section);
225   }
227   MachOObjectFile::LoadCommandInfo Command =
228       MachOObj->getFirstLoadCommandInfo();
229   bool BaseSegmentAddressSet = false;
230   for (unsigned i = 0;; ++i) {
231     if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
232       // We found a function starts segment, parse the addresses for later
233       // consumption.
234       MachO::linkedit_data_command LLC =
235           MachOObj->getLinkeditDataLoadCommand(Command);
237       MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
238     } else if (Command.C.cmd == MachO::LC_SEGMENT) {
239       MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command);
240       StringRef SegName = SLC.segname;
241       if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
242         BaseSegmentAddressSet = true;
243         BaseSegmentAddress = SLC.vmaddr;
244       }
245     }
247     if (i == Header.ncmds - 1)
248       break;
249     else
250       Command = MachOObj->getNextLoadCommandInfo(Command);
251   }
254 // checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file
255 // and if it is and there is a list of architecture flags is specified then
256 // check to make sure this Mach-O file is one of those architectures or all
257 // architectures were specified.  If not then an error is generated and this
258 // routine returns false.  Else it returns true.
259 static bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) {
260   if (isa<MachOObjectFile>(O) && !ArchAll && ArchFlags.size() != 0) {
261     MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O);
262     bool ArchFound = false;
263     MachO::mach_header H;
264     MachO::mach_header_64 H_64;
265     Triple T;
266     if (MachO->is64Bit()) {
267       H_64 = MachO->MachOObjectFile::getHeader64();
268       T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype);
269     } else {
270       H = MachO->MachOObjectFile::getHeader();
271       T = MachOObjectFile::getArch(H.cputype, H.cpusubtype);
272     }
273     unsigned i;
274     for (i = 0; i < ArchFlags.size(); ++i) {
275       if (ArchFlags[i] == T.getArchName())
276         ArchFound = true;
277       break;
278     }
279     if (!ArchFound) {
280       errs() << "llvm-objdump: file: " + Filename + " does not contain "
281              << "architecture: " + ArchFlags[i] + "\n";
282       return false;
283     }
284   }
285   return true;
288 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF);
290 // ProcessMachO() is passed a single opened Mach-O file, which may be an
291 // archive member and or in a slice of a universal file.  It prints the
292 // the file name and header info and then processes it according to the
293 // command line options.
294 static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF,
295                          StringRef ArchiveMemberName = StringRef(),
296                          StringRef ArchitectureName = StringRef()) {
297   outs() << Filename;
298   if (!ArchiveMemberName.empty())
299     outs() << '(' << ArchiveMemberName << ')';
300   if (!ArchitectureName.empty())
301     outs() << " (architecture " << ArchitectureName << ")";
302   outs() << ":\n";
304   if (Disassemble)
305     DisassembleMachO(Filename, MachOOF);
306   // TODO: These should/could be printed in Darwin's otool(1) or nm(1) style
307   //       for -macho. Or just used a new option that maps to the otool(1)
308   //       option like -r, -l, etc.  Or just the normal llvm-objdump option
309   //       but now for this slice so that the -arch options can be used.
310   // if (Relocations)
311   //   PrintRelocations(MachOOF);
312   // if (SectionHeaders)
313   //   PrintSectionHeaders(MachOOF);
314   // if (SectionContents)
315   //   PrintSectionContents(MachOOF);
316   // if (SymbolTable)
317   //   PrintSymbolTable(MachOOF);
318   // if (UnwindInfo)
319   //   PrintUnwindInfo(MachOOF);
320   if (PrivateHeaders)
321     printMachOFileHeader(MachOOF);
322   if (ExportsTrie)
323     printExportsTrie(MachOOF);
324   if (Rebase)
325     printRebaseTable(MachOOF);
326   if (Bind)
327     printBindTable(MachOOF);
328   if (LazyBind)
329     printLazyBindTable(MachOOF);
330   if (WeakBind)
331     printWeakBindTable(MachOOF);
334 // ParseInputMachO() parses the named Mach-O file in Filename and handles the
335 // -arch flags selecting just those slices as specified by them and also parses
336 // archive files.  Then for each individual Mach-O file ProcessMachO() is
337 // called to process the file based on the command line options.
338 void llvm::ParseInputMachO(StringRef Filename) {
339   // Check for -arch all and verifiy the -arch flags are valid.
340   for (unsigned i = 0; i < ArchFlags.size(); ++i) {
341     if (ArchFlags[i] == "all") {
342       ArchAll = true;
343     } else {
344       if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
345         errs() << "llvm-objdump: Unknown architecture named '" + ArchFlags[i] +
346                       "'for the -arch option\n";
347         return;
348       }
349     }
350   }
352   // Attempt to open the binary.
353   ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
354   if (std::error_code EC = BinaryOrErr.getError()) {
355     errs() << "llvm-objdump: '" << Filename << "': " << EC.message() << ".\n";
356     return;
357   }
358   Binary &Bin = *BinaryOrErr.get().getBinary();
360   if (Archive *A = dyn_cast<Archive>(&Bin)) {
361     outs() << "Archive : " << Filename << "\n";
362     for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
363          I != E; ++I) {
364       ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary();
365       if (ChildOrErr.getError())
366         continue;
367       if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
368         if (!checkMachOAndArchFlags(O, Filename))
369           return;
370         ProcessMachO(Filename, O, O->getFileName());
371       }
372     }
373     return;
374   }
375   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
376     // If we have a list of architecture flags specified dump only those.
377     if (!ArchAll && ArchFlags.size() != 0) {
378       // Look for a slice in the universal binary that matches each ArchFlag.
379       bool ArchFound;
380       for (unsigned i = 0; i < ArchFlags.size(); ++i) {
381         ArchFound = false;
382         for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
383                                                    E = UB->end_objects();
384              I != E; ++I) {
385           if (ArchFlags[i] == I->getArchTypeName()) {
386             ArchFound = true;
387             ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
388                 I->getAsObjectFile();
389             std::string ArchitectureName = "";
390             if (ArchFlags.size() > 1)
391               ArchitectureName = I->getArchTypeName();
392             if (ObjOrErr) {
393               ObjectFile &O = *ObjOrErr.get();
394               if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
395                 ProcessMachO(Filename, MachOOF, "", ArchitectureName);
396             } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
397                            I->getAsArchive()) {
398               std::unique_ptr<Archive> &A = *AOrErr;
399               outs() << "Archive : " << Filename;
400               if (!ArchitectureName.empty())
401                 outs() << " (architecture " << ArchitectureName << ")";
402               outs() << "\n";
403               for (Archive::child_iterator AI = A->child_begin(),
404                                            AE = A->child_end();
405                    AI != AE; ++AI) {
406                 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
407                 if (ChildOrErr.getError())
408                   continue;
409                 if (MachOObjectFile *O =
410                         dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
411                   ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
412               }
413             }
414           }
415         }
416         if (!ArchFound) {
417           errs() << "llvm-objdump: file: " + Filename + " does not contain "
418                  << "architecture: " + ArchFlags[i] + "\n";
419           return;
420         }
421       }
422       return;
423     }
424     // No architecture flags were specified so if this contains a slice that
425     // matches the host architecture dump only that.
426     if (!ArchAll) {
427       StringRef HostArchName = MachOObjectFile::getHostArch().getArchName();
428       for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
429                                                  E = UB->end_objects();
430            I != E; ++I) {
431         if (HostArchName == I->getArchTypeName()) {
432           ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
433           std::string ArchiveName;
434           ArchiveName.clear();
435           if (ObjOrErr) {
436             ObjectFile &O = *ObjOrErr.get();
437             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
438               ProcessMachO(Filename, MachOOF);
439           } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
440                          I->getAsArchive()) {
441             std::unique_ptr<Archive> &A = *AOrErr;
442             outs() << "Archive : " << Filename << "\n";
443             for (Archive::child_iterator AI = A->child_begin(),
444                                          AE = A->child_end();
445                  AI != AE; ++AI) {
446               ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
447               if (ChildOrErr.getError())
448                 continue;
449               if (MachOObjectFile *O =
450                       dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
451                 ProcessMachO(Filename, O, O->getFileName());
452             }
453           }
454           return;
455         }
456       }
457     }
458     // Either all architectures have been specified or none have been specified
459     // and this does not contain the host architecture so dump all the slices.
460     bool moreThanOneArch = UB->getNumberOfObjects() > 1;
461     for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
462                                                E = UB->end_objects();
463          I != E; ++I) {
464       ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
465       std::string ArchitectureName = "";
466       if (moreThanOneArch)
467         ArchitectureName = I->getArchTypeName();
468       if (ObjOrErr) {
469         ObjectFile &Obj = *ObjOrErr.get();
470         if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
471           ProcessMachO(Filename, MachOOF, "", ArchitectureName);
472       } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
473         std::unique_ptr<Archive> &A = *AOrErr;
474         outs() << "Archive : " << Filename;
475         if (!ArchitectureName.empty())
476           outs() << " (architecture " << ArchitectureName << ")";
477         outs() << "\n";
478         for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
479              AI != AE; ++AI) {
480           ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
481           if (ChildOrErr.getError())
482             continue;
483           if (MachOObjectFile *O =
484                   dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
485             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
486               ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
487                            ArchitectureName);
488           }
489         }
490       }
491     }
492     return;
493   }
494   if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
495     if (!checkMachOAndArchFlags(O, Filename))
496       return;
497     if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
498       ProcessMachO(Filename, MachOOF);
499     } else
500       errs() << "llvm-objdump: '" << Filename << "': "
501              << "Object is not a Mach-O file type.\n";
502   } else
503     errs() << "llvm-objdump: '" << Filename << "': "
504            << "Unrecognized file type.\n";
507 typedef DenseMap<uint64_t, StringRef> SymbolAddressMap;
508 typedef std::pair<uint64_t, const char *> BindInfoEntry;
509 typedef std::vector<BindInfoEntry> BindTable;
510 typedef BindTable::iterator bind_table_iterator;
512 // The block of info used by the Symbolizer call backs.
513 struct DisassembleInfo {
514   bool verbose;
515   MachOObjectFile *O;
516   SectionRef S;
517   SymbolAddressMap *AddrMap;
518   std::vector<SectionRef> *Sections;
519   const char *class_name;
520   const char *selector_name;
521   char *method;
522   char *demangled_name;
523   uint64_t adrp_addr;
524   uint32_t adrp_inst;
525   BindTable *bindtable;
526 };
528 // GuessSymbolName is passed the address of what might be a symbol and a
529 // pointer to the DisassembleInfo struct.  It returns the name of a symbol
530 // with that address or nullptr if no symbol is found with that address.
531 static const char *GuessSymbolName(uint64_t value,
532                                    struct DisassembleInfo *info) {
533   const char *SymbolName = nullptr;
534   // A DenseMap can't lookup up some values.
535   if (value != 0xffffffffffffffffULL && value != 0xfffffffffffffffeULL) {
536     StringRef name = info->AddrMap->lookup(value);
537     if (!name.empty())
538       SymbolName = name.data();
539   }
540   return SymbolName;
543 // SymbolizerGetOpInfo() is the operand information call back function.
544 // This is called to get the symbolic information for operand(s) of an
545 // instruction when it is being done.  This routine does this from
546 // the relocation information, symbol table, etc. That block of information
547 // is a pointer to the struct DisassembleInfo that was passed when the
548 // disassembler context was created and passed to back to here when
549 // called back by the disassembler for instruction operands that could have
550 // relocation information. The address of the instruction containing operand is
551 // at the Pc parameter.  The immediate value the operand has is passed in
552 // op_info->Value and is at Offset past the start of the instruction and has a
553 // byte Size of 1, 2 or 4. The symbolc information is returned in TagBuf is the
554 // LLVMOpInfo1 struct defined in the header "llvm-c/Disassembler.h" as symbol
555 // names and addends of the symbolic expression to add for the operand.  The
556 // value of TagType is currently 1 (for the LLVMOpInfo1 struct). If symbolic
557 // information is returned then this function returns 1 else it returns 0.
558 int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
559                         uint64_t Size, int TagType, void *TagBuf) {
560   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
561   struct LLVMOpInfo1 *op_info = (struct LLVMOpInfo1 *)TagBuf;
562   uint64_t value = op_info->Value;
564   // Make sure all fields returned are zero if we don't set them.
565   memset((void *)op_info, '\0', sizeof(struct LLVMOpInfo1));
566   op_info->Value = value;
568   // If the TagType is not the value 1 which it code knows about or if no
569   // verbose symbolic information is wanted then just return 0, indicating no
570   // information is being returned.
571   if (TagType != 1 || info->verbose == false)
572     return 0;
574   unsigned int Arch = info->O->getArch();
575   if (Arch == Triple::x86) {
576     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
577       return 0;
578     // First search the section's relocation entries (if any) for an entry
579     // for this section offset.
580     uint32_t sect_addr = info->S.getAddress();
581     uint32_t sect_offset = (Pc + Offset) - sect_addr;
582     bool reloc_found = false;
583     DataRefImpl Rel;
584     MachO::any_relocation_info RE;
585     bool isExtern = false;
586     SymbolRef Symbol;
587     bool r_scattered = false;
588     uint32_t r_value, pair_r_value, r_type;
589     for (const RelocationRef &Reloc : info->S.relocations()) {
590       uint64_t RelocOffset;
591       Reloc.getOffset(RelocOffset);
592       if (RelocOffset == sect_offset) {
593         Rel = Reloc.getRawDataRefImpl();
594         RE = info->O->getRelocation(Rel);
595         r_type = info->O->getAnyRelocationType(RE);
596         r_scattered = info->O->isRelocationScattered(RE);
597         if (r_scattered) {
598           r_value = info->O->getScatteredRelocationValue(RE);
599           if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
600               r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
601             DataRefImpl RelNext = Rel;
602             info->O->moveRelocationNext(RelNext);
603             MachO::any_relocation_info RENext;
604             RENext = info->O->getRelocation(RelNext);
605             if (info->O->isRelocationScattered(RENext))
606               pair_r_value = info->O->getScatteredRelocationValue(RENext);
607             else
608               return 0;
609           }
610         } else {
611           isExtern = info->O->getPlainRelocationExternal(RE);
612           if (isExtern) {
613             symbol_iterator RelocSym = Reloc.getSymbol();
614             Symbol = *RelocSym;
615           }
616         }
617         reloc_found = true;
618         break;
619       }
620     }
621     if (reloc_found && isExtern) {
622       StringRef SymName;
623       Symbol.getName(SymName);
624       const char *name = SymName.data();
625       op_info->AddSymbol.Present = 1;
626       op_info->AddSymbol.Name = name;
627       // For i386 extern relocation entries the value in the instruction is
628       // the offset from the symbol, and value is already set in op_info->Value.
629       return 1;
630     }
631     if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
632                         r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
633       const char *add = GuessSymbolName(r_value, info);
634       const char *sub = GuessSymbolName(pair_r_value, info);
635       uint32_t offset = value - (r_value - pair_r_value);
636       op_info->AddSymbol.Present = 1;
637       if (add != nullptr)
638         op_info->AddSymbol.Name = add;
639       else
640         op_info->AddSymbol.Value = r_value;
641       op_info->SubtractSymbol.Present = 1;
642       if (sub != nullptr)
643         op_info->SubtractSymbol.Name = sub;
644       else
645         op_info->SubtractSymbol.Value = pair_r_value;
646       op_info->Value = offset;
647       return 1;
648     }
649     // TODO:
650     // Second search the external relocation entries of a fully linked image
651     // (if any) for an entry that matches this segment offset.
652     // uint32_t seg_offset = (Pc + Offset);
653     return 0;
654   } else if (Arch == Triple::x86_64) {
655     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
656       return 0;
657     // First search the section's relocation entries (if any) for an entry
658     // for this section offset.
659     uint64_t sect_addr = info->S.getAddress();
660     uint64_t sect_offset = (Pc + Offset) - sect_addr;
661     bool reloc_found = false;
662     DataRefImpl Rel;
663     MachO::any_relocation_info RE;
664     bool isExtern = false;
665     SymbolRef Symbol;
666     for (const RelocationRef &Reloc : info->S.relocations()) {
667       uint64_t RelocOffset;
668       Reloc.getOffset(RelocOffset);
669       if (RelocOffset == sect_offset) {
670         Rel = Reloc.getRawDataRefImpl();
671         RE = info->O->getRelocation(Rel);
672         // NOTE: Scattered relocations don't exist on x86_64.
673         isExtern = info->O->getPlainRelocationExternal(RE);
674         if (isExtern) {
675           symbol_iterator RelocSym = Reloc.getSymbol();
676           Symbol = *RelocSym;
677         }
678         reloc_found = true;
679         break;
680       }
681     }
682     if (reloc_found && isExtern) {
683       // The Value passed in will be adjusted by the Pc if the instruction
684       // adds the Pc.  But for x86_64 external relocation entries the Value
685       // is the offset from the external symbol.
686       if (info->O->getAnyRelocationPCRel(RE))
687         op_info->Value -= Pc + Offset + Size;
688       StringRef SymName;
689       Symbol.getName(SymName);
690       const char *name = SymName.data();
691       unsigned Type = info->O->getAnyRelocationType(RE);
692       if (Type == MachO::X86_64_RELOC_SUBTRACTOR) {
693         DataRefImpl RelNext = Rel;
694         info->O->moveRelocationNext(RelNext);
695         MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
696         unsigned TypeNext = info->O->getAnyRelocationType(RENext);
697         bool isExternNext = info->O->getPlainRelocationExternal(RENext);
698         unsigned SymbolNum = info->O->getPlainRelocationSymbolNum(RENext);
699         if (TypeNext == MachO::X86_64_RELOC_UNSIGNED && isExternNext) {
700           op_info->SubtractSymbol.Present = 1;
701           op_info->SubtractSymbol.Name = name;
702           symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum);
703           Symbol = *RelocSymNext;
704           StringRef SymNameNext;
705           Symbol.getName(SymNameNext);
706           name = SymNameNext.data();
707         }
708       }
709       // TODO: add the VariantKinds to op_info->VariantKind for relocation types
710       // like: X86_64_RELOC_TLV, X86_64_RELOC_GOT_LOAD and X86_64_RELOC_GOT.
711       op_info->AddSymbol.Present = 1;
712       op_info->AddSymbol.Name = name;
713       return 1;
714     }
715     // TODO:
716     // Second search the external relocation entries of a fully linked image
717     // (if any) for an entry that matches this segment offset.
718     // uint64_t seg_offset = (Pc + Offset);
719     return 0;
720   } else if (Arch == Triple::arm) {
721     if (Offset != 0 || (Size != 4 && Size != 2))
722       return 0;
723     // First search the section's relocation entries (if any) for an entry
724     // for this section offset.
725     uint32_t sect_addr = info->S.getAddress();
726     uint32_t sect_offset = (Pc + Offset) - sect_addr;
727     bool reloc_found = false;
728     DataRefImpl Rel;
729     MachO::any_relocation_info RE;
730     bool isExtern = false;
731     SymbolRef Symbol;
732     bool r_scattered = false;
733     uint32_t r_value, pair_r_value, r_type, r_length, other_half;
734     for (const RelocationRef &Reloc : info->S.relocations()) {
735       uint64_t RelocOffset;
736       Reloc.getOffset(RelocOffset);
737       if (RelocOffset == sect_offset) {
738         Rel = Reloc.getRawDataRefImpl();
739         RE = info->O->getRelocation(Rel);
740         r_length = info->O->getAnyRelocationLength(RE);
741         r_scattered = info->O->isRelocationScattered(RE);
742         if (r_scattered) {
743           r_value = info->O->getScatteredRelocationValue(RE);
744           r_type = info->O->getScatteredRelocationType(RE);
745         } else {
746           r_type = info->O->getAnyRelocationType(RE);
747           isExtern = info->O->getPlainRelocationExternal(RE);
748           if (isExtern) {
749             symbol_iterator RelocSym = Reloc.getSymbol();
750             Symbol = *RelocSym;
751           }
752         }
753         if (r_type == MachO::ARM_RELOC_HALF ||
754             r_type == MachO::ARM_RELOC_SECTDIFF ||
755             r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
756             r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
757           DataRefImpl RelNext = Rel;
758           info->O->moveRelocationNext(RelNext);
759           MachO::any_relocation_info RENext;
760           RENext = info->O->getRelocation(RelNext);
761           other_half = info->O->getAnyRelocationAddress(RENext) & 0xffff;
762           if (info->O->isRelocationScattered(RENext))
763             pair_r_value = info->O->getScatteredRelocationValue(RENext);
764         }
765         reloc_found = true;
766         break;
767       }
768     }
769     if (reloc_found && isExtern) {
770       StringRef SymName;
771       Symbol.getName(SymName);
772       const char *name = SymName.data();
773       op_info->AddSymbol.Present = 1;
774       op_info->AddSymbol.Name = name;
775       if (value != 0) {
776         switch (r_type) {
777         case MachO::ARM_RELOC_HALF:
778           if ((r_length & 0x1) == 1) {
779             op_info->Value = value << 16 | other_half;
780             op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
781           } else {
782             op_info->Value = other_half << 16 | value;
783             op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
784           }
785           break;
786         default:
787           break;
788         }
789       } else {
790         switch (r_type) {
791         case MachO::ARM_RELOC_HALF:
792           if ((r_length & 0x1) == 1) {
793             op_info->Value = value << 16 | other_half;
794             op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
795           } else {
796             op_info->Value = other_half << 16 | value;
797             op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
798           }
799           break;
800         default:
801           break;
802         }
803       }
804       return 1;
805     }
806     // If we have a branch that is not an external relocation entry then
807     // return 0 so the code in tryAddingSymbolicOperand() can use the
808     // SymbolLookUp call back with the branch target address to look up the
809     // symbol and possiblity add an annotation for a symbol stub.
810     if (reloc_found && isExtern == 0 && (r_type == MachO::ARM_RELOC_BR24 ||
811                                          r_type == MachO::ARM_THUMB_RELOC_BR22))
812       return 0;
814     uint32_t offset = 0;
815     if (reloc_found) {
816       if (r_type == MachO::ARM_RELOC_HALF ||
817           r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
818         if ((r_length & 0x1) == 1)
819           value = value << 16 | other_half;
820         else
821           value = other_half << 16 | value;
822       }
823       if (r_scattered && (r_type != MachO::ARM_RELOC_HALF &&
824                           r_type != MachO::ARM_RELOC_HALF_SECTDIFF)) {
825         offset = value - r_value;
826         value = r_value;
827       }
828     }
830     if (reloc_found && r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
831       if ((r_length & 0x1) == 1)
832         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
833       else
834         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
835       const char *add = GuessSymbolName(r_value, info);
836       const char *sub = GuessSymbolName(pair_r_value, info);
837       int32_t offset = value - (r_value - pair_r_value);
838       op_info->AddSymbol.Present = 1;
839       if (add != nullptr)
840         op_info->AddSymbol.Name = add;
841       else
842         op_info->AddSymbol.Value = r_value;
843       op_info->SubtractSymbol.Present = 1;
844       if (sub != nullptr)
845         op_info->SubtractSymbol.Name = sub;
846       else
847         op_info->SubtractSymbol.Value = pair_r_value;
848       op_info->Value = offset;
849       return 1;
850     }
852     if (reloc_found == false)
853       return 0;
855     op_info->AddSymbol.Present = 1;
856     op_info->Value = offset;
857     if (reloc_found) {
858       if (r_type == MachO::ARM_RELOC_HALF) {
859         if ((r_length & 0x1) == 1)
860           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
861         else
862           op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
863       }
864     }
865     const char *add = GuessSymbolName(value, info);
866     if (add != nullptr) {
867       op_info->AddSymbol.Name = add;
868       return 1;
869     }
870     op_info->AddSymbol.Value = value;
871     return 1;
872   } else if (Arch == Triple::aarch64) {
873     if (Offset != 0 || Size != 4)
874       return 0;
875     // First search the section's relocation entries (if any) for an entry
876     // for this section offset.
877     uint64_t sect_addr = info->S.getAddress();
878     uint64_t sect_offset = (Pc + Offset) - sect_addr;
879     bool reloc_found = false;
880     DataRefImpl Rel;
881     MachO::any_relocation_info RE;
882     bool isExtern = false;
883     SymbolRef Symbol;
884     uint32_t r_type = 0;
885     for (const RelocationRef &Reloc : info->S.relocations()) {
886       uint64_t RelocOffset;
887       Reloc.getOffset(RelocOffset);
888       if (RelocOffset == sect_offset) {
889         Rel = Reloc.getRawDataRefImpl();
890         RE = info->O->getRelocation(Rel);
891         r_type = info->O->getAnyRelocationType(RE);
892         if (r_type == MachO::ARM64_RELOC_ADDEND) {
893           DataRefImpl RelNext = Rel;
894           info->O->moveRelocationNext(RelNext);
895           MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
896           if (value == 0) {
897             value = info->O->getPlainRelocationSymbolNum(RENext);
898             op_info->Value = value;
899           }
900         }
901         // NOTE: Scattered relocations don't exist on arm64.
902         isExtern = info->O->getPlainRelocationExternal(RE);
903         if (isExtern) {
904           symbol_iterator RelocSym = Reloc.getSymbol();
905           Symbol = *RelocSym;
906         }
907         reloc_found = true;
908         break;
909       }
910     }
911     if (reloc_found && isExtern) {
912       StringRef SymName;
913       Symbol.getName(SymName);
914       const char *name = SymName.data();
915       op_info->AddSymbol.Present = 1;
916       op_info->AddSymbol.Name = name;
918       switch (r_type) {
919       case MachO::ARM64_RELOC_PAGE21:
920         /* @page */
921         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGE;
922         break;
923       case MachO::ARM64_RELOC_PAGEOFF12:
924         /* @pageoff */
925         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGEOFF;
926         break;
927       case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
928         /* @gotpage */
929         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGE;
930         break;
931       case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
932         /* @gotpageoff */
933         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF;
934         break;
935       case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
936         /* @tvlppage is not implemented in llvm-mc */
937         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVP;
938         break;
939       case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
940         /* @tvlppageoff is not implemented in llvm-mc */
941         op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVOFF;
942         break;
943       default:
944       case MachO::ARM64_RELOC_BRANCH26:
945         op_info->VariantKind = LLVMDisassembler_VariantKind_None;
946         break;
947       }
948       return 1;
949     }
950     return 0;
951   } else {
952     return 0;
953   }
956 // GuessCstringPointer is passed the address of what might be a pointer to a
957 // literal string in a cstring section.  If that address is in a cstring section
958 // it returns a pointer to that string.  Else it returns nullptr.
959 const char *GuessCstringPointer(uint64_t ReferenceValue,
960                                 struct DisassembleInfo *info) {
961   uint32_t LoadCommandCount = info->O->getHeader().ncmds;
962   MachOObjectFile::LoadCommandInfo Load = info->O->getFirstLoadCommandInfo();
963   for (unsigned I = 0;; ++I) {
964     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
965       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
966       for (unsigned J = 0; J < Seg.nsects; ++J) {
967         MachO::section_64 Sec = info->O->getSection64(Load, J);
968         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
969         if (section_type == MachO::S_CSTRING_LITERALS &&
970             ReferenceValue >= Sec.addr &&
971             ReferenceValue < Sec.addr + Sec.size) {
972           uint64_t sect_offset = ReferenceValue - Sec.addr;
973           uint64_t object_offset = Sec.offset + sect_offset;
974           StringRef MachOContents = info->O->getData();
975           uint64_t object_size = MachOContents.size();
976           const char *object_addr = (const char *)MachOContents.data();
977           if (object_offset < object_size) {
978             const char *name = object_addr + object_offset;
979             return name;
980           } else {
981             return nullptr;
982           }
983         }
984       }
985     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
986       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
987       for (unsigned J = 0; J < Seg.nsects; ++J) {
988         MachO::section Sec = info->O->getSection(Load, J);
989         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
990         if (section_type == MachO::S_CSTRING_LITERALS &&
991             ReferenceValue >= Sec.addr &&
992             ReferenceValue < Sec.addr + Sec.size) {
993           uint64_t sect_offset = ReferenceValue - Sec.addr;
994           uint64_t object_offset = Sec.offset + sect_offset;
995           StringRef MachOContents = info->O->getData();
996           uint64_t object_size = MachOContents.size();
997           const char *object_addr = (const char *)MachOContents.data();
998           if (object_offset < object_size) {
999             const char *name = object_addr + object_offset;
1000             return name;
1001           } else {
1002             return nullptr;
1003           }
1004         }
1005       }
1006     }
1007     if (I == LoadCommandCount - 1)
1008       break;
1009     else
1010       Load = info->O->getNextLoadCommandInfo(Load);
1011   }
1012   return nullptr;
1015 // GuessIndirectSymbol returns the name of the indirect symbol for the
1016 // ReferenceValue passed in or nullptr.  This is used when ReferenceValue maybe
1017 // an address of a symbol stub or a lazy or non-lazy pointer to associate the
1018 // symbol name being referenced by the stub or pointer.
1019 static const char *GuessIndirectSymbol(uint64_t ReferenceValue,
1020                                        struct DisassembleInfo *info) {
1021   uint32_t LoadCommandCount = info->O->getHeader().ncmds;
1022   MachOObjectFile::LoadCommandInfo Load = info->O->getFirstLoadCommandInfo();
1023   MachO::dysymtab_command Dysymtab = info->O->getDysymtabLoadCommand();
1024   MachO::symtab_command Symtab = info->O->getSymtabLoadCommand();
1025   for (unsigned I = 0;; ++I) {
1026     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1027       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
1028       for (unsigned J = 0; J < Seg.nsects; ++J) {
1029         MachO::section_64 Sec = info->O->getSection64(Load, J);
1030         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
1031         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
1032              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
1033              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
1034              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
1035              section_type == MachO::S_SYMBOL_STUBS) &&
1036             ReferenceValue >= Sec.addr &&
1037             ReferenceValue < Sec.addr + Sec.size) {
1038           uint32_t stride;
1039           if (section_type == MachO::S_SYMBOL_STUBS)
1040             stride = Sec.reserved2;
1041           else
1042             stride = 8;
1043           if (stride == 0)
1044             return nullptr;
1045           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
1046           if (index < Dysymtab.nindirectsyms) {
1047             uint32_t indirect_symbol =
1048                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
1049             if (indirect_symbol < Symtab.nsyms) {
1050               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
1051               SymbolRef Symbol = *Sym;
1052               StringRef SymName;
1053               Symbol.getName(SymName);
1054               const char *name = SymName.data();
1055               return name;
1056             }
1057           }
1058         }
1059       }
1060     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1061       MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
1062       for (unsigned J = 0; J < Seg.nsects; ++J) {
1063         MachO::section Sec = info->O->getSection(Load, J);
1064         uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
1065         if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
1066              section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
1067              section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
1068              section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
1069              section_type == MachO::S_SYMBOL_STUBS) &&
1070             ReferenceValue >= Sec.addr &&
1071             ReferenceValue < Sec.addr + Sec.size) {
1072           uint32_t stride;
1073           if (section_type == MachO::S_SYMBOL_STUBS)
1074             stride = Sec.reserved2;
1075           else
1076             stride = 4;
1077           if (stride == 0)
1078             return nullptr;
1079           uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
1080           if (index < Dysymtab.nindirectsyms) {
1081             uint32_t indirect_symbol =
1082                 info->O->getIndirectSymbolTableEntry(Dysymtab, index);
1083             if (indirect_symbol < Symtab.nsyms) {
1084               symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
1085               SymbolRef Symbol = *Sym;
1086               StringRef SymName;
1087               Symbol.getName(SymName);
1088               const char *name = SymName.data();
1089               return name;
1090             }
1091           }
1092         }
1093       }
1094     }
1095     if (I == LoadCommandCount - 1)
1096       break;
1097     else
1098       Load = info->O->getNextLoadCommandInfo(Load);
1099   }
1100   return nullptr;
1103 // method_reference() is called passing it the ReferenceName that might be
1104 // a reference it to an Objective-C method call.  If so then it allocates and
1105 // assembles a method call string with the values last seen and saved in
1106 // the DisassembleInfo's class_name and selector_name fields.  This is saved
1107 // into the method field of the info and any previous string is free'ed.
1108 // Then the class_name field in the info is set to nullptr.  The method call
1109 // string is set into ReferenceName and ReferenceType is set to
1110 // LLVMDisassembler_ReferenceType_Out_Objc_Message.  If this not a method call
1111 // then both ReferenceType and ReferenceName are left unchanged.
1112 static void method_reference(struct DisassembleInfo *info,
1113                              uint64_t *ReferenceType,
1114                              const char **ReferenceName) {
1115   unsigned int Arch = info->O->getArch();
1116   if (*ReferenceName != nullptr) {
1117     if (strcmp(*ReferenceName, "_objc_msgSend") == 0) {
1118       if (info->selector_name != nullptr) {
1119         if (info->method != nullptr)
1120           free(info->method);
1121         if (info->class_name != nullptr) {
1122           info->method = (char *)malloc(5 + strlen(info->class_name) +
1123                                         strlen(info->selector_name));
1124           if (info->method != nullptr) {
1125             strcpy(info->method, "+[");
1126             strcat(info->method, info->class_name);
1127             strcat(info->method, " ");
1128             strcat(info->method, info->selector_name);
1129             strcat(info->method, "]");
1130             *ReferenceName = info->method;
1131             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
1132           }
1133         } else {
1134           info->method = (char *)malloc(9 + strlen(info->selector_name));
1135           if (info->method != nullptr) {
1136             if (Arch == Triple::x86_64)
1137               strcpy(info->method, "-[%rdi ");
1138             else if (Arch == Triple::aarch64)
1139               strcpy(info->method, "-[x0 ");
1140             else
1141               strcpy(info->method, "-[r? ");
1142             strcat(info->method, info->selector_name);
1143             strcat(info->method, "]");
1144             *ReferenceName = info->method;
1145             *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
1146           }
1147         }
1148         info->class_name = nullptr;
1149       }
1150     } else if (strcmp(*ReferenceName, "_objc_msgSendSuper2") == 0) {
1151       if (info->selector_name != nullptr) {
1152         if (info->method != nullptr)
1153           free(info->method);
1154         info->method = (char *)malloc(17 + strlen(info->selector_name));
1155         if (info->method != nullptr) {
1156           if (Arch == Triple::x86_64)
1157             strcpy(info->method, "-[[%rdi super] ");
1158           else if (Arch == Triple::aarch64)
1159             strcpy(info->method, "-[[x0 super] ");
1160           else
1161             strcpy(info->method, "-[[r? super] ");
1162           strcat(info->method, info->selector_name);
1163           strcat(info->method, "]");
1164           *ReferenceName = info->method;
1165           *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
1166         }
1167         info->class_name = nullptr;
1168       }
1169     }
1170   }
1173 // GuessPointerPointer() is passed the address of what might be a pointer to
1174 // a reference to an Objective-C class, selector, message ref or cfstring.
1175 // If so the value of the pointer is returned and one of the booleans are set
1176 // to true.  If not zero is returned and all the booleans are set to false.
1177 static uint64_t GuessPointerPointer(uint64_t ReferenceValue,
1178                                     struct DisassembleInfo *info,
1179                                     bool &classref, bool &selref, bool &msgref,
1180                                     bool &cfstring) {
1181   classref = false;
1182   selref = false;
1183   msgref = false;
1184   cfstring = false;
1185   uint32_t LoadCommandCount = info->O->getHeader().ncmds;
1186   MachOObjectFile::LoadCommandInfo Load = info->O->getFirstLoadCommandInfo();
1187   for (unsigned I = 0;; ++I) {
1188     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1189       MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
1190       for (unsigned J = 0; J < Seg.nsects; ++J) {
1191         MachO::section_64 Sec = info->O->getSection64(Load, J);
1192         if ((strncmp(Sec.sectname, "__objc_selrefs", 16) == 0 ||
1193              strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
1194              strncmp(Sec.sectname, "__objc_superrefs", 16) == 0 ||
1195              strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 ||
1196              strncmp(Sec.sectname, "__cfstring", 16) == 0) &&
1197             ReferenceValue >= Sec.addr &&
1198             ReferenceValue < Sec.addr + Sec.size) {
1199           uint64_t sect_offset = ReferenceValue - Sec.addr;
1200           uint64_t object_offset = Sec.offset + sect_offset;
1201           StringRef MachOContents = info->O->getData();
1202           uint64_t object_size = MachOContents.size();
1203           const char *object_addr = (const char *)MachOContents.data();
1204           if (object_offset < object_size) {
1205             uint64_t pointer_value;
1206             memcpy(&pointer_value, object_addr + object_offset,
1207                    sizeof(uint64_t));
1208             if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
1209               sys::swapByteOrder(pointer_value);
1210             if (strncmp(Sec.sectname, "__objc_selrefs", 16) == 0)
1211               selref = true;
1212             else if (strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
1213                      strncmp(Sec.sectname, "__objc_superrefs", 16) == 0)
1214               classref = true;
1215             else if (strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 &&
1216                      ReferenceValue + 8 < Sec.addr + Sec.size) {
1217               msgref = true;
1218               memcpy(&pointer_value, object_addr + object_offset + 8,
1219                      sizeof(uint64_t));
1220               if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
1221                 sys::swapByteOrder(pointer_value);
1222             } else if (strncmp(Sec.sectname, "__cfstring", 16) == 0)
1223               cfstring = true;
1224             return pointer_value;
1225           } else {
1226             return 0;
1227           }
1228         }
1229       }
1230     }
1231     // TODO: Look for LC_SEGMENT for 32-bit Mach-O files.
1232     if (I == LoadCommandCount - 1)
1233       break;
1234     else
1235       Load = info->O->getNextLoadCommandInfo(Load);
1236   }
1237   return 0;
1240 // get_pointer_64 returns a pointer to the bytes in the object file at the
1241 // Address from a section in the Mach-O file.  And indirectly returns the
1242 // offset into the section, number of bytes left in the section past the offset
1243 // and which section is was being referenced.  If the Address is not in a
1244 // section nullptr is returned.
1245 const char *get_pointer_64(uint64_t Address, uint32_t &offset, uint32_t &left,
1246                            SectionRef &S, DisassembleInfo *info) {
1247   offset = 0;
1248   left = 0;
1249   S = SectionRef();
1250   for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) {
1251     uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress();
1252     uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize();
1253     if (Address >= SectAddress && Address < SectAddress + SectSize) {
1254       S = (*(info->Sections))[SectIdx];
1255       offset = Address - SectAddress;
1256       left = SectSize - offset;
1257       StringRef SectContents;
1258       ((*(info->Sections))[SectIdx]).getContents(SectContents);
1259       return SectContents.data() + offset;
1260     }
1261   }
1262   return nullptr;
1265 // get_symbol_64() returns the name of a symbol (or nullptr) and the address of
1266 // the symbol indirectly through n_value. Based on the relocation information
1267 // for the specified section offset in the specified section reference.
1268 const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
1269                           DisassembleInfo *info, uint64_t &n_value) {
1270   n_value = 0;
1271   if (info->verbose == false)
1272     return nullptr;
1274   // See if there is an external relocation entry at the sect_offset.
1275   bool reloc_found = false;
1276   DataRefImpl Rel;
1277   MachO::any_relocation_info RE;
1278   bool isExtern = false;
1279   SymbolRef Symbol;
1280   for (const RelocationRef &Reloc : S.relocations()) {
1281     uint64_t RelocOffset;
1282     Reloc.getOffset(RelocOffset);
1283     if (RelocOffset == sect_offset) {
1284       Rel = Reloc.getRawDataRefImpl();
1285       RE = info->O->getRelocation(Rel);
1286       if (info->O->isRelocationScattered(RE))
1287         continue;
1288       isExtern = info->O->getPlainRelocationExternal(RE);
1289       if (isExtern) {
1290         symbol_iterator RelocSym = Reloc.getSymbol();
1291         Symbol = *RelocSym;
1292       }
1293       reloc_found = true;
1294       break;
1295     }
1296   }
1297   // If there is an external relocation entry for a symbol in this section
1298   // at this section_offset then use that symbol's value for the n_value
1299   // and return its name.
1300   const char *SymbolName = nullptr;
1301   if (reloc_found && isExtern) {
1302     Symbol.getAddress(n_value);
1303     StringRef name;
1304     Symbol.getName(name);
1305     if (!name.empty()) {
1306       SymbolName = name.data();
1307       return SymbolName;
1308     }
1309   }
1311   // TODO: For fully linked images, look through the external relocation
1312   // entries off the dynamic symtab command. For these the r_offset is from the
1313   // start of the first writeable segment in the Mach-O file.  So the offset
1314   // to this section from that segment is passed to this routine by the caller,
1315   // as the database_offset. Which is the difference of the section's starting
1316   // address and the first writable segment.
1317   //
1318   // NOTE: need add passing the database_offset to this routine.
1320   // TODO: We did not find an external relocation entry so look up the
1321   // ReferenceValue as an address of a symbol and if found return that symbol's
1322   // name.
1323   //
1324   // NOTE: need add passing the ReferenceValue to this routine.  Then that code
1325   // would simply be this:
1326   // SymbolName = GuessSymbolName(ReferenceValue, info);
1328   return SymbolName;
1331 // These are structs in the Objective-C meta data and read to produce the
1332 // comments for disassembly.  While these are part of the ABI they are no
1333 // public defintions.  So the are here not in include/llvm/Support/MachO.h .
1335 // The cfstring object in a 64-bit Mach-O file.
1336 struct cfstring64_t {
1337   uint64_t isa;        // class64_t * (64-bit pointer)
1338   uint64_t flags;      // flag bits
1339   uint64_t characters; // char * (64-bit pointer)
1340   uint64_t length;     // number of non-NULL characters in above
1341 };
1343 // The class object in a 64-bit Mach-O file.
1344 struct class64_t {
1345   uint64_t isa;        // class64_t * (64-bit pointer)
1346   uint64_t superclass; // class64_t * (64-bit pointer)
1347   uint64_t cache;      // Cache (64-bit pointer)
1348   uint64_t vtable;     // IMP * (64-bit pointer)
1349   uint64_t data;       // class_ro64_t * (64-bit pointer)
1350 };
1352 struct class_ro64_t {
1353   uint32_t flags;
1354   uint32_t instanceStart;
1355   uint32_t instanceSize;
1356   uint32_t reserved;
1357   uint64_t ivarLayout;     // const uint8_t * (64-bit pointer)
1358   uint64_t name;           // const char * (64-bit pointer)
1359   uint64_t baseMethods;    // const method_list_t * (64-bit pointer)
1360   uint64_t baseProtocols;  // const protocol_list_t * (64-bit pointer)
1361   uint64_t ivars;          // const ivar_list_t * (64-bit pointer)
1362   uint64_t weakIvarLayout; // const uint8_t * (64-bit pointer)
1363   uint64_t baseProperties; // const struct objc_property_list (64-bit pointer)
1364 };
1366 inline void swapStruct(struct cfstring64_t &cfs) {
1367   sys::swapByteOrder(cfs.isa);
1368   sys::swapByteOrder(cfs.flags);
1369   sys::swapByteOrder(cfs.characters);
1370   sys::swapByteOrder(cfs.length);
1373 inline void swapStruct(struct class64_t &c) {
1374   sys::swapByteOrder(c.isa);
1375   sys::swapByteOrder(c.superclass);
1376   sys::swapByteOrder(c.cache);
1377   sys::swapByteOrder(c.vtable);
1378   sys::swapByteOrder(c.data);
1381 inline void swapStruct(struct class_ro64_t &cro) {
1382   sys::swapByteOrder(cro.flags);
1383   sys::swapByteOrder(cro.instanceStart);
1384   sys::swapByteOrder(cro.instanceSize);
1385   sys::swapByteOrder(cro.reserved);
1386   sys::swapByteOrder(cro.ivarLayout);
1387   sys::swapByteOrder(cro.name);
1388   sys::swapByteOrder(cro.baseMethods);
1389   sys::swapByteOrder(cro.baseProtocols);
1390   sys::swapByteOrder(cro.ivars);
1391   sys::swapByteOrder(cro.weakIvarLayout);
1392   sys::swapByteOrder(cro.baseProperties);
1395 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
1396                                                  struct DisassembleInfo *info);
1398 // get_objc2_64bit_class_name() is used for disassembly and is passed a pointer
1399 // to an Objective-C class and returns the class name.  It is also passed the
1400 // address of the pointer, so when the pointer is zero as it can be in an .o
1401 // file, that is used to look for an external relocation entry with a symbol
1402 // name.
1403 const char *get_objc2_64bit_class_name(uint64_t pointer_value,
1404                                        uint64_t ReferenceValue,
1405                                        struct DisassembleInfo *info) {
1406   const char *r;
1407   uint32_t offset, left;
1408   SectionRef S;
1410   // The pointer_value can be 0 in an object file and have a relocation
1411   // entry for the class symbol at the ReferenceValue (the address of the
1412   // pointer).
1413   if (pointer_value == 0) {
1414     r = get_pointer_64(ReferenceValue, offset, left, S, info);
1415     if (r == nullptr || left < sizeof(uint64_t))
1416       return nullptr;
1417     uint64_t n_value;
1418     const char *symbol_name = get_symbol_64(offset, S, info, n_value);
1419     if (symbol_name == nullptr)
1420       return nullptr;
1421     const char *class_name = strrchr(symbol_name, '$');
1422     if (class_name != nullptr && class_name[1] == '_' && class_name[2] != '\0')
1423       return class_name + 2;
1424     else
1425       return nullptr;
1426   }
1428   // The case were the pointer_value is non-zero and points to a class defined
1429   // in this Mach-O file.
1430   r = get_pointer_64(pointer_value, offset, left, S, info);
1431   if (r == nullptr || left < sizeof(struct class64_t))
1432     return nullptr;
1433   struct class64_t c;
1434   memcpy(&c, r, sizeof(struct class64_t));
1435   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
1436     swapStruct(c);
1437   if (c.data == 0)
1438     return nullptr;
1439   r = get_pointer_64(c.data, offset, left, S, info);
1440   if (r == nullptr || left < sizeof(struct class_ro64_t))
1441     return nullptr;
1442   struct class_ro64_t cro;
1443   memcpy(&cro, r, sizeof(struct class_ro64_t));
1444   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
1445     swapStruct(cro);
1446   if (cro.name == 0)
1447     return nullptr;
1448   const char *name = get_pointer_64(cro.name, offset, left, S, info);
1449   return name;
1452 // get_objc2_64bit_cfstring_name is used for disassembly and is passed a
1453 // pointer to a cfstring and returns its name or nullptr.
1454 const char *get_objc2_64bit_cfstring_name(uint64_t ReferenceValue,
1455                                           struct DisassembleInfo *info) {
1456   const char *r, *name;
1457   uint32_t offset, left;
1458   SectionRef S;
1459   struct cfstring64_t cfs;
1460   uint64_t cfs_characters;
1462   r = get_pointer_64(ReferenceValue, offset, left, S, info);
1463   if (r == nullptr || left < sizeof(struct cfstring64_t))
1464     return nullptr;
1465   memcpy(&cfs, r, sizeof(struct cfstring64_t));
1466   if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
1467     swapStruct(cfs);
1468   if (cfs.characters == 0) {
1469     uint64_t n_value;
1470     const char *symbol_name = get_symbol_64(
1471         offset + offsetof(struct cfstring64_t, characters), S, info, n_value);
1472     if (symbol_name == nullptr)
1473       return nullptr;
1474     cfs_characters = n_value;
1475   } else
1476     cfs_characters = cfs.characters;
1477   name = get_pointer_64(cfs_characters, offset, left, S, info);
1479   return name;
1482 // get_objc2_64bit_selref() is used for disassembly and is passed a the address
1483 // of a pointer to an Objective-C selector reference when the pointer value is
1484 // zero as in a .o file and is likely to have a external relocation entry with
1485 // who's symbol's n_value is the real pointer to the selector name.  If that is
1486 // the case the real pointer to the selector name is returned else 0 is
1487 // returned
1488 uint64_t get_objc2_64bit_selref(uint64_t ReferenceValue,
1489                                 struct DisassembleInfo *info) {
1490   uint32_t offset, left;
1491   SectionRef S;
1493   const char *r = get_pointer_64(ReferenceValue, offset, left, S, info);
1494   if (r == nullptr || left < sizeof(uint64_t))
1495     return 0;
1496   uint64_t n_value;
1497   const char *symbol_name = get_symbol_64(offset, S, info, n_value);
1498   if (symbol_name == nullptr)
1499     return 0;
1500   return n_value;
1503 // GuessLiteralPointer returns a string which for the item in the Mach-O file
1504 // for the address passed in as ReferenceValue for printing as a comment with
1505 // the instruction and also returns the corresponding type of that item
1506 // indirectly through ReferenceType.
1507 //
1508 // If ReferenceValue is an address of literal cstring then a pointer to the
1509 // cstring is returned and ReferenceType is set to
1510 // LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr .
1511 //
1512 // If ReferenceValue is an address of an Objective-C CFString, Selector ref or
1513 // Class ref that name is returned and the ReferenceType is set accordingly.
1514 //
1515 // Lastly, literals which are Symbol address in a literal pool are looked for
1516 // and if found the symbol name is returned and ReferenceType is set to
1517 // LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr .
1518 //
1519 // If there is no item in the Mach-O file for the address passed in as
1520 // ReferenceValue nullptr is returned and ReferenceType is unchanged.
1521 const char *GuessLiteralPointer(uint64_t ReferenceValue, uint64_t ReferencePC,
1522                                 uint64_t *ReferenceType,
1523                                 struct DisassembleInfo *info) {
1524   // First see if there is an external relocation entry at the ReferencePC.
1525   uint64_t sect_addr = info->S.getAddress();
1526   uint64_t sect_offset = ReferencePC - sect_addr;
1527   bool reloc_found = false;
1528   DataRefImpl Rel;
1529   MachO::any_relocation_info RE;
1530   bool isExtern = false;
1531   SymbolRef Symbol;
1532   for (const RelocationRef &Reloc : info->S.relocations()) {
1533     uint64_t RelocOffset;
1534     Reloc.getOffset(RelocOffset);
1535     if (RelocOffset == sect_offset) {
1536       Rel = Reloc.getRawDataRefImpl();
1537       RE = info->O->getRelocation(Rel);
1538       if (info->O->isRelocationScattered(RE))
1539         continue;
1540       isExtern = info->O->getPlainRelocationExternal(RE);
1541       if (isExtern) {
1542         symbol_iterator RelocSym = Reloc.getSymbol();
1543         Symbol = *RelocSym;
1544       }
1545       reloc_found = true;
1546       break;
1547     }
1548   }
1549   // If there is an external relocation entry for a symbol in a section
1550   // then used that symbol's value for the value of the reference.
1551   if (reloc_found && isExtern) {
1552     if (info->O->getAnyRelocationPCRel(RE)) {
1553       unsigned Type = info->O->getAnyRelocationType(RE);
1554       if (Type == MachO::X86_64_RELOC_SIGNED) {
1555         Symbol.getAddress(ReferenceValue);
1556       }
1557     }
1558   }
1560   // Look for literals such as Objective-C CFStrings refs, Selector refs,
1561   // Message refs and Class refs.
1562   bool classref, selref, msgref, cfstring;
1563   uint64_t pointer_value = GuessPointerPointer(ReferenceValue, info, classref,
1564                                                selref, msgref, cfstring);
1565   if (classref == true && pointer_value == 0) {
1566     // Note the ReferenceValue is a pointer into the __objc_classrefs section.
1567     // And the pointer_value in that section is typically zero as it will be
1568     // set by dyld as part of the "bind information".
1569     const char *name = get_dyld_bind_info_symbolname(ReferenceValue, info);
1570     if (name != nullptr) {
1571       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
1572       const char *class_name = strrchr(name, '$');
1573       if (class_name != nullptr && class_name[1] == '_' &&
1574           class_name[2] != '\0') {
1575         info->class_name = class_name + 2;
1576         return name;
1577       }
1578     }
1579   }
1581   if (classref == true) {
1582     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
1583     const char *name =
1584         get_objc2_64bit_class_name(pointer_value, ReferenceValue, info);
1585     if (name != nullptr)
1586       info->class_name = name;
1587     else
1588       name = "bad class ref";
1589     return name;
1590   }
1592   if (cfstring == true) {
1593     *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref;
1594     const char *name = get_objc2_64bit_cfstring_name(ReferenceValue, info);
1595     return name;
1596   }
1598   if (selref == true && pointer_value == 0)
1599     pointer_value = get_objc2_64bit_selref(ReferenceValue, info);
1601   if (pointer_value != 0)
1602     ReferenceValue = pointer_value;
1604   const char *name = GuessCstringPointer(ReferenceValue, info);
1605   if (name) {
1606     if (pointer_value != 0 && selref == true) {
1607       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref;
1608       info->selector_name = name;
1609     } else if (pointer_value != 0 && msgref == true) {
1610       info->class_name = nullptr;
1611       *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref;
1612       info->selector_name = name;
1613     } else
1614       *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr;
1615     return name;
1616   }
1618   // Lastly look for an indirect symbol with this ReferenceValue which is in
1619   // a literal pool.  If found return that symbol name.
1620   name = GuessIndirectSymbol(ReferenceValue, info);
1621   if (name) {
1622     *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr;
1623     return name;
1624   }
1626   return nullptr;
1629 // SymbolizerSymbolLookUp is the symbol lookup function passed when creating
1630 // the Symbolizer.  It looks up the ReferenceValue using the info passed via the
1631 // pointer to the struct DisassembleInfo that was passed when MCSymbolizer
1632 // is created and returns the symbol name that matches the ReferenceValue or
1633 // nullptr if none.  The ReferenceType is passed in for the IN type of
1634 // reference the instruction is making from the values in defined in the header
1635 // "llvm-c/Disassembler.h".  On return the ReferenceType can set to a specific
1636 // Out type and the ReferenceName will also be set which is added as a comment
1637 // to the disassembled instruction.
1638 //
1639 #if HAVE_CXXABI_H
1640 // If the symbol name is a C++ mangled name then the demangled name is
1641 // returned through ReferenceName and ReferenceType is set to
1642 // LLVMDisassembler_ReferenceType_DeMangled_Name .
1643 #endif
1644 //
1645 // When this is called to get a symbol name for a branch target then the
1646 // ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then
1647 // SymbolValue will be looked for in the indirect symbol table to determine if
1648 // it is an address for a symbol stub.  If so then the symbol name for that
1649 // stub is returned indirectly through ReferenceName and then ReferenceType is
1650 // set to LLVMDisassembler_ReferenceType_Out_SymbolStub.
1651 //
1652 // When this is called with an value loaded via a PC relative load then
1653 // ReferenceType will be LLVMDisassembler_ReferenceType_In_PCrel_Load then the
1654 // SymbolValue is checked to be an address of literal pointer, symbol pointer,
1655 // or an Objective-C meta data reference.  If so the output ReferenceType is
1656 // set to correspond to that as well as setting the ReferenceName.
1657 const char *SymbolizerSymbolLookUp(void *DisInfo, uint64_t ReferenceValue,
1658                                    uint64_t *ReferenceType,
1659                                    uint64_t ReferencePC,
1660                                    const char **ReferenceName) {
1661   struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
1662   // If no verbose symbolic information is wanted then just return nullptr.
1663   if (info->verbose == false) {
1664     *ReferenceName = nullptr;
1665     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
1666     return nullptr;
1667   }
1669   const char *SymbolName = GuessSymbolName(ReferenceValue, info);
1671   if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
1672     *ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
1673     if (*ReferenceName != nullptr) {
1674       method_reference(info, ReferenceType, ReferenceName);
1675       if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message)
1676         *ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
1677     } else
1678 #if HAVE_CXXABI_H
1679         if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
1680       if (info->demangled_name != nullptr)
1681         free(info->demangled_name);
1682       int status;
1683       info->demangled_name =
1684           abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status);
1685       if (info->demangled_name != nullptr) {
1686         *ReferenceName = info->demangled_name;
1687         *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
1688       } else
1689         *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
1690     } else
1691 #endif
1692       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
1693   } else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
1694     *ReferenceName =
1695         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
1696     if (*ReferenceName)
1697       method_reference(info, ReferenceType, ReferenceName);
1698     else
1699       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
1700     // If this is arm64 and the reference is an adrp instruction save the
1701     // instruction, passed in ReferenceValue and the address of the instruction
1702     // for use later if we see and add immediate instruction.
1703   } else if (info->O->getArch() == Triple::aarch64 &&
1704              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
1705     info->adrp_inst = ReferenceValue;
1706     info->adrp_addr = ReferencePC;
1707     SymbolName = nullptr;
1708     *ReferenceName = nullptr;
1709     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
1710     // If this is arm64 and reference is an add immediate instruction and we
1711     // have
1712     // seen an adrp instruction just before it and the adrp's Xd register
1713     // matches
1714     // this add's Xn register reconstruct the value being referenced and look to
1715     // see if it is a literal pointer.  Note the add immediate instruction is
1716     // passed in ReferenceValue.
1717   } else if (info->O->getArch() == Triple::aarch64 &&
1718              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
1719              ReferencePC - 4 == info->adrp_addr &&
1720              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
1721              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
1722     uint32_t addxri_inst;
1723     uint64_t adrp_imm, addxri_imm;
1725     adrp_imm =
1726         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
1727     if (info->adrp_inst & 0x0200000)
1728       adrp_imm |= 0xfffffffffc000000LL;
1730     addxri_inst = ReferenceValue;
1731     addxri_imm = (addxri_inst >> 10) & 0xfff;
1732     if (((addxri_inst >> 22) & 0x3) == 1)
1733       addxri_imm <<= 12;
1735     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
1736                      (adrp_imm << 12) + addxri_imm;
1738     *ReferenceName =
1739         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
1740     if (*ReferenceName == nullptr)
1741       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
1742     // If this is arm64 and the reference is a load register instruction and we
1743     // have seen an adrp instruction just before it and the adrp's Xd register
1744     // matches this add's Xn register reconstruct the value being referenced and
1745     // look to see if it is a literal pointer.  Note the load register
1746     // instruction is passed in ReferenceValue.
1747   } else if (info->O->getArch() == Triple::aarch64 &&
1748              *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXui &&
1749              ReferencePC - 4 == info->adrp_addr &&
1750              (info->adrp_inst & 0x9f000000) == 0x90000000 &&
1751              (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
1752     uint32_t ldrxui_inst;
1753     uint64_t adrp_imm, ldrxui_imm;
1755     adrp_imm =
1756         ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
1757     if (info->adrp_inst & 0x0200000)
1758       adrp_imm |= 0xfffffffffc000000LL;
1760     ldrxui_inst = ReferenceValue;
1761     ldrxui_imm = (ldrxui_inst >> 10) & 0xfff;
1763     ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
1764                      (adrp_imm << 12) + (ldrxui_imm << 3);
1766     *ReferenceName =
1767         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
1768     if (*ReferenceName == nullptr)
1769       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
1770   }
1771   // If this arm64 and is an load register (PC-relative) instruction the
1772   // ReferenceValue is the PC plus the immediate value.
1773   else if (info->O->getArch() == Triple::aarch64 &&
1774            (*ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXl ||
1775             *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADR)) {
1776     *ReferenceName =
1777         GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
1778     if (*ReferenceName == nullptr)
1779       *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
1780   }
1781 #if HAVE_CXXABI_H
1782   else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
1783     if (info->demangled_name != nullptr)
1784       free(info->demangled_name);
1785     int status;
1786     info->demangled_name =
1787         abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status);
1788     if (info->demangled_name != nullptr) {
1789       *ReferenceName = info->demangled_name;
1790       *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
1791     }
1792   }
1793 #endif
1794   else {
1795     *ReferenceName = nullptr;
1796     *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
1797   }
1799   return SymbolName;
1802 /// \brief Emits the comments that are stored in the CommentStream.
1803 /// Each comment in the CommentStream must end with a newline.
1804 static void emitComments(raw_svector_ostream &CommentStream,
1805                          SmallString<128> &CommentsToEmit,
1806                          formatted_raw_ostream &FormattedOS,
1807                          const MCAsmInfo &MAI) {
1808   // Flush the stream before taking its content.
1809   CommentStream.flush();
1810   StringRef Comments = CommentsToEmit.str();
1811   // Get the default information for printing a comment.
1812   const char *CommentBegin = MAI.getCommentString();
1813   unsigned CommentColumn = MAI.getCommentColumn();
1814   bool IsFirst = true;
1815   while (!Comments.empty()) {
1816     if (!IsFirst)
1817       FormattedOS << '\n';
1818     // Emit a line of comments.
1819     FormattedOS.PadToColumn(CommentColumn);
1820     size_t Position = Comments.find('\n');
1821     FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
1822     // Move after the newline character.
1823     Comments = Comments.substr(Position + 1);
1824     IsFirst = false;
1825   }
1826   FormattedOS.flush();
1828   // Tell the comment stream that the vector changed underneath it.
1829   CommentsToEmit.clear();
1830   CommentStream.resync();
1833 static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF) {
1834   const char *McpuDefault = nullptr;
1835   const Target *ThumbTarget = nullptr;
1836   const Target *TheTarget = GetTarget(MachOOF, &McpuDefault, &ThumbTarget);
1837   if (!TheTarget) {
1838     // GetTarget prints out stuff.
1839     return;
1840   }
1841   if (MCPU.empty() && McpuDefault)
1842     MCPU = McpuDefault;
1844   std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
1845   std::unique_ptr<const MCInstrInfo> ThumbInstrInfo;
1846   if (ThumbTarget)
1847     ThumbInstrInfo.reset(ThumbTarget->createMCInstrInfo());
1849   // Package up features to be passed to target/subtarget
1850   std::string FeaturesStr;
1851   if (MAttrs.size()) {
1852     SubtargetFeatures Features;
1853     for (unsigned i = 0; i != MAttrs.size(); ++i)
1854       Features.AddFeature(MAttrs[i]);
1855     FeaturesStr = Features.getString();
1856   }
1858   // Set up disassembler.
1859   std::unique_ptr<const MCRegisterInfo> MRI(
1860       TheTarget->createMCRegInfo(TripleName));
1861   std::unique_ptr<const MCAsmInfo> AsmInfo(
1862       TheTarget->createMCAsmInfo(*MRI, TripleName));
1863   std::unique_ptr<const MCSubtargetInfo> STI(
1864       TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
1865   MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr);
1866   std::unique_ptr<MCDisassembler> DisAsm(
1867       TheTarget->createMCDisassembler(*STI, Ctx));
1868   std::unique_ptr<MCSymbolizer> Symbolizer;
1869   struct DisassembleInfo SymbolizerInfo;
1870   std::unique_ptr<MCRelocationInfo> RelInfo(
1871       TheTarget->createMCRelocationInfo(TripleName, Ctx));
1872   if (RelInfo) {
1873     Symbolizer.reset(TheTarget->createMCSymbolizer(
1874         TripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
1875         &SymbolizerInfo, &Ctx, RelInfo.release()));
1876     DisAsm->setSymbolizer(std::move(Symbolizer));
1877   }
1878   int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
1879   std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
1880       AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI, *STI));
1881   // Set the display preference for hex vs. decimal immediates.
1882   IP->setPrintImmHex(PrintImmHex);
1883   // Comment stream and backing vector.
1884   SmallString<128> CommentsToEmit;
1885   raw_svector_ostream CommentStream(CommentsToEmit);
1886   // FIXME: Setting the CommentStream in the InstPrinter is problematic in that
1887   // if it is done then arm64 comments for string literals don't get printed
1888   // and some constant get printed instead and not setting it causes intel
1889   // (32-bit and 64-bit) comments printed with different spacing before the
1890   // comment causing different diffs with the 'C' disassembler library API.
1891   // IP->setCommentStream(CommentStream);
1893   if (!AsmInfo || !STI || !DisAsm || !IP) {
1894     errs() << "error: couldn't initialize disassembler for target "
1895            << TripleName << '\n';
1896     return;
1897   }
1899   // Set up thumb disassembler.
1900   std::unique_ptr<const MCRegisterInfo> ThumbMRI;
1901   std::unique_ptr<const MCAsmInfo> ThumbAsmInfo;
1902   std::unique_ptr<const MCSubtargetInfo> ThumbSTI;
1903   std::unique_ptr<MCDisassembler> ThumbDisAsm;
1904   std::unique_ptr<MCInstPrinter> ThumbIP;
1905   std::unique_ptr<MCContext> ThumbCtx;
1906   std::unique_ptr<MCSymbolizer> ThumbSymbolizer;
1907   struct DisassembleInfo ThumbSymbolizerInfo;
1908   std::unique_ptr<MCRelocationInfo> ThumbRelInfo;
1909   if (ThumbTarget) {
1910     ThumbMRI.reset(ThumbTarget->createMCRegInfo(ThumbTripleName));
1911     ThumbAsmInfo.reset(
1912         ThumbTarget->createMCAsmInfo(*ThumbMRI, ThumbTripleName));
1913     ThumbSTI.reset(
1914         ThumbTarget->createMCSubtargetInfo(ThumbTripleName, MCPU, FeaturesStr));
1915     ThumbCtx.reset(new MCContext(ThumbAsmInfo.get(), ThumbMRI.get(), nullptr));
1916     ThumbDisAsm.reset(ThumbTarget->createMCDisassembler(*ThumbSTI, *ThumbCtx));
1917     MCContext *PtrThumbCtx = ThumbCtx.get();
1918     ThumbRelInfo.reset(
1919         ThumbTarget->createMCRelocationInfo(ThumbTripleName, *PtrThumbCtx));
1920     if (ThumbRelInfo) {
1921       ThumbSymbolizer.reset(ThumbTarget->createMCSymbolizer(
1922           ThumbTripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
1923           &ThumbSymbolizerInfo, PtrThumbCtx, ThumbRelInfo.release()));
1924       ThumbDisAsm->setSymbolizer(std::move(ThumbSymbolizer));
1925     }
1926     int ThumbAsmPrinterVariant = ThumbAsmInfo->getAssemblerDialect();
1927     ThumbIP.reset(ThumbTarget->createMCInstPrinter(
1928         ThumbAsmPrinterVariant, *ThumbAsmInfo, *ThumbInstrInfo, *ThumbMRI,
1929         *ThumbSTI));
1930     // Set the display preference for hex vs. decimal immediates.
1931     ThumbIP->setPrintImmHex(PrintImmHex);
1932   }
1934   if (ThumbTarget && (!ThumbAsmInfo || !ThumbSTI || !ThumbDisAsm || !ThumbIP)) {
1935     errs() << "error: couldn't initialize disassembler for target "
1936            << ThumbTripleName << '\n';
1937     return;
1938   }
1940   MachO::mach_header Header = MachOOF->getHeader();
1942   // FIXME: Using the -cfg command line option, this code used to be able to
1943   // annotate relocations with the referenced symbol's name, and if this was
1944   // inside a __[cf]string section, the data it points to. This is now replaced
1945   // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
1946   std::vector<SectionRef> Sections;
1947   std::vector<SymbolRef> Symbols;
1948   SmallVector<uint64_t, 8> FoundFns;
1949   uint64_t BaseSegmentAddress;
1951   getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns,
1952                         BaseSegmentAddress);
1954   // Sort the symbols by address, just in case they didn't come in that way.
1955   std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());
1957   // Build a data in code table that is sorted on by the address of each entry.
1958   uint64_t BaseAddress = 0;
1959   if (Header.filetype == MachO::MH_OBJECT)
1960     BaseAddress = Sections[0].getAddress();
1961   else
1962     BaseAddress = BaseSegmentAddress;
1963   DiceTable Dices;
1964   for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
1965        DI != DE; ++DI) {
1966     uint32_t Offset;
1967     DI->getOffset(Offset);
1968     Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
1969   }
1970   array_pod_sort(Dices.begin(), Dices.end());
1972 #ifndef NDEBUG
1973   raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
1974 #else
1975   raw_ostream &DebugOut = nulls();
1976 #endif
1978   std::unique_ptr<DIContext> diContext;
1979   ObjectFile *DbgObj = MachOOF;
1980   // Try to find debug info and set up the DIContext for it.
1981   if (UseDbg) {
1982     // A separate DSym file path was specified, parse it as a macho file,
1983     // get the sections and supply it to the section name parsing machinery.
1984     if (!DSYMFile.empty()) {
1985       ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
1986           MemoryBuffer::getFileOrSTDIN(DSYMFile);
1987       if (std::error_code EC = BufOrErr.getError()) {
1988         errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n';
1989         return;
1990       }
1991       DbgObj =
1992           ObjectFile::createMachOObjectFile(BufOrErr.get()->getMemBufferRef())
1993               .get()
1994               .release();
1995     }
1997     // Setup the DIContext
1998     diContext.reset(DIContext::getDWARFContext(*DbgObj));
1999   }
2001   // TODO: For now this only disassembles the (__TEXT,__text) section (see the
2002   // checks in the code below at the top of this loop).  It should allow a
2003   // darwin otool(1) like -s option to disassemble any named segment & section
2004   // that is marked as containing instructions with the attributes
2005   // S_ATTR_PURE_INSTRUCTIONS or S_ATTR_SOME_INSTRUCTIONS in the flags field of
2006   // the section structure.
2007   outs() << "(__TEXT,__text) section\n";
2009   for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
2011     bool SectIsText = Sections[SectIdx].isText();
2012     if (SectIsText == false)
2013       continue;
2015     StringRef SectName;
2016     if (Sections[SectIdx].getName(SectName) || SectName != "__text")
2017       continue; // Skip non-text sections
2019     DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
2021     StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
2022     if (SegmentName != "__TEXT")
2023       continue;
2025     StringRef BytesStr;
2026     Sections[SectIdx].getContents(BytesStr);
2027     ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
2028                             BytesStr.size());
2029     uint64_t SectAddress = Sections[SectIdx].getAddress();
2031     bool symbolTableWorked = false;
2033     // Parse relocations.
2034     std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
2035     for (const RelocationRef &Reloc : Sections[SectIdx].relocations()) {
2036       uint64_t RelocOffset;
2037       Reloc.getOffset(RelocOffset);
2038       uint64_t SectionAddress = Sections[SectIdx].getAddress();
2039       RelocOffset -= SectionAddress;
2041       symbol_iterator RelocSym = Reloc.getSymbol();
2043       Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
2044     }
2045     array_pod_sort(Relocs.begin(), Relocs.end());
2047     // Create a map of symbol addresses to symbol names for use by
2048     // the SymbolizerSymbolLookUp() routine.
2049     SymbolAddressMap AddrMap;
2050     for (const SymbolRef &Symbol : MachOOF->symbols()) {
2051       SymbolRef::Type ST;
2052       Symbol.getType(ST);
2053       if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
2054           ST == SymbolRef::ST_Other) {
2055         uint64_t Address;
2056         Symbol.getAddress(Address);
2057         StringRef SymName;
2058         Symbol.getName(SymName);
2059         AddrMap[Address] = SymName;
2060       }
2061     }
2062     // Set up the block of info used by the Symbolizer call backs.
2063     SymbolizerInfo.verbose = true;
2064     SymbolizerInfo.O = MachOOF;
2065     SymbolizerInfo.S = Sections[SectIdx];
2066     SymbolizerInfo.AddrMap = &AddrMap;
2067     SymbolizerInfo.Sections = &Sections;
2068     SymbolizerInfo.class_name = nullptr;
2069     SymbolizerInfo.selector_name = nullptr;
2070     SymbolizerInfo.method = nullptr;
2071     SymbolizerInfo.demangled_name = nullptr;
2072     SymbolizerInfo.bindtable = nullptr;
2073     SymbolizerInfo.adrp_addr = 0;
2074     SymbolizerInfo.adrp_inst = 0;
2075     // Same for the ThumbSymbolizer
2076     ThumbSymbolizerInfo.verbose = true;
2077     ThumbSymbolizerInfo.O = MachOOF;
2078     ThumbSymbolizerInfo.S = Sections[SectIdx];
2079     ThumbSymbolizerInfo.AddrMap = &AddrMap;
2080     ThumbSymbolizerInfo.Sections = &Sections;
2081     ThumbSymbolizerInfo.class_name = nullptr;
2082     ThumbSymbolizerInfo.selector_name = nullptr;
2083     ThumbSymbolizerInfo.method = nullptr;
2084     ThumbSymbolizerInfo.demangled_name = nullptr;
2085     ThumbSymbolizerInfo.bindtable = nullptr;
2086     ThumbSymbolizerInfo.adrp_addr = 0;
2087     ThumbSymbolizerInfo.adrp_inst = 0;
2089     // Disassemble symbol by symbol.
2090     for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
2091       StringRef SymName;
2092       Symbols[SymIdx].getName(SymName);
2094       SymbolRef::Type ST;
2095       Symbols[SymIdx].getType(ST);
2096       if (ST != SymbolRef::ST_Function)
2097         continue;
2099       // Make sure the symbol is defined in this section.
2100       bool containsSym = Sections[SectIdx].containsSymbol(Symbols[SymIdx]);
2101       if (!containsSym)
2102         continue;
2104       // Start at the address of the symbol relative to the section's address.
2105       uint64_t Start = 0;
2106       uint64_t SectionAddress = Sections[SectIdx].getAddress();
2107       Symbols[SymIdx].getAddress(Start);
2108       Start -= SectionAddress;
2110       // Stop disassembling either at the beginning of the next symbol or at
2111       // the end of the section.
2112       bool containsNextSym = false;
2113       uint64_t NextSym = 0;
2114       uint64_t NextSymIdx = SymIdx + 1;
2115       while (Symbols.size() > NextSymIdx) {
2116         SymbolRef::Type NextSymType;
2117         Symbols[NextSymIdx].getType(NextSymType);
2118         if (NextSymType == SymbolRef::ST_Function) {
2119           containsNextSym =
2120               Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]);
2121           Symbols[NextSymIdx].getAddress(NextSym);
2122           NextSym -= SectionAddress;
2123           break;
2124         }
2125         ++NextSymIdx;
2126       }
2128       uint64_t SectSize = Sections[SectIdx].getSize();
2129       uint64_t End = containsNextSym ? NextSym : SectSize;
2130       uint64_t Size;
2132       symbolTableWorked = true;
2134       DataRefImpl Symb = Symbols[SymIdx].getRawDataRefImpl();
2135       bool isThumb =
2136           (MachOOF->getSymbolFlags(Symb) & SymbolRef::SF_Thumb) && ThumbTarget;
2138       outs() << SymName << ":\n";
2139       DILineInfo lastLine;
2140       for (uint64_t Index = Start; Index < End; Index += Size) {
2141         MCInst Inst;
2143         uint64_t PC = SectAddress + Index;
2144         if (FullLeadingAddr) {
2145           if (MachOOF->is64Bit())
2146             outs() << format("%016" PRIx64, PC);
2147           else
2148             outs() << format("%08" PRIx64, PC);
2149         } else {
2150           outs() << format("%8" PRIx64 ":", PC);
2151         }
2152         if (!NoShowRawInsn)
2153           outs() << "\t";
2155         // Check the data in code table here to see if this is data not an
2156         // instruction to be disassembled.
2157         DiceTable Dice;
2158         Dice.push_back(std::make_pair(PC, DiceRef()));
2159         dice_table_iterator DTI =
2160             std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(),
2161                         compareDiceTableEntries);
2162         if (DTI != Dices.end()) {
2163           uint16_t Length;
2164           DTI->second.getLength(Length);
2165           uint16_t Kind;
2166           DTI->second.getKind(Kind);
2167           Size = DumpDataInCode(reinterpret_cast<const char *>(Bytes.data()) +
2168                                     Index,
2169                                 Length, Kind);
2170           if ((Kind == MachO::DICE_KIND_JUMP_TABLE8) &&
2171               (PC == (DTI->first + Length - 1)) && (Length & 1))
2172             Size++;
2173           continue;
2174         }
2176         SmallVector<char, 64> AnnotationsBytes;
2177         raw_svector_ostream Annotations(AnnotationsBytes);
2179         bool gotInst;
2180         if (isThumb)
2181           gotInst = ThumbDisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
2182                                                 PC, DebugOut, Annotations);
2183         else
2184           gotInst = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index), PC,
2185                                            DebugOut, Annotations);
2186         if (gotInst) {
2187           if (!NoShowRawInsn) {
2188             DumpBytes(StringRef(
2189                 reinterpret_cast<const char *>(Bytes.data()) + Index, Size));
2190           }
2191           formatted_raw_ostream FormattedOS(outs());
2192           Annotations.flush();
2193           StringRef AnnotationsStr = Annotations.str();
2194           if (isThumb)
2195             ThumbIP->printInst(&Inst, FormattedOS, AnnotationsStr);
2196           else
2197             IP->printInst(&Inst, FormattedOS, AnnotationsStr);
2198           emitComments(CommentStream, CommentsToEmit, FormattedOS, *AsmInfo);
2200           // Print debug info.
2201           if (diContext) {
2202             DILineInfo dli = diContext->getLineInfoForAddress(PC);
2203             // Print valid line info if it changed.
2204             if (dli != lastLine && dli.Line != 0)
2205               outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
2206                      << dli.Column;
2207             lastLine = dli;
2208           }
2209           outs() << "\n";
2210         } else {
2211           unsigned int Arch = MachOOF->getArch();
2212           if (Arch == Triple::x86_64 || Arch == Triple::x86) {
2213             outs() << format("\t.byte 0x%02x #bad opcode\n",
2214                              *(Bytes.data() + Index) & 0xff);
2215             Size = 1; // skip exactly one illegible byte and move on.
2216           } else if (Arch == Triple::aarch64) {
2217             uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
2218                               (*(Bytes.data() + Index + 1) & 0xff) << 8 |
2219                               (*(Bytes.data() + Index + 2) & 0xff) << 16 |
2220                               (*(Bytes.data() + Index + 3) & 0xff) << 24;
2221             outs() << format("\t.long\t0x%08x\n", opcode);
2222             Size = 4;
2223           } else {
2224             errs() << "llvm-objdump: warning: invalid instruction encoding\n";
2225             if (Size == 0)
2226               Size = 1; // skip illegible bytes
2227           }
2228         }
2229       }
2230     }
2231     if (!symbolTableWorked) {
2232       // Reading the symbol table didn't work, disassemble the whole section.
2233       uint64_t SectAddress = Sections[SectIdx].getAddress();
2234       uint64_t SectSize = Sections[SectIdx].getSize();
2235       uint64_t InstSize;
2236       for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
2237         MCInst Inst;
2239         uint64_t PC = SectAddress + Index;
2240         if (DisAsm->getInstruction(Inst, InstSize, Bytes.slice(Index), PC,
2241                                    DebugOut, nulls())) {
2242           if (FullLeadingAddr) {
2243             if (MachOOF->is64Bit())
2244               outs() << format("%016" PRIx64, PC);
2245             else
2246               outs() << format("%08" PRIx64, PC);
2247           } else {
2248             outs() << format("%8" PRIx64 ":", PC);
2249           }
2250           if (!NoShowRawInsn) {
2251             outs() << "\t";
2252             DumpBytes(
2253                 StringRef(reinterpret_cast<const char *>(Bytes.data()) + Index,
2254                           InstSize));
2255           }
2256           IP->printInst(&Inst, outs(), "");
2257           outs() << "\n";
2258         } else {
2259           unsigned int Arch = MachOOF->getArch();
2260           if (Arch == Triple::x86_64 || Arch == Triple::x86) {
2261             outs() << format("\t.byte 0x%02x #bad opcode\n",
2262                              *(Bytes.data() + Index) & 0xff);
2263             InstSize = 1; // skip exactly one illegible byte and move on.
2264           } else {
2265             errs() << "llvm-objdump: warning: invalid instruction encoding\n";
2266             if (InstSize == 0)
2267               InstSize = 1; // skip illegible bytes
2268           }
2269         }
2270       }
2271     }
2272     // The TripleName's need to be reset if we are called again for a different
2273     // archtecture.
2274     TripleName = "";
2275     ThumbTripleName = "";
2277     if (SymbolizerInfo.method != nullptr)
2278       free(SymbolizerInfo.method);
2279     if (SymbolizerInfo.demangled_name != nullptr)
2280       free(SymbolizerInfo.demangled_name);
2281     if (SymbolizerInfo.bindtable != nullptr)
2282       delete SymbolizerInfo.bindtable;
2283     if (ThumbSymbolizerInfo.method != nullptr)
2284       free(ThumbSymbolizerInfo.method);
2285     if (ThumbSymbolizerInfo.demangled_name != nullptr)
2286       free(ThumbSymbolizerInfo.demangled_name);
2287     if (ThumbSymbolizerInfo.bindtable != nullptr)
2288       delete ThumbSymbolizerInfo.bindtable;
2289   }
2292 //===----------------------------------------------------------------------===//
2293 // __compact_unwind section dumping
2294 //===----------------------------------------------------------------------===//
2296 namespace {
2298 template <typename T> static uint64_t readNext(const char *&Buf) {
2299   using llvm::support::little;
2300   using llvm::support::unaligned;
2302   uint64_t Val = support::endian::read<T, little, unaligned>(Buf);
2303   Buf += sizeof(T);
2304   return Val;
2307 struct CompactUnwindEntry {
2308   uint32_t OffsetInSection;
2310   uint64_t FunctionAddr;
2311   uint32_t Length;
2312   uint32_t CompactEncoding;
2313   uint64_t PersonalityAddr;
2314   uint64_t LSDAAddr;
2316   RelocationRef FunctionReloc;
2317   RelocationRef PersonalityReloc;
2318   RelocationRef LSDAReloc;
2320   CompactUnwindEntry(StringRef Contents, unsigned Offset, bool Is64)
2321       : OffsetInSection(Offset) {
2322     if (Is64)
2323       read<uint64_t>(Contents.data() + Offset);
2324     else
2325       read<uint32_t>(Contents.data() + Offset);
2326   }
2328 private:
2329   template <typename UIntPtr> void read(const char *Buf) {
2330     FunctionAddr = readNext<UIntPtr>(Buf);
2331     Length = readNext<uint32_t>(Buf);
2332     CompactEncoding = readNext<uint32_t>(Buf);
2333     PersonalityAddr = readNext<UIntPtr>(Buf);
2334     LSDAAddr = readNext<UIntPtr>(Buf);
2335   }
2336 };
2339 /// Given a relocation from __compact_unwind, consisting of the RelocationRef
2340 /// and data being relocated, determine the best base Name and Addend to use for
2341 /// display purposes.
2342 ///
2343 /// 1. An Extern relocation will directly reference a symbol (and the data is
2344 ///    then already an addend), so use that.
2345 /// 2. Otherwise the data is an offset in the object file's layout; try to find
2346 //     a symbol before it in the same section, and use the offset from there.
2347 /// 3. Finally, if all that fails, fall back to an offset from the start of the
2348 ///    referenced section.
2349 static void findUnwindRelocNameAddend(const MachOObjectFile *Obj,
2350                                       std::map<uint64_t, SymbolRef> &Symbols,
2351                                       const RelocationRef &Reloc, uint64_t Addr,
2352                                       StringRef &Name, uint64_t &Addend) {
2353   if (Reloc.getSymbol() != Obj->symbol_end()) {
2354     Reloc.getSymbol()->getName(Name);
2355     Addend = Addr;
2356     return;
2357   }
2359   auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl());
2360   SectionRef RelocSection = Obj->getRelocationSection(RE);
2362   uint64_t SectionAddr = RelocSection.getAddress();
2364   auto Sym = Symbols.upper_bound(Addr);
2365   if (Sym == Symbols.begin()) {
2366     // The first symbol in the object is after this reference, the best we can
2367     // do is section-relative notation.
2368     RelocSection.getName(Name);
2369     Addend = Addr - SectionAddr;
2370     return;
2371   }
2373   // Go back one so that SymbolAddress <= Addr.
2374   --Sym;
2376   section_iterator SymSection = Obj->section_end();
2377   Sym->second.getSection(SymSection);
2378   if (RelocSection == *SymSection) {
2379     // There's a valid symbol in the same section before this reference.
2380     Sym->second.getName(Name);
2381     Addend = Addr - Sym->first;
2382     return;
2383   }
2385   // There is a symbol before this reference, but it's in a different
2386   // section. Probably not helpful to mention it, so use the section name.
2387   RelocSection.getName(Name);
2388   Addend = Addr - SectionAddr;
2391 static void printUnwindRelocDest(const MachOObjectFile *Obj,
2392                                  std::map<uint64_t, SymbolRef> &Symbols,
2393                                  const RelocationRef &Reloc, uint64_t Addr) {
2394   StringRef Name;
2395   uint64_t Addend;
2397   if (!Reloc.getObjectFile())
2398     return;
2400   findUnwindRelocNameAddend(Obj, Symbols, Reloc, Addr, Name, Addend);
2402   outs() << Name;
2403   if (Addend)
2404     outs() << " + " << format("0x%" PRIx64, Addend);
2407 static void
2408 printMachOCompactUnwindSection(const MachOObjectFile *Obj,
2409                                std::map<uint64_t, SymbolRef> &Symbols,
2410                                const SectionRef &CompactUnwind) {
2412   assert(Obj->isLittleEndian() &&
2413          "There should not be a big-endian .o with __compact_unwind");
2415   bool Is64 = Obj->is64Bit();
2416   uint32_t PointerSize = Is64 ? sizeof(uint64_t) : sizeof(uint32_t);
2417   uint32_t EntrySize = 3 * PointerSize + 2 * sizeof(uint32_t);
2419   StringRef Contents;
2420   CompactUnwind.getContents(Contents);
2422   SmallVector<CompactUnwindEntry, 4> CompactUnwinds;
2424   // First populate the initial raw offsets, encodings and so on from the entry.
2425   for (unsigned Offset = 0; Offset < Contents.size(); Offset += EntrySize) {
2426     CompactUnwindEntry Entry(Contents.data(), Offset, Is64);
2427     CompactUnwinds.push_back(Entry);
2428   }
2430   // Next we need to look at the relocations to find out what objects are
2431   // actually being referred to.
2432   for (const RelocationRef &Reloc : CompactUnwind.relocations()) {
2433     uint64_t RelocAddress;
2434     Reloc.getOffset(RelocAddress);
2436     uint32_t EntryIdx = RelocAddress / EntrySize;
2437     uint32_t OffsetInEntry = RelocAddress - EntryIdx * EntrySize;
2438     CompactUnwindEntry &Entry = CompactUnwinds[EntryIdx];
2440     if (OffsetInEntry == 0)
2441       Entry.FunctionReloc = Reloc;
2442     else if (OffsetInEntry == PointerSize + 2 * sizeof(uint32_t))
2443       Entry.PersonalityReloc = Reloc;
2444     else if (OffsetInEntry == 2 * PointerSize + 2 * sizeof(uint32_t))
2445       Entry.LSDAReloc = Reloc;
2446     else
2447       llvm_unreachable("Unexpected relocation in __compact_unwind section");
2448   }
2450   // Finally, we're ready to print the data we've gathered.
2451   outs() << "Contents of __compact_unwind section:\n";
2452   for (auto &Entry : CompactUnwinds) {
2453     outs() << "  Entry at offset "
2454            << format("0x%" PRIx32, Entry.OffsetInSection) << ":\n";
2456     // 1. Start of the region this entry applies to.
2457     outs() << "    start:                " << format("0x%" PRIx64,
2458                                                      Entry.FunctionAddr) << ' ';
2459     printUnwindRelocDest(Obj, Symbols, Entry.FunctionReloc, Entry.FunctionAddr);
2460     outs() << '\n';
2462     // 2. Length of the region this entry applies to.
2463     outs() << "    length:               " << format("0x%" PRIx32, Entry.Length)
2464            << '\n';
2465     // 3. The 32-bit compact encoding.
2466     outs() << "    compact encoding:     "
2467            << format("0x%08" PRIx32, Entry.CompactEncoding) << '\n';
2469     // 4. The personality function, if present.
2470     if (Entry.PersonalityReloc.getObjectFile()) {
2471       outs() << "    personality function: "
2472              << format("0x%" PRIx64, Entry.PersonalityAddr) << ' ';
2473       printUnwindRelocDest(Obj, Symbols, Entry.PersonalityReloc,
2474                            Entry.PersonalityAddr);
2475       outs() << '\n';
2476     }
2478     // 5. This entry's language-specific data area.
2479     if (Entry.LSDAReloc.getObjectFile()) {
2480       outs() << "    LSDA:                 " << format("0x%" PRIx64,
2481                                                        Entry.LSDAAddr) << ' ';
2482       printUnwindRelocDest(Obj, Symbols, Entry.LSDAReloc, Entry.LSDAAddr);
2483       outs() << '\n';
2484     }
2485   }
2488 //===----------------------------------------------------------------------===//
2489 // __unwind_info section dumping
2490 //===----------------------------------------------------------------------===//
2492 static void printRegularSecondLevelUnwindPage(const char *PageStart) {
2493   const char *Pos = PageStart;
2494   uint32_t Kind = readNext<uint32_t>(Pos);
2495   (void)Kind;
2496   assert(Kind == 2 && "kind for a regular 2nd level index should be 2");
2498   uint16_t EntriesStart = readNext<uint16_t>(Pos);
2499   uint16_t NumEntries = readNext<uint16_t>(Pos);
2501   Pos = PageStart + EntriesStart;
2502   for (unsigned i = 0; i < NumEntries; ++i) {
2503     uint32_t FunctionOffset = readNext<uint32_t>(Pos);
2504     uint32_t Encoding = readNext<uint32_t>(Pos);
2506     outs() << "      [" << i << "]: "
2507            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
2508            << ", "
2509            << "encoding=" << format("0x%08" PRIx32, Encoding) << '\n';
2510   }
2513 static void printCompressedSecondLevelUnwindPage(
2514     const char *PageStart, uint32_t FunctionBase,
2515     const SmallVectorImpl<uint32_t> &CommonEncodings) {
2516   const char *Pos = PageStart;
2517   uint32_t Kind = readNext<uint32_t>(Pos);
2518   (void)Kind;
2519   assert(Kind == 3 && "kind for a compressed 2nd level index should be 3");
2521   uint16_t EntriesStart = readNext<uint16_t>(Pos);
2522   uint16_t NumEntries = readNext<uint16_t>(Pos);
2524   uint16_t EncodingsStart = readNext<uint16_t>(Pos);
2525   readNext<uint16_t>(Pos);
2526   const auto *PageEncodings = reinterpret_cast<const support::ulittle32_t *>(
2527       PageStart + EncodingsStart);
2529   Pos = PageStart + EntriesStart;
2530   for (unsigned i = 0; i < NumEntries; ++i) {
2531     uint32_t Entry = readNext<uint32_t>(Pos);
2532     uint32_t FunctionOffset = FunctionBase + (Entry & 0xffffff);
2533     uint32_t EncodingIdx = Entry >> 24;
2535     uint32_t Encoding;
2536     if (EncodingIdx < CommonEncodings.size())
2537       Encoding = CommonEncodings[EncodingIdx];
2538     else
2539       Encoding = PageEncodings[EncodingIdx - CommonEncodings.size()];
2541     outs() << "      [" << i << "]: "
2542            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
2543            << ", "
2544            << "encoding[" << EncodingIdx
2545            << "]=" << format("0x%08" PRIx32, Encoding) << '\n';
2546   }
2549 static void printMachOUnwindInfoSection(const MachOObjectFile *Obj,
2550                                         std::map<uint64_t, SymbolRef> &Symbols,
2551                                         const SectionRef &UnwindInfo) {
2553   assert(Obj->isLittleEndian() &&
2554          "There should not be a big-endian .o with __unwind_info");
2556   outs() << "Contents of __unwind_info section:\n";
2558   StringRef Contents;
2559   UnwindInfo.getContents(Contents);
2560   const char *Pos = Contents.data();
2562   //===----------------------------------
2563   // Section header
2564   //===----------------------------------
2566   uint32_t Version = readNext<uint32_t>(Pos);
2567   outs() << "  Version:                                   "
2568          << format("0x%" PRIx32, Version) << '\n';
2569   assert(Version == 1 && "only understand version 1");
2571   uint32_t CommonEncodingsStart = readNext<uint32_t>(Pos);
2572   outs() << "  Common encodings array section offset:     "
2573          << format("0x%" PRIx32, CommonEncodingsStart) << '\n';
2574   uint32_t NumCommonEncodings = readNext<uint32_t>(Pos);
2575   outs() << "  Number of common encodings in array:       "
2576          << format("0x%" PRIx32, NumCommonEncodings) << '\n';
2578   uint32_t PersonalitiesStart = readNext<uint32_t>(Pos);
2579   outs() << "  Personality function array section offset: "
2580          << format("0x%" PRIx32, PersonalitiesStart) << '\n';
2581   uint32_t NumPersonalities = readNext<uint32_t>(Pos);
2582   outs() << "  Number of personality functions in array:  "
2583          << format("0x%" PRIx32, NumPersonalities) << '\n';
2585   uint32_t IndicesStart = readNext<uint32_t>(Pos);
2586   outs() << "  Index array section offset:                "
2587          << format("0x%" PRIx32, IndicesStart) << '\n';
2588   uint32_t NumIndices = readNext<uint32_t>(Pos);
2589   outs() << "  Number of indices in array:                "
2590          << format("0x%" PRIx32, NumIndices) << '\n';
2592   //===----------------------------------
2593   // A shared list of common encodings
2594   //===----------------------------------
2596   // These occupy indices in the range [0, N] whenever an encoding is referenced
2597   // from a compressed 2nd level index table. In practice the linker only
2598   // creates ~128 of these, so that indices are available to embed encodings in
2599   // the 2nd level index.
2601   SmallVector<uint32_t, 64> CommonEncodings;
2602   outs() << "  Common encodings: (count = " << NumCommonEncodings << ")\n";
2603   Pos = Contents.data() + CommonEncodingsStart;
2604   for (unsigned i = 0; i < NumCommonEncodings; ++i) {
2605     uint32_t Encoding = readNext<uint32_t>(Pos);
2606     CommonEncodings.push_back(Encoding);
2608     outs() << "    encoding[" << i << "]: " << format("0x%08" PRIx32, Encoding)
2609            << '\n';
2610   }
2612   //===----------------------------------
2613   // Personality functions used in this executable
2614   //===----------------------------------
2616   // There should be only a handful of these (one per source language,
2617   // roughly). Particularly since they only get 2 bits in the compact encoding.
2619   outs() << "  Personality functions: (count = " << NumPersonalities << ")\n";
2620   Pos = Contents.data() + PersonalitiesStart;
2621   for (unsigned i = 0; i < NumPersonalities; ++i) {
2622     uint32_t PersonalityFn = readNext<uint32_t>(Pos);
2623     outs() << "    personality[" << i + 1
2624            << "]: " << format("0x%08" PRIx32, PersonalityFn) << '\n';
2625   }
2627   //===----------------------------------
2628   // The level 1 index entries
2629   //===----------------------------------
2631   // These specify an approximate place to start searching for the more detailed
2632   // information, sorted by PC.
2634   struct IndexEntry {
2635     uint32_t FunctionOffset;
2636     uint32_t SecondLevelPageStart;
2637     uint32_t LSDAStart;
2638   };
2640   SmallVector<IndexEntry, 4> IndexEntries;
2642   outs() << "  Top level indices: (count = " << NumIndices << ")\n";
2643   Pos = Contents.data() + IndicesStart;
2644   for (unsigned i = 0; i < NumIndices; ++i) {
2645     IndexEntry Entry;
2647     Entry.FunctionOffset = readNext<uint32_t>(Pos);
2648     Entry.SecondLevelPageStart = readNext<uint32_t>(Pos);
2649     Entry.LSDAStart = readNext<uint32_t>(Pos);
2650     IndexEntries.push_back(Entry);
2652     outs() << "    [" << i << "]: "
2653            << "function offset=" << format("0x%08" PRIx32, Entry.FunctionOffset)
2654            << ", "
2655            << "2nd level page offset="
2656            << format("0x%08" PRIx32, Entry.SecondLevelPageStart) << ", "
2657            << "LSDA offset=" << format("0x%08" PRIx32, Entry.LSDAStart) << '\n';
2658   }
2660   //===----------------------------------
2661   // Next come the LSDA tables
2662   //===----------------------------------
2664   // The LSDA layout is rather implicit: it's a contiguous array of entries from
2665   // the first top-level index's LSDAOffset to the last (sentinel).
2667   outs() << "  LSDA descriptors:\n";
2668   Pos = Contents.data() + IndexEntries[0].LSDAStart;
2669   int NumLSDAs = (IndexEntries.back().LSDAStart - IndexEntries[0].LSDAStart) /
2670                  (2 * sizeof(uint32_t));
2671   for (int i = 0; i < NumLSDAs; ++i) {
2672     uint32_t FunctionOffset = readNext<uint32_t>(Pos);
2673     uint32_t LSDAOffset = readNext<uint32_t>(Pos);
2674     outs() << "    [" << i << "]: "
2675            << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
2676            << ", "
2677            << "LSDA offset=" << format("0x%08" PRIx32, LSDAOffset) << '\n';
2678   }
2680   //===----------------------------------
2681   // Finally, the 2nd level indices
2682   //===----------------------------------
2684   // Generally these are 4K in size, and have 2 possible forms:
2685   //   + Regular stores up to 511 entries with disparate encodings
2686   //   + Compressed stores up to 1021 entries if few enough compact encoding
2687   //     values are used.
2688   outs() << "  Second level indices:\n";
2689   for (unsigned i = 0; i < IndexEntries.size() - 1; ++i) {
2690     // The final sentinel top-level index has no associated 2nd level page
2691     if (IndexEntries[i].SecondLevelPageStart == 0)
2692       break;
2694     outs() << "    Second level index[" << i << "]: "
2695            << "offset in section="
2696            << format("0x%08" PRIx32, IndexEntries[i].SecondLevelPageStart)
2697            << ", "
2698            << "base function offset="
2699            << format("0x%08" PRIx32, IndexEntries[i].FunctionOffset) << '\n';
2701     Pos = Contents.data() + IndexEntries[i].SecondLevelPageStart;
2702     uint32_t Kind = *reinterpret_cast<const support::ulittle32_t *>(Pos);
2703     if (Kind == 2)
2704       printRegularSecondLevelUnwindPage(Pos);
2705     else if (Kind == 3)
2706       printCompressedSecondLevelUnwindPage(Pos, IndexEntries[i].FunctionOffset,
2707                                            CommonEncodings);
2708     else
2709       llvm_unreachable("Do not know how to print this kind of 2nd level page");
2710   }
2713 void llvm::printMachOUnwindInfo(const MachOObjectFile *Obj) {
2714   std::map<uint64_t, SymbolRef> Symbols;
2715   for (const SymbolRef &SymRef : Obj->symbols()) {
2716     // Discard any undefined or absolute symbols. They're not going to take part
2717     // in the convenience lookup for unwind info and just take up resources.
2718     section_iterator Section = Obj->section_end();
2719     SymRef.getSection(Section);
2720     if (Section == Obj->section_end())
2721       continue;
2723     uint64_t Addr;
2724     SymRef.getAddress(Addr);
2725     Symbols.insert(std::make_pair(Addr, SymRef));
2726   }
2728   for (const SectionRef &Section : Obj->sections()) {
2729     StringRef SectName;
2730     Section.getName(SectName);
2731     if (SectName == "__compact_unwind")
2732       printMachOCompactUnwindSection(Obj, Symbols, Section);
2733     else if (SectName == "__unwind_info")
2734       printMachOUnwindInfoSection(Obj, Symbols, Section);
2735     else if (SectName == "__eh_frame")
2736       outs() << "llvm-objdump: warning: unhandled __eh_frame section\n";
2737   }
2740 static void PrintMachHeader(uint32_t magic, uint32_t cputype,
2741                             uint32_t cpusubtype, uint32_t filetype,
2742                             uint32_t ncmds, uint32_t sizeofcmds, uint32_t flags,
2743                             bool verbose) {
2744   outs() << "Mach header\n";
2745   outs() << "      magic cputype cpusubtype  caps    filetype ncmds "
2746             "sizeofcmds      flags\n";
2747   if (verbose) {
2748     if (magic == MachO::MH_MAGIC)
2749       outs() << "   MH_MAGIC";
2750     else if (magic == MachO::MH_MAGIC_64)
2751       outs() << "MH_MAGIC_64";
2752     else
2753       outs() << format(" 0x%08" PRIx32, magic);
2754     switch (cputype) {
2755     case MachO::CPU_TYPE_I386:
2756       outs() << "    I386";
2757       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
2758       case MachO::CPU_SUBTYPE_I386_ALL:
2759         outs() << "        ALL";
2760         break;
2761       default:
2762         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
2763         break;
2764       }
2765       break;
2766     case MachO::CPU_TYPE_X86_64:
2767       outs() << "  X86_64";
2768     case MachO::CPU_SUBTYPE_X86_64_ALL:
2769       outs() << "        ALL";
2770       break;
2771     case MachO::CPU_SUBTYPE_X86_64_H:
2772       outs() << "    Haswell";
2773       outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
2774       break;
2775     case MachO::CPU_TYPE_ARM:
2776       outs() << "     ARM";
2777       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
2778       case MachO::CPU_SUBTYPE_ARM_ALL:
2779         outs() << "        ALL";
2780         break;
2781       case MachO::CPU_SUBTYPE_ARM_V4T:
2782         outs() << "        V4T";
2783         break;
2784       case MachO::CPU_SUBTYPE_ARM_V5TEJ:
2785         outs() << "      V5TEJ";
2786         break;
2787       case MachO::CPU_SUBTYPE_ARM_XSCALE:
2788         outs() << "     XSCALE";
2789         break;
2790       case MachO::CPU_SUBTYPE_ARM_V6:
2791         outs() << "         V6";
2792         break;
2793       case MachO::CPU_SUBTYPE_ARM_V6M:
2794         outs() << "        V6M";
2795         break;
2796       case MachO::CPU_SUBTYPE_ARM_V7:
2797         outs() << "         V7";
2798         break;
2799       case MachO::CPU_SUBTYPE_ARM_V7EM:
2800         outs() << "       V7EM";
2801         break;
2802       case MachO::CPU_SUBTYPE_ARM_V7K:
2803         outs() << "        V7K";
2804         break;
2805       case MachO::CPU_SUBTYPE_ARM_V7M:
2806         outs() << "        V7M";
2807         break;
2808       case MachO::CPU_SUBTYPE_ARM_V7S:
2809         outs() << "        V7S";
2810         break;
2811       default:
2812         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
2813         break;
2814       }
2815       break;
2816     case MachO::CPU_TYPE_ARM64:
2817       outs() << "   ARM64";
2818       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
2819       case MachO::CPU_SUBTYPE_ARM64_ALL:
2820         outs() << "        ALL";
2821         break;
2822       default:
2823         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
2824         break;
2825       }
2826       break;
2827     case MachO::CPU_TYPE_POWERPC:
2828       outs() << "     PPC";
2829       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
2830       case MachO::CPU_SUBTYPE_POWERPC_ALL:
2831         outs() << "        ALL";
2832         break;
2833       default:
2834         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
2835         break;
2836       }
2837       break;
2838     case MachO::CPU_TYPE_POWERPC64:
2839       outs() << "   PPC64";
2840       switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
2841       case MachO::CPU_SUBTYPE_POWERPC_ALL:
2842         outs() << "        ALL";
2843         break;
2844       default:
2845         outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
2846         break;
2847       }
2848       break;
2849     }
2850     if ((cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64) {
2851       outs() << " LIB64";
2852     } else {
2853       outs() << format("  0x%02" PRIx32,
2854                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
2855     }
2856     switch (filetype) {
2857     case MachO::MH_OBJECT:
2858       outs() << "      OBJECT";
2859       break;
2860     case MachO::MH_EXECUTE:
2861       outs() << "     EXECUTE";
2862       break;
2863     case MachO::MH_FVMLIB:
2864       outs() << "      FVMLIB";
2865       break;
2866     case MachO::MH_CORE:
2867       outs() << "        CORE";
2868       break;
2869     case MachO::MH_PRELOAD:
2870       outs() << "     PRELOAD";
2871       break;
2872     case MachO::MH_DYLIB:
2873       outs() << "       DYLIB";
2874       break;
2875     case MachO::MH_DYLIB_STUB:
2876       outs() << "  DYLIB_STUB";
2877       break;
2878     case MachO::MH_DYLINKER:
2879       outs() << "    DYLINKER";
2880       break;
2881     case MachO::MH_BUNDLE:
2882       outs() << "      BUNDLE";
2883       break;
2884     case MachO::MH_DSYM:
2885       outs() << "        DSYM";
2886       break;
2887     case MachO::MH_KEXT_BUNDLE:
2888       outs() << "  KEXTBUNDLE";
2889       break;
2890     default:
2891       outs() << format("  %10u", filetype);
2892       break;
2893     }
2894     outs() << format(" %5u", ncmds);
2895     outs() << format(" %10u", sizeofcmds);
2896     uint32_t f = flags;
2897     if (f & MachO::MH_NOUNDEFS) {
2898       outs() << "   NOUNDEFS";
2899       f &= ~MachO::MH_NOUNDEFS;
2900     }
2901     if (f & MachO::MH_INCRLINK) {
2902       outs() << " INCRLINK";
2903       f &= ~MachO::MH_INCRLINK;
2904     }
2905     if (f & MachO::MH_DYLDLINK) {
2906       outs() << " DYLDLINK";
2907       f &= ~MachO::MH_DYLDLINK;
2908     }
2909     if (f & MachO::MH_BINDATLOAD) {
2910       outs() << " BINDATLOAD";
2911       f &= ~MachO::MH_BINDATLOAD;
2912     }
2913     if (f & MachO::MH_PREBOUND) {
2914       outs() << " PREBOUND";
2915       f &= ~MachO::MH_PREBOUND;
2916     }
2917     if (f & MachO::MH_SPLIT_SEGS) {
2918       outs() << " SPLIT_SEGS";
2919       f &= ~MachO::MH_SPLIT_SEGS;
2920     }
2921     if (f & MachO::MH_LAZY_INIT) {
2922       outs() << " LAZY_INIT";
2923       f &= ~MachO::MH_LAZY_INIT;
2924     }
2925     if (f & MachO::MH_TWOLEVEL) {
2926       outs() << " TWOLEVEL";
2927       f &= ~MachO::MH_TWOLEVEL;
2928     }
2929     if (f & MachO::MH_FORCE_FLAT) {
2930       outs() << " FORCE_FLAT";
2931       f &= ~MachO::MH_FORCE_FLAT;
2932     }
2933     if (f & MachO::MH_NOMULTIDEFS) {
2934       outs() << " NOMULTIDEFS";
2935       f &= ~MachO::MH_NOMULTIDEFS;
2936     }
2937     if (f & MachO::MH_NOFIXPREBINDING) {
2938       outs() << " NOFIXPREBINDING";
2939       f &= ~MachO::MH_NOFIXPREBINDING;
2940     }
2941     if (f & MachO::MH_PREBINDABLE) {
2942       outs() << " PREBINDABLE";
2943       f &= ~MachO::MH_PREBINDABLE;
2944     }
2945     if (f & MachO::MH_ALLMODSBOUND) {
2946       outs() << " ALLMODSBOUND";
2947       f &= ~MachO::MH_ALLMODSBOUND;
2948     }
2949     if (f & MachO::MH_SUBSECTIONS_VIA_SYMBOLS) {
2950       outs() << " SUBSECTIONS_VIA_SYMBOLS";
2951       f &= ~MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
2952     }
2953     if (f & MachO::MH_CANONICAL) {
2954       outs() << " CANONICAL";
2955       f &= ~MachO::MH_CANONICAL;
2956     }
2957     if (f & MachO::MH_WEAK_DEFINES) {
2958       outs() << " WEAK_DEFINES";
2959       f &= ~MachO::MH_WEAK_DEFINES;
2960     }
2961     if (f & MachO::MH_BINDS_TO_WEAK) {
2962       outs() << " BINDS_TO_WEAK";
2963       f &= ~MachO::MH_BINDS_TO_WEAK;
2964     }
2965     if (f & MachO::MH_ALLOW_STACK_EXECUTION) {
2966       outs() << " ALLOW_STACK_EXECUTION";
2967       f &= ~MachO::MH_ALLOW_STACK_EXECUTION;
2968     }
2969     if (f & MachO::MH_DEAD_STRIPPABLE_DYLIB) {
2970       outs() << " DEAD_STRIPPABLE_DYLIB";
2971       f &= ~MachO::MH_DEAD_STRIPPABLE_DYLIB;
2972     }
2973     if (f & MachO::MH_PIE) {
2974       outs() << " PIE";
2975       f &= ~MachO::MH_PIE;
2976     }
2977     if (f & MachO::MH_NO_REEXPORTED_DYLIBS) {
2978       outs() << " NO_REEXPORTED_DYLIBS";
2979       f &= ~MachO::MH_NO_REEXPORTED_DYLIBS;
2980     }
2981     if (f & MachO::MH_HAS_TLV_DESCRIPTORS) {
2982       outs() << " MH_HAS_TLV_DESCRIPTORS";
2983       f &= ~MachO::MH_HAS_TLV_DESCRIPTORS;
2984     }
2985     if (f & MachO::MH_NO_HEAP_EXECUTION) {
2986       outs() << " MH_NO_HEAP_EXECUTION";
2987       f &= ~MachO::MH_NO_HEAP_EXECUTION;
2988     }
2989     if (f & MachO::MH_APP_EXTENSION_SAFE) {
2990       outs() << " APP_EXTENSION_SAFE";
2991       f &= ~MachO::MH_APP_EXTENSION_SAFE;
2992     }
2993     if (f != 0 || flags == 0)
2994       outs() << format(" 0x%08" PRIx32, f);
2995   } else {
2996     outs() << format(" 0x%08" PRIx32, magic);
2997     outs() << format(" %7d", cputype);
2998     outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
2999     outs() << format("  0x%02" PRIx32,
3000                      (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
3001     outs() << format("  %10u", filetype);
3002     outs() << format(" %5u", ncmds);
3003     outs() << format(" %10u", sizeofcmds);
3004     outs() << format(" 0x%08" PRIx32, flags);
3005   }
3006   outs() << "\n";
3009 static void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize,
3010                                 StringRef SegName, uint64_t vmaddr,
3011                                 uint64_t vmsize, uint64_t fileoff,
3012                                 uint64_t filesize, uint32_t maxprot,
3013                                 uint32_t initprot, uint32_t nsects,
3014                                 uint32_t flags, uint32_t object_size,
3015                                 bool verbose) {
3016   uint64_t expected_cmdsize;
3017   if (cmd == MachO::LC_SEGMENT) {
3018     outs() << "      cmd LC_SEGMENT\n";
3019     expected_cmdsize = nsects;
3020     expected_cmdsize *= sizeof(struct MachO::section);
3021     expected_cmdsize += sizeof(struct MachO::segment_command);
3022   } else {
3023     outs() << "      cmd LC_SEGMENT_64\n";
3024     expected_cmdsize = nsects;
3025     expected_cmdsize *= sizeof(struct MachO::section_64);
3026     expected_cmdsize += sizeof(struct MachO::segment_command_64);
3027   }
3028   outs() << "  cmdsize " << cmdsize;
3029   if (cmdsize != expected_cmdsize)
3030     outs() << " Inconsistent size\n";
3031   else
3032     outs() << "\n";
3033   outs() << "  segname " << SegName << "\n";
3034   if (cmd == MachO::LC_SEGMENT_64) {
3035     outs() << "   vmaddr " << format("0x%016" PRIx64, vmaddr) << "\n";
3036     outs() << "   vmsize " << format("0x%016" PRIx64, vmsize) << "\n";
3037   } else {
3038     outs() << "   vmaddr " << format("0x%08" PRIx64, vmaddr) << "\n";
3039     outs() << "   vmsize " << format("0x%08" PRIx64, vmsize) << "\n";
3040   }
3041   outs() << "  fileoff " << fileoff;
3042   if (fileoff > object_size)
3043     outs() << " (past end of file)\n";
3044   else
3045     outs() << "\n";
3046   outs() << " filesize " << filesize;
3047   if (fileoff + filesize > object_size)
3048     outs() << " (past end of file)\n";
3049   else
3050     outs() << "\n";
3051   if (verbose) {
3052     if ((maxprot &
3053          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
3054            MachO::VM_PROT_EXECUTE)) != 0)
3055       outs() << "  maxprot ?" << format("0x%08" PRIx32, maxprot) << "\n";
3056     else {
3057       if (maxprot & MachO::VM_PROT_READ)
3058         outs() << "  maxprot r";
3059       else
3060         outs() << "  maxprot -";
3061       if (maxprot & MachO::VM_PROT_WRITE)
3062         outs() << "w";
3063       else
3064         outs() << "-";
3065       if (maxprot & MachO::VM_PROT_EXECUTE)
3066         outs() << "x\n";
3067       else
3068         outs() << "-\n";
3069     }
3070     if ((initprot &
3071          ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
3072            MachO::VM_PROT_EXECUTE)) != 0)
3073       outs() << "  initprot ?" << format("0x%08" PRIx32, initprot) << "\n";
3074     else {
3075       if (initprot & MachO::VM_PROT_READ)
3076         outs() << " initprot r";
3077       else
3078         outs() << " initprot -";
3079       if (initprot & MachO::VM_PROT_WRITE)
3080         outs() << "w";
3081       else
3082         outs() << "-";
3083       if (initprot & MachO::VM_PROT_EXECUTE)
3084         outs() << "x\n";
3085       else
3086         outs() << "-\n";
3087     }
3088   } else {
3089     outs() << "  maxprot " << format("0x%08" PRIx32, maxprot) << "\n";
3090     outs() << " initprot " << format("0x%08" PRIx32, initprot) << "\n";
3091   }
3092   outs() << "   nsects " << nsects << "\n";
3093   if (verbose) {
3094     outs() << "    flags";
3095     if (flags == 0)
3096       outs() << " (none)\n";
3097     else {
3098       if (flags & MachO::SG_HIGHVM) {
3099         outs() << " HIGHVM";
3100         flags &= ~MachO::SG_HIGHVM;
3101       }
3102       if (flags & MachO::SG_FVMLIB) {
3103         outs() << " FVMLIB";
3104         flags &= ~MachO::SG_FVMLIB;
3105       }
3106       if (flags & MachO::SG_NORELOC) {
3107         outs() << " NORELOC";
3108         flags &= ~MachO::SG_NORELOC;
3109       }
3110       if (flags & MachO::SG_PROTECTED_VERSION_1) {
3111         outs() << " PROTECTED_VERSION_1";
3112         flags &= ~MachO::SG_PROTECTED_VERSION_1;
3113       }
3114       if (flags)
3115         outs() << format(" 0x%08" PRIx32, flags) << " (unknown flags)\n";
3116       else
3117         outs() << "\n";
3118     }
3119   } else {
3120     outs() << "    flags " << format("0x%" PRIx32, flags) << "\n";
3121   }
3124 static void PrintSection(const char *sectname, const char *segname,
3125                          uint64_t addr, uint64_t size, uint32_t offset,
3126                          uint32_t align, uint32_t reloff, uint32_t nreloc,
3127                          uint32_t flags, uint32_t reserved1, uint32_t reserved2,
3128                          uint32_t cmd, const char *sg_segname,
3129                          uint32_t filetype, uint32_t object_size,
3130                          bool verbose) {
3131   outs() << "Section\n";
3132   outs() << "  sectname " << format("%.16s\n", sectname);
3133   outs() << "   segname " << format("%.16s", segname);
3134   if (filetype != MachO::MH_OBJECT && strncmp(sg_segname, segname, 16) != 0)
3135     outs() << " (does not match segment)\n";
3136   else
3137     outs() << "\n";
3138   if (cmd == MachO::LC_SEGMENT_64) {
3139     outs() << "      addr " << format("0x%016" PRIx64, addr) << "\n";
3140     outs() << "      size " << format("0x%016" PRIx64, size);
3141   } else {
3142     outs() << "      addr " << format("0x%08" PRIx64, addr) << "\n";
3143     outs() << "      size " << format("0x%08" PRIx64, size);
3144   }
3145   if ((flags & MachO::S_ZEROFILL) != 0 && offset + size > object_size)
3146     outs() << " (past end of file)\n";
3147   else
3148     outs() << "\n";
3149   outs() << "    offset " << offset;
3150   if (offset > object_size)
3151     outs() << " (past end of file)\n";
3152   else
3153     outs() << "\n";
3154   uint32_t align_shifted = 1 << align;
3155   outs() << "     align 2^" << align << " (" << align_shifted << ")\n";
3156   outs() << "    reloff " << reloff;
3157   if (reloff > object_size)
3158     outs() << " (past end of file)\n";
3159   else
3160     outs() << "\n";
3161   outs() << "    nreloc " << nreloc;
3162   if (reloff + nreloc * sizeof(struct MachO::relocation_info) > object_size)
3163     outs() << " (past end of file)\n";
3164   else
3165     outs() << "\n";
3166   uint32_t section_type = flags & MachO::SECTION_TYPE;
3167   if (verbose) {
3168     outs() << "      type";
3169     if (section_type == MachO::S_REGULAR)
3170       outs() << " S_REGULAR\n";
3171     else if (section_type == MachO::S_ZEROFILL)
3172       outs() << " S_ZEROFILL\n";
3173     else if (section_type == MachO::S_CSTRING_LITERALS)
3174       outs() << " S_CSTRING_LITERALS\n";
3175     else if (section_type == MachO::S_4BYTE_LITERALS)
3176       outs() << " S_4BYTE_LITERALS\n";
3177     else if (section_type == MachO::S_8BYTE_LITERALS)
3178       outs() << " S_8BYTE_LITERALS\n";
3179     else if (section_type == MachO::S_16BYTE_LITERALS)
3180       outs() << " S_16BYTE_LITERALS\n";
3181     else if (section_type == MachO::S_LITERAL_POINTERS)
3182       outs() << " S_LITERAL_POINTERS\n";
3183     else if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS)
3184       outs() << " S_NON_LAZY_SYMBOL_POINTERS\n";
3185     else if (section_type == MachO::S_LAZY_SYMBOL_POINTERS)
3186       outs() << " S_LAZY_SYMBOL_POINTERS\n";
3187     else if (section_type == MachO::S_SYMBOL_STUBS)
3188       outs() << " S_SYMBOL_STUBS\n";
3189     else if (section_type == MachO::S_MOD_INIT_FUNC_POINTERS)
3190       outs() << " S_MOD_INIT_FUNC_POINTERS\n";
3191     else if (section_type == MachO::S_MOD_TERM_FUNC_POINTERS)
3192       outs() << " S_MOD_TERM_FUNC_POINTERS\n";
3193     else if (section_type == MachO::S_COALESCED)
3194       outs() << " S_COALESCED\n";
3195     else if (section_type == MachO::S_INTERPOSING)
3196       outs() << " S_INTERPOSING\n";
3197     else if (section_type == MachO::S_DTRACE_DOF)
3198       outs() << " S_DTRACE_DOF\n";
3199     else if (section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS)
3200       outs() << " S_LAZY_DYLIB_SYMBOL_POINTERS\n";
3201     else if (section_type == MachO::S_THREAD_LOCAL_REGULAR)
3202       outs() << " S_THREAD_LOCAL_REGULAR\n";
3203     else if (section_type == MachO::S_THREAD_LOCAL_ZEROFILL)
3204       outs() << " S_THREAD_LOCAL_ZEROFILL\n";
3205     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLES)
3206       outs() << " S_THREAD_LOCAL_VARIABLES\n";
3207     else if (section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
3208       outs() << " S_THREAD_LOCAL_VARIABLE_POINTERS\n";
3209     else if (section_type == MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS)
3210       outs() << " S_THREAD_LOCAL_INIT_FUNCTION_POINTERS\n";
3211     else
3212       outs() << format("0x%08" PRIx32, section_type) << "\n";
3213     outs() << "attributes";
3214     uint32_t section_attributes = flags & MachO::SECTION_ATTRIBUTES;
3215     if (section_attributes & MachO::S_ATTR_PURE_INSTRUCTIONS)
3216       outs() << " PURE_INSTRUCTIONS";
3217     if (section_attributes & MachO::S_ATTR_NO_TOC)
3218       outs() << " NO_TOC";
3219     if (section_attributes & MachO::S_ATTR_STRIP_STATIC_SYMS)
3220       outs() << " STRIP_STATIC_SYMS";
3221     if (section_attributes & MachO::S_ATTR_NO_DEAD_STRIP)
3222       outs() << " NO_DEAD_STRIP";
3223     if (section_attributes & MachO::S_ATTR_LIVE_SUPPORT)
3224       outs() << " LIVE_SUPPORT";
3225     if (section_attributes & MachO::S_ATTR_SELF_MODIFYING_CODE)
3226       outs() << " SELF_MODIFYING_CODE";
3227     if (section_attributes & MachO::S_ATTR_DEBUG)
3228       outs() << " DEBUG";
3229     if (section_attributes & MachO::S_ATTR_SOME_INSTRUCTIONS)
3230       outs() << " SOME_INSTRUCTIONS";
3231     if (section_attributes & MachO::S_ATTR_EXT_RELOC)
3232       outs() << " EXT_RELOC";
3233     if (section_attributes & MachO::S_ATTR_LOC_RELOC)
3234       outs() << " LOC_RELOC";
3235     if (section_attributes == 0)
3236       outs() << " (none)";
3237     outs() << "\n";
3238   } else
3239     outs() << "     flags " << format("0x%08" PRIx32, flags) << "\n";
3240   outs() << " reserved1 " << reserved1;
3241   if (section_type == MachO::S_SYMBOL_STUBS ||
3242       section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
3243       section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
3244       section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
3245       section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
3246     outs() << " (index into indirect symbol table)\n";
3247   else
3248     outs() << "\n";
3249   outs() << " reserved2 " << reserved2;
3250   if (section_type == MachO::S_SYMBOL_STUBS)
3251     outs() << " (size of stubs)\n";
3252   else
3253     outs() << "\n";
3256 static void PrintSymtabLoadCommand(MachO::symtab_command st, bool Is64Bit,
3257                                    uint32_t object_size) {
3258   outs() << "     cmd LC_SYMTAB\n";
3259   outs() << " cmdsize " << st.cmdsize;
3260   if (st.cmdsize != sizeof(struct MachO::symtab_command))
3261     outs() << " Incorrect size\n";
3262   else
3263     outs() << "\n";
3264   outs() << "  symoff " << st.symoff;
3265   if (st.symoff > object_size)
3266     outs() << " (past end of file)\n";
3267   else
3268     outs() << "\n";
3269   outs() << "   nsyms " << st.nsyms;
3270   uint64_t big_size;
3271   if (Is64Bit) {
3272     big_size = st.nsyms;
3273     big_size *= sizeof(struct MachO::nlist_64);
3274     big_size += st.symoff;
3275     if (big_size > object_size)
3276       outs() << " (past end of file)\n";
3277     else
3278       outs() << "\n";
3279   } else {
3280     big_size = st.nsyms;
3281     big_size *= sizeof(struct MachO::nlist);
3282     big_size += st.symoff;
3283     if (big_size > object_size)
3284       outs() << " (past end of file)\n";
3285     else
3286       outs() << "\n";
3287   }
3288   outs() << "  stroff " << st.stroff;
3289   if (st.stroff > object_size)
3290     outs() << " (past end of file)\n";
3291   else
3292     outs() << "\n";
3293   outs() << " strsize " << st.strsize;
3294   big_size = st.stroff;
3295   big_size += st.strsize;
3296   if (big_size > object_size)
3297     outs() << " (past end of file)\n";
3298   else
3299     outs() << "\n";
3302 static void PrintDysymtabLoadCommand(MachO::dysymtab_command dyst,
3303                                      uint32_t nsyms, uint32_t object_size,
3304                                      bool Is64Bit) {
3305   outs() << "            cmd LC_DYSYMTAB\n";
3306   outs() << "        cmdsize " << dyst.cmdsize;
3307   if (dyst.cmdsize != sizeof(struct MachO::dysymtab_command))
3308     outs() << " Incorrect size\n";
3309   else
3310     outs() << "\n";
3311   outs() << "      ilocalsym " << dyst.ilocalsym;
3312   if (dyst.ilocalsym > nsyms)
3313     outs() << " (greater than the number of symbols)\n";
3314   else
3315     outs() << "\n";
3316   outs() << "      nlocalsym " << dyst.nlocalsym;
3317   uint64_t big_size;
3318   big_size = dyst.ilocalsym;
3319   big_size += dyst.nlocalsym;
3320   if (big_size > nsyms)
3321     outs() << " (past the end of the symbol table)\n";
3322   else
3323     outs() << "\n";
3324   outs() << "     iextdefsym " << dyst.iextdefsym;
3325   if (dyst.iextdefsym > nsyms)
3326     outs() << " (greater than the number of symbols)\n";
3327   else
3328     outs() << "\n";
3329   outs() << "     nextdefsym " << dyst.nextdefsym;
3330   big_size = dyst.iextdefsym;
3331   big_size += dyst.nextdefsym;
3332   if (big_size > nsyms)
3333     outs() << " (past the end of the symbol table)\n";
3334   else
3335     outs() << "\n";
3336   outs() << "      iundefsym " << dyst.iundefsym;
3337   if (dyst.iundefsym > nsyms)
3338     outs() << " (greater than the number of symbols)\n";
3339   else
3340     outs() << "\n";
3341   outs() << "      nundefsym " << dyst.nundefsym;
3342   big_size = dyst.iundefsym;
3343   big_size += dyst.nundefsym;
3344   if (big_size > nsyms)
3345     outs() << " (past the end of the symbol table)\n";
3346   else
3347     outs() << "\n";
3348   outs() << "         tocoff " << dyst.tocoff;
3349   if (dyst.tocoff > object_size)
3350     outs() << " (past end of file)\n";
3351   else
3352     outs() << "\n";
3353   outs() << "           ntoc " << dyst.ntoc;
3354   big_size = dyst.ntoc;
3355   big_size *= sizeof(struct MachO::dylib_table_of_contents);
3356   big_size += dyst.tocoff;
3357   if (big_size > object_size)
3358     outs() << " (past end of file)\n";
3359   else
3360     outs() << "\n";
3361   outs() << "      modtaboff " << dyst.modtaboff;
3362   if (dyst.modtaboff > object_size)
3363     outs() << " (past end of file)\n";
3364   else
3365     outs() << "\n";
3366   outs() << "        nmodtab " << dyst.nmodtab;
3367   uint64_t modtabend;
3368   if (Is64Bit) {
3369     modtabend = dyst.nmodtab;
3370     modtabend *= sizeof(struct MachO::dylib_module_64);
3371     modtabend += dyst.modtaboff;
3372   } else {
3373     modtabend = dyst.nmodtab;
3374     modtabend *= sizeof(struct MachO::dylib_module);
3375     modtabend += dyst.modtaboff;
3376   }
3377   if (modtabend > object_size)
3378     outs() << " (past end of file)\n";
3379   else
3380     outs() << "\n";
3381   outs() << "   extrefsymoff " << dyst.extrefsymoff;
3382   if (dyst.extrefsymoff > object_size)
3383     outs() << " (past end of file)\n";
3384   else
3385     outs() << "\n";
3386   outs() << "    nextrefsyms " << dyst.nextrefsyms;
3387   big_size = dyst.nextrefsyms;
3388   big_size *= sizeof(struct MachO::dylib_reference);
3389   big_size += dyst.extrefsymoff;
3390   if (big_size > object_size)
3391     outs() << " (past end of file)\n";
3392   else
3393     outs() << "\n";
3394   outs() << " indirectsymoff " << dyst.indirectsymoff;
3395   if (dyst.indirectsymoff > object_size)
3396     outs() << " (past end of file)\n";
3397   else
3398     outs() << "\n";
3399   outs() << "  nindirectsyms " << dyst.nindirectsyms;
3400   big_size = dyst.nindirectsyms;
3401   big_size *= sizeof(uint32_t);
3402   big_size += dyst.indirectsymoff;
3403   if (big_size > object_size)
3404     outs() << " (past end of file)\n";
3405   else
3406     outs() << "\n";
3407   outs() << "      extreloff " << dyst.extreloff;
3408   if (dyst.extreloff > object_size)
3409     outs() << " (past end of file)\n";
3410   else
3411     outs() << "\n";
3412   outs() << "        nextrel " << dyst.nextrel;
3413   big_size = dyst.nextrel;
3414   big_size *= sizeof(struct MachO::relocation_info);
3415   big_size += dyst.extreloff;
3416   if (big_size > object_size)
3417     outs() << " (past end of file)\n";
3418   else
3419     outs() << "\n";
3420   outs() << "      locreloff " << dyst.locreloff;
3421   if (dyst.locreloff > object_size)
3422     outs() << " (past end of file)\n";
3423   else
3424     outs() << "\n";
3425   outs() << "        nlocrel " << dyst.nlocrel;
3426   big_size = dyst.nlocrel;
3427   big_size *= sizeof(struct MachO::relocation_info);
3428   big_size += dyst.locreloff;
3429   if (big_size > object_size)
3430     outs() << " (past end of file)\n";
3431   else
3432     outs() << "\n";
3435 static void PrintDyldInfoLoadCommand(MachO::dyld_info_command dc,
3436                                      uint32_t object_size) {
3437   if (dc.cmd == MachO::LC_DYLD_INFO)
3438     outs() << "            cmd LC_DYLD_INFO\n";
3439   else
3440     outs() << "            cmd LC_DYLD_INFO_ONLY\n";
3441   outs() << "        cmdsize " << dc.cmdsize;
3442   if (dc.cmdsize != sizeof(struct MachO::dyld_info_command))
3443     outs() << " Incorrect size\n";
3444   else
3445     outs() << "\n";
3446   outs() << "     rebase_off " << dc.rebase_off;
3447   if (dc.rebase_off > object_size)
3448     outs() << " (past end of file)\n";
3449   else
3450     outs() << "\n";
3451   outs() << "    rebase_size " << dc.rebase_size;
3452   uint64_t big_size;
3453   big_size = dc.rebase_off;
3454   big_size += dc.rebase_size;
3455   if (big_size > object_size)
3456     outs() << " (past end of file)\n";
3457   else
3458     outs() << "\n";
3459   outs() << "       bind_off " << dc.bind_off;
3460   if (dc.bind_off > object_size)
3461     outs() << " (past end of file)\n";
3462   else
3463     outs() << "\n";
3464   outs() << "      bind_size " << dc.bind_size;
3465   big_size = dc.bind_off;
3466   big_size += dc.bind_size;
3467   if (big_size > object_size)
3468     outs() << " (past end of file)\n";
3469   else
3470     outs() << "\n";
3471   outs() << "  weak_bind_off " << dc.weak_bind_off;
3472   if (dc.weak_bind_off > object_size)
3473     outs() << " (past end of file)\n";
3474   else
3475     outs() << "\n";
3476   outs() << " weak_bind_size " << dc.weak_bind_size;
3477   big_size = dc.weak_bind_off;
3478   big_size += dc.weak_bind_size;
3479   if (big_size > object_size)
3480     outs() << " (past end of file)\n";
3481   else
3482     outs() << "\n";
3483   outs() << "  lazy_bind_off " << dc.lazy_bind_off;
3484   if (dc.lazy_bind_off > object_size)
3485     outs() << " (past end of file)\n";
3486   else
3487     outs() << "\n";
3488   outs() << " lazy_bind_size " << dc.lazy_bind_size;
3489   big_size = dc.lazy_bind_off;
3490   big_size += dc.lazy_bind_size;
3491   if (big_size > object_size)
3492     outs() << " (past end of file)\n";
3493   else
3494     outs() << "\n";
3495   outs() << "     export_off " << dc.export_off;
3496   if (dc.export_off > object_size)
3497     outs() << " (past end of file)\n";
3498   else
3499     outs() << "\n";
3500   outs() << "    export_size " << dc.export_size;
3501   big_size = dc.export_off;
3502   big_size += dc.export_size;
3503   if (big_size > object_size)
3504     outs() << " (past end of file)\n";
3505   else
3506     outs() << "\n";
3509 static void PrintDyldLoadCommand(MachO::dylinker_command dyld,
3510                                  const char *Ptr) {
3511   if (dyld.cmd == MachO::LC_ID_DYLINKER)
3512     outs() << "          cmd LC_ID_DYLINKER\n";
3513   else if (dyld.cmd == MachO::LC_LOAD_DYLINKER)
3514     outs() << "          cmd LC_LOAD_DYLINKER\n";
3515   else if (dyld.cmd == MachO::LC_DYLD_ENVIRONMENT)
3516     outs() << "          cmd LC_DYLD_ENVIRONMENT\n";
3517   else
3518     outs() << "          cmd ?(" << dyld.cmd << ")\n";
3519   outs() << "      cmdsize " << dyld.cmdsize;
3520   if (dyld.cmdsize < sizeof(struct MachO::dylinker_command))
3521     outs() << " Incorrect size\n";
3522   else
3523     outs() << "\n";
3524   if (dyld.name >= dyld.cmdsize)
3525     outs() << "         name ?(bad offset " << dyld.name << ")\n";
3526   else {
3527     const char *P = (const char *)(Ptr) + dyld.name;
3528     outs() << "         name " << P << " (offset " << dyld.name << ")\n";
3529   }
3532 static void PrintUuidLoadCommand(MachO::uuid_command uuid) {
3533   outs() << "     cmd LC_UUID\n";
3534   outs() << " cmdsize " << uuid.cmdsize;
3535   if (uuid.cmdsize != sizeof(struct MachO::uuid_command))
3536     outs() << " Incorrect size\n";
3537   else
3538     outs() << "\n";
3539   outs() << "    uuid ";
3540   outs() << format("%02" PRIX32, uuid.uuid[0]);
3541   outs() << format("%02" PRIX32, uuid.uuid[1]);
3542   outs() << format("%02" PRIX32, uuid.uuid[2]);
3543   outs() << format("%02" PRIX32, uuid.uuid[3]);
3544   outs() << "-";
3545   outs() << format("%02" PRIX32, uuid.uuid[4]);
3546   outs() << format("%02" PRIX32, uuid.uuid[5]);
3547   outs() << "-";
3548   outs() << format("%02" PRIX32, uuid.uuid[6]);
3549   outs() << format("%02" PRIX32, uuid.uuid[7]);
3550   outs() << "-";
3551   outs() << format("%02" PRIX32, uuid.uuid[8]);
3552   outs() << format("%02" PRIX32, uuid.uuid[9]);
3553   outs() << "-";
3554   outs() << format("%02" PRIX32, uuid.uuid[10]);
3555   outs() << format("%02" PRIX32, uuid.uuid[11]);
3556   outs() << format("%02" PRIX32, uuid.uuid[12]);
3557   outs() << format("%02" PRIX32, uuid.uuid[13]);
3558   outs() << format("%02" PRIX32, uuid.uuid[14]);
3559   outs() << format("%02" PRIX32, uuid.uuid[15]);
3560   outs() << "\n";
3563 static void PrintRpathLoadCommand(MachO::rpath_command rpath, const char *Ptr) {
3564   outs() << "          cmd LC_RPATH\n";
3565   outs() << "      cmdsize " << rpath.cmdsize;
3566   if (rpath.cmdsize < sizeof(struct MachO::rpath_command))
3567     outs() << " Incorrect size\n";
3568   else
3569     outs() << "\n";
3570   if (rpath.path >= rpath.cmdsize)
3571     outs() << "         path ?(bad offset " << rpath.path << ")\n";
3572   else {
3573     const char *P = (const char *)(Ptr) + rpath.path;
3574     outs() << "         path " << P << " (offset " << rpath.path << ")\n";
3575   }
3578 static void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
3579   if (vd.cmd == MachO::LC_VERSION_MIN_MACOSX)
3580     outs() << "      cmd LC_VERSION_MIN_MACOSX\n";
3581   else if (vd.cmd == MachO::LC_VERSION_MIN_IPHONEOS)
3582     outs() << "      cmd LC_VERSION_MIN_IPHONEOS\n";
3583   else
3584     outs() << "      cmd " << vd.cmd << " (?)\n";
3585   outs() << "  cmdsize " << vd.cmdsize;
3586   if (vd.cmdsize != sizeof(struct MachO::version_min_command))
3587     outs() << " Incorrect size\n";
3588   else
3589     outs() << "\n";
3590   outs() << "  version " << ((vd.version >> 16) & 0xffff) << "."
3591          << ((vd.version >> 8) & 0xff);
3592   if ((vd.version & 0xff) != 0)
3593     outs() << "." << (vd.version & 0xff);
3594   outs() << "\n";
3595   if (vd.sdk == 0)
3596     outs() << "      sdk n/a";
3597   else {
3598     outs() << "      sdk " << ((vd.sdk >> 16) & 0xffff) << "."
3599            << ((vd.sdk >> 8) & 0xff);
3600   }
3601   if ((vd.sdk & 0xff) != 0)
3602     outs() << "." << (vd.sdk & 0xff);
3603   outs() << "\n";
3606 static void PrintSourceVersionCommand(MachO::source_version_command sd) {
3607   outs() << "      cmd LC_SOURCE_VERSION\n";
3608   outs() << "  cmdsize " << sd.cmdsize;
3609   if (sd.cmdsize != sizeof(struct MachO::source_version_command))
3610     outs() << " Incorrect size\n";
3611   else
3612     outs() << "\n";
3613   uint64_t a = (sd.version >> 40) & 0xffffff;
3614   uint64_t b = (sd.version >> 30) & 0x3ff;
3615   uint64_t c = (sd.version >> 20) & 0x3ff;
3616   uint64_t d = (sd.version >> 10) & 0x3ff;
3617   uint64_t e = sd.version & 0x3ff;
3618   outs() << "  version " << a << "." << b;
3619   if (e != 0)
3620     outs() << "." << c << "." << d << "." << e;
3621   else if (d != 0)
3622     outs() << "." << c << "." << d;
3623   else if (c != 0)
3624     outs() << "." << c;
3625   outs() << "\n";
3628 static void PrintEntryPointCommand(MachO::entry_point_command ep) {
3629   outs() << "       cmd LC_MAIN\n";
3630   outs() << "   cmdsize " << ep.cmdsize;
3631   if (ep.cmdsize != sizeof(struct MachO::entry_point_command))
3632     outs() << " Incorrect size\n";
3633   else
3634     outs() << "\n";
3635   outs() << "  entryoff " << ep.entryoff << "\n";
3636   outs() << " stacksize " << ep.stacksize << "\n";
3639 static void PrintEncryptionInfoCommand(MachO::encryption_info_command ec,
3640                                        uint32_t object_size) {
3641   outs() << "          cmd LC_ENCRYPTION_INFO\n";
3642   outs() << "      cmdsize " << ec.cmdsize;
3643   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command))
3644     outs() << " Incorrect size\n";
3645   else
3646     outs() << "\n";
3647   outs() << "     cryptoff " << ec.cryptoff;
3648   if (ec.cryptoff > object_size)
3649     outs() << " (past end of file)\n";
3650   else
3651     outs() << "\n";
3652   outs() << "    cryptsize " << ec.cryptsize;
3653   if (ec.cryptsize > object_size)
3654     outs() << " (past end of file)\n";
3655   else
3656     outs() << "\n";
3657   outs() << "      cryptid " << ec.cryptid << "\n";
3660 static void PrintEncryptionInfoCommand64(MachO::encryption_info_command_64 ec,
3661                                          uint32_t object_size) {
3662   outs() << "          cmd LC_ENCRYPTION_INFO_64\n";
3663   outs() << "      cmdsize " << ec.cmdsize;
3664   if (ec.cmdsize != sizeof(struct MachO::encryption_info_command_64))
3665     outs() << " Incorrect size\n";
3666   else
3667     outs() << "\n";
3668   outs() << "     cryptoff " << ec.cryptoff;
3669   if (ec.cryptoff > object_size)
3670     outs() << " (past end of file)\n";
3671   else
3672     outs() << "\n";
3673   outs() << "    cryptsize " << ec.cryptsize;
3674   if (ec.cryptsize > object_size)
3675     outs() << " (past end of file)\n";
3676   else
3677     outs() << "\n";
3678   outs() << "      cryptid " << ec.cryptid << "\n";
3679   outs() << "          pad " << ec.pad << "\n";
3682 static void PrintLinkerOptionCommand(MachO::linker_option_command lo,
3683                                      const char *Ptr) {
3684   outs() << "     cmd LC_LINKER_OPTION\n";
3685   outs() << " cmdsize " << lo.cmdsize;
3686   if (lo.cmdsize < sizeof(struct MachO::linker_option_command))
3687     outs() << " Incorrect size\n";
3688   else
3689     outs() << "\n";
3690   outs() << "   count " << lo.count << "\n";
3691   const char *string = Ptr + sizeof(struct MachO::linker_option_command);
3692   uint32_t left = lo.cmdsize - sizeof(struct MachO::linker_option_command);
3693   uint32_t i = 0;
3694   while (left > 0) {
3695     while (*string == '\0' && left > 0) {
3696       string++;
3697       left--;
3698     }
3699     if (left > 0) {
3700       i++;
3701       outs() << "  string #" << i << " " << format("%.*s\n", left, string);
3702       uint32_t NullPos = StringRef(string, left).find('\0');
3703       uint32_t len = std::min(NullPos, left) + 1;
3704       string += len;
3705       left -= len;
3706     }
3707   }
3708   if (lo.count != i)
3709     outs() << "   count " << lo.count << " does not match number of strings "
3710            << i << "\n";
3713 static void PrintSubFrameworkCommand(MachO::sub_framework_command sub,
3714                                      const char *Ptr) {
3715   outs() << "          cmd LC_SUB_FRAMEWORK\n";
3716   outs() << "      cmdsize " << sub.cmdsize;
3717   if (sub.cmdsize < sizeof(struct MachO::sub_framework_command))
3718     outs() << " Incorrect size\n";
3719   else
3720     outs() << "\n";
3721   if (sub.umbrella < sub.cmdsize) {
3722     const char *P = Ptr + sub.umbrella;
3723     outs() << "     umbrella " << P << " (offset " << sub.umbrella << ")\n";
3724   } else {
3725     outs() << "     umbrella ?(bad offset " << sub.umbrella << ")\n";
3726   }
3729 static void PrintSubUmbrellaCommand(MachO::sub_umbrella_command sub,
3730                                     const char *Ptr) {
3731   outs() << "          cmd LC_SUB_UMBRELLA\n";
3732   outs() << "      cmdsize " << sub.cmdsize;
3733   if (sub.cmdsize < sizeof(struct MachO::sub_umbrella_command))
3734     outs() << " Incorrect size\n";
3735   else
3736     outs() << "\n";
3737   if (sub.sub_umbrella < sub.cmdsize) {
3738     const char *P = Ptr + sub.sub_umbrella;
3739     outs() << " sub_umbrella " << P << " (offset " << sub.sub_umbrella << ")\n";
3740   } else {
3741     outs() << " sub_umbrella ?(bad offset " << sub.sub_umbrella << ")\n";
3742   }
3745 static void PrintSubLibraryCommand(MachO::sub_library_command sub,
3746                                    const char *Ptr) {
3747   outs() << "          cmd LC_SUB_LIBRARY\n";
3748   outs() << "      cmdsize " << sub.cmdsize;
3749   if (sub.cmdsize < sizeof(struct MachO::sub_library_command))
3750     outs() << " Incorrect size\n";
3751   else
3752     outs() << "\n";
3753   if (sub.sub_library < sub.cmdsize) {
3754     const char *P = Ptr + sub.sub_library;
3755     outs() << "  sub_library " << P << " (offset " << sub.sub_library << ")\n";
3756   } else {
3757     outs() << "  sub_library ?(bad offset " << sub.sub_library << ")\n";
3758   }
3761 static void PrintSubClientCommand(MachO::sub_client_command sub,
3762                                   const char *Ptr) {
3763   outs() << "          cmd LC_SUB_CLIENT\n";
3764   outs() << "      cmdsize " << sub.cmdsize;
3765   if (sub.cmdsize < sizeof(struct MachO::sub_client_command))
3766     outs() << " Incorrect size\n";
3767   else
3768     outs() << "\n";
3769   if (sub.client < sub.cmdsize) {
3770     const char *P = Ptr + sub.client;
3771     outs() << "       client " << P << " (offset " << sub.client << ")\n";
3772   } else {
3773     outs() << "       client ?(bad offset " << sub.client << ")\n";
3774   }
3777 static void PrintRoutinesCommand(MachO::routines_command r) {
3778   outs() << "          cmd LC_ROUTINES\n";
3779   outs() << "      cmdsize " << r.cmdsize;
3780   if (r.cmdsize != sizeof(struct MachO::routines_command))
3781     outs() << " Incorrect size\n";
3782   else
3783     outs() << "\n";
3784   outs() << " init_address " << format("0x%08" PRIx32, r.init_address) << "\n";
3785   outs() << "  init_module " << r.init_module << "\n";
3786   outs() << "    reserved1 " << r.reserved1 << "\n";
3787   outs() << "    reserved2 " << r.reserved2 << "\n";
3788   outs() << "    reserved3 " << r.reserved3 << "\n";
3789   outs() << "    reserved4 " << r.reserved4 << "\n";
3790   outs() << "    reserved5 " << r.reserved5 << "\n";
3791   outs() << "    reserved6 " << r.reserved6 << "\n";
3794 static void PrintRoutinesCommand64(MachO::routines_command_64 r) {
3795   outs() << "          cmd LC_ROUTINES_64\n";
3796   outs() << "      cmdsize " << r.cmdsize;
3797   if (r.cmdsize != sizeof(struct MachO::routines_command_64))
3798     outs() << " Incorrect size\n";
3799   else
3800     outs() << "\n";
3801   outs() << " init_address " << format("0x%016" PRIx64, r.init_address) << "\n";
3802   outs() << "  init_module " << r.init_module << "\n";
3803   outs() << "    reserved1 " << r.reserved1 << "\n";
3804   outs() << "    reserved2 " << r.reserved2 << "\n";
3805   outs() << "    reserved3 " << r.reserved3 << "\n";
3806   outs() << "    reserved4 " << r.reserved4 << "\n";
3807   outs() << "    reserved5 " << r.reserved5 << "\n";
3808   outs() << "    reserved6 " << r.reserved6 << "\n";
3811 static void Print_x86_thread_state64_t(MachO::x86_thread_state64_t &cpu64) {
3812   outs() << "   rax  " << format("0x%016" PRIx64, cpu64.rax);
3813   outs() << " rbx " << format("0x%016" PRIx64, cpu64.rbx);
3814   outs() << " rcx  " << format("0x%016" PRIx64, cpu64.rcx) << "\n";
3815   outs() << "   rdx  " << format("0x%016" PRIx64, cpu64.rdx);
3816   outs() << " rdi " << format("0x%016" PRIx64, cpu64.rdi);
3817   outs() << " rsi  " << format("0x%016" PRIx64, cpu64.rsi) << "\n";
3818   outs() << "   rbp  " << format("0x%016" PRIx64, cpu64.rbp);
3819   outs() << " rsp " << format("0x%016" PRIx64, cpu64.rsp);
3820   outs() << " r8   " << format("0x%016" PRIx64, cpu64.r8) << "\n";
3821   outs() << "    r9  " << format("0x%016" PRIx64, cpu64.r9);
3822   outs() << " r10 " << format("0x%016" PRIx64, cpu64.r10);
3823   outs() << " r11  " << format("0x%016" PRIx64, cpu64.r11) << "\n";
3824   outs() << "   r12  " << format("0x%016" PRIx64, cpu64.r12);
3825   outs() << " r13 " << format("0x%016" PRIx64, cpu64.r13);
3826   outs() << " r14  " << format("0x%016" PRIx64, cpu64.r14) << "\n";
3827   outs() << "   r15  " << format("0x%016" PRIx64, cpu64.r15);
3828   outs() << " rip " << format("0x%016" PRIx64, cpu64.rip) << "\n";
3829   outs() << "rflags  " << format("0x%016" PRIx64, cpu64.rflags);
3830   outs() << " cs  " << format("0x%016" PRIx64, cpu64.cs);
3831   outs() << " fs   " << format("0x%016" PRIx64, cpu64.fs) << "\n";
3832   outs() << "    gs  " << format("0x%016" PRIx64, cpu64.gs) << "\n";
3835 static void Print_mmst_reg(MachO::mmst_reg_t &r) {
3836   uint32_t f;
3837   outs() << "\t      mmst_reg  ";
3838   for (f = 0; f < 10; f++)
3839     outs() << format("%02" PRIx32, (r.mmst_reg[f] & 0xff)) << " ";
3840   outs() << "\n";
3841   outs() << "\t      mmst_rsrv ";
3842   for (f = 0; f < 6; f++)
3843     outs() << format("%02" PRIx32, (r.mmst_rsrv[f] & 0xff)) << " ";
3844   outs() << "\n";
3847 static void Print_xmm_reg(MachO::xmm_reg_t &r) {
3848   uint32_t f;
3849   outs() << "\t      xmm_reg ";
3850   for (f = 0; f < 16; f++)
3851     outs() << format("%02" PRIx32, (r.xmm_reg[f] & 0xff)) << " ";
3852   outs() << "\n";
3855 static void Print_x86_float_state_t(MachO::x86_float_state64_t &fpu) {
3856   outs() << "\t    fpu_reserved[0] " << fpu.fpu_reserved[0];
3857   outs() << " fpu_reserved[1] " << fpu.fpu_reserved[1] << "\n";
3858   outs() << "\t    control: invalid " << fpu.fpu_fcw.invalid;
3859   outs() << " denorm " << fpu.fpu_fcw.denorm;
3860   outs() << " zdiv " << fpu.fpu_fcw.zdiv;
3861   outs() << " ovrfl " << fpu.fpu_fcw.ovrfl;
3862   outs() << " undfl " << fpu.fpu_fcw.undfl;
3863   outs() << " precis " << fpu.fpu_fcw.precis << "\n";
3864   outs() << "\t\t     pc ";
3865   if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_24B)
3866     outs() << "FP_PREC_24B ";
3867   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_53B)
3868     outs() << "FP_PREC_53B ";
3869   else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_64B)
3870     outs() << "FP_PREC_64B ";
3871   else
3872     outs() << fpu.fpu_fcw.pc << " ";
3873   outs() << "rc ";
3874   if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_NEAR)
3875     outs() << "FP_RND_NEAR ";
3876   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_DOWN)
3877     outs() << "FP_RND_DOWN ";
3878   else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_UP)
3879     outs() << "FP_RND_UP ";
3880   else if (fpu.fpu_fcw.rc == MachO::x86_FP_CHOP)
3881     outs() << "FP_CHOP ";
3882   outs() << "\n";
3883   outs() << "\t    status: invalid " << fpu.fpu_fsw.invalid;
3884   outs() << " denorm " << fpu.fpu_fsw.denorm;
3885   outs() << " zdiv " << fpu.fpu_fsw.zdiv;
3886   outs() << " ovrfl " << fpu.fpu_fsw.ovrfl;
3887   outs() << " undfl " << fpu.fpu_fsw.undfl;
3888   outs() << " precis " << fpu.fpu_fsw.precis;
3889   outs() << " stkflt " << fpu.fpu_fsw.stkflt << "\n";
3890   outs() << "\t            errsumm " << fpu.fpu_fsw.errsumm;
3891   outs() << " c0 " << fpu.fpu_fsw.c0;
3892   outs() << " c1 " << fpu.fpu_fsw.c1;
3893   outs() << " c2 " << fpu.fpu_fsw.c2;
3894   outs() << " tos " << fpu.fpu_fsw.tos;
3895   outs() << " c3 " << fpu.fpu_fsw.c3;
3896   outs() << " busy " << fpu.fpu_fsw.busy << "\n";
3897   outs() << "\t    fpu_ftw " << format("0x%02" PRIx32, fpu.fpu_ftw);
3898   outs() << " fpu_rsrv1 " << format("0x%02" PRIx32, fpu.fpu_rsrv1);
3899   outs() << " fpu_fop " << format("0x%04" PRIx32, fpu.fpu_fop);
3900   outs() << " fpu_ip " << format("0x%08" PRIx32, fpu.fpu_ip) << "\n";
3901   outs() << "\t    fpu_cs " << format("0x%04" PRIx32, fpu.fpu_cs);
3902   outs() << " fpu_rsrv2 " << format("0x%04" PRIx32, fpu.fpu_rsrv2);
3903   outs() << " fpu_dp " << format("0x%08" PRIx32, fpu.fpu_dp);
3904   outs() << " fpu_ds " << format("0x%04" PRIx32, fpu.fpu_ds) << "\n";
3905   outs() << "\t    fpu_rsrv3 " << format("0x%04" PRIx32, fpu.fpu_rsrv3);
3906   outs() << " fpu_mxcsr " << format("0x%08" PRIx32, fpu.fpu_mxcsr);
3907   outs() << " fpu_mxcsrmask " << format("0x%08" PRIx32, fpu.fpu_mxcsrmask);
3908   outs() << "\n";
3909   outs() << "\t    fpu_stmm0:\n";
3910   Print_mmst_reg(fpu.fpu_stmm0);
3911   outs() << "\t    fpu_stmm1:\n";
3912   Print_mmst_reg(fpu.fpu_stmm1);
3913   outs() << "\t    fpu_stmm2:\n";
3914   Print_mmst_reg(fpu.fpu_stmm2);
3915   outs() << "\t    fpu_stmm3:\n";
3916   Print_mmst_reg(fpu.fpu_stmm3);
3917   outs() << "\t    fpu_stmm4:\n";
3918   Print_mmst_reg(fpu.fpu_stmm4);
3919   outs() << "\t    fpu_stmm5:\n";
3920   Print_mmst_reg(fpu.fpu_stmm5);
3921   outs() << "\t    fpu_stmm6:\n";
3922   Print_mmst_reg(fpu.fpu_stmm6);
3923   outs() << "\t    fpu_stmm7:\n";
3924   Print_mmst_reg(fpu.fpu_stmm7);
3925   outs() << "\t    fpu_xmm0:\n";
3926   Print_xmm_reg(fpu.fpu_xmm0);
3927   outs() << "\t    fpu_xmm1:\n";
3928   Print_xmm_reg(fpu.fpu_xmm1);
3929   outs() << "\t    fpu_xmm2:\n";
3930   Print_xmm_reg(fpu.fpu_xmm2);
3931   outs() << "\t    fpu_xmm3:\n";
3932   Print_xmm_reg(fpu.fpu_xmm3);
3933   outs() << "\t    fpu_xmm4:\n";
3934   Print_xmm_reg(fpu.fpu_xmm4);
3935   outs() << "\t    fpu_xmm5:\n";
3936   Print_xmm_reg(fpu.fpu_xmm5);
3937   outs() << "\t    fpu_xmm6:\n";
3938   Print_xmm_reg(fpu.fpu_xmm6);
3939   outs() << "\t    fpu_xmm7:\n";
3940   Print_xmm_reg(fpu.fpu_xmm7);
3941   outs() << "\t    fpu_xmm8:\n";
3942   Print_xmm_reg(fpu.fpu_xmm8);
3943   outs() << "\t    fpu_xmm9:\n";
3944   Print_xmm_reg(fpu.fpu_xmm9);
3945   outs() << "\t    fpu_xmm10:\n";
3946   Print_xmm_reg(fpu.fpu_xmm10);
3947   outs() << "\t    fpu_xmm11:\n";
3948   Print_xmm_reg(fpu.fpu_xmm11);
3949   outs() << "\t    fpu_xmm12:\n";
3950   Print_xmm_reg(fpu.fpu_xmm12);
3951   outs() << "\t    fpu_xmm13:\n";
3952   Print_xmm_reg(fpu.fpu_xmm13);
3953   outs() << "\t    fpu_xmm14:\n";
3954   Print_xmm_reg(fpu.fpu_xmm14);
3955   outs() << "\t    fpu_xmm15:\n";
3956   Print_xmm_reg(fpu.fpu_xmm15);
3957   outs() << "\t    fpu_rsrv4:\n";
3958   for (uint32_t f = 0; f < 6; f++) {
3959     outs() << "\t            ";
3960     for (uint32_t g = 0; g < 16; g++)
3961       outs() << format("%02" PRIx32, fpu.fpu_rsrv4[f * g]) << " ";
3962     outs() << "\n";
3963   }
3964   outs() << "\t    fpu_reserved1 " << format("0x%08" PRIx32, fpu.fpu_reserved1);
3965   outs() << "\n";
3968 static void Print_x86_exception_state_t(MachO::x86_exception_state64_t &exc64) {
3969   outs() << "\t    trapno " << format("0x%08" PRIx32, exc64.trapno);
3970   outs() << " err " << format("0x%08" PRIx32, exc64.err);
3971   outs() << " faultvaddr " << format("0x%016" PRIx64, exc64.faultvaddr) << "\n";
3974 static void PrintThreadCommand(MachO::thread_command t, const char *Ptr,
3975                                bool isLittleEndian, uint32_t cputype) {
3976   if (t.cmd == MachO::LC_THREAD)
3977     outs() << "        cmd LC_THREAD\n";
3978   else if (t.cmd == MachO::LC_UNIXTHREAD)
3979     outs() << "        cmd LC_UNIXTHREAD\n";
3980   else
3981     outs() << "        cmd " << t.cmd << " (unknown)\n";
3982   outs() << "    cmdsize " << t.cmdsize;
3983   if (t.cmdsize < sizeof(struct MachO::thread_command) + 2 * sizeof(uint32_t))
3984     outs() << " Incorrect size\n";
3985   else
3986     outs() << "\n";
3988   const char *begin = Ptr + sizeof(struct MachO::thread_command);
3989   const char *end = Ptr + t.cmdsize;
3990   uint32_t flavor, count, left;
3991   if (cputype == MachO::CPU_TYPE_X86_64) {
3992     while (begin < end) {
3993       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
3994         memcpy((char *)&flavor, begin, sizeof(uint32_t));
3995         begin += sizeof(uint32_t);
3996       } else {
3997         flavor = 0;
3998         begin = end;
3999       }
4000       if (isLittleEndian != sys::IsLittleEndianHost)
4001         sys::swapByteOrder(flavor);
4002       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
4003         memcpy((char *)&count, begin, sizeof(uint32_t));
4004         begin += sizeof(uint32_t);
4005       } else {
4006         count = 0;
4007         begin = end;
4008       }
4009       if (isLittleEndian != sys::IsLittleEndianHost)
4010         sys::swapByteOrder(count);
4011       if (flavor == MachO::x86_THREAD_STATE64) {
4012         outs() << "     flavor x86_THREAD_STATE64\n";
4013         if (count == MachO::x86_THREAD_STATE64_COUNT)
4014           outs() << "      count x86_THREAD_STATE64_COUNT\n";
4015         else
4016           outs() << "      count " << count
4017                  << " (not x86_THREAD_STATE64_COUNT)\n";
4018         MachO::x86_thread_state64_t cpu64;
4019         left = end - begin;
4020         if (left >= sizeof(MachO::x86_thread_state64_t)) {
4021           memcpy(&cpu64, begin, sizeof(MachO::x86_thread_state64_t));
4022           begin += sizeof(MachO::x86_thread_state64_t);
4023         } else {
4024           memset(&cpu64, '\0', sizeof(MachO::x86_thread_state64_t));
4025           memcpy(&cpu64, begin, left);
4026           begin += left;
4027         }
4028         if (isLittleEndian != sys::IsLittleEndianHost)
4029           swapStruct(cpu64);
4030         Print_x86_thread_state64_t(cpu64);
4031       } else if (flavor == MachO::x86_THREAD_STATE) {
4032         outs() << "     flavor x86_THREAD_STATE\n";
4033         if (count == MachO::x86_THREAD_STATE_COUNT)
4034           outs() << "      count x86_THREAD_STATE_COUNT\n";
4035         else
4036           outs() << "      count " << count
4037                  << " (not x86_THREAD_STATE_COUNT)\n";
4038         struct MachO::x86_thread_state_t ts;
4039         left = end - begin;
4040         if (left >= sizeof(MachO::x86_thread_state_t)) {
4041           memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
4042           begin += sizeof(MachO::x86_thread_state_t);
4043         } else {
4044           memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
4045           memcpy(&ts, begin, left);
4046           begin += left;
4047         }
4048         if (isLittleEndian != sys::IsLittleEndianHost)
4049           swapStruct(ts);
4050         if (ts.tsh.flavor == MachO::x86_THREAD_STATE64) {
4051           outs() << "\t    tsh.flavor x86_THREAD_STATE64 ";
4052           if (ts.tsh.count == MachO::x86_THREAD_STATE64_COUNT)
4053             outs() << "tsh.count x86_THREAD_STATE64_COUNT\n";
4054           else
4055             outs() << "tsh.count " << ts.tsh.count
4056                    << " (not x86_THREAD_STATE64_COUNT\n";
4057           Print_x86_thread_state64_t(ts.uts.ts64);
4058         } else {
4059           outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
4060                  << ts.tsh.count << "\n";
4061         }
4062       } else if (flavor == MachO::x86_FLOAT_STATE) {
4063         outs() << "     flavor x86_FLOAT_STATE\n";
4064         if (count == MachO::x86_FLOAT_STATE_COUNT)
4065           outs() << "      count x86_FLOAT_STATE_COUNT\n";
4066         else
4067           outs() << "      count " << count << " (not x86_FLOAT_STATE_COUNT)\n";
4068         struct MachO::x86_float_state_t fs;
4069         left = end - begin;
4070         if (left >= sizeof(MachO::x86_float_state_t)) {
4071           memcpy(&fs, begin, sizeof(MachO::x86_float_state_t));
4072           begin += sizeof(MachO::x86_float_state_t);
4073         } else {
4074           memset(&fs, '\0', sizeof(MachO::x86_float_state_t));
4075           memcpy(&fs, begin, left);
4076           begin += left;
4077         }
4078         if (isLittleEndian != sys::IsLittleEndianHost)
4079           swapStruct(fs);
4080         if (fs.fsh.flavor == MachO::x86_FLOAT_STATE64) {
4081           outs() << "\t    fsh.flavor x86_FLOAT_STATE64 ";
4082           if (fs.fsh.count == MachO::x86_FLOAT_STATE64_COUNT)
4083             outs() << "fsh.count x86_FLOAT_STATE64_COUNT\n";
4084           else
4085             outs() << "fsh.count " << fs.fsh.count
4086                    << " (not x86_FLOAT_STATE64_COUNT\n";
4087           Print_x86_float_state_t(fs.ufs.fs64);
4088         } else {
4089           outs() << "\t    fsh.flavor " << fs.fsh.flavor << "  fsh.count "
4090                  << fs.fsh.count << "\n";
4091         }
4092       } else if (flavor == MachO::x86_EXCEPTION_STATE) {
4093         outs() << "     flavor x86_EXCEPTION_STATE\n";
4094         if (count == MachO::x86_EXCEPTION_STATE_COUNT)
4095           outs() << "      count x86_EXCEPTION_STATE_COUNT\n";
4096         else
4097           outs() << "      count " << count
4098                  << " (not x86_EXCEPTION_STATE_COUNT)\n";
4099         struct MachO::x86_exception_state_t es;
4100         left = end - begin;
4101         if (left >= sizeof(MachO::x86_exception_state_t)) {
4102           memcpy(&es, begin, sizeof(MachO::x86_exception_state_t));
4103           begin += sizeof(MachO::x86_exception_state_t);
4104         } else {
4105           memset(&es, '\0', sizeof(MachO::x86_exception_state_t));
4106           memcpy(&es, begin, left);
4107           begin += left;
4108         }
4109         if (isLittleEndian != sys::IsLittleEndianHost)
4110           swapStruct(es);
4111         if (es.esh.flavor == MachO::x86_EXCEPTION_STATE64) {
4112           outs() << "\t    esh.flavor x86_EXCEPTION_STATE64\n";
4113           if (es.esh.count == MachO::x86_EXCEPTION_STATE64_COUNT)
4114             outs() << "\t    esh.count x86_EXCEPTION_STATE64_COUNT\n";
4115           else
4116             outs() << "\t    esh.count " << es.esh.count
4117                    << " (not x86_EXCEPTION_STATE64_COUNT\n";
4118           Print_x86_exception_state_t(es.ues.es64);
4119         } else {
4120           outs() << "\t    esh.flavor " << es.esh.flavor << "  esh.count "
4121                  << es.esh.count << "\n";
4122         }
4123       } else {
4124         outs() << "     flavor " << flavor << " (unknown)\n";
4125         outs() << "      count " << count << "\n";
4126         outs() << "      state (unknown)\n";
4127         begin += count * sizeof(uint32_t);
4128       }
4129     }
4130   } else {
4131     while (begin < end) {
4132       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
4133         memcpy((char *)&flavor, begin, sizeof(uint32_t));
4134         begin += sizeof(uint32_t);
4135       } else {
4136         flavor = 0;
4137         begin = end;
4138       }
4139       if (isLittleEndian != sys::IsLittleEndianHost)
4140         sys::swapByteOrder(flavor);
4141       if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
4142         memcpy((char *)&count, begin, sizeof(uint32_t));
4143         begin += sizeof(uint32_t);
4144       } else {
4145         count = 0;
4146         begin = end;
4147       }
4148       if (isLittleEndian != sys::IsLittleEndianHost)
4149         sys::swapByteOrder(count);
4150       outs() << "     flavor " << flavor << "\n";
4151       outs() << "      count " << count << "\n";
4152       outs() << "      state (Unknown cputype/cpusubtype)\n";
4153       begin += count * sizeof(uint32_t);
4154     }
4155   }
4158 static void PrintDylibCommand(MachO::dylib_command dl, const char *Ptr) {
4159   if (dl.cmd == MachO::LC_ID_DYLIB)
4160     outs() << "          cmd LC_ID_DYLIB\n";
4161   else if (dl.cmd == MachO::LC_LOAD_DYLIB)
4162     outs() << "          cmd LC_LOAD_DYLIB\n";
4163   else if (dl.cmd == MachO::LC_LOAD_WEAK_DYLIB)
4164     outs() << "          cmd LC_LOAD_WEAK_DYLIB\n";
4165   else if (dl.cmd == MachO::LC_REEXPORT_DYLIB)
4166     outs() << "          cmd LC_REEXPORT_DYLIB\n";
4167   else if (dl.cmd == MachO::LC_LAZY_LOAD_DYLIB)
4168     outs() << "          cmd LC_LAZY_LOAD_DYLIB\n";
4169   else if (dl.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
4170     outs() << "          cmd LC_LOAD_UPWARD_DYLIB\n";
4171   else
4172     outs() << "          cmd " << dl.cmd << " (unknown)\n";
4173   outs() << "      cmdsize " << dl.cmdsize;
4174   if (dl.cmdsize < sizeof(struct MachO::dylib_command))
4175     outs() << " Incorrect size\n";
4176   else
4177     outs() << "\n";
4178   if (dl.dylib.name < dl.cmdsize) {
4179     const char *P = (const char *)(Ptr) + dl.dylib.name;
4180     outs() << "         name " << P << " (offset " << dl.dylib.name << ")\n";
4181   } else {
4182     outs() << "         name ?(bad offset " << dl.dylib.name << ")\n";
4183   }
4184   outs() << "   time stamp " << dl.dylib.timestamp << " ";
4185   time_t t = dl.dylib.timestamp;
4186   outs() << ctime(&t);
4187   outs() << "      current version ";
4188   if (dl.dylib.current_version == 0xffffffff)
4189     outs() << "n/a\n";
4190   else
4191     outs() << ((dl.dylib.current_version >> 16) & 0xffff) << "."
4192            << ((dl.dylib.current_version >> 8) & 0xff) << "."
4193            << (dl.dylib.current_version & 0xff) << "\n";
4194   outs() << "compatibility version ";
4195   if (dl.dylib.compatibility_version == 0xffffffff)
4196     outs() << "n/a\n";
4197   else
4198     outs() << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
4199            << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
4200            << (dl.dylib.compatibility_version & 0xff) << "\n";
4203 static void PrintLinkEditDataCommand(MachO::linkedit_data_command ld,
4204                                      uint32_t object_size) {
4205   if (ld.cmd == MachO::LC_CODE_SIGNATURE)
4206     outs() << "      cmd LC_FUNCTION_STARTS\n";
4207   else if (ld.cmd == MachO::LC_SEGMENT_SPLIT_INFO)
4208     outs() << "      cmd LC_SEGMENT_SPLIT_INFO\n";
4209   else if (ld.cmd == MachO::LC_FUNCTION_STARTS)
4210     outs() << "      cmd LC_FUNCTION_STARTS\n";
4211   else if (ld.cmd == MachO::LC_DATA_IN_CODE)
4212     outs() << "      cmd LC_DATA_IN_CODE\n";
4213   else if (ld.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS)
4214     outs() << "      cmd LC_DYLIB_CODE_SIGN_DRS\n";
4215   else if (ld.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT)
4216     outs() << "      cmd LC_LINKER_OPTIMIZATION_HINT\n";
4217   else
4218     outs() << "      cmd " << ld.cmd << " (?)\n";
4219   outs() << "  cmdsize " << ld.cmdsize;
4220   if (ld.cmdsize != sizeof(struct MachO::linkedit_data_command))
4221     outs() << " Incorrect size\n";
4222   else
4223     outs() << "\n";
4224   outs() << "  dataoff " << ld.dataoff;
4225   if (ld.dataoff > object_size)
4226     outs() << " (past end of file)\n";
4227   else
4228     outs() << "\n";
4229   outs() << " datasize " << ld.datasize;
4230   uint64_t big_size = ld.dataoff;
4231   big_size += ld.datasize;
4232   if (big_size > object_size)
4233     outs() << " (past end of file)\n";
4234   else
4235     outs() << "\n";
4238 static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t ncmds,
4239                               uint32_t filetype, uint32_t cputype,
4240                               bool verbose) {
4241   if (ncmds == 0)
4242     return;
4243   StringRef Buf = Obj->getData();
4244   MachOObjectFile::LoadCommandInfo Command = Obj->getFirstLoadCommandInfo();
4245   for (unsigned i = 0;; ++i) {
4246     outs() << "Load command " << i << "\n";
4247     if (Command.C.cmd == MachO::LC_SEGMENT) {
4248       MachO::segment_command SLC = Obj->getSegmentLoadCommand(Command);
4249       const char *sg_segname = SLC.segname;
4250       PrintSegmentCommand(SLC.cmd, SLC.cmdsize, SLC.segname, SLC.vmaddr,
4251                           SLC.vmsize, SLC.fileoff, SLC.filesize, SLC.maxprot,
4252                           SLC.initprot, SLC.nsects, SLC.flags, Buf.size(),
4253                           verbose);
4254       for (unsigned j = 0; j < SLC.nsects; j++) {
4255         MachO::section S = Obj->getSection(Command, j);
4256         PrintSection(S.sectname, S.segname, S.addr, S.size, S.offset, S.align,
4257                      S.reloff, S.nreloc, S.flags, S.reserved1, S.reserved2,
4258                      SLC.cmd, sg_segname, filetype, Buf.size(), verbose);
4259       }
4260     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
4261       MachO::segment_command_64 SLC_64 = Obj->getSegment64LoadCommand(Command);
4262       const char *sg_segname = SLC_64.segname;
4263       PrintSegmentCommand(SLC_64.cmd, SLC_64.cmdsize, SLC_64.segname,
4264                           SLC_64.vmaddr, SLC_64.vmsize, SLC_64.fileoff,
4265                           SLC_64.filesize, SLC_64.maxprot, SLC_64.initprot,
4266                           SLC_64.nsects, SLC_64.flags, Buf.size(), verbose);
4267       for (unsigned j = 0; j < SLC_64.nsects; j++) {
4268         MachO::section_64 S_64 = Obj->getSection64(Command, j);
4269         PrintSection(S_64.sectname, S_64.segname, S_64.addr, S_64.size,
4270                      S_64.offset, S_64.align, S_64.reloff, S_64.nreloc,
4271                      S_64.flags, S_64.reserved1, S_64.reserved2, SLC_64.cmd,
4272                      sg_segname, filetype, Buf.size(), verbose);
4273       }
4274     } else if (Command.C.cmd == MachO::LC_SYMTAB) {
4275       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
4276       PrintSymtabLoadCommand(Symtab, Obj->is64Bit(), Buf.size());
4277     } else if (Command.C.cmd == MachO::LC_DYSYMTAB) {
4278       MachO::dysymtab_command Dysymtab = Obj->getDysymtabLoadCommand();
4279       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
4280       PrintDysymtabLoadCommand(Dysymtab, Symtab.nsyms, Buf.size(),
4281                                Obj->is64Bit());
4282     } else if (Command.C.cmd == MachO::LC_DYLD_INFO ||
4283                Command.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
4284       MachO::dyld_info_command DyldInfo = Obj->getDyldInfoLoadCommand(Command);
4285       PrintDyldInfoLoadCommand(DyldInfo, Buf.size());
4286     } else if (Command.C.cmd == MachO::LC_LOAD_DYLINKER ||
4287                Command.C.cmd == MachO::LC_ID_DYLINKER ||
4288                Command.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
4289       MachO::dylinker_command Dyld = Obj->getDylinkerCommand(Command);
4290       PrintDyldLoadCommand(Dyld, Command.Ptr);
4291     } else if (Command.C.cmd == MachO::LC_UUID) {
4292       MachO::uuid_command Uuid = Obj->getUuidCommand(Command);
4293       PrintUuidLoadCommand(Uuid);
4294     } else if (Command.C.cmd == MachO::LC_RPATH) {
4295       MachO::rpath_command Rpath = Obj->getRpathCommand(Command);
4296       PrintRpathLoadCommand(Rpath, Command.Ptr);
4297     } else if (Command.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
4298                Command.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
4299       MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
4300       PrintVersionMinLoadCommand(Vd);
4301     } else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
4302       MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
4303       PrintSourceVersionCommand(Sd);
4304     } else if (Command.C.cmd == MachO::LC_MAIN) {
4305       MachO::entry_point_command Ep = Obj->getEntryPointCommand(Command);
4306       PrintEntryPointCommand(Ep);
4307     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO) {
4308       MachO::encryption_info_command Ei =
4309           Obj->getEncryptionInfoCommand(Command);
4310       PrintEncryptionInfoCommand(Ei, Buf.size());
4311     } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
4312       MachO::encryption_info_command_64 Ei =
4313           Obj->getEncryptionInfoCommand64(Command);
4314       PrintEncryptionInfoCommand64(Ei, Buf.size());
4315     } else if (Command.C.cmd == MachO::LC_LINKER_OPTION) {
4316       MachO::linker_option_command Lo =
4317           Obj->getLinkerOptionLoadCommand(Command);
4318       PrintLinkerOptionCommand(Lo, Command.Ptr);
4319     } else if (Command.C.cmd == MachO::LC_SUB_FRAMEWORK) {
4320       MachO::sub_framework_command Sf = Obj->getSubFrameworkCommand(Command);
4321       PrintSubFrameworkCommand(Sf, Command.Ptr);
4322     } else if (Command.C.cmd == MachO::LC_SUB_UMBRELLA) {
4323       MachO::sub_umbrella_command Sf = Obj->getSubUmbrellaCommand(Command);
4324       PrintSubUmbrellaCommand(Sf, Command.Ptr);
4325     } else if (Command.C.cmd == MachO::LC_SUB_LIBRARY) {
4326       MachO::sub_library_command Sl = Obj->getSubLibraryCommand(Command);
4327       PrintSubLibraryCommand(Sl, Command.Ptr);
4328     } else if (Command.C.cmd == MachO::LC_SUB_CLIENT) {
4329       MachO::sub_client_command Sc = Obj->getSubClientCommand(Command);
4330       PrintSubClientCommand(Sc, Command.Ptr);
4331     } else if (Command.C.cmd == MachO::LC_ROUTINES) {
4332       MachO::routines_command Rc = Obj->getRoutinesCommand(Command);
4333       PrintRoutinesCommand(Rc);
4334     } else if (Command.C.cmd == MachO::LC_ROUTINES_64) {
4335       MachO::routines_command_64 Rc = Obj->getRoutinesCommand64(Command);
4336       PrintRoutinesCommand64(Rc);
4337     } else if (Command.C.cmd == MachO::LC_THREAD ||
4338                Command.C.cmd == MachO::LC_UNIXTHREAD) {
4339       MachO::thread_command Tc = Obj->getThreadCommand(Command);
4340       PrintThreadCommand(Tc, Command.Ptr, Obj->isLittleEndian(), cputype);
4341     } else if (Command.C.cmd == MachO::LC_LOAD_DYLIB ||
4342                Command.C.cmd == MachO::LC_ID_DYLIB ||
4343                Command.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
4344                Command.C.cmd == MachO::LC_REEXPORT_DYLIB ||
4345                Command.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
4346                Command.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
4347       MachO::dylib_command Dl = Obj->getDylibIDLoadCommand(Command);
4348       PrintDylibCommand(Dl, Command.Ptr);
4349     } else if (Command.C.cmd == MachO::LC_CODE_SIGNATURE ||
4350                Command.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO ||
4351                Command.C.cmd == MachO::LC_FUNCTION_STARTS ||
4352                Command.C.cmd == MachO::LC_DATA_IN_CODE ||
4353                Command.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS ||
4354                Command.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
4355       MachO::linkedit_data_command Ld =
4356           Obj->getLinkeditDataLoadCommand(Command);
4357       PrintLinkEditDataCommand(Ld, Buf.size());
4358     } else {
4359       outs() << "      cmd ?(" << format("0x%08" PRIx32, Command.C.cmd)
4360              << ")\n";
4361       outs() << "  cmdsize " << Command.C.cmdsize << "\n";
4362       // TODO: get and print the raw bytes of the load command.
4363     }
4364     // TODO: print all the other kinds of load commands.
4365     if (i == ncmds - 1)
4366       break;
4367     else
4368       Command = Obj->getNextLoadCommandInfo(Command);
4369   }
4372 static void getAndPrintMachHeader(const MachOObjectFile *Obj, uint32_t &ncmds,
4373                                   uint32_t &filetype, uint32_t &cputype,
4374                                   bool verbose) {
4375   if (Obj->is64Bit()) {
4376     MachO::mach_header_64 H_64;
4377     H_64 = Obj->getHeader64();
4378     PrintMachHeader(H_64.magic, H_64.cputype, H_64.cpusubtype, H_64.filetype,
4379                     H_64.ncmds, H_64.sizeofcmds, H_64.flags, verbose);
4380     ncmds = H_64.ncmds;
4381     filetype = H_64.filetype;
4382     cputype = H_64.cputype;
4383   } else {
4384     MachO::mach_header H;
4385     H = Obj->getHeader();
4386     PrintMachHeader(H.magic, H.cputype, H.cpusubtype, H.filetype, H.ncmds,
4387                     H.sizeofcmds, H.flags, verbose);
4388     ncmds = H.ncmds;
4389     filetype = H.filetype;
4390     cputype = H.cputype;
4391   }
4394 void llvm::printMachOFileHeader(const object::ObjectFile *Obj) {
4395   const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
4396   uint32_t ncmds = 0;
4397   uint32_t filetype = 0;
4398   uint32_t cputype = 0;
4399   getAndPrintMachHeader(file, ncmds, filetype, cputype, true);
4400   PrintLoadCommands(file, ncmds, filetype, cputype, true);
4403 //===----------------------------------------------------------------------===//
4404 // export trie dumping
4405 //===----------------------------------------------------------------------===//
4407 void llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) {
4408   for (const llvm::object::ExportEntry &Entry : Obj->exports()) {
4409     uint64_t Flags = Entry.flags();
4410     bool ReExport = (Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
4411     bool WeakDef = (Flags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
4412     bool ThreadLocal = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
4413                         MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL);
4414     bool Abs = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
4415                 MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
4416     bool Resolver = (Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
4417     if (ReExport)
4418       outs() << "[re-export] ";
4419     else
4420       outs() << format("0x%08llX  ",
4421                        Entry.address()); // FIXME:add in base address
4422     outs() << Entry.name();
4423     if (WeakDef || ThreadLocal || Resolver || Abs) {
4424       bool NeedsComma = false;
4425       outs() << " [";
4426       if (WeakDef) {
4427         outs() << "weak_def";
4428         NeedsComma = true;
4429       }
4430       if (ThreadLocal) {
4431         if (NeedsComma)
4432           outs() << ", ";
4433         outs() << "per-thread";
4434         NeedsComma = true;
4435       }
4436       if (Abs) {
4437         if (NeedsComma)
4438           outs() << ", ";
4439         outs() << "absolute";
4440         NeedsComma = true;
4441       }
4442       if (Resolver) {
4443         if (NeedsComma)
4444           outs() << ", ";
4445         outs() << format("resolver=0x%08llX", Entry.other());
4446         NeedsComma = true;
4447       }
4448       outs() << "]";
4449     }
4450     if (ReExport) {
4451       StringRef DylibName = "unknown";
4452       int Ordinal = Entry.other() - 1;
4453       Obj->getLibraryShortNameByIndex(Ordinal, DylibName);
4454       if (Entry.otherName().empty())
4455         outs() << " (from " << DylibName << ")";
4456       else
4457         outs() << " (" << Entry.otherName() << " from " << DylibName << ")";
4458     }
4459     outs() << "\n";
4460   }
4463 //===----------------------------------------------------------------------===//
4464 // rebase table dumping
4465 //===----------------------------------------------------------------------===//
4467 namespace {
4468 class SegInfo {
4469 public:
4470   SegInfo(const object::MachOObjectFile *Obj);
4472   StringRef segmentName(uint32_t SegIndex);
4473   StringRef sectionName(uint32_t SegIndex, uint64_t SegOffset);
4474   uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
4476 private:
4477   struct SectionInfo {
4478     uint64_t Address;
4479     uint64_t Size;
4480     StringRef SectionName;
4481     StringRef SegmentName;
4482     uint64_t OffsetInSegment;
4483     uint64_t SegmentStartAddress;
4484     uint32_t SegmentIndex;
4485   };
4486   const SectionInfo &findSection(uint32_t SegIndex, uint64_t SegOffset);
4487   SmallVector<SectionInfo, 32> Sections;
4488 };
4491 SegInfo::SegInfo(const object::MachOObjectFile *Obj) {
4492   // Build table of sections so segIndex/offset pairs can be translated.
4493   uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
4494   StringRef CurSegName;
4495   uint64_t CurSegAddress;
4496   for (const SectionRef &Section : Obj->sections()) {
4497     SectionInfo Info;
4498     if (error(Section.getName(Info.SectionName)))
4499       return;
4500     Info.Address = Section.getAddress();
4501     Info.Size = Section.getSize();
4502     Info.SegmentName =
4503         Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
4504     if (!Info.SegmentName.equals(CurSegName)) {
4505       ++CurSegIndex;
4506       CurSegName = Info.SegmentName;
4507       CurSegAddress = Info.Address;
4508     }
4509     Info.SegmentIndex = CurSegIndex - 1;
4510     Info.OffsetInSegment = Info.Address - CurSegAddress;
4511     Info.SegmentStartAddress = CurSegAddress;
4512     Sections.push_back(Info);
4513   }
4516 StringRef SegInfo::segmentName(uint32_t SegIndex) {
4517   for (const SectionInfo &SI : Sections) {
4518     if (SI.SegmentIndex == SegIndex)
4519       return SI.SegmentName;
4520   }
4521   llvm_unreachable("invalid segIndex");
4524 const SegInfo::SectionInfo &SegInfo::findSection(uint32_t SegIndex,
4525                                                  uint64_t OffsetInSeg) {
4526   for (const SectionInfo &SI : Sections) {
4527     if (SI.SegmentIndex != SegIndex)
4528       continue;
4529     if (SI.OffsetInSegment > OffsetInSeg)
4530       continue;
4531     if (OffsetInSeg >= (SI.OffsetInSegment + SI.Size))
4532       continue;
4533     return SI;
4534   }
4535   llvm_unreachable("segIndex and offset not in any section");
4538 StringRef SegInfo::sectionName(uint32_t SegIndex, uint64_t OffsetInSeg) {
4539   return findSection(SegIndex, OffsetInSeg).SectionName;
4542 uint64_t SegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
4543   const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4544   return SI.SegmentStartAddress + OffsetInSeg;
4547 void llvm::printMachORebaseTable(const object::MachOObjectFile *Obj) {
4548   // Build table of sections so names can used in final output.
4549   SegInfo sectionTable(Obj);
4551   outs() << "segment  section            address     type\n";
4552   for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable()) {
4553     uint32_t SegIndex = Entry.segmentIndex();
4554     uint64_t OffsetInSeg = Entry.segmentOffset();
4555     StringRef SegmentName = sectionTable.segmentName(SegIndex);
4556     StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
4557     uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
4559     // Table lines look like: __DATA  __nl_symbol_ptr  0x0000F00C  pointer
4560     outs() << format("%-8s %-18s 0x%08" PRIX64 "  %s\n",
4561                      SegmentName.str().c_str(), SectionName.str().c_str(),
4562                      Address, Entry.typeName().str().c_str());
4563   }
4566 static StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) {
4567   StringRef DylibName;
4568   switch (Ordinal) {
4569   case MachO::BIND_SPECIAL_DYLIB_SELF:
4570     return "this-image";
4571   case MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE:
4572     return "main-executable";
4573   case MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP:
4574     return "flat-namespace";
4575   default:
4576     if (Ordinal > 0) {
4577       std::error_code EC =
4578           Obj->getLibraryShortNameByIndex(Ordinal - 1, DylibName);
4579       if (EC)
4580         return "<<bad library ordinal>>";
4581       return DylibName;
4582     }
4583   }
4584   return "<<unknown special ordinal>>";
4587 //===----------------------------------------------------------------------===//
4588 // bind table dumping
4589 //===----------------------------------------------------------------------===//
4591 void llvm::printMachOBindTable(const object::MachOObjectFile *Obj) {
4592   // Build table of sections so names can used in final output.
4593   SegInfo sectionTable(Obj);
4595   outs() << "segment  section            address    type       "
4596             "addend dylib            symbol\n";
4597   for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable()) {
4598     uint32_t SegIndex = Entry.segmentIndex();
4599     uint64_t OffsetInSeg = Entry.segmentOffset();
4600     StringRef SegmentName = sectionTable.segmentName(SegIndex);
4601     StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
4602     uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
4604     // Table lines look like:
4605     //  __DATA  __got  0x00012010    pointer   0 libSystem ___stack_chk_guard
4606     StringRef Attr;
4607     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT)
4608       Attr = " (weak_import)";
4609     outs() << left_justify(SegmentName, 8) << " "
4610            << left_justify(SectionName, 18) << " "
4611            << format_hex(Address, 10, true) << " "
4612            << left_justify(Entry.typeName(), 8) << " "
4613            << format_decimal(Entry.addend(), 8) << " "
4614            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
4615            << Entry.symbolName() << Attr << "\n";
4616   }
4619 //===----------------------------------------------------------------------===//
4620 // lazy bind table dumping
4621 //===----------------------------------------------------------------------===//
4623 void llvm::printMachOLazyBindTable(const object::MachOObjectFile *Obj) {
4624   // Build table of sections so names can used in final output.
4625   SegInfo sectionTable(Obj);
4627   outs() << "segment  section            address     "
4628             "dylib            symbol\n";
4629   for (const llvm::object::MachOBindEntry &Entry : Obj->lazyBindTable()) {
4630     uint32_t SegIndex = Entry.segmentIndex();
4631     uint64_t OffsetInSeg = Entry.segmentOffset();
4632     StringRef SegmentName = sectionTable.segmentName(SegIndex);
4633     StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
4634     uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
4636     // Table lines look like:
4637     //  __DATA  __got  0x00012010 libSystem ___stack_chk_guard
4638     outs() << left_justify(SegmentName, 8) << " "
4639            << left_justify(SectionName, 18) << " "
4640            << format_hex(Address, 10, true) << " "
4641            << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
4642            << Entry.symbolName() << "\n";
4643   }
4646 //===----------------------------------------------------------------------===//
4647 // weak bind table dumping
4648 //===----------------------------------------------------------------------===//
4650 void llvm::printMachOWeakBindTable(const object::MachOObjectFile *Obj) {
4651   // Build table of sections so names can used in final output.
4652   SegInfo sectionTable(Obj);
4654   outs() << "segment  section            address     "
4655             "type       addend   symbol\n";
4656   for (const llvm::object::MachOBindEntry &Entry : Obj->weakBindTable()) {
4657     // Strong symbols don't have a location to update.
4658     if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
4659       outs() << "                                        strong              "
4660              << Entry.symbolName() << "\n";
4661       continue;
4662     }
4663     uint32_t SegIndex = Entry.segmentIndex();
4664     uint64_t OffsetInSeg = Entry.segmentOffset();
4665     StringRef SegmentName = sectionTable.segmentName(SegIndex);
4666     StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
4667     uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
4669     // Table lines look like:
4670     // __DATA  __data  0x00001000  pointer    0   _foo
4671     outs() << left_justify(SegmentName, 8) << " "
4672            << left_justify(SectionName, 18) << " "
4673            << format_hex(Address, 10, true) << " "
4674            << left_justify(Entry.typeName(), 8) << " "
4675            << format_decimal(Entry.addend(), 8) << "   " << Entry.symbolName()
4676            << "\n";
4677   }
4680 // get_dyld_bind_info_symbolname() is used for disassembly and passed an
4681 // address, ReferenceValue, in the Mach-O file and looks in the dyld bind
4682 // information for that address. If the address is found its binding symbol
4683 // name is returned.  If not nullptr is returned.
4684 static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
4685                                                  struct DisassembleInfo *info) {
4686   if (info->bindtable == nullptr) {
4687     info->bindtable = new (BindTable);
4688     SegInfo sectionTable(info->O);
4689     for (const llvm::object::MachOBindEntry &Entry : info->O->bindTable()) {
4690       uint32_t SegIndex = Entry.segmentIndex();
4691       uint64_t OffsetInSeg = Entry.segmentOffset();
4692       uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
4693       const char *SymbolName = nullptr;
4694       StringRef name = Entry.symbolName();
4695       if (!name.empty())
4696         SymbolName = name.data();
4697       info->bindtable->push_back(std::make_pair(Address, SymbolName));
4698     }
4699   }
4700   for (bind_table_iterator BI = info->bindtable->begin(),
4701                            BE = info->bindtable->end();
4702        BI != BE; ++BI) {
4703     uint64_t Address = BI->first;
4704     if (ReferenceValue == Address) {
4705       const char *SymbolName = BI->second;
4706       return SymbolName;
4707     }
4708   }
4709   return nullptr;