diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -661,6 +661,13 @@ toString(file)); continue; } + int addressSizeInBits = file->ctx.config.is64() ? 64 : 32; + if (sizeInBits < addressSizeInBits) { + warn("runtime pseudo relocation in " + toString(file) + " against " + + "symbol " + target->getName() + " is too narrow (only " + + Twine(sizeInBits) + " bits wide); this can fail at runtime " + + "depending on memory layout"); + } // sizeInBits is used to initialize the Flags field; currently no // other flags are defined. res.emplace_back(target, this, rel.VirtualAddress, sizeInBits); diff --git a/lld/test/CMakeLists.txt b/lld/test/CMakeLists.txt --- a/lld/test/CMakeLists.txt +++ b/lld/test/CMakeLists.txt @@ -51,6 +51,7 @@ llvm-config llvm-cvtres llvm-dis + llvm-dlltool llvm-dwarfdump llvm-lib llvm-lipo diff --git a/lld/test/COFF/autoimport-nowarn.s b/lld/test/COFF/autoimport-nowarn.s new file mode 100644 --- /dev/null +++ b/lld/test/COFF/autoimport-nowarn.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 + +# RUN: echo -e "EXPORTS\nvariable" > %t-lib.def +# RUN: llvm-dlltool -m i386 -d %t-lib.def -D lib.dll -l %t-lib.lib + +# RUN: llvm-mc -triple=i386-windows-gnu %s -filetype=obj -o %t.obj +# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose 2>&1 | FileCheck --allow-empty %s + +# CHECK-NOT: runtime pseudo relocation {{.*}} is too narrow + + .global _main + .text +_main: + movl _variable, %eax + ret + +relocs: + .long ___RUNTIME_PSEUDO_RELOC_LIST__ + .long ___RUNTIME_PSEUDO_RELOC_LIST_END__ diff --git a/lld/test/COFF/autoimport-warn.s b/lld/test/COFF/autoimport-warn.s new file mode 100644 --- /dev/null +++ b/lld/test/COFF/autoimport-warn.s @@ -0,0 +1,29 @@ +# REQUIRES: x86 + +# RUN: echo -e "EXPORTS\nvariable1 DATA\nvariable2 DATA" > %t-lib.def +# RUN: llvm-dlltool -m i386:x86-64 -d %t-lib.def -D lib.dll -l %t-lib.lib + +# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj +# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose 2>&1 | FileCheck %s + +# CHECK-NOT: runtime pseudo relocation {{.*}} against symbol variable1 +# 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 +# CHECK-NOT: runtime pseudo relocation {{.*}} against symbol variable1 + + .global main + .text +main: + movq .refptr.variable1(%rip), %rax + movl (%rax), %eax + movl variable2(%rip), %ecx + addl %ecx, %eax + ret + + .section .rdata$.refptr.variable1,"dr",discard,.refptr.variable1 + .global .refptr.variable1 +.refptr.variable1: + .quad variable1 + +relocs: + .quad __RUNTIME_PSEUDO_RELOC_LIST__ + .quad __RUNTIME_PSEUDO_RELOC_LIST_END__