summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp142
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp20
3 files changed, 161 insertions, 2 deletions
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index 24a9e8bf6f5..b98c37bfbc8 100644
--- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -27,6 +27,7 @@ if(HAVE_DIA_SDK)
endif()
add_pdb_impl_folder(Raw
+ Raw/ModInfo.cpp
Raw/PDBFile.cpp
Raw/PDBDbiStream.cpp
Raw/PDBInfoStream.cpp
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
new file mode 100644
index 00000000000..4634cb08245
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
@@ -0,0 +1,142 @@
+//===- ModInfo.cpp - PDB module information -------------------------------===//
+//
+// 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/ModInfo.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/Support/Endian.h"
+
+using namespace llvm;
+using namespace llvm::support;
+
+namespace {
+struct SCBytes {
+ ulittle16_t Section;
+ char Padding1[2];
+ little32_t Offset;
+ little32_t Size;
+ ulittle32_t Characteristics;
+ ulittle16_t ModuleIndex;
+ char Padding2[2];
+ ulittle32_t DataCrc;
+ ulittle32_t RelocCrc;
+};
+
+// struct Flags {
+// uint16_t fWritten : 1; // True if ModInfo is dirty
+// uint16_t fECEnabled : 1; // Is EC symbolic info present? (What is EC?)
+// uint16_t unused : 6; // Reserved
+// uint16_t iTSM : 8; // Type Server Index for this module
+//};
+const uint16_t HasECFlagMask = 0x2;
+
+const uint16_t TypeServerIndexMask = 0xFF00;
+const uint16_t TypeServerIndexShift = 8;
+}
+
+struct ModInfo::FileLayout {
+ ulittle32_t Mod; // Currently opened module. This field is a
+ // pointer in the reference implementation, but
+ // that won't work on 64-bit systems, and anyway
+ // it doesn't make sense to read a pointer from a
+ // file. For now it is unused, so just ignore it.
+ SCBytes SC; // First section contribution of this module.
+ ulittle16_t Flags; // See Flags definition.
+ ulittle16_t ModDiStream; // Stream Number of module debug info
+ ulittle32_t SymBytes; // Size of local symbol debug info in above stream
+ ulittle32_t LineBytes; // Size of line number debug info in above stream
+ ulittle32_t C13Bytes; // Size of C13 line number info in above stream
+ ulittle16_t NumFiles; // Number of files contributing to this module
+ char Padding1[2]; // Padding so the next field is 4-byte aligned.
+ ulittle32_t FileNameOffs; // array of [0..NumFiles) DBI name buffer offsets.
+ // This field is a pointer in the reference
+ // implementation, but as with `Mod`, we ignore it
+ // for now since it is unused.
+ ulittle32_t SrcFileNameNI; // Name Index for src file name
+ ulittle32_t PdbFilePathNI; // Name Index for path to compiler PDB
+ char VarInfo[1]; // Module name followed by Obj File Name
+
+ StringRef getModuleName() const { return StringRef(VarInfo); }
+
+ StringRef getObjectFileName() const {
+ return StringRef(getModuleName().end() + 1);
+ }
+};
+
+ModInfo::ModInfo(const uint8_t *Bytes)
+ : Layout(reinterpret_cast<const FileLayout *>(Bytes)) {}
+
+ModInfo::~ModInfo() {}
+
+bool ModInfo::hasECInfo() const { return (Layout->Flags & HasECFlagMask) != 0; }
+
+uint16_t ModInfo::getTypeServerIndex() const {
+ return (Layout->Flags & TypeServerIndexMask) >> TypeServerIndexShift;
+}
+
+uint16_t ModInfo::getModuleStreamIndex() const { return Layout->ModDiStream; }
+
+uint32_t ModInfo::getSymbolDebugInfoByteSize() const {
+ return Layout->SymBytes;
+}
+
+uint32_t ModInfo::getLineInfoByteSize() const { return Layout->LineBytes; }
+
+uint32_t ModInfo::getC13LineInfoByteSize() const { return Layout->C13Bytes; }
+
+uint32_t ModInfo::getNumberOfFiles() const { return Layout->NumFiles; }
+
+uint32_t ModInfo::getSourceFileNameIndex() const {
+ return Layout->SrcFileNameNI;
+}
+
+uint32_t ModInfo::getPdbFilePathNameIndex() const {
+ return Layout->PdbFilePathNI;
+}
+
+llvm::StringRef ModInfo::getModuleName() const {
+ return Layout->getModuleName();
+}
+
+llvm::StringRef ModInfo::getObjFileName() const {
+ return Layout->getObjectFileName();
+}
+
+ModInfoIterator::ModInfoIterator(const uint8_t *Stream) : Bytes(Stream) {}
+
+ModInfoIterator::ModInfoIterator(const ModInfoIterator &Other)
+ : Bytes(Other.Bytes) {}
+
+ModInfo ModInfoIterator::operator*() { return ModInfo(Bytes); }
+
+ModInfoIterator &ModInfoIterator::operator++() {
+ StringRef Obj = ModInfo(Bytes).getObjFileName();
+ Bytes = Obj.bytes_end() + 1;
+ Bytes = reinterpret_cast<const uint8_t *>(llvm::alignAddr(Bytes, 4));
+
+ return *this;
+}
+
+ModInfoIterator ModInfoIterator::operator++(int) {
+ ModInfoIterator Copy(*this);
+ ++(*this);
+ return Copy;
+}
+
+bool ModInfoIterator::operator==(const ModInfoIterator &Other) {
+ return Bytes == Other.Bytes;
+}
+
+bool ModInfoIterator::operator!=(const ModInfoIterator &Other) {
+ return !(*this == Other);
+}
+
+ModInfoIterator &ModInfoIterator::operator=(const ModInfoIterator &Other) {
+ Bytes = Other.Bytes;
+ return *this;
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp
index 40eb567d167..db84192bc36 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Raw/PDBDbiStream.h"
+#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBRawConstants.h"
@@ -84,8 +85,10 @@ std::error_code PDBDbiStream::reload() {
if (Header->VersionSignature != -1)
return std::make_error_code(std::errc::illegal_byte_sequence);
- // Prior to VC50 an old style header was used. We don't support this.
- if (Header->VersionHeader < PdbDbiV50)
+ // Require at least version 7, which should be present in all PDBs
+ // produced in the last decade and allows us to avoid having to
+ // special case all kinds of complicated arcane formats.
+ if (Header->VersionHeader < PdbDbiV70)
return std::make_error_code(std::errc::not_supported);
if (Header->Age != Pdb.getPDBInfoStream().getAge())
@@ -98,6 +101,14 @@ std::error_code PDBDbiStream::reload() {
Header->OptionalDbgHdrSize + Header->ECSubstreamSize)
return std::make_error_code(std::errc::illegal_byte_sequence);
+ if (Header->ModiSubstreamSize % sizeof(uint32_t) != 0)
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+
+ ModInfoSubstream.resize(Header->ModiSubstreamSize);
+ if (auto EC =
+ Stream.readBytes(&ModInfoSubstream[0], Header->ModiSubstreamSize))
+ return EC;
+
return std::error_code();
}
@@ -138,3 +149,8 @@ PDB_Machine PDBDbiStream::getMachineType() const {
uint16_t Machine = Header->MachineType;
return static_cast<PDB_Machine>(Machine);
}
+
+llvm::iterator_range<ModInfoIterator> PDBDbiStream::modules() const {
+ return llvm::make_range(ModInfoIterator(&ModInfoSubstream.front()),
+ ModInfoIterator(&ModInfoSubstream.back() + 1));
+}
OpenPOWER on IntegriCloud