Index: lld/COFF/PDB.cpp =================================================================== --- lld/COFF/PDB.cpp +++ lld/COFF/PDB.cpp @@ -17,6 +17,7 @@ #include "llvm/DebugInfo/CodeView/CVDebugRecord.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" @@ -460,7 +461,78 @@ S.OpeningRecord->PtrEnd = CurOffset; } +static bool symbolGoesInModuleStream(const CVSymbol &Sym) { + switch (Sym.kind()) { + case SymbolKind::S_GDATA32: + case SymbolKind::S_CONSTANT: + case SymbolKind::S_UDT: + // We really should not be seeing S_PROCREF and S_LPROCREF in the first place + // since they are synthesized by the linker in response to S_GPROC32 and + // S_LPROC32, but if we do see them, don't put them in the module stream I + // guess. + case SymbolKind::S_PROCREF: + case SymbolKind::S_LPROCREF: + return false; + // S_GDATA32 does not go in the module stream, but S_LDATA32 does. + case SymbolKind::S_LDATA32: + default: + return true; + } +} + +static bool symbolGoesInGlobalsStream(const CVSymbol &Sym) { + switch (Sym.kind()) { + case SymbolKind::S_CONSTANT: + case SymbolKind::S_UDT: + case SymbolKind::S_GDATA32: + // S_LDATA32 goes in both the module stream and the globals stream. + case SymbolKind::S_LDATA32: + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: + // We really should not be seeing S_PROCREF and S_LPROCREF in the first place + // since they are synthesized by the linker in response to S_GPROC32 and + // S_LPROC32, but if we do see them, copy them straight through. + case SymbolKind::S_PROCREF: + case SymbolKind::S_LPROCREF: + return true; + default: + return false; + } +} + +static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File, + const CVSymbol &Sym) { + switch (Sym.kind()) { + case SymbolKind::S_CONSTANT: + case SymbolKind::S_UDT: + case SymbolKind::S_GDATA32: + case SymbolKind::S_LDATA32: + case SymbolKind::S_PROCREF: + case SymbolKind::S_LPROCREF: + Builder.addGlobalSymbol(Sym); + break; + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: { + SymbolRecordKind K = SymbolRecordKind::ProcRefSym; + if (Sym.kind() == SymbolKind::S_LPROC32) + K = SymbolRecordKind::LocalProcRef; + ProcRefSym PS(K); + PS.Module = static_cast(File.ModuleDBI->getModuleIndex()); + // For some reason, MSVC seems to add one to this value. + ++PS.Module; + PS.Name = getSymbolName(Sym); + PS.SumName = 0; + PS.SymOffset = File.ModuleDBI->getNextSymbolOffset(); + Builder.addGlobalSymbol(PS); + break; + } + default: + llvm_unreachable("Invalid symbol kind!"); + } +} + static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File, + pdb::GSIStreamBuilder &GsiBuilder, const CVIndexMap &IndexMap, const TypeTableBuilder &IDTable, BinaryStreamRef SymData) { @@ -500,8 +572,15 @@ else if (symbolEndsScope(NewKind)) scopeStackClose(Scopes, File->ModuleDBI->getNextSymbolOffset(), File); + // Add the symbol to the globals stream if necessary. Do this before adding + // the symbol to the module since we may need to get the next symbol offset, + // and writing to the module's symbol stream will update that offset. + if (symbolGoesInGlobalsStream(NewSym)) + addGlobalSymbol(GsiBuilder, *File, NewSym); + // Add the symbol to the module. - File->ModuleDBI->addSymbol(NewSym); + if (symbolGoesInModuleStream(NewSym)) + File->ModuleDBI->addSymbol(NewSym); } } @@ -567,7 +646,8 @@ File->ModuleDBI->addDebugSubsection(SS); break; case DebugSubsectionKind::Symbols: - mergeSymbolRecords(Alloc, File, IndexMap, IDTable, SS.getRecordData()); + mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, + IDTable, SS.getRecordData()); break; default: // FIXME: Process the rest of the subsections. @@ -626,9 +706,10 @@ // Construct IPI stream contents. addTypeInfo(Builder.getIpiBuilder(), IDTable); - // Compute the public symbols. + // Compute the public and global symbols. + auto &GsiBuilder = Builder.getGsiBuilder(); std::vector Publics; - Symtab->forEachSymbol([&Publics](Symbol *S) { + Symtab->forEachSymbol([&Publics, &GsiBuilder](Symbol *S) { // Only emit defined, live symbols that have a chunk. auto *Def = dyn_cast(S->body()); if (Def && Def->isLive() && Def->getChunk()) @@ -641,7 +722,6 @@ [](const PublicSym32 &L, const PublicSym32 &R) { return L.Name < R.Name; }); - auto &GsiBuilder = Builder.getGsiBuilder(); for (const PublicSym32 &Pub : Publics) GsiBuilder.addPublicSymbol(Pub); } Index: lld/test/COFF/Inputs/pdb-globals.yaml =================================================================== --- /dev/null +++ lld/test/COFF/Inputs/pdb-globals.yaml @@ -0,0 +1,593 @@ +# // YAML Generated from the following source code: +# // Compile with clang-cl /Z7 /GS- /c t.obj pdb-globals.cpp + +# void *__purecall = 0; + +# struct HelloPoint { + # int X = 3; + # int Y = 4; + # int Z = 5; +# }; + +# // S_LPROCREF +# static int LocalFunc() { return 42; } + +# // S_PROCREF +# int GlobalFunc() { return 43; } + +# // S_LDATA32 +# const int ConstantVar = 17; + +# // S_GDATA32 +# const int *GlobalVar = &ConstantVar; + +# // S_CONSTANT +# constexpr int ConstexprVar = 18; + +# // S_UDT +# typedef HelloPoint HelloPointTypedef; + +# int main(int argc, char **argv) { + # HelloPointTypedef P; + # int N = P.X + P.Y + P.Z; + # N += LocalFunc() + GlobalFunc(); + # N += *GlobalVar; + # N += ConstexprVar; +# } + + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 5589E5B82B0000005DC3660F1F4400005589E583EC208B450C8B4D088D55F4894DEC89D18945E8E8000000008B4DF4034DF8034DFC894DF08945E4E8000000008945E0E80000000031C98B55E001C20355F08955F0A1000000008B000345F08945F08B45F083C0128945F089C883C4205DC366666666662E0F1F8400000000005589E5B82A0000005DC3 + Relocations: + - VirtualAddress: 40 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_REL32 + - VirtualAddress: 60 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_REL32 + - VirtualAddress: 68 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_REL32 + - VirtualAddress: 86 + SymbolName: '?GlobalVar@@3PBHB' + Type: IMAGE_REL_I386_DIR32 + - Name: .data + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '00000000' + Relocations: + - VirtualAddress: 0 + SymbolName: _ConstantVar + Type: IMAGE_REL_I386_DIR32 + - Name: .bss + Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 5589E550894DFC8B4DFCC70103000000C7410404000000C741080500000089C883C4045DC3 + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '11000000' + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F100000036000000300047110000000000000000000000000A00000000000000000000000210000000000000000000476C6F62616C46756E630002004F110000F20000002000000000000000000000000A0000000000000001000000140000000000000010000000F1000000B60000002A00471100000000000000000000000062000000000000000000000006100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001F000000000053000D003E11031000000100617267760012004511160000000C0000001F000000000053000A003E1107100000000050001200451116000000F4FFFFFF1F000000000053000A003E117400000000004E001200451116000000F0FFFFFF1F0000000000530002004F110000F200000050000000000000000000000062000000000000000700000044000000000000001E0000000F0000001F0000001C000000200000002800000021000000450000002200000052000000230000005B00000024000000F1000000350000002F0046110000000000000000000000000A00000000000000000000000F100000000000000000004C6F63616C46756E630002004F11000000F20000002000000000000000000000000A000000000000000100000014000000000000000D000000F10000004B00000017000D11030400000000000000005F5F7075726563616C6C0016000D1111100000000000000000476C6F62616C5661720018000C1110100000000000000000436F6E7374616E745661720000F10000002D000000180008110710000048656C6C6F506F696E745479706564656600110008110910000048656C6C6F506F696E7400000000F4000000080000000100000000000000F30000003800000000643A5C7372635C6C6C766D2D6D6F6E6F5C6C6C645C746573745C636F66665C696E707574735C7064622D676C6F62616C732E6370700000 + Subsections: + - !Symbols + Records: + - Kind: S_COMPILE3 + Compile3Sym: + Flags: [ ] + Machine: Pentium3 + FrontendMajor: 6 + FrontendMinor: 0 + FrontendBuild: 0 + FrontendQFE: 0 + BackendMajor: 6000 + BackendMinor: 0 + BackendBuild: 0 + BackendQFE: 0 + Version: 'clang version 6.0.0 ' + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 10 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4098 + Flags: [ ] + DisplayName: GlobalFunc + - Kind: S_PROC_ID_END + ScopeEndSym: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 98 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4102 + Flags: [ ] + DisplayName: main + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: argc + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_LOCAL + LocalSym: + Type: 4099 + Flags: [ IsParameter ] + VarName: argv + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_LOCAL + LocalSym: + Type: 4103 + Flags: [ ] + VarName: P + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ ] + VarName: N + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_PROC_ID_END + ScopeEndSym: + - Kind: S_LPROC32_ID + ProcSym: + CodeSize: 10 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4111 + Flags: [ ] + DisplayName: LocalFunc + - Kind: S_PROC_ID_END + ScopeEndSym: + - Kind: S_GDATA32 + DataSym: + Type: 1027 + DisplayName: __purecall + - Kind: S_GDATA32 + DataSym: + Type: 4113 + DisplayName: GlobalVar + - Kind: S_LDATA32 + DataSym: + Type: 4112 + DisplayName: ConstantVar + - Kind: S_UDT + UDTSym: + Type: 4103 + UDTName: HelloPointTypedef + - Kind: S_UDT + UDTSym: + Type: 4105 + UDTName: HelloPoint + - !FileChecksums + Checksums: + - FileName: 'd:\src\llvm-mono\lld\test\coff\inputs\pdb-globals.cpp' + Kind: None + Checksum: '' + - !StringTable + Strings: + - 'd:\src\llvm-mono\lld\test\coff\inputs\pdb-globals.cpp' + - '' + Relocations: + - VirtualAddress: 100 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 104 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 132 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 136 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 204 + SymbolName: _main + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 208 + SymbolName: _main + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 243 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 247 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 278 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 282 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 310 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 314 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 342 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 346 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 364 + SymbolName: _main + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 368 + SymbolName: _main + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 484 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 488 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 516 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 520 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 564 + SymbolName: '?__purecall@@3PAXA' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 568 + SymbolName: '?__purecall@@3PAXA' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 589 + SymbolName: '?GlobalVar@@3PBHB' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 593 + SymbolName: '?GlobalVar@@3PBHB' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 613 + SymbolName: _ConstantVar + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 617 + SymbolName: _ConstantVar + Type: IMAGE_REL_I386_SECTION + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 0400000006000112000000000E000810740000000000000000100000160001160000000001100000476C6F62616C46756E6300F10A000210700400000A8000000E0001120200000074000000031000000E0008107400000000000200041000001200011600000000051000006D61696E00F3F2F13200051500008002000000000000000000000000000048656C6C6F506F696E74002E3F415548656C6C6F506F696E74404000F2F1260003120D15030074000000000058000D15030074000000040059000D1503007400000008005A0032000515030000020810000000000000000000000C0048656C6C6F506F696E74002E3F415548656C6C6F506F696E74404000F2F13E00051600000000643A5C7372635C6C6C766D2D6D6F6E6F5C6C6C645C746573745C636F66665C696E707574735C7064622D676C6F62616C732E63707000F2F10E000616091000000A100000060000000A000210071000000A8000001A00091003000000071000000C1000000B000000001000000000000016000216071000000D10000048656C6C6F506F696E7400F11600011600000000011000004C6F63616C46756E6300F2F10A000110740000000100F2F10A000210101000000A800000 + Types: + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 0 + ArgumentList: 4096 + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 0 + FunctionType: 4097 + Name: GlobalFunc + - Kind: LF_POINTER + Pointer: + ReferentType: 1136 + Attrs: 32778 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 116, 4099 ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 2 + ArgumentList: 4100 + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 0 + FunctionType: 4101 + Name: main + - Kind: LF_STRUCTURE + Class: + MemberCount: 0 + Options: [ None, ForwardReference, HasUniqueName ] + FieldList: 0 + Name: HelloPoint + UniqueName: '.?AUHelloPoint@@' + DerivationList: 0 + VTableShape: 0 + Size: 0 + - Kind: LF_FIELDLIST + FieldList: + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 0 + Name: X + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 4 + Name: Y + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 8 + Name: Z + - Kind: LF_STRUCTURE + Class: + MemberCount: 3 + Options: [ None, HasUniqueName ] + FieldList: 4104 + Name: HelloPoint + UniqueName: '.?AUHelloPoint@@' + DerivationList: 0 + VTableShape: 0 + Size: 12 + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'd:\src\llvm-mono\lld\test\coff\inputs\pdb-globals.cpp' + - Kind: LF_UDT_SRC_LINE + UdtSourceLine: + UDT: 4105 + SourceFile: 4106 + LineNumber: 6 + - Kind: LF_POINTER + Pointer: + ReferentType: 4103 + Attrs: 32778 + - Kind: LF_MFUNCTION + MemberFunction: + ReturnType: 3 + ClassType: 4103 + ThisType: 4108 + CallConv: ThisCall + Options: [ None ] + ParameterCount: 0 + ArgumentList: 4096 + ThisPointerAdjustment: 0 + - Kind: LF_MFUNC_ID + MemberFuncId: + ClassType: 4103 + FunctionType: 4109 + Name: HelloPoint + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 0 + FunctionType: 4097 + Name: LocalFunc + - Kind: LF_MODIFIER + Modifier: + ModifiedType: 116 + Modifiers: [ None, Const ] + - Kind: LF_POINTER + Pointer: + ReferentType: 4112 + Attrs: 32778 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 04000000F1000000650000003C0047110000000000000000000000002500000000000000000000000E1000000000000000000048656C6C6F506F696E743A3A48656C6C6F506F696E74000D003E110C100000010074686973001200451116000000FCFFFFFF0A00000000001B0002004F11000000F20000004000000000000000000000002500000000000000050000003400000000000000060000000A00000007000000100000000800000017000000090000001E00000006000000 + Subsections: + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 37 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4110 + Flags: [ ] + DisplayName: 'HelloPoint::HelloPoint' + - Kind: S_LOCAL + LocalSym: + Type: 4108 + Flags: [ IsParameter ] + VarName: this + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_PROC_ID_END + ScopeEndSym: + Relocations: + - VirtualAddress: 44 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 48 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 101 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 105 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 124 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 128 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_SECTION +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 138 + NumberOfRelocations: 4 + NumberOfLinenumbers: 0 + CheckSum: 3215092891 + Number: 1 + - Name: .data + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 4 + NumberOfRelocations: 1 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 2 + - Name: .bss + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 4 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 3 + - Name: .text + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 37 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 77530982 + Number: 4 + Selection: IMAGE_COMDAT_SELECT_ANY + - Name: '??0HelloPoint@@QAE@XZ' + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: .rdata + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 4 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 3903140090 + Number: 5 + - Name: .drectve + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 48 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 149686238 + Number: 6 + - Name: '.debug$S' + Value: 0 + SectionNumber: 7 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 768 + NumberOfRelocations: 26 + NumberOfLinenumbers: 0 + CheckSum: 2940884584 + Number: 7 + - Name: '.debug$S' + Value: 0 + SectionNumber: 9 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 188 + NumberOfRelocations: 6 + NumberOfLinenumbers: 0 + CheckSum: 1246640575 + Number: 4 + Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE + - Name: '.debug$T' + Value: 0 + SectionNumber: 8 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 452 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2561906059 + Number: 8 + - Name: '@feat.00' + Value: 1 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: '?GlobalFunc@@YAHXZ' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _main + Value: 16 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: '?LocalFunc@@YAHXZ' + Value: 128 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: '?GlobalVar@@3PBHB' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: '?__purecall@@3PAXA' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _ConstantVar + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... Index: lld/test/COFF/pdb-comdat.test =================================================================== --- lld/test/COFF/pdb-comdat.test +++ lld/test/COFF/pdb-comdat.test @@ -26,7 +26,7 @@ RUN: yaml2obj %S/Inputs/pdb_comdat_main.yaml -o pdb_comdat_main.obj RUN: yaml2obj %S/Inputs/pdb_comdat_bar.yaml -o pdb_comdat_bar.obj RUN: lld-link pdb_comdat_main.obj pdb_comdat_bar.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main -RUN: llvm-pdbutil dump -l -symbols t.pdb | FileCheck %s +RUN: llvm-pdbutil dump -l -symbols -globals t.pdb | FileCheck %s CHECK: Lines CHECK: ============================================================ @@ -38,6 +38,20 @@ CHECK-NOT: c:\src\llvm-project\build\foo.h CHECK-LABEL: Mod 0002 | `* Linker *`: +CHECK-LABEL: Global Symbols +CHECK-NEXT: ============================================================ +CHECK-NEXT: Records +CHECK-NEXT: 84 | S_PROCREF [size = 20] `main` +CHECK-NEXT: module = 1, sum name = 0, offset = 120 +CHECK-NEXT: 128 | S_PROCREF [size = 20] `foo` +CHECK-NEXT: module = 1, sum name = 0, offset = 208 +CHECK-NEXT: 148 | S_PROCREF [size = 20] `bar` +CHECK-NEXT: module = 2, sum name = 0, offset = 120 +CHECK-NEXT: 104 | S_GDATA32 [size = 24] `global` +CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000 +CHECK-NEXT: 168 | S_GDATA32 [size = 24] `global` +CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000 + CHECK: Symbols CHECK: ============================================================ CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`: @@ -54,17 +68,15 @@ CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 CHECK: flags = has async eh | opt speed CHECK: 196 | S_END [size = 4] -CHECK: 200 | S_GDATA32 [size = 24] `global` -CHECK: type = 0x0074 (int), addr = 0000:0000 -CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100A` -CHECK: 232 | S_GPROC32 [size = 44] `foo` -CHECK: parent = 0, end = 308, addr = 0002:0032, code size = 15 +CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `0x100A` +CHECK: 208 | S_GPROC32 [size = 44] `foo` +CHECK: parent = 0, end = 284, addr = 0002:0032, code size = 15 CHECK: debug start = 0, debug end = 14, flags = none -CHECK: 276 | S_FRAMEPROC [size = 32] +CHECK: 252 | S_FRAMEPROC [size = 32] CHECK: size = 0, padding size = 0, offset to padding = 0 CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 CHECK: flags = marked inline | has async eh | opt speed -CHECK: 308 | S_END [size = 4] +CHECK: 284 | S_END [size = 4] CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`: CHECK: 4 | S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_bar.obj` CHECK: 60 | S_COMPILE3 [size = 60] @@ -79,9 +91,7 @@ CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 CHECK: flags = has async eh | opt speed CHECK: 196 | S_END [size = 4] -CHECK: 200 | S_GDATA32 [size = 24] `global` -CHECK: type = 0x0074 (int), addr = 0000:0000 -CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100D` +CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `0x100D` CHECK-NOT: S_GPROC32 {{.*}} `foo` CHECK-LABEL: Mod 0002 | `* Linker *`: Index: lld/test/COFF/pdb-global-gc.yaml =================================================================== --- lld/test/COFF/pdb-global-gc.yaml +++ lld/test/COFF/pdb-global-gc.yaml @@ -2,7 +2,7 @@ # RUN: llvm-mc %S/Inputs/pdb-global-gc.s -triple x86_64-windows-msvc -filetype=obj -o %t2.obj # RUN: lld-link %t.obj %t2.obj -debug -entry:main \ # RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb -verbose -# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s # This tests the case where an __imp_ chunk is discarded by linker GC. The debug # info may refer to the __imp_ symbol still. @@ -12,13 +12,17 @@ # int discarded() { return __wc_mb_cur; } # int main() { return g2; } -# CHECK: Symbols -# CHECK: ============================================================ -# CHECK: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`: -# CHECK: 4 | S_GDATA32 [size = 28] `__wc_mb_cur` -# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 -# CHECK: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`: -# CHECK: Mod 0002 | `* Linker *`: +# CHECK: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 20 | S_GDATA32 [size = 28] `__wc_mb_cur` +# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 + +# CHECK: Symbols +# CHECK: ============================================================ +# CHECK-NEXT: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`: +# CHECK-NEXT: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`: +# CHECK-NEXT: Mod 0002 | `* Linker *`: --- !COFF header: Index: lld/test/COFF/pdb-globals.test =================================================================== --- /dev/null +++ lld/test/COFF/pdb-globals.test @@ -0,0 +1,46 @@ +RUN: yaml2obj %S/Inputs/pdb-globals.yaml > %t.obj +RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj +RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s + +# Test that we correctly distribute symbols between the globals and module +# symbol streams. Specifically: +# * S_UDT, S_GDATA32, and S_CONSTANT end up in the globals stream, and are +# omitted from the module stream. +# * S_GPROC32 and S_LPROC32 end up in the symbols stream, but S_PROCREF and +# S_LPROCREF are added to the globals stream that refer to the module +# stream. +# * S_LDATA32 is copied byte for byte into both streams. + + +CHECK-LABEL: Global Symbols +CHECK-NEXT: ============================================================ +CHECK-NEXT: Records +CHECK-NEXT: 340 | S_UDT [size = 20] `HelloPoint` +CHECK-NEXT: original type = 0x1007 +CHECK-NEXT: 160 | S_PROCREF [size = 28] `GlobalFunc` +CHECK-NEXT: module = 1, sum name = 0, offset = 52 +CHECK-NEXT: 188 | S_PROCREF [size = 20] `main` +CHECK-NEXT: module = 1, sum name = 0, offset = 108 +CHECK-NEXT: 208 | S_LPROCREF [size = 24] `LocalFunc` +CHECK-NEXT: module = 1, sum name = 0, offset = 292 +CHECK-NEXT: 360 | S_PROCREF [size = 40] `HelloPoint::HelloPoint` +CHECK-NEXT: module = 1, sum name = 0, offset = 376 +CHECK-NEXT: 232 | S_GDATA32 [size = 28] `__purecall` +CHECK-NEXT: type = 0x0403 (void*), addr = 0000:0000 +CHECK-NEXT: 260 | S_GDATA32 [size = 24] `GlobalVar` +CHECK-NEXT: type = 0x100B (const int*), addr = 0001:0000 +CHECK-NEXT: 312 | S_UDT [size = 28] `HelloPointTypedef` +CHECK-NEXT: original type = 0x1005 +CHECK-NEXT: 284 | S_LDATA32 [size = 28] `ConstantVar` +CHECK-NEXT: type = 0x100A (const int), addr = 0002:0000 + +CHECK-LABEL: Symbols +CHECK-NEXT: ============================================================ +CHECK-NEXT: Mod 0000 +CHECK-NOT: | S_GDATA32 +CHECK-NOT: | S_UDT +CHECK: 52 | S_GPROC32 [size = 52] `GlobalFunc` +CHECK: 108 | S_GPROC32 [size = 44] `main` +CHECK: 292 | S_LPROC32 [size = 52] `LocalFunc` +CHECK: 348 | S_LDATA32 [size = 28] `ConstantVar` +CHECK: 376 | S_GPROC32 [size = 64] `HelloPoint::HelloPoint` Index: lld/test/COFF/pdb-import-gc.yaml =================================================================== --- lld/test/COFF/pdb-import-gc.yaml +++ lld/test/COFF/pdb-import-gc.yaml @@ -1,7 +1,7 @@ # RUN: yaml2obj %s -o %t.obj # RUN: lld-link %t.obj %S/Inputs/pdb-import-gc.lib -debug -entry:main \ # RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb -# RUN: llvm-pdbutil dump -publics -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -globals -symbols %t.pdb | FileCheck %s # This tests the case where an __imp_ chunk is discarded by linker GC. The debug # info may refer to the __imp_ symbol still. @@ -11,12 +11,16 @@ # int discarded() { return __wc_mb_cur; } # int main() { return g2; } -# CHECK: Symbols -# CHECK: ============================================================ -# CHECK: Mod 0000 | `{{.*}}pdb-import-gc.yaml.tmp.obj`: -# CHECK: 4 | S_GDATA32 [size = 32] `__imp___wc_mb_cur` -# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 -# CHECK: Mod 0001 | `* Linker *`: +# CHECK: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 20 | S_GDATA32 [size = 32] `__imp___wc_mb_cur` +# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 + +# CHECK: Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Mod 0000 | `{{.*}}pdb-import-gc.yaml.tmp.obj`: +# CHECK-NEXT: Mod 0001 | `* Linker *`: --- !COFF header: Index: lld/test/COFF/pdb-safeseh.yaml =================================================================== --- lld/test/COFF/pdb-safeseh.yaml +++ lld/test/COFF/pdb-safeseh.yaml @@ -1,16 +1,17 @@ # RUN: yaml2obj %s -o %t.obj # RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj -# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -globals %t.pdb | FileCheck %s # There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in # it in this debug info. This is similar to the relocations in the loadcfg.obj # file in the MSVC CRT. We need to make sure that our relocation logic matches # MSVC's for these absolute, linker-provided symbols. -# CHECK: Mod 0000 | -# CHECK-NEXT: 4 | S_GDATA32 [size = 40] `___safe_se_handler_table` -# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 -# CHECK-NEXT: Mod 0001 | `* Linker *`: +# CHECK: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 20 | S_GDATA32 [size = 40] `___safe_se_handler_table` +# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 --- !COFF header: Index: lld/test/COFF/pdb-secrel-absolute.yaml =================================================================== --- lld/test/COFF/pdb-secrel-absolute.yaml +++ lld/test/COFF/pdb-secrel-absolute.yaml @@ -1,16 +1,17 @@ # RUN: yaml2obj %s -o %t.obj # RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj -# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -globals %t.pdb | FileCheck %s # There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in # it in this debug info. This is similar to the relocations in the loadcfg.obj # file in the MSVC CRT. We need to make sure that our relocation logic matches # MSVC's for these absolute, linker-provided symbols. -# CHECK: Mod 0000 | -# CHECK-NEXT: 4 | S_GDATA32 [size = 36] `__guard_fids_table` -# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 -# CHECK-NEXT: Mod 0001 | `* Linker *`: +# CHECK: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 20 | S_GDATA32 [size = 36] `__guard_fids_table` +# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 --- !COFF header: Index: lld/test/COFF/pdb-symbol-types.yaml =================================================================== --- lld/test/COFF/pdb-symbol-types.yaml +++ lld/test/COFF/pdb-symbol-types.yaml @@ -1,6 +1,6 @@ # RUN: yaml2obj %s -o %t.obj # RUN: lld-link %t.obj -nodefaultlib -entry:main -debug -out:%t.exe -pdb:%t.pdb -# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s # To regenerate the object file: # $ cat symbol-types.c @@ -13,6 +13,18 @@ # Note that the type of 'global' goes from 0x1005 in the object file to 0x1004 # in the PDB because the LF_FUNC_ID is moved to the id stream. +# CHECK-LABEL: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 48 | S_PROCREF [size = 20] `main` +# CHECK-NEXT: module = 1, sum name = 0, offset = 116 +# CHECK-NEXT: 96 | S_UDT [size = 16] `UDT_Foo` +# CHECK-NEXT: original type = 0x1004 +# CHECK-NEXT: 112 | S_UDT [size = 12] `Foo` +# CHECK-NEXT: original type = 0x1004 +# CHECK-NEXT: 68 | S_GDATA32 [size = 28] `global_foo` +# CHECK-NEXT: type = 0x1004 (Foo), addr = 0001:0000 + # CHECK: Symbols # CHECK: ============================================================ # CHECK-LABEL: Mod 0000 | `{{.*}}pdb-symbol-types.yaml.tmp.obj`: @@ -29,13 +41,7 @@ # CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 # CHECK: flags = has async eh | opt speed # CHECK: 192 | S_END [size = 4] -# CHECK: 196 | S_GDATA32 [size = 28] `global_foo` -# CHECK: type = 0x1004 (Foo), addr = 0001:0000 -# CHECK: 224 | S_UDT [size = 16] `UDT_Foo` -# CHECK: original type = 0x1004 -# CHECK: 240 | S_UDT [size = 12] `Foo` -# CHECK: original type = 0x1004 -# CHECK: 252 | S_BUILDINFO [size = 8] BuildId = `0x100A` +# CHECK: 196 | S_BUILDINFO [size = 8] BuildId = `0x100A` # CHECK-LABEL: Mod 0001 | `* Linker *`: --- !COFF Index: lld/test/COFF/pdb-type-server-simple.test =================================================================== --- lld/test/COFF/pdb-type-server-simple.test +++ lld/test/COFF/pdb-type-server-simple.test @@ -21,7 +21,7 @@ RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib -RUN: llvm-pdbutil dump -symbols -types -ids %t/t.pdb | FileCheck %s +RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s CHECK-LABEL: Types (TPI Stream) @@ -59,6 +59,18 @@ CHECK: [[B_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28] CHECK: {{.*}}: `b.c` +CHECK-LABEL: Global Symbols +CHECK: ============================================================ +CHECK-NEXT: Records +CHECK-NEXT: 36 | S_PROCREF [size = 20] `main` +CHECK-NEXT: module = 1, sum name = 0, offset = 104 +CHECK-NEXT: 68 | S_PROCREF [size = 16] `g` +CHECK-NEXT: module = 2, sum name = 0, offset = 104 +CHECK-NEXT: 56 | S_UDT [size = 12] `Foo` +CHECK-NEXT: original type = 0x1006 +CHECK-NEXT: 84 | S_UDT [size = 12] `Foo` +CHECK-NEXT: original type = 0x1006 + CHECK-LABEL: Symbols CHECK: ============================================================ CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`: @@ -66,9 +78,7 @@ CHECK: 104 | S_GPROC32 [size = 44] `main` CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 27 CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none -CHECK: 200 | S_UDT [size = 12] `Foo` -CHECK: original type = [[FOO_COMPLETE]] -CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` +CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`: CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\b.obj` CHECK: 44 | S_COMPILE3 [size = 60] @@ -85,7 +95,5 @@ CHECK: 180 | S_REGREL32 [size = 16] `p` CHECK: type = [[FOO_PTR]] (Foo*), register = rsp, offset = 8 CHECK: 196 | S_END [size = 4] -CHECK: 200 | S_UDT [size = 12] `Foo` -CHECK: original type = [[FOO_COMPLETE]] -CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` +CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` CHECK-LABEL: Mod 0002 | `* Linker *`: Index: llvm/include/llvm/DebugInfo/CodeView/RecordName.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/RecordName.h +++ llvm/include/llvm/DebugInfo/CodeView/RecordName.h @@ -1,4 +1,4 @@ -//===- TypeName.h --------------------------------------------- *- C++ --*-===// +//===- RecordName.h ------------------------------------------- *- C++ --*-===// // // The LLVM Compiler Infrastructure // @@ -7,16 +7,18 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H -#define LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H +#ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDNAME_H +#define LLVM_DEBUGINFO_CODEVIEW_RECORDNAME_H +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/TypeCollection.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" namespace llvm { namespace codeview { std::string computeTypeName(TypeCollection &Types, TypeIndex Index); -} +StringRef getSymbolName(CVSymbol Sym); +} // namespace codeview } // namespace llvm #endif Index: llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -54,14 +54,12 @@ template static Expected deserializeAs(ArrayRef Data) { - CVType CVT; - CVT.RecordData = Data; - MappingInfo I(CVT.content()); const RecordPrefix *Prefix = reinterpret_cast(Data.data()); TypeRecordKind K = static_cast(uint16_t(Prefix->RecordKind)); T Record(K); + CVType CVT(static_cast(K), Data); if (auto EC = deserializeAs(CVT, Record)) return std::move(EC); return Record; Index: llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -412,6 +412,10 @@ return (Options & ClassOptions::HasUniqueName) != ClassOptions::None; } + bool isNested() const { + return (Options & ClassOptions::Nested) != ClassOptions::None; + } + uint16_t getMemberCount() const { return MemberCount; } ClassOptions getOptions() const { return Options; } TypeIndex getFieldList() const { return FieldList; } Index: llvm/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h =================================================================== --- llvm/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h +++ llvm/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h @@ -58,6 +58,12 @@ void addPublicSymbol(const codeview::PublicSym32 &Pub); + void addGlobalSymbol(const codeview::ProcRefSym &Sym); + void addGlobalSymbol(const codeview::DataSym &Sym); + void addGlobalSymbol(const codeview::ConstantSym &Sym); + void addGlobalSymbol(const codeview::UDTSym &Sym); + void addGlobalSymbol(const codeview::CVSymbol &Sym); + private: uint32_t calculatePublicsHashStreamSize() const; uint32_t calculateGlobalsHashStreamSize() const; Index: llvm/lib/DebugInfo/CodeView/CMakeLists.txt =================================================================== --- llvm/lib/DebugInfo/CodeView/CMakeLists.txt +++ llvm/lib/DebugInfo/CodeView/CMakeLists.txt @@ -19,6 +19,7 @@ Formatters.cpp LazyRandomTypeCollection.cpp Line.cpp + RecordName.cpp RecordSerialization.cpp StringsAndChecksums.cpp SymbolRecordMapping.cpp @@ -27,7 +28,6 @@ TypeDumpVisitor.cpp TypeIndex.cpp TypeIndexDiscovery.cpp - TypeName.cpp TypeRecordMapping.cpp TypeSerializer.cpp TypeStreamMerger.cpp Index: llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp +++ llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp @@ -13,7 +13,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" -#include "llvm/DebugInfo/CodeView/TypeName.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Endian.h" Index: llvm/lib/DebugInfo/CodeView/RecordName.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/RecordName.cpp +++ llvm/lib/DebugInfo/CodeView/RecordName.cpp @@ -1,4 +1,4 @@ -//===- TypeName.cpp ------------------------------------------- *- C++ --*-===// +//===- RecordName.cpp ----------------------------------------- *- C++ --*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/DebugInfo/CodeView/TypeName.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/ADT/SmallString.h" +#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h" #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" #include "llvm/Support/FormatVariadic.h" @@ -241,3 +243,78 @@ } return Computer.name(); } + +static int getSymbolNameOffset(CVSymbol Sym) { + switch (Sym.kind()) { + // See ProcSym + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: + case SymbolKind::S_GPROC32_ID: + case SymbolKind::S_LPROC32_ID: + case SymbolKind::S_LPROC32_DPC: + case SymbolKind::S_LPROC32_DPC_ID: + return 35; + // See Thunk32Sym + case SymbolKind::S_THUNK32: + return 21; + // See SectionSym + case SymbolKind::S_SECTION: + return 16; + // See CoffGroupSym + case SymbolKind::S_COFFGROUP: + return 14; + // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym + case SymbolKind::S_PUB32: + case SymbolKind::S_FILESTATIC: + case SymbolKind::S_REGREL32: + case SymbolKind::S_GDATA32: + case SymbolKind::S_LDATA32: + case SymbolKind::S_LMANDATA: + case SymbolKind::S_GMANDATA: + case SymbolKind::S_LTHREAD32: + case SymbolKind::S_GTHREAD32: + return 10; + // See RegisterSym and LocalSym + case SymbolKind::S_REGISTER: + case SymbolKind::S_LOCAL: + return 6; + // See BlockSym + case SymbolKind::S_BLOCK32: + return 18; + // See LabelSym + case SymbolKind::S_LABEL32: + return 7; + // See ObjNameSym, ExportSym, and UDTSym + case SymbolKind::S_OBJNAME: + case SymbolKind::S_EXPORT: + case SymbolKind::S_UDT: + return 4; + // See BPRelativeSym + case SymbolKind::S_BPREL32: + return 8; + default: + return -1; + } +} + +StringRef llvm::codeview::getSymbolName(CVSymbol Sym) { + if (Sym.kind() == SymbolKind::S_CONSTANT) { + // S_CONSTANT is preceded by an APSInt, which has a variable length. So we + // have to do a full deserialization. + BinaryStreamReader Reader(Sym.content(), llvm::support::little); + // The container doesn't matter for single records. + SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile); + ConstantSym Const(SymbolKind::S_CONSTANT); + cantFail(Mapping.visitSymbolBegin(Sym)); + cantFail(Mapping.visitKnownRecord(Sym, Const)); + cantFail(Mapping.visitSymbolEnd(Sym)); + return Const.Name; + } + + int Offset = getSymbolNameOffset(Sym); + if (Offset == -1) + return StringRef(); + + StringRef StringData = toStringRef(Sym.content()).drop_front(Offset); + return StringData.split('\0').first; +} Index: llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp +++ llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp @@ -10,7 +10,7 @@ #include "llvm/DebugInfo/CodeView/TypeTableCollection.h" #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" -#include "llvm/DebugInfo/CodeView/TypeName.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamReader.h" Index: llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp =================================================================== --- llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp +++ llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp @@ -9,6 +9,7 @@ #include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" @@ -27,13 +28,6 @@ using namespace llvm::pdb; using namespace llvm::codeview; -static StringRef getSymbolName(const CVSymbol &Sym) { - assert(Sym.kind() == S_PUB32 && "handle other kinds"); - PublicSym32 PSL = - cantFail(SymbolDeserializer::deserializeAs(Sym)); - return PSL.Name; -} - struct llvm::pdb::GSIHashStreamBuilder { std::vector Records; uint32_t StreamIndex; @@ -45,6 +39,13 @@ uint32_t calculateRecordByteSize() const; Error commit(BinaryStreamWriter &Writer); void finalizeBuckets(uint32_t RecordZeroOffset); + + template void addSymbol(const T &Symbol, MSFBuilder &Msf) { + T Copy(Symbol); + Records.push_back(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(), + CodeViewContainer::Pdb)); + } + void addSymbol(const CVSymbol &Symbol) { Records.push_back(Symbol); } }; uint32_t GSIHashStreamBuilder::calculateSerializedLength() const { @@ -222,9 +223,27 @@ } void GSIStreamBuilder::addPublicSymbol(const PublicSym32 &Pub) { - PublicSym32 Copy(Pub); - PSH->Records.push_back(SymbolSerializer::writeOneSymbol( - Copy, Msf.getAllocator(), CodeViewContainer::Pdb)); + PSH->addSymbol(Pub, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const ProcRefSym &Sym) { + GSH->addSymbol(Sym, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const DataSym &Sym) { + GSH->addSymbol(Sym, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const ConstantSym &Sym) { + GSH->addSymbol(Sym, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const UDTSym &Sym) { + GSH->addSymbol(Sym, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const codeview::CVSymbol &Sym) { + GSH->addSymbol(Sym); } static Error writeRecords(BinaryStreamWriter &Writer,