bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when lo


From: mintsuki at protonmail dot com
Subject: [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0
Date: Sun, 26 May 2024 14:23:36 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=31795

--- Comment #25 from mintsuki <mintsuki at protonmail dot com> ---
(In reply to H.J. Lu from comment #23)
> (In reply to mintsuki from comment #21)
> > (In reply to H.J. Lu from comment #20)
> > > It turns out that static PIE with non-zero load address must have ET_EXEC:
> > > 
> > > https://sourceware.org/bugzilla/show_bug.cgi?id=31799
> > > 
> > > Otherwise, there is no way for loader to tell if the dynamic section 
> > > entries
> > > contain the relocated values for the load address or not.  Since static 
> > > PIE
> > > with non-zero load address must have ET_EXEC, PIE with non-zero load 
> > > address
> > > also should have ET_EXEC.
> > > 
> > > BTW, gold doesn't support static PIE and static PIE with non-zero load
> > > address
> > > generated by lld crashes with the fix glibc.
> > 
> > At least in the context of making a kernel, gold does generate a static-pie,
> > at least as printed out by the file command, and the output of readelf -a
> > looks similar to ld.bfd's -static -pie generation, even without the -static
> > part.
> 
> [hjl@gnu-cfl-3 tmp]$ gcc -static-pie x.c 
> [hjl@gnu-cfl-3 tmp]$ gcc -static-pie x.c -fuse-ld=lld
> [hjl@gnu-cfl-3 tmp]$ gcc -static-pie x.c -fuse-ld=gold
> /usr/local/bin/ld.gold: --no-dynamic-linker: unknown option
> /usr/local/bin/ld.gold: use the --help option for usage information
> collect2: error: ld returned 1 exit status
> [hjl@gnu-cfl-3 tmp]$ 

This is not an issue if you call ld.gold manually as done by the kernel in
question (see above test case).

I know that "you should not invoke the linker outside the driver" and I do
agree, but I do make an exception for linking bare metal, freestanding stuff,
as I like to have more control over the linking process.

With that, I just didn't pass --no-dynamic-linker (as it is not supported by
gold, and the linker script makes it a non issue), and I didn't pass -static,
as frankly it seems to do nothing anyways when linking a -nostdlib -pie kernel,
and isn't supported by gold in combination with -pie.

Please once again see the test case above.

> 
> > I assume this is because no other dynamic libraries are linked in when using
> > -nostdlib and not specifying any dynamic library explicitly.
> > 
> > I do not know what the problem with glibc is, but static-pie kernels loaded
> > by Limine with a non-0 load address (or shared objects with a non-0 load
> > address for that matter) work perfectly fine if relocated (at or above
> > whatever specified non-0 load address).
> 
> Does your kernel have any dynamic tags which need relocation?
> 
> [hjl@gnu-cfl-3 tmp]$ readelf -d /bin/ld
> 
> Dynamic section at offset 0x11f4a8 contains 35 entries:
>   Tag        Type                         Name/Value
>  0x0000000000000001 (NEEDED)             Shared library:
> [libbfd-2.42.50.0.1.20240523.so]
>  0x0000000000000001 (NEEDED)             Shared library: [libctf.so.0]
>  0x0000000000000001 (NEEDED)             Shared library: [libjansson.so.4]
>  0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
>  0x000000000000000c (INIT)               0x6000
>  0x000000000000000d (FINI)               0x4e594
>  0x0000000000000019 (INIT_ARRAY)         0x1197f0
>  0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
>  0x000000000000001a (FINI_ARRAY)         0x1197f8
>  0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
>  0x000000006ffffef5 (GNU_HASH)           0x460
>  0x0000000000000005 (STRTAB)             0x2148
>  0x0000000000000006 (SYMTAB)             0x540
>  0x000000000000000a (STRSZ)              4860 (bytes)
>  0x000000000000000b (SYMENT)             24 (bytes)
>  0x0000000070000000 (DT_X86_64_PLT)      0x7140
>  0x0000000070000001 (DT_X86_64_PLTSZ)    0x10c0
>  0x0000000070000003 (DT_X86_64_PLTENT)   0x10
>  0x0000000000000015 (DEBUG)              0x0
>  0x0000000000000003 (PLTGOT)             0x120728
>  0x0000000000000002 (PLTRELSZ)           6432 (bytes)
>  0x0000000000000014 (PLTREL)             RELA
>  0x0000000000000017 (JMPREL)             0x39c8
>  0x0000000000000007 (RELA)               0x37a0
>  0x0000000000000008 (RELASZ)             552 (bytes)
>  0x0000000000000009 (RELAENT)            24 (bytes)
>  0x000000000000001e (FLAGS)              BIND_NOW
>  0x000000006ffffffb (FLAGS_1)            Flags: NOW PIE
>  0x000000006ffffffe (VERNEED)            0x36a0
>  0x000000006fffffff (VERNEEDNUM)         2
>  0x000000006ffffff0 (VERSYM)             0x3444
>  0x0000000000000024 (RELR)               0x52e8
>  0x0000000000000023 (RELRSZ)             536 (bytes)
>  0x0000000000000025 (RELRENT)            8 (bytes)
>  0x0000000000000000 (NULL)               0x0
> [hjl@gnu-cfl-3 tmp]$ 
> 
> These dynamic tags with addresses must be relocated before accessing the
> memory.

The test case above is too small to have any necessary relocation, but I have
another kernel using the same build system that has plenty of R_X86_64_RELATIVE
relocations and it works fine after Limine relocates it.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]