[PDB] Start emitting source file and line information

Summary:
This is a first step towards getting line info to show up in VS and
windbg. So far, only llvm-pdbutil can parse the PDBs that we produce.
cvdump doesn't like something about our file checksum tables. I'll have
to dig into that next.

This patch adds a new DebugSubsectionRecordBuilder which takes bytes
directly from some other producer, such as a linker, and sticks it into
the PDB. Line tables only need to be relocated. No data needs to be
rewritten.

File checksums and string tables, on the other hand, need to be re-done.

Reviewers: zturner, ruiu

Subscribers: llvm-commits, hiraditya

Differential Revision: https://reviews.llvm.org/D34257

llvm-svn: 305713
This commit is contained in:
Reid Kleckner 2017-06-19 17:21:45 +00:00
parent 214b354f2e
commit 44cdb10964
14 changed files with 993 additions and 55 deletions

View File

@ -64,7 +64,6 @@ public:
uint64_t getRVA() const { return RVA; }
uint32_t getAlign() const { return Align; }
void setRVA(uint64_t V) { RVA = V; }
void setOutputSectionOff(uint64_t V) { OutputSectionOff = V; }
// Returns true if this has non-zero data. BSS chunks return
// false. If false is returned, the space occupied by this chunk
@ -97,17 +96,19 @@ protected:
Chunk(Kind K = OtherKind) : ChunkKind(K) {}
const Kind ChunkKind;
// The alignment of this chunk. The writer uses the value.
uint32_t Align = 1;
// The RVA of this chunk in the output. The writer sets a value.
uint64_t RVA = 0;
public:
// The offset from beginning of the output section. The writer sets a value.
uint64_t OutputSectionOff = 0;
protected:
// The output section for this chunk.
OutputSection *Out = nullptr;
// The alignment of this chunk. The writer uses the value.
uint32_t Align = 1;
};
// A chunk corresponding a section of an input file.

View File

@ -15,6 +15,8 @@
#include "Symbols.h"
#include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
@ -45,8 +47,6 @@ using namespace lld;
using namespace lld::coff;
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::support;
using namespace llvm::support::endian;
using llvm::object::coff_section;
@ -67,22 +67,24 @@ static SectionChunk *findByName(std::vector<SectionChunk *> &Sections,
return nullptr;
}
static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) {
SectionChunk *Sec = findByName(File->getDebugChunks(), SecName);
if (!Sec)
return {};
static ArrayRef<uint8_t> consumeDebugMagic(ArrayRef<uint8_t> Data,
StringRef SecName) {
// First 4 bytes are section magic.
ArrayRef<uint8_t> Data = Sec->getContents();
if (Data.size() < 4)
fatal(SecName + " too short");
if (read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
if (support::endian::read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
fatal(SecName + " has an invalid magic");
return Data.slice(4);
}
static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) {
if (SectionChunk *Sec = findByName(File->getDebugChunks(), SecName))
return consumeDebugMagic(Sec->getContents(), SecName);
return {};
}
static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
codeview::TypeTableBuilder &TypeTable) {
TypeTableBuilder &TypeTable) {
// Start the TPI or IPI stream header.
TpiBuilder.setVersionHeader(pdb::PdbTpiV80);
@ -93,17 +95,53 @@ static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
});
}
static void mergeDebugT(ObjectFile *File,
TypeTableBuilder &IDTable,
TypeTableBuilder &TypeTable,
SmallVectorImpl<TypeIndex> &TypeIndexMap,
pdb::PDBTypeServerHandler &Handler) {
ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
if (Data.empty())
return;
BinaryByteStream Stream(Data, support::little);
CVTypeArray Types;
BinaryStreamReader Reader(Stream);
Handler.addSearchPath(sys::path::parent_path(File->getName()));
if (auto EC = Reader.readArray(Types, Reader.getLength()))
fatal(EC, "Reader::readArray failed");
if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
TypeIndexMap, &Handler, Types))
fatal(Err, "codeview::mergeTypeStreams failed");
}
// Allocate memory for a .debug$S section and relocate it.
static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
SectionChunk *DebugChunk) {
uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk->getSize());
assert(DebugChunk->OutputSectionOff == 0 &&
"debug sections should not be in output sections");
DebugChunk->writeTo(Buffer);
return consumeDebugMagic(makeArrayRef(Buffer, DebugChunk->getSize()),
".debug$S");
}
// Add all object files to the PDB. Merge .debug$T sections into IpiData and
// TpiData.
static void addObjectsToPDB(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder,
codeview::TypeTableBuilder &TypeTable,
codeview::TypeTableBuilder &IDTable) {
static void addObjectsToPDB(BumpPtrAllocator &Alloc, SymbolTable *Symtab,
pdb::PDBFileBuilder &Builder,
TypeTableBuilder &TypeTable,
TypeTableBuilder &IDTable) {
// Follow type servers. If the same type server is encountered more than
// once for this instance of `PDBTypeServerHandler` (for example if many
// object files reference the same TypeServer), the types from the
// TypeServer will only be visited once.
pdb::PDBTypeServerHandler Handler;
// PDBs use a single global string table for filenames in the file checksum
// table.
auto PDBStrTab = std::make_shared<DebugStringTableSubsection>();
// Visit all .debug$T sections to add them to Builder.
for (ObjectFile *File : Symtab->ObjectFiles) {
// Add a module descriptor for every object file. We need to put an absolute
@ -117,25 +155,74 @@ static void addObjectsToPDB(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder,
File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));
File->ModuleDBI->setObjFileName(Path);
// FIXME: Walk the .debug$S sections and add them. Do things like recording
// source files.
// Before we can process symbol substreams from .debug$S, we need to process
// type information, file checksums, and the string table. Add type info to
// the PDB first, so that we can get the map from object file type and item
// indices to PDB type and item indices.
SmallVector<TypeIndex, 128> TypeIndexMap;
mergeDebugT(File, IDTable, TypeTable, TypeIndexMap, Handler);
ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
if (Data.empty())
continue;
// Now do all line info.
for (SectionChunk *DebugChunk : File->getDebugChunks()) {
// FIXME: Debug chunks do not have a correct isLive() bit.
// FIXME: When linker GC is off we need to ignore debug info whose
// associated symbol was discarded.
if (DebugChunk->getSectionName() != ".debug$S")
continue;
BinaryByteStream Stream(Data, support::little);
codeview::CVTypeArray Types;
BinaryStreamReader Reader(Stream);
SmallVector<TypeIndex, 128> SourceToDest;
Handler.addSearchPath(llvm::sys::path::parent_path(File->getName()));
if (auto EC = Reader.readArray(Types, Reader.getLength()))
fatal(EC, "Reader::readArray failed");
if (auto Err = codeview::mergeTypeAndIdRecords(
IDTable, TypeTable, SourceToDest, &Handler, Types))
fatal(Err, "codeview::mergeTypeStreams failed");
ArrayRef<uint8_t> RelocatedDebugContents =
relocateDebugChunk(Alloc, DebugChunk);
if (RelocatedDebugContents.empty())
continue;
DebugSubsectionArray Subsections;
BinaryStreamReader Reader(RelocatedDebugContents, support::little);
ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size()));
DebugStringTableSubsectionRef CVStrTab;
DebugChecksumsSubsectionRef Checksums;
for (const DebugSubsectionRecord &SS : Subsections) {
switch (SS.kind()) {
case DebugSubsectionKind::StringTable:
ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
break;
case DebugSubsectionKind::FileChecksums:
ExitOnErr(Checksums.initialize(SS.getRecordData()));
break;
case DebugSubsectionKind::Lines:
// We can add the relocated line table directly to the PDB without
// modification because the file checksum offsets will stay the same.
File->ModuleDBI->addDebugSubsection(SS);
break;
default:
// FIXME: Process the rest of the subsections.
break;
}
}
if (Checksums.valid()) {
// Make a new file checksum table that refers to offsets in the PDB-wide
// string table. Generally the string table subsection appears after the
// checksum table, so we have to do this after looping over all the
// subsections.
if (!CVStrTab.valid())
fatal(".debug$S sections must have both a string table subsection "
"and a checksum subsection table or neither");
auto NewChecksums =
std::make_unique<DebugChecksumsSubsection>(*PDBStrTab);
for (FileChecksumEntry &FC : Checksums) {
StringRef FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset));
ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(
*File->ModuleDBI, FileName));
NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum);
}
File->ModuleDBI->addDebugSubsection(std::move(NewChecksums));
}
}
}
Builder.getStringTableBuilder().setStrings(*PDBStrTab);
// Construct TPI stream contents.
addTypeInfo(Builder.getTpiBuilder(), TypeTable);
@ -172,9 +259,9 @@ void coff::createPDB(StringRef Path, SymbolTable *Symtab,
pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
DbiBuilder.setVersionHeader(pdb::PdbDbiV110);
codeview::TypeTableBuilder TypeTable(BAlloc);
codeview::TypeTableBuilder IDTable(BAlloc);
addObjectsToPDB(Symtab, Builder, TypeTable, IDTable);
TypeTableBuilder TypeTable(BAlloc);
TypeTableBuilder IDTable(BAlloc);
addObjectsToPDB(Alloc, Symtab, Builder, TypeTable, IDTable);
// Add Section Contributions.
addSectionContribs(Symtab, DbiBuilder);

View File

@ -181,7 +181,7 @@ void OutputSection::addChunk(Chunk *C) {
uint64_t Off = Header.VirtualSize;
Off = alignTo(Off, C->getAlign());
C->setRVA(Off);
C->setOutputSectionOff(Off);
C->OutputSectionOff = Off;
Off += C->getSize();
Header.VirtualSize = Off;
if (C->hasData())

View File

@ -0,0 +1,480 @@
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_AMD64
Characteristics: [ ]
sections:
- Name: .drectve
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
Alignment: 1
SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
- Name: '.debug$S'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
Subsections:
- !Symbols
Records:
- Kind: S_OBJNAME
ObjNameSym:
Signature: 0
ObjectName: 'C:\src\llvm-project\build\pdb_lines_1.obj'
- Kind: S_COMPILE3
Compile3Sym:
Flags: [ SecurityChecks, HotPatch ]
Machine: X64
FrontendMajor: 19
FrontendMinor: 0
FrontendBuild: 24215
FrontendQFE: 1
BackendMajor: 19
BackendMinor: 0
BackendBuild: 24215
BackendQFE: 1
Version: 'Microsoft (R) Optimizing Compiler'
- !Symbols
Records:
- Kind: S_GPROC32_ID
ProcSym:
PtrParent: 0
PtrEnd: 0
PtrNext: 0
CodeSize: 19
DbgStart: 4
DbgEnd: 14
FunctionType: 4102
Segment: 0
Flags: [ ]
DisplayName: main
- Kind: S_FRAMEPROC
FrameProcSym:
TotalFrameBytes: 40
PaddingFrameBytes: 0
OffsetToPadding: 0
BytesOfCalleeSavedRegisters: 0
OffsetOfExceptionHandler: 0
SectionIdOfExceptionHandler: 0
Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
- Kind: S_PROC_ID_END
ScopeEndSym:
- !Lines
CodeSize: 19
Flags: [ ]
RelocOffset: 0
RelocSegment: 0
Blocks:
- FileName: 'c:\src\llvm-project\build\pdb_lines_1.c'
Lines:
- Offset: 0
LineStart: 2
IsStatement: true
EndDelta: 0
- Offset: 4
LineStart: 3
IsStatement: true
EndDelta: 0
- Offset: 9
LineStart: 4
IsStatement: true
EndDelta: 0
- Offset: 14
LineStart: 5
IsStatement: true
EndDelta: 0
Columns:
- !FileChecksums
Checksums:
- FileName: 'c:\src\llvm-project\build\pdb_lines_1.c'
Kind: MD5
Checksum: 4EB19DCD86C3BA2238A255C718572E7B
- FileName: 'c:\src\llvm-project\build\foo.h'
Kind: MD5
Checksum: 061EB73ABB642532857A4F1D9CBAC323
- !StringTable
Strings:
- 'c:\src\llvm-project\build\pdb_lines_1.c'
- 'c:\src\llvm-project\build\foo.h'
- !Symbols
Records:
- Kind: S_BUILDINFO
BuildInfoSym:
BuildId: 4111
Relocations:
- VirtualAddress: 164
SymbolName: main
Type: IMAGE_REL_AMD64_SECREL
- VirtualAddress: 168
SymbolName: main
Type: IMAGE_REL_AMD64_SECTION
- VirtualAddress: 220
SymbolName: main
Type: IMAGE_REL_AMD64_SECREL
- VirtualAddress: 224
SymbolName: main
Type: IMAGE_REL_AMD64_SECTION
- Name: '.debug$T'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
Types:
- Kind: LF_ARGLIST
ArgList:
ArgIndices: [ ]
- Kind: LF_PROCEDURE
Procedure:
ReturnType: 3
CallConv: NearC
Options: [ None ]
ParameterCount: 0
ArgumentList: 4096
- Kind: LF_POINTER
Pointer:
ReferentType: 4097
Attrs: 65548
- Kind: LF_FUNC_ID
FuncId:
ParentScope: 0
FunctionType: 4097
Name: foo
- Kind: LF_ARGLIST
ArgList:
ArgIndices: [ 0 ]
- Kind: LF_PROCEDURE
Procedure:
ReturnType: 116
CallConv: NearC
Options: [ None ]
ParameterCount: 0
ArgumentList: 4100
- Kind: LF_FUNC_ID
FuncId:
ParentScope: 0
FunctionType: 4101
Name: main
- Kind: LF_FUNC_ID
FuncId:
ParentScope: 0
FunctionType: 4097
Name: bar
- Kind: LF_STRING_ID
StringId:
Id: 0
String: 'C:\src\llvm-project\build'
- Kind: LF_STRING_ID
StringId:
Id: 0
String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
- Kind: LF_STRING_ID
StringId:
Id: 0
String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
- Kind: LF_SUBSTR_LIST
StringList:
StringIndices: [ 4106 ]
- Kind: LF_STRING_ID
StringId:
Id: 4107
String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
- Kind: LF_STRING_ID
StringId:
Id: 0
String: pdb_lines_1.c
- Kind: LF_STRING_ID
StringId:
Id: 0
String: 'C:\src\llvm-project\build\vc140.pdb'
- Kind: LF_BUILDINFO
BuildInfo:
ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
- Name: '.text$mn'
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 16
SectionData: 4883EC28E800000000B82A0000004883C428C3
Relocations:
- VirtualAddress: 5
SymbolName: foo
Type: IMAGE_REL_AMD64_REL32
- Name: '.text$mn'
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 16
SectionData: 4883EC28E8000000004883C428C3
Relocations:
- VirtualAddress: 5
SymbolName: bar
Type: IMAGE_REL_AMD64_REL32
- Name: '.debug$S'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
Subsections:
- !Symbols
Records:
- Kind: S_GPROC32_ID
ProcSym:
PtrParent: 0
PtrEnd: 0
PtrNext: 0
CodeSize: 14
DbgStart: 4
DbgEnd: 9
FunctionType: 4099
Segment: 0
Flags: [ ]
DisplayName: foo
- Kind: S_FRAMEPROC
FrameProcSym:
TotalFrameBytes: 40
PaddingFrameBytes: 0
OffsetToPadding: 0
BytesOfCalleeSavedRegisters: 0
OffsetOfExceptionHandler: 0
SectionIdOfExceptionHandler: 0
Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
- Kind: S_PROC_ID_END
ScopeEndSym:
- !Lines
CodeSize: 14
Flags: [ ]
RelocOffset: 0
RelocSegment: 0
Blocks:
- FileName: 'c:\src\llvm-project\build\foo.h'
Lines:
- Offset: 0
LineStart: 2
IsStatement: true
EndDelta: 0
- Offset: 4
LineStart: 3
IsStatement: true
EndDelta: 0
- Offset: 9
LineStart: 4
IsStatement: true
EndDelta: 0
Columns:
Relocations:
- VirtualAddress: 44
SymbolName: foo
Type: IMAGE_REL_AMD64_SECREL
- VirtualAddress: 48
SymbolName: foo
Type: IMAGE_REL_AMD64_SECTION
- VirtualAddress: 100
SymbolName: foo
Type: IMAGE_REL_AMD64_SECREL
- VirtualAddress: 104
SymbolName: foo
Type: IMAGE_REL_AMD64_SECTION
- Name: .xdata
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: '0104010004420000'
- Name: .pdata
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: '000000000E00000000000000'
Relocations:
- VirtualAddress: 0
SymbolName: '$LN3'
Type: IMAGE_REL_AMD64_ADDR32NB
- VirtualAddress: 4
SymbolName: '$LN3'
Type: IMAGE_REL_AMD64_ADDR32NB
- VirtualAddress: 8
SymbolName: '$unwind$foo'
Type: IMAGE_REL_AMD64_ADDR32NB
- Name: .xdata
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: '0104010004420000'
- Name: .pdata
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: '000000001300000000000000'
Relocations:
- VirtualAddress: 0
SymbolName: '$LN3'
Type: IMAGE_REL_AMD64_ADDR32NB
- VirtualAddress: 4
SymbolName: '$LN3'
Type: IMAGE_REL_AMD64_ADDR32NB
- VirtualAddress: 8
SymbolName: '$unwind$main'
Type: IMAGE_REL_AMD64_ADDR32NB
symbols:
- Name: .drectve
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 47
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- Name: '.debug$S'
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 432
NumberOfRelocations: 4
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- Name: '.debug$T'
Value: 0
SectionNumber: 3
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 644
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- Name: '.text$mn'
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 19
NumberOfRelocations: 1
NumberOfLinenumbers: 0
CheckSum: 791570821
Number: 0
- Name: '.text$mn'
Value: 0
SectionNumber: 5
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 14
NumberOfRelocations: 1
NumberOfLinenumbers: 0
CheckSum: 1682752513
Number: 0
Selection: IMAGE_COMDAT_SELECT_ANY
- Name: '.debug$S'
Value: 0
SectionNumber: 6
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 148
NumberOfRelocations: 4
NumberOfLinenumbers: 0
CheckSum: 0
Number: 5
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
- Name: bar
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: foo
Value: 0
SectionNumber: 5
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: main
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: '$LN3'
Value: 0
SectionNumber: 5
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_LABEL
- Name: '$LN3'
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_LABEL
- Name: .xdata
Value: 0
SectionNumber: 7
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 8
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 264583633
Number: 5
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
- Name: '$unwind$foo'
Value: 0
SectionNumber: 7
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: .pdata
Value: 0
SectionNumber: 8
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 12
NumberOfRelocations: 3
NumberOfLinenumbers: 0
CheckSum: 361370162
Number: 5
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
- Name: '$pdata$foo'
Value: 0
SectionNumber: 8
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: .xdata
Value: 0
SectionNumber: 9
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 8
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 264583633
Number: 0
- Name: '$unwind$main'
Value: 0
SectionNumber: 9
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: .pdata
Value: 0
SectionNumber: 10
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 12
NumberOfRelocations: 3
NumberOfLinenumbers: 0
CheckSum: 4063508168
Number: 0
- Name: '$pdata$main'
Value: 0
SectionNumber: 10
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
...

View File

@ -0,0 +1,209 @@
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_AMD64
Characteristics: [ ]
sections:
- Name: .drectve
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
Alignment: 1
SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
- Name: '.debug$S'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
Subsections:
- !Symbols
Records:
- Kind: S_OBJNAME
ObjNameSym:
Signature: 0
ObjectName: 'C:\src\llvm-project\build\pdb_lines_2.obj'
- Kind: S_COMPILE3
Compile3Sym:
Flags: [ SecurityChecks, HotPatch ]
Machine: X64
FrontendMajor: 19
FrontendMinor: 0
FrontendBuild: 24215
FrontendQFE: 1
BackendMajor: 19
BackendMinor: 0
BackendBuild: 24215
BackendQFE: 1
Version: 'Microsoft (R) Optimizing Compiler'
- !Symbols
Records:
- Kind: S_GPROC32_ID
ProcSym:
PtrParent: 0
PtrEnd: 0
PtrNext: 0
CodeSize: 1
DbgStart: 0
DbgEnd: 0
FunctionType: 4098
Segment: 0
Flags: [ ]
DisplayName: bar
- Kind: S_FRAMEPROC
FrameProcSym:
TotalFrameBytes: 0
PaddingFrameBytes: 0
OffsetToPadding: 0
BytesOfCalleeSavedRegisters: 0
OffsetOfExceptionHandler: 0
SectionIdOfExceptionHandler: 0
Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
- Kind: S_PROC_ID_END
ScopeEndSym:
- !Lines
CodeSize: 1
Flags: [ ]
RelocOffset: 0
RelocSegment: 0
Blocks:
- FileName: 'c:\src\llvm-project\build\pdb_lines_2.c'
Lines:
- Offset: 0
LineStart: 1
IsStatement: true
EndDelta: 0
- Offset: 0
LineStart: 2
IsStatement: true
EndDelta: 0
Columns:
- !FileChecksums
Checksums:
- FileName: 'c:\src\llvm-project\build\pdb_lines_2.c'
Kind: MD5
Checksum: DF91CB3A2B8D917486574BB50CAC4CC7
- !StringTable
Strings:
- 'c:\src\llvm-project\build\pdb_lines_2.c'
- !Symbols
Records:
- Kind: S_BUILDINFO
BuildInfoSym:
BuildId: 4106
Relocations:
- VirtualAddress: 164
SymbolName: bar
Type: IMAGE_REL_AMD64_SECREL
- VirtualAddress: 168
SymbolName: bar
Type: IMAGE_REL_AMD64_SECTION
- VirtualAddress: 220
SymbolName: bar
Type: IMAGE_REL_AMD64_SECREL
- VirtualAddress: 224
SymbolName: bar
Type: IMAGE_REL_AMD64_SECTION
- Name: '.debug$T'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
Types:
- Kind: LF_ARGLIST
ArgList:
ArgIndices: [ ]
- Kind: LF_PROCEDURE
Procedure:
ReturnType: 3
CallConv: NearC
Options: [ None ]
ParameterCount: 0
ArgumentList: 4096
- Kind: LF_FUNC_ID
FuncId:
ParentScope: 0
FunctionType: 4097
Name: bar
- Kind: LF_STRING_ID
StringId:
Id: 0
String: 'C:\src\llvm-project\build'
- Kind: LF_STRING_ID
StringId:
Id: 0
String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
- Kind: LF_STRING_ID
StringId:
Id: 0
String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
- Kind: LF_SUBSTR_LIST
StringList:
StringIndices: [ 4101 ]
- Kind: LF_STRING_ID
StringId:
Id: 4102
String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
- Kind: LF_STRING_ID
StringId:
Id: 0
String: pdb_lines_2.c
- Kind: LF_STRING_ID
StringId:
Id: 0
String: 'C:\src\llvm-project\build\vc140.pdb'
- Kind: LF_BUILDINFO
BuildInfo:
ArgIndices: [ 4099, 4100, 4104, 4105, 4103 ]
- Name: '.text$mn'
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 16
SectionData: C3
symbols:
- Name: .drectve
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 47
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- Name: '.debug$S'
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 360
NumberOfRelocations: 4
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- Name: '.debug$T'
Value: 0
SectionNumber: 3
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 568
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- Name: '.text$mn'
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 1
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 40735498
Number: 0
- Name: bar
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...

View File

@ -16,7 +16,7 @@ sections:
Alignment: 16
SectionData: 4883EC28E8000000004883C428C3
- Name: '.debug$S'
- Name: '.debug_blah'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
SectionData: 0000000000000000000000000000
@ -26,7 +26,7 @@ sections:
Alignment: 16
SectionData: 4883EC28E8000000004883C428C3
- Name: '.debug$S'
- Name: '.debug_blah'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
SectionData: FFFFFFFFFFFFFFFFFFFFFFFFFFFF
@ -46,7 +46,7 @@ symbols:
Number: 0
Selection: IMAGE_COMDAT_SELECT_ANY
- Name: '.debug$S'
- Name: '.debug_blah'
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
@ -74,7 +74,7 @@ symbols:
Number: 0
Selection: IMAGE_COMDAT_SELECT_ANY
- Name: '.debug$S'
- Name: '.debug_blah'
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL

View File

@ -0,0 +1,124 @@
Test the linker line tables on roughly the following example:
==> foo.h <==
void bar(void);
inline void foo(void) {
bar();
}
==> pdb_lines_1.c <==
#include "foo.h"
int main(void) {
foo();
return 42;
}
==> pdb_lines_2.c <==
void bar(void) {
}
$ cl -c -Z7 pdb_lines*.c
RUN: yaml2obj %S/Inputs/pdb_lines_1.yaml -o %t.pdb_lines_1.obj
RUN: yaml2obj %S/Inputs/pdb_lines_2.yaml -o %t.pdb_lines_2.obj
RUN: lld-link -debug -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1.obj %t.pdb_lines_2.obj
RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s
CHECK-LABEL: DbiStream:
CHECK-NEXT: VerHeader: V110
CHECK-NEXT: Age: 1
CHECK-NEXT: BuildNumber: 0
CHECK-NEXT: PdbDllVersion: 0
CHECK-NEXT: PdbDllRbld: 0
CHECK-NEXT: Flags: 0
CHECK-NEXT: MachineType: x86
CHECK-NEXT: Modules:
CHECK-LABEL: - Module: '{{.*}}pdb_lines_1.obj'
CHECK-NEXT: ObjFile: '{{.*}}pdb_lines_1.obj'
CHECK-NEXT: SourceFiles:
CHECK-NEXT: - '{{.*}}pdb_lines_1.c'
CHECK-NEXT: - '{{.*}}foo.h'
CHECK-NEXT: Subsections:
CHECK-NEXT: - !Lines
CHECK-NEXT: CodeSize: 19
CHECK-NEXT: Flags: [ ]
CHECK-NEXT: RelocOffset: 0
CHECK-NEXT: RelocSegment: 2
CHECK-NEXT: Blocks:
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
CHECK-NEXT: Lines:
CHECK-NEXT: - Offset: 0
CHECK-NEXT: LineStart: 2
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
CHECK-NEXT: - Offset: 4
CHECK-NEXT: LineStart: 3
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
CHECK-NEXT: - Offset: 9
CHECK-NEXT: LineStart: 4
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
CHECK-NEXT: - Offset: 14
CHECK-NEXT: LineStart: 5
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
CHECK-NEXT: Columns:
CHECK-NEXT: - !FileChecksums
CHECK-NEXT: Checksums:
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
CHECK-NEXT: Kind: MD5
CHECK-NEXT: Checksum: 4EB19DCD86C3BA2238A255C718572E7B
CHECK-NEXT: - FileName: '{{.*}}foo.h'
CHECK-NEXT: Kind: MD5
CHECK-NEXT: Checksum: 061EB73ABB642532857A4F1D9CBAC323
CHECK-NEXT: - !Lines
CHECK-NEXT: CodeSize: 14
CHECK-NEXT: Flags: [ ]
CHECK-NEXT: RelocOffset: 32
CHECK-NEXT: RelocSegment: 2
CHECK-NEXT: Blocks:
CHECK-NEXT: - FileName: '{{.*}}foo.h'
CHECK-NEXT: Lines:
CHECK-NEXT: - Offset: 0
CHECK-NEXT: LineStart: 2
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
CHECK-NEXT: - Offset: 4
CHECK-NEXT: LineStart: 3
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
CHECK-NEXT: - Offset: 9
CHECK-NEXT: LineStart: 4
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
CHECK-NEXT: Columns:
CHECK-LABEL: - Module: '{{.*}}pdb_lines_2.obj'
CHECK-NEXT: ObjFile: '{{.*}}pdb_lines_2.obj'
CHECK-NEXT: SourceFiles:
CHECK-NEXT: - '{{.*}}pdb_lines_2.c'
CHECK-NEXT: Subsections:
CHECK-NEXT: - !Lines
CHECK-NEXT: CodeSize: 1
CHECK-NEXT: Flags: [ ]
CHECK-NEXT: RelocOffset: 48
CHECK-NEXT: RelocSegment: 2
CHECK-NEXT: Blocks:
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
CHECK-NEXT: Lines:
CHECK-NEXT: - Offset: 0
CHECK-NEXT: LineStart: 1
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
CHECK-NEXT: - Offset: 0
CHECK-NEXT: LineStart: 2
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
CHECK-NEXT: Columns:
CHECK-NEXT: - !FileChecksums
CHECK-NEXT: Checksums:
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
CHECK-NEXT: Kind: MD5
CHECK-NEXT: Checksum: DF91CB3A2B8D917486574BB50CAC4CC7
CHECK-NEXT: - Module: '* Linker *'
CHECK-NEXT: ObjFile: ''

View File

@ -22,7 +22,7 @@
# CHECK-NEXT: NumStreams:
# CHECK-NEXT: FileSize:
# CHECK-NEXT: StreamSizes:
# CHECK-NEXT: StreamMap:
# CHECK: StreamMap:
# CHECK: PdbStream:
# CHECK-NEXT: Age: 1
# CHECK-NEXT: Guid:
@ -119,10 +119,10 @@ RAW: Modules
RAW-NEXT: ============================================================
RAW-NEXT: Mod 0000 | Name: `{{.*}}pdb.test.tmp1.obj`:
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`:
RAW-NEXT: debug stream: 9, # files: 0, has ec info: false
RAW-NEXT: debug stream: 9, # files: 1, has ec info: false
RAW-NEXT: Mod 0001 | Name: `{{.*}}pdb.test.tmp2.obj`:
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`:
RAW-NEXT: debug stream: 10, # files: 0, has ec info: false
RAW-NEXT: debug stream: 10, # files: 1, has ec info: false
RAW-NEXT: Mod 0002 | Name: `* Linker *`:
RAW-NEXT: Obj: ``:
RAW-NEXT: debug stream: 11, # files: 0, has ec info: false

View File

@ -51,11 +51,23 @@ class DebugSubsectionRecordBuilder {
public:
DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
CodeViewContainer Container);
/// Use this to copy existing subsections directly from source to destination.
/// For example, line table subsections in an object file only need to be
/// relocated before being copied into the PDB.
DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents,
CodeViewContainer Container);
uint32_t calculateSerializedLength();
Error commit(BinaryStreamWriter &Writer) const;
private:
/// The subsection to build. Will be null if Contents is non-empty.
std::shared_ptr<DebugSubsection> Subsection;
/// The bytes of the subsection. Only non-empty if Subsection is null.
DebugSubsectionRecord Contents;
CodeViewContainer Container;
};

View File

@ -14,6 +14,7 @@
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/Error.h"
@ -52,6 +53,9 @@ public:
void
addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
void
addDebugSubsection(const codeview::DebugSubsectionRecord &SubsectionContents);
uint16_t getStreamIndex() const;
StringRef getModuleName() const { return ModuleName; }
StringRef getObjFileName() const { return ObjFileName; }

View File

@ -58,6 +58,7 @@ public:
Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName);
Error addModuleSourceFile(StringRef Module, StringRef File);
Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File);
Expected<uint32_t> getSourceFileNameIndex(StringRef FileName);
Error finalizeMsfLayout();

View File

@ -53,12 +53,16 @@ DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
std::shared_ptr<DebugSubsection> Subsection, CodeViewContainer Container)
: Subsection(std::move(Subsection)), Container(Container) {}
DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
const DebugSubsectionRecord &Contents, CodeViewContainer Container)
: Contents(Contents), Container(Container) {}
uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() {
// The length of the entire subsection is always padded to 4 bytes, regardless
// of the container kind.
uint32_t Size = sizeof(DebugSubsectionHeader) +
alignTo(Subsection->calculateSerializedSize(), 4);
return Size;
uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
: Contents.getRecordData().getLength();
// The length of the entire subsection is always padded to 4 bytes,
// regardless of the container kind.
return sizeof(DebugSubsectionHeader) + alignTo(DataSize, 4);
}
Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) const {
@ -66,16 +70,22 @@ Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) const {
"Debug Subsection not properly aligned");
DebugSubsectionHeader Header;
Header.Kind = uint32_t(Subsection->kind());
Header.Kind = uint32_t(Subsection ? Subsection->kind() : Contents.kind());
// The value written into the Header's Length field is only padded to the
// container's alignment
Header.Length =
alignTo(Subsection->calculateSerializedSize(), alignOf(Container));
uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
: Contents.getRecordData().getLength();
Header.Length = alignTo(DataSize, alignOf(Container));
if (auto EC = Writer.writeObject(Header))
return EC;
if (auto EC = Subsection->commit(Writer))
return EC;
if (Subsection) {
if (auto EC = Subsection->commit(Writer))
return EC;
} else {
if (auto EC = Writer.writeStreamRef(Contents.getRecordData()))
return EC;
}
if (auto EC = Writer.padToAlignment(4))
return EC;

View File

@ -182,3 +182,9 @@ void DbiModuleDescriptorBuilder::addDebugSubsection(
C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
std::move(Subsection), CodeViewContainer::Pdb));
}
void DbiModuleDescriptorBuilder::addDebugSubsection(
const DebugSubsectionRecord &SubsectionContents) {
C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
SubsectionContents, CodeViewContainer::Pdb));
}

View File

@ -90,10 +90,14 @@ Error DbiStreamBuilder::addModuleSourceFile(StringRef Module, StringRef File) {
if (ModIter == ModiMap.end())
return make_error<RawError>(raw_error_code::no_entry,
"The specified module was not found");
return addModuleSourceFile(*ModIter->second, File);
}
Error DbiStreamBuilder::addModuleSourceFile(DbiModuleDescriptorBuilder &Module,
StringRef File) {
uint32_t Index = SourceFileNames.size();
SourceFileNames.insert(std::make_pair(File, Index));
auto &ModEntry = *ModIter;
ModEntry.second->addSourceFile(File);
Module.addSourceFile(File);
return Error::success();
}