mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-25 17:20:48 +00:00
PR21189: Teach llvm-readobj to dump bits of COFF symbol subsections required to debug using VS2012+
Reviewed at http://reviews.llvm.org/D5755 Thanks to Andrey Guskov for his help investigating this! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220526 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -69,6 +69,10 @@ private:
|
||||
|
||||
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,
|
||||
@@ -444,6 +448,7 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
|
||||
|
||||
ListScope D(W, "CodeViewLineTables");
|
||||
{
|
||||
// FIXME: Add more offset correctness checks.
|
||||
DataExtractor DE(Data, true, 4);
|
||||
uint32_t Offset = 0,
|
||||
Magic = DE.getU32(&Offset);
|
||||
@@ -473,6 +478,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
|
||||
@@ -592,6 +600,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 FunctionName = DE.getCStr(&Offset);
|
||||
if (!DE.isValidOffset(Offset)) {
|
||||
error(object_error::parse_failed);
|
||||
return;
|
||||
}
|
||||
W.printString("FunctionName", FunctionName);
|
||||
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;
|
||||
|
Reference in New Issue
Block a user