mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 04:06:46 +00:00

The loader can usually handle an unaligned import dir chunk, but It's not optimal and it's not what MSVC link.exe does. Windows refuses to load ARM64X binaries with unaligned import directory. aarch64 and arm64ec imports are shared in such binaries as much as possible. As long as they use the same set of functions from given import directory, both the directory and import addresses chunk are just shared. When used set of functions differs, ARM64X dynamic relocations are used to modify import dir to point to different names and import addresses for its EC view. I suspect that the loader expects some alignment on ARM64X dynamic relocation offset and may not be the case when relocated import dir is not aligned.
187 lines
10 KiB
Plaintext
187 lines
10 KiB
Plaintext
Make a DLL that exports a few functions, then make a DLL with PDBs that imports
|
|
them. Check that the __imp_ pointer and the generated thunks appear in the
|
|
publics stream.
|
|
|
|
RUN: yaml2obj %p/Inputs/export.yaml -o %t1.obj
|
|
RUN: lld-link /out:%t1.dll /dll %t1.obj /implib:%t1.lib \
|
|
RUN: /export:exportfn1 /export:exportfn2
|
|
RUN: yaml2obj %p/Inputs/import.yaml -o %t2.obj
|
|
RUN: lld-link /out:%t2.exe /pdb:%t2.pdb /pdbaltpath:test.pdb \
|
|
RUN: /debug /entry:main %t2.obj %t1.lib
|
|
RUN: llvm-pdbutil dump %t2.pdb -all | FileCheck %s
|
|
|
|
CHECK: Streams
|
|
CHECK-NEXT: ============================================================
|
|
CHECK-LABEL: Stream 10 ( 256 bytes): [Module "Import:pdb-publics-import.test.tmp1.dll"]
|
|
|
|
CHECK: Module Stats
|
|
CHECK-NEXT: ============================================================
|
|
CHECK-NEXT: Mod 0000 | `{{.*}}pdb-publics-import.test.tmp2.obj`:
|
|
CHECK-NEXT: Mod 0 (debug info not present): [{{.*}}pdb-publics-import.test.tmp2.obj]
|
|
CHECK-NEXT: Mod 0001 | `pdb-publics-import.test.tmp1.dll`:
|
|
CHECK-NEXT: Mod 1 (debug info not present): [pdb-publics-import.test.tmp1.dll]
|
|
CHECK-NEXT: Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`:
|
|
CHECK-NEXT: Stream 10, 256 bytes
|
|
|
|
CHECK: Modules
|
|
CHECK-NEXT: ============================================================
|
|
CHECK-NEXT: Mod 0000 | `{{.*}}pdb-publics-import.test.tmp2.obj`:
|
|
CHECK-NEXT: SC[.text] | mod = 0, 0001:0000, size = 8, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_EXECUTE |
|
|
CHECK-NEXT: IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: Obj: `{{.*}}pdb-publics-import.test.tmp2.obj`:
|
|
CHECK-NEXT: debug stream: 65535, # files: 0, has ec info: false
|
|
CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
|
|
CHECK-NEXT: Mod 0001 | `pdb-publics-import.test.tmp1.dll`:
|
|
CHECK-NEXT: SC[???] | mod = 65535, 65535:0000, size = -1, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: none
|
|
CHECK-NEXT: Obj: `{{.*}}pdb-publics-import.test.tmp1.lib`:
|
|
CHECK-NEXT: debug stream: 65535, # files: 0, has ec info: false
|
|
CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
|
|
CHECK-NEXT: Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`:
|
|
CHECK-NEXT: SC[.text] | mod = 2, 0001:0032, size = 6, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: Obj: `{{.*}}pdb-publics-import.test.tmp1.lib`:
|
|
CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false
|
|
CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
|
|
CHECK-NEXT: Mod 0003 | `* Linker *`:
|
|
CHECK-NEXT: SC[???] | mod = 65535, 65535:0000, size = -1, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: none
|
|
CHECK-NEXT: Obj: ``:
|
|
CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false
|
|
CHECK-NEXT: pdb file ni: 1 `{{.*}}pdb-publics-import.test.tmp2.pdb`, src file ni: 0 ``
|
|
|
|
CHECK: Public Symbols
|
|
CHECK-NEXT: ============================================================
|
|
CHECK-NEXT: Records
|
|
CHECK-NEXT: 112 | S_PUB32 [size = 20] `main`
|
|
CHECK-NEXT: flags = function, addr = 0001:0000
|
|
CHECK-NEXT: 64 | S_PUB32 [size = 24] `exportfn1`
|
|
CHECK-NEXT: flags = function, addr = 0001:0016
|
|
CHECK-NEXT: 88 | S_PUB32 [size = 24] `exportfn2`
|
|
CHECK-NEXT: flags = function, addr = 0001:0032
|
|
CHECK-NEXT: 32 | S_PUB32 [size = 32] `__imp_exportfn2`
|
|
CHECK-NEXT: flags = none, addr = 0002:0136
|
|
CHECK-NEXT: 0 | S_PUB32 [size = 32] `__imp_exportfn1`
|
|
CHECK-NEXT: flags = none, addr = 0002:0128
|
|
|
|
CHECK: Symbols
|
|
CHECK-NEXT: ============================================================
|
|
CHECK-NEXT: Mod 0000 | `{{.*}}pdb-publics-import.test.tmp2.obj`:
|
|
CHECK-NEXT: Error loading module stream 0. The specified stream could not be loaded. Module stream not present
|
|
CHECK-NEXT: Mod 0001 | `pdb-publics-import.test.tmp1.dll`:
|
|
CHECK-NEXT: Error loading module stream 1. The specified stream could not be loaded. Module stream not present
|
|
CHECK-NEXT: Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`:
|
|
CHECK-NEXT: 4 | S_OBJNAME [size = 44] sig=0, `pdb-publics-import.test.tmp1.dll`
|
|
CHECK-NEXT: 48 | S_COMPILE3 [size = 40]
|
|
CHECK-NEXT: machine = intel x86-x64, Ver = LLVM Linker, language = link
|
|
CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0
|
|
CHECK-NEXT: flags = none
|
|
CHECK-NEXT: 88 | S_THUNK32 [size = 36] `exportfn1`
|
|
CHECK-NEXT: parent = 0, end = 124, next = 0
|
|
CHECK-NEXT: kind = thunk, size = 6, addr = 0001:0016
|
|
CHECK-NEXT: 124 | S_END [size = 4]
|
|
CHECK-NEXT: 128 | S_OBJNAME [size = 44] sig=0, `pdb-publics-import.test.tmp1.dll`
|
|
CHECK-NEXT: 172 | S_COMPILE3 [size = 40]
|
|
CHECK-NEXT: machine = intel x86-x64, Ver = LLVM Linker, language = link
|
|
CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0
|
|
CHECK-NEXT: flags = none
|
|
CHECK-NEXT: 212 | S_THUNK32 [size = 36] `exportfn2`
|
|
CHECK-NEXT: parent = 0, end = 248, next = 0
|
|
CHECK-NEXT: kind = thunk, size = 6, addr = 0001:0032
|
|
CHECK-NEXT: 248 | S_END [size = 4]
|
|
CHECK-NEXT: Mod 0003 | `* Linker *`:
|
|
CHECK-NEXT: 4 | S_OBJNAME [size = 20] sig=0, `* Linker *`
|
|
CHECK-NEXT: 24 | S_COMPILE3 [size = 40]
|
|
CHECK-NEXT: machine = intel x86-x64, Ver = LLVM Linker, language = link
|
|
CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0
|
|
CHECK-NEXT: flags = none
|
|
CHECK-NEXT: 64 | S_ENVBLOCK [size = {{[0-9]+}}]
|
|
CHECK: {{[0-9]+}} | S_SECTION [size = 28] `.text`
|
|
CHECK-NEXT: length = 38, alignment = 12, rva = 4096, section # = 1
|
|
CHECK-NEXT: characteristics =
|
|
CHECK-NEXT: code
|
|
CHECK-NEXT: execute permissions
|
|
CHECK-NEXT: read permissions
|
|
CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 24] `.text`
|
|
CHECK-NEXT: length = 8, addr = 0001:0000
|
|
CHECK-NEXT: characteristics =
|
|
CHECK-NEXT: code
|
|
CHECK-NEXT: execute permissions
|
|
CHECK-NEXT: read permissions
|
|
CHECK-NEXT: {{[0-9]+}} | S_SECTION [size = 28] `.rdata`
|
|
CHECK-NEXT: length = 209, alignment = 12, rva = 8192, section # = 2
|
|
CHECK-NEXT: characteristics =
|
|
CHECK-NEXT: initialized data
|
|
CHECK-NEXT: read permissions
|
|
CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$2`
|
|
CHECK-NEXT: length = 40, addr = 0002:0064
|
|
CHECK-NEXT: characteristics =
|
|
CHECK-NEXT: initialized data
|
|
CHECK-NEXT: read permissions
|
|
CHECK-NEXT: write permissions
|
|
CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$4`
|
|
CHECK-NEXT: length = 24, addr = 0002:0104
|
|
CHECK-NEXT: characteristics =
|
|
CHECK-NEXT: initialized data
|
|
CHECK-NEXT: read permissions
|
|
CHECK-NEXT: write permissions
|
|
CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$5`
|
|
CHECK-NEXT: length = 24, addr = 0002:0128
|
|
CHECK-NEXT: characteristics =
|
|
CHECK-NEXT: initialized data
|
|
CHECK-NEXT: read permissions
|
|
CHECK-NEXT: write permissions
|
|
CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$6`
|
|
CHECK-NEXT: length = 24, addr = 0002:0152
|
|
CHECK-NEXT: characteristics =
|
|
CHECK-NEXT: initialized data
|
|
CHECK-NEXT: read permissions
|
|
CHECK-NEXT: write permissions
|
|
CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$7`
|
|
CHECK-NEXT: length = 33, addr = 0002:0176
|
|
CHECK-NEXT: characteristics =
|
|
CHECK-NEXT: initialized data
|
|
CHECK-NEXT: read permissions
|
|
CHECK-NEXT: write permissions
|
|
|
|
CHECK: Section Contributions
|
|
CHECK-NEXT: ============================================================
|
|
main
|
|
CHECK-NEXT: SC[.text] | mod = 0, 0001:0000, size = 8, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_EXECUTE |
|
|
CHECK-NEXT: IMAGE_SCN_MEM_READ
|
|
exportfn1 thunk
|
|
CHECK-NEXT: SC[.text] | mod = 3, 0001:0016, size = 6, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
|
|
exportfn2 thunk
|
|
CHECK-NEXT: SC[.text] | mod = 3, 0001:0032, size = 6, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
|
|
.rdata debug directory data chunks
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0000, size = 28, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0028, size = 33, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0064, size = 20, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0084, size = 20, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0104, size = 8, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0112, size = 8, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0120, size = 8, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0128, size = 8, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0136, size = 8, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0144, size = 8, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0152, size = 12, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0164, size = 12, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
|
CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0176, size = 33, data crc = 0, reloc crc = 0
|
|
CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|