diff options
author | Zachary Turner <zturner@google.com> | 2016-05-24 18:55:14 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-05-24 18:55:14 +0000 |
commit | 653eb429f5042e80e68f2f5ebc8f963db76d322d (patch) | |
tree | 324f29d0f18adcf563113366c5bfd3673c9a9d90 | |
parent | 0f324db0db5d57cebe1b16701b8a6f4e1fc77562 (diff) |
Differential Revision: http://reviews.llvm.org/D20580
Reviewed By: ruiu
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270597 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/DebugInfo/CodeView/CVSymbolTypes.def | 5 | ||||
-rw-r--r-- | include/llvm/DebugInfo/CodeView/SymbolRecord.h | 58 | ||||
-rw-r--r-- | include/llvm/DebugInfo/PDB/Raw/PublicsStream.h | 3 | ||||
-rw-r--r-- | include/llvm/DebugInfo/PDB/Raw/SymbolStream.h | 9 | ||||
-rw-r--r-- | lib/DebugInfo/CodeView/SymbolDumper.cpp | 17 | ||||
-rw-r--r-- | lib/DebugInfo/PDB/Raw/PublicsStream.cpp | 18 | ||||
-rw-r--r-- | lib/DebugInfo/PDB/Raw/SymbolStream.cpp | 65 | ||||
-rw-r--r-- | test/DebugInfo/PDB/pdbdump-headers.test | 47 | ||||
-rw-r--r-- | tools/llvm-pdbdump/llvm-pdbdump.cpp | 15 |
9 files changed, 164 insertions, 73 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def b/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def index d3ecca534e1..991644d102c 100644 --- a/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def +++ b/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def @@ -130,7 +130,6 @@ CV_SYMBOL(S_THUNK32 , 0x1102) CV_SYMBOL(S_WITH32 , 0x1104) CV_SYMBOL(S_REGISTER , 0x1106) CV_SYMBOL(S_MANYREG , 0x110a) -CV_SYMBOL(S_PUB32 , 0x110e) CV_SYMBOL(S_LPROCMIPS , 0x1114) CV_SYMBOL(S_GPROCMIPS , 0x1115) CV_SYMBOL(S_COMPILE2 , 0x1116) @@ -148,7 +147,6 @@ CV_SYMBOL(S_MANMANYREG , 0x1121) CV_SYMBOL(S_MANREGREL , 0x1122) CV_SYMBOL(S_MANMANYREG2 , 0x1123) CV_SYMBOL(S_UNAMESPACE , 0x1124) -CV_SYMBOL(S_PROCREF , 0x1125) CV_SYMBOL(S_DATAREF , 0x1126) CV_SYMBOL(S_LPROCREF , 0x1127) CV_SYMBOL(S_ANNOTATIONREF , 0x1128) @@ -208,6 +206,9 @@ SYMBOL_RECORD_ALIAS(S_GPROC32_ID , 0x1147, GlobalProcIdSym, ProcSym) SYMBOL_RECORD_ALIAS(S_LPROC32_DPC , 0x1155, DPCProcSym, ProcSym) SYMBOL_RECORD_ALIAS(S_LPROC32_DPC_ID , 0x1156, DPCProcIdSym, ProcSym) +SYMBOL_RECORD(S_PUB32 , 0x110e, PublicSym32) +SYMBOL_RECORD(S_PROCREF , 0x1125, ProcRefSym) + SYMBOL_RECORD(S_INLINESITE , 0x114d, InlineSiteSym) SYMBOL_RECORD(S_LOCAL , 0x113e, LocalSym) SYMBOL_RECORD(S_DEFRANGE , 0x113f, DefRangeSym) diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h index 54d114c19b1..f0ff7335111 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -334,6 +334,64 @@ private: ArrayRef<uint8_t> Annotations; }; +// S_PUB32 +class PublicSym32 : public SymbolRecord { +public: + struct Hdr { + ulittle32_t Index; // Type index, or Metadata token if a managed symbol + ulittle32_t Off; + ulittle16_t Seg; + // Name: The null-terminated name follows. + }; + + PublicSym32(uint32_t RecordOffset, const Hdr *H, StringRef Name) + : SymbolRecord(SymbolRecordKind::PublicSym32), RecordOffset(RecordOffset), + Header(*H), Name(Name) {} + + static ErrorOr<PublicSym32> deserialize(SymbolRecordKind Kind, + uint32_t RecordOffset, + ArrayRef<uint8_t> &Data) { + const Hdr *H = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, H, Name); + + return PublicSym32(RecordOffset, H, Name); + } + + uint32_t RecordOffset; + Hdr Header; + StringRef Name; +}; + +// S_PROCREF +class ProcRefSym : public SymbolRecord { +public: + struct Hdr { + ulittle32_t SumName; // SUC of the name (?) + ulittle32_t SymOffset; // Offset of actual symbol in $$Symbols + ulittle16_t Mod; // Module containing the actual symbol + // Name: The null-terminated name follows. + }; + + ProcRefSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) + : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset), + Header(*H), Name(Name) {} + + static ErrorOr<ProcRefSym> deserialize(SymbolRecordKind Kind, + uint32_t RecordOffset, + ArrayRef<uint8_t> &Data) { + const Hdr *H = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, H, Name); + + return ProcRefSym(RecordOffset, H, Name); + } + + uint32_t RecordOffset; + Hdr Header; + StringRef Name; +}; + // S_LOCAL class LocalSym : public SymbolRecord { public: diff --git a/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h b/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h index 7f9522e4465..088bcb4da31 100644 --- a/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h +++ b/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_PUBLICSSTREAM_H #define LLVM_DEBUGINFO_PDB_RAW_PUBLICSSTREAM_H +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/TypeStream.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/DebugInfo/PDB/Raw/ByteStream.h" @@ -37,7 +38,7 @@ public: uint32_t getSymHash() const; uint32_t getAddrMap() const; uint32_t getNumBuckets() const { return NumBuckets; } - std::vector<std::string> getSymbols() const; + iterator_range<codeview::SymbolIterator> getSymbols() const; ArrayRef<uint32_t> getHashBuckets() const { return HashBuckets; } ArrayRef<uint32_t> getAddressMap() const { return AddressMap; } ArrayRef<uint32_t> getThunkMap() const { return ThunkMap; } diff --git a/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h b/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h index cffc92674d8..590fed735b3 100644 --- a/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h +++ b/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h @@ -10,11 +10,9 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSYMBOLSTREAM_H #define LLVM_DEBUGINFO_PDB_RAW_PDBSYMBOLSTREAM_H -#include "llvm/DebugInfo/CodeView/TypeStream.h" -#include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/PDB/Raw/ByteStream.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/Support/Error.h" @@ -28,10 +26,11 @@ public: ~SymbolStream(); Error reload(); - Expected<std::string> getSymbolName(uint32_t Offset) const; + iterator_range<codeview::SymbolIterator> getSymbols() const; private: - MappedBlockStream Stream; + ByteStream Stream; + MappedBlockStream MappedStream; }; } } diff --git a/lib/DebugInfo/CodeView/SymbolDumper.cpp b/lib/DebugInfo/CodeView/SymbolDumper.cpp index 2becd94b101..60a3b8156b6 100644 --- a/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ b/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -537,6 +537,23 @@ void CVSymbolDumperImpl::visitInlineSiteSym(SymbolKind Kind, } } +void CVSymbolDumperImpl::visitPublicSym32(SymbolKind Kind, + PublicSym32 &Public) { + DictScope S(W, "PublicSym"); + W.printNumber("Type", Public.Header.Index); + W.printNumber("Seg", Public.Header.Seg); + W.printNumber("Off", Public.Header.Off); + W.printString("Name", Public.Name); +} + +void CVSymbolDumperImpl::visitProcRefSym(SymbolKind Kind, ProcRefSym &ProcRef) { + DictScope S(W, "ProcRef"); + W.printNumber("SumName", ProcRef.Header.SumName); + W.printNumber("SymOffset", ProcRef.Header.SymOffset); + W.printNumber("Mod", ProcRef.Header.Mod); + W.printString("Name", ProcRef.Name); +} + void CVSymbolDumperImpl::visitLabelSym(SymbolKind Kind, LabelSym &Label) { DictScope S(W, "Label"); diff --git a/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/lib/DebugInfo/PDB/Raw/PublicsStream.cpp index 2e0b8971f91..af3cff32eb4 100644 --- a/lib/DebugInfo/PDB/Raw/PublicsStream.cpp +++ b/lib/DebugInfo/PDB/Raw/PublicsStream.cpp @@ -181,19 +181,13 @@ Error PublicsStream::reload() { return Error::success(); } -std::vector<std::string> PublicsStream::getSymbols() const { +iterator_range<codeview::SymbolIterator> PublicsStream::getSymbols() const { + using codeview::SymbolIterator; auto SymbolS = Pdb.getPDBSymbolStream(); - if (SymbolS.takeError()) - return {}; + if (SymbolS.takeError()) { + return llvm::make_range<SymbolIterator>(SymbolIterator(), SymbolIterator()); + } SymbolStream &SS = SymbolS.get(); - std::vector<std::string> Ret; - for (const HashRecord &HR : HashRecords) { - // For some reason, symbol offset is biased by one. - Expected<std::string> Name = SS.getSymbolName(HR.Off - 1); - if (Name.takeError()) - return Ret; - Ret.push_back(std::move(Name.get())); - } - return Ret; + return SS.getSymbols(); } diff --git a/lib/DebugInfo/PDB/Raw/SymbolStream.cpp b/lib/DebugInfo/PDB/Raw/SymbolStream.cpp index bd4280f3492..6249524eddd 100644 --- a/lib/DebugInfo/PDB/Raw/SymbolStream.cpp +++ b/lib/DebugInfo/PDB/Raw/SymbolStream.cpp @@ -11,6 +11,7 @@ #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Raw/ByteStream.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" @@ -22,62 +23,28 @@ using namespace llvm; using namespace llvm::support; using namespace llvm::pdb; -// Symbol stream is an array of symbol records. Each record starts with -// length and type fields followed by type-specfic fields. -namespace { -struct SymbolHeader { - ulittle16_t Len; // Record length - ulittle16_t Type; -}; - -// For S_PUB32 symbol type. -struct DataSym32 { - ulittle32_t TypIndex; // Type index, or Metadata token if a managed symbol - ulittle32_t off; - ulittle16_t seg; - char Name[1]; -}; - -// For S_PROCREF symbol type. -struct RefSym { - ulittle32_t SumName; // SUC of the name (?) - ulittle32_t SymOffset; // Offset of actual symbol in $$Symbols - ulittle16_t Mod; // Module containing the actual symbol - char Name[1]; -}; -} - SymbolStream::SymbolStream(PDBFile &File, uint32_t StreamNum) - : Stream(StreamNum, File) {} + : MappedStream(StreamNum, File) {} SymbolStream::~SymbolStream() {} -Error SymbolStream::reload() { return Error::success(); } - -Expected<std::string> SymbolStream::getSymbolName(uint32_t Off) const { - StreamReader Reader(Stream); - Reader.setOffset(Off); +Error SymbolStream::reload() { + StreamReader Reader(MappedStream); - // Read length field. - SymbolHeader Hdr; - if (Reader.readObject(&Hdr)) + if (Stream.initialize(Reader, MappedStream.getLength())) return make_error<RawError>(raw_error_code::corrupt_file, - "Corrupted symbol stream."); + "Could not load symbol stream."); - // Read the entire record. - std::vector<uint8_t> Buf(Hdr.Len - sizeof(Hdr.Type)); - if (Reader.readBytes(Buf)) - return make_error<RawError>(raw_error_code::corrupt_file, - "Corrupted symbol stream."); + return Error::success(); +} - switch (Hdr.Type) { - case codeview::S_PUB32: - return reinterpret_cast<DataSym32 *>(Buf.data())->Name; - case codeview::S_PROCREF: - return reinterpret_cast<RefSym *>(Buf.data())->Name; - default: - return make_error<RawError>(raw_error_code::corrupt_file, - "Unknown symbol type"); +iterator_range<codeview::SymbolIterator> SymbolStream::getSymbols() const { + using codeview::SymbolIterator; + ArrayRef<uint8_t> Data; + if (auto Error = Stream.getArrayRef(0, Data, Stream.getLength())) { + consumeError(std::move(Error)); + return iterator_range<SymbolIterator>(SymbolIterator(), SymbolIterator()); } - return Error::success(); + + return codeview::makeSymbolRange(Data, nullptr); } diff --git a/test/DebugInfo/PDB/pdbdump-headers.test b/test/DebugInfo/PDB/pdbdump-headers.test index 080b058e394..bb591355a55 100644 --- a/test/DebugInfo/PDB/pdbdump-headers.test +++ b/test/DebugInfo/PDB/pdbdump-headers.test @@ -380,7 +380,52 @@ ; EMPTY-NEXT: Address Map: [36, 0] ; EMPTY-NEXT: Thunk Map: [4112] ; EMPTY-NEXT: Section Offsets: [4096, 1] -; EMPTY-NEXT: Symbols: [?__purecall@@3PAXA, _main] +; EMPTY-NEXT: Symbols [ +; EMPTY-NEXT: { +; EMPTY-NEXT: PublicSym { +; EMPTY-NEXT: Type: 0 +; EMPTY-NEXT: Seg: 3 +; EMPTY-NEXT: Off: 0 +; EMPTY-NEXT: Name: ?__purecall@@3PAXA +; EMPTY-NEXT: } +; EMPTY-NEXT: Bytes ( +; EMPTY-NEXT: 0000: 00000000 00000000 03003F5F 5F707572 |..........?__pur| +; EMPTY-NEXT: 0010: 6563616C 6C404033 50415841 00000000 |ecall@@3PAXA....| +; EMPTY-NEXT: ) +; EMPTY-NEXT: } +; EMPTY-NEXT: { +; EMPTY-NEXT: PublicSym { +; EMPTY-NEXT: Type: 2 +; EMPTY-NEXT: Seg: 1 +; EMPTY-NEXT: Off: 16 +; EMPTY-NEXT: Name: _main +; EMPTY-NEXT: } +; EMPTY-NEXT: Bytes ( +; EMPTY-NEXT: 0000: 02000000 10000000 01005F6D 61696E00 |.........._main.| +; EMPTY-NEXT: ) +; EMPTY-NEXT: } +; EMPTY-NEXT: { +; EMPTY-NEXT: ProcRef { +; EMPTY-NEXT: SumName: 0 +; EMPTY-NEXT: SymOffset: 120 +; EMPTY-NEXT: Mod: 1 +; EMPTY-NEXT: Name: main +; EMPTY-NEXT: } +; EMPTY-NEXT: Bytes ( +; EMPTY-NEXT: 0000: 00000000 78000000 01006D61 696E0000 |....x.....main..| +; EMPTY-NEXT: ) +; EMPTY-NEXT: } +; EMPTY-NEXT: { +; EMPTY-NEXT: DataSym { +; EMPTY-NEXT: Type: void* (0x403) +; EMPTY-NEXT: DisplayName: __purecall +; EMPTY-NEXT: } +; EMPTY-NEXT: Bytes ( +; EMPTY-NEXT: 0000: 03040000 00000000 03005F5F 70757265 |..........__pure| +; EMPTY-NEXT: 0010: 63616C6C 00000000 |call....| +; EMPTY-NEXT: ) +; EMPTY-NEXT: } +; EMPTY-NEXT: ] ; EMPTY-NEXT: } ; BIG: FileHeaders { diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index 53c88ad3c26..d8dcd3d4076 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -425,7 +425,8 @@ static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File, return Error::success(); } -static Error dumpPublicsStream(ScopedPrinter &P, PDBFile &File) { +static Error dumpPublicsStream(ScopedPrinter &P, PDBFile &File, + codeview::CVTypeDumper &TD) { if (!opts::DumpPublics) return Error::success(); @@ -442,7 +443,15 @@ static Error dumpPublicsStream(ScopedPrinter &P, PDBFile &File) { P.printList("Address Map", Publics.getAddressMap()); P.printList("Thunk Map", Publics.getThunkMap()); P.printList("Section Offsets", Publics.getSectionOffsets()); - P.printList("Symbols", Publics.getSymbols()); + ListScope L(P, "Symbols"); + codeview::CVSymbolDumper SD(P, TD, nullptr, false); + for (auto S : Publics.getSymbols()) { + DictScope DD(P, ""); + + SD.dump(S); + if (opts::DumpSymRecordBytes) + P.printBinaryBlock("Bytes", S.Data); + } return Error::success(); } @@ -475,7 +484,7 @@ static Error dumpStructure(RawSession &RS) { if (auto EC = dumpDbiStream(P, File, TD)) return EC; - if (auto EC = dumpPublicsStream(P, File)) + if (auto EC = dumpPublicsStream(P, File, TD)) return EC; return Error::success(); } |