mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-14 15:28:20 +00:00
tools: refactor COFFDumper symbol resolution logic
Make the use of the cache more transparent to the users. There is no reason that the cached entries really need to be passed along. The overhead for doing so is minimal: a single extra parameter. This requires that some standalone functions be brought into the COFFDumper class so that they may access the cache. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209604 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -64,15 +64,12 @@ private:
|
|||||||
void printBaseOfDataField(const pe32_header *Hdr);
|
void printBaseOfDataField(const pe32_header *Hdr);
|
||||||
void printBaseOfDataField(const pe32plus_header *Hdr);
|
void printBaseOfDataField(const pe32plus_header *Hdr);
|
||||||
|
|
||||||
void printRuntimeFunction(
|
void printRuntimeFunction(const RuntimeFunction& RTF,
|
||||||
const RuntimeFunction& RTF,
|
const coff_section *Section,
|
||||||
uint64_t OffsetInSection,
|
uint64_t SectionOffset);
|
||||||
const std::vector<RelocationRef> &Rels);
|
|
||||||
|
|
||||||
void printUnwindInfo(
|
void printUnwindInfo(const Win64EH::UnwindInfo& UI,
|
||||||
const Win64EH::UnwindInfo& UI,
|
const coff_section *Section, uint64_t SectionOffset);
|
||||||
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);
|
||||||
|
|
||||||
@@ -80,8 +77,16 @@ private:
|
|||||||
|
|
||||||
void cacheRelocations();
|
void cacheRelocations();
|
||||||
|
|
||||||
error_code getSection(const std::vector<RelocationRef> &Rels, uint64_t Offset,
|
error_code resolveRelocation(const coff_section *Section, uint64_t Offset,
|
||||||
const coff_section *&Section, uint64_t &AddrPtr);
|
const coff_section *&ReesolvedSection,
|
||||||
|
uint64_t &ResolvedAddress);
|
||||||
|
|
||||||
|
error_code resolveSymbol(const coff_section *Section, uint64_t Offset,
|
||||||
|
SymbolRef &Sym);
|
||||||
|
error_code resolveSymbolName(const coff_section *Section, uint64_t Offset,
|
||||||
|
StringRef &Name);
|
||||||
|
std::string formatSymbol(const coff_section *Section, uint64_t Offset,
|
||||||
|
uint32_t Disp);
|
||||||
|
|
||||||
typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
|
typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
|
||||||
|
|
||||||
@@ -182,32 +187,33 @@ static error_code resolveSectionAndAddress(const COFFObjectFile *Obj,
|
|||||||
return object_error::success;
|
return object_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a vector of relocations for a section and an offset into this section
|
// Given a a section and an offset into this section the function returns the
|
||||||
// the function returns the symbol used for the relocation at the offset.
|
// symbol used for the relocation at the offset.
|
||||||
static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
|
error_code COFFDumper::resolveSymbol(const coff_section *Section,
|
||||||
uint64_t Offset, SymbolRef &Sym) {
|
uint64_t Offset, SymbolRef &Sym) {
|
||||||
for (const auto &Relocation : Rels) {
|
const auto &Relocations = RelocMap[Section];
|
||||||
uint64_t Ofs;
|
for (const auto &Relocation : Relocations) {
|
||||||
if (error_code EC = Relocation.getOffset(Ofs))
|
uint64_t RelocationOffset;
|
||||||
|
if (error_code EC = Relocation.getOffset(RelocationOffset))
|
||||||
return EC;
|
return EC;
|
||||||
|
|
||||||
if (Ofs == Offset) {
|
if (RelocationOffset == Offset) {
|
||||||
Sym = *Relocation.getSymbol();
|
Sym = *Relocation.getSymbol();
|
||||||
return readobj_error::success;
|
return readobj_error::success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return readobj_error::unknown_symbol;
|
return readobj_error::unknown_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a vector of relocations for a section and an offset into this section
|
// Given a section and an offset into this section the function returns the name
|
||||||
// the function returns the name of the symbol used for the relocation at the
|
// of the symbol used for the relocation at the offset.
|
||||||
// offset.
|
error_code COFFDumper::resolveSymbolName(const coff_section *Section,
|
||||||
static error_code resolveSymbolName(const std::vector<RelocationRef> &Rels,
|
|
||||||
uint64_t Offset, StringRef &Name) {
|
uint64_t Offset, StringRef &Name) {
|
||||||
SymbolRef Sym;
|
SymbolRef Symbol;
|
||||||
if (error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC;
|
if (error_code EC = resolveSymbol(Section, Offset, Symbol))
|
||||||
if (error_code EC = Sym.getName(Name)) return EC;
|
return EC;
|
||||||
|
if (error_code EC = Symbol.getName(Name))
|
||||||
|
return EC;
|
||||||
return object_error::success;
|
return object_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,13 +442,13 @@ static error_code getSymbolAuxData(const COFFObjectFile *Obj,
|
|||||||
return readobj_error::success;
|
return readobj_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string formatSymbol(const std::vector<RelocationRef> &Rels,
|
std::string COFFDumper::formatSymbol(const coff_section *Section,
|
||||||
uint64_t Offset, uint32_t Disp) {
|
uint64_t Offset, uint32_t Disp) {
|
||||||
std::string Buffer;
|
std::string Buffer;
|
||||||
raw_string_ostream Str(Buffer);
|
raw_string_ostream Str(Buffer);
|
||||||
|
|
||||||
StringRef Sym;
|
StringRef Sym;
|
||||||
if (resolveSymbolName(Rels, Offset, Sym)) {
|
if (resolveSymbolName(Section, Offset, Sym)) {
|
||||||
Str << format(" (0x%" PRIX64 ")", Offset);
|
Str << format(" (0x%" PRIX64 ")", Offset);
|
||||||
return Str.str();
|
return Str.str();
|
||||||
}
|
}
|
||||||
@@ -457,15 +463,16 @@ static std::string formatSymbol(const std::vector<RelocationRef> &Rels,
|
|||||||
return Str.str();
|
return Str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code COFFDumper::getSection(const std::vector<RelocationRef> &Rels,
|
error_code COFFDumper::resolveRelocation(const coff_section *Section,
|
||||||
uint64_t Offset,
|
uint64_t Offset,
|
||||||
const coff_section *&SectionPtr,
|
const coff_section *&ResolvedSection,
|
||||||
uint64_t &AddrPtr) {
|
uint64_t &ResolvedAddress) {
|
||||||
SymbolRef Sym;
|
SymbolRef Sym;
|
||||||
if (error_code EC = resolveSymbol(Rels, Offset, Sym))
|
if (error_code EC = resolveSymbol(Section, Offset, Sym))
|
||||||
return EC;
|
return EC;
|
||||||
|
|
||||||
if (error_code EC = resolveSectionAndAddress(Obj, Sym, SectionPtr, AddrPtr))
|
if (error_code EC = resolveSectionAndAddress(Obj, Sym, ResolvedSection,
|
||||||
|
ResolvedAddress))
|
||||||
return EC;
|
return EC;
|
||||||
|
|
||||||
return object_error::success;
|
return object_error::success;
|
||||||
@@ -638,8 +645,8 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringRef FunctionName;
|
StringRef FunctionName;
|
||||||
if (error(resolveSymbolName(RelocMap[Obj->getCOFFSection(Section)],
|
if (error(resolveSymbolName(Obj->getCOFFSection(Section), Offset,
|
||||||
Offset, FunctionName)))
|
FunctionName)))
|
||||||
return;
|
return;
|
||||||
W.printString("FunctionName", FunctionName);
|
W.printString("FunctionName", FunctionName);
|
||||||
if (FunctionLineTables.count(FunctionName) != 0) {
|
if (FunctionLineTables.count(FunctionName) != 0) {
|
||||||
@@ -1033,27 +1040,27 @@ void COFFDumper::printX64UnwindInfo() {
|
|||||||
const uint64_t OffsetInSection = std::distance(RFs.begin(), I)
|
const uint64_t OffsetInSection = std::distance(RFs.begin(), I)
|
||||||
* sizeof(RuntimeFunction);
|
* sizeof(RuntimeFunction);
|
||||||
|
|
||||||
printRuntimeFunction(*I, OffsetInSection, RelocMap[PData]);
|
printRuntimeFunction(*I, PData, OffsetInSection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void COFFDumper::printRuntimeFunction(
|
void COFFDumper::printRuntimeFunction(const RuntimeFunction& RTF,
|
||||||
const RuntimeFunction& RTF,
|
const coff_section *Section,
|
||||||
uint64_t OffsetInSection,
|
uint64_t SectionOffset) {
|
||||||
const std::vector<RelocationRef> &Rels) {
|
|
||||||
|
|
||||||
DictScope D(W, "RuntimeFunction");
|
DictScope D(W, "RuntimeFunction");
|
||||||
W.printString("StartAddress",
|
W.printString("StartAddress",
|
||||||
formatSymbol(Rels, OffsetInSection + 0, RTF.StartAddress));
|
formatSymbol(Section, SectionOffset + 0, RTF.StartAddress));
|
||||||
W.printString("EndAddress",
|
W.printString("EndAddress",
|
||||||
formatSymbol(Rels, OffsetInSection + 4, RTF.EndAddress));
|
formatSymbol(Section, SectionOffset + 4, RTF.EndAddress));
|
||||||
W.printString("UnwindInfoAddress",
|
W.printString("UnwindInfoAddress",
|
||||||
formatSymbol(Rels, OffsetInSection + 8, RTF.UnwindInfoOffset));
|
formatSymbol(Section, SectionOffset + 8, RTF.UnwindInfoOffset));
|
||||||
|
|
||||||
const coff_section* XData = nullptr;
|
const coff_section* XData = nullptr;
|
||||||
uint64_t UnwindInfoOffset = 0;
|
uint64_t UnwindInfoOffset = 0;
|
||||||
if (error(getSection(Rels, OffsetInSection + 8, XData, UnwindInfoOffset)))
|
if (error(getSectionFromRelocation(Section, SectionOffset + 8,
|
||||||
|
XData, UnwindInfoOffset)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ArrayRef<uint8_t> XContents;
|
ArrayRef<uint8_t> XContents;
|
||||||
@@ -1068,13 +1075,12 @@ void COFFDumper::printRuntimeFunction(
|
|||||||
reinterpret_cast<const Win64EH::UnwindInfo *>(
|
reinterpret_cast<const Win64EH::UnwindInfo *>(
|
||||||
XContents.data() + UnwindInfoOffset);
|
XContents.data() + UnwindInfoOffset);
|
||||||
|
|
||||||
printUnwindInfo(*UI, UnwindInfoOffset, RelocMap[XData]);
|
printUnwindInfo(*UI, XData, UnwindInfoOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void COFFDumper::printUnwindInfo(
|
void COFFDumper::printUnwindInfo(const Win64EH::UnwindInfo& UI,
|
||||||
const Win64EH::UnwindInfo& UI,
|
const coff_section *Section,
|
||||||
uint64_t OffsetInSection,
|
uint64_t SectionOffset) {
|
||||||
const std::vector<RelocationRef> &Rels) {
|
|
||||||
DictScope D(W, "UnwindInfo");
|
DictScope D(W, "UnwindInfo");
|
||||||
W.printNumber("Version", UI.getVersion());
|
W.printNumber("Version", UI.getVersion());
|
||||||
W.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags));
|
W.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags));
|
||||||
@@ -1103,19 +1109,21 @@ void COFFDumper::printUnwindInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t LSDAOffset = OffsetInSection + getOffsetOfLSDA(UI);
|
uint64_t LSDAOffset = SectionOffset + getOffsetOfLSDA(UI);
|
||||||
if (UI.getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
|
if (UI.getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
|
||||||
W.printString("Handler", formatSymbol(Rels, LSDAOffset,
|
W.printString("Handler",
|
||||||
|
formatSymbol(Section, LSDAOffset,
|
||||||
UI.getLanguageSpecificHandlerOffset()));
|
UI.getLanguageSpecificHandlerOffset()));
|
||||||
} else if (UI.getFlags() & UNW_ChainInfo) {
|
} else if (UI.getFlags() & UNW_ChainInfo) {
|
||||||
const RuntimeFunction *Chained = UI.getChainedFunctionEntry();
|
const RuntimeFunction *Chained = UI.getChainedFunctionEntry();
|
||||||
if (Chained) {
|
if (Chained) {
|
||||||
DictScope D(W, "Chained");
|
DictScope D(W, "Chained");
|
||||||
W.printString("StartAddress", formatSymbol(Rels, LSDAOffset + 0,
|
W.printString("StartAddress", formatSymbol(Section, LSDAOffset + 0,
|
||||||
Chained->StartAddress));
|
Chained->StartAddress));
|
||||||
W.printString("EndAddress", formatSymbol(Rels, LSDAOffset + 4,
|
W.printString("EndAddress", formatSymbol(Section, LSDAOffset + 4,
|
||||||
Chained->EndAddress));
|
Chained->EndAddress));
|
||||||
W.printString("UnwindInfoAddress", formatSymbol(Rels, LSDAOffset + 8,
|
W.printString("UnwindInfoAddress",
|
||||||
|
formatSymbol(Section, LSDAOffset + 8,
|
||||||
Chained->UnwindInfoOffset));
|
Chained->UnwindInfoOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user