summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/PDB
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp81
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp38
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp4
4 files changed, 114 insertions, 10 deletions
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index 0938c0762c8..46074f769cd 100644
--- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -29,6 +29,7 @@ endif()
add_pdb_impl_folder(Raw
Raw/DbiStream.cpp
+ Raw/EnumTables.cpp
Raw/InfoStream.cpp
Raw/MappedBlockStream.cpp
Raw/ModInfo.cpp
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
index 1827ab078df..96a68b6caa6 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
@@ -10,14 +10,17 @@
#include "llvm/DebugInfo/CodeView/StreamArray.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
+#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
using namespace llvm;
+using namespace llvm::codeview;
using namespace llvm::pdb;
using namespace llvm::support;
@@ -73,6 +76,20 @@ struct DbiStream::HeaderInfo {
ulittle32_t Reserved; // Pad to 64 bytes
};
+template <typename ContribType>
+Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
+ StreamReader &Reader) {
+ if (Reader.bytesRemaining() % sizeof(ContribType) != 0)
+ return make_error<RawError>(
+ raw_error_code::corrupt_file,
+ "Invalid number of bytes of section contributions");
+
+ uint32_t Count = Reader.bytesRemaining() / sizeof(ContribType);
+ if (auto EC = Reader.readArray(Output, Count))
+ return EC;
+ return Error::success();
+}
+
DbiStream::DbiStream(PDBFile &File)
: Pdb(File), Stream(StreamDBI, File), Header(nullptr) {
static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!");
@@ -81,7 +98,7 @@ DbiStream::DbiStream(PDBFile &File)
DbiStream::~DbiStream() {}
Error DbiStream::reload() {
- codeview::StreamReader Reader(Stream);
+ StreamReader Reader(Stream);
if (Stream.getLength() < sizeof(HeaderInfo))
return make_error<RawError>(raw_error_code::corrupt_file,
@@ -98,7 +115,7 @@ Error DbiStream::reload() {
// 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 make_error<RawError>(raw_error_code::corrupt_file,
+ return make_error<RawError>(raw_error_code::feature_unsupported,
"Unsupported DBI version.");
auto InfoStream = Pdb.getPDBInfoStream();
@@ -138,7 +155,7 @@ Error DbiStream::reload() {
// Since each ModInfo in the stream is a variable length, we have to iterate
// them to know how many there actually are.
- codeview::VarStreamArray<ModInfo> ModInfoArray;
+ VarStreamArray<ModInfo> ModInfoArray;
if (auto EC = Reader.readArray(ModInfoArray, Header->ModiSubstreamSize))
return EC;
for (auto &Info : ModInfoArray) {
@@ -161,6 +178,12 @@ Error DbiStream::reload() {
sizeof(ulittle16_t)))
return EC;
+ if (auto EC = initializeSectionContributionData())
+ return EC;
+
+ if (auto EC = initializeSectionMapData())
+ return EC;
+
if (auto EC = initializeFileInfo())
return EC;
@@ -168,7 +191,7 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"Found unexpected bytes in DBI Stream.");
- codeview::StreamReader ECReader(ECSubstream);
+ StreamReader ECReader(ECSubstream);
if (auto EC = ECNames.load(ECReader))
return EC;
@@ -222,6 +245,44 @@ PDB_Machine DbiStream::getMachineType() const {
}
ArrayRef<ModuleInfoEx> DbiStream::modules() const { return ModuleInfos; }
+codeview::FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
+ return SectionMap;
+}
+
+void llvm::pdb::DbiStream::visitSectionContributions(
+ ISectionContribVisitor &Visitor) const {
+ if (SectionContribVersion == DbiSecContribVer60) {
+ for (auto &SC : SectionContribs)
+ Visitor.visit(SC);
+ } else if (SectionContribVersion == DbiSecContribV2) {
+ for (auto &SC : SectionContribs2)
+ Visitor.visit(SC);
+ }
+}
+
+Error DbiStream::initializeSectionContributionData() {
+ StreamReader SCReader(SecContrSubstream);
+ if (auto EC = SCReader.readEnum(SectionContribVersion))
+ return EC;
+
+ if (SectionContribVersion == DbiSecContribVer60)
+ return loadSectionContribs<SectionContrib>(SectionContribs, SCReader);
+ if (SectionContribVersion == DbiSecContribV2)
+ return loadSectionContribs<SectionContrib2>(SectionContribs2, SCReader);
+
+ return make_error<RawError>(raw_error_code::feature_unsupported,
+ "Unsupported DBI Section Contribution version");
+}
+
+Error DbiStream::initializeSectionMapData() {
+ StreamReader SMReader(SecMapSubstream);
+ const SecMapHeader *Header;
+ if (auto EC = SMReader.readObject(Header))
+ return EC;
+ if (auto EC = SMReader.readArray(SectionMap, Header->SecCount))
+ return EC;
+ return Error::success();
+}
Error DbiStream::initializeFileInfo() {
struct FileInfoSubstreamHeader {
@@ -246,7 +307,7 @@ Error DbiStream::initializeFileInfo() {
// it is computed by summing `ModFileCounts`.
//
const FileInfoSubstreamHeader *FH;
- codeview::StreamReader FISR(FileInfoSubstream);
+ StreamReader FISR(FileInfoSubstream);
if (auto EC = FISR.readObject(FH))
return EC;
@@ -256,9 +317,9 @@ Error DbiStream::initializeFileInfo() {
return make_error<RawError>(raw_error_code::corrupt_file,
"FileInfo substream count doesn't match DBI.");
- codeview::FixedStreamArray<ulittle16_t> ModIndexArray;
- codeview::FixedStreamArray<ulittle16_t> ModFileCountArray;
- codeview::FixedStreamArray<little32_t> FileNameOffsets;
+ FixedStreamArray<ulittle16_t> ModIndexArray;
+ FixedStreamArray<ulittle16_t> ModFileCountArray;
+ FixedStreamArray<little32_t> FileNameOffsets;
// First is an array of `NumModules` module indices. This is not used for the
// same reason that `NumSourceFiles` is not used. It's an array of uint16's,
@@ -286,10 +347,10 @@ Error DbiStream::initializeFileInfo() {
if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles))
return EC;
- codeview::StreamRef NamesBufferRef;
+ StreamRef NamesBufferRef;
if (auto EC = FISR.readStreamRef(NamesBufferRef))
return EC;
- codeview::StreamReader Names(NamesBufferRef);
+ StreamReader Names(NamesBufferRef);
// We go through each ModuleInfo, determine the number N of source files for
// that module, and then get the next N offsets from the Offsets array, using
diff --git a/llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp b/llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp
new file mode 100644
index 00000000000..fc9270c6994
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp
@@ -0,0 +1,38 @@
+//===- EnumTables.cpp - Enum to string conversion tables --------*- 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/EnumTables.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+#define PDB_ENUM_CLASS_ENT(enum_class, enum) \
+ { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
+
+#define PDB_ENUM_ENT(ns, enum) \
+ { #enum, ns::enum }
+
+static const EnumEntry<uint16_t> OMFSegMapDescFlagNames[] = {
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Read),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Write),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Execute),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, AddressIs32Bit),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsSelector),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsAbsoluteAddress),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsGroup),
+};
+
+namespace llvm {
+namespace pdb {
+ArrayRef<EnumEntry<uint16_t>> getOMFSegMapDescFlagNames() {
+ return makeArrayRef(OMFSegMapDescFlagNames);
+}
+}
+} \ No newline at end of file
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
index 8b7a71508f8..b7204cb5afa 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
@@ -45,6 +45,10 @@ Error ModStream::reload() {
return EC;
if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
return EC;
+ ArrayRef<uint8_t> LineBytes;
+ codeview::StreamReader LinesReader(C13LinesSubstream);
+ if (auto EC = LinesReader.readBytes(LineBytes, C13LinesSubstream.getLength()))
+ return EC;
uint32_t GlobalRefsSize;
if (auto EC = Reader.readInteger(GlobalRefsSize))
OpenPOWER on IntegriCloud