Skip to content

Commit a169d4c

Browse files
authored
[LLD] [COFF] Error out if the runtime pseudo relocation function is missing (#88573)
When then linker creates runtime pseudo relocations, it places them in a list with the assumption that the runtime will fix these relocations later, when the image gets loaded. If the relevant runtime function doesn't seem to be present in the linked image, error out. Normally when linking the mingw-w64 runtime libraries, this function always is available. However, if linking without including the mingw-w64 CRT startup files, and the image needs runtime pseudo relocations, make it clear that this won't work as expected at runtime. With ld.bfd, this situation is a hard error too; ld.bfd adds an undefined reference to this symbol if runtime pseudo relocations are needed. A later alternative would be to actually try to pull in the symbol (if seen in a static library, but not included yet). This would allow decoupling the function from the main mingw-w64 CRT startup code (making it optional, only running if the linker actually produced runtime pseudo relocations). Doing that would require restructuring the lld code (gathering pseudo relocations earlier, then loading the relocator function, then pulling in more object files to satisfy the dependencies of the relocator) though. Also, ld.bfd doesn't currently successfully pull in more object files to satisfy the dependency on _pei386_runtime_relocator, so with that in mind, there's not much extra value in making LLD do it currently either; we can't make such a change in mingw-w64's CRT until both linkers handle it. This fixes one issue brought up in #84424.
1 parent 89071f3 commit a169d4c

File tree

7 files changed

+60
-1
lines changed

7 files changed

+60
-1
lines changed

lld/COFF/Writer.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2072,8 +2072,16 @@ void Writer::createRuntimePseudoRelocs() {
20722072
return;
20732073
}
20742074

2075-
if (!rels.empty())
2075+
if (!rels.empty()) {
20762076
log("Writing " + Twine(rels.size()) + " runtime pseudo relocations");
2077+
const char *symbolName = "_pei386_runtime_relocator";
2078+
Symbol *relocator = ctx.symtab.findUnderscore(symbolName);
2079+
if (!relocator)
2080+
error("output image has runtime pseudo relocations, but the function " +
2081+
Twine(symbolName) +
2082+
" is missing; it is needed for fixing the relocations at runtime");
2083+
}
2084+
20772085
PseudoRelocTableChunk *table = make<PseudoRelocTableChunk>(rels);
20782086
rdataSec->addChunk(table);
20792087
EmptyChunk *endOfList = make<EmptyChunk>();

lld/test/COFF/autoimport-arm-data.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
.text
3434
.thumb
3535
main:
36+
bx lr
37+
.global _pei386_runtime_relocator
38+
_pei386_runtime_relocator:
3639
bx lr
3740
.data
3841
ptr:

lld/test/COFF/autoimport-arm64-data.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
.global main
3434
.text
3535
main:
36+
ret
37+
.global _pei386_runtime_relocator
38+
_pei386_runtime_relocator:
3639
ret
3740
.data
3841
ptr:

lld/test/COFF/autoimport-gnu-implib.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,8 @@
2727
.text
2828
main:
2929
movl data(%rip), %eax
30+
ret
31+
.global _pei386_runtime_relocator
32+
_pei386_runtime_relocator:
3033
ret
3134
.data
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# REQUIRES: x86
2+
# RUN: split-file %s %t.dir
3+
4+
# RUN: llvm-dlltool -m i386:x86-64 -d %t.dir/lib.def -D lib.dll -l %t.dir/lib.lib
5+
6+
# RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/main.s -filetype=obj -o %t.dir/main.obj
7+
# RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/func.s -filetype=obj -o %t.dir/func.obj
8+
# RUN: env LLD_IN_TEST=1 not lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/lib.lib 2>&1 | FileCheck %s --check-prefix=ERR
9+
10+
# RUN: lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/func.obj %t.dir/lib.lib 2>&1 | FileCheck %s --check-prefix=NOERR --allow-empty
11+
12+
# ERR: error: output image has runtime pseudo relocations, but the function _pei386_runtime_relocator is missing; it is needed for fixing the relocations at runtime
13+
14+
# NOERR-NOT: error
15+
16+
#--- main.s
17+
.global main
18+
.text
19+
main:
20+
ret
21+
22+
.data
23+
.long 1
24+
.quad variable
25+
.long 2
26+
27+
#--- func.s
28+
.global _pei386_runtime_relocator
29+
.text
30+
_pei386_runtime_relocator:
31+
ret
32+
33+
#--- lib.def
34+
EXPORTS
35+
variable DATA
36+

lld/test/COFF/autoimport-warn.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ main:
1818
movl variable2(%rip), %ecx
1919
addl %ecx, %eax
2020
ret
21+
.global _pei386_runtime_relocator
22+
_pei386_runtime_relocator:
23+
ret
2124

2225
.section .rdata$.refptr.variable1,"dr",discard,.refptr.variable1
2326
.global .refptr.variable1

lld/test/COFF/autoimport-x86.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
.text
5656
main:
5757
movl variable(%rip), %eax
58+
ret
59+
.global _pei386_runtime_relocator
60+
_pei386_runtime_relocator:
5861
ret
5962
.data
6063
ptr:

0 commit comments

Comments
 (0)