forked from OSchip/llvm-project
[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:
parent
214b354f2e
commit
44cdb10964
|
@ -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.
|
||||
|
|
149
lld/COFF/PDB.cpp
149
lld/COFF/PDB.cpp
|
@ -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);
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
|
|
|
@ -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: ''
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue