summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/PDB
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-07-06 18:05:57 +0000
committerZachary Turner <zturner@google.com>2016-07-06 18:05:57 +0000
commit8848a7a6b253b9bba64283d4d754c2b52138c48a (patch)
treecfd03e61893308c413012debf91315424ec968c4 /llvm/lib/DebugInfo/PDB
parent2ebe18b6098ea7ba78bba54c633d9c6c3357d786 (diff)
downloadbcm5719-llvm-8848a7a6b253b9bba64283d4d754c2b52138c48a.tar.gz
bcm5719-llvm-8848a7a6b253b9bba64283d4d754c2b52138c48a.zip
[pdb] Round trip the PDB stream between YAML and binary PDB.
This gets writing of the PDB stream working. llvm-svn: 274647
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp51
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp20
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp94
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp2
8 files changed, 164 insertions, 11 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
index eba09bf0601..28250c588ff 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
@@ -452,3 +452,5 @@ Expected<StringRef> DbiStream::getFileNameForIndex(uint32_t Index) const {
return std::move(EC);
return Name;
}
+
+Error DbiStream::commit() { return Error::success(); }
diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
index 00671edf8e3..5273118f7c2 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
@@ -11,27 +11,31 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
+#include "llvm/DebugInfo/CodeView/StreamWriter.h"
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
using namespace llvm;
+using namespace llvm::codeview;
using namespace llvm::pdb;
+namespace {
+struct Header {
+ support::ulittle32_t Version;
+ support::ulittle32_t Signature;
+ support::ulittle32_t Age;
+ PDB_UniqueId Guid;
+};
+}
+
InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream)
: Stream(std::move(Stream)) {}
Error InfoStream::reload() {
codeview::StreamReader Reader(*Stream);
- struct Header {
- support::ulittle32_t Version;
- support::ulittle32_t Signature;
- support::ulittle32_t Age;
- PDB_UniqueId Guid;
- };
-
const Header *H;
if (auto EC = Reader.readObject(H))
return joinErrors(
@@ -39,9 +43,16 @@ Error InfoStream::reload() {
make_error<RawError>(raw_error_code::corrupt_file,
"PDB Stream does not contain a header."));
- if (H->Version < PdbRaw_ImplVer::PdbImplVC70)
+ switch (H->Version) {
+ case PdbImplVC70:
+ case PdbImplVC80:
+ case PdbImplVC110:
+ case PdbImplVC140:
+ break;
+ default:
return make_error<RawError>(raw_error_code::corrupt_file,
"Unsupported PDB stream version.");
+ }
Version = H->Version;
Signature = H->Signature;
@@ -72,3 +83,27 @@ uint32_t InfoStream::getSignature() const { return Signature; }
uint32_t InfoStream::getAge() const { return Age; }
PDB_UniqueId InfoStream::getGuid() const { return Guid; }
+
+void InfoStream::setVersion(PdbRaw_ImplVer Ver) {
+ Version = static_cast<uint32_t>(Ver);
+}
+
+void InfoStream::setSignature(uint32_t Sig) { Signature = Sig; }
+
+void InfoStream::setAge(uint32_t Age) { this->Age = Age; }
+
+void InfoStream::setGuid(PDB_UniqueId Guid) { this->Guid = Guid; }
+
+Error InfoStream::commit() {
+ StreamWriter Writer(*Stream);
+
+ Header H;
+ H.Age = Age;
+ H.Signature = Signature;
+ H.Version = Version;
+ H.Guid = Guid;
+ if (auto EC = Writer.writeObject(H))
+ return EC;
+
+ return NamedStreams.commit(Writer);
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
index e1c5e20067a..3415fcd4779 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
@@ -78,3 +78,5 @@ iterator_range<codeview::ModuleSubstreamArray::Iterator>
ModStream::lines(bool *HadError) const {
return llvm::make_range(LineInfo.begin(HadError), LineInfo.end());
}
+
+Error ModStream::commit() { return Error::success(); }
diff --git a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
index 51ec66a1b9d..3638380eb22 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
@@ -10,9 +10,11 @@
#include "llvm/DebugInfo/PDB/Raw/NameMap.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
+#include "llvm/DebugInfo/CodeView/StreamWriter.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
using namespace llvm;
+using namespace llvm::codeview;
using namespace llvm::pdb;
NameMap::NameMap() {}
@@ -143,6 +145,24 @@ Error NameMap::load(codeview::StreamReader &Stream) {
return Error::success();
}
+Error NameMap::commit(codeview::StreamWriter &Writer) {
+ if (auto EC = Writer.writeInteger(0U)) // Number of bytes in table
+ return EC;
+
+ if (auto EC = Writer.writeInteger(0U)) // Hash Size
+ return EC;
+
+ if (auto EC = Writer.writeInteger(0U)) // Max Number of Strings
+ return EC;
+
+ if (auto EC = Writer.writeInteger(0U)) // Num Present Words
+ return EC;
+
+ if (auto EC = Writer.writeInteger(0U)) // Num Deleted Words
+ return EC;
+ return Error::success();
+}
+
iterator_range<StringMapConstIterator<uint32_t>> NameMap::entries() const {
return llvm::make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(),
Mapping.end());
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
index cf0ef688b66..2d8e0d0ed91 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
@@ -89,7 +89,7 @@ Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset,
return make_error<RawError>(
raw_error_code::invalid_block_address,
"setBlockData attempted to write out of block bounds.");
- if (Data.size() >= getBlockSize() - Offset)
+ if (Data.size() > getBlockSize() - Offset)
return make_error<RawError>(
raw_error_code::invalid_block_address,
"setBlockData attempted to write out of block bounds.");
@@ -167,6 +167,17 @@ llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
return DirectoryBlocks;
}
+Expected<InfoStream &> PDBFile::emplacePDBInfoStream() {
+ if (Info)
+ Info.reset();
+
+ auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this);
+ if (!InfoS)
+ return InfoS.takeError();
+ Info = llvm::make_unique<InfoStream>(std::move(*InfoS));
+ return *Info;
+}
+
Expected<InfoStream &> PDBFile::getPDBInfoStream() {
if (!Info) {
auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this);
@@ -340,12 +351,59 @@ void PDBFile::setStreamSizes(ArrayRef<support::ulittle32_t> Sizes) {
}
void PDBFile::setStreamMap(
- ArrayRef<support::ulittle32_t> Directory,
std::vector<ArrayRef<support::ulittle32_t>> &Streams) {
- DirectoryBlocks = Directory;
StreamMap = Streams;
}
+void PDBFile::setDirectoryBlocks(ArrayRef<support::ulittle32_t> Directory) {
+ DirectoryBlocks = Directory;
+}
+
+Error PDBFile::generateSimpleStreamMap() {
+ if (StreamSizes.empty())
+ return Error::success();
+
+ static std::vector<std::vector<support::ulittle32_t>> StaticMap;
+ StreamMap.clear();
+ StaticMap.clear();
+
+ // Figure out how many blocks are needed for all streams, and set the first
+ // used block to the highest block so that we can write the rest of the
+ // blocks contiguously.
+ uint32_t TotalFileBlocks = getBlockCount();
+ std::vector<support::ulittle32_t> ReservedBlocks;
+ ReservedBlocks.push_back(support::ulittle32_t(0));
+ ReservedBlocks.push_back(SB->BlockMapAddr);
+ ReservedBlocks.insert(ReservedBlocks.end(), DirectoryBlocks.begin(),
+ DirectoryBlocks.end());
+
+ uint32_t BlocksNeeded = 0;
+ for (auto Size : StreamSizes)
+ BlocksNeeded += bytesToBlocks(Size, getBlockSize());
+
+ support::ulittle32_t NextBlock(TotalFileBlocks - BlocksNeeded -
+ ReservedBlocks.size());
+
+ StaticMap.resize(StreamSizes.size());
+ for (uint32_t S = 0; S < StreamSizes.size(); ++S) {
+ uint32_t Size = StreamSizes[S];
+ uint32_t NumBlocks = bytesToBlocks(Size, getBlockSize());
+ auto &ThisStream = StaticMap[S];
+ for (uint32_t I = 0; I < NumBlocks;) {
+ NextBlock += 1;
+ if (std::find(ReservedBlocks.begin(), ReservedBlocks.end(), NextBlock) !=
+ ReservedBlocks.end())
+ continue;
+
+ ++I;
+ assert(NextBlock < getBlockCount());
+ ThisStream.push_back(NextBlock);
+ }
+ StreamMap.push_back(ThisStream);
+ }
+ return Error::success();
+}
+
Error PDBFile::commit() {
StreamWriter Writer(*Buffer);
@@ -371,5 +429,35 @@ Error PDBFile::commit() {
return EC;
}
+ if (Info) {
+ if (auto EC = Info->commit())
+ return EC;
+ }
+
+ if (Dbi) {
+ if (auto EC = Dbi->commit())
+ return EC;
+ }
+
+ if (Symbols) {
+ if (auto EC = Symbols->commit())
+ return EC;
+ }
+
+ if (Publics) {
+ if (auto EC = Publics->commit())
+ return EC;
+ }
+
+ if (Tpi) {
+ if (auto EC = Tpi->commit())
+ return EC;
+ }
+
+ if (Ipi) {
+ if (auto EC = Ipi->commit())
+ return EC;
+ }
+
return Buffer->commit();
} \ No newline at end of file
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
index f768c01d4eb..af3d2d026b4 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
@@ -169,3 +169,5 @@ PublicsStream::getSymbols(bool *HadError) const {
return SS.getSymbols(HadError);
}
+
+Error PublicsStream::commit() { return Error::success(); }
diff --git a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
index c8e93c26a7d..41b2a64bfb1 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
@@ -42,3 +42,5 @@ iterator_range<codeview::CVSymbolArray::Iterator>
SymbolStream::getSymbols(bool *HadError) const {
return llvm::make_range(SymbolRecords.begin(HadError), SymbolRecords.end());
}
+
+Error SymbolStream::commit() { return Error::success(); }
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
index 7ff1e3dc8ce..8b44ec1b35e 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
@@ -269,3 +269,5 @@ iterator_range<CVTypeArray::Iterator>
TpiStream::types(bool *HadError) const {
return llvm::make_range(TypeRecords.begin(HadError), TypeRecords.end());
}
+
+Error TpiStream::commit() { return Error::success(); }
OpenPOWER on IntegriCloud