aboutsummaryrefslogtreecommitdiffstats
path: root/tools/llvm-readobj
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-12-01 14:51:49 -0800
committerStephen Hines <srhines@google.com>2014-12-02 16:08:10 -0800
commit37ed9c199ca639565f6ce88105f9e39e898d82d0 (patch)
tree8fb36d3910e3ee4c4e1b7422f4f017108efc52f5 /tools/llvm-readobj
parentd2327b22152ced7bc46dc629fc908959e8a52d03 (diff)
downloadexternal_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.zip
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.gz
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.bz2
Update aosp/master LLVM for rebase to r222494.
Change-Id: Ic787f5e0124df789bd26f3f24680f45e678eef2d
Diffstat (limited to 'tools/llvm-readobj')
-rw-r--r--tools/llvm-readobj/ARMAttributeParser.h4
-rw-r--r--tools/llvm-readobj/ARMEHABIPrinter.h4
-rw-r--r--tools/llvm-readobj/ARMWinEHPrinter.cpp61
-rw-r--r--tools/llvm-readobj/ARMWinEHPrinter.h52
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp407
-rw-r--r--tools/llvm-readobj/ELFDumper.cpp6
-rw-r--r--tools/llvm-readobj/Error.cpp2
-rw-r--r--tools/llvm-readobj/Error.h4
-rw-r--r--tools/llvm-readobj/MachODumper.cpp202
-rw-r--r--tools/llvm-readobj/ObjDumper.h9
-rw-r--r--tools/llvm-readobj/StreamWriter.h20
-rw-r--r--tools/llvm-readobj/Win64EHDumper.h4
-rw-r--r--tools/llvm-readobj/llvm-readobj.cpp46
-rw-r--r--tools/llvm-readobj/llvm-readobj.h4
14 files changed, 629 insertions, 196 deletions
diff --git a/tools/llvm-readobj/ARMAttributeParser.h b/tools/llvm-readobj/ARMAttributeParser.h
index c286251..f924c83 100644
--- a/tools/llvm-readobj/ARMAttributeParser.h
+++ b/tools/llvm-readobj/ARMAttributeParser.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_READOBJ_ARMATTRIBUTE_PARSER_H
-#define LLVM_READOBJ_ARMATTRIBUTE_PARSER_H
+#ifndef LLVM_TOOLS_LLVM_READOBJ_ARMATTRIBUTEPARSER_H
+#define LLVM_TOOLS_LLVM_READOBJ_ARMATTRIBUTEPARSER_H
#include "StreamWriter.h"
#include "llvm/Support/ARMBuildAttributes.h"
diff --git a/tools/llvm-readobj/ARMEHABIPrinter.h b/tools/llvm-readobj/ARMEHABIPrinter.h
index 7608cfb..b15421d 100644
--- a/tools/llvm-readobj/ARMEHABIPrinter.h
+++ b/tools/llvm-readobj/ARMEHABIPrinter.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_READOBJ_ARMEHABI_PRINTER_H
-#define LLVM_READOBJ_ARMEHABI_PRINTER_H
+#ifndef LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
+#define LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
#include "Error.h"
#include "StreamWriter.h"
diff --git a/tools/llvm-readobj/ARMWinEHPrinter.cpp b/tools/llvm-readobj/ARMWinEHPrinter.cpp
index b486e4a..ede36d1 100644
--- a/tools/llvm-readobj/ARMWinEHPrinter.cpp
+++ b/tools/llvm-readobj/ARMWinEHPrinter.cpp
@@ -186,13 +186,8 @@ void Decoder::printRegisters(const std::pair<uint16_t, uint32_t> &RegisterMask)
ErrorOr<object::SectionRef>
Decoder::getSectionContaining(const COFFObjectFile &COFF, uint64_t VA) {
for (const auto &Section : COFF.sections()) {
- uint64_t Address;
- uint64_t Size;
-
- if (std::error_code EC = Section.getAddress(Address))
- return EC;
- if (std::error_code EC = Section.getSize(Size))
- return EC;
+ uint64_t Address = Section.getAddress();
+ uint64_t Size = Section.getSize();
if (VA >= Address && (VA - Address) <= Size)
return Section;
@@ -233,7 +228,7 @@ ErrorOr<SymbolRef> Decoder::getRelocatedSymbol(const COFFObjectFile &,
return readobj_error::unknown_symbol;
}
-bool Decoder::opcode_0xxxxxxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_0xxxxxxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint8_t Imm = OC[Offset] & 0x7f;
SW.startLine() << format("0x%02x ; %s sp, #(%u * 4)\n",
@@ -244,7 +239,7 @@ bool Decoder::opcode_0xxxxxxx(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_10Lxxxxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_10Lxxxxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Link = (OC[Offset] & 0x20) >> 5;
uint16_t RegisterMask = (Link << (Prologue ? 14 : 15))
@@ -263,7 +258,7 @@ bool Decoder::opcode_10Lxxxxx(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_1100xxxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_1100xxxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
if (Prologue)
SW.startLine() << format("0x%02x ; mov r%u, sp\n",
@@ -275,7 +270,7 @@ bool Decoder::opcode_1100xxxx(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11010Lxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11010Lxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Link = (OC[Offset] & 0x4) >> 3;
unsigned Count = (OC[Offset] & 0x3);
@@ -292,7 +287,7 @@ bool Decoder::opcode_11010Lxx(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11011Lxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11011Lxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Link = (OC[Offset] & 0x4) >> 2;
unsigned Count = (OC[Offset] & 0x3) + 4;
@@ -309,7 +304,7 @@ bool Decoder::opcode_11011Lxx(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11100xxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11100xxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned High = (OC[Offset] & 0x7);
uint32_t VFPMask = (((1 << (High + 1)) - 1) << 8);
@@ -323,7 +318,7 @@ bool Decoder::opcode_11100xxx(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_111010xx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_111010xx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint16_t Imm = ((OC[Offset + 0] & 0x03) << 8) | ((OC[Offset + 1] & 0xff) << 0);
@@ -336,7 +331,7 @@ bool Decoder::opcode_111010xx(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_1110110L(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_1110110L(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint8_t GPRMask = ((OC[Offset + 0] & 0x01) << (Prologue ? 14 : 15))
| ((OC[Offset + 1] & 0xff) << 0);
@@ -350,7 +345,7 @@ bool Decoder::opcode_1110110L(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11101110(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11101110(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
assert(!Prologue && "may not be used in prologue");
@@ -366,7 +361,7 @@ bool Decoder::opcode_11101110(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11101111(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11101111(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
assert(!Prologue && "may not be used in prologue");
@@ -382,7 +377,7 @@ bool Decoder::opcode_11101111(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11110101(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11110101(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
@@ -397,7 +392,7 @@ bool Decoder::opcode_11110101(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11110110(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11110110(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
@@ -412,7 +407,7 @@ bool Decoder::opcode_11110110(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11110111(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11110111(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
@@ -425,7 +420,7 @@ bool Decoder::opcode_11110111(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11111000(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111000(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint32_t Imm = (OC[Offset + 1] << 16)
| (OC[Offset + 2] << 8)
@@ -440,7 +435,7 @@ bool Decoder::opcode_11111000(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11111001(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111001(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
@@ -453,7 +448,7 @@ bool Decoder::opcode_11111001(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11111010(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111010(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint32_t Imm = (OC[Offset + 1] << 16)
| (OC[Offset + 2] << 8)
@@ -468,41 +463,41 @@ bool Decoder::opcode_11111010(const ulittle8_t *OC, unsigned &Offset,
return false;
}
-bool Decoder::opcode_11111011(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111011(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; nop\n", OC[Offset]);
++Offset;
return false;
}
-bool Decoder::opcode_11111100(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111100(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; nop.w\n", OC[Offset]);
++Offset;
return false;
}
-bool Decoder::opcode_11111101(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111101(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; b\n", OC[Offset]);
++Offset;
return true;
}
-bool Decoder::opcode_11111110(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111110(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; b.w\n", OC[Offset]);
++Offset;
return true;
}
-bool Decoder::opcode_11111111(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111111(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
++Offset;
return true;
}
-void Decoder::decodeOpcodes(ArrayRef<ulittle8_t> Opcodes, unsigned Offset,
+void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
bool Prologue) {
assert((!Prologue || Offset == 0) && "prologue should always use offset 0");
@@ -525,10 +520,7 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents))
return false;
- uint64_t SectionVA;
- if (Section.getAddress(SectionVA))
- return false;
-
+ uint64_t SectionVA = Section.getAddress();
uint64_t Offset = VA - SectionVA;
const ulittle32_t *Data =
reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset);
@@ -546,7 +538,7 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
static_cast<uint64_t>(XData.CodeWords() * sizeof(uint32_t)));
if (XData.E()) {
- ArrayRef<ulittle8_t> UC = XData.UnwindByteCode();
+ ArrayRef<uint8_t> UC = XData.UnwindByteCode();
if (!XData.F()) {
ListScope PS(SW, "Prologue");
decodeOpcodes(UC, 0, /*Prologue=*/true);
@@ -741,4 +733,3 @@ std::error_code Decoder::dumpProcedureData(const COFFObjectFile &COFF) {
}
}
}
-
diff --git a/tools/llvm-readobj/ARMWinEHPrinter.h b/tools/llvm-readobj/ARMWinEHPrinter.h
index 740c8b5..274ef11 100644
--- a/tools/llvm-readobj/ARMWinEHPrinter.h
+++ b/tools/llvm-readobj/ARMWinEHPrinter.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_READOBJ_ARMWINEHPRINTER_H
-#define LLVM_READOBJ_ARMWINEHPRINTER_H
+#ifndef LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
+#define LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
#include "StreamWriter.h"
#include "llvm/Object/COFF.h"
@@ -28,55 +28,54 @@ class Decoder {
struct RingEntry {
uint8_t Mask;
uint8_t Value;
- bool (Decoder::*Routine)(const support::ulittle8_t *, unsigned &, unsigned,
- bool);
+ bool (Decoder::*Routine)(const uint8_t *, unsigned &, unsigned, bool);
};
static const RingEntry Ring[];
- bool opcode_0xxxxxxx(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_0xxxxxxx(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_10Lxxxxx(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_10Lxxxxx(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_1100xxxx(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_1100xxxx(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11010Lxx(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11010Lxx(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11011Lxx(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11011Lxx(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11100xxx(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11100xxx(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_111010xx(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_111010xx(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_1110110L(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_1110110L(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11101110(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11101110(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11101111(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11101111(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11110101(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11110101(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11110110(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11110110(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11110111(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11110111(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11111000(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11111000(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11111001(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11111001(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11111010(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11111010(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11111011(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11111011(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11111100(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11111100(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11111101(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11111101(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11111110(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11111110(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- bool opcode_11111111(const support::ulittle8_t *Opcodes, unsigned &Offset,
+ bool opcode_11111111(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
- void decodeOpcodes(ArrayRef<support::ulittle8_t> Opcodes, unsigned Offset,
+ void decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
bool Prologue);
void printRegisters(const std::pair<uint16_t, uint32_t> &RegisterMask);
@@ -116,4 +115,3 @@ public:
}
#endif
-
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
index 7842cd4..5276428 100644
--- a/tools/llvm-readobj/COFFDumper.cpp
+++ b/tools/llvm-readobj/COFFDumper.cpp
@@ -20,6 +20,7 @@
#include "Win64EHDumper.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/COFF.h"
@@ -49,35 +50,49 @@ public:
cacheRelocations();
}
- virtual void printFileHeaders() override;
- virtual void printSections() override;
- virtual void printRelocations() override;
- virtual void printSymbols() override;
- virtual void printDynamicSymbols() override;
- virtual void printUnwindInfo() override;
+ void printFileHeaders() override;
+ void printSections() override;
+ void printRelocations() override;
+ void printSymbols() override;
+ void printDynamicSymbols() override;
+ void printUnwindInfo() override;
+ void printCOFFImports() override;
+ void printCOFFDirectives() override;
+ void printCOFFBaseReloc() override;
private:
void printSymbol(const SymbolRef &Sym);
void printRelocation(const SectionRef &Section, const RelocationRef &Reloc);
void printDataDirectory(uint32_t Index, const std::string &FieldName);
+ void printDOSHeader(const dos_header *DH);
template <class PEHeader> void printPEHeader(const PEHeader *Hdr);
void printBaseOfDataField(const pe32_header *Hdr);
void printBaseOfDataField(const pe32plus_header *Hdr);
void printCodeViewLineTables(const SectionRef &Section);
+ void printCodeViewSymbolsSubsection(StringRef Subsection,
+ const SectionRef &Section,
+ uint32_t Offset);
+
void cacheRelocations();
std::error_code resolveSymbol(const coff_section *Section, uint64_t Offset,
SymbolRef &Sym);
std::error_code resolveSymbolName(const coff_section *Section,
uint64_t Offset, StringRef &Name);
+ void printImportedSymbols(iterator_range<imported_symbol_iterator> Range);
+ void printDelayImportedSymbols(
+ const DelayImportDirectoryEntryRef &I,
+ iterator_range<imported_symbol_iterator> Range);
typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
const llvm::object::COFFObjectFile *Obj;
RelocMapTy RelocMap;
+ StringRef CVFileIndexToStringOffsetTable;
+ StringRef CVStringTable;
};
} // namespace
@@ -313,9 +328,10 @@ WeakExternalCharacteristics[] = {
template <typename T>
static std::error_code getSymbolAuxData(const COFFObjectFile *Obj,
- const coff_symbol *Symbol,
- const T *&Aux) {
+ COFFSymbolRef Symbol,
+ uint8_t AuxSymbolIdx, const T *&Aux) {
ArrayRef<uint8_t> AuxData = Obj->getSymbolAuxData(Symbol);
+ AuxData = AuxData.slice(AuxSymbolIdx * Obj->getSymbolTableEntrySize());
Aux = reinterpret_cast<const T*>(AuxData.data());
return readobj_error::success;
}
@@ -342,25 +358,20 @@ void COFFDumper::printDataDirectory(uint32_t Index, const std::string &FieldName
}
void COFFDumper::printFileHeaders() {
- // Print COFF header
- const coff_file_header *COFFHeader = nullptr;
- if (error(Obj->getCOFFHeader(COFFHeader)))
- return;
-
- time_t TDS = COFFHeader->TimeDateStamp;
+ time_t TDS = Obj->getTimeDateStamp();
char FormattedTime[20] = { };
strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
{
DictScope D(W, "ImageFileHeader");
- W.printEnum ("Machine", COFFHeader->Machine,
+ W.printEnum ("Machine", Obj->getMachine(),
makeArrayRef(ImageFileMachineType));
- W.printNumber("SectionCount", COFFHeader->NumberOfSections);
- W.printHex ("TimeDateStamp", FormattedTime, COFFHeader->TimeDateStamp);
- W.printHex ("PointerToSymbolTable", COFFHeader->PointerToSymbolTable);
- W.printNumber("SymbolCount", COFFHeader->NumberOfSymbols);
- W.printNumber("OptionalHeaderSize", COFFHeader->SizeOfOptionalHeader);
- W.printFlags ("Characteristics", COFFHeader->Characteristics,
+ W.printNumber("SectionCount", Obj->getNumberOfSections());
+ W.printHex ("TimeDateStamp", FormattedTime, Obj->getTimeDateStamp());
+ W.printHex ("PointerToSymbolTable", Obj->getPointerToSymbolTable());
+ W.printNumber("SymbolCount", Obj->getNumberOfSymbols());
+ W.printNumber("OptionalHeaderSize", Obj->getSizeOfOptionalHeader());
+ W.printFlags ("Characteristics", Obj->getCharacteristics(),
makeArrayRef(ImageFileCharacteristics));
}
@@ -377,6 +388,30 @@ void COFFDumper::printFileHeaders() {
return;
if (PEPlusHeader)
printPEHeader<pe32plus_header>(PEPlusHeader);
+
+ if (const dos_header *DH = Obj->getDOSHeader())
+ printDOSHeader(DH);
+}
+
+void COFFDumper::printDOSHeader(const dos_header *DH) {
+ DictScope D(W, "DOSHeader");
+ W.printString("Magic", StringRef(DH->Magic, sizeof(DH->Magic)));
+ W.printNumber("UsedBytesInTheLastPage", DH->UsedBytesInTheLastPage);
+ W.printNumber("FileSizeInPages", DH->FileSizeInPages);
+ W.printNumber("NumberOfRelocationItems", DH->NumberOfRelocationItems);
+ W.printNumber("HeaderSizeInParagraphs", DH->HeaderSizeInParagraphs);
+ W.printNumber("MinimumExtraParagraphs", DH->MinimumExtraParagraphs);
+ W.printNumber("MaximumExtraParagraphs", DH->MaximumExtraParagraphs);
+ W.printNumber("InitialRelativeSS", DH->InitialRelativeSS);
+ W.printNumber("InitialSP", DH->InitialSP);
+ W.printNumber("Checksum", DH->Checksum);
+ W.printNumber("InitialIP", DH->InitialIP);
+ W.printNumber("InitialRelativeCS", DH->InitialRelativeCS);
+ W.printNumber("AddressOfRelocationTable", DH->AddressOfRelocationTable);
+ W.printNumber("OverlayNumber", DH->OverlayNumber);
+ W.printNumber("OEMid", DH->OEMid);
+ W.printNumber("OEMinfo", DH->OEMinfo);
+ W.printNumber("AddressOfNewExeHeader", DH->AddressOfNewExeHeader);
}
template <class PEHeader>
@@ -404,7 +439,7 @@ void COFFDumper::printPEHeader(const PEHeader *Hdr) {
W.printNumber("SizeOfImage", Hdr->SizeOfImage);
W.printNumber("SizeOfHeaders", Hdr->SizeOfHeaders);
W.printEnum ("Subsystem", Hdr->Subsystem, makeArrayRef(PEWindowsSubsystem));
- W.printFlags ("Subsystem", Hdr->DLLCharacteristics,
+ W.printFlags ("Characteristics", Hdr->DLLCharacteristics,
makeArrayRef(PEDLLCharacteristics));
W.printNumber("SizeOfStackReserve", Hdr->SizeOfStackReserve);
W.printNumber("SizeOfStackCommit", Hdr->SizeOfStackCommit);
@@ -440,11 +475,10 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
SmallVector<StringRef, 10> FunctionNames;
StringMap<StringRef> FunctionLineTables;
- StringRef FileIndexToStringOffsetTable;
- StringRef StringTable;
ListScope D(W, "CodeViewLineTables");
{
+ // FIXME: Add more offset correctness checks.
DataExtractor DE(Data, true, 4);
uint32_t Offset = 0,
Magic = DE.getU32(&Offset);
@@ -474,6 +508,9 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
W.printBinaryBlock("Contents", Contents);
switch (SubSectionType) {
+ case COFF::DEBUG_SYMBOL_SUBSECTION:
+ printCodeViewSymbolsSubsection(Contents, Section, Offset);
+ break;
case COFF::DEBUG_LINE_TABLE_SUBSECTION: {
// Holds a PC to file:line table. Some data to parse this subsection is
// stored in the other subsections, so just check sanity and store the
@@ -502,25 +539,25 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
break;
}
case COFF::DEBUG_STRING_TABLE_SUBSECTION:
- if (PayloadSize == 0 || StringTable.data() != nullptr ||
+ if (PayloadSize == 0 || CVStringTable.data() != nullptr ||
Contents.back() != '\0') {
// Empty or duplicate or non-null-terminated subsection.
error(object_error::parse_failed);
return;
}
- StringTable = Contents;
+ CVStringTable = Contents;
break;
case COFF::DEBUG_INDEX_SUBSECTION:
// Holds the translation table from file indices
// to offsets in the string table.
if (PayloadSize == 0 ||
- FileIndexToStringOffsetTable.data() != nullptr) {
+ CVFileIndexToStringOffsetTable.data() != nullptr) {
// Empty or duplicate subsection.
error(object_error::parse_failed);
return;
}
- FileIndexToStringOffsetTable = Contents;
+ CVFileIndexToStringOffsetTable = Contents;
break;
}
Offset += PayloadSize;
@@ -555,7 +592,7 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
uint32_t FilenameOffset;
{
- DataExtractor SDE(FileIndexToStringOffsetTable, true, 4);
+ DataExtractor SDE(CVFileIndexToStringOffsetTable, true, 4);
uint32_t OffsetInSDE = OffsetInIndex;
if (!SDE.isValidOffset(OffsetInSDE)) {
error(object_error::parse_failed);
@@ -564,15 +601,15 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
FilenameOffset = SDE.getU32(&OffsetInSDE);
}
- if (FilenameOffset == 0 || FilenameOffset + 1 >= StringTable.size() ||
- StringTable.data()[FilenameOffset - 1] != '\0') {
+ if (FilenameOffset == 0 || FilenameOffset + 1 >= CVStringTable.size() ||
+ CVStringTable.data()[FilenameOffset - 1] != '\0') {
// Each string in an F3 subsection should be preceded by a null
// character.
error(object_error::parse_failed);
return;
}
- StringRef Filename(StringTable.data() + FilenameOffset);
+ StringRef Filename(CVStringTable.data() + FilenameOffset);
ListScope S(W, "FilenameSegment");
W.printString("Filename", Filename);
for (unsigned J = 0; J != SegmentLength && DE.isValidOffset(Offset);
@@ -593,6 +630,80 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
}
}
+void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
+ const SectionRef &Section,
+ uint32_t OffsetInSection) {
+ if (Subsection.size() == 0) {
+ error(object_error::parse_failed);
+ return;
+ }
+ DataExtractor DE(Subsection, true, 4);
+ uint32_t Offset = 0;
+
+ // Function-level subsections have "procedure start" and "procedure end"
+ // commands that should come in pairs and surround relevant info.
+ bool InFunctionScope = false;
+ while (DE.isValidOffset(Offset)) {
+ // Read subsection segments one by one.
+ uint16_t Size = DE.getU16(&Offset);
+ // The section size includes the size of the type identifier.
+ if (Size < 2 || !DE.isValidOffsetForDataOfSize(Offset, Size)) {
+ error(object_error::parse_failed);
+ return;
+ }
+ Size -= 2;
+ uint16_t Type = DE.getU16(&Offset);
+ switch (Type) {
+ case COFF::DEBUG_SYMBOL_TYPE_PROC_START: {
+ DictScope S(W, "ProcStart");
+ if (InFunctionScope || Size < 36) {
+ error(object_error::parse_failed);
+ return;
+ }
+ InFunctionScope = true;
+
+ // We're currently interested in a limited subset of fields in this
+ // segment, just ignore the rest of the fields for now.
+ uint8_t Unused[12];
+ DE.getU8(&Offset, Unused, 12);
+ uint32_t CodeSize = DE.getU32(&Offset);
+ DE.getU8(&Offset, Unused, 12);
+ StringRef SectionName;
+ if (error(resolveSymbolName(Obj->getCOFFSection(Section),
+ OffsetInSection + Offset, SectionName)))
+ return;
+ Offset += 4;
+ DE.getU8(&Offset, Unused, 3);
+ StringRef DisplayName = DE.getCStr(&Offset);
+ if (!DE.isValidOffset(Offset)) {
+ error(object_error::parse_failed);
+ return;
+ }
+ W.printString("DisplayName", DisplayName);
+ W.printString("Section", SectionName);
+ W.printHex("CodeSize", CodeSize);
+
+ break;
+ }
+ case COFF::DEBUG_SYMBOL_TYPE_PROC_END: {
+ W.startLine() << "ProcEnd\n";
+ if (!InFunctionScope || Size > 0) {
+ error(object_error::parse_failed);
+ return;
+ }
+ InFunctionScope = false;
+ break;
+ }
+ default:
+ Offset += Size;
+ break;
+ }
+ }
+
+ if (InFunctionScope)
+ error(object_error::parse_failed);
+}
+
void COFFDumper::printSections() {
ListScope SectionsD(W, "Sections");
int SectionNumber = 0;
@@ -628,8 +739,7 @@ void COFFDumper::printSections() {
if (opts::SectionSymbols) {
ListScope D(W, "Symbols");
for (const SymbolRef &Symbol : Obj->symbols()) {
- bool Contained = false;
- if (Sec.containsSymbol(Symbol, Contained) || !Contained)
+ if (!Sec.containsSymbol(Symbol))
continue;
printSymbol(Symbol);
@@ -639,7 +749,8 @@ void COFFDumper::printSections() {
if (Name == ".debug$S" && opts::CodeViewLineTables)
printCodeViewLineTables(Sec);
- if (opts::SectionData) {
+ if (opts::SectionData &&
+ !(Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) {
StringRef Data;
if (error(Sec.getContents(Data)))
break;
@@ -683,7 +794,6 @@ void COFFDumper::printRelocation(const SectionRef &Section,
uint64_t RelocType;
SmallString<32> RelocName;
StringRef SymbolName;
- StringRef Contents;
if (error(Reloc.getOffset(Offset)))
return;
if (error(Reloc.getType(RelocType)))
@@ -691,21 +801,19 @@ void COFFDumper::printRelocation(const SectionRef &Section,
if (error(Reloc.getTypeName(RelocName)))
return;
symbol_iterator Symbol = Reloc.getSymbol();
- if (error(Symbol->getName(SymbolName)))
- return;
- if (error(Section.getContents(Contents)))
+ if (Symbol != Obj->symbol_end() && error(Symbol->getName(SymbolName)))
return;
if (opts::ExpandRelocs) {
DictScope Group(W, "Relocation");
W.printHex("Offset", Offset);
W.printNumber("Type", RelocName, RelocType);
- W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
+ W.printString("Symbol", SymbolName.empty() ? "-" : SymbolName);
} else {
raw_ostream& OS = W.startLine();
OS << W.hex(Offset)
<< " " << RelocName
- << " " << (SymbolName.size() > 0 ? SymbolName : "-")
+ << " " << (SymbolName.empty() ? "-" : SymbolName)
<< "\n";
}
}
@@ -719,12 +827,30 @@ void COFFDumper::printSymbols() {
void COFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); }
+static ErrorOr<StringRef>
+getSectionName(const llvm::object::COFFObjectFile *Obj, int32_t SectionNumber,
+ const coff_section *Section) {
+ if (Section) {
+ StringRef SectionName;
+ if (std::error_code EC = Obj->getSectionName(Section, SectionName))
+ return EC;
+ return SectionName;
+ }
+ if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
+ return StringRef("IMAGE_SYM_DEBUG");
+ if (SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE)
+ return StringRef("IMAGE_SYM_ABSOLUTE");
+ if (SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED)
+ return StringRef("IMAGE_SYM_UNDEFINED");
+ return StringRef("");
+}
+
void COFFDumper::printSymbol(const SymbolRef &Sym) {
DictScope D(W, "Symbol");
- const coff_symbol *Symbol = Obj->getCOFFSymbol(Sym);
+ COFFSymbolRef Symbol = Obj->getCOFFSymbol(Sym);
const coff_section *Section;
- if (std::error_code EC = Obj->getSection(Symbol->SectionNumber, Section)) {
+ if (std::error_code EC = Obj->getSection(Symbol.getSectionNumber(), Section)) {
W.startLine() << "Invalid section number: " << EC.message() << "\n";
W.flush();
return;
@@ -735,23 +861,25 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
SymbolName = "";
StringRef SectionName = "";
- if (Section)
- Obj->getSectionName(Section, SectionName);
+ ErrorOr<StringRef> Res =
+ getSectionName(Obj, Symbol.getSectionNumber(), Section);
+ if (Res)
+ SectionName = *Res;
W.printString("Name", SymbolName);
- W.printNumber("Value", Symbol->Value);
- W.printNumber("Section", SectionName, Symbol->SectionNumber);
- W.printEnum ("BaseType", Symbol->getBaseType(), makeArrayRef(ImageSymType));
- W.printEnum ("ComplexType", Symbol->getComplexType(),
+ W.printNumber("Value", Symbol.getValue());
+ W.printNumber("Section", SectionName, Symbol.getSectionNumber());
+ W.printEnum ("BaseType", Symbol.getBaseType(), makeArrayRef(ImageSymType));
+ W.printEnum ("ComplexType", Symbol.getComplexType(),
makeArrayRef(ImageSymDType));
- W.printEnum ("StorageClass", Symbol->StorageClass,
+ W.printEnum ("StorageClass", Symbol.getStorageClass(),
makeArrayRef(ImageSymClass));
- W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols);
+ W.printNumber("AuxSymbolCount", Symbol.getNumberOfAuxSymbols());
- for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) {
- if (Symbol->isFunctionDefinition()) {
+ for (uint8_t I = 0; I < Symbol.getNumberOfAuxSymbols(); ++I) {
+ if (Symbol.isFunctionDefinition()) {
const coff_aux_function_definition *Aux;
- if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
+ if (error(getSymbolAuxData(Obj, Symbol, I, Aux)))
break;
DictScope AS(W, "AuxFunctionDef");
@@ -759,18 +887,16 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
W.printNumber("TotalSize", Aux->TotalSize);
W.printHex("PointerToLineNumber", Aux->PointerToLinenumber);
W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);
- W.printBinary("Unused", makeArrayRef(Aux->Unused));
- } else if (Symbol->isWeakExternal()) {
+ } else if (Symbol.isAnyUndefined()) {
const coff_aux_weak_external *Aux;
- if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
+ if (error(getSymbolAuxData(Obj, Symbol, I, Aux)))
break;
- const coff_symbol *Linked;
+ ErrorOr<COFFSymbolRef> Linked = Obj->getSymbol(Aux->TagIndex);
StringRef LinkedName;
- std::error_code EC;
- if ((EC = Obj->getSymbol(Aux->TagIndex, Linked)) ||
- (EC = Obj->getSymbolName(Linked, LinkedName))) {
+ std::error_code EC = Linked.getError();
+ if (EC || (EC = Obj->getSymbolName(*Linked, LinkedName))) {
LinkedName = "";
error(EC);
}
@@ -779,56 +905,60 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
W.printNumber("Linked", LinkedName, Aux->TagIndex);
W.printEnum ("Search", Aux->Characteristics,
makeArrayRef(WeakExternalCharacteristics));
- W.printBinary("Unused", makeArrayRef(Aux->Unused));
- } else if (Symbol->isFileRecord()) {
- const coff_aux_file *Aux;
- if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
+ } else if (Symbol.isFileRecord()) {
+ const char *FileName;
+ if (error(getSymbolAuxData(Obj, Symbol, I, FileName)))
break;
DictScope AS(W, "AuxFileRecord");
- StringRef Name(Aux->FileName,
- Symbol->NumberOfAuxSymbols * COFF::SymbolSize);
+ StringRef Name(FileName, Symbol.getNumberOfAuxSymbols() *
+ Obj->getSymbolTableEntrySize());
W.printString("FileName", Name.rtrim(StringRef("\0", 1)));
break;
- } else if (Symbol->isSectionDefinition()) {
+ } else if (Symbol.isSectionDefinition()) {
const coff_aux_section_definition *Aux;
- if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
+ if (error(getSymbolAuxData(Obj, Symbol, I, Aux)))
break;
+ int32_t AuxNumber = Aux->getNumber(Symbol.isBigObj());
+
DictScope AS(W, "AuxSectionDef");
W.printNumber("Length", Aux->Length);
W.printNumber("RelocationCount", Aux->NumberOfRelocations);
W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers);
W.printHex("Checksum", Aux->CheckSum);
- W.printNumber("Number", Aux->Number);
+ W.printNumber("Number", AuxNumber);
W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect));
- W.printBinary("Unused", makeArrayRef(Aux->Unused));
if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
&& Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
const coff_section *Assoc;
- StringRef AssocName;
- std::error_code EC;
- if ((EC = Obj->getSection(Aux->Number, Assoc)) ||
- (EC = Obj->getSectionName(Assoc, AssocName))) {
+ StringRef AssocName = "";
+ std::error_code EC = Obj->getSection(AuxNumber, Assoc);
+ ErrorOr<StringRef> Res = getSectionName(Obj, AuxNumber, Assoc);
+ if (Res)
+ AssocName = *Res;
+ if (!EC)
+ EC = Res.getError();
+ if (EC) {
AssocName = "";
error(EC);
}
- W.printNumber("AssocSection", AssocName, Aux->Number);
+ W.printNumber("AssocSection", AssocName, AuxNumber);
}
- } else if (Symbol->isCLRToken()) {
+ } else if (Symbol.isCLRToken()) {
const coff_aux_clr_token *Aux;
- if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
+ if (error(getSymbolAuxData(Obj, Symbol, I, Aux)))
break;
- const coff_symbol *ReferredSym;
+ ErrorOr<COFFSymbolRef> ReferredSym =
+ Obj->getSymbol(Aux->SymbolTableIndex);
StringRef ReferredName;
- std::error_code EC;
- if ((EC = Obj->getSymbol(Aux->SymbolTableIndex, ReferredSym)) ||
- (EC = Obj->getSymbolName(ReferredSym, ReferredName))) {
+ std::error_code EC = ReferredSym.getError();
+ if (EC || (EC = Obj->getSymbolName(*ReferredSym, ReferredName))) {
ReferredName = "";
error(EC);
}
@@ -837,7 +967,6 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
W.printNumber("AuxType", Aux->AuxType);
W.printNumber("Reserved", Aux->Reserved);
W.printNumber("SymbolTableIndex", ReferredName, Aux->SymbolTableIndex);
- W.printBinary("Unused", makeArrayRef(Aux->Unused));
} else {
W.startLine() << "<unhandled auxiliary record>\n";
@@ -846,12 +975,8 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
}
void COFFDumper::printUnwindInfo() {
- const coff_file_header *Header;
- if (error(Obj->getCOFFHeader(Header)))
- return;
-
ListScope D(W, "UnwindInformation");
- switch (Header->Machine) {
+ switch (Obj->getMachine()) {
case COFF::IMAGE_FILE_MACHINE_AMD64: {
Win64EH::Dumper Dumper(W);
Win64EH::Dumper::SymbolResolver
@@ -870,9 +995,113 @@ void COFFDumper::printUnwindInfo() {
break;
}
default:
- W.printEnum("unsupported Image Machine", Header->Machine,
+ W.printEnum("unsupported Image Machine", Obj->getMachine(),
makeArrayRef(ImageFileMachineType));
break;
}
}
+void COFFDumper::printImportedSymbols(
+ iterator_range<imported_symbol_iterator> Range) {
+ for (const ImportedSymbolRef &I : Range) {
+ StringRef Sym;
+ if (error(I.getSymbolName(Sym))) return;
+ uint16_t Ordinal;
+ if (error(I.getOrdinal(Ordinal))) return;
+ W.printNumber("Symbol", Sym, Ordinal);
+ }
+}
+
+void COFFDumper::printDelayImportedSymbols(
+ const DelayImportDirectoryEntryRef &I,
+ iterator_range<imported_symbol_iterator> Range) {
+ int Index = 0;
+ for (const ImportedSymbolRef &S : Range) {
+ DictScope Import(W, "Import");
+ StringRef Sym;
+ if (error(S.getSymbolName(Sym))) return;
+ uint16_t Ordinal;
+ if (error(S.getOrdinal(Ordinal))) return;
+ W.printNumber("Symbol", Sym, Ordinal);
+ uint64_t Addr;
+ if (error(I.getImportAddress(Index++, Addr))) return;
+ W.printHex("Address", Addr);
+ }
+}
+
+void COFFDumper::printCOFFImports() {
+ // Regular imports
+ for (const ImportDirectoryEntryRef &I : Obj->import_directories()) {
+ DictScope Import(W, "Import");
+ StringRef Name;
+ if (error(I.getName(Name))) return;
+ W.printString("Name", Name);
+ uint32_t Addr;
+ if (error(I.getImportLookupTableRVA(Addr))) return;
+ W.printHex("ImportLookupTableRVA", Addr);
+ if (error(I.getImportAddressTableRVA(Addr))) return;
+ W.printHex("ImportAddressTableRVA", Addr);
+ printImportedSymbols(I.imported_symbols());
+ }
+
+ // Delay imports
+ for (const DelayImportDirectoryEntryRef &I : Obj->delay_import_directories()) {
+ DictScope Import(W, "DelayImport");
+ StringRef Name;
+ if (error(I.getName(Name))) return;
+ W.printString("Name", Name);
+ const delay_import_directory_table_entry *Table;
+ if (error(I.getDelayImportTable(Table))) return;
+ W.printHex("Attributes", Table->Attributes);
+ W.printHex("ModuleHandle", Table->ModuleHandle);
+ W.printHex("ImportAddressTable", Table->DelayImportAddressTable);
+ W.printHex("ImportNameTable", Table->DelayImportNameTable);
+ W.printHex("BoundDelayImportTable", Table->BoundDelayImportTable);
+ W.printHex("UnloadDelayImportTable", Table->UnloadDelayImportTable);
+ printDelayImportedSymbols(I, I.imported_symbols());
+ }
+}
+
+void COFFDumper::printCOFFDirectives() {
+ for (const SectionRef &Section : Obj->sections()) {
+ StringRef Contents;
+ StringRef Name;
+
+ if (error(Section.getName(Name)))
+ continue;
+ if (Name != ".drectve")
+ continue;
+
+ if (error(Section.getContents(Contents)))
+ return;
+
+ W.printString("Directive(s)", Contents);
+ }
+}
+
+static StringRef getBaseRelocTypeName(uint8_t Type) {
+ switch (Type) {
+ case COFF::IMAGE_REL_BASED_ABSOLUTE: return "ABSOLUTE";
+ case COFF::IMAGE_REL_BASED_HIGH: return "HIGH";
+ case COFF::IMAGE_REL_BASED_LOW: return "LOW";
+ case COFF::IMAGE_REL_BASED_HIGHLOW: return "HIGHLOW";
+ case COFF::IMAGE_REL_BASED_HIGHADJ: return "HIGHADJ";
+ case COFF::IMAGE_REL_BASED_DIR64: return "DIR64";
+ default: return "unknown (" + llvm::utostr(Type) + ")";
+ }
+}
+
+void COFFDumper::printCOFFBaseReloc() {
+ ListScope D(W, "BaseReloc");
+ for (const BaseRelocRef &I : Obj->base_relocs()) {
+ uint8_t Type;
+ uint32_t RVA;
+ if (error(I.getRVA(RVA)))
+ continue;
+ if (error(I.getType(Type)))
+ continue;
+ DictScope Import(W, "Entry");
+ W.printString("Type", getBaseRelocTypeName(Type));
+ W.printHex("Address", RVA);
+ }
+}
diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp
index 5df51e2..d68c786 100644
--- a/tools/llvm-readobj/ELFDumper.cpp
+++ b/tools/llvm-readobj/ELFDumper.cpp
@@ -407,6 +407,7 @@ static const char *getElfSectionType(unsigned Arch, unsigned Type) {
switch (Type) {
LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
+ LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
}
}
@@ -603,7 +604,7 @@ void ELFDumper<ELFT>::printSections() {
}
}
- if (opts::SectionData) {
+ if (opts::SectionData && Section->sh_type != ELF::SHT_NOBITS) {
ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(Section));
W.printBinaryBlock("SectionData",
StringRef((const char *)Data.data(), Data.size()));
@@ -675,7 +676,8 @@ void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec,
DictScope Group(W, "Relocation");
W.printHex("Offset", Rel.r_offset);
W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
- W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
+ W.printNumber("Symbol", SymbolName.size() > 0 ? SymbolName : "-",
+ Rel.getSymbol(Obj->isMips64EL()));
W.printHex("Addend", Rel.r_addend);
} else {
raw_ostream& OS = W.startLine();
diff --git a/tools/llvm-readobj/Error.cpp b/tools/llvm-readobj/Error.cpp
index a078f5c..7e6f780 100644
--- a/tools/llvm-readobj/Error.cpp
+++ b/tools/llvm-readobj/Error.cpp
@@ -24,7 +24,7 @@ public:
};
} // namespace
-const char *_readobj_error_category::name() const {
+const char *_readobj_error_category::name() const LLVM_NOEXCEPT {
return "llvm.readobj";
}
diff --git a/tools/llvm-readobj/Error.h b/tools/llvm-readobj/Error.h
index 81ce408..f3e24bb 100644
--- a/tools/llvm-readobj/Error.h
+++ b/tools/llvm-readobj/Error.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_READOBJ_ERROR_H
-#define LLVM_READOBJ_ERROR_H
+#ifndef LLVM_TOOLS_LLVM_READOBJ_ERROR_H
+#define LLVM_TOOLS_LLVM_READOBJ_ERROR_H
#include <system_error>
diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp
index a5e5cf8..7e8fdad 100644
--- a/tools/llvm-readobj/MachODumper.cpp
+++ b/tools/llvm-readobj/MachODumper.cpp
@@ -31,14 +31,17 @@ public:
: ObjDumper(Writer)
, Obj(Obj) { }
- virtual void printFileHeaders() override;
- virtual void printSections() override;
- virtual void printRelocations() override;
- virtual void printSymbols() override;
- virtual void printDynamicSymbols() override;
- virtual void printUnwindInfo() override;
+ void printFileHeaders() override;
+ void printSections() override;
+ void printRelocations() override;
+ void printSymbols() override;
+ void printDynamicSymbols() override;
+ void printUnwindInfo() override;
private:
+ template<class MachHeader>
+ void printFileHeaders(const MachHeader &Header);
+
void printSymbol(const SymbolRef &Symbol);
void printRelocation(const RelocationRef &Reloc);
@@ -68,6 +71,137 @@ std::error_code createMachODumper(const object::ObjectFile *Obj,
} // namespace llvm
+static const EnumEntry<uint32_t> MachOMagics[] = {
+ { "Magic", MachO::MH_MAGIC },
+ { "Cigam", MachO::MH_CIGAM },
+ { "Magic64", MachO::MH_MAGIC_64 },
+ { "Cigam64", MachO::MH_CIGAM_64 },
+ { "FatMagic", MachO::FAT_MAGIC },
+ { "FatCigam", MachO::FAT_CIGAM },
+};
+
+static const EnumEntry<uint32_t> MachOHeaderFileTypes[] = {
+ { "Relocatable", MachO::MH_OBJECT },
+ { "Executable", MachO::MH_EXECUTE },
+ { "FixedVMLibrary", MachO::MH_FVMLIB },
+ { "Core", MachO::MH_CORE },
+ { "PreloadedExecutable", MachO::MH_PRELOAD },
+ { "DynamicLibrary", MachO::MH_DYLIB },
+ { "DynamicLinker", MachO::MH_DYLINKER },
+ { "Bundle", MachO::MH_BUNDLE },
+ { "DynamicLibraryStub", MachO::MH_DYLIB_STUB },
+ { "DWARFSymbol", MachO::MH_DSYM },
+ { "KextBundle", MachO::MH_KEXT_BUNDLE },
+};
+
+static const EnumEntry<uint32_t> MachOHeaderCpuTypes[] = {
+ { "Any" , static_cast<uint32_t>(MachO::CPU_TYPE_ANY) },
+ { "X86" , MachO::CPU_TYPE_X86 },
+ { "X86-64" , MachO::CPU_TYPE_X86_64 },
+ { "Mc98000" , MachO::CPU_TYPE_MC98000 },
+ { "Arm" , MachO::CPU_TYPE_ARM },
+ { "Arm64" , MachO::CPU_TYPE_ARM64 },
+ { "Sparc" , MachO::CPU_TYPE_SPARC },
+ { "PowerPC" , MachO::CPU_TYPE_POWERPC },
+ { "PowerPC64" , MachO::CPU_TYPE_POWERPC64 },
+};
+
+static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesX86[] = {
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_I386_ALL),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_386),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_486),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_486SX),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_586),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTPRO),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTII_M3),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTII_M5),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_CELERON),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_CELERON_MOBILE),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3_M),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3_XEON),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_M),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_4),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_4_M),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ITANIUM),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ITANIUM_2),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_XEON),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_XEON_MP),
+};
+
+static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesX64[] = {
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_64_ALL),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_ARCH1),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_64_H),
+};
+
+static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesARM[] = {
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_ALL),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V4T),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V6),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V5),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V5TEJ),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_XSCALE),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7S),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7K),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V6M),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7M),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7EM),
+};
+
+static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesARM64[] = {
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64_ALL),
+};
+
+static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesSPARC[] = {
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_SPARC_ALL),
+};
+
+static const EnumEntry<uint32_t> MachOHeaderCpuSubtypesPPC[] = {
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_ALL),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_601),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_602),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603e),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603ev),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_604),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_604e),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_620),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_750),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_7400),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_7450),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_970),
+};
+
+static const EnumEntry<uint32_t> MachOHeaderFlags[] = {
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_NOUNDEFS),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_INCRLINK),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_DYLDLINK),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_BINDATLOAD),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_PREBOUND),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_SPLIT_SEGS),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_LAZY_INIT),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_TWOLEVEL),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_FORCE_FLAT),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_NOMULTIDEFS),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_NOFIXPREBINDING),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_PREBINDABLE),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_ALLMODSBOUND),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_SUBSECTIONS_VIA_SYMBOLS),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_CANONICAL),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_WEAK_DEFINES),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_BINDS_TO_WEAK),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_ALLOW_STACK_EXECUTION),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_ROOT_SAFE),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_SETUID_SAFE),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_NO_REEXPORTED_DYLIBS),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_PIE),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_DEAD_STRIPPABLE_DYLIB),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_HAS_TLV_DESCRIPTORS),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_NO_HEAP_EXECUTION),
+ LLVM_READOBJ_ENUM_ENT(MachO, MH_APP_EXTENSION_SAFE),
+};
static const EnumEntry<unsigned> MachOSectionTypes[] = {
{ "Regular" , 0x00 },
@@ -205,7 +339,47 @@ static void getSymbol(const MachOObjectFile *Obj,
}
void MachODumper::printFileHeaders() {
- W.startLine() << "FileHeaders not implemented.\n";
+ DictScope H(W, "MachHeader");
+ if (!Obj->is64Bit()) {
+ printFileHeaders(Obj->getHeader());
+ } else {
+ printFileHeaders(Obj->getHeader64());
+ W.printHex("Reserved", Obj->getHeader64().reserved);
+ }
+}
+
+template<class MachHeader>
+void MachODumper::printFileHeaders(const MachHeader &Header) {
+ W.printEnum("Magic", Header.magic, makeArrayRef(MachOMagics));
+ W.printEnum("CpuType", Header.cputype, makeArrayRef(MachOHeaderCpuTypes));
+ uint32_t subtype = Header.cpusubtype & ~MachO::CPU_SUBTYPE_MASK;
+ switch (Header.cputype) {
+ case MachO::CPU_TYPE_X86:
+ W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX86));
+ break;
+ case MachO::CPU_TYPE_X86_64:
+ W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX64));
+ break;
+ case MachO::CPU_TYPE_ARM:
+ W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM));
+ break;
+ case MachO::CPU_TYPE_POWERPC:
+ W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesPPC));
+ break;
+ case MachO::CPU_TYPE_SPARC:
+ W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesSPARC));
+ break;
+ case MachO::CPU_TYPE_ARM64:
+ W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM64));
+ break;
+ case MachO::CPU_TYPE_POWERPC64:
+ default:
+ W.printHex("CpuSubtype", subtype);
+ }
+ W.printEnum("FileType", Header.filetype, makeArrayRef(MachOHeaderFileTypes));
+ W.printNumber("NumOfLoadCommands", Header.ncmds);
+ W.printNumber("SizeOfLoadCommands", Header.sizeofcmds);
+ W.printFlags("Flags", Header.flags, makeArrayRef(MachOHeaderFlags));
}
void MachODumper::printSections() {
@@ -257,8 +431,7 @@ void MachODumper::printSections(const MachOObjectFile *Obj) {
if (opts::SectionSymbols) {
ListScope D(W, "Symbols");
for (const SymbolRef &Symbol : Obj->symbols()) {
- bool Contained = false;
- if (Section.containsSymbol(Symbol, Contained) || !Contained)
+ if (!Section.containsSymbol(Symbol))
continue;
printSymbol(Symbol);
@@ -266,11 +439,14 @@ void MachODumper::printSections(const MachOObjectFile *Obj) {
}
if (opts::SectionData) {
- StringRef Data;
- if (error(Section.getContents(Data)))
- break;
+ bool IsBSS = Section.isBSS();
+ if (!IsBSS) {
+ StringRef Data;
+ if (error(Section.getContents(Data)))
+ break;
- W.printBinaryBlock("SectionData", Data);
+ W.printBinaryBlock("SectionData", Data);
+ }
}
}
}
diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h
index f80a28b..a34e091 100644
--- a/tools/llvm-readobj/ObjDumper.h
+++ b/tools/llvm-readobj/ObjDumper.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_READOBJ_OBJDUMPER_H
-#define LLVM_READOBJ_OBJDUMPER_H
+#ifndef LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H
+#define LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H
#include <memory>
#include <system_error>
@@ -43,6 +43,11 @@ public:
// Only implemented for MIPS ELF at this time.
virtual void printMipsPLTGOT() { }
+ // Only implemented for PE/COFF.
+ virtual void printCOFFImports() { }
+ virtual void printCOFFDirectives() { }
+ virtual void printCOFFBaseReloc() { }
+
protected:
StreamWriter& W;
};
diff --git a/tools/llvm-readobj/StreamWriter.h b/tools/llvm-readobj/StreamWriter.h
index 04b38fb..2fc53ee 100644
--- a/tools/llvm-readobj/StreamWriter.h
+++ b/tools/llvm-readobj/StreamWriter.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_READOBJ_STREAMWRITER_H
-#define LLVM_READOBJ_STREAMWRITER_H
+#ifndef LLVM_TOOLS_LLVM_READOBJ_STREAMWRITER_H
+#define LLVM_TOOLS_LLVM_READOBJ_STREAMWRITER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
@@ -214,8 +214,8 @@ public:
}
void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
- ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
- Value.size());
+ auto V = makeArrayRef(reinterpret_cast<const uint8_t*>(Value.data()),
+ Value.size());
printBinaryImpl(Label, Str, V, false);
}
@@ -224,20 +224,20 @@ public:
}
void printBinary(StringRef Label, ArrayRef<char> Value) {
- ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
- Value.size());
+ auto V = makeArrayRef(reinterpret_cast<const uint8_t*>(Value.data()),
+ Value.size());
printBinaryImpl(Label, StringRef(), V, false);
}
void printBinary(StringRef Label, StringRef Value) {
- ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
- Value.size());
+ auto V = makeArrayRef(reinterpret_cast<const uint8_t*>(Value.data()),
+ Value.size());
printBinaryImpl(Label, StringRef(), V, false);
}
void printBinaryBlock(StringRef Label, StringRef Value) {
- ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
- Value.size());
+ auto V = makeArrayRef(reinterpret_cast<const uint8_t*>(Value.data()),
+ Value.size());
printBinaryImpl(Label, StringRef(), V, true);
}
diff --git a/tools/llvm-readobj/Win64EHDumper.h b/tools/llvm-readobj/Win64EHDumper.h
index 9ce4d39..a80df9c 100644
--- a/tools/llvm-readobj/Win64EHDumper.h
+++ b/tools/llvm-readobj/Win64EHDumper.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TOOLS_READOBJ_WIN64EHPRINTER_H
-#define LLVM_TOOLS_READOBJ_WIN64EHPRINTER_H
+#ifndef LLVM_TOOLS_LLVM_READOBJ_WIN64EHDUMPER_H
+#define LLVM_TOOLS_LLVM_READOBJ_WIN64EHDUMPER_H
#include "StreamWriter.h"
#include "llvm/Support/Win64EH.h"
diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp
index 8d2a997..d08f186 100644
--- a/tools/llvm-readobj/llvm-readobj.cpp
+++ b/tools/llvm-readobj/llvm-readobj.cpp
@@ -24,6 +24,7 @@
#include "ObjDumper.h"
#include "StreamWriter.h"
#include "llvm/Object/Archive.h"
+#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
@@ -140,6 +141,20 @@ namespace opts {
cl::opt<bool>
MipsPLTGOT("mips-plt-got",
cl::desc("Display the MIPS GOT and PLT GOT sections"));
+
+ // -coff-imports
+ cl::opt<bool>
+ COFFImports("coff-imports", cl::desc("Display the PE/COFF import table"));
+
+ // -coff-directives
+ cl::opt<bool>
+ COFFDirectives("coff-directives",
+ cl::desc("Display the PE/COFF .drectve section"));
+
+ // -coff-basereloc
+ cl::opt<bool>
+ COFFBaseRelocs("coff-basereloc",
+ cl::desc("Display the PE/COFF .reloc section"));
} // namespace opts
static int ReturnValue = EXIT_SUCCESS;
@@ -158,8 +173,8 @@ bool error(std::error_code EC) {
bool relocAddressLess(RelocationRef a, RelocationRef b) {
uint64_t a_addr, b_addr;
- if (error(a.getOffset(a_addr))) return false;
- if (error(b.getOffset(b_addr))) return false;
+ if (error(a.getOffset(a_addr))) exit(ReturnValue);
+ if (error(b.getOffset(b_addr))) exit(ReturnValue);
return a_addr < b_addr;
}
@@ -210,6 +225,17 @@ static std::error_code createDumper(const ObjectFile *Obj, StreamWriter &Writer,
return readobj_error::unsupported_obj_file_format;
}
+static StringRef getLoadName(const ObjectFile *Obj) {
+ if (auto *ELF = dyn_cast<ELF32LEObjectFile>(Obj))
+ return ELF->getLoadName();
+ if (auto *ELF = dyn_cast<ELF64LEObjectFile>(Obj))
+ return ELF->getLoadName();
+ if (auto *ELF = dyn_cast<ELF32BEObjectFile>(Obj))
+ return ELF->getLoadName();
+ if (auto *ELF = dyn_cast<ELF64BEObjectFile>(Obj))
+ return ELF->getLoadName();
+ llvm_unreachable("Not ELF");
+}
/// @brief Dumps the specified object file.
static void dumpObject(const ObjectFile *Obj) {
@@ -228,7 +254,7 @@ static void dumpObject(const ObjectFile *Obj) {
<< "\n";
outs() << "AddressSize: " << (8*Obj->getBytesInAddress()) << "bit\n";
if (Obj->isELF())
- outs() << "LoadName: " << Obj->getLoadName() << "\n";
+ outs() << "LoadName: " << getLoadName(Obj) << "\n";
if (opts::FileHeaders)
Dumper->printFileHeaders();
@@ -254,6 +280,12 @@ static void dumpObject(const ObjectFile *Obj) {
if (isMipsArch(Obj->getArch()) && Obj->isELF())
if (opts::MipsPLTGOT)
Dumper->printMipsPLTGOT();
+ if (opts::COFFImports)
+ Dumper->printCOFFImports();
+ if (opts::COFFDirectives)
+ Dumper->printCOFFDirectives();
+ if (opts::COFFBaseRelocs)
+ Dumper->printCOFFBaseReloc();
}
@@ -287,16 +319,16 @@ static void dumpInput(StringRef File) {
}
// Attempt to open the binary.
- ErrorOr<Binary *> BinaryOrErr = createBinary(File);
+ ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
if (std::error_code EC = BinaryOrErr.getError()) {
reportError(File, EC);
return;
}
- std::unique_ptr<Binary> Binary(BinaryOrErr.get());
+ Binary &Binary = *BinaryOrErr.get().getBinary();
- if (Archive *Arc = dyn_cast<Archive>(Binary.get()))
+ if (Archive *Arc = dyn_cast<Archive>(&Binary))
dumpArchive(Arc);
- else if (ObjectFile *Obj = dyn_cast<ObjectFile>(Binary.get()))
+ else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
dumpObject(Obj);
else
reportError(File, readobj_error::unrecognized_file_format);
diff --git a/tools/llvm-readobj/llvm-readobj.h b/tools/llvm-readobj/llvm-readobj.h
index 0413948..1c33417 100644
--- a/tools/llvm-readobj/llvm-readobj.h
+++ b/tools/llvm-readobj/llvm-readobj.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TOOLS_READ_OBJ_H
-#define LLVM_TOOLS_READ_OBJ_H
+#ifndef LLVM_TOOLS_LLVM_READOBJ_LLVM_READOBJ_H
+#define LLVM_TOOLS_LLVM_READOBJ_LLVM_READOBJ_H
#include "llvm/Support/CommandLine.h"
#include <string>