diff options
| author | Zachary Turner <zturner@google.com> | 2016-04-26 16:20:00 +0000 |
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2016-04-26 16:20:00 +0000 |
| commit | f34e01624a95a86247b3ba8888feb24cba1f9006 (patch) | |
| tree | 8b92d38370952a49f7ee7cb48f81909dccbd8a3e /llvm/lib/DebugInfo | |
| parent | 1d99c4d03ce7d8d251f815e49caba968ea94b488 (diff) | |
| download | bcm5719-llvm-f34e01624a95a86247b3ba8888feb24cba1f9006.tar.gz bcm5719-llvm-f34e01624a95a86247b3ba8888feb24cba1f9006.zip | |
Refactor some more PDB reading code into DebugInfoPDB.
Differential Revision: http://reviews.llvm.org/D19445
Reviewed By: David Majnemer
llvm-svn: 267564
Diffstat (limited to 'llvm/lib/DebugInfo')
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp | 54 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp | 108 |
3 files changed, 164 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index 9d5eb69dbf5..5d6f3022889 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -28,6 +28,8 @@ endif() add_pdb_impl_folder(Raw Raw/PDBFile.cpp + Raw/PDBInfoStream.cpp + Raw/PDBNameMap.cpp Raw/PDBStream.cpp Raw/RawSession.cpp) diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp new file mode 100644 index 00000000000..47d9b294ec0 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp @@ -0,0 +1,54 @@ +//===- PDBInfoStream.cpp - PDB Info Stream (Stream 1) Access ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallVector.h" + +using namespace llvm; + +PDBInfoStream::PDBInfoStream(const PDBFile &File) + : Pdb(File), Stream1(1, File) {} + +std::error_code PDBInfoStream::reload() { + Stream1.setOffset(0); + support::ulittle32_t Value; + + Stream1.readObject(&Version); + if (Version < PdbRaw_ImplVer::VC70) + return std::make_error_code(std::errc::not_supported); + + Stream1.readObject(&Value); + Signature = Value; + + Stream1.readObject(&Value); + Age = Value; + + Stream1.readObject(&Guid); + NamedStreams.load(Stream1); + + return std::error_code(); +} + +uint32_t PDBInfoStream::getNamedStreamIndex(llvm::StringRef Name) const { + uint32_t Result; + if (!NamedStreams.tryGetValue(Name, Result)) + return 0; + return Result; +} + +PdbRaw_ImplVer PDBInfoStream::getVersion() const { + return static_cast<PdbRaw_ImplVer>(Version); +} + +uint32_t PDBInfoStream::getSignature() const { return Signature; } + +uint32_t PDBInfoStream::getAge() const { return Age; } + +PDB_UniqueId PDBInfoStream::getGuid() const { return Guid; } diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp new file mode 100644 index 00000000000..ed469317ee8 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp @@ -0,0 +1,108 @@ +//===- PDBNameMap.cpp - PDB Name Map ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Raw/PDBNameMap.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/DebugInfo/PDB/Raw/PDBStream.h" + +using namespace llvm; + +PDBNameMap::PDBNameMap() {} + +std::error_code PDBNameMap::load(PDBStream &Stream) { + // This is some sort of weird string-set/hash table encoded in the stream. + // It starts with the number of bytes in the table. + uint32_t NumberOfBytes; + Stream.readInteger(NumberOfBytes); + + // Following that field is the starting offset of strings in the name table. + uint32_t StringsOffset = Stream.getOffset(); + Stream.setOffset(StringsOffset + NumberOfBytes); + + // This appears to be equivalent to the total number of strings *actually* + // in the name table. + uint32_t HashSize; + Stream.readInteger(HashSize); + + // This appears to be an upper bound on the number of strings in the name + // table. + uint32_t MaxNumberOfStrings; + Stream.readInteger(MaxNumberOfStrings); + + // This appears to be a hash table which uses bitfields to determine whether + // or not a bucket is 'present'. + uint32_t NumPresentWords; + Stream.readInteger(NumPresentWords); + + // Store all the 'present' bits in a vector for later processing. + SmallVector<uint32_t, 1> PresentWords; + for (uint32_t I = 0; I != NumPresentWords; ++I) { + uint32_t Word; + Stream.readInteger(Word); + PresentWords.push_back(Word); + } + + // This appears to be a hash table which uses bitfields to determine whether + // or not a bucket is 'deleted'. + uint32_t NumDeletedWords; + Stream.readInteger(NumDeletedWords); + + // Store all the 'deleted' bits in a vector for later processing. + SmallVector<uint32_t, 1> DeletedWords; + for (uint32_t I = 0; I != NumDeletedWords; ++I) { + uint32_t Word; + Stream.readInteger(Word); + DeletedWords.push_back(Word); + } + + BitVector Present(MaxNumberOfStrings, false); + if (!PresentWords.empty()) + Present.setBitsInMask(PresentWords.data(), PresentWords.size()); + BitVector Deleted(MaxNumberOfStrings, false); + if (!DeletedWords.empty()) + Deleted.setBitsInMask(DeletedWords.data(), DeletedWords.size()); + + for (uint32_t I = 0; I < MaxNumberOfStrings; ++I) { + if (!Present.test(I)) + continue; + + // For all present entries, dump out their mapping. + + // This appears to be an offset relative to the start of the strings. + // It tells us where the null-terminated string begins. + uint32_t NameOffset; + Stream.readInteger(NameOffset); + + // This appears to be a stream number into the stream directory. + uint32_t NameIndex; + Stream.readInteger(NameIndex); + + // Compute the offset of the start of the string relative to the stream. + uint32_t StringOffset = StringsOffset + NameOffset; + uint32_t OldOffset = Stream.getOffset(); + // Pump out our c-string from the stream. + std::string Str; + Stream.setOffset(StringOffset); + Stream.readZeroString(Str); + + Stream.setOffset(OldOffset); + // Add this to a string-map from name to stream number. + Mapping.insert({Str, NameIndex}); + } + + return std::error_code(); +} + +bool PDBNameMap::tryGetValue(StringRef Name, uint32_t &Value) const { + auto Iter = Mapping.find(Name); + if (Iter == Mapping.end()) + return false; + Value = Iter->second; + return true; +} |

