[PATCH 0/6] ld: Add "-z textonly" option to ELF linker
Michael Matz
matz@suse.de
Tue Nov 14 12:55:00 GMT 2017
Hi,
On Mon, 13 Nov 2017, H.J. Lu wrote:
> Text-only LOAD segment has the same requirement for segment alignment
> and page sizes as GNU_RELRO segment. But for GNU_RELRO segment, the
> segment may not end at the same address of the end of data segment.
> But for text-only LOAD segment, it is exactly the same as text LOAD
> segment.
>
> The new "-z textonly" option will turn on both text-only LOAD segment
> and GNU_RELRO segment. The new "-z notextonly" option will turn off
> only text-only LOAD segment. "-z relro" is updated not to turn off
> text-only LOAD segment. "-z norelro" is updated to turn off both
> GNU_RELRO segment and text-only LOAD segment.
>
> When there is a text-only LOAD segment, create a new LOAD segment if the
> previous section contains text and the current section doesn't or vice
> versa:
>
> Elf file type is DYN (Shared object file)
> Entry point 0x200ff0
> There are 7 program headers, starting at offset 52
>
> Program Headers:
> Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
> LOAD 0x000000 0x00000000 0x00000000 0x00200 0x00200 R 0x200000
> LOAD 0x000fd0 0x00200fd0 0x00200fd0 0x0002b 0x0002b R E 0x200000
> LOAD 0x001000 0x00201000 0x00201000 0x00058 0x00058 R 0x200000
> LOAD 0x200f80 0x00400f80 0x00400f80 0x000a0 0x000a0 RW 0x200000
This seems strange. The (file)offset of the fourth segment is much larger
than than the added sizes of the individual segments, which isn't
necessary.
> Since there are more than 2 LOAD segments, the minimum file size is
> bigger than the maximum page size which is 2MB (0x200000):
>
> -rwxr-xr-x 1 hjl hjl 2104892 Nov 12 11:53 libfoo.so
This is the result of the above problem, but it's not necessary. Like in
a traditional two-LOAD-segment file, which also isn't larger than 2MB,
just because the page size is 2MB. It achieves this by mapping the same
file bytes multiple times, and you could do the same. E.g. for the file
above the better layout would be:
LOAD 0x000000 0x00000000 0x00000000 0x00200 0x00200 R 0x200000
LOAD 0x000fd0 0x00200fd0 0x00200fd0 0x0002b 0x0002b R E 0x200000
LOAD 0x001000 0x00201000 0x00201000 0x00058 0x00058 R 0x200000
LOAD 0x001060 0x00401060 0x00401060 0x000a0 0x000a0 RW 0x200000
But even then something is wrong: The RE and the second R page are both
mapped onto 0x0020xxxx, i.e. the same 2MB page, so can't have different
protections. (You'd need 4k pages again, which defeats the whole purpose
of having 2MB pages in the file to start with).
>
> "-z max-page-size=0x1000" can be used to reduce the maximum page size to
> 4KB (0x1000):
>
> -rwxr-xr-x 1 hjl hjl 11836 Nov 12 13:22 libfoo.so
>
> Elf file type is DYN (Shared object file)
> Entry point 0x1ff0
> There are 7 program headers, starting at offset 52
>
> Program Headers:
> Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
> LOAD 0x000000 0x00000000 0x00000000 0x00200 0x00200 R 0x1000
> LOAD 0x000fd0 0x00001fd0 0x00001fd0 0x0002b 0x0002b R E 0x1000
> LOAD 0x001000 0x00002000 0x00002000 0x00058 0x00058 R 0x1000
> LOAD 0x001f80 0x00002f80 0x00002f80 0x000a0 0x000a0 RW 0x1000
Also this shows strangeness. The second R and the RW page are both mapped
to 0x2xxx, the same 4k page, which can't have different protections. Also
the offsets are somehow wrong. The second R page starts at 0x1000 (in
file), and is 0x58 bytes long (memsize is 0x58 as well). So the next
thing in file should start at 0x1060, not 0x1f80 (and should be mapped to
0x3060, not 0x2f80).
So, I think something in your patch series is quite wrong with offset,
size and vaddr calculations.
Ciao,
Michael.
More information about the Binutils
mailing list