diff options
Diffstat (limited to 'gnu/llvm/tools/llvm-objdump/MachODump.cpp')
| -rw-r--r-- | gnu/llvm/tools/llvm-objdump/MachODump.cpp | 680 |
1 files changed, 364 insertions, 316 deletions
diff --git a/gnu/llvm/tools/llvm-objdump/MachODump.cpp b/gnu/llvm/tools/llvm-objdump/MachODump.cpp index 4d950f1d7bd..563084856f6 100644 --- a/gnu/llvm/tools/llvm-objdump/MachODump.cpp +++ b/gnu/llvm/tools/llvm-objdump/MachODump.cpp @@ -20,6 +20,7 @@ #include "llvm/Config/config.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/Demangle/Demangle.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" @@ -48,10 +49,6 @@ #include <cstring> #include <system_error> -#if HAVE_CXXABI_H -#include <cxxabi.h> -#endif - #ifdef HAVE_LIBXAR extern "C" { #include <xar/xar.h> @@ -74,6 +71,9 @@ static cl::opt<bool> FullLeadingAddr("full-leading-addr", static cl::opt<bool> NoLeadingAddr("no-leading-addr", cl::desc("Print no leading address")); +static cl::opt<bool> NoLeadingHeaders("no-leading-headers", + cl::desc("Print no leading headers")); + cl::opt<bool> llvm::UniversalHeaders("universal-headers", cl::desc("Print Mach-O universal headers " "(requires -macho)")); @@ -131,7 +131,7 @@ cl::opt<bool> cl::opt<std::string> llvm::DisSymName( "dis-symname", - cl::desc("disassemble just this symbol's instructions (requires -macho")); + cl::desc("disassemble just this symbol's instructions (requires -macho)")); static cl::opt<bool> NoSymbolicOperands( "no-symbolic-operands", @@ -186,22 +186,12 @@ static const Target *GetTarget(const MachOObjectFile *MachOObj, struct SymbolSorter { bool operator()(const SymbolRef &A, const SymbolRef &B) { Expected<SymbolRef::Type> ATypeOrErr = A.getType(); - if (!ATypeOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(ATypeOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!ATypeOrErr) + report_error(A.getObject()->getFileName(), ATypeOrErr.takeError()); SymbolRef::Type AType = *ATypeOrErr; Expected<SymbolRef::Type> BTypeOrErr = B.getType(); - if (!BTypeOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(BTypeOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!BTypeOrErr) + report_error(B.getObject()->getFileName(), BTypeOrErr.takeError()); SymbolRef::Type BType = *BTypeOrErr; uint64_t AAddr = (AType != SymbolRef::ST_Function) ? 0 : A.getValue(); uint64_t BAddr = (BType != SymbolRef::ST_Function) ? 0 : B.getValue(); @@ -298,13 +288,8 @@ static void getSectionsAndSymbols(MachOObjectFile *MachOObj, uint64_t &BaseSegmentAddress) { for (const SymbolRef &Symbol : MachOObj->symbols()) { Expected<StringRef> SymName = Symbol.getName(); - if (!SymName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymName) + report_error(MachOObj->getFileName(), SymName.takeError()); if (!SymName->startswith("ltmp")) Symbols.push_back(Symbol); } @@ -383,13 +368,8 @@ static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose, symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol); SymbolRef Symbol = *Sym; Expected<StringRef> SymName = Symbol.getName(); - if (!SymName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymName) + report_error(O->getFileName(), SymName.takeError()); outs() << *SymName; } else { outs() << "?"; @@ -615,25 +595,15 @@ static void CreateSymbolAddressMap(MachOObjectFile *O, // Create a map of symbol addresses to symbol names. for (const SymbolRef &Symbol : O->symbols()) { Expected<SymbolRef::Type> STOrErr = Symbol.getType(); - if (!STOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(STOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!STOrErr) + report_error(O->getFileName(), STOrErr.takeError()); SymbolRef::Type ST = *STOrErr; if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data || ST == SymbolRef::ST_Other) { uint64_t Address = Symbol.getValue(); Expected<StringRef> SymNameOrErr = Symbol.getName(); - if (!SymNameOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymNameOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymNameOrErr) + report_error(O->getFileName(), SymNameOrErr.takeError()); StringRef SymName = *SymNameOrErr; if (!SymName.startswith(".objc")) (*AddrMap)[Address] = SymName; @@ -862,29 +832,22 @@ static void DumpLiteralPointerSection(MachOObjectFile *O, } // First look for an external relocation entry for this literal pointer. - auto Reloc = std::find_if( - Relocs.begin(), Relocs.end(), - [&](const std::pair<uint64_t, SymbolRef> &P) { return P.first == i; }); + auto Reloc = find_if(Relocs, [&](const std::pair<uint64_t, SymbolRef> &P) { + return P.first == i; + }); if (Reloc != Relocs.end()) { symbol_iterator RelocSym = Reloc->second; Expected<StringRef> SymName = RelocSym->getName(); - if (!SymName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymName) + report_error(O->getFileName(), SymName.takeError()); outs() << "external relocation entry for symbol:" << *SymName << "\n"; continue; } // For local references see what the section the literal pointer points to. - auto Sect = std::find_if(LiteralSections.begin(), LiteralSections.end(), - [&](const SectionRef &R) { - return lp >= R.getAddress() && - lp < R.getAddress() + R.getSize(); - }); + auto Sect = find_if(LiteralSections, [&](const SectionRef &R) { + return lp >= R.getAddress() && lp < R.getAddress() + R.getSize(); + }); if (Sect == LiteralSections.end()) { outs() << format("0x%" PRIx64, lp) << " (not in a literal section)\n"; continue; @@ -1191,30 +1154,30 @@ static void DumpInfoPlistSectionContents(StringRef Filename, // architectures were specified. If not then an error is generated and this // routine returns false. Else it returns true. static bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) { - if (isa<MachOObjectFile>(O) && !ArchAll && ArchFlags.size() != 0) { - MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O); - bool ArchFound = false; - MachO::mach_header H; - MachO::mach_header_64 H_64; - Triple T; - if (MachO->is64Bit()) { - H_64 = MachO->MachOObjectFile::getHeader64(); - T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype); - } else { - H = MachO->MachOObjectFile::getHeader(); - T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype); - } - unsigned i; - for (i = 0; i < ArchFlags.size(); ++i) { - if (ArchFlags[i] == T.getArchName()) - ArchFound = true; - break; - } - if (!ArchFound) { - errs() << "llvm-objdump: file: " + Filename + " does not contain " - << "architecture: " + ArchFlags[i] + "\n"; - return false; - } + auto *MachO = dyn_cast<MachOObjectFile>(O); + + if (!MachO || ArchAll || ArchFlags.empty()) + return true; + + MachO::mach_header H; + MachO::mach_header_64 H_64; + Triple T; + const char *McpuDefault, *ArchFlag; + if (MachO->is64Bit()) { + H_64 = MachO->MachOObjectFile::getHeader64(); + T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype, + &McpuDefault, &ArchFlag); + } else { + H = MachO->MachOObjectFile::getHeader(); + T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype, + &McpuDefault, &ArchFlag); + } + const std::string ArchFlagName(ArchFlag); + if (none_of(ArchFlags, [&](const std::string &Name) { + return Name == ArchFlagName; + })) { + errs() << "llvm-objdump: " + Filename + ": No architecture specified.\n"; + return false; } return true; } @@ -1225,7 +1188,7 @@ static void printObjcMetaData(MachOObjectFile *O, bool verbose); // archive member and or in a slice of a universal file. It prints the // the file name and header info and then processes it according to the // command line options. -static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF, +static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF, StringRef ArchiveMemberName = StringRef(), StringRef ArchitectureName = StringRef()) { // If we are doing some processing here on the Mach-O file print the header @@ -1234,16 +1197,37 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF, if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind || SymbolTable || LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints || DylibsUsed || DylibId || ObjcMetaData || (FilterSections.size() != 0)) { - outs() << Filename; - if (!ArchiveMemberName.empty()) - outs() << '(' << ArchiveMemberName << ')'; - if (!ArchitectureName.empty()) - outs() << " (architecture " << ArchitectureName << ")"; - outs() << ":\n"; + if (!NoLeadingHeaders) { + outs() << Name; + if (!ArchiveMemberName.empty()) + outs() << '(' << ArchiveMemberName << ')'; + if (!ArchitectureName.empty()) + outs() << " (architecture " << ArchitectureName << ")"; + outs() << ":\n"; + } + } + // To use the report_error() form with an ArchiveName and FileName set + // these up based on what is passed for Name and ArchiveMemberName. + StringRef ArchiveName; + StringRef FileName; + if (!ArchiveMemberName.empty()) { + ArchiveName = Name; + FileName = ArchiveMemberName; + } else { + ArchiveName = StringRef(); + FileName = Name; } + // If we need the symbol table to do the operation then check it here to + // produce a good error message as to where the Mach-O file comes from in + // the error message. + if (Disassemble || IndirectSymbols || FilterSections.size() != 0 || + UnwindInfo) + if (Error Err = MachOOF->checkSymbolTable()) + report_error(ArchiveName, FileName, std::move(Err), ArchitectureName); + if (Disassemble) - DisassembleMachO(Filename, MachOOF, "__TEXT", "__text"); + DisassembleMachO(FileName, MachOOF, "__TEXT", "__text"); if (IndirectSymbols) PrintIndirectSymbols(MachOOF, !NonVerbose); if (DataInCode) @@ -1257,17 +1241,15 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF, if (SectionContents) PrintSectionContents(MachOOF); if (FilterSections.size() != 0) - DumpSectionContents(Filename, MachOOF, !NonVerbose); + DumpSectionContents(FileName, MachOOF, !NonVerbose); if (InfoPlist) - DumpInfoPlistSectionContents(Filename, MachOOF); + DumpInfoPlistSectionContents(FileName, MachOOF); if (DylibsUsed) PrintDylibs(MachOOF, false); if (DylibId) PrintDylibs(MachOOF, true); - if (SymbolTable) { - StringRef ArchiveName = ArchiveMemberName == StringRef() ? "" : Filename; + if (SymbolTable) PrintSymbolTable(MachOOF, ArchiveName, ArchitectureName); - } if (UnwindInfo) printMachOUnwindInfo(MachOOF); if (PrivateHeaders) { @@ -1441,7 +1423,7 @@ static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB, } } if (verbose) { - outs() << OFA.getArchTypeName() << "\n"; + outs() << OFA.getArchFlagName() << "\n"; printCPUType(cputype, cpusubtype & ~MachO::CPU_SUBTYPE_MASK); } else { outs() << i << "\n"; @@ -1472,11 +1454,15 @@ static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB, } } -static void printArchiveChild(const Archive::Child &C, bool verbose, - bool print_offset) { +static void printArchiveChild(StringRef Filename, const Archive::Child &C, + bool verbose, bool print_offset, + StringRef ArchitectureName = StringRef()) { if (print_offset) outs() << C.getChildOffset() << "\t"; - sys::fs::perms Mode = C.getAccessMode(); + Expected<sys::fs::perms> ModeOrErr = C.getAccessMode(); + if (!ModeOrErr) + report_error(Filename, C, ModeOrErr.takeError(), ArchitectureName); + sys::fs::perms Mode = ModeOrErr.get(); if (verbose) { // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG. // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG. @@ -1494,20 +1480,27 @@ static void printArchiveChild(const Archive::Child &C, bool verbose, outs() << format("0%o ", Mode); } - unsigned UID = C.getUID(); + Expected<unsigned> UIDOrErr = C.getUID(); + if (!UIDOrErr) + report_error(Filename, C, UIDOrErr.takeError(), ArchitectureName); + unsigned UID = UIDOrErr.get(); outs() << format("%3d/", UID); - unsigned GID = C.getGID(); + Expected<unsigned> GIDOrErr = C.getGID(); + if (!GIDOrErr) + report_error(Filename, C, GIDOrErr.takeError(), ArchitectureName); + unsigned GID = GIDOrErr.get(); outs() << format("%-3d ", GID); - ErrorOr<uint64_t> Size = C.getRawSize(); - if (std::error_code EC = Size.getError()) - report_fatal_error(EC.message()); + Expected<uint64_t> Size = C.getRawSize(); + if (!Size) + report_error(Filename, C, Size.takeError(), ArchitectureName); outs() << format("%5" PRId64, Size.get()) << " "; StringRef RawLastModified = C.getRawLastModified(); if (verbose) { unsigned Seconds; if (RawLastModified.getAsInteger(10, Seconds)) - outs() << "(date: \"%s\" contains non-decimal chars) " << RawLastModified; + outs() << "(date: \"" << RawLastModified + << "\" contains non-decimal chars) "; else { // Since cime(3) returns a 26 character string of the form: // "Sun Sep 16 01:03:52 1973\n\0" @@ -1520,26 +1513,37 @@ static void printArchiveChild(const Archive::Child &C, bool verbose, } if (verbose) { - ErrorOr<StringRef> NameOrErr = C.getName(); - if (NameOrErr.getError()) { - StringRef RawName = C.getRawName(); + Expected<StringRef> NameOrErr = C.getName(); + if (!NameOrErr) { + consumeError(NameOrErr.takeError()); + Expected<StringRef> NameOrErr = C.getRawName(); + if (!NameOrErr) + report_error(Filename, C, NameOrErr.takeError(), ArchitectureName); + StringRef RawName = NameOrErr.get(); outs() << RawName << "\n"; } else { StringRef Name = NameOrErr.get(); outs() << Name << "\n"; } } else { - StringRef RawName = C.getRawName(); + Expected<StringRef> NameOrErr = C.getRawName(); + if (!NameOrErr) + report_error(Filename, C, NameOrErr.takeError(), ArchitectureName); + StringRef RawName = NameOrErr.get(); outs() << RawName << "\n"; } } -static void printArchiveHeaders(Archive *A, bool verbose, bool print_offset) { - Error Err; +static void printArchiveHeaders(StringRef Filename, Archive *A, bool verbose, + bool print_offset, + StringRef ArchitectureName = StringRef()) { + Error Err = Error::success(); + ; for (const auto &C : A->children(Err, false)) - printArchiveChild(C, verbose, print_offset); + printArchiveChild(Filename, C, verbose, print_offset, ArchitectureName); + if (Err) - report_fatal_error(std::move(Err)); + report_error(StringRef(), Filename, std::move(Err), ArchitectureName); } // ParseInputMachO() parses the named Mach-O file in Filename and handles the @@ -1569,8 +1573,9 @@ void llvm::ParseInputMachO(StringRef Filename) { if (Archive *A = dyn_cast<Archive>(&Bin)) { outs() << "Archive : " << Filename << "\n"; if (ArchiveHeaders) - printArchiveHeaders(A, !NonVerbose, ArchiveMemberOffsets); - Error Err; + printArchiveHeaders(Filename, A, !NonVerbose, ArchiveMemberOffsets); + + Error Err = Error::success(); for (auto &C : A->children(Err)) { Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(); if (!ChildOrErr) { @@ -1602,13 +1607,13 @@ void llvm::ParseInputMachO(StringRef Filename) { for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { - if (ArchFlags[i] == I->getArchTypeName()) { + if (ArchFlags[i] == I->getArchFlagName()) { ArchFound = true; Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); std::string ArchitectureName = ""; if (ArchFlags.size() > 1) - ArchitectureName = I->getArchTypeName(); + ArchitectureName = I->getArchFlagName(); if (ObjOrErr) { ObjectFile &O = *ObjOrErr.get(); if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O)) @@ -1626,8 +1631,9 @@ void llvm::ParseInputMachO(StringRef Filename) { outs() << " (architecture " << ArchitectureName << ")"; outs() << "\n"; if (ArchiveHeaders) - printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets); - Error Err; + printArchiveHeaders(Filename, A.get(), !NonVerbose, + ArchiveMemberOffsets, ArchitectureName); + Error Err = Error::success(); for (auto &C : A->children(Err)) { Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(); if (!ChildOrErr) { @@ -1644,7 +1650,7 @@ void llvm::ParseInputMachO(StringRef Filename) { } else { consumeError(AOrErr.takeError()); error("Mach-O universal file: " + Filename + " for " + - "architecture " + StringRef(I->getArchTypeName()) + + "architecture " + StringRef(I->getArchFlagName()) + " is not a Mach-O file or an archive file"); } } @@ -1664,7 +1670,7 @@ void llvm::ParseInputMachO(StringRef Filename) { E = UB->end_objects(); I != E; ++I) { if (MachOObjectFile::getHostArch().getArchName() == - I->getArchTypeName()) { + I->getArchFlagName()) { Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; ArchiveName.clear(); @@ -1681,8 +1687,9 @@ void llvm::ParseInputMachO(StringRef Filename) { std::unique_ptr<Archive> &A = *AOrErr; outs() << "Archive : " << Filename << "\n"; if (ArchiveHeaders) - printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets); - Error Err; + printArchiveHeaders(Filename, A.get(), !NonVerbose, + ArchiveMemberOffsets); + Error Err = Error::success(); for (auto &C : A->children(Err)) { Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(); if (!ChildOrErr) { @@ -1699,7 +1706,7 @@ void llvm::ParseInputMachO(StringRef Filename) { } else { consumeError(AOrErr.takeError()); error("Mach-O universal file: " + Filename + " for architecture " + - StringRef(I->getArchTypeName()) + + StringRef(I->getArchFlagName()) + " is not a Mach-O file or an archive file"); } return; @@ -1715,7 +1722,7 @@ void llvm::ParseInputMachO(StringRef Filename) { Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); std::string ArchitectureName = ""; if (moreThanOneArch) - ArchitectureName = I->getArchTypeName(); + ArchitectureName = I->getArchFlagName(); if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj)) @@ -1732,8 +1739,9 @@ void llvm::ParseInputMachO(StringRef Filename) { outs() << " (architecture " << ArchitectureName << ")"; outs() << "\n"; if (ArchiveHeaders) - printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets); - Error Err; + printArchiveHeaders(Filename, A.get(), !NonVerbose, + ArchiveMemberOffsets, ArchitectureName); + Error Err = Error::success(); for (auto &C : A->children(Err)) { Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(); if (!ChildOrErr) { @@ -1753,7 +1761,7 @@ void llvm::ParseInputMachO(StringRef Filename) { } else { consumeError(AOrErr.takeError()); error("Mach-O universal file: " + Filename + " for architecture " + - StringRef(I->getArchTypeName()) + + StringRef(I->getArchFlagName()) + " is not a Mach-O file or an archive file"); } } @@ -1772,10 +1780,6 @@ void llvm::ParseInputMachO(StringRef Filename) { llvm_unreachable("Input object can't be invalid at this point"); } -typedef std::pair<uint64_t, const char *> BindInfoEntry; -typedef std::vector<BindInfoEntry> BindTable; -typedef BindTable::iterator bind_table_iterator; - // The block of info used by the Symbolizer call backs. struct DisassembleInfo { bool verbose; @@ -1789,7 +1793,7 @@ struct DisassembleInfo { char *demangled_name; uint64_t adrp_addr; uint32_t adrp_inst; - BindTable *bindtable; + std::unique_ptr<SymbolAddressMap> bindtable; uint32_t depth; }; @@ -1879,13 +1883,8 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, } if (reloc_found && isExtern) { Expected<StringRef> SymName = Symbol.getName(); - if (!SymName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymName) + report_error(info->O->getFileName(), SymName.takeError()); const char *name = SymName->data(); op_info->AddSymbol.Present = 1; op_info->AddSymbol.Name = name; @@ -1954,13 +1953,8 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, if (info->O->getAnyRelocationPCRel(RE)) op_info->Value -= Pc + Offset + Size; Expected<StringRef> SymName = Symbol.getName(); - if (!SymName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymName) + report_error(info->O->getFileName(), SymName.takeError()); const char *name = SymName->data(); unsigned Type = info->O->getAnyRelocationType(RE); if (Type == MachO::X86_64_RELOC_SUBTRACTOR) { @@ -1976,13 +1970,8 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum); Symbol = *RelocSymNext; Expected<StringRef> SymNameNext = Symbol.getName(); - if (!SymNameNext) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymNameNext.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymNameNext) + report_error(info->O->getFileName(), SymNameNext.takeError()); name = SymNameNext->data(); } } @@ -2015,11 +2004,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, bool r_scattered = false; uint32_t r_value, pair_r_value, r_type, r_length, other_half; auto Reloc = - std::find_if(info->S.relocations().begin(), info->S.relocations().end(), - [&](const RelocationRef &Reloc) { - uint64_t RelocOffset = Reloc.getOffset(); - return RelocOffset == sect_offset; - }); + find_if(info->S.relocations(), [&](const RelocationRef &Reloc) { + uint64_t RelocOffset = Reloc.getOffset(); + return RelocOffset == sect_offset; + }); if (Reloc == info->S.relocations().end()) return 0; @@ -2054,13 +2042,8 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, if (isExtern) { Expected<StringRef> SymName = Symbol.getName(); - if (!SymName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymName) + report_error(info->O->getFileName(), SymName.takeError()); const char *name = SymName->data(); op_info->AddSymbol.Present = 1; op_info->AddSymbol.Name = name; @@ -2082,7 +2065,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, // If we have a branch that is not an external relocation entry then // return 0 so the code in tryAddingSymbolicOperand() can use the // SymbolLookUp call back with the branch target address to look up the - // symbol and possiblity add an annotation for a symbol stub. + // symbol and possibility add an annotation for a symbol stub. if (isExtern == 0 && (r_type == MachO::ARM_RELOC_BR24 || r_type == MachO::ARM_THUMB_RELOC_BR22)) return 0; @@ -2154,11 +2137,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, uint64_t sect_addr = info->S.getAddress(); uint64_t sect_offset = (Pc + Offset) - sect_addr; auto Reloc = - std::find_if(info->S.relocations().begin(), info->S.relocations().end(), - [&](const RelocationRef &Reloc) { - uint64_t RelocOffset = Reloc.getOffset(); - return RelocOffset == sect_offset; - }); + find_if(info->S.relocations(), [&](const RelocationRef &Reloc) { + uint64_t RelocOffset = Reloc.getOffset(); + return RelocOffset == sect_offset; + }); if (Reloc == info->S.relocations().end()) return 0; @@ -2179,13 +2161,8 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, if (!info->O->getPlainRelocationExternal(RE)) return 0; Expected<StringRef> SymName = Reloc->getSymbol()->getName(); - if (!SymName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymName) + report_error(info->O->getFileName(), SymName.takeError()); const char *name = SymName->data(); op_info->AddSymbol.Present = 1; op_info->AddSymbol.Name = name; @@ -2314,13 +2291,8 @@ static const char *GuessIndirectSymbol(uint64_t ReferenceValue, symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol); SymbolRef Symbol = *Sym; Expected<StringRef> SymName = Symbol.getName(); - if (!SymName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymName) + report_error(info->O->getFileName(), SymName.takeError()); const char *name = SymName->data(); return name; } @@ -2354,13 +2326,8 @@ static const char *GuessIndirectSymbol(uint64_t ReferenceValue, symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol); SymbolRef Symbol = *Sym; Expected<StringRef> SymName = Symbol.getName(); - if (!SymName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymName) + report_error(info->O->getFileName(), SymName.takeError()); const char *name = SymName->data(); return name; } @@ -2588,13 +2555,8 @@ static const char *get_symbol_64(uint32_t sect_offset, SectionRef S, if (reloc_found && isExtern) { n_value = Symbol.getValue(); Expected<StringRef> NameOrError = Symbol.getName(); - if (!NameOrError) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(NameOrError.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!NameOrError) + report_error(info->O->getFileName(), NameOrError.takeError()); StringRef Name = *NameOrError; if (!Name.empty()) { SymbolName = Name.data(); @@ -4391,12 +4353,7 @@ static bool print_class_ro64_t(uint64_t p, struct DisassembleInfo *info, r = get_pointer_64(p, offset, left, S, info); if (r == nullptr || left < sizeof(struct class_ro64_t)) return false; - memset(&cro, '\0', sizeof(struct class_ro64_t)); - if (left < sizeof(struct class_ro64_t)) { - memcpy(&cro, r, left); - outs() << " (class_ro_t entends past the end of the section)\n"; - } else - memcpy(&cro, r, sizeof(struct class_ro64_t)); + memcpy(&cro, r, sizeof(struct class_ro64_t)); if (info->O->isLittleEndian() != sys::IsLittleEndianHost) swapStruct(cro); outs() << " flags " << format("0x%" PRIx32, cro.flags); @@ -4593,12 +4550,7 @@ static void print_class64_t(uint64_t p, struct DisassembleInfo *info) { r = get_pointer_64(p, offset, left, S, info); if (r == nullptr || left < sizeof(struct class64_t)) return; - memset(&c, '\0', sizeof(struct class64_t)); - if (left < sizeof(struct class64_t)) { - memcpy(&c, r, left); - outs() << " (class_t entends past the end of the section)\n"; - } else - memcpy(&c, r, sizeof(struct class64_t)); + memcpy(&c, r, sizeof(struct class64_t)); if (info->O->isLittleEndian() != sys::IsLittleEndianHost) swapStruct(c); @@ -5355,9 +5307,6 @@ static void printObjc2_64bit_MetaData(MachOObjectFile *O, bool verbose) { II = get_section(O, "__DATA", "__objc_imageinfo"); info.S = II; print_image_info64(II, &info); - - if (info.bindtable != nullptr) - delete info.bindtable; } static void printObjc2_32bit_MetaData(MachOObjectFile *O, bool verbose) { @@ -6214,11 +6163,9 @@ static const char *GuessLiteralPointer(uint64_t ReferenceValue, // Out type and the ReferenceName will also be set which is added as a comment // to the disassembled instruction. // -#if HAVE_CXXABI_H // If the symbol name is a C++ mangled name then the demangled name is // returned through ReferenceName and ReferenceType is set to // LLVMDisassembler_ReferenceType_DeMangled_Name . -#endif // // When this is called to get a symbol name for a branch target then the // ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then @@ -6253,21 +6200,18 @@ static const char *SymbolizerSymbolLookUp(void *DisInfo, method_reference(info, ReferenceType, ReferenceName); if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message) *ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub; - } else -#if HAVE_CXXABI_H - if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) { + } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) { if (info->demangled_name != nullptr) free(info->demangled_name); int status; info->demangled_name = - abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status); + itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status); if (info->demangled_name != nullptr) { *ReferenceName = info->demangled_name; *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name; } else *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None; } else -#endif *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None; } else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) { *ReferenceName = @@ -6356,20 +6300,17 @@ static const char *SymbolizerSymbolLookUp(void *DisInfo, GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info); if (*ReferenceName == nullptr) *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None; - } -#if HAVE_CXXABI_H - else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) { + } else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) { if (info->demangled_name != nullptr) free(info->demangled_name); int status; info->demangled_name = - abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status); + itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status); if (info->demangled_name != nullptr) { *ReferenceName = info->demangled_name; *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name; } } -#endif else { *ReferenceName = nullptr; *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None; @@ -6387,7 +6328,7 @@ static void emitComments(raw_svector_ostream &CommentStream, // Flush the stream before taking its content. StringRef Comments = CommentsToEmit.str(); // Get the default information for printing a comment. - const char *CommentBegin = MAI.getCommentString(); + StringRef CommentBegin = MAI.getCommentString(); unsigned CommentColumn = MAI.getCommentColumn(); bool IsFirst = true; while (!Comments.empty()) { @@ -6604,25 +6545,15 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, bool DisSymNameFound = false; for (const SymbolRef &Symbol : MachOOF->symbols()) { Expected<SymbolRef::Type> STOrErr = Symbol.getType(); - if (!STOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(STOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!STOrErr) + report_error(MachOOF->getFileName(), STOrErr.takeError()); SymbolRef::Type ST = *STOrErr; if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data || ST == SymbolRef::ST_Other) { uint64_t Address = Symbol.getValue(); Expected<StringRef> SymNameOrErr = Symbol.getName(); - if (!SymNameOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymNameOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymNameOrErr) + report_error(MachOOF->getFileName(), SymNameOrErr.takeError()); StringRef SymName = *SymNameOrErr; AddrMap[Address] = SymName; if (!DisSymName.empty() && DisSymName == SymName) @@ -6669,23 +6600,13 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, // Disassemble symbol by symbol. for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) { Expected<StringRef> SymNameOrErr = Symbols[SymIdx].getName(); - if (!SymNameOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymNameOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SymNameOrErr) + report_error(MachOOF->getFileName(), SymNameOrErr.takeError()); StringRef SymName = *SymNameOrErr; Expected<SymbolRef::Type> STOrErr = Symbols[SymIdx].getType(); - if (!STOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(STOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!STOrErr) + report_error(MachOOF->getFileName(), STOrErr.takeError()); SymbolRef::Type ST = *STOrErr; if (ST != SymbolRef::ST_Function && ST != SymbolRef::ST_Data) continue; @@ -6740,13 +6661,8 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, uint64_t NextSymIdx = SymIdx + 1; while (Symbols.size() > NextSymIdx) { Expected<SymbolRef::Type> STOrErr = Symbols[NextSymIdx].getType(); - if (!STOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(STOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!STOrErr) + report_error(MachOOF->getFileName(), STOrErr.takeError()); SymbolRef::Type NextSymType = *STOrErr; if (NextSymType == SymbolRef::ST_Function) { containsNextSym = @@ -6918,14 +6834,10 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, free(SymbolizerInfo.method); if (SymbolizerInfo.demangled_name != nullptr) free(SymbolizerInfo.demangled_name); - if (SymbolizerInfo.bindtable != nullptr) - delete SymbolizerInfo.bindtable; if (ThumbSymbolizerInfo.method != nullptr) free(ThumbSymbolizerInfo.method); if (ThumbSymbolizerInfo.demangled_name != nullptr) free(ThumbSymbolizerInfo.demangled_name); - if (ThumbSymbolizerInfo.bindtable != nullptr) - delete ThumbSymbolizerInfo.bindtable; } } @@ -6992,13 +6904,8 @@ static void findUnwindRelocNameAddend(const MachOObjectFile *Obj, StringRef &Name, uint64_t &Addend) { if (Reloc.getSymbol() != Obj->symbol_end()) { Expected<StringRef> NameOrErr = Reloc.getSymbol()->getName(); - if (!NameOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(NameOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!NameOrErr) + report_error(Obj->getFileName(), NameOrErr.takeError()); Name = *NameOrErr; Addend = Addr; return; @@ -7022,24 +6929,14 @@ static void findUnwindRelocNameAddend(const MachOObjectFile *Obj, --Sym; auto SectOrErr = Sym->second.getSection(); - if (!SectOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SectOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!SectOrErr) + report_error(Obj->getFileName(), SectOrErr.takeError()); section_iterator SymSection = *SectOrErr; if (RelocSection == *SymSection) { // There's a valid symbol in the same section before this reference. Expected<StringRef> NameOrErr = Sym->second.getName(); - if (!NameOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(NameOrErr.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!NameOrErr) + report_error(Obj->getFileName(), NameOrErr.takeError()); Name = *NameOrErr; Addend = Addr - Sym->first; return; @@ -7072,8 +6969,10 @@ printMachOCompactUnwindSection(const MachOObjectFile *Obj, std::map<uint64_t, SymbolRef> &Symbols, const SectionRef &CompactUnwind) { - assert(Obj->isLittleEndian() && - "There should not be a big-endian .o with __compact_unwind"); + if (!Obj->isLittleEndian()) { + outs() << "Skipping big-endian __compact_unwind section\n"; + return; + } bool Is64 = Obj->is64Bit(); uint32_t PointerSize = Is64 ? sizeof(uint64_t) : sizeof(uint32_t); @@ -7105,8 +7004,10 @@ printMachOCompactUnwindSection(const MachOObjectFile *Obj, Entry.PersonalityReloc = Reloc; else if (OffsetInEntry == 2 * PointerSize + 2 * sizeof(uint32_t)) Entry.LSDAReloc = Reloc; - else - llvm_unreachable("Unexpected relocation in __compact_unwind section"); + else { + outs() << "Invalid relocation in __compact_unwind section\n"; + return; + } } // Finally, we're ready to print the data we've gathered. @@ -7212,8 +7113,10 @@ static void printMachOUnwindInfoSection(const MachOObjectFile *Obj, std::map<uint64_t, SymbolRef> &Symbols, const SectionRef &UnwindInfo) { - assert(Obj->isLittleEndian() && - "There should not be a big-endian .o with __unwind_info"); + if (!Obj->isLittleEndian()) { + outs() << "Skipping big-endian __unwind_info section\n"; + return; + } outs() << "Contents of __unwind_info section:\n"; @@ -7228,7 +7131,10 @@ static void printMachOUnwindInfoSection(const MachOObjectFile *Obj, uint32_t Version = readNext<uint32_t>(Pos); outs() << " Version: " << format("0x%" PRIx32, Version) << '\n'; - assert(Version == 1 && "only understand version 1"); + if (Version != 1) { + outs() << " Skipping section with unknown version\n"; + return; + } uint32_t CommonEncodingsStart = readNext<uint32_t>(Pos); outs() << " Common encodings array section offset: " @@ -7368,7 +7274,8 @@ static void printMachOUnwindInfoSection(const MachOObjectFile *Obj, printCompressedSecondLevelUnwindPage(Pos, IndexEntries[i].FunctionOffset, CommonEncodings); else - llvm_unreachable("Do not know how to print this kind of 2nd level page"); + outs() << " Skipping 2nd level page with unknown kind " << Kind + << '\n'; } } @@ -7735,9 +7642,9 @@ static void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize, if ((initprot & ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE)) != 0) - outs() << " initprot ?" << format("0x%08" PRIx32, initprot) << "\n"; + outs() << " initprot ?" << format("0x%08" PRIx32, initprot) << "\n"; else { - outs() << " initprot "; + outs() << " initprot "; outs() << ((initprot & MachO::VM_PROT_READ) ? "r" : "-"); outs() << ((initprot & MachO::VM_PROT_WRITE) ? "w" : "-"); outs() << ((initprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n"); @@ -8630,6 +8537,63 @@ static void Print_x86_exception_state_t(MachO::x86_exception_state64_t &exc64) { outs() << " faultvaddr " << format("0x%016" PRIx64, exc64.faultvaddr) << "\n"; } +static void Print_arm_thread_state32_t(MachO::arm_thread_state32_t &cpu32) { + outs() << "\t r0 " << format("0x%08" PRIx32, cpu32.r[0]); + outs() << " r1 " << format("0x%08" PRIx32, cpu32.r[1]); + outs() << " r2 " << format("0x%08" PRIx32, cpu32.r[2]); + outs() << " r3 " << format("0x%08" PRIx32, cpu32.r[3]) << "\n"; + outs() << "\t r4 " << format("0x%08" PRIx32, cpu32.r[4]); + outs() << " r5 " << format("0x%08" PRIx32, cpu32.r[5]); + outs() << " r6 " << format("0x%08" PRIx32, cpu32.r[6]); + outs() << " r7 " << format("0x%08" PRIx32, cpu32.r[7]) << "\n"; + outs() << "\t r8 " << format("0x%08" PRIx32, cpu32.r[8]); + outs() << " r9 " << format("0x%08" PRIx32, cpu32.r[9]); + outs() << " r10 " << format("0x%08" PRIx32, cpu32.r[10]); + outs() << " r11 " << format("0x%08" PRIx32, cpu32.r[11]) << "\n"; + outs() << "\t r12 " << format("0x%08" PRIx32, cpu32.r[12]); + outs() << " sp " << format("0x%08" PRIx32, cpu32.sp); + outs() << " lr " << format("0x%08" PRIx32, cpu32.lr); + outs() << " pc " << format("0x%08" PRIx32, cpu32.pc) << "\n"; + outs() << "\t cpsr " << format("0x%08" PRIx32, cpu32.cpsr) << "\n"; +} + +static void Print_arm_thread_state64_t(MachO::arm_thread_state64_t &cpu64) { + outs() << "\t x0 " << format("0x%016" PRIx64, cpu64.x[0]); + outs() << " x1 " << format("0x%016" PRIx64, cpu64.x[1]); + outs() << " x2 " << format("0x%016" PRIx64, cpu64.x[2]) << "\n"; + outs() << "\t x3 " << format("0x%016" PRIx64, cpu64.x[3]); + outs() << " x4 " << format("0x%016" PRIx64, cpu64.x[4]); + outs() << " x5 " << format("0x%016" PRIx64, cpu64.x[5]) << "\n"; + outs() << "\t x6 " << format("0x%016" PRIx64, cpu64.x[6]); + outs() << " x7 " << format("0x%016" PRIx64, cpu64.x[7]); + outs() << " x8 " << format("0x%016" PRIx64, cpu64.x[8]) << "\n"; + outs() << "\t x9 " << format("0x%016" PRIx64, cpu64.x[9]); + outs() << " x10 " << format("0x%016" PRIx64, cpu64.x[10]); + outs() << " x11 " << format("0x%016" PRIx64, cpu64.x[11]) << "\n"; + outs() << "\t x12 " << format("0x%016" PRIx64, cpu64.x[12]); + outs() << " x13 " << format("0x%016" PRIx64, cpu64.x[13]); + outs() << " x14 " << format("0x%016" PRIx64, cpu64.x[14]) << "\n"; + outs() << "\t x15 " << format("0x%016" PRIx64, cpu64.x[15]); + outs() << " x16 " << format("0x%016" PRIx64, cpu64.x[16]); + outs() << " x17 " << format("0x%016" PRIx64, cpu64.x[17]) << "\n"; + outs() << "\t x18 " << format("0x%016" PRIx64, cpu64.x[18]); + outs() << " x19 " << format("0x%016" PRIx64, cpu64.x[19]); + outs() << " x20 " << format("0x%016" PRIx64, cpu64.x[20]) << "\n"; + outs() << "\t x21 " << format("0x%016" PRIx64, cpu64.x[21]); + outs() << " x22 " << format("0x%016" PRIx64, cpu64.x[22]); + outs() << " x23 " << format("0x%016" PRIx64, cpu64.x[23]) << "\n"; + outs() << "\t x24 " << format("0x%016" PRIx64, cpu64.x[24]); + outs() << " x25 " << format("0x%016" PRIx64, cpu64.x[25]); + outs() << " x26 " << format("0x%016" PRIx64, cpu64.x[26]) << "\n"; + outs() << "\t x27 " << format("0x%016" PRIx64, cpu64.x[27]); + outs() << " x28 " << format("0x%016" PRIx64, cpu64.x[28]); + outs() << " fp " << format("0x%016" PRIx64, cpu64.fp) << "\n"; + outs() << "\t lr " << format("0x%016" PRIx64, cpu64.lr); + outs() << " sp " << format("0x%016" PRIx64, cpu64.sp); + outs() << " pc " << format("0x%016" PRIx64, cpu64.pc) << "\n"; + outs() << "\t cpsr " << format("0x%08" PRIx32, cpu64.cpsr) << "\n"; +} + static void PrintThreadCommand(MachO::thread_command t, const char *Ptr, bool isLittleEndian, uint32_t cputype) { if (t.cmd == MachO::LC_THREAD) @@ -8786,6 +8750,100 @@ static void PrintThreadCommand(MachO::thread_command t, const char *Ptr, begin += count * sizeof(uint32_t); } } + } else if (cputype == MachO::CPU_TYPE_ARM) { + while (begin < end) { + if (end - begin > (ptrdiff_t)sizeof(uint32_t)) { + memcpy((char *)&flavor, begin, sizeof(uint32_t)); + begin += sizeof(uint32_t); + } else { + flavor = 0; + begin = end; + } + if (isLittleEndian != sys::IsLittleEndianHost) + sys::swapByteOrder(flavor); + if (end - begin > (ptrdiff_t)sizeof(uint32_t)) { + memcpy((char *)&count, begin, sizeof(uint32_t)); + begin += sizeof(uint32_t); + } else { + count = 0; + begin = end; + } + if (isLittleEndian != sys::IsLittleEndianHost) + sys::swapByteOrder(count); + if (flavor == MachO::ARM_THREAD_STATE) { + outs() << " flavor ARM_THREAD_STATE\n"; + if (count == MachO::ARM_THREAD_STATE_COUNT) + outs() << " count ARM_THREAD_STATE_COUNT\n"; + else + outs() << " count " << count + << " (not ARM_THREAD_STATE_COUNT)\n"; + MachO::arm_thread_state32_t cpu32; + left = end - begin; + if (left >= sizeof(MachO::arm_thread_state32_t)) { + memcpy(&cpu32, begin, sizeof(MachO::arm_thread_state32_t)); + begin += sizeof(MachO::arm_thread_state32_t); + } else { + memset(&cpu32, '\0', sizeof(MachO::arm_thread_state32_t)); + memcpy(&cpu32, begin, left); + begin += left; + } + if (isLittleEndian != sys::IsLittleEndianHost) + swapStruct(cpu32); + Print_arm_thread_state32_t(cpu32); + } else { + outs() << " flavor " << flavor << " (unknown)\n"; + outs() << " count " << count << "\n"; + outs() << " state (unknown)\n"; + begin += count * sizeof(uint32_t); + } + } + } else if (cputype == MachO::CPU_TYPE_ARM64) { + while (begin < end) { + if (end - begin > (ptrdiff_t)sizeof(uint32_t)) { + memcpy((char *)&flavor, begin, sizeof(uint32_t)); + begin += sizeof(uint32_t); + } else { + flavor = 0; + begin = end; + } + if (isLittleEndian != sys::IsLittleEndianHost) + sys::swapByteOrder(flavor); + if (end - begin > (ptrdiff_t)sizeof(uint32_t)) { + memcpy((char *)&count, begin, sizeof(uint32_t)); + begin += sizeof(uint32_t); + } else { + count = 0; + begin = end; + } + if (isLittleEndian != sys::IsLittleEndianHost) + sys::swapByteOrder(count); + if (flavor == MachO::ARM_THREAD_STATE64) { + outs() << " flavor ARM_THREAD_STATE64\n"; + if (count == MachO::ARM_THREAD_STATE64_COUNT) + outs() << " count ARM_THREAD_STATE64_COUNT\n"; + else + outs() << " count " << count + << " (not ARM_THREAD_STATE64_COUNT)\n"; + MachO::arm_thread_state64_t cpu64; + left = end - begin; + if (left >= sizeof(MachO::arm_thread_state64_t)) { + memcpy(&cpu64, begin, sizeof(MachO::arm_thread_state64_t)); + begin += sizeof(MachO::arm_thread_state64_t); + } else { + memset(&cpu64, '\0', sizeof(MachO::arm_thread_state64_t)); + memcpy(&cpu64, begin, left); + begin += left; + } + if (isLittleEndian != sys::IsLittleEndianHost) + swapStruct(cpu64); + Print_arm_thread_state64_t(cpu64); + } else { + outs() << " flavor " << flavor << " (unknown)\n"; + outs() << " count " << count << "\n"; + outs() << " state (unknown)\n"; + begin += count * sizeof(uint32_t); + } + } } else { while (begin < end) { if (end - begin > (ptrdiff_t)sizeof(uint32_t)) { @@ -9358,7 +9416,7 @@ void llvm::printMachOWeakBindTable(const object::MachOObjectFile *Obj) { static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue, struct DisassembleInfo *info) { if (info->bindtable == nullptr) { - info->bindtable = new (BindTable); + info->bindtable = llvm::make_unique<SymbolAddressMap>(); SegInfo sectionTable(info->O); for (const llvm::object::MachOBindEntry &Entry : info->O->bindTable()) { uint32_t SegIndex = Entry.segmentIndex(); @@ -9366,21 +9424,11 @@ static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue, if (!sectionTable.isValidSegIndexAndOffset(SegIndex, OffsetInSeg)) continue; uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg); - const char *SymbolName = nullptr; StringRef name = Entry.symbolName(); if (!name.empty()) - SymbolName = name.data(); - info->bindtable->push_back(std::make_pair(Address, SymbolName)); + (*info->bindtable)[Address] = name; } } - for (bind_table_iterator BI = info->bindtable->begin(), - BE = info->bindtable->end(); - BI != BE; ++BI) { - uint64_t Address = BI->first; - if (ReferenceValue == Address) { - const char *SymbolName = BI->second; - return SymbolName; - } - } - return nullptr; + auto name = info->bindtable->lookup(ReferenceValue); + return !name.empty() ? name.data() : nullptr; } |
