Created attachment 9642 [details] testcase A Gentoo user reported an error when using gold to build Linux kernel with x32 enabled: markus@x4 testcase % gcc -fuse-ld=bfd -nostdlib -Wl,-m,elf32_x86_64 -Wl,-T,vdsox32.lds vclock_gettime-x32.o markus@x4 testcase % gcc -fuse-ld=gold -nostdlib -Wl,-m,elf32_x86_64 -Wl,-T,vdsox32.lds vclock_gettime-x32.o arch/x86/entry/vdso/vclock_gettime.c:246: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:240: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:241: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:230: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:231: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:213: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:212: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:170: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:214: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:216: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:192: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:191: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:170: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:193: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:195: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:148: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:178: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:179: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:148: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:178: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:179: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:275: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:192: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:191: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:170: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:193: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:195: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:281: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:282: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:148: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:178: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:179: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' arch/x86/entry/vdso/vclock_gettime.c:297: error: relocation overflow: reference to 'vvar_vsyscall_gtod_data' collect2: error: ld returned 1 exit status gold 2.26.1. was fine.
Created attachment 9644 [details] A patch Try this.
(In reply to H.J. Lu from comment #1) > Created attachment 9644 [details] > A patch > > Try this. Works fine. Thank you.
Technically, gold is correct to complain relocation overflow. But vvar_vsyscall_gtod_data is in vvar page which is placed before vdso page: 7fffe89d8000-7fffe89da000 r--p 00000000 00:00 0 [vvar] 7fffe89da000-7fffe89dc000 r-xp 00000000 00:00 0 [vdso] There is no good way to express it. ld happens to store the absolute value of 0xffffe080 as 0xffffffffffffe080.
Gold can implement -z noreloc-overflow to disable relocation overflow check and -z noreloc-overflow should be used to build vdso.
(In reply to H.J. Lu from comment #3) > Technically, gold is correct to complain relocation overflow. > But vvar_vsyscall_gtod_data is in vvar page which is placed before > vdso page: > > 7fffe89d8000-7fffe89da000 r--p 00000000 00:00 0 > [vvar] > 7fffe89da000-7fffe89dc000 r-xp 00000000 00:00 0 > [vdso] > > There is no good way to express it. ld happens to store the absolute > value of 0xffffe080 as 0xffffffffffffe080. HJ, is the patch you posted above intended for trunk? Or do you want instead a -z noreloc-overflow option?
(In reply to Cary Coutant from comment #5) > (In reply to H.J. Lu from comment #3) > > Technically, gold is correct to complain relocation overflow. > > But vvar_vsyscall_gtod_data is in vvar page which is placed before > > vdso page: > > > > 7fffe89d8000-7fffe89da000 r--p 00000000 00:00 0 > > [vvar] > > 7fffe89da000-7fffe89dc000 r-xp 00000000 00:00 0 > > [vdso] > > > > There is no good way to express it. ld happens to store the absolute > > value of 0xffffe080 as 0xffffffffffffe080. > > HJ, is the patch you posted above intended for trunk? Or do you want instead > a -z noreloc-overflow option? I prefer -z noreloc-overflow. I haven't decided if ld should issue an error for relocation overflow.
X32 uses 32-bit pointers in 64-bit address space. It can reach the full 64-bit address space: [hjl@gnu-6 far-3]$ cat x.c #include <stdio.h> extern int foo (long long); int main () { long long addr = 0xffffffffff600000LL; int x = foo (addr); printf ("0x%llx: %p\n", addr, x); return 0; } [hjl@gnu-6 far-3]$ cat foo.S .text .p2align 4,,15 .globl foo .type foo, @function foo: .LFB0: .cfi_startproc movl (%rdi), %eax ret .cfi_endproc .LFE0: .size foo, .-foo .section .note.GNU-stack,"",@progbits [hjl@gnu-6 far-3]$ gcc x.c foo.S -mx32 [hjl@gnu-6 far-3]$ ./a.out 0xffffffffff600000: 0x60c0c748 [hjl@gnu-6 far-3]$ 0xffffffffff600000 is mapped to vsyscall page, which is invisible to normal x32 application. In this sense, ld isn't wrong not to issue an error to access below 0 for both LP64 and ILP32.
*** Bug 21230 has been marked as a duplicate of this bug. ***
This still occurs with gold version 1.14 (binutils version 2.29.1). I noticed https://sourceware.org/ml/binutils/2016-03/msg00202.html has been committed, however "-z noreloc-overflow" is still not recognised as a valid option.