aboutsummaryrefslogtreecommitdiffstats
path: root/tools/llvm-objdump
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-objdump')
-rw-r--r--tools/llvm-objdump/CMakeLists.txt3
-rw-r--r--tools/llvm-objdump/COFFDump.cpp427
-rw-r--r--tools/llvm-objdump/MachODump.cpp80
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp385
4 files changed, 534 insertions, 361 deletions
diff --git a/tools/llvm-objdump/CMakeLists.txt b/tools/llvm-objdump/CMakeLists.txt
index e983ec9..413cb9b 100644
--- a/tools/llvm-objdump/CMakeLists.txt
+++ b/tools/llvm-objdump/CMakeLists.txt
@@ -2,9 +2,8 @@ set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
DebugInfo
MC
- MCParser
- MCDisassembler
Object
+ Support
)
add_llvm_tool(llvm-objdump
diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp
index 5f0bcbb..49f2755 100644
--- a/tools/llvm-objdump/COFFDump.cpp
+++ b/tools/llvm-objdump/COFFDump.cpp
@@ -10,7 +10,7 @@
/// \file
/// \brief This file implements the COFF-specific dumper for llvm-objdump.
/// It outputs the Win64 EH data structures as plain text.
-/// The encoding of the unwind codes is decribed in MSDN:
+/// The encoding of the unwind codes is described in MSDN:
/// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
///
//===----------------------------------------------------------------------===//
@@ -94,7 +94,7 @@ static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
// slots is provided.
static void printUnwindCode(ArrayRef<UnwindCode> UCs) {
assert(UCs.size() >= getNumUsedSlots(UCs[0]));
- outs() << format(" 0x%02x: ", unsigned(UCs[0].u.CodeOffset))
+ outs() << format(" 0x%02x: ", unsigned(UCs[0].u.CodeOffset))
<< getUnwindCodeTypeName(UCs[0].getUnwindOp());
switch (UCs[0].getUnwindOp()) {
case UOP_PushNonVol:
@@ -161,10 +161,12 @@ static error_code resolveSectionAndAddress(const COFFObjectFile *Obj,
const SymbolRef &Sym,
const coff_section *&ResolvedSection,
uint64_t &ResolvedAddr) {
- if (error_code ec = Sym.getAddress(ResolvedAddr)) return ec;
- section_iterator iter(Obj->begin_sections());
- if (error_code ec = Sym.getSection(iter)) return ec;
- ResolvedSection = Obj->getCOFFSection(iter);
+ if (error_code EC = Sym.getAddress(ResolvedAddr))
+ return EC;
+ section_iterator iter(Obj->section_begin());
+ if (error_code EC = Sym.getSection(iter))
+ return EC;
+ ResolvedSection = Obj->getCOFFSection(*iter);
return object_error::success;
}
@@ -176,13 +178,14 @@ static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
E = Rels.end();
I != E; ++I) {
uint64_t Ofs;
- if (error_code ec = I->getOffset(Ofs)) return ec;
+ if (error_code EC = I->getOffset(Ofs))
+ return EC;
if (Ofs == Offset) {
Sym = *I->getSymbol();
- break;
+ return object_error::success;
}
}
- return object_error::success;
+ return object_error::parse_failed;
}
// Given a vector of relocations for a section and an offset into this section
@@ -195,11 +198,13 @@ static error_code getSectionContents(const COFFObjectFile *Obj,
ArrayRef<uint8_t> &Contents,
uint64_t &Addr) {
SymbolRef Sym;
- if (error_code ec = resolveSymbol(Rels, Offset, Sym)) return ec;
+ if (error_code EC = resolveSymbol(Rels, Offset, Sym))
+ return EC;
const coff_section *Section;
- if (error_code ec = resolveSectionAndAddress(Obj, Sym, Section, Addr))
- return ec;
- if (error_code ec = Obj->getSectionContents(Section, Contents)) return ec;
+ if (error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr))
+ return EC;
+ if (error_code EC = Obj->getSectionContents(Section, Contents))
+ return EC;
return object_error::success;
}
@@ -209,8 +214,10 @@ static error_code getSectionContents(const COFFObjectFile *Obj,
static error_code resolveSymbolName(const std::vector<RelocationRef> &Rels,
uint64_t Offset, StringRef &Name) {
SymbolRef Sym;
- if (error_code ec = resolveSymbol(Rels, Offset, Sym)) return ec;
- if (error_code ec = Sym.getName(Name)) return ec;
+ if (error_code EC = resolveSymbol(Rels, Offset, Sym))
+ return EC;
+ if (error_code EC = Sym.getName(Name))
+ return EC;
return object_error::success;
}
@@ -218,30 +225,95 @@ static void printCOFFSymbolAddress(llvm::raw_ostream &Out,
const std::vector<RelocationRef> &Rels,
uint64_t Offset, uint32_t Disp) {
StringRef Sym;
- if (error_code ec = resolveSymbolName(Rels, Offset, Sym)) {
- error(ec);
- return ;
+ if (!resolveSymbolName(Rels, Offset, Sym)) {
+ Out << Sym;
+ if (Disp > 0)
+ Out << format(" + 0x%04x", Disp);
+ } else {
+ Out << format("0x%04x", Disp);
}
- Out << Sym;
- if (Disp > 0)
- Out << format(" + 0x%04x", Disp);
+}
+
+static void
+printSEHTable(const COFFObjectFile *Obj, uint32_t TableVA, int Count) {
+ if (Count == 0)
+ return;
+
+ const pe32_header *PE32Header;
+ if (error(Obj->getPE32Header(PE32Header)))
+ return;
+ uint32_t ImageBase = PE32Header->ImageBase;
+ uintptr_t IntPtr = 0;
+ if (error(Obj->getVaPtr(TableVA, IntPtr)))
+ return;
+ const support::ulittle32_t *P = (const support::ulittle32_t *)IntPtr;
+ outs() << "SEH Table:";
+ for (int I = 0; I < Count; ++I)
+ outs() << format(" 0x%x", P[I] + ImageBase);
+ outs() << "\n\n";
+}
+
+static void printLoadConfiguration(const COFFObjectFile *Obj) {
+ // Skip if it's not executable.
+ const pe32_header *PE32Header;
+ if (error(Obj->getPE32Header(PE32Header)))
+ return;
+ if (!PE32Header)
+ return;
+
+ const coff_file_header *Header;
+ if (error(Obj->getCOFFHeader(Header)))
+ return;
+ // Currently only x86 is supported
+ if (Header->Machine != COFF::IMAGE_FILE_MACHINE_I386)
+ return;
+
+ const data_directory *DataDir;
+ if (error(Obj->getDataDirectory(COFF::LOAD_CONFIG_TABLE, DataDir)))
+ return;
+ uintptr_t IntPtr = 0;
+ if (DataDir->RelativeVirtualAddress == 0)
+ return;
+ if (error(Obj->getRvaPtr(DataDir->RelativeVirtualAddress, IntPtr)))
+ return;
+
+ auto *LoadConf = reinterpret_cast<const coff_load_configuration32 *>(IntPtr);
+ outs() << "Load configuration:"
+ << "\n Timestamp: " << LoadConf->TimeDateStamp
+ << "\n Major Version: " << LoadConf->MajorVersion
+ << "\n Minor Version: " << LoadConf->MinorVersion
+ << "\n GlobalFlags Clear: " << LoadConf->GlobalFlagsClear
+ << "\n GlobalFlags Set: " << LoadConf->GlobalFlagsSet
+ << "\n Critical Section Default Timeout: " << LoadConf->CriticalSectionDefaultTimeout
+ << "\n Decommit Free Block Threshold: " << LoadConf->DeCommitFreeBlockThreshold
+ << "\n Decommit Total Free Threshold: " << LoadConf->DeCommitTotalFreeThreshold
+ << "\n Lock Prefix Table: " << LoadConf->LockPrefixTable
+ << "\n Maximum Allocation Size: " << LoadConf->MaximumAllocationSize
+ << "\n Virtual Memory Threshold: " << LoadConf->VirtualMemoryThreshold
+ << "\n Process Affinity Mask: " << LoadConf->ProcessAffinityMask
+ << "\n Process Heap Flags: " << LoadConf->ProcessHeapFlags
+ << "\n CSD Version: " << LoadConf->CSDVersion
+ << "\n Security Cookie: " << LoadConf->SecurityCookie
+ << "\n SEH Table: " << LoadConf->SEHandlerTable
+ << "\n SEH Count: " << LoadConf->SEHandlerCount
+ << "\n\n";
+ printSEHTable(Obj, LoadConf->SEHandlerTable, LoadConf->SEHandlerCount);
+ outs() << "\n";
}
// Prints import tables. The import table is a table containing the list of
// DLL name and symbol names which will be linked by the loader.
static void printImportTables(const COFFObjectFile *Obj) {
+ import_directory_iterator I = Obj->import_directory_begin();
+ import_directory_iterator E = Obj->import_directory_end();
+ if (I == E)
+ return;
outs() << "The Import Tables:\n";
- error_code ec;
- for (import_directory_iterator i = Obj->import_directory_begin(),
- e = Obj->import_directory_end();
- i != e; i = i.increment(ec)) {
- if (ec)
- return;
-
+ for (; I != E; I = ++I) {
const import_directory_table_entry *Dir;
StringRef Name;
- if (i->getImportTableEntry(Dir)) return;
- if (i->getName(Name)) return;
+ if (I->getImportTableEntry(Dir)) return;
+ if (I->getName(Name)) return;
outs() << format(" lookup %08x time %08x fwd %08x name %08x addr %08x\n\n",
static_cast<uint32_t>(Dir->ImportLookupTableRVA),
@@ -252,7 +324,7 @@ static void printImportTables(const COFFObjectFile *Obj) {
outs() << " DLL Name: " << Name << "\n";
outs() << " Hint/Ord Name\n";
const import_lookup_table_entry32 *entry;
- if (i->getImportLookupEntry(entry))
+ if (I->getImportLookupEntry(entry))
return;
for (; entry->data; ++entry) {
if (entry->isOrdinal()) {
@@ -269,133 +341,218 @@ static void printImportTables(const COFFObjectFile *Obj) {
}
}
-void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) {
- const coff_file_header *Header;
- if (error(Obj->getCOFFHeader(Header))) return;
-
- if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) {
- errs() << "Unsupported image machine type "
- "(currently only AMD64 is supported).\n";
+// Prints export tables. The export table is a table containing the list of
+// exported symbol from the DLL.
+static void printExportTable(const COFFObjectFile *Obj) {
+ outs() << "Export Table:\n";
+ export_directory_iterator I = Obj->export_directory_begin();
+ export_directory_iterator E = Obj->export_directory_end();
+ if (I == E)
return;
- }
-
- const coff_section *Pdata = 0;
-
- error_code ec;
- for (section_iterator SI = Obj->begin_sections(),
- SE = Obj->end_sections();
- SI != SE; SI.increment(ec)) {
- if (error(ec)) return;
+ StringRef DllName;
+ uint32_t OrdinalBase;
+ if (I->getDllName(DllName))
+ return;
+ if (I->getOrdinalBase(OrdinalBase))
+ return;
+ outs() << " DLL name: " << DllName << "\n";
+ outs() << " Ordinal base: " << OrdinalBase << "\n";
+ outs() << " Ordinal RVA Name\n";
+ for (; I != E; I = ++I) {
+ uint32_t Ordinal;
+ if (I->getOrdinal(Ordinal))
+ return;
+ uint32_t RVA;
+ if (I->getExportRVA(RVA))
+ return;
+ outs() << format(" % 4d %# 8x", Ordinal, RVA);
StringRef Name;
- if (error(SI->getName(Name))) continue;
+ if (I->getSymbolName(Name))
+ continue;
+ if (!Name.empty())
+ outs() << " " << Name;
+ outs() << "\n";
+ }
+}
- if (Name != ".pdata") continue;
+// Given the COFF object file, this function returns the relocations for .pdata
+// and the pointer to "runtime function" structs.
+static bool getPDataSection(const COFFObjectFile *Obj,
+ std::vector<RelocationRef> &Rels,
+ const RuntimeFunction *&RFStart, int &NumRFs) {
+ for (const SectionRef &Section : Obj->sections()) {
+ StringRef Name;
+ if (error(Section.getName(Name)))
+ continue;
+ if (Name != ".pdata")
+ continue;
- Pdata = Obj->getCOFFSection(SI);
- std::vector<RelocationRef> Rels;
- for (relocation_iterator RI = SI->begin_relocations(),
- RE = SI->end_relocations();
- RI != RE; RI.increment(ec)) {
- if (error(ec)) break;
- Rels.push_back(*RI);
- }
+ const coff_section *Pdata = Obj->getCOFFSection(Section);
+ for (const RelocationRef &Reloc : Section.relocations())
+ Rels.push_back(Reloc);
// Sort relocations by address.
std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
ArrayRef<uint8_t> Contents;
- if (error(Obj->getSectionContents(Pdata, Contents))) continue;
- if (Contents.empty()) continue;
+ if (error(Obj->getSectionContents(Pdata, Contents)))
+ continue;
+ if (Contents.empty())
+ continue;
+
+ RFStart = reinterpret_cast<const RuntimeFunction *>(Contents.data());
+ NumRFs = Contents.size() / sizeof(RuntimeFunction);
+ return true;
+ }
+ return false;
+}
- ArrayRef<RuntimeFunction> RFs(
- reinterpret_cast<const RuntimeFunction *>(Contents.data()),
- Contents.size() / sizeof(RuntimeFunction));
- for (const RuntimeFunction *I = RFs.begin(), *E = RFs.end(); I < E; ++I) {
- const uint64_t SectionOffset = std::distance(RFs.begin(), I)
- * sizeof(RuntimeFunction);
+static void printWin64EHUnwindInfo(const Win64EH::UnwindInfo *UI) {
+ // The casts to int are required in order to output the value as number.
+ // Without the casts the value would be interpreted as char data (which
+ // results in garbage output).
+ outs() << " Version: " << static_cast<int>(UI->getVersion()) << "\n";
+ outs() << " Flags: " << static_cast<int>(UI->getFlags());
+ if (UI->getFlags()) {
+ if (UI->getFlags() & UNW_ExceptionHandler)
+ outs() << " UNW_ExceptionHandler";
+ if (UI->getFlags() & UNW_TerminateHandler)
+ outs() << " UNW_TerminateHandler";
+ if (UI->getFlags() & UNW_ChainInfo)
+ outs() << " UNW_ChainInfo";
+ }
+ outs() << "\n";
+ outs() << " Size of prolog: " << static_cast<int>(UI->PrologSize) << "\n";
+ outs() << " Number of Codes: " << static_cast<int>(UI->NumCodes) << "\n";
+ // Maybe this should move to output of UOP_SetFPReg?
+ if (UI->getFrameRegister()) {
+ outs() << " Frame register: "
+ << getUnwindRegisterName(UI->getFrameRegister()) << "\n";
+ outs() << " Frame offset: " << 16 * UI->getFrameOffset() << "\n";
+ } else {
+ outs() << " No frame pointer used\n";
+ }
+ if (UI->getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
+ // FIXME: Output exception handler data
+ } else if (UI->getFlags() & UNW_ChainInfo) {
+ // FIXME: Output chained unwind info
+ }
- outs() << "Function Table:\n";
+ if (UI->NumCodes)
+ outs() << " Unwind Codes:\n";
- outs() << " Start Address: ";
- printCOFFSymbolAddress(outs(), Rels, SectionOffset +
+ printAllUnwindCodes(ArrayRef<UnwindCode>(&UI->UnwindCodes[0], UI->NumCodes));
+
+ outs() << "\n";
+ outs().flush();
+}
+
+/// Prints out the given RuntimeFunction struct for x64, assuming that Obj is
+/// pointing to an executable file.
+static void printRuntimeFunction(const COFFObjectFile *Obj,
+ const RuntimeFunction &RF) {
+ if (!RF.StartAddress)
+ return;
+ outs() << "Function Table:\n"
+ << format(" Start Address: 0x%04x\n",
+ static_cast<uint32_t>(RF.StartAddress))
+ << format(" End Address: 0x%04x\n",
+ static_cast<uint32_t>(RF.EndAddress))
+ << format(" Unwind Info Address: 0x%04x\n",
+ static_cast<uint32_t>(RF.UnwindInfoOffset));
+ uintptr_t addr;
+ if (Obj->getRvaPtr(RF.UnwindInfoOffset, addr))
+ return;
+ printWin64EHUnwindInfo(reinterpret_cast<const Win64EH::UnwindInfo *>(addr));
+}
+
+/// Prints out the given RuntimeFunction struct for x64, assuming that Obj is
+/// pointing to an object file. Unlike executable, fields in RuntimeFunction
+/// struct are filled with zeros, but instead there are relocations pointing to
+/// them so that the linker will fill targets' RVAs to the fields at link
+/// time. This function interprets the relocations to find the data to be used
+/// in the resulting executable.
+static void printRuntimeFunctionRels(const COFFObjectFile *Obj,
+ const RuntimeFunction &RF,
+ uint64_t SectionOffset,
+ const std::vector<RelocationRef> &Rels) {
+ outs() << "Function Table:\n";
+ outs() << " Start Address: ";
+ printCOFFSymbolAddress(outs(), Rels,
+ SectionOffset +
/*offsetof(RuntimeFunction, StartAddress)*/ 0,
- I->StartAddress);
- outs() << "\n";
+ RF.StartAddress);
+ outs() << "\n";
- outs() << " End Address: ";
- printCOFFSymbolAddress(outs(), Rels, SectionOffset +
+ outs() << " End Address: ";
+ printCOFFSymbolAddress(outs(), Rels,
+ SectionOffset +
/*offsetof(RuntimeFunction, EndAddress)*/ 4,
- I->EndAddress);
- outs() << "\n";
+ RF.EndAddress);
+ outs() << "\n";
- outs() << " Unwind Info Address: ";
- printCOFFSymbolAddress(outs(), Rels, SectionOffset +
+ outs() << " Unwind Info Address: ";
+ printCOFFSymbolAddress(outs(), Rels,
+ SectionOffset +
/*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
- I->UnwindInfoOffset);
- outs() << "\n";
-
- ArrayRef<uint8_t> XContents;
- uint64_t UnwindInfoOffset = 0;
- if (error(getSectionContents(Obj, Rels, SectionOffset +
- /*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
- XContents, UnwindInfoOffset))) continue;
- if (XContents.empty()) continue;
-
- UnwindInfoOffset += I->UnwindInfoOffset;
- if (UnwindInfoOffset > XContents.size()) continue;
-
- const Win64EH::UnwindInfo *UI =
- reinterpret_cast<const Win64EH::UnwindInfo *>
- (XContents.data() + UnwindInfoOffset);
-
- // The casts to int are required in order to output the value as number.
- // Without the casts the value would be interpreted as char data (which
- // results in garbage output).
- outs() << " Version: " << static_cast<int>(UI->getVersion()) << "\n";
- outs() << " Flags: " << static_cast<int>(UI->getFlags());
- if (UI->getFlags()) {
- if (UI->getFlags() & UNW_ExceptionHandler)
- outs() << " UNW_ExceptionHandler";
- if (UI->getFlags() & UNW_TerminateHandler)
- outs() << " UNW_TerminateHandler";
- if (UI->getFlags() & UNW_ChainInfo)
- outs() << " UNW_ChainInfo";
- }
- outs() << "\n";
- outs() << " Size of prolog: "
- << static_cast<int>(UI->PrologSize) << "\n";
- outs() << " Number of Codes: "
- << static_cast<int>(UI->NumCodes) << "\n";
- // Maybe this should move to output of UOP_SetFPReg?
- if (UI->getFrameRegister()) {
- outs() << " Frame register: "
- << getUnwindRegisterName(UI->getFrameRegister())
- << "\n";
- outs() << " Frame offset: "
- << 16 * UI->getFrameOffset()
- << "\n";
- } else {
- outs() << " No frame pointer used\n";
- }
- if (UI->getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
- // FIXME: Output exception handler data
- } else if (UI->getFlags() & UNW_ChainInfo) {
- // FIXME: Output chained unwind info
- }
+ RF.UnwindInfoOffset);
+ outs() << "\n";
- if (UI->NumCodes)
- outs() << " Unwind Codes:\n";
+ ArrayRef<uint8_t> XContents;
+ uint64_t UnwindInfoOffset = 0;
+ if (error(getSectionContents(
+ Obj, Rels, SectionOffset +
+ /*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
+ XContents, UnwindInfoOffset)))
+ return;
+ if (XContents.empty())
+ return;
- printAllUnwindCodes(ArrayRef<UnwindCode>(&UI->UnwindCodes[0],
- UI->NumCodes));
+ UnwindInfoOffset += RF.UnwindInfoOffset;
+ if (UnwindInfoOffset > XContents.size())
+ return;
- outs() << "\n\n";
- outs().flush();
- }
+ auto *UI = reinterpret_cast<const Win64EH::UnwindInfo *>(XContents.data() +
+ UnwindInfoOffset);
+ printWin64EHUnwindInfo(UI);
+}
+
+void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) {
+ const coff_file_header *Header;
+ if (error(Obj->getCOFFHeader(Header)))
+ return;
+
+ if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) {
+ errs() << "Unsupported image machine type "
+ "(currently only AMD64 is supported).\n";
+ return;
+ }
+
+ std::vector<RelocationRef> Rels;
+ const RuntimeFunction *RFStart;
+ int NumRFs;
+ if (!getPDataSection(Obj, Rels, RFStart, NumRFs))
+ return;
+ ArrayRef<RuntimeFunction> RFs(RFStart, NumRFs);
+
+ bool IsExecutable = Rels.empty();
+ if (IsExecutable) {
+ for (const RuntimeFunction &RF : RFs)
+ printRuntimeFunction(Obj, RF);
+ return;
+ }
+
+ for (const RuntimeFunction &RF : RFs) {
+ uint64_t SectionOffset =
+ std::distance(RFs.begin(), &RF) * sizeof(RuntimeFunction);
+ printRuntimeFunctionRels(Obj, RF, SectionOffset, Rels);
}
}
void llvm::printCOFFFileHeader(const object::ObjectFile *Obj) {
- printImportTables(dyn_cast<const COFFObjectFile>(Obj));
+ const COFFObjectFile *file = dyn_cast<const COFFObjectFile>(Obj);
+ printLoadConfiguration(file);
+ printImportTables(file);
+ printExportTable(file);
}
diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp
index 86923fd..89b038f 100644
--- a/tools/llvm-objdump/MachODump.cpp
+++ b/tools/llvm-objdump/MachODump.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "llvm-objdump.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
@@ -147,28 +146,23 @@ static void DumpDataInCode(const char *bytes, uint64_t Size,
}
}
-static void
-getSectionsAndSymbols(const MachO::mach_header Header,
- MachOObjectFile *MachOObj,
- std::vector<SectionRef> &Sections,
- std::vector<SymbolRef> &Symbols,
- SmallVectorImpl<uint64_t> &FoundFns,
- uint64_t &BaseSegmentAddress) {
- error_code ec;
- for (symbol_iterator SI = MachOObj->begin_symbols(),
- SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
- Symbols.push_back(*SI);
-
- for (section_iterator SI = MachOObj->begin_sections(),
- SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) {
- SectionRef SR = *SI;
+static void getSectionsAndSymbols(const MachO::mach_header Header,
+ MachOObjectFile *MachOObj,
+ std::vector<SectionRef> &Sections,
+ std::vector<SymbolRef> &Symbols,
+ SmallVectorImpl<uint64_t> &FoundFns,
+ uint64_t &BaseSegmentAddress) {
+ for (const SymbolRef &Symbol : MachOObj->symbols())
+ Symbols.push_back(Symbol);
+
+ for (const SectionRef &Section : MachOObj->sections()) {
StringRef SectName;
- SR.getName(SectName);
- Sections.push_back(*SI);
+ Section.getName(SectName);
+ Sections.push_back(Section);
}
MachOObjectFile::LoadCommandInfo Command =
- MachOObj->getFirstLoadCommandInfo();
+ MachOObj->getFirstLoadCommandInfo();
bool BaseSegmentAddressSet = false;
for (unsigned i = 0; ; ++i) {
if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
@@ -200,15 +194,15 @@ static void DisassembleInputMachO2(StringRef Filename,
MachOObjectFile *MachOOF);
void llvm::DisassembleInputMachO(StringRef Filename) {
- OwningPtr<MemoryBuffer> Buff;
+ std::unique_ptr<MemoryBuffer> Buff;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n";
return;
}
- OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>(
- ObjectFile::createMachOObjectFile(Buff.take())));
+ std::unique_ptr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile *>(
+ ObjectFile::createMachOObjectFile(Buff.release()).get()));
DisassembleInputMachO2(Filename, MachOOF.get());
}
@@ -220,21 +214,22 @@ static void DisassembleInputMachO2(StringRef Filename,
// GetTarget prints out stuff.
return;
}
- OwningPtr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
- OwningPtr<MCInstrAnalysis>
- InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get()));
+ std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
+ std::unique_ptr<MCInstrAnalysis> InstrAnalysis(
+ TheTarget->createMCInstrAnalysis(InstrInfo.get()));
// Set up disassembler.
- OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
- OwningPtr<const MCAsmInfo> AsmInfo(
+ std::unique_ptr<const MCRegisterInfo> MRI(
+ TheTarget->createMCRegInfo(TripleName));
+ std::unique_ptr<const MCAsmInfo> AsmInfo(
TheTarget->createMCAsmInfo(*MRI, TripleName));
- OwningPtr<const MCSubtargetInfo>
- STI(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
- OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
+ std::unique_ptr<const MCSubtargetInfo> STI(
+ TheTarget->createMCSubtargetInfo(TripleName, "", ""));
+ std::unique_ptr<const MCDisassembler> DisAsm(
+ TheTarget->createMCDisassembler(*STI));
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
- OwningPtr<MCInstPrinter>
- IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo,
- *MRI, *STI));
+ std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
+ AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI, *STI));
if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) {
errs() << "error: couldn't initialize disassembler for target "
@@ -270,9 +265,8 @@ static void DisassembleInputMachO2(StringRef Filename,
else
BaseAddress = BaseSegmentAddress;
DiceTable Dices;
- error_code ec;
for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
- DI != DE; DI.increment(ec)){
+ DI != DE; ++DI) {
uint32_t Offset;
DI->getOffset(Offset);
Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
@@ -285,19 +279,19 @@ static void DisassembleInputMachO2(StringRef Filename,
raw_ostream &DebugOut = nulls();
#endif
- OwningPtr<DIContext> diContext;
+ std::unique_ptr<DIContext> diContext;
ObjectFile *DbgObj = MachOOF;
// Try to find debug info and set up the DIContext for it.
if (UseDbg) {
// A separate DSym file path was specified, parse it as a macho file,
// get the sections and supply it to the section name parsing machinery.
if (!DSYMFile.empty()) {
- OwningPtr<MemoryBuffer> Buf;
+ std::unique_ptr<MemoryBuffer> Buf;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile, Buf)) {
errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
return;
}
- DbgObj = ObjectFile::createMachOObjectFile(Buf.take());
+ DbgObj = ObjectFile::createMachOObjectFile(Buf.release()).get();
}
// Setup the DIContext
@@ -328,16 +322,14 @@ static void DisassembleInputMachO2(StringRef Filename,
bool symbolTableWorked = false;
// Parse relocations.
- std::vector<std::pair<uint64_t, SymbolRef> > Relocs;
- error_code ec;
- for (relocation_iterator RI = Sections[SectIdx].begin_relocations(),
- RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) {
+ std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
+ for (const RelocationRef &Reloc : Sections[SectIdx].relocations()) {
uint64_t RelocOffset, SectionAddress;
- RI->getOffset(RelocOffset);
+ Reloc.getOffset(RelocOffset);
Sections[SectIdx].getAddress(SectionAddress);
RelocOffset -= SectionAddress;
- symbol_iterator RelocSym = RI->getSymbol();
+ symbol_iterator RelocSym = Reloc.getSymbol();
Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
}
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 9bc092e..729fcba 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -17,7 +17,6 @@
//===----------------------------------------------------------------------===//
#include "llvm-objdump.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
@@ -149,10 +148,11 @@ YAMLCFG("yaml-cfg",
static StringRef ToolName;
-bool llvm::error(error_code ec) {
- if (!ec) return false;
+bool llvm::error(error_code EC) {
+ if (!EC)
+ return false;
- outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
+ outs() << ToolName << ": error reading file: " << EC.message() << ".\n";
outs().flush();
return true;
}
@@ -166,7 +166,7 @@ static const Target *getTarget(const ObjectFile *Obj = NULL) {
// TheTriple defaults to ELF, and COFF doesn't have an environment:
// the best we can do here is indicate that it is mach-o.
if (Obj->isMachO())
- TheTriple.setEnvironment(Triple::MachO);
+ TheTriple.setObjectFormat(Triple::MachO);
}
} else
TheTriple.setTriple(Triple::normalize(TripleName));
@@ -191,7 +191,7 @@ static void emitDOTFile(const char *FileName, const MCFunction &f,
MCInstPrinter *IP) {
// Start a new dot file.
std::string Error;
- raw_fd_ostream Out(FileName, Error);
+ raw_fd_ostream Out(FileName, Error, sys::fs::F_Text);
if (!Error.empty()) {
errs() << "llvm-objdump: warning: " << Error << '\n';
return;
@@ -281,60 +281,62 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
FeaturesStr = Features.getString();
}
- OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
+ std::unique_ptr<const MCRegisterInfo> MRI(
+ TheTarget->createMCRegInfo(TripleName));
if (!MRI) {
errs() << "error: no register info for target " << TripleName << "\n";
return;
}
// Set up disassembler.
- OwningPtr<const MCAsmInfo> AsmInfo(
- TheTarget->createMCAsmInfo(*MRI, TripleName));
+ std::unique_ptr<const MCAsmInfo> AsmInfo(
+ TheTarget->createMCAsmInfo(*MRI, TripleName));
if (!AsmInfo) {
errs() << "error: no assembly info for target " << TripleName << "\n";
return;
}
- OwningPtr<const MCSubtargetInfo> STI(
- TheTarget->createMCSubtargetInfo(TripleName, "", FeaturesStr));
+ std::unique_ptr<const MCSubtargetInfo> STI(
+ TheTarget->createMCSubtargetInfo(TripleName, "", FeaturesStr));
if (!STI) {
errs() << "error: no subtarget info for target " << TripleName << "\n";
return;
}
- OwningPtr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
+ std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
if (!MII) {
errs() << "error: no instruction info for target " << TripleName << "\n";
return;
}
- OwningPtr<MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
+ std::unique_ptr<MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
if (!DisAsm) {
errs() << "error: no disassembler for target " << TripleName << "\n";
return;
}
- OwningPtr<const MCObjectFileInfo> MOFI;
- OwningPtr<MCContext> Ctx;
+ std::unique_ptr<const MCObjectFileInfo> MOFI;
+ std::unique_ptr<MCContext> Ctx;
if (Symbolize) {
MOFI.reset(new MCObjectFileInfo);
Ctx.reset(new MCContext(AsmInfo.get(), MRI.get(), MOFI.get()));
- OwningPtr<MCRelocationInfo> RelInfo(
- TheTarget->createMCRelocationInfo(TripleName, *Ctx.get()));
+ std::unique_ptr<MCRelocationInfo> RelInfo(
+ TheTarget->createMCRelocationInfo(TripleName, *Ctx.get()));
if (RelInfo) {
- OwningPtr<MCSymbolizer> Symzer(
- MCObjectSymbolizer::createObjectSymbolizer(*Ctx.get(), RelInfo, Obj));
+ std::unique_ptr<MCSymbolizer> Symzer(
+ MCObjectSymbolizer::createObjectSymbolizer(*Ctx.get(),
+ std::move(RelInfo), Obj));
if (Symzer)
- DisAsm->setSymbolizer(Symzer);
+ DisAsm->setSymbolizer(std::move(Symzer));
}
}
- OwningPtr<const MCInstrAnalysis>
- MIA(TheTarget->createMCInstrAnalysis(MII.get()));
+ std::unique_ptr<const MCInstrAnalysis> MIA(
+ TheTarget->createMCInstrAnalysis(MII.get()));
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
- OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
+ std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
if (!IP) {
errs() << "error: no instruction printer for target " << TripleName
@@ -343,9 +345,9 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
}
if (CFG || !YAMLCFG.empty()) {
- OwningPtr<MCObjectDisassembler> OD(
- new MCObjectDisassembler(*Obj, *DisAsm, *MIA));
- OwningPtr<MCModule> Mod(OD->buildModule(/* withCFG */ true));
+ std::unique_ptr<MCObjectDisassembler> OD(
+ new MCObjectDisassembler(*Obj, *DisAsm, *MIA));
+ std::unique_ptr<MCModule> Mod(OD->buildModule(/* withCFG */ true));
for (MCModule::const_atom_iterator AI = Mod->atom_begin(),
AE = Mod->atom_end();
AI != AE; ++AI) {
@@ -372,7 +374,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
}
if (!YAMLCFG.empty()) {
std::string Error;
- raw_fd_ostream YAMLOut(YAMLCFG.c_str(), Error);
+ raw_fd_ostream YAMLOut(YAMLCFG.c_str(), Error, sys::fs::F_Text);
if (!Error.empty()) {
errs() << ToolName << ": warning: " << Error << '\n';
return;
@@ -381,33 +383,51 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
}
}
+ StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " :
+ "\t\t\t%08" PRIx64 ": ";
+
+ // Create a mapping, RelocSecs = SectionRelocMap[S], where sections
+ // in RelocSecs contain the relocations for section S.
+ error_code EC;
+ std::map<SectionRef, SmallVector<SectionRef, 1>> SectionRelocMap;
+ for (const SectionRef &Section : Obj->sections()) {
+ section_iterator Sec2 = Section.getRelocatedSection();
+ if (Sec2 != Obj->section_end())
+ SectionRelocMap[*Sec2].push_back(Section);
+ }
- error_code ec;
- for (section_iterator i = Obj->begin_sections(),
- e = Obj->end_sections();
- i != e; i.increment(ec)) {
- if (error(ec)) break;
- bool text;
- if (error(i->isText(text))) break;
- if (!text) continue;
+ for (const SectionRef &Section : Obj->sections()) {
+ bool Text;
+ if (error(Section.isText(Text)))
+ break;
+ if (!Text)
+ continue;
uint64_t SectionAddr;
- if (error(i->getAddress(SectionAddr))) break;
+ if (error(Section.getAddress(SectionAddr)))
+ break;
+
+ uint64_t SectSize;
+ if (error(Section.getSize(SectSize)))
+ break;
// Make a list of all the symbols in this section.
- std::vector<std::pair<uint64_t, StringRef> > Symbols;
- for (symbol_iterator si = Obj->begin_symbols(),
- se = Obj->end_symbols();
- si != se; si.increment(ec)) {
+ std::vector<std::pair<uint64_t, StringRef>> Symbols;
+ for (const SymbolRef &Symbol : Obj->symbols()) {
bool contains;
- if (!error(i->containsSymbol(*si, contains)) && contains) {
+ if (!error(Section.containsSymbol(Symbol, contains)) && contains) {
uint64_t Address;
- if (error(si->getAddress(Address))) break;
- if (Address == UnknownAddressOrSize) continue;
+ if (error(Symbol.getAddress(Address)))
+ break;
+ if (Address == UnknownAddressOrSize)
+ continue;
Address -= SectionAddr;
+ if (Address >= SectSize)
+ continue;
StringRef Name;
- if (error(si->getName(Name))) break;
+ if (error(Symbol.getName(Name)))
+ break;
Symbols.push_back(std::make_pair(Address, Name));
}
}
@@ -418,11 +438,10 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
// Make a list of all the relocations for this section.
std::vector<RelocationRef> Rels;
if (InlineRelocs) {
- for (relocation_iterator ri = i->begin_relocations(),
- re = i->end_relocations();
- ri != re; ri.increment(ec)) {
- if (error(ec)) break;
- Rels.push_back(*ri);
+ for (const SectionRef &RelocSec : SectionRelocMap[Section]) {
+ for (const RelocationRef &Reloc : RelocSec.relocations()) {
+ Rels.push_back(Reloc);
+ }
}
}
@@ -430,13 +449,13 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
StringRef SegmentName = "";
- if (const MachOObjectFile *MachO =
- dyn_cast<const MachOObjectFile>(Obj)) {
- DataRefImpl DR = i->getRawDataRefImpl();
+ if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) {
+ DataRefImpl DR = Section.getRawDataRefImpl();
SegmentName = MachO->getSectionFinalSegmentName(DR);
}
StringRef name;
- if (error(i->getName(name))) break;
+ if (error(Section.getName(name)))
+ break;
outs() << "Disassembly of section ";
if (!SegmentName.empty())
outs() << SegmentName << ",";
@@ -452,12 +471,11 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
raw_svector_ostream CommentStream(Comments);
StringRef Bytes;
- if (error(i->getContents(Bytes))) break;
+ if (error(Section.getContents(Bytes)))
+ break;
StringRefMemoryObject memoryObject(Bytes, SectionAddr);
uint64_t Size;
uint64_t Index;
- uint64_t SectSize;
- if (error(i->getSize(SectSize))) break;
std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
@@ -479,9 +497,9 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
outs() << '\n' << Symbols[si].second << ":\n";
#ifndef NDEBUG
- raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
+ raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
#else
- raw_ostream &DebugOut = nulls();
+ raw_ostream &DebugOut = nulls();
#endif
for (Index = Start; Index < End; Index += Size) {
@@ -522,7 +540,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
if (error(rel_cur->getValueString(val))) goto skip_print_rel;
- outs() << format("\t\t\t%8" PRIx64 ": ", SectionAddr + addr) << name
+ outs() << format(Fmt.data(), SectionAddr + addr) << name
<< "\t" << val << "\n";
skip_print_rel:
@@ -533,76 +551,82 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
}
}
-static void PrintRelocations(const ObjectFile *o) {
- error_code ec;
- for (section_iterator si = o->begin_sections(), se = o->end_sections();
- si != se; si.increment(ec)){
- if (error(ec)) return;
- if (si->begin_relocations() == si->end_relocations())
+static void PrintRelocations(const ObjectFile *Obj) {
+ StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
+ "%08" PRIx64;
+ for (const SectionRef &Section : Obj->sections()) {
+ if (Section.relocation_begin() == Section.relocation_end())
continue;
StringRef secname;
- if (error(si->getName(secname))) continue;
+ if (error(Section.getName(secname)))
+ continue;
outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
- for (relocation_iterator ri = si->begin_relocations(),
- re = si->end_relocations();
- ri != re; ri.increment(ec)) {
- if (error(ec)) return;
-
+ for (const RelocationRef &Reloc : Section.relocations()) {
bool hidden;
uint64_t address;
SmallString<32> relocname;
SmallString<32> valuestr;
- if (error(ri->getHidden(hidden))) continue;
- if (hidden) continue;
- if (error(ri->getTypeName(relocname))) continue;
- if (error(ri->getOffset(address))) continue;
- if (error(ri->getValueString(valuestr))) continue;
- outs() << address << " " << relocname << " " << valuestr << "\n";
+ if (error(Reloc.getHidden(hidden)))
+ continue;
+ if (hidden)
+ continue;
+ if (error(Reloc.getTypeName(relocname)))
+ continue;
+ if (error(Reloc.getOffset(address)))
+ continue;
+ if (error(Reloc.getValueString(valuestr)))
+ continue;
+ outs() << format(Fmt.data(), address) << " " << relocname << " "
+ << valuestr << "\n";
}
outs() << "\n";
}
}
-static void PrintSectionHeaders(const ObjectFile *o) {
+static void PrintSectionHeaders(const ObjectFile *Obj) {
outs() << "Sections:\n"
"Idx Name Size Address Type\n";
- error_code ec;
unsigned i = 0;
- for (section_iterator si = o->begin_sections(), se = o->end_sections();
- si != se; si.increment(ec)) {
- if (error(ec)) return;
+ for (const SectionRef &Section : Obj->sections()) {
StringRef Name;
- if (error(si->getName(Name))) return;
+ if (error(Section.getName(Name)))
+ return;
uint64_t Address;
- if (error(si->getAddress(Address))) return;
+ if (error(Section.getAddress(Address)))
+ return;
uint64_t Size;
- if (error(si->getSize(Size))) return;
+ if (error(Section.getSize(Size)))
+ return;
bool Text, Data, BSS;
- if (error(si->isText(Text))) return;
- if (error(si->isData(Data))) return;
- if (error(si->isBSS(BSS))) return;
+ if (error(Section.isText(Text)))
+ return;
+ if (error(Section.isData(Data)))
+ return;
+ if (error(Section.isBSS(BSS)))
+ return;
std::string Type = (std::string(Text ? "TEXT " : "") +
(Data ? "DATA " : "") + (BSS ? "BSS" : ""));
- outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n",
- i, Name.str().c_str(), Size, Address, Type.c_str());
+ outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n", i,
+ Name.str().c_str(), Size, Address, Type.c_str());
++i;
}
}
-static void PrintSectionContents(const ObjectFile *o) {
- error_code ec;
- for (section_iterator si = o->begin_sections(),
- se = o->end_sections();
- si != se; si.increment(ec)) {
- if (error(ec)) return;
+static void PrintSectionContents(const ObjectFile *Obj) {
+ error_code EC;
+ for (const SectionRef &Section : Obj->sections()) {
StringRef Name;
StringRef Contents;
uint64_t BaseAddr;
bool BSS;
- if (error(si->getName(Name))) continue;
- if (error(si->getContents(Contents))) continue;
- if (error(si->getAddress(BaseAddr))) continue;
- if (error(si->isBSS(BSS))) continue;
+ if (error(Section.getName(Name)))
+ continue;
+ if (error(Section.getContents(Contents)))
+ continue;
+ if (error(Section.getAddress(BaseAddr)))
+ continue;
+ if (error(Section.isBSS(BSS)))
+ continue;
outs() << "Contents of section " << Name << ":\n";
if (BSS) {
@@ -646,8 +670,7 @@ static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) {
if (aux_count--) {
// Figure out which type of aux this is.
- if (symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC
- && symbol->Value == 0) { // Section definition.
+ if (symbol->isSectionDefinition()) { // Section definition.
const coff_aux_section_definition *asd;
if (error(coff->getAuxSymbol<coff_aux_section_definition>(i, asd)))
return;
@@ -682,78 +705,79 @@ static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
static void PrintSymbolTable(const ObjectFile *o) {
outs() << "SYMBOL TABLE:\n";
- if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o))
+ if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o)) {
PrintCOFFSymbolTable(coff);
- else {
- error_code ec;
- for (symbol_iterator si = o->begin_symbols(),
- se = o->end_symbols(); si != se; si.increment(ec)) {
- if (error(ec)) return;
- StringRef Name;
- uint64_t Address;
- SymbolRef::Type Type;
- uint64_t Size;
- uint32_t Flags;
- section_iterator Section = o->end_sections();
- if (error(si->getName(Name))) continue;
- if (error(si->getAddress(Address))) continue;
- if (error(si->getFlags(Flags))) continue;
- if (error(si->getType(Type))) continue;
- if (error(si->getSize(Size))) continue;
- if (error(si->getSection(Section))) continue;
-
- bool Global = Flags & SymbolRef::SF_Global;
- bool Weak = Flags & SymbolRef::SF_Weak;
- bool Absolute = Flags & SymbolRef::SF_Absolute;
-
- if (Address == UnknownAddressOrSize)
- Address = 0;
- if (Size == UnknownAddressOrSize)
- Size = 0;
- char GlobLoc = ' ';
- if (Type != SymbolRef::ST_Unknown)
- GlobLoc = Global ? 'g' : 'l';
- char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
- ? 'd' : ' ';
- char FileFunc = ' ';
- if (Type == SymbolRef::ST_File)
- FileFunc = 'f';
- else if (Type == SymbolRef::ST_Function)
- FileFunc = 'F';
-
- const char *Fmt = o->getBytesInAddress() > 4 ? "%016" PRIx64 :
- "%08" PRIx64;
-
- outs() << format(Fmt, Address) << " "
- << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
- << (Weak ? 'w' : ' ') // Weak?
- << ' ' // Constructor. Not supported yet.
- << ' ' // Warning. Not supported yet.
- << ' ' // Indirect reference to another symbol.
- << Debug // Debugging (d) or dynamic (D) symbol.
- << FileFunc // Name of function (F), file (f) or object (O).
- << ' ';
- if (Absolute)
- outs() << "*ABS*";
- else if (Section == o->end_sections())
- outs() << "*UND*";
- else {
- if (const MachOObjectFile *MachO =
- dyn_cast<const MachOObjectFile>(o)) {
- DataRefImpl DR = Section->getRawDataRefImpl();
- StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
- outs() << SegmentName << ",";
- }
- StringRef SectionName;
- if (error(Section->getName(SectionName)))
- SectionName = "";
- outs() << SectionName;
+ return;
+ }
+ for (const SymbolRef &Symbol : o->symbols()) {
+ StringRef Name;
+ uint64_t Address;
+ SymbolRef::Type Type;
+ uint64_t Size;
+ uint32_t Flags = Symbol.getFlags();
+ section_iterator Section = o->section_end();
+ if (error(Symbol.getName(Name)))
+ continue;
+ if (error(Symbol.getAddress(Address)))
+ continue;
+ if (error(Symbol.getType(Type)))
+ continue;
+ if (error(Symbol.getSize(Size)))
+ continue;
+ if (error(Symbol.getSection(Section)))
+ continue;
+
+ bool Global = Flags & SymbolRef::SF_Global;
+ bool Weak = Flags & SymbolRef::SF_Weak;
+ bool Absolute = Flags & SymbolRef::SF_Absolute;
+
+ if (Address == UnknownAddressOrSize)
+ Address = 0;
+ if (Size == UnknownAddressOrSize)
+ Size = 0;
+ char GlobLoc = ' ';
+ if (Type != SymbolRef::ST_Unknown)
+ GlobLoc = Global ? 'g' : 'l';
+ char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
+ ? 'd' : ' ';
+ char FileFunc = ' ';
+ if (Type == SymbolRef::ST_File)
+ FileFunc = 'f';
+ else if (Type == SymbolRef::ST_Function)
+ FileFunc = 'F';
+
+ const char *Fmt = o->getBytesInAddress() > 4 ? "%016" PRIx64 :
+ "%08" PRIx64;
+
+ outs() << format(Fmt, Address) << " "
+ << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
+ << (Weak ? 'w' : ' ') // Weak?
+ << ' ' // Constructor. Not supported yet.
+ << ' ' // Warning. Not supported yet.
+ << ' ' // Indirect reference to another symbol.
+ << Debug // Debugging (d) or dynamic (D) symbol.
+ << FileFunc // Name of function (F), file (f) or object (O).
+ << ' ';
+ if (Absolute) {
+ outs() << "*ABS*";
+ } else if (Section == o->section_end()) {
+ outs() << "*UND*";
+ } else {
+ if (const MachOObjectFile *MachO =
+ dyn_cast<const MachOObjectFile>(o)) {
+ DataRefImpl DR = Section->getRawDataRefImpl();
+ StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
+ outs() << SegmentName << ",";
}
- outs() << '\t'
- << format("%08" PRIx64 " ", Size)
- << Name
- << '\n';
+ StringRef SectionName;
+ if (error(Section->getName(SectionName)))
+ SectionName = "";
+ outs() << SectionName;
}
+ outs() << '\t'
+ << format("%08" PRIx64 " ", Size)
+ << Name
+ << '\n';
}
}
@@ -801,13 +825,13 @@ static void DumpObject(const ObjectFile *o) {
/// @brief Dump each object file in \a a;
static void DumpArchive(const Archive *a) {
- for (Archive::child_iterator i = a->begin_children(),
- e = a->end_children(); i != e; ++i) {
- OwningPtr<Binary> child;
- if (error_code ec = i->getAsBinary(child)) {
+ for (Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e;
+ ++i) {
+ std::unique_ptr<Binary> child;
+ if (error_code EC = i->getAsBinary(child)) {
// Ignore non-object files.
- if (ec != object_error::invalid_file_type)
- errs() << ToolName << ": '" << a->getFileName() << "': " << ec.message()
+ if (EC != object_error::invalid_file_type)
+ errs() << ToolName << ": '" << a->getFileName() << "': " << EC.message()
<< ".\n";
continue;
}
@@ -833,11 +857,12 @@ static void DumpInput(StringRef file) {
}
// Attempt to open the binary.
- OwningPtr<Binary> binary;
- if (error_code ec = createBinary(file, binary)) {
- errs() << ToolName << ": '" << file << "': " << ec.message() << ".\n";
+ ErrorOr<Binary *> BinaryOrErr = createBinary(file);
+ if (error_code EC = BinaryOrErr.getError()) {
+ errs() << ToolName << ": '" << file << "': " << EC.message() << ".\n";
return;
}
+ std::unique_ptr<Binary> binary(BinaryOrErr.get());
if (Archive *a = dyn_cast<Archive>(binary.get()))
DumpArchive(a);