aboutsummaryrefslogtreecommitdiffstats
path: root/tools/llvm-readobj/COFFDumper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-readobj/COFFDumper.cpp')
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp497
1 files changed, 304 insertions, 193 deletions
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
index 2f309e3..cd40da7 100644
--- a/tools/llvm-readobj/COFFDumper.cpp
+++ b/tools/llvm-readobj/COFFDumper.cpp
@@ -13,23 +13,22 @@
//===----------------------------------------------------------------------===//
#include "llvm-readobj.h"
-#include "ObjDumper.h"
-
#include "Error.h"
+#include "ObjDumper.h"
#include "StreamWriter.h"
-
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/COFF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Win64EH.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-
#include <algorithm>
#include <cstring>
#include <time.h>
@@ -48,22 +47,23 @@ public:
cacheRelocations();
}
- virtual void printFileHeaders() LLVM_OVERRIDE;
- virtual void printSections() LLVM_OVERRIDE;
- virtual void printRelocations() LLVM_OVERRIDE;
- virtual void printSymbols() LLVM_OVERRIDE;
- virtual void printDynamicSymbols() LLVM_OVERRIDE;
- virtual void printUnwindInfo() LLVM_OVERRIDE;
+ virtual void printFileHeaders() override;
+ virtual void printSections() override;
+ virtual void printRelocations() override;
+ virtual void printSymbols() override;
+ virtual void printDynamicSymbols() override;
+ virtual void printUnwindInfo() override;
private:
- void printSymbol(symbol_iterator SymI);
-
- void printRelocation(section_iterator SecI, relocation_iterator RelI);
-
+ void printSymbol(const SymbolRef &Sym);
+ void printRelocation(const SectionRef &Section, const RelocationRef &Reloc);
void printDataDirectory(uint32_t Index, const std::string &FieldName);
-
void printX64UnwindInfo();
+ template <class PEHeader> void printPEHeader(const PEHeader *Hdr);
+ void printBaseOfDataField(const pe32_header *Hdr);
+ void printBaseOfDataField(const pe32plus_header *Hdr);
+
void printRuntimeFunction(
const RuntimeFunction& RTF,
uint64_t OffsetInSection,
@@ -74,7 +74,9 @@ private:
uint64_t OffsetInSection,
const std::vector<RelocationRef> &Rels);
- void printUnwindCode(const Win64EH::UnwindInfo& UI, ArrayRef<UnwindCode> UCs);
+ void printUnwindCode(const Win64EH::UnwindInfo &UI, ArrayRef<UnwindCode> UCs);
+
+ void printCodeViewLineTables(const SectionRef &Section);
void cacheRelocations();
@@ -102,9 +104,8 @@ private:
namespace llvm {
-error_code createCOFFDumper(const object::ObjectFile *Obj,
- StreamWriter& Writer,
- OwningPtr<ObjDumper> &Result) {
+error_code createCOFFDumper(const object::ObjectFile *Obj, StreamWriter &Writer,
+ std::unique_ptr<ObjDumper> &Result) {
const COFFObjectFile *COFFObj = dyn_cast<COFFObjectFile>(Obj);
if (!COFFObj)
return readobj_error::unsupported_obj_file_format;
@@ -183,11 +184,11 @@ static error_code resolveSectionAndAddress(const COFFObjectFile *Obj,
if (error_code EC = Sym.getAddress(ResolvedAddr))
return EC;
- section_iterator iter(Obj->begin_sections());
+ section_iterator iter(Obj->section_begin());
if (error_code EC = Sym.getSection(iter))
return EC;
- ResolvedSection = Obj->getCOFFSection(iter);
+ ResolvedSection = Obj->getCOFFSection(*iter);
return object_error::success;
}
@@ -227,7 +228,7 @@ static const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = {
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33 ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64 ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMV7 ),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMNT ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386 ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_IA64 ),
@@ -279,6 +280,7 @@ static const EnumEntry<COFF::WindowsSubsystem> PEWindowsSubsystem[] = {
};
static const EnumEntry<COFF::DLLCharacteristics> PEDLLCharacteristics[] = {
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ),
@@ -428,30 +430,9 @@ static const EnumEntry<unsigned> UnwindOpInfo[] = {
// Some additional COFF structures not defined by llvm::object.
namespace {
- struct coff_aux_function_definition {
- support::ulittle32_t TagIndex;
- support::ulittle32_t TotalSize;
- support::ulittle32_t PointerToLineNumber;
- support::ulittle32_t PointerToNextFunction;
- uint8_t Unused[2];
- };
-
- struct coff_aux_weak_external_definition {
- support::ulittle32_t TagIndex;
- support::ulittle32_t Characteristics;
- uint8_t Unused[10];
- };
-
struct coff_aux_file_record {
char FileName[18];
};
-
- struct coff_aux_clr_token {
- support::ulittle8_t AuxType;
- support::ulittle8_t Reserved;
- support::ulittle32_t SymbolTableIndex;
- uint8_t Unused[12];
- };
} // namespace
static uint64_t getOffsetOfLSDA(const Win64EH::UnwindInfo& UI) {
@@ -538,23 +519,11 @@ error_code COFFDumper::getSection(
}
void COFFDumper::cacheRelocations() {
- error_code EC;
- for (section_iterator SecI = Obj->begin_sections(),
- SecE = Obj->end_sections();
- SecI != SecE; SecI.increment(EC)) {
- if (error(EC))
- break;
-
- const coff_section *Section = Obj->getCOFFSection(SecI);
-
- for (relocation_iterator RelI = SecI->begin_relocations(),
- RelE = SecI->end_relocations();
- RelI != RelE; RelI.increment(EC)) {
- if (error(EC))
- break;
+ for (const SectionRef &S : Obj->sections()) {
+ const coff_section *Section = Obj->getCOFFSection(S);
- RelocMap[Section].push_back(*RelI);
- }
+ for (const RelocationRef &Reloc : S.relocations())
+ RelocMap[Section].push_back(Reloc);
// Sort relocations by address.
std::sort(RelocMap[Section].begin(), RelocMap[Section].end(),
@@ -598,73 +567,239 @@ void COFFDumper::printFileHeaders() {
const pe32_header *PEHeader = 0;
if (error(Obj->getPE32Header(PEHeader)))
return;
+ if (PEHeader)
+ printPEHeader<pe32_header>(PEHeader);
+
+ const pe32plus_header *PEPlusHeader = 0;
+ if (error(Obj->getPE32PlusHeader(PEPlusHeader)))
+ return;
+ if (PEPlusHeader)
+ printPEHeader<pe32plus_header>(PEPlusHeader);
+}
+
+template <class PEHeader>
+void COFFDumper::printPEHeader(const PEHeader *Hdr) {
+ DictScope D(W, "ImageOptionalHeader");
+ W.printNumber("MajorLinkerVersion", Hdr->MajorLinkerVersion);
+ W.printNumber("MinorLinkerVersion", Hdr->MinorLinkerVersion);
+ W.printNumber("SizeOfCode", Hdr->SizeOfCode);
+ W.printNumber("SizeOfInitializedData", Hdr->SizeOfInitializedData);
+ W.printNumber("SizeOfUninitializedData", Hdr->SizeOfUninitializedData);
+ W.printHex ("AddressOfEntryPoint", Hdr->AddressOfEntryPoint);
+ W.printHex ("BaseOfCode", Hdr->BaseOfCode);
+ printBaseOfDataField(Hdr);
+ W.printHex ("ImageBase", Hdr->ImageBase);
+ W.printNumber("SectionAlignment", Hdr->SectionAlignment);
+ W.printNumber("FileAlignment", Hdr->FileAlignment);
+ W.printNumber("MajorOperatingSystemVersion",
+ Hdr->MajorOperatingSystemVersion);
+ W.printNumber("MinorOperatingSystemVersion",
+ Hdr->MinorOperatingSystemVersion);
+ W.printNumber("MajorImageVersion", Hdr->MajorImageVersion);
+ W.printNumber("MinorImageVersion", Hdr->MinorImageVersion);
+ W.printNumber("MajorSubsystemVersion", Hdr->MajorSubsystemVersion);
+ W.printNumber("MinorSubsystemVersion", Hdr->MinorSubsystemVersion);
+ W.printNumber("SizeOfImage", Hdr->SizeOfImage);
+ W.printNumber("SizeOfHeaders", Hdr->SizeOfHeaders);
+ W.printEnum ("Subsystem", Hdr->Subsystem, makeArrayRef(PEWindowsSubsystem));
+ W.printFlags ("Subsystem", Hdr->DLLCharacteristics,
+ makeArrayRef(PEDLLCharacteristics));
+ W.printNumber("SizeOfStackReserve", Hdr->SizeOfStackReserve);
+ W.printNumber("SizeOfStackCommit", Hdr->SizeOfStackCommit);
+ W.printNumber("SizeOfHeapReserve", Hdr->SizeOfHeapReserve);
+ W.printNumber("SizeOfHeapCommit", Hdr->SizeOfHeapCommit);
+ W.printNumber("NumberOfRvaAndSize", Hdr->NumberOfRvaAndSize);
+
+ if (Hdr->NumberOfRvaAndSize > 0) {
+ DictScope D(W, "DataDirectory");
+ static const char * const directory[] = {
+ "ExportTable", "ImportTable", "ResourceTable", "ExceptionTable",
+ "CertificateTable", "BaseRelocationTable", "Debug", "Architecture",
+ "GlobalPtr", "TLSTable", "LoadConfigTable", "BoundImport", "IAT",
+ "DelayImportDescriptor", "CLRRuntimeHeader", "Reserved"
+ };
+
+ for (uint32_t i = 0; i < Hdr->NumberOfRvaAndSize; ++i) {
+ printDataDirectory(i, directory[i]);
+ }
+ }
+}
+
+void COFFDumper::printBaseOfDataField(const pe32_header *Hdr) {
+ W.printHex("BaseOfData", Hdr->BaseOfData);
+}
+
+void COFFDumper::printBaseOfDataField(const pe32plus_header *) {}
+
+void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
+ StringRef Data;
+ if (error(Section.getContents(Data)))
+ return;
+
+ SmallVector<StringRef, 10> FunctionNames;
+ StringMap<StringRef> FunctionLineTables;
+ StringRef FileIndexToStringOffsetTable;
+ StringRef StringTable;
+
+ ListScope D(W, "CodeViewLineTables");
+ {
+ DataExtractor DE(Data, true, 4);
+ uint32_t Offset = 0,
+ Magic = DE.getU32(&Offset);
+ W.printHex("Magic", Magic);
+ if (Magic != COFF::DEBUG_SECTION_MAGIC) {
+ error(object_error::parse_failed);
+ return;
+ }
+
+ bool Finished = false;
+ while (DE.isValidOffset(Offset) && !Finished) {
+ // The section consists of a number of subsection in the following format:
+ // |Type|PayloadSize|Payload...|
+ uint32_t SubSectionType = DE.getU32(&Offset),
+ PayloadSize = DE.getU32(&Offset);
+ ListScope S(W, "Subsection");
+ W.printHex("Type", SubSectionType);
+ W.printHex("PayloadSize", PayloadSize);
+ if (PayloadSize > Data.size() - Offset) {
+ error(object_error::parse_failed);
+ return;
+ }
+
+ // Print the raw contents to simplify debugging if anything goes wrong
+ // afterwards.
+ StringRef Contents = Data.substr(Offset, PayloadSize);
+ W.printBinaryBlock("Contents", Contents);
+
+ switch (SubSectionType) {
+ 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
+ // pointers for deferred processing.
+
+ if (PayloadSize < 12) {
+ // There should be at least three words to store two function
+ // relocations and size of the code.
+ error(object_error::parse_failed);
+ return;
+ }
+
+ StringRef FunctionName;
+ if (error(resolveSymbolName(RelocMap[Obj->getCOFFSection(Section)],
+ Offset, FunctionName)))
+ return;
+ W.printString("FunctionName", FunctionName);
+ if (FunctionLineTables.count(FunctionName) != 0) {
+ // Saw debug info for this function already?
+ error(object_error::parse_failed);
+ return;
+ }
+
+ FunctionLineTables[FunctionName] = Contents;
+ FunctionNames.push_back(FunctionName);
+ break;
+ }
+ case COFF::DEBUG_STRING_TABLE_SUBSECTION:
+ if (PayloadSize == 0 || StringTable.data() != 0 ||
+ Contents.back() != '\0') {
+ // Empty or duplicate or non-null-terminated subsection.
+ error(object_error::parse_failed);
+ return;
+ }
+ StringTable = 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() != 0) {
+ // Empty or duplicate subsection.
+ error(object_error::parse_failed);
+ return;
+ }
+ FileIndexToStringOffsetTable = Contents;
+ break;
+ }
+ Offset += PayloadSize;
+
+ // Align the reading pointer by 4.
+ Offset += (-Offset) % 4;
+ }
+ }
+
+ // Dump the line tables now that we've read all the subsections and know all
+ // the required information.
+ for (unsigned I = 0, E = FunctionNames.size(); I != E; ++I) {
+ StringRef Name = FunctionNames[I];
+ ListScope S(W, "FunctionLineTable");
+ W.printString("FunctionName", Name);
+
+ DataExtractor DE(FunctionLineTables[Name], true, 4);
+ uint32_t Offset = 8; // Skip relocations.
+ uint32_t FunctionSize = DE.getU32(&Offset);
+ W.printHex("CodeSize", FunctionSize);
+ while (DE.isValidOffset(Offset)) {
+ // For each range of lines with the same filename, we have a segment
+ // in the line table. The filename string is accessed using double
+ // indirection to the string table subsection using the index subsection.
+ uint32_t OffsetInIndex = DE.getU32(&Offset),
+ SegmentLength = DE.getU32(&Offset),
+ FullSegmentSize = DE.getU32(&Offset);
+ if (FullSegmentSize != 12 + 8 * SegmentLength) {
+ error(object_error::parse_failed);
+ return;
+ }
+
+ uint32_t FilenameOffset;
+ {
+ DataExtractor SDE(FileIndexToStringOffsetTable, true, 4);
+ uint32_t OffsetInSDE = OffsetInIndex;
+ if (!SDE.isValidOffset(OffsetInSDE)) {
+ error(object_error::parse_failed);
+ return;
+ }
+ FilenameOffset = SDE.getU32(&OffsetInSDE);
+ }
- if (PEHeader) {
- DictScope D(W, "ImageOptionalHeader");
- W.printNumber("MajorLinkerVersion", PEHeader->MajorLinkerVersion);
- W.printNumber("MinorLinkerVersion", PEHeader->MinorLinkerVersion);
- W.printNumber("SizeOfCode", PEHeader->SizeOfCode);
- W.printNumber("SizeOfInitializedData", PEHeader->SizeOfInitializedData);
- W.printNumber("SizeOfUninitializedData", PEHeader->SizeOfUninitializedData);
- W.printHex ("AddressOfEntryPoint", PEHeader->AddressOfEntryPoint);
- W.printHex ("BaseOfCode", PEHeader->BaseOfCode);
- W.printHex ("BaseOfData", PEHeader->BaseOfData);
- W.printHex ("ImageBase", PEHeader->ImageBase);
- W.printNumber("SectionAlignment", PEHeader->SectionAlignment);
- W.printNumber("FileAlignment", PEHeader->FileAlignment);
- W.printNumber("MajorOperatingSystemVersion",
- PEHeader->MajorOperatingSystemVersion);
- W.printNumber("MinorOperatingSystemVersion",
- PEHeader->MinorOperatingSystemVersion);
- W.printNumber("MajorImageVersion", PEHeader->MajorImageVersion);
- W.printNumber("MinorImageVersion", PEHeader->MinorImageVersion);
- W.printNumber("MajorSubsystemVersion", PEHeader->MajorSubsystemVersion);
- W.printNumber("MinorSubsystemVersion", PEHeader->MinorSubsystemVersion);
- W.printNumber("SizeOfImage", PEHeader->SizeOfImage);
- W.printNumber("SizeOfHeaders", PEHeader->SizeOfHeaders);
- W.printEnum ("Subsystem", PEHeader->Subsystem,
- makeArrayRef(PEWindowsSubsystem));
- W.printFlags ("Subsystem", PEHeader->DLLCharacteristics,
- makeArrayRef(PEDLLCharacteristics));
- W.printNumber("SizeOfStackReserve", PEHeader->SizeOfStackReserve);
- W.printNumber("SizeOfStackCommit", PEHeader->SizeOfStackCommit);
- W.printNumber("SizeOfHeapReserve", PEHeader->SizeOfHeapReserve);
- W.printNumber("SizeOfHeapCommit", PEHeader->SizeOfHeapCommit);
- W.printNumber("NumberOfRvaAndSize", PEHeader->NumberOfRvaAndSize);
-
- if (PEHeader->NumberOfRvaAndSize > 0) {
- DictScope D(W, "DataDirectory");
- static const char * const directory[] = {
- "ExportTable", "ImportTable", "ResourceTable", "ExceptionTable",
- "CertificateTable", "BaseRelocationTable", "Debug", "Architecture",
- "GlobalPtr", "TLSTable", "LoadConfigTable", "BoundImport", "IAT",
- "DelayImportDescriptor", "CLRRuntimeHeader", "Reserved"
- };
-
- for (uint32_t i = 0; i < PEHeader->NumberOfRvaAndSize; ++i) {
- printDataDirectory(i, directory[i]);
+ if (FilenameOffset == 0 || FilenameOffset + 1 >= StringTable.size() ||
+ StringTable.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);
+ ListScope S(W, "FilenameSegment");
+ W.printString("Filename", Filename);
+ for (unsigned J = 0; J != SegmentLength && DE.isValidOffset(Offset);
+ ++J) {
+ // Then go the (PC, LineNumber) pairs. The line number is stored in the
+ // least significant 31 bits of the respective word in the table.
+ uint32_t PC = DE.getU32(&Offset),
+ LineNumber = DE.getU32(&Offset) & 0x7fffffff;
+ if (PC >= FunctionSize) {
+ error(object_error::parse_failed);
+ return;
+ }
+ char Buffer[32];
+ format("+0x%X", PC).snprint(Buffer, 32);
+ W.printNumber(Buffer, LineNumber);
}
}
}
}
void COFFDumper::printSections() {
- error_code EC;
-
ListScope SectionsD(W, "Sections");
int SectionNumber = 0;
- for (section_iterator SecI = Obj->begin_sections(),
- SecE = Obj->end_sections();
- SecI != SecE; SecI.increment(EC)) {
- if (error(EC))
- break;
-
+ for (const SectionRef &Sec : Obj->sections()) {
++SectionNumber;
- const coff_section *Section = Obj->getCOFFSection(SecI);
+ const coff_section *Section = Obj->getCOFFSection(Sec);
StringRef Name;
- if (error(SecI->getName(Name)))
- Name = "";
+ if (error(Sec.getName(Name)))
+ Name = "";
DictScope D(W, "Section");
W.printNumber("Number", SectionNumber);
@@ -683,33 +818,28 @@ void COFFDumper::printSections() {
if (opts::SectionRelocations) {
ListScope D(W, "Relocations");
- for (relocation_iterator RelI = SecI->begin_relocations(),
- RelE = SecI->end_relocations();
- RelI != RelE; RelI.increment(EC)) {
- if (error(EC)) break;
-
- printRelocation(SecI, RelI);
- }
+ for (const RelocationRef &Reloc : Sec.relocations())
+ printRelocation(Sec, Reloc);
}
if (opts::SectionSymbols) {
ListScope D(W, "Symbols");
- for (symbol_iterator SymI = Obj->begin_symbols(),
- SymE = Obj->end_symbols();
- SymI != SymE; SymI.increment(EC)) {
- if (error(EC)) break;
-
+ for (const SymbolRef &Symbol : Obj->symbols()) {
bool Contained = false;
- if (SecI->containsSymbol(*SymI, Contained) || !Contained)
+ if (Sec.containsSymbol(Symbol, Contained) || !Contained)
continue;
- printSymbol(SymI);
+ printSymbol(Symbol);
}
}
+ if (Name == ".debug$S" && opts::CodeViewLineTables)
+ printCodeViewLineTables(Sec);
+
if (opts::SectionData) {
StringRef Data;
- if (error(SecI->getContents(Data))) break;
+ if (error(Sec.getContents(Data)))
+ break;
W.printBinaryBlock("SectionData", Data);
}
@@ -719,32 +849,22 @@ void COFFDumper::printSections() {
void COFFDumper::printRelocations() {
ListScope D(W, "Relocations");
- error_code EC;
int SectionNumber = 0;
- for (section_iterator SecI = Obj->begin_sections(),
- SecE = Obj->end_sections();
- SecI != SecE; SecI.increment(EC)) {
+ for (const SectionRef &Section : Obj->sections()) {
++SectionNumber;
- if (error(EC))
- break;
-
StringRef Name;
- if (error(SecI->getName(Name)))
+ if (error(Section.getName(Name)))
continue;
bool PrintedGroup = false;
- for (relocation_iterator RelI = SecI->begin_relocations(),
- RelE = SecI->end_relocations();
- RelI != RelE; RelI.increment(EC)) {
- if (error(EC)) break;
-
+ for (const RelocationRef &Reloc : Section.relocations()) {
if (!PrintedGroup) {
W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
W.indent();
PrintedGroup = true;
}
- printRelocation(SecI, RelI);
+ printRelocation(Section, Reloc);
}
if (PrintedGroup) {
@@ -754,19 +874,24 @@ void COFFDumper::printRelocations() {
}
}
-void COFFDumper::printRelocation(section_iterator SecI,
- relocation_iterator RelI) {
+void COFFDumper::printRelocation(const SectionRef &Section,
+ const RelocationRef &Reloc) {
uint64_t Offset;
uint64_t RelocType;
SmallString<32> RelocName;
StringRef SymbolName;
StringRef Contents;
- if (error(RelI->getOffset(Offset))) return;
- if (error(RelI->getType(RelocType))) return;
- if (error(RelI->getTypeName(RelocName))) return;
- symbol_iterator Symbol = RelI->getSymbol();
- if (error(Symbol->getName(SymbolName))) return;
- if (error(SecI->getContents(Contents))) return;
+ if (error(Reloc.getOffset(Offset)))
+ return;
+ if (error(Reloc.getType(RelocType)))
+ return;
+ if (error(Reloc.getTypeName(RelocName)))
+ return;
+ symbol_iterator Symbol = Reloc.getSymbol();
+ if (error(Symbol->getName(SymbolName)))
+ return;
+ if (error(Section.getContents(Contents)))
+ return;
if (opts::ExpandRelocs) {
DictScope Group(W, "Relocation");
@@ -785,24 +910,16 @@ void COFFDumper::printRelocation(section_iterator SecI,
void COFFDumper::printSymbols() {
ListScope Group(W, "Symbols");
- error_code EC;
- for (symbol_iterator SymI = Obj->begin_symbols(),
- SymE = Obj->end_symbols();
- SymI != SymE; SymI.increment(EC)) {
- if (error(EC)) break;
-
- printSymbol(SymI);
- }
+ for (const SymbolRef &Symbol : Obj->symbols())
+ printSymbol(Symbol);
}
-void COFFDumper::printDynamicSymbols() {
- ListScope Group(W, "DynamicSymbols");
-}
+void COFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); }
-void COFFDumper::printSymbol(symbol_iterator SymI) {
+void COFFDumper::printSymbol(const SymbolRef &Sym) {
DictScope D(W, "Symbol");
- const coff_symbol *Symbol = Obj->getCOFFSymbol(SymI);
+ const coff_symbol *Symbol = Obj->getCOFFSymbol(Sym);
const coff_section *Section;
if (error_code EC = Obj->getSection(Symbol->SectionNumber, Section)) {
W.startLine() << "Invalid section number: " << EC.message() << "\n";
@@ -829,10 +946,7 @@ void COFFDumper::printSymbol(symbol_iterator SymI) {
W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols);
for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) {
- if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
- Symbol->getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
- Symbol->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
- Symbol->SectionNumber > 0) {
+ if (Symbol->isFunctionDefinition()) {
const coff_aux_function_definition *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break;
@@ -840,16 +954,12 @@ void COFFDumper::printSymbol(symbol_iterator SymI) {
DictScope AS(W, "AuxFunctionDef");
W.printNumber("TagIndex", Aux->TagIndex);
W.printNumber("TotalSize", Aux->TotalSize);
- W.printHex("PointerToLineNumber", Aux->PointerToLineNumber);
+ W.printHex("PointerToLineNumber", Aux->PointerToLinenumber);
W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);
W.printBinary("Unused", makeArrayRef(Aux->Unused));
- } else if (
- Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
- (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
- Symbol->SectionNumber == 0 &&
- Symbol->Value == 0)) {
- const coff_aux_weak_external_definition *Aux;
+ } else if (Symbol->isWeakExternal()) {
+ const coff_aux_weak_external *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break;
@@ -866,9 +976,9 @@ void COFFDumper::printSymbol(symbol_iterator SymI) {
W.printNumber("Linked", LinkedName, Aux->TagIndex);
W.printEnum ("Search", Aux->Characteristics,
makeArrayRef(WeakExternalCharacteristics));
- W.printBinary("Unused", Aux->Unused);
+ W.printBinary("Unused", makeArrayRef(Aux->Unused));
- } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FILE) {
+ } else if (Symbol->isFileRecord()) {
const coff_aux_file_record *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break;
@@ -876,9 +986,7 @@ void COFFDumper::printSymbol(symbol_iterator SymI) {
DictScope AS(W, "AuxFileRecord");
W.printString("FileName", StringRef(Aux->FileName));
- } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC ||
- (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
- Symbol->SectionNumber != COFF::IMAGE_SYM_UNDEFINED)) {
+ } else if (Symbol->isSectionDefinition()) {
const coff_aux_section_definition *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break;
@@ -905,16 +1013,25 @@ void COFFDumper::printSymbol(symbol_iterator SymI) {
W.printNumber("AssocSection", AssocName, Aux->Number);
}
- } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN) {
+ } else if (Symbol->isCLRToken()) {
const coff_aux_clr_token *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break;
+ const coff_symbol *ReferredSym;
+ StringRef ReferredName;
+ error_code EC;
+ if ((EC = Obj->getSymbol(Aux->SymbolTableIndex, ReferredSym)) ||
+ (EC = Obj->getSymbolName(ReferredSym, ReferredName))) {
+ ReferredName = "";
+ error(EC);
+ }
+
DictScope AS(W, "AuxCLRToken");
W.printNumber("AuxType", Aux->AuxType);
W.printNumber("Reserved", Aux->Reserved);
- W.printNumber("SymbolTableIndex", Aux->SymbolTableIndex);
- W.printBinary("Unused", Aux->Unused);
+ W.printNumber("SymbolTableIndex", ReferredName, Aux->SymbolTableIndex);
+ W.printBinary("Unused", makeArrayRef(Aux->Unused));
} else {
W.startLine() << "<unhandled auxiliary record>\n";
@@ -938,23 +1055,17 @@ void COFFDumper::printUnwindInfo() {
}
void COFFDumper::printX64UnwindInfo() {
- error_code EC;
- for (section_iterator SecI = Obj->begin_sections(),
- SecE = Obj->end_sections();
- SecI != SecE; SecI.increment(EC)) {
- if (error(EC)) break;
-
+ for (const SectionRef &Section : Obj->sections()) {
StringRef Name;
- if (error(SecI->getName(Name)))
+ if (error(Section.getName(Name)))
continue;
if (Name != ".pdata" && !Name.startswith(".pdata$"))
continue;
- const coff_section *PData = Obj->getCOFFSection(SecI);
+ const coff_section *PData = Obj->getCOFFSection(Section);
ArrayRef<uint8_t> Contents;
- if (error(Obj->getSectionContents(PData, Contents)) ||
- Contents.empty())
+ if (error(Obj->getSectionContents(PData, Contents)) || Contents.empty())
continue;
ArrayRef<RuntimeFunction> RFs(