This patch makes LLD generate a PDB with import modules & coff groups.
This is suitable for hot patching tools like Recode and Live++, which need to extract this information from the PDB. We're using this patch on several productions for a few months now.
We generate one debug symbol stream for each imported dll:
Streams ============================================================ [...] Stream 10 ( 256 bytes): [Module "Import:pdb-publics-import.test.tmp1.dll"] Blocks: [9]
We generate two modules for each imported dll:
(currently the first module is empty because llvm-lib does not generate the additional symbol stream, and some descriptors are not imported (remains TODO)
Module Stats ============================================================ [...] Mod 0001 | `pdb-publics-import.test.tmp1.dll`: Mod 1 (debug info not present): [pdb-publics-import.test.tmp1.dll] Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`: Stream 10, 256 bytes Symbols Total: 8 entries ( 248 bytes) -------------------------------------------------------------------------- S_THUNK32: 2 entries ( 72 bytes) S_END: 2 entries ( 8 bytes) S_OBJNAME: 2 entries ( 88 bytes) S_COMPILE3: 2 entries ( 80 bytes) Chunks Total: 0 entries ( 0 bytes) --------------------------------------------------------------------------
We ensure the modules' first contrib section is properly set (65535 values):
Modules ============================================================ [...] Mod 0001 | `pdb-publics-import.test.tmp1.dll`: SC[???] | mod = 65535, 65535:0000, size = -1, data crc = 0, reloc crc = 0 none Obj: `F:\svn\build2\tools\lld\test\COFF\Output\pdb-publics-import.test.tmp1.lib`: debug stream: 65535, # files: 0, has ec info: false pdb file ni: 0 ``, src file ni: 0 `` Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`: SC[.text] | mod = 2, 0001:0032, size = 6, data crc = 0, reloc crc = 0 IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ Obj: `F:\svn\build2\tools\lld\test\COFF\Output\pdb-publics-import.test.tmp1.lib`: debug stream: 10, # files: 0, has ec info: false pdb file ni: 0 ``, src file ni: 0 ``
We generate proper symbol streams for each import module, in the same way as link.exe:
Symbols ============================================================ [...] Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`: 4 | S_OBJNAME [size = 44] sig=0, `pdb-publics-import.test.tmp1.dll` 48 | S_COMPILE3 [size = 40] machine = intel x86-x64, Ver = LLVM Linker, language = link frontend = 0.0.0.0, backend = 14.10.25019.0 flags = none 88 | S_THUNK32 [size = 36] `exportfn1` parent = 0, end = 124, next = 0 kind = thunk, size = 6, addr = 0001:0016 124 | S_END [size = 4] 128 | S_OBJNAME [size = 44] sig=0, `pdb-publics-import.test.tmp1.dll` 172 | S_COMPILE3 [size = 40] machine = intel x86-x64, Ver = LLVM Linker, language = link frontend = 0.0.0.0, backend = 14.10.25019.0 flags = none 212 | S_THUNK32 [size = 36] `exportfn2` parent = 0, end = 248, next = 0 kind = thunk, size = 6, addr = 0001:0032 248 | S_END [size = 4]
And we also generate COFF groups in the * Linker * section, out from PartialSections (that is, unmerged sections).
(there's a subtly here: the .idata$XXX COFF groups have the "write" flag set, whereas the corresponding .idata section does not have it - this is what link.exe does)
Mod 0003 | `* Linker *`: [...] 588 | S_SECTION [size = 28] `.text` length = 38, alignment = 12, rva = 4096, section # = 1 characteristics = code execute permissions read permissions 616 | S_COFFGROUP [size = 24] `.text` length = 8, addr = 0001:0000 characteristics = code execute permissions read permissions 640 | S_SECTION [size = 28] `.rdata` length = 61, alignment = 12, rva = 8192, section # = 2 characteristics = initialized data read permissions 668 | S_SECTION [size = 28] `.idata` length = 145, alignment = 12, rva = 12288, section # = 3 characteristics = initialized data read permissions 696 | S_COFFGROUP [size = 28] `.idata$2` length = 40, addr = 0003:0000 characteristics = initialized data read permissions write permissions 724 | S_COFFGROUP [size = 28] `.idata$4` length = 24, addr = 0003:0040 characteristics = initialized data read permissions write permissions 752 | S_COFFGROUP [size = 28] `.idata$5` length = 24, addr = 0003:0064 characteristics = initialized data read permissions write permissions 780 | S_COFFGROUP [size = 28] `.idata$6` length = 24, addr = 0003:0088 characteristics = initialized data read permissions write permissions 808 | S_COFFGROUP [size = 28] `.idata$7` length = 33, addr = 0003:0112 characteristics = initialized data read permissions write permissions
Needs wrapping