summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp47
-rw-r--r--llvm/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp38
-rw-r--r--llvm/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp89
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp59
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp8
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.cpp0
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp6
9 files changed, 246 insertions, 7 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp
index 4bbfe285423..79e5b9d690d 100644
--- a/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp
+++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp
@@ -48,3 +48,50 @@ Error ModuleDebugFileChecksumFragmentRef::initialize(
return Error::success();
}
+
+ModuleDebugFileChecksumFragment::ModuleDebugFileChecksumFragment()
+ : ModuleDebugFragment(ModuleDebugFragmentKind::FileChecksums) {}
+
+void ModuleDebugFileChecksumFragment::addChecksum(uint32_t StringTableOffset,
+ FileChecksumKind Kind,
+ ArrayRef<uint8_t> Bytes) {
+ FileChecksumEntry Entry;
+ if (!Bytes.empty()) {
+ uint8_t *Copy = Storage.Allocate<uint8_t>(Bytes.size());
+ ::memcpy(Copy, Bytes.data(), Bytes.size());
+ Entry.Checksum = makeArrayRef(Copy, Bytes.size());
+ }
+ Entry.FileNameOffset = StringTableOffset;
+ Entry.Kind = Kind;
+ Checksums.push_back(Entry);
+
+ // This maps the offset of this string in the string table to the offset
+ // of this checksum entry in the checksum buffer.
+ OffsetMap[StringTableOffset] = SerializedSize;
+ SerializedSize += sizeof(FileChecksumEntryHeader) + Bytes.size();
+}
+
+uint32_t ModuleDebugFileChecksumFragment::calculateSerializedLength() {
+ return SerializedSize;
+}
+
+Error ModuleDebugFileChecksumFragment::commit(BinaryStreamWriter &Writer) {
+ for (const auto &FC : Checksums) {
+ FileChecksumEntryHeader Header;
+ Header.ChecksumKind = uint8_t(FC.Kind);
+ Header.ChecksumSize = FC.Checksum.size();
+ Header.FileNameOffset = FC.FileNameOffset;
+ if (auto EC = Writer.writeObject(Header))
+ return EC;
+ if (auto EC = Writer.writeArray(makeArrayRef(FC.Checksum)))
+ return EC;
+ }
+ return Error::success();
+}
+
+uint32_t ModuleDebugFileChecksumFragment::mapChecksumOffset(
+ uint32_t StringTableOffset) const {
+ auto Iter = OffsetMap.find(StringTableOffset);
+ assert(Iter != OffsetMap.end());
+ return Iter->second;
+}
diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp
index 36f86cbbdf6..2af1917413d 100644
--- a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp
+++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp
@@ -12,3 +12,5 @@
using namespace llvm::codeview;
ModuleDebugFragmentRef::~ModuleDebugFragmentRef() {}
+
+ModuleDebugFragment::~ModuleDebugFragment() {}
diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp
index 20c06e9bebe..263b632da3f 100644
--- a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp
+++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/Support/BinaryStreamReader.h"
@@ -30,6 +31,13 @@ Error ModuleDebugFragmentRecord::initialize(BinaryStreamRef Stream,
ModuleDebugFragmentKind Kind =
static_cast<ModuleDebugFragmentKind>(uint32_t(Header->Kind));
+ switch (Kind) {
+ case ModuleDebugFragmentKind::FileChecksums:
+ case ModuleDebugFragmentKind::Lines:
+ break;
+ default:
+ llvm_unreachable("Unexpected debug fragment kind!");
+ }
if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))
return EC;
Info.Kind = Kind;
@@ -37,7 +45,9 @@ Error ModuleDebugFragmentRecord::initialize(BinaryStreamRef Stream,
}
uint32_t ModuleDebugFragmentRecord::getRecordLength() const {
- return sizeof(ModuleDebugFragmentHeader) + Data.getLength();
+ uint32_t Result = sizeof(ModuleDebugFragmentHeader) + Data.getLength();
+ assert(Result % 4 == 0);
+ return Result;
}
ModuleDebugFragmentKind ModuleDebugFragmentRecord::kind() const { return Kind; }
@@ -45,3 +55,29 @@ ModuleDebugFragmentKind ModuleDebugFragmentRecord::kind() const { return Kind; }
BinaryStreamRef ModuleDebugFragmentRecord::getRecordData() const {
return Data;
}
+
+ModuleDebugFragmentRecordBuilder::ModuleDebugFragmentRecordBuilder(
+ ModuleDebugFragmentKind Kind, ModuleDebugFragment &Frag)
+ : Kind(Kind), Frag(Frag) {}
+
+uint32_t ModuleDebugFragmentRecordBuilder::calculateSerializedLength() {
+ uint32_t Size = sizeof(ModuleDebugFragmentHeader) +
+ alignTo(Frag.calculateSerializedLength(), 4);
+ return Size;
+}
+
+Error ModuleDebugFragmentRecordBuilder::commit(BinaryStreamWriter &Writer) {
+ ModuleDebugFragmentHeader Header;
+ Header.Kind = uint32_t(Kind);
+ Header.Length =
+ calculateSerializedLength() - sizeof(ModuleDebugFragmentHeader);
+
+ if (auto EC = Writer.writeObject(Header))
+ return EC;
+ if (auto EC = Frag.commit(Writer))
+ return EC;
+ if (auto EC = Writer.padToAlignment(4))
+ return EC;
+
+ return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp
index 6a9751c1257..103010ca283 100644
--- a/llvm/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp
+++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp
@@ -64,3 +64,92 @@ Error ModuleDebugLineFragmentRef::initialize(BinaryStreamReader Reader) {
bool ModuleDebugLineFragmentRef::hasColumnInfo() const {
return !!(Header->Flags & LF_HaveColumns);
}
+
+ModuleDebugLineFragment::ModuleDebugLineFragment()
+ : ModuleDebugFragment(ModuleDebugFragmentKind::Lines) {}
+
+void ModuleDebugLineFragment::createBlock(uint32_t ChecksumBufferOffset) {
+ Blocks.emplace_back(ChecksumBufferOffset);
+}
+
+void ModuleDebugLineFragment::addLineInfo(uint32_t Offset,
+ const LineInfo &Line) {
+ Block &B = Blocks.back();
+ LineNumberEntry LNE;
+ LNE.Flags = Line.getRawData();
+ LNE.Offset = Offset;
+ B.Lines.push_back(LNE);
+}
+
+void ModuleDebugLineFragment::addLineAndColumnInfo(uint32_t Offset,
+ const LineInfo &Line,
+ uint32_t ColStart,
+ uint32_t ColEnd) {
+ Block &B = Blocks.back();
+ assert(B.Lines.size() == B.Columns.size());
+
+ addLineInfo(Offset, Line);
+ ColumnNumberEntry CNE;
+ CNE.StartColumn = ColStart;
+ CNE.EndColumn = ColEnd;
+ B.Columns.push_back(CNE);
+}
+
+Error ModuleDebugLineFragment::commit(BinaryStreamWriter &Writer) {
+ LineFragmentHeader Header;
+ Header.CodeSize = CodeSize;
+ Header.Flags = hasColumnInfo() ? LF_HaveColumns : 0;
+ Header.RelocOffset = RelocOffset;
+ Header.RelocSegment = RelocSegment;
+
+ if (auto EC = Writer.writeObject(Header))
+ return EC;
+
+ for (const auto &B : Blocks) {
+ LineBlockFragmentHeader BlockHeader;
+ assert(B.Lines.size() == B.Columns.size() || B.Columns.empty());
+
+ BlockHeader.NumLines = B.Lines.size();
+ BlockHeader.BlockSize = sizeof(LineBlockFragmentHeader);
+ BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(LineNumberEntry);
+ if (hasColumnInfo())
+ BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(ColumnNumberEntry);
+ BlockHeader.NameIndex = B.ChecksumBufferOffset;
+ if (auto EC = Writer.writeObject(BlockHeader))
+ return EC;
+
+ if (auto EC = Writer.writeArray(makeArrayRef(B.Lines)))
+ return EC;
+
+ if (hasColumnInfo()) {
+ if (auto EC = Writer.writeArray(makeArrayRef(B.Columns)))
+ return EC;
+ }
+ }
+ return Error::success();
+}
+
+uint32_t ModuleDebugLineFragment::calculateSerializedLength() {
+ uint32_t Size = sizeof(LineFragmentHeader);
+ for (const auto &B : Blocks) {
+ Size += sizeof(LineBlockFragmentHeader);
+ Size += B.Lines.size() * sizeof(LineNumberEntry);
+ if (hasColumnInfo())
+ Size += B.Columns.size() * sizeof(ColumnNumberEntry);
+ }
+ return Size;
+}
+
+void ModuleDebugLineFragment::setRelocationAddress(uint16_t Segment,
+ uint16_t Offset) {
+ RelocOffset = Offset;
+ RelocSegment = Segment;
+}
+
+void ModuleDebugLineFragment::setCodeSize(uint32_t Size) { CodeSize = Size; }
+
+void ModuleDebugLineFragment::setFlags(LineFlags Flags) { this->Flags = Flags; }
+
+bool ModuleDebugLineFragment::hasColumnInfo() const {
+ return Flags & LF_HaveColumns;
+}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp b/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp
index f9ded6ce2a8..efaba4646ff 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp
@@ -110,6 +110,10 @@ const CVType &TypeDatabase::getTypeRecord(TypeIndex Index) const {
return TypeRecords[Index.getIndex() - TypeIndex::FirstNonSimpleIndex];
}
+CVType &TypeDatabase::getTypeRecord(TypeIndex Index) {
+ return TypeRecords[Index.getIndex() - TypeIndex::FirstNonSimpleIndex];
+}
+
bool TypeDatabase::containsTypeIndex(TypeIndex Index) const {
uint32_t I = Index.getIndex() - TypeIndex::FirstNonSimpleIndex;
return I < CVUDTNames.size();
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index 8920dd9bbea..41cb23a188f 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -10,6 +10,7 @@
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
@@ -35,11 +36,12 @@ template <> struct BinaryItemTraits<CVSymbol> {
};
}
-static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize) {
+static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize,
+ uint32_t C13Size) {
uint32_t Size = sizeof(uint32_t); // Signature
Size += SymbolByteSize; // Symbol Data
- Size += 0; // TODO: Layout.LineBytes
- Size += 0; // TODO: Layout.C13Bytes
+ Size += 0; // TODO: Layout.C11Bytes
+ Size += C13Size; // C13 Debug Info Size
Size += sizeof(uint32_t); // GlobalRefs substream size (always 0)
Size += 0; // GlobalRefs substream bytes
return Size;
@@ -52,6 +54,8 @@ DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
Layout.Mod = ModIndex;
}
+DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder() {}
+
uint16_t DbiModuleDescriptorBuilder::getStreamIndex() const {
return Layout.ModDiStream;
}
@@ -69,6 +73,15 @@ void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
SourceFiles.push_back(Path);
}
+uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
+ uint32_t Result = 0;
+ for (const auto &Builder : C13Builders) {
+ assert(Builder && "Empty C13 Fragment Builder!");
+ Result += Builder->calculateSerializedLength();
+ }
+ return Result;
+}
+
uint32_t DbiModuleDescriptorBuilder::calculateSerializedLength() const {
uint32_t L = sizeof(Layout);
uint32_t M = ModuleName.size() + 1;
@@ -80,7 +93,7 @@ void DbiModuleDescriptorBuilder::finalize() {
Layout.FileNameOffs = 0; // TODO: Fix this
Layout.Flags = 0; // TODO: Fix this
Layout.C11Bytes = 0;
- Layout.C13Bytes = 0;
+ Layout.C13Bytes = calculateC13DebugInfoSize();
(void)Layout.Mod; // Set in constructor
(void)Layout.ModDiStream; // Set in finalizeMsfLayout
Layout.NumFiles = SourceFiles.size();
@@ -94,7 +107,9 @@ void DbiModuleDescriptorBuilder::finalize() {
Error DbiModuleDescriptorBuilder::finalizeMsfLayout() {
this->Layout.ModDiStream = kInvalidStreamIndex;
- auto ExpectedSN = MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize));
+ uint32_t C13Size = calculateC13DebugInfoSize();
+ auto ExpectedSN =
+ MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size));
if (!ExpectedSN)
return ExpectedSN.takeError();
Layout.ModDiStream = *ExpectedSN;
@@ -130,7 +145,13 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
if (auto EC = SymbolWriter.writeStreamRef(RecordsRef))
return EC;
// TODO: Write C11 Line data
- // TODO: Write C13 Line data
+
+ for (const auto &Builder : C13Builders) {
+ assert(Builder && "Empty C13 Fragment Builder!");
+ if (auto EC = Builder->commit(SymbolWriter))
+ return EC;
+ }
+
// TODO: Figure out what GlobalRefs substream actually is and populate it.
if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
return EC;
@@ -139,3 +160,29 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
}
return Error::success();
}
+
+void DbiModuleDescriptorBuilder::addC13LineFragment(
+ std::unique_ptr<ModuleDebugLineFragment> Lines) {
+ ModuleDebugLineFragment &Frag = *Lines;
+
+ // File Checksums have to come first, so push an empty entry on if this
+ // is the first.
+ if (C13Builders.empty())
+ C13Builders.push_back(nullptr);
+
+ this->LineInfo.push_back(std::move(Lines));
+ C13Builders.push_back(
+ llvm::make_unique<ModuleDebugFragmentRecordBuilder>(Frag.kind(), Frag));
+}
+
+void DbiModuleDescriptorBuilder::setC13FileChecksums(
+ std::unique_ptr<ModuleDebugFileChecksumFragment> Checksums) {
+ assert(!ChecksumInfo && "Can't have more than one checksum info!");
+
+ if (C13Builders.empty())
+ C13Builders.push_back(nullptr);
+
+ ChecksumInfo = std::move(Checksums);
+ C13Builders[0] = llvm::make_unique<ModuleDebugFragmentRecordBuilder>(
+ ChecksumInfo->kind(), *ChecksumInfo);
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index 62bda65cd99..c19a2f0d311 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -101,6 +101,14 @@ Error DbiStreamBuilder::addModuleSourceFile(StringRef Module, StringRef File) {
return Error::success();
}
+Expected<uint32_t> DbiStreamBuilder::getSourceFileNameIndex(StringRef File) {
+ auto NameIter = SourceFileNames.find(File);
+ if (NameIter == SourceFileNames.end())
+ return make_error<RawError>(raw_error_code::no_entry,
+ "The specified source file was not found");
+ return NameIter->getValue();
+}
+
uint32_t DbiStreamBuilder::calculateModiSubstreamSize() const {
uint32_t Size = 0;
for (const auto &M : ModiList)
diff --git a/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.cpp
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.cpp
diff --git a/llvm/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp
index e0f8370ab60..40dc8e1bfcb 100644
--- a/llvm/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp
@@ -29,6 +29,12 @@ uint32_t StringTableBuilder::insert(StringRef S) {
return P.first->second;
}
+uint32_t StringTableBuilder::getStringIndex(StringRef S) {
+ auto Iter = Strings.find(S);
+ assert(Iter != Strings.end());
+ return Iter->second;
+}
+
static uint32_t computeBucketCount(uint32_t NumStrings) {
// The /names stream is basically an on-disk open-addressing hash table.
// Hash collisions are resolved by linear probing. We cannot make
OpenPOWER on IntegriCloud