[llvm-readobj] Add support for dumping S_DEFRANGE symbols

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@259719 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer 2016-02-03 22:36:46 +00:00
parent 337ec77e1a
commit 62dc24c965
2 changed files with 138 additions and 2 deletions

View File

@ -19,6 +19,7 @@ namespace codeview {
using llvm::support::ulittle16_t;
using llvm::support::ulittle32_t;
using llvm::support::little32_t;
/// Distinguishes individual records in the Symbols subsection of a .debug$S
/// section. Equivalent to SYM_ENUM_e in cvinfo.h.
@ -111,6 +112,58 @@ struct LocalSym {
// Name: The null-terminated name follows.
};
struct LocalVariableAddrRange {
ulittle32_t OffsetStart;
ulittle16_t ISectStart;
ulittle16_t Range;
};
struct LocalVariableAddrGap {
ulittle16_t GapStartOffset;
ulittle16_t Range;
};
// S_DEFRANGE_REGISTER
struct DefRangeRegisterSym {
ulittle16_t Register;
ulittle16_t MayHaveNoName;
LocalVariableAddrRange Range;
// LocalVariableAddrGap Gaps[];
};
// S_DEFRANGE_SUBFIELD_REGISTER
struct DefRangeSubfieldRegisterSym {
ulittle16_t Register; // Register to which the variable is relative
ulittle16_t MayHaveNoName;
ulittle32_t OffsetInParent;
LocalVariableAddrRange Range;
// LocalVariableAddrGap Gaps[];
};
// S_DEFRANGE_FRAMEPOINTER_REL
struct DefRangeFramePointerRelSym {
little32_t Offset; // Offset from the frame pointer register
LocalVariableAddrRange Range;
// LocalVariableAddrGap Gaps[];
};
// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
struct DefRangeFramePointerRelFullScopeSym {
little32_t Offset; // Offset from the frame pointer register
};
// S_DEFRANGE_REGISTER_REL
struct DefRangeRegisterRelSym {
ulittle16_t BaseRegister;
ulittle16_t Flags;
ulittle32_t BasePointerOffset;
LocalVariableAddrRange Range;
// LocalVariableAddrGap Gaps[];
bool hasSpilledUDTMember() const { return Flags & 1; }
uint16_t offsetInParent() const { return Flags >> 4; }
};
// S_BLOCK32
struct BlockSym {
ulittle32_t PtrParent;
@ -219,7 +272,7 @@ struct BuildInfoSym {
// S_BPREL32
struct BPRelativeSym {
ulittle32_t Offset; // Offset from the base pointer register
little32_t Offset; // Offset from the base pointer register
TypeIndex Type; // Type of the variable
// Name: The null-terminated name follows.
};

View File

@ -89,6 +89,8 @@ private:
StringRef getFileNameForFileOffset(uint32_t FileOffset);
void printFileNameForOffset(StringRef Label, uint32_t FileOffset);
void printTypeIndex(StringRef FieldName, TypeIndex TI);
void printLocalVariableAddrRange(const LocalVariableAddrRange &Range);
void printLocalVariableAddrGap(const LocalVariableAddrGap &Gap);
void printCodeViewSymbolsSubsection(StringRef Subsection,
const SectionRef &Section,
@ -1499,6 +1501,75 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
break;
}
case S_DEFRANGE_REGISTER: {
DictScope S(W, "DefRangeRegister");
const DefRangeRegisterSym *DefRangeRegister;
error(consumeObject(SymData, DefRangeRegister));
W.printNumber("Register", DefRangeRegister->Register);
W.printNumber("MayHaveNoName", DefRangeRegister->MayHaveNoName);
printLocalVariableAddrRange(DefRangeRegister->Range);
while (!SymData.empty()) {
const LocalVariableAddrGap *Gap;
error(consumeObject(SymData, Gap));
printLocalVariableAddrGap(*Gap);
}
break;
}
case S_DEFRANGE_SUBFIELD_REGISTER: {
DictScope S(W, "DefRangeSubfieldRegister");
const DefRangeSubfieldRegisterSym *DefRangeSubfieldRegisterSym;
error(consumeObject(SymData, DefRangeSubfieldRegisterSym));
W.printNumber("Register", DefRangeSubfieldRegisterSym->Register);
W.printNumber("MayHaveNoName",
DefRangeSubfieldRegisterSym->MayHaveNoName);
W.printNumber("OffsetInParent",
DefRangeSubfieldRegisterSym->OffsetInParent);
printLocalVariableAddrRange(DefRangeSubfieldRegisterSym->Range);
while (!SymData.empty()) {
const LocalVariableAddrGap *Gap;
error(consumeObject(SymData, Gap));
printLocalVariableAddrGap(*Gap);
}
break;
}
case S_DEFRANGE_FRAMEPOINTER_REL: {
DictScope S(W, "DefRangeFramePointerRel");
const DefRangeFramePointerRelSym *DefRangeFramePointerRel;
error(consumeObject(SymData, DefRangeFramePointerRel));
W.printNumber("Offset", DefRangeFramePointerRel->Offset);
printLocalVariableAddrRange(DefRangeFramePointerRel->Range);
while (!SymData.empty()) {
const LocalVariableAddrGap *Gap;
error(consumeObject(SymData, Gap));
printLocalVariableAddrGap(*Gap);
}
break;
}
case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: {
DictScope S(W, "DefRangeFramePointerRelFullScope");
const DefRangeFramePointerRelFullScopeSym
*DefRangeFramePointerRelFullScope;
error(consumeObject(SymData, DefRangeFramePointerRelFullScope));
W.printNumber("Offset", DefRangeFramePointerRelFullScope->Offset);
break;
}
case S_DEFRANGE_REGISTER_REL: {
DictScope S(W, "DefRangeRegisterRel");
const DefRangeRegisterRelSym *DefRangeRegisterRel;
error(consumeObject(SymData, DefRangeRegisterRel));
W.printNumber("BaseRegister", DefRangeRegisterRel->BaseRegister);
W.printBoolean("HasSpilledUDTMember",
DefRangeRegisterRel->hasSpilledUDTMember());
W.printNumber("OffsetInParent", DefRangeRegisterRel->offsetInParent());
printLocalVariableAddrRange(DefRangeRegisterRel->Range);
while (!SymData.empty()) {
const LocalVariableAddrGap *Gap;
error(consumeObject(SymData, Gap));
printLocalVariableAddrGap(*Gap);
}
break;
}
case S_CALLSITEINFO: {
DictScope S(W, "CallSiteInfo");
const CallSiteInfoSym *CallSiteInfo;
@ -1650,7 +1721,7 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
DictScope S(W, "BPRelativeSym");
const BPRelativeSym *BPRel;
error(consumeObject(SymData, BPRel));
W.printHex("Offset", BPRel->Offset);
W.printNumber("Offset", BPRel->Offset);
printTypeIndex("Type", BPRel->Type);
StringRef VarName = SymData.split('\0').first;
W.printString("VarName", VarName);
@ -1812,6 +1883,18 @@ void COFFDumper::printTypeIndex(StringRef FieldName, TypeIndex TI) {
W.printHex(FieldName, TI.getIndex());
}
void COFFDumper::printLocalVariableAddrRange(
const LocalVariableAddrRange &Range) {
W.printNumber("OffsetStart", Range.OffsetStart);
W.printNumber("ISectStart", Range.ISectStart);
W.printNumber("Range", Range.Range);
}
void COFFDumper::printLocalVariableAddrGap(const LocalVariableAddrGap &Gap) {
W.printNumber("GapStartOffset", Gap.GapStartOffset);
W.printNumber("Range", Gap.Range);
}
StringRef COFFDumper::getFileNameForFileOffset(uint32_t FileOffset) {
// The file checksum subsection should precede all references to it.
if (!CVFileChecksumTable.data() || !CVStringTable.data())