summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-05-24 18:55:14 +0000
committerZachary Turner <zturner@google.com>2016-05-24 18:55:14 +0000
commit653eb429f5042e80e68f2f5ebc8f963db76d322d (patch)
tree324f29d0f18adcf563113366c5bfd3673c9a9d90
parent0f324db0db5d57cebe1b16701b8a6f4e1fc77562 (diff)
[codeview, pdb] Dump symbol records in publics streamHEADmaster
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.def5
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolRecord.h58
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/PublicsStream.h3
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/SymbolStream.h9
-rw-r--r--lib/DebugInfo/CodeView/SymbolDumper.cpp17
-rw-r--r--lib/DebugInfo/PDB/Raw/PublicsStream.cpp18
-rw-r--r--lib/DebugInfo/PDB/Raw/SymbolStream.cpp65
-rw-r--r--test/DebugInfo/PDB/pdbdump-headers.test47
-rw-r--r--tools/llvm-pdbdump/llvm-pdbdump.cpp15
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();
}