Index: include/llvm/DebugInfo/CodeView/SymbolRecord.h =================================================================== --- include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -12,8 +12,10 @@ #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/RecordIterator.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" namespace llvm { namespace codeview { @@ -22,20 +24,80 @@ using llvm::support::ulittle32_t; using llvm::support::little32_t; +class SymbolRecord { +protected: + explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {} + +public: + SymbolRecordKind getKind() const { return Kind; } + +private: + SymbolRecordKind Kind; +}; + // S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or // S_LPROC32_DPC_ID -struct ProcSym { - ulittle32_t PtrParent; - ulittle32_t PtrEnd; - ulittle32_t PtrNext; - ulittle32_t CodeSize; - ulittle32_t DbgStart; - ulittle32_t DbgEnd; +class ProcSym : public SymbolRecord { +private: +public: + ProcSym(SymbolRecordKind Kind, uint32_t PtrParent, uint32_t PtrEnd, + uint32_t PtrNext, uint32_t CodeSize, uint32_t DbgStart, + uint32_t DbgEnd, TypeIndex FunctionType, uint32_t CodeOffset, + uint16_t Segment, ProcSymFlags Flags, StringRef Name) + : SymbolRecord(Kind), PtrParent(PtrParent), PtrEnd(PtrEnd), + PtrNext(PtrNext), CodeSize(CodeSize), DbgStart(DbgStart), + DbgEnd(DbgEnd), FunctionType(FunctionType), CodeOffset(CodeOffset), + Segment(Segment), Flags(Flags), Name(Name) {} + + static ErrorOr deserialize(SymbolRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, L, Name); + + return ProcSym(Kind, L->PtrParent, L->PtrEnd, L->PtrNext, L->CodeSize, + L->DbgStart, L->DbgEnd, L->FunctionType, L->CodeOffset, + L->Segment, static_cast(L->Flags), Name); + } + + uint32_t getParent() const { return PtrParent; } + uint32_t getEnd() const { return PtrEnd; } + uint32_t getNext() const { return PtrNext; } + uint32_t getCodeSize() const { return CodeSize; } + uint32_t getDbgStart() const { return DbgStart; } + uint32_t getDbgEnd() const { return DbgEnd; } + TypeIndex getFunctionType() const { return FunctionType; } + uint32_t getCodeOffset() const { return CodeOffset; } + uint16_t getSegment() const { return Segment; } + ProcSymFlags getFlags() const { return Flags; } + StringRef getName() const { return Name; } + +private: + struct Layout { + ulittle32_t PtrParent; + ulittle32_t PtrEnd; + ulittle32_t PtrNext; + ulittle32_t CodeSize; + ulittle32_t DbgStart; + ulittle32_t DbgEnd; + TypeIndex FunctionType; + ulittle32_t CodeOffset; + ulittle16_t Segment; + uint8_t Flags; // ProcSymFlags enum + // Name: The null-terminated name follows. + }; + + uint32_t PtrParent; + uint32_t PtrEnd; + uint32_t PtrNext; + uint32_t CodeSize; + uint32_t DbgStart; + uint32_t DbgEnd; TypeIndex FunctionType; - ulittle32_t CodeOffset; - ulittle16_t Segment; - uint8_t Flags; // ProcSymFlags enum - // Name: The null-terminated name follows. + uint32_t CodeOffset; + uint16_t Segment; + ProcSymFlags Flags; + StringRef Name; }; // S_INLINESITE Index: tools/llvm-readobj/COFFDumper.cpp =================================================================== --- tools/llvm-readobj/COFFDumper.cpp +++ tools/llvm-readobj/COFFDumper.cpp @@ -1021,25 +1021,29 @@ case S_LPROC32_DPC: case S_LPROC32_DPC_ID: { DictScope S(W, "ProcStart"); - const ProcSym *Proc; - error(consumeObject(SymData, Proc)); + ArrayRef Data(SymData.bytes_begin(), SymData.bytes_end()); + auto Proc = + ProcSym::deserialize(static_cast(Kind), Data); + if (Proc) + error(Proc.getError()); + if (InFunctionScope) return error(object_error::parse_failed); InFunctionScope = true; StringRef LinkageName; StringRef DisplayName = SymData.split('\0').first; - W.printHex("PtrParent", Proc->PtrParent); - W.printHex("PtrEnd", Proc->PtrEnd); - W.printHex("PtrNext", Proc->PtrNext); - W.printHex("CodeSize", Proc->CodeSize); - W.printHex("DbgStart", Proc->DbgStart); - W.printHex("DbgEnd", Proc->DbgEnd); - printTypeIndex("FunctionType", Proc->FunctionType); - printRelocatedField("CodeOffset", Sec, SectionContents, &Proc->CodeOffset, - &LinkageName); - W.printHex("Segment", Proc->Segment); - W.printFlags("Flags", Proc->Flags, makeArrayRef(ProcSymFlagNames)); + W.printHex("PtrParent", Proc->getParent()); + W.printHex("PtrEnd", Proc->getEnd()); + W.printHex("PtrNext", Proc->getNext()); + W.printHex("CodeSize", Proc->getCodeSize()); + W.printHex("DbgStart", Proc->getDbgStart()); + W.printHex("DbgEnd", Proc->getDbgEnd()); + printTypeIndex("FunctionType", Proc->getFunctionType()); + W.printHex("CodeOffset", Proc->getCodeOffset()); + W.printHex("Segment", Proc->getSegment()); + W.printFlags("Flags", static_cast(Proc->getFlags()), + makeArrayRef(ProcSymFlagNames)); W.printString("DisplayName", DisplayName); W.printString("LinkageName", LinkageName); break;