bool TerminalServerAware = true;
bool LargeAddressAware = false;
bool HighEntropyVA = false;
+
+ // This is for debugging.
+ bool DumpPdb = false;
};
extern Configuration *Config;
Config->TerminalServerAware = false;
if (Args.hasArg(OPT_nosymtab))
Config->WriteSymtab = false;
+ Config->DumpPdb = Args.hasArg(OPT_dumppdb);
// Create a list of input files. Files can be given as arguments
// for /defaultlib option.
Directives = std::string((const char *)Data.data(), Data.size());
continue;
}
- // Skip non-DWARF debug info. MSVC linker converts the sections into
- // a PDB file, but we don't support that.
- if (Name == ".debug" || Name.startswith(".debug$"))
- continue;
- // We want to preserve DWARF debug sections only when /debug is on.
+
+ // Object files may have DWARF debug info or MS CodeView debug info
+ // (or both).
+ //
+ // DWARF sections don't need any special handling from the perspective
+ // of the linker; they are just a data section containing relocations.
+ // We can just link them to complete debug info.
+ //
+ // CodeView needs a linker support. We need to interpret and debug
+ // info, and then write it to a separate .pdb file.
+
+ // Ignore debug info unless /debug is given.
if (!Config->Debug && Name.startswith(".debug"))
continue;
+
+ // CodeView sections are stored to a different vector because they are
+ // not linked in the regular manner.
+ if (Name == ".debug" || Name.startswith(".debug$")) {
+ DebugChunks.push_back(new (Alloc) SectionChunk(this, Sec));
+ continue;
+ }
+
if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
continue;
auto *C = new (Alloc) SectionChunk(this, Sec);
class DefinedImportData;
class DefinedImportThunk;
class Lazy;
+class SectionChunk;
class SymbolBody;
class Undefined;
void parse() override;
MachineTypes getMachineType() override;
std::vector<Chunk *> &getChunks() { return Chunks; }
+ std::vector<SectionChunk *> &getDebugChunks() { return DebugChunks; }
std::vector<SymbolBody *> &getSymbols() override { return SymbolBodies; }
// Returns a SymbolBody object for the SymbolIndex'th symbol in the
// chunks and non-section chunks for common symbols.
std::vector<Chunk *> Chunks;
+ // CodeView debug info sections.
+ std::vector<SectionChunk *> DebugChunks;
+
// This vector contains the same chunks as Chunks, but they are
// indexed such that you can get a SectionChunk by section index.
// Nonexistent section indices are filled with null pointers.
def nosymtab : F<"nosymtab">;
// Flags for debugging
+def dumppdb : Joined<["/", "-"], "dumppdb">;
def lldmap : Joined<["/", "-"], "lldmap:">;
//==============================================================================
#include "PDB.h"
#include "Chunks.h"
+#include "Config.h"
#include "Error.h"
#include "SymbolTable.h"
#include "Symbols.h"
+#include "llvm/DebugInfo/CodeView/TypeDumper.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/ScopedPrinter.h"
#include <memory>
using namespace lld;
using namespace lld::coff;
using namespace llvm;
+using namespace llvm::codeview;
using namespace llvm::support;
using namespace llvm::support::endian;
return V;
}
+static SectionChunk *findByName(std::vector<SectionChunk *> &Sections,
+ StringRef Name) {
+ for (SectionChunk *C : Sections)
+ if (C->getSectionName() == Name)
+ return C;
+ return nullptr;
+}
+
+// Dump CodeView debug info. This is for debugging.
+static void dumpCodeView(SymbolTable *Symtab) {
+ ScopedPrinter W(outs());
+
+ for (ObjectFile *File : Symtab->ObjectFiles) {
+ SectionChunk *C = findByName(File->getDebugChunks(), ".debug$T");
+ if (!C)
+ continue;
+
+ CVTypeDumper TypeDumper(&W, false);
+ if (auto EC = TypeDumper.dump(C->getContents()))
+ fatal(EC, "CVTypeDumper::dump failed");
+ }
+}
+
// Creates a PDB file.
void coff::createPDB(StringRef Path, SymbolTable *Symtab,
ArrayRef<uint8_t> SectionTable) {
+ if (Config->DumpPdb)
+ dumpCodeView(Symtab);
+
BumpPtrAllocator Alloc;
pdb::PDBFileBuilder Builder(Alloc);
ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
class Chunk;
class Defined;
class Lazy;
+class SectionChunk;
class SymbolBody;
struct Symbol;
--- /dev/null
+# RUN: yaml2obj %s > %t.obj
+# RUN: lld-link /debug /pdb:%t.pdb /dumppdb /dll /out:%t.dll /entry:main \
+# RUN: /nodefaultlib %t.obj | FileCheck %s
+
+# CHECK: UnknownLeaf (0x1000) {
+# CHECK-NEXT: TypeLeafKind: 0x0
+# CHECK-NEXT: Kind: 0x0
+# CHECK-NEXT: Length: 2
+# CHECK-NEXT: }
+
+
+--- !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
+ SectionData: 04000000F1000000530000001500011100000000443A5C625C72657434322E6F626A003A003C1100600000D00013000000F259000013000000F25900004D6963726F736F667420285229204F7074696D697A696E6720436F6D70696C65720000F10000004E0000002A00471100000000000000000000000006000000000000000500000002100000000000000000006D61696E001C001210000000000000000000000000000000000000000000000042110002004F110000F2000000200000000000000000000000060000000000000001000000140000000000000001000080F4000000180000000100000010010BFC79AA614B536E3D64B110330D1E580000F30000000E00000000643A5C625C72657434322E63000000F10000000800000006004C110A100000
+ Relocations:
+ - VirtualAddress: 136
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 140
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 192
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 196
+ 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
+ SectionData: 040000000A00011201000000000000000E0008107400000000000000001000001200011600000000011000006D61696E00F3F2F10E00051600000000443A5C6200F3F2F12200051600000000433A5C767331345C56435C42494E5C616D6436345C636C2E6578650002010516000000002D5A37202D63202D4D54202D49433A5C767331345C56435C494E434C554445202D49433A5C767331345C56435C41544C4D46435C494E434C554445202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31303135302E305C7563727422202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C4E4554465853444B5C342E365C696E636C7564655C756D22202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C382E315C696E636C7564655C73686172656422000A00041601000000051000008200051606100000202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C382E315C696E636C7564655C756D22202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C382E315C696E636C7564655C77696E727422202D5443202D5800F3F2F10E0005160000000072657434322E63001600051600000000443A5C625C76633134302E70646200F11A00031605000310000004100000081000000910000007100000F2F1
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: B82A000000C3
+symbols:
+ - Name: '@comp.id'
+ Value: 17062386
+ SectionNumber: -1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: '@feat.00'
+ Value: 2147484048
+ SectionNumber: -1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - 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: 296
+ 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: 576
+ 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: 6
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 2139436471
+ Number: 0
+ - Name: main
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...