Skip to content

Commit 6daa4b9

Browse files
committed
[LLD] [COFF] Warn about pseudo relocations that are too narrow
In 64 bit mode, any references to symbols that might end up autoimported must be made via full 64 bit pointers (usually in .refptr stubs generated by the compiler). If referenced via e.g. a 32 bit rip relative offset, it might work as long as DLLs are loaded close together in the 64 bit address space, but will fail surprisingly later if they happen to be loaded further apart. Any cases of that happening is usually a toolchain error, and the sooner we can warn about it, the easier it is to diagnose. Differential Revision: https://reviews.llvm.org/D154777
1 parent 1776dc8 commit 6daa4b9

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

lld/COFF/Chunks.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,13 @@ void SectionChunk::getRuntimePseudoRelocs(
661661
toString(file));
662662
continue;
663663
}
664+
int addressSizeInBits = file->ctx.config.is64() ? 64 : 32;
665+
if (sizeInBits < addressSizeInBits) {
666+
warn("runtime pseudo relocation in " + toString(file) + " against " +
667+
"symbol " + target->getName() + " is too narrow (only " +
668+
Twine(sizeInBits) + " bits wide); this can fail at runtime " +
669+
"depending on memory layout");
670+
}
664671
// sizeInBits is used to initialize the Flags field; currently no
665672
// other flags are defined.
666673
res.emplace_back(target, this, rel.VirtualAddress, sizeInBits);

lld/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ if (NOT LLD_BUILT_STANDALONE)
5151
llvm-config
5252
llvm-cvtres
5353
llvm-dis
54+
llvm-dlltool
5455
llvm-dwarfdump
5556
llvm-lib
5657
llvm-lipo

lld/test/COFF/autoimport-nowarn.s

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# REQUIRES: x86
2+
3+
# RUN: echo -e "EXPORTS\nvariable" > %t-lib.def
4+
# RUN: llvm-dlltool -m i386 -d %t-lib.def -D lib.dll -l %t-lib.lib
5+
6+
# RUN: llvm-mc -triple=i386-windows-gnu %s -filetype=obj -o %t.obj
7+
# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose 2>&1 | FileCheck --allow-empty %s
8+
9+
# CHECK-NOT: runtime pseudo relocation {{.*}} is too narrow
10+
11+
.global _main
12+
.text
13+
_main:
14+
movl _variable, %eax
15+
ret
16+
17+
relocs:
18+
.long ___RUNTIME_PSEUDO_RELOC_LIST__
19+
.long ___RUNTIME_PSEUDO_RELOC_LIST_END__

lld/test/COFF/autoimport-warn.s

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# REQUIRES: x86
2+
3+
# RUN: echo -e "EXPORTS\nvariable1 DATA\nvariable2 DATA" > %t-lib.def
4+
# RUN: llvm-dlltool -m i386:x86-64 -d %t-lib.def -D lib.dll -l %t-lib.lib
5+
6+
# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
7+
# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose 2>&1 | FileCheck %s
8+
9+
# CHECK-NOT: runtime pseudo relocation {{.*}} against symbol variable1
10+
# CHECK: warning: runtime pseudo relocation in {{.*}}.obj against symbol variable2 is too narrow (only 32 bits wide); this can fail at runtime depending on memory layout
11+
# CHECK-NOT: runtime pseudo relocation {{.*}} against symbol variable1
12+
13+
.global main
14+
.text
15+
main:
16+
movq .refptr.variable1(%rip), %rax
17+
movl (%rax), %eax
18+
movl variable2(%rip), %ecx
19+
addl %ecx, %eax
20+
ret
21+
22+
.section .rdata$.refptr.variable1,"dr",discard,.refptr.variable1
23+
.global .refptr.variable1
24+
.refptr.variable1:
25+
.quad variable1
26+
27+
relocs:
28+
.quad __RUNTIME_PSEUDO_RELOC_LIST__
29+
.quad __RUNTIME_PSEUDO_RELOC_LIST_END__

0 commit comments

Comments
 (0)