Re: kallsyms failure: relative symbol value 0xffffffff810002a0 out of range in relative mode

From: Ard Biesheuvel
Date: Thu Mar 17 2016 - 11:07:11 EST


On 17 March 2016 at 12:17, Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> wrote:
> On 17 March 2016 at 12:01, Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> wrote:
>> On 17 March 2016 at 08:14, Markus Trippelsdorf <markus@xxxxxxxxxxxxxxx> wrote:
>>> On 2016.03.17 at 08:03 +0100, Ard Biesheuvel wrote:
>>>> On 16 March 2016 at 22:25, Markus Trippelsdorf <markus@xxxxxxxxxxxxxxx> wrote:
>>>> > Since:
>>>> > commit 2213e9a66bb87d8344a1256b4ef568220d9587fb
>>>> > Author: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx>
>>>> > Date: Tue Mar 15 14:58:19 2016 -0700
>>>> >
>>>> > kallsyms: add support for relative offsets in kallsyms address table
>>>> >
>>>> > kernels linked with ld.gold are broken:
>>>> >
>>>>
>>>> Could you elaborate? I tried building x86_64_defconfig with
>>>> -fuse-ld=gold added to LDFLAGS, and it builds fine.
>>>>
>>>> Could you share your config, please? And instructions how to invoke
>>>> the gold linker?
>>>
>>> I'm using gold trunk and ld.gold is my system linker (just a hard link
>>> to ld). My config is attached.
>>>
>>> (For testing I use the following qemu command:
>>> qemu-system-x86_64 -s -enable-kvm -net nic,vlan=0,model=virtio -net user -fsdev local,security_model=none,id=root,path=/ -device virtio-9p-pci,id=root,fsdev=root,mount_tag=/dev/root -m 512 -smp 2 -kernel /usr/src/linux/arch/x86/boot/bzImage -nographic -append "init=/bin/zsh root=/dev/root console=ttyS0 kgdboc=ttyS0 rootflags=rw,trans=virtio rootfstype=9p ip=dhcp earlyprintk=ttyS0" )
>>>
>>>> > KSYM .tmp_kallsyms1.o
>>>> > kallsyms failure: relative symbol value 0xffffffff810002a0 out of range in relative mode
>>>> > KSYM .tmp_kallsyms2.o
>>>> > kallsyms failure: relative symbol value 0xffffffff810002a0 out of range in relative mode
>>>> > LD vmlinux
>>>> >
>>>> > They die early during boot:
>>>> >
>>>>
>>>> Note that there is a patch queued in the kbuild tree to at least abort
>>>> the build if such failures happens.
>>>
>>> Yes. That would be much better.
>>>
>>
>> I tried building with your config, and I still cannot reproduce. I
>> using my system's GCC + GOLD:
>>
>> gold -v
>> GNU gold (GNU Binutils for Ubuntu 2.25.1) 1.11
>>
>> Using built-in specs.
>> COLLECT_GCC=gcc
>> COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
>> Target: x86_64-linux-gnu
>> Configured with: ../src/configure -v --with-pkgversion='Ubuntu
>> 5.2.1-22ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs
>> --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++
>> --prefix=/usr --program-suffix=-5 --enable-shared
>> --enable-linker-build-id --libexecdir=/usr/lib
>> --without-included-gettext --enable-threads=posix --libdir=/usr/lib
>> --enable-nls --with-sysroot=/ --enable-clocale=gnu
>> --enable-libstdcxx-debug --enable-libstdcxx-time=yes
>> --with-default-libstdcxx-abi=new --enable-gnu-unique-object
>> --disable-vtable-verify --enable-libmpx --enable-plugin
>> --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk
>> --enable-gtk-cairo
>> --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre
>> --enable-java-home
>> --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64
>> --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64
>> --with-arch-directory=amd64
>> --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc
>> --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64
>> --with-multilib-list=m32,m64,mx32 --enable-multilib
>> --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu
>> --host=x86_64-linux-gnu --target=x86_64-linux-gnu
>> Thread model: posix
>> gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu2)
>>
>> Can you reproduce it with a release version of GOLD?
>
> Actually, I managed to reproduce it by updating my system's
> /usr/bin/ld symlink to point to ld.gold.
>
> Looking into it now ...

The following patch fixes things for me:

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 5af9958cbdb6..aa7a0cbd1d2e 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -82,10 +82,10 @@ SECTIONS
{
#ifdef CONFIG_X86_32
. = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
- phys_startup_32 = startup_32 - LOAD_OFFSET;
+ phys_startup_32 = ABSOLUTE(startup_32 - LOAD_OFFSET);
#else
. = __START_KERNEL;
- phys_startup_64 = startup_64 - LOAD_OFFSET;
+ phys_startup_64 = ABSOLUTE(startup_64 - LOAD_OFFSET);
#endif

/* Text and read-only data */

The problem appears to be that GOLD emits a 'T' type symbol for
phys_startup_64, while ld.bfd treats this as an absolute quantity
(which kallsyms ignores).

Since this symbol has no meaning to the kernel itself when it runs
from its virtual offset, forcing it to absolute is probably the
simplest approach.

If anyone disagrees, let me know. Otherwise, I will fold this into a
proper patch and send it out tomorrow.

--
Ard.