diff options
| author | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
|---|---|---|
| committer | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
| commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
| tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp | |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp')
| -rw-r--r-- | contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp new file mode 100644 index 00000000000..b6f11a942a2 --- /dev/null +++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp @@ -0,0 +1,218 @@ +//===- DbiModuleDescriptorBuilder.cpp - PDB Mod Info Creation ---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/BinaryFormat/COFF.h" +#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" +#include "llvm/DebugInfo/MSF/MSFBuilder.h" +#include "llvm/DebugInfo/MSF/MSFCommon.h" +#include "llvm/DebugInfo/MSF/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawError.h" +#include "llvm/Support/BinaryStreamWriter.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::msf; +using namespace llvm::pdb; + +static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize, + uint32_t C13Size) { + uint32_t Size = sizeof(uint32_t); // Signature + Size += alignTo(SymbolByteSize, 4); // Symbol Data + 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; +} + +DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName, + uint32_t ModIndex, + msf::MSFBuilder &Msf) + : MSF(Msf), ModuleName(std::string(ModuleName)) { + ::memset(&Layout, 0, sizeof(Layout)); + Layout.Mod = ModIndex; +} + +DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder() {} + +uint16_t DbiModuleDescriptorBuilder::getStreamIndex() const { + return Layout.ModDiStream; +} + +void DbiModuleDescriptorBuilder::setObjFileName(StringRef Name) { + ObjFileName = std::string(Name); +} + +void DbiModuleDescriptorBuilder::setPdbFilePathNI(uint32_t NI) { + PdbFilePathNI = NI; +} + +void DbiModuleDescriptorBuilder::setFirstSectionContrib( + const SectionContrib &SC) { + Layout.SC = SC; +} + +void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) { + // Defer to the bulk API. It does the same thing. + addSymbolsInBulk(Symbol.data()); +} + +void DbiModuleDescriptorBuilder::addSymbolsInBulk( + ArrayRef<uint8_t> BulkSymbols) { + // Do nothing for empty runs of symbols. + if (BulkSymbols.empty()) + return; + + Symbols.push_back(SymbolListWrapper(BulkSymbols)); + // Symbols written to a PDB file are required to be 4 byte aligned. The same + // is not true of object files. + assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 && + "Invalid Symbol alignment!"); + SymbolByteSize += BulkSymbols.size(); +} + +void DbiModuleDescriptorBuilder::addUnmergedSymbols(void *SymSrc, + uint32_t SymLength) { + assert(SymLength > 0); + Symbols.push_back(SymbolListWrapper(SymSrc, SymLength)); + + // Symbols written to a PDB file are required to be 4 byte aligned. The same + // is not true of object files. + assert(SymLength % alignOf(CodeViewContainer::Pdb) == 0 && + "Invalid Symbol alignment!"); + SymbolByteSize += SymLength; +} + +void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) { + SourceFiles.push_back(std::string(Path)); +} + +uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const { + uint32_t Result = 0; + for (const auto &Builder : C13Builders) { + Result += Builder.calculateSerializedLength(); + } + return Result; +} + +uint32_t DbiModuleDescriptorBuilder::calculateSerializedLength() const { + uint32_t L = sizeof(Layout); + uint32_t M = ModuleName.size() + 1; + uint32_t O = ObjFileName.size() + 1; + return alignTo(L + M + O, sizeof(uint32_t)); +} + +void DbiModuleDescriptorBuilder::finalize() { + Layout.FileNameOffs = 0; // TODO: Fix this + Layout.Flags = 0; // TODO: Fix this + Layout.C11Bytes = 0; + Layout.C13Bytes = calculateC13DebugInfoSize(); + (void)Layout.Mod; // Set in constructor + (void)Layout.ModDiStream; // Set in finalizeMsfLayout + Layout.NumFiles = SourceFiles.size(); + Layout.PdbFilePathNI = PdbFilePathNI; + Layout.SrcFileNameNI = 0; + + // This value includes both the signature field as well as the record bytes + // from the symbol stream. + Layout.SymBytes = + Layout.ModDiStream == kInvalidStreamIndex ? 0 : getNextSymbolOffset(); +} + +Error DbiModuleDescriptorBuilder::finalizeMsfLayout() { + this->Layout.ModDiStream = kInvalidStreamIndex; + uint32_t C13Size = calculateC13DebugInfoSize(); + if (!C13Size && !SymbolByteSize) + return Error::success(); + auto ExpectedSN = + MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size)); + if (!ExpectedSN) + return ExpectedSN.takeError(); + Layout.ModDiStream = *ExpectedSN; + return Error::success(); +} + +Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter) { + // We write the Modi record to the `ModiWriter`, but we additionally write its + // symbol stream to a brand new stream. + if (auto EC = ModiWriter.writeObject(Layout)) + return EC; + if (auto EC = ModiWriter.writeCString(ModuleName)) + return EC; + if (auto EC = ModiWriter.writeCString(ObjFileName)) + return EC; + if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t))) + return EC; + return Error::success(); +} + +Error DbiModuleDescriptorBuilder::commitSymbolStream( + const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer) { + if (Layout.ModDiStream == kInvalidStreamIndex) + return Error::success(); + + auto NS = WritableMappedBlockStream::createIndexedStream( + MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator()); + WritableBinaryStreamRef Ref(*NS); + BinaryStreamWriter SymbolWriter(Ref); + // Write the symbols. + if (auto EC = SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC)) + return EC; + for (const SymbolListWrapper &Sym : Symbols) { + if (Sym.NeedsToBeMerged) { + assert(MergeSymsCallback); + if (auto EC = MergeSymsCallback(MergeSymsCtx, Sym.SymPtr, SymbolWriter)) + return EC; + } else { + if (auto EC = SymbolWriter.writeBytes(Sym.asArray())) + return EC; + } + } + + // Apply the string table fixups. + auto SavedOffset = SymbolWriter.getOffset(); + for (const StringTableFixup &Fixup : StringTableFixups) { + SymbolWriter.setOffset(Fixup.SymOffsetOfReference); + if (auto E = SymbolWriter.writeInteger<uint32_t>(Fixup.StrTabOffset)) + return E; + } + SymbolWriter.setOffset(SavedOffset); + + assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 && + "Invalid debug section alignment!"); + // TODO: Write C11 Line data + for (const auto &Builder : C13Builders) { + if (auto EC = Builder.commit(SymbolWriter, CodeViewContainer::Pdb)) + return EC; + } + + // TODO: Figure out what GlobalRefs substream actually is and populate it. + if (auto EC = SymbolWriter.writeInteger<uint32_t>(0)) + return EC; + if (SymbolWriter.bytesRemaining() > 0) + return make_error<RawError>(raw_error_code::stream_too_long); + + return Error::success(); +} + +void DbiModuleDescriptorBuilder::addDebugSubsection( + std::shared_ptr<DebugSubsection> Subsection) { + assert(Subsection); + C13Builders.push_back(DebugSubsectionRecordBuilder(std::move(Subsection))); +} + +void DbiModuleDescriptorBuilder::addDebugSubsection( + const DebugSubsectionRecord &SubsectionContents) { + C13Builders.push_back(DebugSubsectionRecordBuilder(SubsectionContents)); +} |
