[COFF] Teach LLD to use the COFF .debug$H section.

This adds the /DEBUG:GHASH option to LLD which will look for
the existence of .debug$H sections in linker inputs and use them
to accelerate type merging.  The clang-cl side has already been
added, so this completes the work necessary to begin experimenting
with this feature.

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

llvm-svn: 320719
This commit is contained in:
Zachary Turner 2017-12-14 18:07:04 +00:00
parent dcc646e40b
commit 0d07a8e948
13 changed files with 1592 additions and 37 deletions

View File

@ -89,6 +89,7 @@ struct Configuration {
bool Force = false;
bool Debug = false;
bool DebugDwarf = false;
bool DebugGHashes = false;
unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
llvm::SmallString<128> PDBPath;
std::vector<llvm::StringRef> Argv;

View File

@ -809,7 +809,8 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Config->Force = true;
// Handle /debug
if (Args.hasArg(OPT_debug) || Args.hasArg(OPT_debug_dwarf)) {
if (Args.hasArg(OPT_debug) || Args.hasArg(OPT_debug_dwarf) ||
Args.hasArg(OPT_debug_ghash)) {
Config->Debug = true;
if (auto *Arg = Args.getLastArg(OPT_debugtype))
Config->DebugTypes = parseDebugType(Arg->getValue());
@ -1018,6 +1019,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true);
Config->TerminalServerAware = Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
Config->DebugDwarf = Args.hasArg(OPT_debug_dwarf);
Config->DebugGHashes = Args.hasArg(OPT_debug_ghash);
Config->MapFile = getMapFile(Args);

View File

@ -117,6 +117,7 @@ def help : F<"help">;
def help_q : Flag<["/?", "-?"], "">, Alias<help>;
// LLD extensions
def debug_ghash : F<"debug:ghash">;
def debug_dwarf : F<"debug:dwarf">;
def export_all_symbols : F<"export-all-symbols">;
def nopdb : F<"nopdb">, HelpText<"Disable PDB generation for DWARF users">;

View File

@ -17,6 +17,7 @@
#include "lld/Common/ErrorHandler.h"
#include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/RecordName.h"
@ -72,8 +73,8 @@ struct CVIndexMap {
class PDBLinker {
public:
PDBLinker(SymbolTable *Symtab)
: Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc),
IDTable(Alloc) {}
: Alloc(), Symtab(Symtab), Builder(Alloc), GlobalTypeTable(Alloc),
GlobalIDTable(Alloc), TypeTable(Alloc), IDTable(Alloc) {}
/// Emit the basic PDB structure: initial streams, headers, etc.
void initialize(const llvm::codeview::DebugInfo &BuildId);
@ -123,6 +124,12 @@ private:
/// Item records that will go into the PDB IPI stream.
MergingTypeTableBuilder IDTable;
/// Type records that will go into the PDB TPI stream (for /DEBUG:GHASH)
GlobalTypeTableBuilder GlobalTypeTable;
/// Item records that will go into the PDB IPI stream (for /DEBUG:GHASH)
GlobalTypeTableBuilder GlobalIDTable;
/// PDBs use a single global string table for filenames in the file checksum
/// table.
DebugStringTableSubsection PDBStrTab;
@ -160,6 +167,41 @@ static ArrayRef<uint8_t> getDebugSection(ObjFile *File, StringRef SecName) {
return {};
}
// A COFF .debug$H section is currently a clang extension. This function checks
// if a .debug$H section is in a format that we expect / understand, so that we
// can ignore any sections which are coincidentally also named .debug$H but do
// not contain a format we recognize.
static bool canUseDebugH(ArrayRef<uint8_t> DebugH) {
if (DebugH.size() < sizeof(object::debug_h_header))
return false;
auto *Header =
reinterpret_cast<const object::debug_h_header *>(DebugH.data());
DebugH = DebugH.drop_front(sizeof(object::debug_h_header));
return Header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC &&
Header->Version == 0 &&
Header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1) &&
(DebugH.size() % 20 == 0);
}
static Optional<ArrayRef<uint8_t>> getDebugH(ObjFile *File) {
SectionChunk *Sec = findByName(File->getDebugChunks(), ".debug$H");
if (!Sec)
return llvm::None;
ArrayRef<uint8_t> Contents = Sec->getContents();
if (!canUseDebugH(Contents))
return None;
return Contents;
}
static ArrayRef<GloballyHashedType>
getHashesFromDebugH(ArrayRef<uint8_t> DebugH) {
assert(canUseDebugH(DebugH));
DebugH = DebugH.drop_front(sizeof(object::debug_h_header));
uint32_t Count = DebugH.size() / sizeof(GloballyHashedType);
return {reinterpret_cast<const GloballyHashedType *>(DebugH.data()), Count};
}
static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
TypeCollection &TypeTable) {
// Start the TPI or IPI stream header.
@ -207,10 +249,26 @@ const CVIndexMap &PDBLinker::mergeDebugT(ObjFile *File,
// This is a /Z7 object. Fill in the temporary, caller-provided
// ObjectIndexMap.
if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
ObjectIndexMap.TPIMap, Types))
fatal("codeview::mergeTypeAndIdRecords failed: " +
toString(std::move(Err)));
if (Config->DebugGHashes) {
ArrayRef<GloballyHashedType> Hashes;
std::vector<GloballyHashedType> OwnedHashes;
if (Optional<ArrayRef<uint8_t>> DebugH = getDebugH(File))
Hashes = getHashesFromDebugH(*DebugH);
else {
OwnedHashes = GloballyHashedType::hashTypes(Types);
Hashes = OwnedHashes;
}
if (auto Err = mergeTypeAndIdRecords(GlobalIDTable, GlobalTypeTable,
ObjectIndexMap.TPIMap, Types, Hashes))
fatal("codeview::mergeTypeAndIdRecords failed: " +
toString(std::move(Err)));
} else {
if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
ObjectIndexMap.TPIMap, Types))
fatal("codeview::mergeTypeAndIdRecords failed: " +
toString(std::move(Err)));
}
return ObjectIndexMap;
}
@ -274,21 +332,44 @@ const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
if (auto E = ExpectedSession.takeError())
fatal("Type server PDB was not found: " + toString(std::move(E)));
// Merge TPI first, because the IPI stream will reference type indices.
auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream();
if (auto E = ExpectedTpi.takeError())
fatal("Type server does not have TPI stream: " + toString(std::move(E)));
if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap,
ExpectedTpi->typeArray()))
fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));
// Merge IPI.
auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream();
if (auto E = ExpectedIpi.takeError())
fatal("Type server does not have TPI stream: " + toString(std::move(E)));
if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap,
ExpectedIpi->typeArray()))
fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
if (Config->DebugGHashes) {
// PDBs do not actually store global hashes, so when merging a type server
// PDB we have to synthesize global hashes. To do this, we first synthesize
// global hashes for the TPI stream, since it is independent, then we
// synthesize hashes for the IPI stream, using the hashes for the TPI stream
// as inputs.
auto TpiHashes = GloballyHashedType::hashTypes(ExpectedTpi->typeArray());
auto IpiHashes =
GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes);
// Merge TPI first, because the IPI stream will reference type indices.
if (auto Err = mergeTypeRecords(GlobalTypeTable, IndexMap.TPIMap,
ExpectedTpi->typeArray(), TpiHashes))
fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));
// Merge IPI.
if (auto Err =
mergeIdRecords(GlobalIDTable, IndexMap.TPIMap, IndexMap.IPIMap,
ExpectedIpi->typeArray(), IpiHashes))
fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
} else {
// Merge TPI first, because the IPI stream will reference type indices.
if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap,
ExpectedTpi->typeArray()))
fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));
// Merge IPI.
if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap,
ExpectedIpi->typeArray()))
fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
}
return IndexMap;
}
@ -658,8 +739,13 @@ void PDBLinker::addObjFile(ObjFile *File) {
File->ModuleDBI->addDebugSubsection(SS);
break;
case DebugSubsectionKind::Symbols:
mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap,
IDTable, SS.getRecordData());
if (Config->DebugGHashes) {
mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap,
GlobalIDTable, SS.getRecordData());
} else {
mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap,
IDTable, SS.getRecordData());
}
break;
default:
// FIXME: Process the rest of the subsections.
@ -712,11 +798,14 @@ void PDBLinker::addObjectsToPDB() {
Builder.getStringTableBuilder().setStrings(PDBStrTab);
// Construct TPI stream contents.
addTypeInfo(Builder.getTpiBuilder(), TypeTable);
// Construct IPI stream contents.
addTypeInfo(Builder.getIpiBuilder(), IDTable);
// Construct TPI and IPI stream contents.
if (Config->DebugGHashes) {
addTypeInfo(Builder.getTpiBuilder(), GlobalTypeTable);
addTypeInfo(Builder.getIpiBuilder(), GlobalIDTable);
} else {
addTypeInfo(Builder.getTpiBuilder(), TypeTable);
addTypeInfo(Builder.getIpiBuilder(), IDTable);
}
// Compute the public and global symbols.
auto &GsiBuilder = Builder.getGsiBuilder();

View File

@ -0,0 +1,540 @@
--- !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: 5589E55683EC188B450C8B4D088D55F4C745F8000000008B7508894DF089D18934248945ECE80000000083EC048D4DF4890C248945E8E80000000083C4185E5DC3
Relocations:
- VirtualAddress: 38
SymbolName: '??0Foo@NS@@QAE@H@Z'
Type: IMAGE_REL_I386_REL32
- VirtualAddress: 55
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
Type: IMAGE_REL_I386_REL32
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ''
- 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: 5589E583EC088B4508894DFC8B4DFC8B550889118945F889C883C4085DC20400
- 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: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F50000008400000000000000000000004100000000000000080000000000000052000000070000000400000001000000400000000000000008000000000000007F0000000600040000000000030000003E000000000000000800000000000000BD0000000400040000000000040000003D000000000000000800000000000000FA0000000300080000000000F1000000960000002A00471100000000000000000000000041000000000000000000000003100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001700000000002A000D003E11001000000100617267760012004511160000000C0000001700000000002A000A003E1109100000000066001200451116000000F4FFFFFF1700000000002A0002004F110000F200000030000000000000000000000041000000000000000300000024000000000000000300000017000000040000003000000005000000F1000000100000000E000811091000004E533A3A466F6F00F40000003000000001000000100165C9E387F88362A8EB2B49539DD5A65500002B00000010019303CF100D518DAF59C31DA01FEF4AFC0000F30000004801000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A312E63707000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D2024657369202454302038202D205E203D2000
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 '
- !FrameData
Frames:
- CodeSize: 65
FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 8
PrologSize: 7
RvaStart: 0
SavedRegsSize: 0
- CodeSize: 64
FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 8
PrologSize: 6
RvaStart: 1
SavedRegsSize: 4
- CodeSize: 62
FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 8
PrologSize: 4
RvaStart: 3
SavedRegsSize: 4
- CodeSize: 61
FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 8
PrologSize: 3
RvaStart: 4
SavedRegsSize: 8
- !Symbols
Records:
- Kind: S_GPROC32_ID
ProcSym:
CodeSize: 65
DbgStart: 0
DbgEnd: 0
FunctionType: 4099
Flags: [ ]
DisplayName: main
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: argc
- Kind: S_DEFRANGE_REGISTER_REL
DefRangeRegisterRelSym:
- Kind: S_LOCAL
LocalSym:
Type: 4096
Flags: [ IsParameter ]
VarName: argv
- Kind: S_DEFRANGE_REGISTER_REL
DefRangeRegisterRelSym:
- Kind: S_LOCAL
LocalSym:
Type: 4105
Flags: [ ]
VarName: f
- Kind: S_DEFRANGE_REGISTER_REL
DefRangeRegisterRelSym:
- Kind: S_PROC_ID_END
ScopeEndSym:
- !Lines
CodeSize: 65
Flags: [ ]
RelocOffset: 0
RelocSegment: 0
Blocks:
- FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp'
Lines:
- Offset: 0
LineStart: 3
IsStatement: false
EndDelta: 0
- Offset: 23
LineStart: 4
IsStatement: false
EndDelta: 0
- Offset: 48
LineStart: 5
IsStatement: false
EndDelta: 0
Columns:
- !Symbols
Records:
- Kind: S_UDT
UDTSym:
Type: 4105
UDTName: 'NS::Foo'
- !FileChecksums
Checksums:
- FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp'
Kind: MD5
Checksum: 65C9E387F88362A8EB2B49539DD5A655
- FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h'
Kind: MD5
Checksum: 9303CF100D518DAF59C31DA01FEF4AFC
- !StringTable
Strings:
- 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp'
- 'D:\src\llvmbuild\clang\Debug\x86\obj.h'
- '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
- '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
- '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
- '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = '
Relocations:
- VirtualAddress: 68
SymbolName: _main
Type: IMAGE_REL_I386_DIR32NB
- VirtualAddress: 240
SymbolName: _main
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 244
SymbolName: _main
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 279
SymbolName: .text
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 283
SymbolName: .text
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 314
SymbolName: .text
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 318
SymbolName: .text
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 346
SymbolName: .text
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 350
SymbolName: .text
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 368
SymbolName: _main
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 372
SymbolName: _main
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: 040000000A000210700400000A8000000E0001120200000074000000001000000E0008107400000000000200011000001200011600000000021000006D61696E00F3F2F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000210041000000A8000000A00011201000000740000001A0009100300000004100000051000000B00010006100000000000001A0003120D15030074000000000058001115030007100000466F6F002A0005150200000208100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E000616091000000A100000020000000E0002160410000007100000466F6F00
Types:
- Kind: LF_POINTER
Pointer:
ReferentType: 1136
Attrs: 32778
- Kind: LF_ARGLIST
ArgList:
ArgIndices: [ 116, 4096 ]
- Kind: LF_PROCEDURE
Procedure:
ReturnType: 116
CallConv: NearC
Options: [ None ]
ParameterCount: 2
ArgumentList: 4097
- Kind: LF_FUNC_ID
FuncId:
ParentScope: 0
FunctionType: 4098
Name: main
- Kind: LF_STRUCTURE
Class:
MemberCount: 0
Options: [ None, ForwardReference, HasUniqueName ]
FieldList: 0
Name: 'NS::Foo'
UniqueName: '.?AUFoo@NS@@'
DerivationList: 0
VTableShape: 0
Size: 0
- Kind: LF_POINTER
Pointer:
ReferentType: 4100
Attrs: 32778
- Kind: LF_ARGLIST
ArgList:
ArgIndices: [ 116 ]
- Kind: LF_MFUNCTION
MemberFunction:
ReturnType: 3
ClassType: 4100
ThisType: 4101
CallConv: ThisCall
Options: [ None ]
ParameterCount: 1
ArgumentList: 4102
ThisPointerAdjustment: 0
- Kind: LF_FIELDLIST
FieldList:
- Kind: LF_MEMBER
DataMember:
Attrs: 3
Type: 116
FieldOffset: 0
Name: X
- Kind: LF_ONEMETHOD
OneMethod:
Type: 4103
Attrs: 3
VFTableOffset: -1
Name: Foo
- Kind: LF_STRUCTURE
Class:
MemberCount: 2
Options: [ None, HasUniqueName ]
FieldList: 4104
Name: 'NS::Foo'
UniqueName: '.?AUFoo@NS@@'
DerivationList: 0
VTableShape: 0
Size: 4
- Kind: LF_STRING_ID
StringId:
Id: 0
String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h'
- Kind: LF_UDT_SRC_LINE
UdtSourceLine:
UDT: 4105
SourceFile: 4106
LineNumber: 2
- Kind: LF_MFUNC_ID
MemberFuncId:
ClassType: 4100
FunctionType: 4103
Name: Foo
- Name: '.debug$H'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: C5C93301000000009E56666824DC4B12E25261D4E09E6E9DA0F4EE31FDEC3D2D96287486127C66070B248ED52E421F55074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E99E616EF06A14EA74A2420F9062A1FB04917E5975E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D894CEAE81AEF8680D723D403D9A4481F0E28683A98
GlobalHashes:
Version: 0
HashAlgorithm: 0
HashValues:
- 9E56666824DC4B12E25261D4E09E6E9DA0F4EE31
- FDEC3D2D96287486127C66070B248ED52E421F55
- 074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84
- BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E9
- 9E616EF06A14EA74A2420F9062A1FB04917E5975
- E3A50EABE5E8FE3945468547C19DC681D0BFB3B7
- 97DD91CA4D7F1953C314442D5549419E78044E38
- A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0
- C0A9021B711ACC4F67008974EBF441031BDD653F
- 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA
- 0AF6C1846743F43D846BB19517E12E8873BBA90C
- C41DD1BEAC89CBA8897AC1BA46762E2557A82D89
- 4CEAE81AEF8680D723D403D9A4481F0E28683A98
- Name: '.debug$S'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: 04000000F500000064000000000000000000000020000000000000000400000000000000520000000600000004000000010000001F0000000000000004000000000000007F0000000500040000000000030000001D000000000000000400000000000000BD0000000300040000000000F10000007B000000320047110000000000000000000000002000000000000000000000000C100000000000000000004E533A3A466F6F3A3A466F6F000D003E1105100000010074686973001200451116000000FCFFFFFF0F000000000011000A003E1174000000010078001200451116000000080000000F0000000000110002004F1100F2000000200000000000000000000000200000001800000001000000140000000000000003000000
Subsections:
- !FrameData
Frames:
- CodeSize: 32
FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 4
PrologSize: 6
RvaStart: 0
SavedRegsSize: 0
- CodeSize: 31
FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 4
PrologSize: 5
RvaStart: 1
SavedRegsSize: 4
- CodeSize: 29
FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 4
PrologSize: 3
RvaStart: 3
SavedRegsSize: 4
- !Symbols
Records:
- Kind: S_GPROC32_ID
ProcSym:
CodeSize: 32
DbgStart: 0
DbgEnd: 0
FunctionType: 4108
Flags: [ ]
DisplayName: 'NS::Foo::Foo'
- Kind: S_LOCAL
LocalSym:
Type: 4101
Flags: [ IsParameter ]
VarName: this
- Kind: S_DEFRANGE_REGISTER_REL
DefRangeRegisterRelSym:
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: x
- Kind: S_DEFRANGE_REGISTER_REL
DefRangeRegisterRelSym:
- Kind: S_PROC_ID_END
ScopeEndSym:
- !Lines
CodeSize: 32
Flags: [ ]
RelocOffset: 0
RelocSegment: 0
Blocks:
- FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h'
Lines:
- Offset: 0
LineStart: 3
IsStatement: false
EndDelta: 0
Columns:
Relocations:
- VirtualAddress: 12
SymbolName: '??0Foo@NS@@QAE@H@Z'
Type: IMAGE_REL_I386_DIR32NB
- VirtualAddress: 152
SymbolName: '??0Foo@NS@@QAE@H@Z'
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 156
SymbolName: '??0Foo@NS@@QAE@H@Z'
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 199
SymbolName: .text
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 203
SymbolName: .text
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 231
SymbolName: .text
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 235
SymbolName: .text
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 252
SymbolName: '??0Foo@NS@@QAE@H@Z'
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 256
SymbolName: '??0Foo@NS@@QAE@H@Z'
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: 65
NumberOfRelocations: 2
NumberOfLinenumbers: 0
CheckSum: 4176946275
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: 0
NumberOfRelocations: 0
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: 0
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: 32
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 1438182552
Number: 4
Selection: IMAGE_COMDAT_SELECT_ANY
- Name: '??0Foo@NS@@QAE@H@Z'
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: .drectve
Value: 0
SectionNumber: 5
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: 5
- Name: '.debug$S'
Value: 0
SectionNumber: 6
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 832
NumberOfRelocations: 11
NumberOfLinenumbers: 0
CheckSum: 4106171226
Number: 6
- Name: '.debug$S'
Value: 0
SectionNumber: 9
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 284
NumberOfRelocations: 9
NumberOfLinenumbers: 0
CheckSum: 1378739251
Number: 4
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
- Name: '.debug$T'
Value: 0
SectionNumber: 7
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 316
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 3343977630
Number: 7
- Name: '.debug$H'
Value: 0
SectionNumber: 8
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 268
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 3965031229
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: _main
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: '?func@NS@@YAHABUFoo@1@@Z'
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...

View File

@ -0,0 +1,321 @@
--- !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: 5589E5508B45088B4D088B09C1E1018945FC89C883C4045DC3
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ''
- Name: .bss
Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ''
- 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: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000
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 '
- !FrameData
Frames:
- CodeSize: 25
FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 4
PrologSize: 4
RvaStart: 0
SavedRegsSize: 0
- CodeSize: 24
FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 4
PrologSize: 3
RvaStart: 1
SavedRegsSize: 4
- CodeSize: 22
FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 4
PrologSize: 1
RvaStart: 3
SavedRegsSize: 4
- !Symbols
Records:
- Kind: S_GPROC32_ID
ProcSym:
CodeSize: 25
DbgStart: 0
DbgEnd: 0
FunctionType: 4109
Flags: [ ]
DisplayName: 'NS::func'
- Kind: S_LOCAL
LocalSym:
Type: 4099
Flags: [ IsParameter ]
VarName: f
- Kind: S_DEFRANGE_REGISTER_REL
DefRangeRegisterRelSym:
- Kind: S_PROC_ID_END
ScopeEndSym:
- !Lines
CodeSize: 25
Flags: [ ]
RelocOffset: 0
RelocSegment: 0
Blocks:
- FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
Lines:
- Offset: 0
LineStart: 3
IsStatement: false
EndDelta: 0
- Offset: 7
LineStart: 4
IsStatement: false
EndDelta: 0
Columns:
- !Symbols
Records:
- Kind: S_UDT
UDTSym:
Type: 4106
UDTName: 'NS::Foo'
- !FileChecksums
Checksums:
- FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
Kind: MD5
Checksum: 59DFAC75D18675AED1AD169FE316317E
- !StringTable
Strings:
- 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
- '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
- '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
- '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
- ''
Relocations:
- VirtualAddress: 68
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
Type: IMAGE_REL_I386_DIR32NB
- VirtualAddress: 208
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 212
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 248
SymbolName: .text
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 252
SymbolName: .text
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 268
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 272
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
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: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1
Types:
- Kind: LF_STRING_ID
StringId:
Id: 0
String: NS
- Kind: LF_STRUCTURE
Class:
MemberCount: 0
Options: [ None, ForwardReference, HasUniqueName ]
FieldList: 0
Name: 'NS::Foo'
UniqueName: '.?AUFoo@NS@@'
DerivationList: 0
VTableShape: 0
Size: 0
- Kind: LF_MODIFIER
Modifier:
ModifiedType: 4097
Modifiers: [ None, Const ]
- Kind: LF_POINTER
Pointer:
ReferentType: 4098
Attrs: 32810
- Kind: LF_ARGLIST
ArgList:
ArgIndices: [ 4099 ]
- Kind: LF_PROCEDURE
Procedure:
ReturnType: 116
CallConv: NearC
Options: [ None ]
ParameterCount: 1
ArgumentList: 4100
- Kind: LF_POINTER
Pointer:
ReferentType: 4097
Attrs: 32778
- Kind: LF_ARGLIST
ArgList:
ArgIndices: [ 116 ]
- Kind: LF_MFUNCTION
MemberFunction:
ReturnType: 3
ClassType: 4097
ThisType: 4102
CallConv: ThisCall
Options: [ None ]
ParameterCount: 1
ArgumentList: 4103
ThisPointerAdjustment: 0
- Kind: LF_FIELDLIST
FieldList:
- Kind: LF_MEMBER
DataMember:
Attrs: 3
Type: 116
FieldOffset: 0
Name: X
- Kind: LF_ONEMETHOD
OneMethod:
Type: 4104
Attrs: 3
VFTableOffset: -1
Name: Foo
- Kind: LF_STRUCTURE
Class:
MemberCount: 2
Options: [ None, HasUniqueName ]
FieldList: 4105
Name: 'NS::Foo'
UniqueName: '.?AUFoo@NS@@'
DerivationList: 0
VTableShape: 0
Size: 4
- Kind: LF_STRING_ID
StringId:
Id: 0
String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h'
- Kind: LF_UDT_SRC_LINE
UdtSourceLine:
UDT: 4106
SourceFile: 4107
LineNumber: 2
- Kind: LF_FUNC_ID
FuncId:
ParentScope: 4096
FunctionType: 4101
Name: func
symbols:
- Name: .text
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 25
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 1820185021
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: 0
NumberOfRelocations: 0
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: 0
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 3
- Name: .drectve
Value: 0
SectionNumber: 4
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: 4
- Name: '.debug$S'
Value: 0
SectionNumber: 5
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 584
NumberOfRelocations: 7
NumberOfLinenumbers: 0
CheckSum: 2847177244
Number: 5
- Name: '.debug$T'
Value: 0
SectionNumber: 6
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 320
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 2684556216
Number: 6
- Name: '@feat.00'
Value: 1
SectionNumber: -1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: '?func@NS@@YAHABUFoo@1@@Z'
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...

View File

@ -0,0 +1,355 @@
--- !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: 5589E5508B45088B4D088B09C1E1018945FC89C883C4045DC3
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ''
- Name: .bss
Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ''
- 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: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000
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 '
- !FrameData
Frames:
- CodeSize: 25
FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 4
PrologSize: 4
RvaStart: 0
SavedRegsSize: 0
- CodeSize: 24
FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 4
PrologSize: 3
RvaStart: 1
SavedRegsSize: 4
- CodeSize: 22
FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
LocalSize: 0
MaxStackSize: 0
ParamsSize: 4
PrologSize: 1
RvaStart: 3
SavedRegsSize: 4
- !Symbols
Records:
- Kind: S_GPROC32_ID
ProcSym:
CodeSize: 25
DbgStart: 0
DbgEnd: 0
FunctionType: 4109
Flags: [ ]
DisplayName: 'NS::func'
- Kind: S_LOCAL
LocalSym:
Type: 4099
Flags: [ IsParameter ]
VarName: f
- Kind: S_DEFRANGE_REGISTER_REL
DefRangeRegisterRelSym:
- Kind: S_PROC_ID_END
ScopeEndSym:
- !Lines
CodeSize: 25
Flags: [ ]
RelocOffset: 0
RelocSegment: 0
Blocks:
- FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
Lines:
- Offset: 0
LineStart: 3
IsStatement: false
EndDelta: 0
- Offset: 7
LineStart: 4
IsStatement: false
EndDelta: 0
Columns:
- !Symbols
Records:
- Kind: S_UDT
UDTSym:
Type: 4106
UDTName: 'NS::Foo'
- !FileChecksums
Checksums:
- FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
Kind: MD5
Checksum: 59DFAC75D18675AED1AD169FE316317E
- !StringTable
Strings:
- 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
- '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
- '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
- '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
- ''
Relocations:
- VirtualAddress: 68
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
Type: IMAGE_REL_I386_DIR32NB
- VirtualAddress: 208
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 212
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 248
SymbolName: .text
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 252
SymbolName: .text
Type: IMAGE_REL_I386_SECTION
- VirtualAddress: 268
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
Type: IMAGE_REL_I386_SECREL
- VirtualAddress: 272
SymbolName: '?func@NS@@YAHABUFoo@1@@Z'
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: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1
Types:
- Kind: LF_STRING_ID
StringId:
Id: 0
String: NS
- Kind: LF_STRUCTURE
Class:
MemberCount: 0
Options: [ None, ForwardReference, HasUniqueName ]
FieldList: 0
Name: 'NS::Foo'
UniqueName: '.?AUFoo@NS@@'
DerivationList: 0
VTableShape: 0
Size: 0
- Kind: LF_MODIFIER
Modifier:
ModifiedType: 4097
Modifiers: [ None, Const ]
- Kind: LF_POINTER
Pointer:
ReferentType: 4098
Attrs: 32810
- Kind: LF_ARGLIST
ArgList:
ArgIndices: [ 4099 ]
- Kind: LF_PROCEDURE
Procedure:
ReturnType: 116
CallConv: NearC
Options: [ None ]
ParameterCount: 1
ArgumentList: 4100
- Kind: LF_POINTER
Pointer:
ReferentType: 4097
Attrs: 32778
- Kind: LF_ARGLIST
ArgList:
ArgIndices: [ 116 ]
- Kind: LF_MFUNCTION
MemberFunction:
ReturnType: 3
ClassType: 4097
ThisType: 4102
CallConv: ThisCall
Options: [ None ]
ParameterCount: 1
ArgumentList: 4103
ThisPointerAdjustment: 0
- Kind: LF_FIELDLIST
FieldList:
- Kind: LF_MEMBER
DataMember:
Attrs: 3
Type: 116
FieldOffset: 0
Name: X
- Kind: LF_ONEMETHOD
OneMethod:
Type: 4104
Attrs: 3
VFTableOffset: -1
Name: Foo
- Kind: LF_STRUCTURE
Class:
MemberCount: 2
Options: [ None, HasUniqueName ]
FieldList: 4105
Name: 'NS::Foo'
UniqueName: '.?AUFoo@NS@@'
DerivationList: 0
VTableShape: 0
Size: 4
- Kind: LF_STRING_ID
StringId:
Id: 0
String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h'
- Kind: LF_UDT_SRC_LINE
UdtSourceLine:
UDT: 4106
SourceFile: 4107
LineNumber: 2
- Kind: LF_FUNC_ID
FuncId:
ParentScope: 4096
FunctionType: 4101
Name: func
- Name: '.debug$H'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: C5C9330100000000EC145CD76AEFE74E78880D531132B3BB8FFACEF79E616EF06A14EA74A2420F9062A1FB04917E59759949E334BA18509ED692F3C65CE242D8450EBC78B81B63AF8316DC324562EB9F0D4A0D708E8A25C263DB05943C19B84A36719E1E414DDA3EDBDF005322238D70F9058EEDC5C50EF11BC849618B51FD89E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D89DCBC783AF285D9DBB672F67A81E36906B2038B57
GlobalHashes:
Version: 0
HashAlgorithm: 0
HashValues:
- EC145CD76AEFE74E78880D531132B3BB8FFACEF7
- 9E616EF06A14EA74A2420F9062A1FB04917E5975
- 9949E334BA18509ED692F3C65CE242D8450EBC78
- B81B63AF8316DC324562EB9F0D4A0D708E8A25C2
- 63DB05943C19B84A36719E1E414DDA3EDBDF0053
- 22238D70F9058EEDC5C50EF11BC849618B51FD89
- E3A50EABE5E8FE3945468547C19DC681D0BFB3B7
- 97DD91CA4D7F1953C314442D5549419E78044E38
- A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0
- C0A9021B711ACC4F67008974EBF441031BDD653F
- 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA
- 0AF6C1846743F43D846BB19517E12E8873BBA90C
- C41DD1BEAC89CBA8897AC1BA46762E2557A82D89
- DCBC783AF285D9DBB672F67A81E36906B2038B57
symbols:
- Name: .text
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 25
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 1820185021
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: 0
NumberOfRelocations: 0
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: 0
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 3
- Name: .drectve
Value: 0
SectionNumber: 4
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: 4
- Name: '.debug$S'
Value: 0
SectionNumber: 5
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 584
NumberOfRelocations: 7
NumberOfLinenumbers: 0
CheckSum: 2847177244
Number: 5
- Name: '.debug$T'
Value: 0
SectionNumber: 6
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 320
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 2684556216
Number: 6
- Name: '.debug$H'
Value: 0
SectionNumber: 7
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 288
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 2348181452
Number: 7
- Name: '@feat.00'
Value: 1
SectionNumber: -1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: '?func@NS@@YAHABUFoo@1@@Z'
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...

View File

@ -0,0 +1,93 @@
RUN: yaml2obj %p/Inputs/pdb-hashes-1.yaml > %t.1.obj
RUN: yaml2obj %p/Inputs/pdb-hashes-2.yaml > %t.2.obj
RUN: yaml2obj %p/Inputs/pdb-hashes-2-missing.yaml > %t.2.missing.obj
RUN: lld-link /debug %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.nohash.pdb
RUN: lld-link /debug:ghash %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.hash.pdb
RUN: lld-link /debug:ghash %t.1.obj %t.2.missing.obj /entry:main /nodefaultlib /PDB:%t.mixed.pdb
RUN: llvm-pdbutil dump -types -ids %t.nohash.pdb | FileCheck %s
RUN: llvm-pdbutil dump -types -ids %t.hash.pdb | FileCheck %s
RUN: llvm-pdbutil dump -types -ids %t.mixed.pdb | FileCheck %s
; These object files were generated via the following inputs and commands:
; ----------------------------------------------
; // obj.h
; namespace NS {
; struct Foo {
; explicit Foo(int x) : X(x) {}
; int X;
; };
;
; int func(const Foo &f);
; }
; ----------------------------------------------
; // obj1.cpp
; #include "obj.h"
;
; int main(int argc, char **argv) {
; NS::Foo f(argc);
; return NS::func(f);
; }
; ----------------------------------------------
; // obj2.cpp
; #include "obj.h"
;
; int NS::func(const Foo &f) {
; return 2 * f.X;
; }
; ----------------------------------------------
; $ clang-cl /Z7 /GS- obj1.cpp /c /o obj1.obj
; $ clang-cl /Z7 /GS- obj2.cpp /c /o obj2.obj
CHECK: Types (TPI Stream)
CHECK-NEXT: ============================================================
CHECK-NEXT: Showing 13 records
CHECK-NEXT: 0x1000 | LF_POINTER [size = 12]
CHECK-NEXT: referent = 0x0470 (char*), mode = pointer, opts = None, kind = ptr32
CHECK-NEXT: 0x1001 | LF_ARGLIST [size = 16]
CHECK-NEXT: 0x0074 (int): `int`
CHECK-NEXT: 0x1000: `char**`
CHECK-NEXT: 0x1002 | LF_PROCEDURE [size = 16]
CHECK-NEXT: return type = 0x0074 (int), # args = 2, param list = 0x1001
CHECK-NEXT: calling conv = cdecl, options = None
CHECK-NEXT: 0x1003 | LF_STRUCTURE [size = 44] `NS::Foo`
CHECK-NEXT: unique name: `.?AUFoo@NS@@`
CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: <no type>
CHECK-NEXT: options: forward ref | has unique name
CHECK-NEXT: 0x1004 | LF_POINTER [size = 12]
CHECK-NEXT: referent = 0x1003, mode = pointer, opts = None, kind = ptr32
CHECK-NEXT: 0x1005 | LF_ARGLIST [size = 12]
CHECK-NEXT: 0x0074 (int): `int`
CHECK-NEXT: 0x1006 | LF_MFUNCTION [size = 28]
CHECK-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x1005
CHECK-NEXT: class type = 0x1003, this type = 0x1004, this adjust = 0
CHECK-NEXT: calling conv = thiscall, options = None
CHECK-NEXT: 0x1007 | LF_FIELDLIST [size = 28]
CHECK-NEXT: - LF_MEMBER [name = `X`, Type = 0x0074 (int), offset = 0, attrs = public]
CHECK-NEXT: - LF_ONEMETHOD [name = `Foo`]
CHECK-NEXT: type = 0x1006, vftable offset = -1, attrs = public
CHECK-NEXT: 0x1008 | LF_STRUCTURE [size = 44] `NS::Foo`
CHECK-NEXT: unique name: `.?AUFoo@NS@@`
CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: 0x1007
CHECK-NEXT: options: has unique name
CHECK-NEXT: 0x1009 | LF_MODIFIER [size = 12]
CHECK-NEXT: referent = 0x1003, modifiers = const
CHECK-NEXT: 0x100A | LF_POINTER [size = 12]
CHECK-NEXT: referent = 0x1009, mode = ref, opts = None, kind = ptr32
CHECK-NEXT: 0x100B | LF_ARGLIST [size = 12]
CHECK-NEXT: 0x100A: `const NS::Foo&`
CHECK-NEXT: 0x100C | LF_PROCEDURE [size = 16]
CHECK-NEXT: return type = 0x0074 (int), # args = 1, param list = 0x100B
CHECK-NEXT: calling conv = cdecl, options = None
CHECK: Types (IPI Stream)
CHECK-NEXT: ============================================================
CHECK-NEXT: Showing 6 records
CHECK-NEXT: 0x1000 | LF_FUNC_ID [size = 20]
CHECK-NEXT: name = main, type = 0x1002, parent scope = <no type>
CHECK-NEXT: 0x1001 | LF_STRING_ID [size = 48] ID: <no type>, String: D:\src\llvmbuild\clang\Debug\x86\obj.h
CHECK-NEXT: 0x1002 | LF_UDT_SRC_LINE [size = 16]
CHECK-NEXT: udt = 0x1008, file = 4097, line = 2
CHECK-NEXT: 0x1003 | LF_MFUNC_ID [size = 16]
CHECK-NEXT: name = Foo, type = 0x1006, class type = 0x1003
CHECK-NEXT: 0x1004 | LF_STRING_ID [size = 12] ID: <no type>, String: NS
CHECK-NEXT: 0x1005 | LF_FUNC_ID [size = 20]
CHECK-NEXT: name = func, type = 0x100C, parent scope = 0x1004

View File

@ -88,18 +88,39 @@ struct GloballyHashedType {
ArrayRef<GloballyHashedType> PreviousTypes,
ArrayRef<GloballyHashedType> PreviousIds);
/// Given a sequence of bytes representing a record, compute a global hash for
/// this record. Due to the nature of global hashes incorporating the hashes
/// of referenced records, this function requires a list of types and ids
/// that RecordData might reference, indexable by TypeIndex.
static GloballyHashedType hashType(CVType Type,
ArrayRef<GloballyHashedType> PreviousTypes,
ArrayRef<GloballyHashedType> PreviousIds) {
return hashType(Type.RecordData, PreviousTypes, PreviousIds);
}
/// Given a sequence of combined type and ID records, compute global hashes
/// for each of them, returning the results in a vector of hashed types.
template <typename Range>
static std::vector<GloballyHashedType> hashTypes(Range &&Records) {
std::vector<GloballyHashedType> Hashes;
Hashes.reserve(std::distance(std::begin(Records), std::end(Records)));
for (const auto &R : Records)
Hashes.push_back(hashType(R, Hashes, Hashes));
return Hashes;
}
/// Given a sequence of combined type and ID records, compute global hashes
/// for each of them, returning the results in a vector of hashed types.
template <typename Range>
static std::vector<GloballyHashedType>
hashIds(Range &&Records, ArrayRef<GloballyHashedType> TypeHashes) {
std::vector<GloballyHashedType> IdHashes;
for (const auto &R : Records)
IdHashes.push_back(hashType(R, TypeHashes, IdHashes));
return IdHashes;
}
static std::vector<GloballyHashedType>
hashTypeCollection(TypeCollection &Types) {
std::vector<GloballyHashedType> Hashes;
@ -109,6 +130,11 @@ struct GloballyHashedType {
return Hashes;
}
};
static_assert(std::is_trivially_copyable<GloballyHashedType>::value,
"GloballyHashedType must be trivially copyable so that we can "
"reinterpret_cast arrays of hash data to arrays of "
"GloballyHashedType");
} // namespace codeview
template <> struct DenseMapInfo<codeview::LocallyHashedType> {

View File

@ -19,6 +19,8 @@ namespace llvm {
namespace codeview {
class TypeIndex;
struct GloballyHashedType;
class GlobalTypeTableBuilder;
class MergingTypeTableBuilder;
/// \brief Merge one set of type records into another. This method assumes
@ -83,6 +85,22 @@ Error mergeTypeAndIdRecords(MergingTypeTableBuilder &DestIds,
SmallVectorImpl<TypeIndex> &SourceToDest,
const CVTypeArray &IdsAndTypes);
Error mergeTypeAndIdRecords(GlobalTypeTableBuilder &DestIds,
GlobalTypeTableBuilder &DestTypes,
SmallVectorImpl<TypeIndex> &SourceToDest,
const CVTypeArray &IdsAndTypes,
ArrayRef<GloballyHashedType> Hashes);
Error mergeTypeRecords(GlobalTypeTableBuilder &Dest,
SmallVectorImpl<TypeIndex> &SourceToDest,
const CVTypeArray &Types,
ArrayRef<GloballyHashedType> Hashes);
Error mergeIdRecords(GlobalTypeTableBuilder &Dest, ArrayRef<TypeIndex> Types,
SmallVectorImpl<TypeIndex> &SourceToDest,
const CVTypeArray &Ids,
ArrayRef<GloballyHashedType> Hashes);
} // end namespace codeview
} // end namespace llvm

View File

@ -743,6 +743,12 @@ struct coff_resource_dir_table {
support::ulittle16_t NumberOfIDEntries;
};
struct debug_h_header {
support::ulittle32_t Magic;
support::ulittle16_t Version;
support::ulittle16_t HashAlgorithm;
};
class COFFObjectFile : public ObjectFile {
private:
friend class ImportDirectoryEntryRef;

View File

@ -54,7 +54,7 @@ GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
reinterpret_cast<const TypeIndex *>(RefData.data()), Ref.Count);
for (TypeIndex TI : Indices) {
ArrayRef<uint8_t> BytesToHash;
if (TI.isSimple() || TI.isNoneType()) {
if (TI.isSimple() || TI.isNoneType() || TI.toArrayIndex() >= Prev.size()) {
const uint8_t *IndexBytes = reinterpret_cast<const uint8_t *>(&TI);
BytesToHash = makeArrayRef(IndexBytes, sizeof(TypeIndex));
} else {

View File

@ -10,6 +10,7 @@
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
@ -62,6 +63,7 @@ public:
static const TypeIndex Untranslated;
// Local hashing entry points
Error mergeTypesAndIds(MergingTypeTableBuilder &DestIds,
MergingTypeTableBuilder &DestTypes,
const CVTypeArray &IdsAndTypes);
@ -71,6 +73,18 @@ public:
Error mergeTypeRecords(MergingTypeTableBuilder &Dest,
const CVTypeArray &Types);
// Global hashing entry points
Error mergeTypesAndIds(GlobalTypeTableBuilder &DestIds,
GlobalTypeTableBuilder &DestTypes,
const CVTypeArray &IdsAndTypes,
ArrayRef<GloballyHashedType> Hashes);
Error mergeIdRecords(GlobalTypeTableBuilder &Dest,
ArrayRef<TypeIndex> TypeSourceToDest,
const CVTypeArray &Ids,
ArrayRef<GloballyHashedType> Hashes);
Error mergeTypeRecords(GlobalTypeTableBuilder &Dest, const CVTypeArray &Types,
ArrayRef<GloballyHashedType> Hashes);
private:
Error doit(const CVTypeArray &Types);
@ -83,6 +97,14 @@ private:
bool remapTypeIndex(TypeIndex &Idx);
bool remapItemIndex(TypeIndex &Idx);
bool hasTypeStream() const {
return (UseGlobalHashes) ? (!!DestGlobalTypeStream) : (!!DestTypeStream);
}
bool hasIdStream() const {
return (UseGlobalHashes) ? (!!DestGlobalIdStream) : (!!DestIdStream);
}
ArrayRef<uint8_t> serializeRemapped(const RemappedType &Record);
bool remapIndices(RemappedType &Record, ArrayRef<TiReference> Refs);
@ -100,6 +122,8 @@ private:
Optional<Error> LastError;
bool UseGlobalHashes = false;
bool IsSecondPass = false;
unsigned NumBadIndices = 0;
@ -109,6 +133,11 @@ private:
MergingTypeTableBuilder *DestIdStream = nullptr;
MergingTypeTableBuilder *DestTypeStream = nullptr;
GlobalTypeTableBuilder *DestGlobalIdStream = nullptr;
GlobalTypeTableBuilder *DestGlobalTypeStream = nullptr;
ArrayRef<GloballyHashedType> GlobalHashes;
// If we're only mapping id records, this array contains the mapping for
// type records.
ArrayRef<TypeIndex> TypeLookup;
@ -209,7 +238,7 @@ bool TypeStreamMerger::remapTypeIndex(TypeIndex &Idx) {
// special mapping from OldTypeStream -> NewTypeStream which was computed
// externally. Regardless, we use this special map if and only if we are
// doing an id-only mapping.
if (DestTypeStream == nullptr)
if (!hasTypeStream())
return remapIndex(Idx, TypeLookup);
assert(TypeLookup.empty());
@ -217,13 +246,15 @@ bool TypeStreamMerger::remapTypeIndex(TypeIndex &Idx) {
}
bool TypeStreamMerger::remapItemIndex(TypeIndex &Idx) {
assert(DestIdStream);
assert(hasIdStream());
return remapIndex(Idx, IndexMap);
}
// Local hashing entry points
Error TypeStreamMerger::mergeTypeRecords(MergingTypeTableBuilder &Dest,
const CVTypeArray &Types) {
DestTypeStream = &Dest;
UseGlobalHashes = false;
return doit(Types);
}
@ -233,6 +264,7 @@ Error TypeStreamMerger::mergeIdRecords(MergingTypeTableBuilder &Dest,
const CVTypeArray &Ids) {
DestIdStream = &Dest;
TypeLookup = TypeSourceToDest;
UseGlobalHashes = false;
return doit(Ids);
}
@ -242,6 +274,41 @@ Error TypeStreamMerger::mergeTypesAndIds(MergingTypeTableBuilder &DestIds,
const CVTypeArray &IdsAndTypes) {
DestIdStream = &DestIds;
DestTypeStream = &DestTypes;
UseGlobalHashes = false;
return doit(IdsAndTypes);
}
// Global hashing entry points
Error TypeStreamMerger::mergeTypeRecords(GlobalTypeTableBuilder &Dest,
const CVTypeArray &Types,
ArrayRef<GloballyHashedType> Hashes) {
DestGlobalTypeStream = &Dest;
UseGlobalHashes = true;
GlobalHashes = Hashes;
return doit(Types);
}
Error TypeStreamMerger::mergeIdRecords(GlobalTypeTableBuilder &Dest,
ArrayRef<TypeIndex> TypeSourceToDest,
const CVTypeArray &Ids,
ArrayRef<GloballyHashedType> Hashes) {
DestGlobalIdStream = &Dest;
TypeLookup = TypeSourceToDest;
UseGlobalHashes = true;
GlobalHashes = Hashes;
return doit(Ids);
}
Error TypeStreamMerger::mergeTypesAndIds(GlobalTypeTableBuilder &DestIds,
GlobalTypeTableBuilder &DestTypes,
const CVTypeArray &IdsAndTypes,
ArrayRef<GloballyHashedType> Hashes) {
DestGlobalIdStream = &DestIds;
DestGlobalTypeStream = &DestTypes;
UseGlobalHashes = true;
GlobalHashes = Hashes;
return doit(IdsAndTypes);
}
@ -286,18 +353,29 @@ Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) {
}
Error TypeStreamMerger::remapType(const CVType &Type) {
MergingTypeTableBuilder &Dest =
isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;
RemappedType R(Type);
SmallVector<TiReference, 32> Refs;
discoverTypeIndices(Type.RecordData, Refs);
bool MappedAllIndices = remapIndices(R, Refs);
ArrayRef<uint8_t> Data = serializeRemapped(R);
auto DoSerialize = [this, Type]() -> ArrayRef<uint8_t> {
RemappedType R(Type);
SmallVector<TiReference, 32> Refs;
discoverTypeIndices(Type.RecordData, Refs);
if (!remapIndices(R, Refs))
return {};
return serializeRemapped(R);
};
TypeIndex DestIdx = Untranslated;
if (MappedAllIndices)
DestIdx = Dest.insertRecordBytes(Data);
if (UseGlobalHashes) {
GlobalTypeTableBuilder &Dest =
isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream;
GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()];
DestIdx = Dest.insertRecordAs(H, DoSerialize);
} else {
MergingTypeTableBuilder &Dest =
isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;
auto Data = DoSerialize();
if (!Data.empty())
DestIdx = Dest.insertRecordBytes(Data);
}
addMapping(DestIdx);
++CurIndex;
@ -350,3 +428,28 @@ Error llvm::codeview::mergeTypeAndIdRecords(
TypeStreamMerger M(SourceToDest);
return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes);
}
Error llvm::codeview::mergeTypeAndIdRecords(
GlobalTypeTableBuilder &DestIds, GlobalTypeTableBuilder &DestTypes,
SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes,
ArrayRef<GloballyHashedType> Hashes) {
TypeStreamMerger M(SourceToDest);
return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, Hashes);
}
Error llvm::codeview::mergeTypeRecords(GlobalTypeTableBuilder &Dest,
SmallVectorImpl<TypeIndex> &SourceToDest,
const CVTypeArray &Types,
ArrayRef<GloballyHashedType> Hashes) {
TypeStreamMerger M(SourceToDest);
return M.mergeTypeRecords(Dest, Types, Hashes);
}
Error llvm::codeview::mergeIdRecords(GlobalTypeTableBuilder &Dest,
ArrayRef<TypeIndex> Types,
SmallVectorImpl<TypeIndex> &SourceToDest,
const CVTypeArray &Ids,
ArrayRef<GloballyHashedType> Hashes) {
TypeStreamMerger M(SourceToDest);
return M.mergeIdRecords(Dest, Types, Ids, Hashes);
}