mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-11 07:15:26 +00:00
[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:
parent
337ec77e1a
commit
62dc24c965
@ -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.
|
||||
};
|
||||
|
@ -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())
|
||||
|
Loading…
x
Reference in New Issue
Block a user