Sergey Vlasov
2007-Feb-18 16:30 UTC
[klibc] shared klibc broken on x86_64 with binutils >= 2.17.50.0.2
Hello! I have encountered a problem when building shared klibc with recent binutils versions - apparently the breakage happened since binutils 2.17.50.0.2 due to the following change: http://sources.redhat.com/ml/binutils/2006-05/msg00279.html http://sourceware.org/ml/binutils/2006-05/msg00466.html --- a/binutils/bfd/elf64-x86-64.c +++ b/binutils/bfd/elf64-x86-64.c @@ -3630,7 +3630,8 @@ static const struct bfd_elf_special_section #define TARGET_LITTLE_NAME "elf64-x86-64" #define ELF_ARCH bfd_arch_i386 #define ELF_MACHINE_CODE EM_X86_64 -#define ELF_MAXPAGESIZE 0x100000 +#define ELF_MAXPAGESIZE 0x200000 +#define ELF_MINPAGESIZE 0x1000 #define elf_backend_can_gc_sections 1 #define elf_backend_can_refcount 1 When building klibc with new binutils, I get: $ readelf -l usr/klibc/libc.so Elf file type is EXEC (Executable file) Entry point 0x200200 There are 3 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000200000 0x0000000000200000 0x0000000000011a5e 0x0000000000011a5e R E 200000 LOAD 0x0000000000011a60 0x0000000000411a60 0x0000000000411a60 0x0000000000000100 0x0000000000004288 RW 200000 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RWE 8 Section to Segment mapping: Segment Sections... 00 .text .rodata 01 .data .bss 02 The .text and .rodata sections are placed in a segment starting at 0x200000, but .data and .bss are placed starting at 0x411a60. But binaries are linked starting at 0x400000 - therefore the executable code falls between the klibc.so segments. This even seems to work on mainline kernels (at least on 2.6.18 - although it seems to work just because programs are small enough), but breaks on kernels with the exec-shield patch (http://people.redhat.com/mingo/exec-shield/) - all programs linked with shared klibc segfault immediately on such kernels, because the executable code segment is not mapped into virtual memory at all. Older binutils versions with ELF_MAXPAGESIZE = 0x100000 generated working klibc.so: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000200000 0x0000000000200000 0x0000000000011a5e 0x0000000000011a5e R E 100000 LOAD 0x0000000000011a60 0x0000000000311a60 0x0000000000311a60 0x0000000000000100 0x0000000000004288 RW 100000 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RWE 8 Here the data segment was placed at 0x311a60, leaving enough space for the main executable code at 0x400000. Seems that the increased maximum page size is just for better performance, and the value can be decreased without losing compatibility. New ld versions have an option for this: -z max-page-size=SIZE Set maximum page size to SIZE Adding "-z max-page-size=0x100000" to KLIBCSHAREDFLAGS fixes klibc.so build on new binutils - the resulting binaries run fine even on kernels with the exec-shield patch. Probably this option can even be added unconditionally - GNU ld silently ignores all "-z KEYWORD" options which it does not understand, therefore the added options should not break linking with old ld versions (although I did not actually test this yet). Maybe somebody has some other solution to this problem? -- Sergey Vlasov -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.zytor.com/pipermail/klibc/attachments/20070218/6e1eebb7/attachment.bin
Sergey Vlasov
2007-Feb-18 17:28 UTC
[klibc] shared klibc broken on x86_64 with binutils >= 2.17.50.0.2
On Sun, Feb 18, 2007 at 07:30:08PM +0300, Sergey Vlasov wrote:> Adding "-z max-page-size=0x100000" to KLIBCSHAREDFLAGS fixes klibc.so > build on new binutils - the resulting binaries run fine even on > kernels with the exec-shield patch. Probably this option can even be > added unconditionally - GNU ld silently ignores all "-z KEYWORD" > options which it does not understand, therefore the added options > should not break linking with old ld versions (although I did not > actually test this yet).Now tested with binutils-2.15.94.0.2.2 (older versions don't seem to compile here), which does not know about the "-z max-page-size=SIZE" option - linking still works (ld ignores the unknown option), and the resulting klibc.so is good (max-page-size is 0x100000 there). -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.zytor.com/pipermail/klibc/attachments/20070218/a84da089/attachment.bin
Sergey Vlasov
2007-Feb-18 20:30 UTC
[klibc] [PATCH] x86_64: fix shared library breakage with new binutils versions
In recent versions of binutils the maximum page size for x86_64 was increased from 1 MB to 2 MB: http://sources.redhat.com/ml/binutils/2006-05/msg00279.html This change breaks building of the klibc shared library - klibc.so data is pushed over the 4 MB mark, where it may overlap the main executable (which is linked starting at 4 MB). Adding the "-z max-page-size=0x100000" option fixes the problem with new binutils, and does not break linking with old binutils (ld silently ignores unknown "-z KEYWORD" options). Signed-off-by: Sergey Vlasov <vsu at altlinux.ru> --- Alternatively, you may pull from the following git repo and branch: git://git.altlinux.org/people/vsu/packages/klibc.git upstream-fixes usr/klibc/arch/x86_64/MCONFIG | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/usr/klibc/arch/x86_64/MCONFIG b/usr/klibc/arch/x86_64/MCONFIG index a229905..b40c627 100644 --- a/usr/klibc/arch/x86_64/MCONFIG +++ b/usr/klibc/arch/x86_64/MCONFIG @@ -29,7 +29,11 @@ KLIBCLDFLAGS = -m elf_x86_64 # This address needs to be reachable using normal inter-module # calls, and work on the memory models for this architecture # 2 MB - normal binaries start at 4 MB -KLIBCSHAREDFLAGS = -Ttext 0x00200200 +# +# Recent binutils use max-page-size=0x200000 by default, which pushes +# klibc.so data over the 4 MB mark, overlapping the executable. +# Revert to the old max-page-size=0x100000 value. +KLIBCSHAREDFLAGS = -Ttext 0x00200200 -z max-page-size=0x100000 # Additional asm- directories needed during installation ASMARCH = asm-i386 -- 1.5.0.57.g09e9d