summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/llvm-objdump
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/llvm-objdump')
-rw-r--r--contrib/llvm/tools/llvm-objdump/COFFDump.cpp34
-rw-r--r--contrib/llvm/tools/llvm-objdump/ELFDump.cpp35
-rw-r--r--contrib/llvm/tools/llvm-objdump/MachODump.cpp680
-rw-r--r--contrib/llvm/tools/llvm-objdump/WasmDump.cpp28
-rw-r--r--contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp594
-rw-r--r--contrib/llvm/tools/llvm-objdump/llvm-objdump.h4
6 files changed, 901 insertions, 474 deletions
diff --git a/contrib/llvm/tools/llvm-objdump/COFFDump.cpp b/contrib/llvm/tools/llvm-objdump/COFFDump.cpp
index 3ec6a1f..db549bb 100644
--- a/contrib/llvm/tools/llvm-objdump/COFFDump.cpp
+++ b/contrib/llvm/tools/llvm-objdump/COFFDump.cpp
@@ -17,6 +17,7 @@
#include "llvm-objdump.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/SourceMgr.h"
@@ -176,12 +177,10 @@ resolveSectionAndAddress(const COFFObjectFile *Obj, const SymbolRef &Sym,
// the function returns the symbol used for the relocation at the offset.
static std::error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
uint64_t Offset, SymbolRef &Sym) {
- for (std::vector<RelocationRef>::const_iterator I = Rels.begin(),
- E = Rels.end();
- I != E; ++I) {
- uint64_t Ofs = I->getOffset();
+ for (auto &R : Rels) {
+ uint64_t Ofs = R.getOffset();
if (Ofs == Offset) {
- Sym = *I->getSymbol();
+ Sym = *R.getSymbol();
return std::error_code();
}
}
@@ -353,7 +352,7 @@ static void printImportTables(const COFFObjectFile *Obj) {
return;
outs() << "The Import Tables:\n";
for (const ImportDirectoryEntryRef &DirRef : Obj->import_directories()) {
- const import_directory_table_entry *Dir;
+ const coff_import_directory_table_entry *Dir;
StringRef Name;
if (DirRef.getImportTableEntry(Dir)) return;
if (DirRef.getName(Name)) return;
@@ -617,6 +616,29 @@ void llvm::printCOFFFileHeader(const object::ObjectFile *Obj) {
printExportTable(file);
}
+void llvm::printCOFFSymbolTable(const object::COFFImportFile *i) {
+ unsigned Index = 0;
+ bool IsCode = i->getCOFFImportHeader()->getType() == COFF::IMPORT_CODE;
+
+ for (const object::BasicSymbolRef &Sym : i->symbols()) {
+ std::string Name;
+ raw_string_ostream NS(Name);
+
+ Sym.printName(NS);
+ NS.flush();
+
+ outs() << "[" << format("%2d", Index) << "]"
+ << "(sec " << format("%2d", 0) << ")"
+ << "(fl 0x00)" // Flag bits, which COFF doesn't have.
+ << "(ty " << format("%3x", (IsCode && Index) ? 32 : 0) << ")"
+ << "(scl " << format("%3x", 0) << ") "
+ << "(nx " << 0 << ") "
+ << "0x" << format("%08x", 0) << " " << Name << '\n';
+
+ ++Index;
+ }
+}
+
void llvm::printCOFFSymbolTable(const COFFObjectFile *coff) {
for (unsigned SI = 0, SE = coff->getNumberOfSymbols(); SI != SE; ++SI) {
ErrorOr<COFFSymbolRef> Symbol = coff->getSymbol(SI);
diff --git a/contrib/llvm/tools/llvm-objdump/ELFDump.cpp b/contrib/llvm/tools/llvm-objdump/ELFDump.cpp
index 7b44e39..7f5fe5a 100644
--- a/contrib/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/contrib/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -24,22 +24,41 @@ using namespace llvm::object;
template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
typedef ELFFile<ELFT> ELFO;
outs() << "Program Header:\n";
- for (const typename ELFO::Elf_Phdr &Phdr : o->program_headers()) {
+ auto ProgramHeaderOrError = o->program_headers();
+ if (!ProgramHeaderOrError)
+ report_fatal_error(
+ errorToErrorCode(ProgramHeaderOrError.takeError()).message());
+ for (const typename ELFO::Elf_Phdr &Phdr : *ProgramHeaderOrError) {
switch (Phdr.p_type) {
- case ELF::PT_LOAD:
- outs() << " LOAD ";
- break;
- case ELF::PT_GNU_STACK:
- outs() << " STACK ";
+ case ELF::PT_DYNAMIC:
+ outs() << " DYNAMIC ";
break;
case ELF::PT_GNU_EH_FRAME:
outs() << "EH_FRAME ";
break;
+ case ELF::PT_GNU_RELRO:
+ outs() << " RELRO ";
+ break;
+ case ELF::PT_GNU_STACK:
+ outs() << " STACK ";
+ break;
case ELF::PT_INTERP:
outs() << " INTERP ";
break;
- case ELF::PT_DYNAMIC:
- outs() << " DYNAMIC ";
+ case ELF::PT_LOAD:
+ outs() << " LOAD ";
+ break;
+ case ELF::PT_NOTE:
+ outs() << " NOTE ";
+ break;
+ case ELF::PT_OPENBSD_BOOTDATA:
+ outs() << " OPENBSD_BOOTDATA ";
+ break;
+ case ELF::PT_OPENBSD_RANDOMIZE:
+ outs() << " OPENBSD_RANDOMIZE ";
+ break;
+ case ELF::PT_OPENBSD_WXNEEDED:
+ outs() << " OPENBSD_WXNEEDED ";
break;
case ELF::PT_PHDR:
outs() << " PHDR ";
diff --git a/contrib/llvm/tools/llvm-objdump/MachODump.cpp b/contrib/llvm/tools/llvm-objdump/MachODump.cpp
index 4d950f1..5630848 100644
--- a/contrib/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/contrib/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;
}
diff --git a/contrib/llvm/tools/llvm-objdump/WasmDump.cpp b/contrib/llvm/tools/llvm-objdump/WasmDump.cpp
new file mode 100644
index 0000000..0d8ffba
--- /dev/null
+++ b/contrib/llvm/tools/llvm-objdump/WasmDump.cpp
@@ -0,0 +1,28 @@
+//===-- WasmDump.cpp - wasm-specific dumper ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements the wasm-specific dumper for llvm-objdump.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm-objdump.h"
+#include "llvm/Object/Wasm.h"
+
+using namespace llvm;
+using namespace object;
+
+void llvm::printWasmFileHeader(const object::ObjectFile *Obj) {
+ const WasmObjectFile *File = dyn_cast<const WasmObjectFile>(Obj);
+
+ outs() << "Program Header:\n";
+ outs() << "Version: 0x";
+ outs().write_hex(File->getHeader().Version);
+ outs() << "\n";
+}
diff --git a/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp b/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
index ed55c91..8373f0c 100644
--- a/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/Triple.h"
#include "llvm/CodeGen/FaultMaps.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/Symbolize/Symbolize.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
@@ -36,6 +37,7 @@
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
@@ -60,6 +62,7 @@
#include <cstring>
#include <system_error>
#include <utility>
+#include <unordered_map>
using namespace llvm;
using namespace object;
@@ -185,9 +188,29 @@ cl::opt<bool> PrintFaultMaps("fault-map-section",
cl::opt<DIDumpType> llvm::DwarfDumpType(
"dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
- cl::values(clEnumValN(DIDT_Frames, "frames", ".debug_frame"),
- clEnumValEnd));
+ cl::values(clEnumValN(DIDT_Frames, "frames", ".debug_frame")));
+cl::opt<bool> PrintSource(
+ "source",
+ cl::desc(
+ "Display source inlined with disassembly. Implies disassmble object"));
+
+cl::alias PrintSourceShort("S", cl::desc("Alias for -source"),
+ cl::aliasopt(PrintSource));
+
+cl::opt<bool> PrintLines("line-numbers",
+ cl::desc("Display source line numbers with "
+ "disassembly. Implies disassemble object"));
+
+cl::alias PrintLinesShort("l", cl::desc("Alias for -line-numbers"),
+ cl::aliasopt(PrintLines));
+
+cl::opt<unsigned long long>
+ StartAddress("start-address", cl::desc("Disassemble beginning at address"),
+ cl::value_desc("address"), cl::init(0));
+cl::opt<unsigned long long>
+ StopAddress("stop-address", cl::desc("Stop disassembly at address"),
+ cl::value_desc("address"), cl::init(UINT64_MAX));
static StringRef ToolName;
namespace {
@@ -240,18 +263,17 @@ private:
llvm::object::ObjectFile const &Object;
};
SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O) {
- return SectionFilter([](llvm::object::SectionRef const &S) {
- if(FilterSections.empty())
- return true;
- llvm::StringRef String;
- std::error_code error = S.getName(String);
- if (error)
- return false;
- return std::find(FilterSections.begin(),
- FilterSections.end(),
- String) != FilterSections.end();
- },
- O);
+ return SectionFilter(
+ [](llvm::object::SectionRef const &S) {
+ if (FilterSections.empty())
+ return true;
+ llvm::StringRef String;
+ std::error_code error = S.getName(String);
+ if (error)
+ return false;
+ return is_contained(FilterSections, String);
+ },
+ O);
}
}
@@ -271,6 +293,12 @@ LLVM_ATTRIBUTE_NORETURN void llvm::error(Twine Message) {
}
LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
+ Twine Message) {
+ errs() << ToolName << ": '" << File << "': " << Message << ".\n";
+ exit(1);
+}
+
+LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
std::error_code EC) {
assert(EC);
errs() << ToolName << ": '" << File << "': " << EC.message() << ".\n";
@@ -297,14 +325,14 @@ LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
if (ArchiveName != "")
errs() << ArchiveName << "(" << FileName << ")";
else
- errs() << FileName;
+ errs() << "'" << FileName << "'";
if (!ArchitectureName.empty())
errs() << " (for architecture " << ArchitectureName << ")";
std::string Buf;
raw_string_ostream OS(Buf);
logAllUnhandledErrors(std::move(E), OS, "");
OS.flush();
- errs() << " " << Buf;
+ errs() << ": " << Buf;
exit(1);
}
@@ -312,13 +340,14 @@ LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
const object::Archive::Child &C,
llvm::Error E,
StringRef ArchitectureName) {
- ErrorOr<StringRef> NameOrErr = C.getName();
+ Expected<StringRef> NameOrErr = C.getName();
// TODO: if we have a error getting the name then it would be nice to print
// the index of which archive member this is and or its offset in the
// archive instead of "???" as the name.
- if (NameOrErr.getError())
+ if (!NameOrErr) {
+ consumeError(NameOrErr.takeError());
llvm::report_error(ArchiveName, "???", std::move(E), ArchitectureName);
- else
+ } else
llvm::report_error(ArchiveName, NameOrErr.get(), std::move(E),
ArchitectureName);
}
@@ -347,8 +376,12 @@ static const Target *getTarget(const ObjectFile *Obj = nullptr) {
std::string Error;
const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
Error);
- if (!TheTarget)
- report_fatal_error("can't find target: " + Error);
+ if (!TheTarget) {
+ if (Obj)
+ report_error(Obj->getFileName(), "can't find target: " + Error);
+ else
+ error("can't find target: " + Error);
+ }
// Update the triple name and return the found target.
TripleName = TheTriple.getTriple();
@@ -360,13 +393,104 @@ bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
}
namespace {
+class SourcePrinter {
+protected:
+ DILineInfo OldLineInfo;
+ const ObjectFile *Obj;
+ std::unique_ptr<symbolize::LLVMSymbolizer> Symbolizer;
+ // File name to file contents of source
+ std::unordered_map<std::string, std::unique_ptr<MemoryBuffer>> SourceCache;
+ // Mark the line endings of the cached source
+ std::unordered_map<std::string, std::vector<StringRef>> LineCache;
+
+private:
+ bool cacheSource(std::string File);
+
+public:
+ virtual ~SourcePrinter() {}
+ SourcePrinter() : Obj(nullptr), Symbolizer(nullptr) {}
+ SourcePrinter(const ObjectFile *Obj, StringRef DefaultArch) : Obj(Obj) {
+ symbolize::LLVMSymbolizer::Options SymbolizerOpts(
+ DILineInfoSpecifier::FunctionNameKind::None, true, false, false,
+ DefaultArch);
+ Symbolizer.reset(new symbolize::LLVMSymbolizer(SymbolizerOpts));
+ }
+ virtual void printSourceLine(raw_ostream &OS, uint64_t Address,
+ StringRef Delimiter = "; ");
+};
+
+bool SourcePrinter::cacheSource(std::string File) {
+ auto BufferOrError = MemoryBuffer::getFile(File);
+ if (!BufferOrError)
+ return false;
+ // Chomp the file to get lines
+ size_t BufferSize = (*BufferOrError)->getBufferSize();
+ const char *BufferStart = (*BufferOrError)->getBufferStart();
+ for (const char *Start = BufferStart, *End = BufferStart;
+ End < BufferStart + BufferSize; End++)
+ if (*End == '\n' || End == BufferStart + BufferSize - 1 ||
+ (*End == '\r' && *(End + 1) == '\n')) {
+ LineCache[File].push_back(StringRef(Start, End - Start));
+ if (*End == '\r')
+ End++;
+ Start = End + 1;
+ }
+ SourceCache[File] = std::move(*BufferOrError);
+ return true;
+}
+
+void SourcePrinter::printSourceLine(raw_ostream &OS, uint64_t Address,
+ StringRef Delimiter) {
+ if (!Symbolizer)
+ return;
+ DILineInfo LineInfo = DILineInfo();
+ auto ExpectecLineInfo =
+ Symbolizer->symbolizeCode(Obj->getFileName(), Address);
+ if (!ExpectecLineInfo)
+ consumeError(ExpectecLineInfo.takeError());
+ else
+ LineInfo = *ExpectecLineInfo;
+
+ if ((LineInfo.FileName == "<invalid>") || OldLineInfo.Line == LineInfo.Line ||
+ LineInfo.Line == 0)
+ return;
+
+ if (PrintLines)
+ OS << Delimiter << LineInfo.FileName << ":" << LineInfo.Line << "\n";
+ if (PrintSource) {
+ if (SourceCache.find(LineInfo.FileName) == SourceCache.end())
+ if (!cacheSource(LineInfo.FileName))
+ return;
+ auto FileBuffer = SourceCache.find(LineInfo.FileName);
+ if (FileBuffer != SourceCache.end()) {
+ auto LineBuffer = LineCache.find(LineInfo.FileName);
+ if (LineBuffer != LineCache.end())
+ // Vector begins at 0, line numbers are non-zero
+ OS << Delimiter << LineBuffer->second[LineInfo.Line - 1].ltrim()
+ << "\n";
+ }
+ }
+ OldLineInfo = LineInfo;
+}
+
+static bool isArmElf(const ObjectFile *Obj) {
+ return (Obj->isELF() &&
+ (Obj->getArch() == Triple::aarch64 ||
+ Obj->getArch() == Triple::aarch64_be ||
+ Obj->getArch() == Triple::arm || Obj->getArch() == Triple::armeb ||
+ Obj->getArch() == Triple::thumb ||
+ Obj->getArch() == Triple::thumbeb));
+}
+
class PrettyPrinter {
public:
virtual ~PrettyPrinter(){}
virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
ArrayRef<uint8_t> Bytes, uint64_t Address,
raw_ostream &OS, StringRef Annot,
- MCSubtargetInfo const &STI) {
+ MCSubtargetInfo const &STI, SourcePrinter *SP) {
+ if (SP && (PrintSource || PrintLines))
+ SP->printSourceLine(OS, Address);
OS << format("%8" PRIx64 ":", Address);
if (!NoShowRawInsn) {
OS << "\t";
@@ -392,10 +516,11 @@ public:
OS << format("%08" PRIx32, opcode);
}
}
- void printInst(MCInstPrinter &IP, const MCInst *MI,
- ArrayRef<uint8_t> Bytes, uint64_t Address,
- raw_ostream &OS, StringRef Annot,
- MCSubtargetInfo const &STI) override {
+ void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
+ uint64_t Address, raw_ostream &OS, StringRef Annot,
+ MCSubtargetInfo const &STI, SourcePrinter *SP) override {
+ if (SP && (PrintSource || PrintLines))
+ SP->printSourceLine(OS, Address, "");
if (!MI) {
printLead(Bytes, Address, OS);
OS << " <unknown>";
@@ -416,6 +541,8 @@ public:
while(!HeadTail.first.empty()) {
OS << Separator;
Separator = "\n";
+ if (SP && (PrintSource || PrintLines))
+ SP->printSourceLine(OS, Address, "");
printLead(Bytes, Address, OS);
OS << Preamble;
Preamble = " ";
@@ -440,13 +567,9 @@ HexagonPrettyPrinter HexagonPrettyPrinterInst;
class AMDGCNPrettyPrinter : public PrettyPrinter {
public:
- void printInst(MCInstPrinter &IP,
- const MCInst *MI,
- ArrayRef<uint8_t> Bytes,
- uint64_t Address,
- raw_ostream &OS,
- StringRef Annot,
- MCSubtargetInfo const &STI) override {
+ void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
+ uint64_t Address, raw_ostream &OS, StringRef Annot,
+ MCSubtargetInfo const &STI, SourcePrinter *SP) override {
if (!MI) {
OS << " <unknown>";
return;
@@ -471,6 +594,26 @@ public:
};
AMDGCNPrettyPrinter AMDGCNPrettyPrinterInst;
+class BPFPrettyPrinter : public PrettyPrinter {
+public:
+ void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
+ uint64_t Address, raw_ostream &OS, StringRef Annot,
+ MCSubtargetInfo const &STI, SourcePrinter *SP) override {
+ if (SP && (PrintSource || PrintLines))
+ SP->printSourceLine(OS, Address);
+ OS << format("%8" PRId64 ":", Address / 8);
+ if (!NoShowRawInsn) {
+ OS << "\t";
+ dumpBytes(Bytes, OS);
+ }
+ if (MI)
+ IP.printInst(MI, OS, "", STI);
+ else
+ OS << " <unknown>";
+ }
+};
+BPFPrettyPrinter BPFPrettyPrinterInst;
+
PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
switch(Triple.getArch()) {
default:
@@ -479,6 +622,9 @@ PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
return HexagonPrettyPrinterInst;
case Triple::amdgcn:
return AMDGCNPrettyPrinterInst;
+ case Triple::bpfel:
+ case Triple::bpfeb:
+ return BPFPrettyPrinterInst;
}
}
}
@@ -495,22 +641,22 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
const ELFFile<ELFT> &EF = *Obj->getELFFile();
- ErrorOr<const Elf_Shdr *> SecOrErr = EF.getSection(Rel.d.a);
- if (std::error_code EC = SecOrErr.getError())
- return EC;
+ auto SecOrErr = EF.getSection(Rel.d.a);
+ if (!SecOrErr)
+ return errorToErrorCode(SecOrErr.takeError());
const Elf_Shdr *Sec = *SecOrErr;
- ErrorOr<const Elf_Shdr *> SymTabOrErr = EF.getSection(Sec->sh_link);
- if (std::error_code EC = SymTabOrErr.getError())
- return EC;
+ auto SymTabOrErr = EF.getSection(Sec->sh_link);
+ if (!SymTabOrErr)
+ return errorToErrorCode(SymTabOrErr.takeError());
const Elf_Shdr *SymTab = *SymTabOrErr;
assert(SymTab->sh_type == ELF::SHT_SYMTAB ||
SymTab->sh_type == ELF::SHT_DYNSYM);
- ErrorOr<const Elf_Shdr *> StrTabSec = EF.getSection(SymTab->sh_link);
- if (std::error_code EC = StrTabSec.getError())
- return EC;
- ErrorOr<StringRef> StrTabOrErr = EF.getStringTable(*StrTabSec);
- if (std::error_code EC = StrTabOrErr.getError())
- return EC;
+ auto StrTabSec = EF.getSection(SymTab->sh_link);
+ if (!StrTabSec)
+ return errorToErrorCode(StrTabSec.takeError());
+ auto StrTabOrErr = EF.getStringTable(*StrTabSec);
+ if (!StrTabOrErr)
+ return errorToErrorCode(StrTabOrErr.takeError());
StringRef StrTab = *StrTabOrErr;
uint8_t type = RelRef.getType();
StringRef res;
@@ -536,9 +682,9 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
if (!SymSI)
return errorToErrorCode(SymSI.takeError());
const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
- ErrorOr<StringRef> SecName = EF.getSectionName(SymSec);
- if (std::error_code EC = SecName.getError())
- return EC;
+ auto SecName = EF.getSectionName(SymSec);
+ if (!SecName)
+ return errorToErrorCode(SecName.takeError());
Target = *SecName;
} else {
Expected<StringRef> SymName = symb->getName(StrTab);
@@ -574,6 +720,7 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
}
break;
case ELF::EM_LANAI:
+ case ELF::EM_AVR:
case ELF::EM_AARCH64: {
std::string fmtbuf;
raw_string_ostream fmt(fmtbuf);
@@ -590,6 +737,7 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
case ELF::EM_HEXAGON:
case ELF::EM_MIPS:
case ELF::EM_BPF:
+ case ELF::EM_RISCV:
res = Target;
break;
case ELF::EM_WEBASSEMBLY:
@@ -657,23 +805,13 @@ static void printRelocationTargetName(const MachOObjectFile *O,
for (const SymbolRef &Symbol : O->symbols()) {
std::error_code ec;
Expected<uint64_t> Addr = Symbol.getAddress();
- if (!Addr) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(Addr.takeError(), OS, "");
- OS.flush();
- report_fatal_error(Buf);
- }
+ if (!Addr)
+ report_error(O->getFileName(), Addr.takeError());
if (*Addr != Val)
continue;
Expected<StringRef> Name = Symbol.getName();
- if (!Name) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(Name.takeError(), OS, "");
- OS.flush();
- report_fatal_error(Buf);
- }
+ if (!Name)
+ report_error(O->getFileName(), Name.takeError());
fmt << *Name;
return;
}
@@ -688,7 +826,7 @@ static void printRelocationTargetName(const MachOObjectFile *O,
if (Addr != Val)
continue;
if ((ec = Section.getName(Name)))
- report_fatal_error(ec.message());
+ report_error(O->getFileName(), ec);
fmt << Name;
return;
}
@@ -705,7 +843,8 @@ static void printRelocationTargetName(const MachOObjectFile *O,
symbol_iterator SI = O->symbol_begin();
advance(SI, Val);
Expected<StringRef> SOrErr = SI->getName();
- error(errorToErrorCode(SOrErr.takeError()));
+ if (!SOrErr)
+ report_error(O->getFileName(), SOrErr.takeError());
S = *SOrErr;
} else {
section_iterator SI = O->section_begin();
@@ -756,8 +895,8 @@ static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
// NOTE: Scattered relocations don't exist on x86_64.
unsigned RType = Obj->getAnyRelocationType(RENext);
if (RType != MachO::X86_64_RELOC_UNSIGNED)
- report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
- "X86_64_RELOC_SUBTRACTOR.");
+ report_error(Obj->getFileName(), "Expected X86_64_RELOC_UNSIGNED after "
+ "X86_64_RELOC_SUBTRACTOR.");
// The X86_64_RELOC_UNSIGNED contains the minuend symbol;
// X86_64_RELOC_SUBTRACTOR contains the subtrahend.
@@ -805,8 +944,8 @@ static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
unsigned RType = Obj->getAnyRelocationType(RENext);
if (RType != MachO::GENERIC_RELOC_PAIR)
- report_fatal_error("Expected GENERIC_RELOC_PAIR after "
- "GENERIC_RELOC_SECTDIFF.");
+ report_error(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
+ "GENERIC_RELOC_SECTDIFF.");
printRelocationTargetName(Obj, RE, fmt);
fmt << "-";
@@ -826,8 +965,8 @@ static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
// GENERIC_RELOC_PAIR.
unsigned RType = Obj->getAnyRelocationType(RENext);
if (RType != MachO::GENERIC_RELOC_PAIR)
- report_fatal_error("Expected GENERIC_RELOC_PAIR after "
- "GENERIC_RELOC_LOCAL_SECTDIFF.");
+ report_error(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
+ "GENERIC_RELOC_LOCAL_SECTDIFF.");
printRelocationTargetName(Obj, RE, fmt);
fmt << "-";
@@ -866,8 +1005,8 @@ static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
// ARM_RELOC_PAIR.
unsigned RType = Obj->getAnyRelocationType(RENext);
if (RType != MachO::ARM_RELOC_PAIR)
- report_fatal_error("Expected ARM_RELOC_PAIR after "
- "ARM_RELOC_HALF");
+ report_error(Obj->getFileName(), "Expected ARM_RELOC_PAIR after "
+ "ARM_RELOC_HALF");
// NOTE: The half of the target virtual address is stashed in the
// address field of the secondary relocation, but we can't reverse
@@ -939,7 +1078,23 @@ static bool getHidden(RelocationRef RelRef) {
return false;
}
+static uint8_t getElfSymbolType(const ObjectFile *Obj, const SymbolRef &Sym) {
+ assert(Obj->isELF());
+ if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
+ return Elf32LEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
+ if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
+ return Elf64LEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
+ if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
+ return Elf32BEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
+ if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj))
+ return Elf64BEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
+ llvm_unreachable("Unsupported binary format");
+}
+
static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
+ if (StartAddress > StopAddress)
+ error("Start address should be less than stop address");
+
const Target *TheTarget = getTarget(Obj);
// Package up features to be passed to target/subtarget
@@ -952,27 +1107,34 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
std::unique_ptr<const MCRegisterInfo> MRI(
TheTarget->createMCRegInfo(TripleName));
if (!MRI)
- report_fatal_error("error: no register info for target " + TripleName);
+ report_error(Obj->getFileName(), "no register info for target " +
+ TripleName);
// Set up disassembler.
std::unique_ptr<const MCAsmInfo> AsmInfo(
TheTarget->createMCAsmInfo(*MRI, TripleName));
if (!AsmInfo)
- report_fatal_error("error: no assembly info for target " + TripleName);
+ report_error(Obj->getFileName(), "no assembly info for target " +
+ TripleName);
std::unique_ptr<const MCSubtargetInfo> STI(
TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
if (!STI)
- report_fatal_error("error: no subtarget info for target " + TripleName);
+ report_error(Obj->getFileName(), "no subtarget info for target " +
+ TripleName);
std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
if (!MII)
- report_fatal_error("error: no instruction info for target " + TripleName);
- std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo);
- MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get());
+ report_error(Obj->getFileName(), "no instruction info for target " +
+ TripleName);
+ MCObjectFileInfo MOFI;
+ MCContext Ctx(AsmInfo.get(), MRI.get(), &MOFI);
+ // FIXME: for now initialize MCObjectFileInfo with default values
+ MOFI.InitMCObjectFileInfo(Triple(TripleName), false, CodeModel::Default, Ctx);
std::unique_ptr<MCDisassembler> DisAsm(
TheTarget->createMCDisassembler(*STI, Ctx));
if (!DisAsm)
- report_fatal_error("error: no disassembler for target " + TripleName);
+ report_error(Obj->getFileName(), "no disassembler for target " +
+ TripleName);
std::unique_ptr<const MCInstrAnalysis> MIA(
TheTarget->createMCInstrAnalysis(MII.get()));
@@ -981,14 +1143,16 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
if (!IP)
- report_fatal_error("error: no instruction printer for target " +
- TripleName);
+ report_error(Obj->getFileName(), "no instruction printer for target " +
+ TripleName);
IP->setPrintImmHex(PrintImmHex);
PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " :
"\t\t\t%08" PRIx64 ": ";
+ SourcePrinter SP(Obj, TheTarget->getName());
+
// Create a mapping, RelocSecs = SectionRelocMap[S], where sections
// in RelocSecs contain the relocations for section S.
std::error_code EC;
@@ -1001,25 +1165,33 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
// Create a mapping from virtual address to symbol name. This is used to
// pretty print the symbols while disassembling.
- typedef std::vector<std::pair<uint64_t, StringRef>> SectionSymbolsTy;
+ typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy;
std::map<SectionRef, SectionSymbolsTy> AllSymbols;
for (const SymbolRef &Symbol : Obj->symbols()) {
Expected<uint64_t> AddressOrErr = Symbol.getAddress();
- error(errorToErrorCode(AddressOrErr.takeError()));
+ if (!AddressOrErr)
+ report_error(Obj->getFileName(), AddressOrErr.takeError());
uint64_t Address = *AddressOrErr;
Expected<StringRef> Name = Symbol.getName();
- error(errorToErrorCode(Name.takeError()));
+ if (!Name)
+ report_error(Obj->getFileName(), Name.takeError());
if (Name->empty())
continue;
Expected<section_iterator> SectionOrErr = Symbol.getSection();
- error(errorToErrorCode(SectionOrErr.takeError()));
+ if (!SectionOrErr)
+ report_error(Obj->getFileName(), SectionOrErr.takeError());
section_iterator SecI = *SectionOrErr;
if (SecI == Obj->section_end())
continue;
- AllSymbols[*SecI].emplace_back(Address, *Name);
+ uint8_t SymbolType = ELF::STT_NOTYPE;
+ if (Obj->isELF())
+ SymbolType = getElfSymbolType(Obj, Symbol);
+
+ AllSymbols[*SecI].emplace_back(Address, *Name, SymbolType);
+
}
// Create a mapping from virtual address to section.
@@ -1051,7 +1223,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
Sec = SectionAddresses.end();
if (Sec != SectionAddresses.end())
- AllSymbols[Sec->second].emplace_back(VA, Name);
+ AllSymbols[Sec->second].emplace_back(VA, Name, ELF::STT_NOTYPE);
}
}
@@ -1073,20 +1245,36 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
SectionSymbolsTy &Symbols = AllSymbols[Section];
std::vector<uint64_t> DataMappingSymsAddr;
std::vector<uint64_t> TextMappingSymsAddr;
- if (Obj->isELF() && Obj->getArch() == Triple::aarch64) {
+ if (isArmElf(Obj)) {
for (const auto &Symb : Symbols) {
- uint64_t Address = Symb.first;
- StringRef Name = Symb.second;
+ uint64_t Address = std::get<0>(Symb);
+ StringRef Name = std::get<1>(Symb);
if (Name.startswith("$d"))
DataMappingSymsAddr.push_back(Address - SectionAddr);
if (Name.startswith("$x"))
TextMappingSymsAddr.push_back(Address - SectionAddr);
+ if (Name.startswith("$a"))
+ TextMappingSymsAddr.push_back(Address - SectionAddr);
+ if (Name.startswith("$t"))
+ TextMappingSymsAddr.push_back(Address - SectionAddr);
}
}
std::sort(DataMappingSymsAddr.begin(), DataMappingSymsAddr.end());
std::sort(TextMappingSymsAddr.begin(), TextMappingSymsAddr.end());
+ if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
+ // AMDGPU disassembler uses symbolizer for printing labels
+ std::unique_ptr<MCRelocationInfo> RelInfo(
+ TheTarget->createMCRelocationInfo(TripleName, Ctx));
+ if (RelInfo) {
+ std::unique_ptr<MCSymbolizer> Symbolizer(
+ TheTarget->createMCSymbolizer(
+ TripleName, nullptr, nullptr, &Symbols, &Ctx, std::move(RelInfo)));
+ DisAsm->setSymbolizer(std::move(Symbolizer));
+ }
+ }
+
// Make a list of all the relocations for this section.
std::vector<RelocationRef> Rels;
if (InlineRelocs) {
@@ -1107,14 +1295,22 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
}
StringRef name;
error(Section.getName(name));
+
+ if ((SectionAddr <= StopAddress) &&
+ (SectionAddr + SectSize) >= StartAddress) {
outs() << "Disassembly of section ";
if (!SegmentName.empty())
outs() << SegmentName << ",";
outs() << name << ':';
+ }
// If the section has no symbol at the start, just insert a dummy one.
- if (Symbols.empty() || Symbols[0].first != 0)
- Symbols.insert(Symbols.begin(), std::make_pair(SectionAddr, name));
+ if (Symbols.empty() || std::get<0>(Symbols[0]) != 0) {
+ Symbols.insert(Symbols.begin(),
+ std::make_tuple(SectionAddr, name, Section.isText()
+ ? ELF::STT_FUNC
+ : ELF::STT_OBJECT));
+ }
SmallString<40> Comments;
raw_svector_ostream CommentStream(Comments);
@@ -1131,12 +1327,11 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
// Disassemble symbol by symbol.
for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
-
- uint64_t Start = Symbols[si].first - SectionAddr;
+ uint64_t Start = std::get<0>(Symbols[si]) - SectionAddr;
// The end is either the section end or the beginning of the next
// symbol.
uint64_t End =
- (si == se - 1) ? SectSize : Symbols[si + 1].first - SectionAddr;
+ (si == se - 1) ? SectSize : std::get<0>(Symbols[si + 1]) - SectionAddr;
// Don't try to disassemble beyond the end of section contents.
if (End > SectSize)
End = SectSize;
@@ -1144,19 +1339,37 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (Start >= End)
continue;
+ // Check if we need to skip symbol
+ // Skip if the symbol's data is not between StartAddress and StopAddress
+ if (End + SectionAddr < StartAddress ||
+ Start + SectionAddr > StopAddress) {
+ continue;
+ }
+
+ // Stop disassembly at the stop address specified
+ if (End + SectionAddr > StopAddress)
+ End = StopAddress - SectionAddr;
+
if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
// make size 4 bytes folded
End = Start + ((End - Start) & ~0x3ull);
- Start += 256; // add sizeof(amd_kernel_code_t)
- // cut trailing zeroes - up to 256 bytes (align)
- const uint64_t EndAlign = 256;
- const auto Limit = End - (std::min)(EndAlign, End - Start);
- while (End > Limit &&
- *reinterpret_cast<const support::ulittle32_t*>(&Bytes[End - 4]) == 0)
- End -= 4;
+ if (std::get<2>(Symbols[si]) == ELF::STT_AMDGPU_HSA_KERNEL) {
+ // skip amd_kernel_code_t at the begining of kernel symbol (256 bytes)
+ Start += 256;
+ }
+ if (si == se - 1 ||
+ std::get<2>(Symbols[si + 1]) == ELF::STT_AMDGPU_HSA_KERNEL) {
+ // cut trailing zeroes at the end of kernel
+ // cut up to 256 bytes
+ const uint64_t EndAlign = 256;
+ const auto Limit = End - (std::min)(EndAlign, End - Start);
+ while (End > Limit &&
+ *reinterpret_cast<const support::ulittle32_t*>(&Bytes[End - 4]) == 0)
+ End -= 4;
+ }
}
- outs() << '\n' << Symbols[si].second << ":\n";
+ outs() << '\n' << std::get<1>(Symbols[si]) << ":\n";
#ifndef NDEBUG
raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
@@ -1167,10 +1380,18 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
for (Index = Start; Index < End; Index += Size) {
MCInst Inst;
+ if (Index + SectionAddr < StartAddress ||
+ Index + SectionAddr > StopAddress) {
+ // skip byte by byte till StartAddress is reached
+ Size = 1;
+ continue;
+ }
// AArch64 ELF binaries can interleave data and text in the
// same section. We rely on the markers introduced to
- // understand what we need to dump.
- if (Obj->isELF() && Obj->getArch() == Triple::aarch64) {
+ // understand what we need to dump. If the data marker is within a
+ // function, it is denoted as a word/short etc
+ if (isArmElf(Obj) && std::get<2>(Symbols[si]) != ELF::STT_OBJECT &&
+ !DisassembleAll) {
uint64_t Stride = 0;
auto DAI = std::lower_bound(DataMappingSymsAddr.begin(),
@@ -1183,15 +1404,41 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (Index + 4 <= End) {
Stride = 4;
dumpBytes(Bytes.slice(Index, 4), outs());
- outs() << "\t.word";
+ outs() << "\t.word\t";
+ uint32_t Data = 0;
+ if (Obj->isLittleEndian()) {
+ const auto Word =
+ reinterpret_cast<const support::ulittle32_t *>(
+ Bytes.data() + Index);
+ Data = *Word;
+ } else {
+ const auto Word = reinterpret_cast<const support::ubig32_t *>(
+ Bytes.data() + Index);
+ Data = *Word;
+ }
+ outs() << "0x" << format("%08" PRIx32, Data);
} else if (Index + 2 <= End) {
Stride = 2;
dumpBytes(Bytes.slice(Index, 2), outs());
- outs() << "\t.short";
+ outs() << "\t\t.short\t";
+ uint16_t Data = 0;
+ if (Obj->isLittleEndian()) {
+ const auto Short =
+ reinterpret_cast<const support::ulittle16_t *>(
+ Bytes.data() + Index);
+ Data = *Short;
+ } else {
+ const auto Short =
+ reinterpret_cast<const support::ubig16_t *>(Bytes.data() +
+ Index);
+ Data = *Short;
+ }
+ outs() << "0x" << format("%04" PRIx16, Data);
} else {
Stride = 1;
dumpBytes(Bytes.slice(Index, 1), outs());
- outs() << "\t.byte";
+ outs() << "\t\t.byte\t";
+ outs() << "0x" << format("%02" PRIx8, Bytes.slice(Index, 1)[0]);
}
Index += Stride;
outs() << "\n";
@@ -1203,17 +1450,62 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
}
}
+ // If there is a data symbol inside an ELF text section and we are only
+ // disassembling text (applicable all architectures),
+ // we are in a situation where we must print the data and not
+ // disassemble it.
+ if (Obj->isELF() && std::get<2>(Symbols[si]) == ELF::STT_OBJECT &&
+ !DisassembleAll && Section.isText()) {
+ // print out data up to 8 bytes at a time in hex and ascii
+ uint8_t AsciiData[9] = {'\0'};
+ uint8_t Byte;
+ int NumBytes = 0;
+
+ for (Index = Start; Index < End; Index += 1) {
+ if (((SectionAddr + Index) < StartAddress) ||
+ ((SectionAddr + Index) > StopAddress))
+ continue;
+ if (NumBytes == 0) {
+ outs() << format("%8" PRIx64 ":", SectionAddr + Index);
+ outs() << "\t";
+ }
+ Byte = Bytes.slice(Index)[0];
+ outs() << format(" %02x", Byte);
+ AsciiData[NumBytes] = isprint(Byte) ? Byte : '.';
+
+ uint8_t IndentOffset = 0;
+ NumBytes++;
+ if (Index == End - 1 || NumBytes > 8) {
+ // Indent the space for less than 8 bytes data.
+ // 2 spaces for byte and one for space between bytes
+ IndentOffset = 3 * (8 - NumBytes);
+ for (int Excess = 8 - NumBytes; Excess < 8; Excess++)
+ AsciiData[Excess] = '\0';
+ NumBytes = 8;
+ }
+ if (NumBytes == 8) {
+ AsciiData[8] = '\0';
+ outs() << std::string(IndentOffset, ' ') << " ";
+ outs() << reinterpret_cast<char *>(AsciiData);
+ outs() << '\n';
+ NumBytes = 0;
+ }
+ }
+ }
if (Index >= End)
break;
+ // Disassemble a real instruction or a data when disassemble all is
+ // provided
bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
SectionAddr + Index, DebugOut,
CommentStream);
if (Size == 0)
Size = 1;
+
PIP.printInst(*IP, Disassembled ? &Inst : nullptr,
- Bytes.slice(Index, Size),
- SectionAddr + Index, outs(), "", *STI);
+ Bytes.slice(Index, Size), SectionAddr + Index, outs(), "",
+ *STI, &SP);
outs() << CommentStream.str();
Comments.clear();
@@ -1252,8 +1544,8 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
auto TargetSym = std::upper_bound(
TargetSectionSymbols->begin(), TargetSectionSymbols->end(),
Target, [](uint64_t LHS,
- const std::pair<uint64_t, StringRef> &RHS) {
- return LHS < RHS.first;
+ const std::tuple<uint64_t, StringRef, uint8_t> &RHS) {
+ return LHS < std::get<0>(RHS);
});
if (TargetSym != TargetSectionSymbols->begin()) {
--TargetSym;
@@ -1278,7 +1570,10 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
SmallString<32> val;
// If this relocation is hidden, skip it.
- if (hidden) goto skip_print_rel;
+ if (hidden || ((SectionAddr + addr) < StartAddress)) {
+ ++rel_cur;
+ continue;
+ }
// Stop when rel_cur's address is past the current instruction.
if (addr >= Index + Size) break;
@@ -1286,8 +1581,6 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
error(getRelocationValueString(*rel_cur, val));
outs() << format(Fmt.data(), SectionAddr + addr) << name
<< "\t" << val << "\n";
-
- skip_print_rel:
++rel_cur;
}
}
@@ -1314,7 +1607,7 @@ void llvm::PrintRelocations(const ObjectFile *Obj) {
uint64_t address = Reloc.getOffset();
SmallString<32> relocname;
SmallString<32> valuestr;
- if (hidden)
+ if (address < StartAddress || address > StopAddress || hidden)
continue;
Reloc.getTypeName(relocname);
error(getRelocationValueString(Reloc, valuestr));
@@ -1403,15 +1696,21 @@ void llvm::PrintSymbolTable(const ObjectFile *o, StringRef ArchiveName,
for (const SymbolRef &Symbol : o->symbols()) {
Expected<uint64_t> AddressOrError = Symbol.getAddress();
if (!AddressOrError)
- report_error(ArchiveName, o->getFileName(), AddressOrError.takeError());
+ report_error(ArchiveName, o->getFileName(), AddressOrError.takeError(),
+ ArchitectureName);
uint64_t Address = *AddressOrError;
+ if ((Address < StartAddress) || (Address > StopAddress))
+ continue;
Expected<SymbolRef::Type> TypeOrError = Symbol.getType();
if (!TypeOrError)
- report_error(ArchiveName, o->getFileName(), TypeOrError.takeError());
+ report_error(ArchiveName, o->getFileName(), TypeOrError.takeError(),
+ ArchitectureName);
SymbolRef::Type Type = *TypeOrError;
uint32_t Flags = Symbol.getFlags();
Expected<section_iterator> SectionOrErr = Symbol.getSection();
- error(errorToErrorCode(SectionOrErr.takeError()));
+ if (!SectionOrErr)
+ report_error(ArchiveName, o->getFileName(), SectionOrErr.takeError(),
+ ArchitectureName);
section_iterator Section = *SectionOrErr;
StringRef Name;
if (Type == SymbolRef::ST_Debug && Section != o->section_end()) {
@@ -1629,27 +1928,20 @@ static void printFaultMaps(const ObjectFile *Obj) {
outs() << FMP;
}
-static void printPrivateFileHeaders(const ObjectFile *o) {
- if (o->isELF())
- printELFFileHeader(o);
- else if (o->isCOFF())
- printCOFFFileHeader(o);
- else if (o->isMachO()) {
- printMachOFileHeader(o);
- printMachOLoadCommands(o);
- } else
- report_fatal_error("Invalid/Unsupported object file format");
-}
-
-static void printFirstPrivateFileHeader(const ObjectFile *o) {
+static void printPrivateFileHeaders(const ObjectFile *o, bool onlyFirst) {
if (o->isELF())
- printELFFileHeader(o);
- else if (o->isCOFF())
- printCOFFFileHeader(o);
- else if (o->isMachO())
+ return printELFFileHeader(o);
+ if (o->isCOFF())
+ return printCOFFFileHeader(o);
+ if (o->isWasm())
+ return printWasmFileHeader(o);
+ if (o->isMachO()) {
printMachOFileHeader(o);
- else
- report_fatal_error("Invalid/Unsupported object file format");
+ if (!onlyFirst)
+ printMachOLoadCommands(o);
+ return;
+ }
+ report_error(o->getFileName(), "Invalid/Unsupported object file format");
}
static void DumpObject(const ObjectFile *o, const Archive *a = nullptr) {
@@ -1676,10 +1968,8 @@ static void DumpObject(const ObjectFile *o, const Archive *a = nullptr) {
PrintSymbolTable(o, ArchiveName);
if (UnwindInfo)
PrintUnwindInfo(o);
- if (PrivateHeaders)
- printPrivateFileHeaders(o);
- if (FirstPrivateHeader)
- printFirstPrivateFileHeader(o);
+ if (PrivateHeaders || FirstPrivateHeader)
+ printPrivateFileHeaders(o, FirstPrivateHeader);
if (ExportsTrie)
printExportsTrie(o);
if (Rebase)
@@ -1701,9 +1991,23 @@ static void DumpObject(const ObjectFile *o, const Archive *a = nullptr) {
}
}
+static void DumpObject(const COFFImportFile *I, const Archive *A) {
+ StringRef ArchiveName = A ? A->getFileName() : "";
+
+ // Avoid other output when using a raw option.
+ if (!RawClangAST)
+ outs() << '\n'
+ << ArchiveName << "(" << I->getFileName() << ")"
+ << ":\tfile format COFF-import-file"
+ << "\n\n";
+
+ if (SymbolTable)
+ printCOFFSymbolTable(I);
+}
+
/// @brief Dump each object file in \a a;
static void DumpArchive(const Archive *a) {
- Error Err;
+ Error Err = Error::success();
for (auto &C : a->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
@@ -1713,6 +2017,8 @@ static void DumpArchive(const Archive *a) {
}
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
DumpObject(o, a);
+ else if (COFFImportFile *I = dyn_cast<COFFImportFile>(&*ChildOrErr.get()))
+ DumpObject(I, a);
else
report_error(a->getFileName(), object_error::invalid_file_type);
}
@@ -1768,7 +2074,7 @@ int main(int argc, char **argv) {
if (InputFilenames.size() == 0)
InputFilenames.push_back("a.out");
- if (DisassembleAll)
+ if (DisassembleAll || PrintSource || PrintLines)
Disassemble = true;
if (!Disassemble
&& !Relocations
diff --git a/contrib/llvm/tools/llvm-objdump/llvm-objdump.h b/contrib/llvm/tools/llvm-objdump/llvm-objdump.h
index 5b10ee8..dace82a 100644
--- a/contrib/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/contrib/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -20,6 +20,7 @@ class StringRef;
namespace object {
class COFFObjectFile;
+ class COFFImportFile;
class MachOObjectFile;
class ObjectFile;
class Archive;
@@ -74,9 +75,11 @@ void printMachOLazyBindTable(const object::MachOObjectFile* o);
void printMachOWeakBindTable(const object::MachOObjectFile* o);
void printELFFileHeader(const object::ObjectFile *o);
void printCOFFFileHeader(const object::ObjectFile *o);
+void printCOFFSymbolTable(const object::COFFImportFile *i);
void printCOFFSymbolTable(const object::COFFObjectFile *o);
void printMachOFileHeader(const object::ObjectFile *o);
void printMachOLoadCommands(const object::ObjectFile *o);
+void printWasmFileHeader(const object::ObjectFile *o);
void printExportsTrie(const object::ObjectFile *o);
void printRebaseTable(const object::ObjectFile *o);
void printBindTable(const object::ObjectFile *o);
@@ -89,6 +92,7 @@ void PrintSectionContents(const object::ObjectFile *o);
void PrintSymbolTable(const object::ObjectFile *o, StringRef ArchiveName,
StringRef ArchitectureName = StringRef());
LLVM_ATTRIBUTE_NORETURN void error(Twine Message);
+LLVM_ATTRIBUTE_NORETURN void report_error(StringRef File, Twine Message);
LLVM_ATTRIBUTE_NORETURN void report_error(StringRef File, std::error_code EC);
LLVM_ATTRIBUTE_NORETURN void report_error(StringRef File, llvm::Error E);
LLVM_ATTRIBUTE_NORETURN void report_error(StringRef FileName,
OpenPOWER on IntegriCloud