From: Rui Ueyama Date: Mon, 21 Nov 2016 17:22:35 +0000 (+0000) Subject: Do plumbing work for CodeView debug info. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=be939b3ff6aba44ff8d760852a24e39a0f70d084;p=platform%2Fupstream%2Fllvm.git Do plumbing work for CodeView debug info. Previously, we discarded .debug$ sections. This patch adds them to files so that PDB.cpp can access them. This patch also adds a debug option, /dumppdb, to dump debug info fed to createPDB so that we can verify that valid data has been passed. llvm-svn: 287555 --- diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 5bfb12e..7fd8fec 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -150,6 +150,9 @@ struct Configuration { bool TerminalServerAware = true; bool LargeAddressAware = false; bool HighEntropyVA = false; + + // This is for debugging. + bool DumpPdb = false; }; extern Configuration *Config; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 89649ce..fa1d6d2 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -528,6 +528,7 @@ void LinkerDriver::link(llvm::ArrayRef ArgsArr) { 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. diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index ead0d39..d832b57 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -150,13 +150,28 @@ void ObjectFile::initializeChunks() { 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); diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h index 801bd05..4cb9dd2 100644 --- a/lld/COFF/InputFiles.h +++ b/lld/COFF/InputFiles.h @@ -38,6 +38,7 @@ class Defined; class DefinedImportData; class DefinedImportThunk; class Lazy; +class SectionChunk; class SymbolBody; class Undefined; @@ -122,6 +123,7 @@ public: void parse() override; MachineTypes getMachineType() override; std::vector &getChunks() { return Chunks; } + std::vector &getDebugChunks() { return DebugChunks; } std::vector &getSymbols() override { return SymbolBodies; } // Returns a SymbolBody object for the SymbolIndex'th symbol in the @@ -157,6 +159,9 @@ private: // chunks and non-section chunks for common symbols. std::vector Chunks; + // CodeView debug info sections. + std::vector 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. diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index 3866993..f9abff8 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -94,6 +94,7 @@ def help_q : Flag<["/?", "-?"], "">, Alias; def nosymtab : F<"nosymtab">; // Flags for debugging +def dumppdb : Joined<["/", "-"], "dumppdb">; def lldmap : Joined<["/", "-"], "lldmap:">; //============================================================================== diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 470c07a..97b7f69 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -9,9 +9,11 @@ #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" @@ -25,11 +27,13 @@ #include "llvm/Object/COFF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/ScopedPrinter.h" #include using namespace lld; using namespace lld::coff; using namespace llvm; +using namespace llvm::codeview; using namespace llvm::support; using namespace llvm::support::endian; @@ -46,9 +50,35 @@ static std::vector getInputSections(SymbolTable *Symtab) { return V; } +static SectionChunk *findByName(std::vector &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 SectionTable) { + if (Config->DumpPdb) + dumpCodeView(Symtab); + BumpPtrAllocator Alloc; pdb::PDBFileBuilder Builder(Alloc); ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index 8bf4387..034fa13 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -33,6 +33,7 @@ namespace coff { class Chunk; class Defined; class Lazy; +class SectionChunk; class SymbolBody; struct Symbol; diff --git a/lld/test/COFF/dumppdb.test b/lld/test/COFF/dumppdb.test new file mode 100644 index 0000000..fbf977c --- /dev/null +++ b/lld/test/COFF/dumppdb.test @@ -0,0 +1,113 @@ +# 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 +...