diff options
Diffstat (limited to 'llvm/tools/llvm-objdump/MachODump.cpp')
-rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 234 |
1 files changed, 117 insertions, 117 deletions
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 87c7a92933f1d..6d46496ecd4ea 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +#include "MachODump.h" + #include "llvm-objdump.h" #include "llvm-c/Disassembler.h" #include "llvm/ADT/STLExtras.h" @@ -56,53 +58,35 @@ extern "C" { } #endif +using namespace llvm; using namespace llvm::object; +using namespace llvm::objdump; -namespace llvm { - -cl::OptionCategory MachOCat("llvm-objdump MachO Specific Options"); - -extern cl::opt<bool> ArchiveHeaders; -extern cl::opt<bool> Disassemble; -extern cl::opt<bool> DisassembleAll; -extern cl::opt<DIDumpType> DwarfDumpType; -extern cl::list<std::string> FilterSections; -extern cl::list<std::string> MAttrs; -extern cl::opt<std::string> MCPU; -extern cl::opt<bool> NoShowRawInsn; -extern cl::opt<bool> NoLeadingAddr; -extern cl::opt<bool> PrintImmHex; -extern cl::opt<bool> PrivateHeaders; -extern cl::opt<bool> Relocations; -extern cl::opt<bool> SectionHeaders; -extern cl::opt<bool> SectionContents; -extern cl::opt<bool> SymbolTable; -extern cl::opt<std::string> TripleName; -extern cl::opt<bool> UnwindInfo; +cl::OptionCategory objdump::MachOCat("llvm-objdump MachO Specific Options"); -cl::opt<bool> - FirstPrivateHeader("private-header", - cl::desc("Display only the first format specific file " - "header"), - cl::cat(MachOCat)); +cl::opt<bool> objdump::FirstPrivateHeader( + "private-header", + cl::desc("Display only the first format specific file header"), + cl::cat(MachOCat)); -cl::opt<bool> ExportsTrie("exports-trie", - cl::desc("Display mach-o exported symbols"), - cl::cat(MachOCat)); +cl::opt<bool> objdump::ExportsTrie("exports-trie", + cl::desc("Display mach-o exported symbols"), + cl::cat(MachOCat)); -cl::opt<bool> Rebase("rebase", cl::desc("Display mach-o rebasing info"), - cl::cat(MachOCat)); +cl::opt<bool> objdump::Rebase("rebase", + cl::desc("Display mach-o rebasing info"), + cl::cat(MachOCat)); -cl::opt<bool> Bind("bind", cl::desc("Display mach-o binding info"), - cl::cat(MachOCat)); +cl::opt<bool> objdump::Bind("bind", cl::desc("Display mach-o binding info"), + cl::cat(MachOCat)); -cl::opt<bool> LazyBind("lazy-bind", - cl::desc("Display mach-o lazy binding info"), - cl::cat(MachOCat)); +cl::opt<bool> objdump::LazyBind("lazy-bind", + cl::desc("Display mach-o lazy binding info"), + cl::cat(MachOCat)); -cl::opt<bool> WeakBind("weak-bind", - cl::desc("Display mach-o weak binding info"), - cl::cat(MachOCat)); +cl::opt<bool> objdump::WeakBind("weak-bind", + cl::desc("Display mach-o weak binding info"), + cl::cat(MachOCat)); static cl::opt<bool> UseDbg("g", cl::Grouping, @@ -121,63 +105,65 @@ static cl::opt<bool> NoLeadingHeaders("no-leading-headers", cl::desc("Print no leading headers"), cl::cat(MachOCat)); -cl::opt<bool> UniversalHeaders("universal-headers", - cl::desc("Print Mach-O universal headers " - "(requires -macho)"), - cl::cat(MachOCat)); - -cl::opt<bool> - ArchiveMemberOffsets("archive-member-offsets", - cl::desc("Print the offset to each archive member for " - "Mach-O archives (requires -macho and " - "-archive-headers)"), - cl::cat(MachOCat)); - -cl::opt<bool> IndirectSymbols("indirect-symbols", - cl::desc("Print indirect symbol table for Mach-O " - "objects (requires -macho)"), - cl::cat(MachOCat)); +cl::opt<bool> objdump::UniversalHeaders( + "universal-headers", + cl::desc("Print Mach-O universal headers (requires -macho)"), + cl::cat(MachOCat)); -cl::opt<bool> - DataInCode("data-in-code", - cl::desc("Print the data in code table for Mach-O objects " - "(requires -macho)"), - cl::cat(MachOCat)); +static cl::opt<bool> ArchiveMemberOffsets( + "archive-member-offsets", + cl::desc("Print the offset to each archive member for Mach-O archives " + "(requires -macho and -archive-headers)"), + cl::cat(MachOCat)); -cl::opt<bool> LinkOptHints("link-opt-hints", - cl::desc("Print the linker optimization hints for " - "Mach-O objects (requires -macho)"), - cl::cat(MachOCat)); +cl::opt<bool> objdump::IndirectSymbols( + "indirect-symbols", + cl::desc( + "Print indirect symbol table for Mach-O objects (requires -macho)"), + cl::cat(MachOCat)); -cl::opt<bool> InfoPlist("info-plist", - cl::desc("Print the info plist section as strings for " - "Mach-O objects (requires -macho)"), - cl::cat(MachOCat)); +cl::opt<bool> objdump::DataInCode( + "data-in-code", + cl::desc( + "Print the data in code table for Mach-O objects (requires -macho)"), + cl::cat(MachOCat)); -cl::opt<bool> DylibsUsed("dylibs-used", - cl::desc("Print the shared libraries used for linked " - "Mach-O files (requires -macho)"), - cl::cat(MachOCat)); +cl::opt<bool> + objdump::LinkOptHints("link-opt-hints", + cl::desc("Print the linker optimization hints for " + "Mach-O objects (requires -macho)"), + cl::cat(MachOCat)); cl::opt<bool> - DylibId("dylib-id", - cl::desc("Print the shared library's id for the dylib Mach-O " - "file (requires -macho)"), - cl::cat(MachOCat)); + objdump::InfoPlist("info-plist", + cl::desc("Print the info plist section as strings for " + "Mach-O objects (requires -macho)"), + cl::cat(MachOCat)); cl::opt<bool> + objdump::DylibsUsed("dylibs-used", + cl::desc("Print the shared libraries used for linked " + "Mach-O files (requires -macho)"), + cl::cat(MachOCat)); + +cl::opt<bool> objdump::DylibId("dylib-id", + cl::desc("Print the shared library's id for the " + "dylib Mach-O file (requires -macho)"), + cl::cat(MachOCat)); + +static cl::opt<bool> NonVerbose("non-verbose", - cl::desc("Print the info for Mach-O objects in " - "non-verbose or numeric form (requires -macho)"), + cl::desc("Print the info for Mach-O objects in non-verbose or " + "numeric form (requires -macho)"), cl::cat(MachOCat)); cl::opt<bool> - ObjcMetaData("objc-meta-data", - cl::desc("Print the Objective-C runtime meta data for " - "Mach-O files (requires -macho)"), - cl::cat(MachOCat)); + objdump::ObjcMetaData("objc-meta-data", + cl::desc("Print the Objective-C runtime meta data " + "for Mach-O files (requires -macho)"), + cl::cat(MachOCat)); -cl::opt<std::string> DisSymName( +static cl::opt<std::string> DisSymName( "dis-symname", cl::desc("disassemble just this symbol's instructions (requires -macho)"), cl::cat(MachOCat)); @@ -191,7 +177,7 @@ static cl::list<std::string> ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), cl::ZeroOrMore, cl::cat(MachOCat)); -bool ArchAll = false; +static bool ArchAll = false; static std::string ThumbTripleName; @@ -233,6 +219,7 @@ static const Target *GetTarget(const MachOObjectFile *MachOObj, return nullptr; } +namespace { struct SymbolSorter { bool operator()(const SymbolRef &A, const SymbolRef &B) { Expected<SymbolRef::Type> ATypeOrErr = A.getType(); @@ -243,11 +230,14 @@ struct SymbolSorter { if (!BTypeOrErr) reportError(BTypeOrErr.takeError(), B.getObject()->getFileName()); SymbolRef::Type BType = *BTypeOrErr; - uint64_t AAddr = (AType != SymbolRef::ST_Function) ? 0 : A.getValue(); - uint64_t BAddr = (BType != SymbolRef::ST_Function) ? 0 : B.getValue(); + uint64_t AAddr = + (AType != SymbolRef::ST_Function) ? 0 : cantFail(A.getValue()); + uint64_t BAddr = + (BType != SymbolRef::ST_Function) ? 0 : cantFail(B.getValue()); return AAddr < BAddr; } }; +} // namespace // Types for the storted data in code table that is built before disassembly // and the predicate function to sort them. @@ -497,9 +487,9 @@ static void printRelocationTargetName(const MachOObjectFile *O, Fmt << S; } -Error getMachORelocationValueString(const MachOObjectFile *Obj, - const RelocationRef &RelRef, - SmallVectorImpl<char> &Result) { +Error objdump::getMachORelocationValueString(const MachOObjectFile *Obj, + const RelocationRef &RelRef, + SmallVectorImpl<char> &Result) { DataRefImpl Rel = RelRef.getRawDataRefImpl(); MachO::any_relocation_info RE = Obj->getRelocation(Rel); @@ -1279,7 +1269,7 @@ static void CreateSymbolAddressMap(MachOObjectFile *O, SymbolRef::Type ST = unwrapOrError(Symbol.getType(), FileName); if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data || ST == SymbolRef::ST_Other) { - uint64_t Address = Symbol.getValue(); + uint64_t Address = cantFail(Symbol.getValue()); StringRef SymName = unwrapOrError(Symbol.getName(), FileName); if (!SymName.startswith(".objc")) (*AddrMap)[Address] = SymName; @@ -1754,6 +1744,9 @@ static void DumpSectionContents(StringRef Filename, MachOObjectFile *O, else consumeError(SecNameOrErr.takeError()); + if (!DumpSection.empty()) + FoundSectionSet.insert(DumpSection); + DataRefImpl Ref = Section.getRawDataRefImpl(); StringRef SegName = O->getSectionFinalSegmentName(Ref); if ((DumpSegName.empty() || SegName == DumpSegName) && @@ -1776,8 +1769,9 @@ static void DumpSectionContents(StringRef Filename, MachOObjectFile *O, uint32_t sect_size = BytesStr.size(); uint64_t sect_addr = Section.getAddress(); - outs() << "Contents of (" << SegName << "," << SectName - << ") section\n"; + if (!NoLeadingHeaders) + outs() << "Contents of (" << SegName << "," << SectName + << ") section\n"; if (verbose) { if ((section_flags & MachO::S_ATTR_PURE_INSTRUCTIONS) || @@ -2318,7 +2312,7 @@ static bool ValidateArchFlags() { // -arch flags selecting just those slices as specified by them and also parses // archive files. Then for each individual Mach-O file ProcessMachO() is // called to process the file based on the command line options. -void parseInputMachO(StringRef Filename) { +void objdump::parseInputMachO(StringRef Filename) { if (!ValidateArchFlags()) return; @@ -2376,7 +2370,7 @@ void parseInputMachO(StringRef Filename) { llvm_unreachable("Input object can't be invalid at this point"); } -void parseInputMachO(MachOUniversalBinary *UB) { +void objdump::parseInputMachO(MachOUniversalBinary *UB) { if (!ValidateArchFlags()) return; @@ -2562,6 +2556,7 @@ void parseInputMachO(MachOUniversalBinary *UB) { } } +namespace { // The block of info used by the Symbolizer call backs. struct DisassembleInfo { DisassembleInfo(MachOObjectFile *O, SymbolAddressMap *AddrMap, @@ -2581,6 +2576,7 @@ struct DisassembleInfo { std::unique_ptr<SymbolAddressMap> bindtable; uint32_t depth = 0; }; +} // namespace // SymbolizerGetOpInfo() is the operand information call back function. // This is called to get the symbolic information for operand(s) of an @@ -3358,7 +3354,7 @@ static const char *get_symbol_64(uint32_t sect_offset, SectionRef S, // and return its name. const char *SymbolName = nullptr; if (reloc_found && isExtern) { - n_value = Symbol.getValue(); + n_value = cantFail(Symbol.getValue()); StringRef Name = unwrapOrError(Symbol.getName(), info->O->getFileName()); if (!Name.empty()) { SymbolName = Name.data(); @@ -3389,6 +3385,8 @@ static const char *get_symbol_32(uint32_t sect_offset, SectionRef S, return get_symbol_64(sect_offset, S, info, n_value64, ReferenceValue); } +namespace { + // These are structs in the Objective-C meta data and read to produce the // comments for disassembly. While these are part of the ABI they are no // public defintions. So the are here not in include/llvm/BinaryFormat/MachO.h @@ -3974,6 +3972,8 @@ inline void swapStruct(struct objc_method_description_t &md) { sys::swapByteOrder(md.types); } +} // namespace + static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue, struct DisassembleInfo *info); @@ -6473,7 +6473,7 @@ static void DumpProtocolSection(MachOObjectFile *O, const char *sect, } #ifdef HAVE_LIBXAR -inline void swapStruct(struct xar_header &xar) { +static inline void swapStruct(struct xar_header &xar) { sys::swapByteOrder(xar.magic); sys::swapByteOrder(xar.size); sys::swapByteOrder(xar.version); @@ -6910,7 +6910,7 @@ static const char *GuessLiteralPointer(uint64_t ReferenceValue, if (info->O->getAnyRelocationPCRel(RE)) { unsigned Type = info->O->getAnyRelocationType(RE); if (Type == MachO::X86_64_RELOC_SIGNED) { - ReferenceValue = Symbol.getValue(); + ReferenceValue = cantFail(Symbol.getValue()); } } } @@ -7346,7 +7346,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, SmallString<1024> FullPath(DSYMPath); llvm::sys::path::append(FullPath, "Contents", "Resources", "DWARF", ShortName); - DSYMPath = FullPath.str(); + DSYMPath = std::string(FullPath.str()); } // Load the file. @@ -7451,7 +7451,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, unwrapOrError(Symbol.getType(), MachOOF->getFileName()); if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data || ST == SymbolRef::ST_Other) { - uint64_t Address = Symbol.getValue(); + uint64_t Address = cantFail(Symbol.getValue()); StringRef SymName = unwrapOrError(Symbol.getName(), MachOOF->getFileName()); AddrMap[Address] = SymName; @@ -7530,7 +7530,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, // Start at the address of the symbol relative to the section's address. uint64_t SectSize = Sections[SectIdx].getSize(); - uint64_t Start = Symbols[SymIdx].getValue(); + uint64_t Start = cantFail(Symbols[SymIdx].getValue()); uint64_t SectionAddress = Sections[SectIdx].getAddress(); Start -= SectionAddress; @@ -7551,7 +7551,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, if (NextSymType == SymbolRef::ST_Function) { containsNextSym = Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]); - NextSym = Symbols[NextSymIdx].getValue(); + NextSym = cantFail(Symbols[NextSymIdx].getValue()); NextSym -= SectionAddress; break; } @@ -7564,7 +7564,8 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, symbolTableWorked = true; DataRefImpl Symb = Symbols[SymIdx].getRawDataRefImpl(); - bool IsThumb = MachOOF->getSymbolFlags(Symb) & SymbolRef::SF_Thumb; + uint32_t SymbolFlags = cantFail(MachOOF->getSymbolFlags(Symb)); + bool IsThumb = SymbolFlags & SymbolRef::SF_Thumb; // We only need the dedicated Thumb target if there's a real choice // (i.e. we're not targeting M-class) and the function is Thumb. @@ -8194,7 +8195,7 @@ static void printMachOUnwindInfoSection(const MachOObjectFile *Obj, } } -void printMachOUnwindInfo(const MachOObjectFile *Obj) { +void objdump::printMachOUnwindInfo(const MachOObjectFile *Obj) { std::map<uint64_t, SymbolRef> Symbols; for (const SymbolRef &SymRef : Obj->symbols()) { // Discard any undefined or absolute symbols. They're not going to take part @@ -8209,7 +8210,7 @@ void printMachOUnwindInfo(const MachOObjectFile *Obj) { if (Section == Obj->section_end()) continue; - uint64_t Addr = SymRef.getValue(); + uint64_t Addr = cantFail(SymRef.getValue()); Symbols.insert(std::make_pair(Addr, SymRef)); } @@ -10202,12 +10203,12 @@ static void PrintMachHeader(const MachOObjectFile *Obj, bool verbose) { } } -void printMachOFileHeader(const object::ObjectFile *Obj) { +void objdump::printMachOFileHeader(const object::ObjectFile *Obj) { const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj); PrintMachHeader(file, !NonVerbose); } -void printMachOLoadCommands(const object::ObjectFile *Obj) { +void objdump::printMachOLoadCommands(const object::ObjectFile *Obj) { const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj); uint32_t filetype = 0; uint32_t cputype = 0; @@ -10229,7 +10230,7 @@ void printMachOLoadCommands(const object::ObjectFile *Obj) { // export trie dumping //===----------------------------------------------------------------------===// -void printMachOExportsTrie(const object::MachOObjectFile *Obj) { +static void printMachOExportsTrie(const object::MachOObjectFile *Obj) { uint64_t BaseSegmentAddress = 0; for (const auto &Command : Obj->load_commands()) { if (Command.C.cmd == MachO::LC_SEGMENT) { @@ -10308,7 +10309,7 @@ void printMachOExportsTrie(const object::MachOObjectFile *Obj) { // rebase table dumping //===----------------------------------------------------------------------===// -void printMachORebaseTable(object::MachOObjectFile *Obj) { +static void printMachORebaseTable(object::MachOObjectFile *Obj) { outs() << "segment section address type\n"; Error Err = Error::success(); for (const object::MachORebaseEntry &Entry : Obj->rebaseTable(Err)) { @@ -10350,7 +10351,7 @@ static StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) { // bind table dumping //===----------------------------------------------------------------------===// -void printMachOBindTable(object::MachOObjectFile *Obj) { +static void printMachOBindTable(object::MachOObjectFile *Obj) { // Build table of sections so names can used in final output. outs() << "segment section address type " "addend dylib symbol\n"; @@ -10381,7 +10382,7 @@ void printMachOBindTable(object::MachOObjectFile *Obj) { // lazy bind table dumping //===----------------------------------------------------------------------===// -void printMachOLazyBindTable(object::MachOObjectFile *Obj) { +static void printMachOLazyBindTable(object::MachOObjectFile *Obj) { outs() << "segment section address " "dylib symbol\n"; Error Err = Error::success(); @@ -10406,7 +10407,7 @@ void printMachOLazyBindTable(object::MachOObjectFile *Obj) { // weak bind table dumping //===----------------------------------------------------------------------===// -void printMachOWeakBindTable(object::MachOObjectFile *Obj) { +static void printMachOWeakBindTable(object::MachOObjectFile *Obj) { outs() << "segment section address " "type addend symbol\n"; Error Err = Error::success(); @@ -10456,7 +10457,7 @@ static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue, return !name.empty() ? name.data() : nullptr; } -void printLazyBindTable(ObjectFile *o) { +void objdump::printLazyBindTable(ObjectFile *o) { outs() << "Lazy bind table:\n"; if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o)) printMachOLazyBindTable(MachO); @@ -10466,7 +10467,7 @@ void printLazyBindTable(ObjectFile *o) { "for Mach-O executable files.\n"; } -void printWeakBindTable(ObjectFile *o) { +void objdump::printWeakBindTable(ObjectFile *o) { outs() << "Weak bind table:\n"; if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o)) printMachOWeakBindTable(MachO); @@ -10476,7 +10477,7 @@ void printWeakBindTable(ObjectFile *o) { "for Mach-O executable files.\n"; } -void printExportsTrie(const ObjectFile *o) { +void objdump::printExportsTrie(const ObjectFile *o) { outs() << "Exports trie:\n"; if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o)) printMachOExportsTrie(MachO); @@ -10486,7 +10487,7 @@ void printExportsTrie(const ObjectFile *o) { "for Mach-O executable files.\n"; } -void printRebaseTable(ObjectFile *o) { +void objdump::printRebaseTable(ObjectFile *o) { outs() << "Rebase table:\n"; if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o)) printMachORebaseTable(MachO); @@ -10496,7 +10497,7 @@ void printRebaseTable(ObjectFile *o) { "for Mach-O executable files.\n"; } -void printBindTable(ObjectFile *o) { +void objdump::printBindTable(ObjectFile *o) { outs() << "Bind table:\n"; if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o)) printMachOBindTable(MachO); @@ -10505,4 +10506,3 @@ void printBindTable(ObjectFile *o) { << "This operation is only currently supported " "for Mach-O executable files.\n"; } -} // namespace llvm |