This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
ld -Ttext 0x80000 causes ld.so segfault on ppc-unknown-linux-gnu
- To: binutils at sourceware dot cygnus dot com
- Subject: ld -Ttext 0x80000 causes ld.so segfault on ppc-unknown-linux-gnu
- From: Anton Ertl <anton at a0 dot complang dot tuwien dot ac dot at>
- Date: Sat, 8 Jul 2000 09:23:23 +0200 (MET DST)
- Reply-To: anton at mips dot complang dot tuwien dot ac dot at
[This is a modified version of a bug report to bug-gnu-utils@gnu.org
(http://sources.redhat.com/ml/bug-gnu-utils/2000-07/msg00037.html),
for which I have seen no reaction yet.]
Versions: GNU ld 2.9.5 (as distributed with Yellow Dog Linux), 2.10,
and the 000705 snapshot.
Platform: ppc-unknown-linux-gnu (actually a PowerMac), Yellow Dog
Linux 1.0, linux-2.2.9, glibc-2.1.
The Bug:
[anton@samhain tmp]$ cat <<EOF >yyy.c
> main()
> {
> puts("hello, world");
> exit(0);
> }
> EOF
[anton@samhain tmp]$ gcc -O -Xlinker -Ttext -Xlinker 0x80000 yyy.c
[anton@samhain tmp]$ ./a.out
Segmentation fault
This happens if the text address is below the default value of
0x10000000, but not for addresses between 0x10000000 and 0x80000000.
The segfault is in ld.so code, so I reported this first to the libc
people (http://www-gnats.gnu.org:8080/cgi-bin/wwwgnats.pl/full/1808).
Geoff Keating thinks this is a bug in ld:
> From: Geoff Keating <geoffk@cygnus.com>
> Message-Id: <200007060710.AAA01832@localhost.cygnus.com>
> Subject: Re: [(nowhere)] libc/1808: ld.so on powerpc-redhat-linux-gnu with ld -Ttext ...
>
> > From: Anton Ertl <anton@a0.complang.tuwien.ac.at>
> > Date: Thu, 6 Jul 2000 08:16:48 +0200 (MET DST)
>
> > [anton@samhain tmp]$ gcc -O -Xlinker -Ttext -Xlinker 0x80000 xxx.c
> > [anton@samhain tmp]$ objdump -p a.out
> >
> > a.out: file format elf32-powerpc
> >
> > Program Header:
> > PHDR off 0x00000034 vaddr 0x00010034 paddr 0x00000000 align 2**2
> > filesz 0x000000e0 memsz 0x000000e0 flags r-x
> > INTERP off 0x00020114 vaddr 0x10000114 paddr 0x10000114 align 2**0
> > filesz 0x0000000d memsz 0x0000000d flags r--
> > LOAD off 0x00010000 vaddr 0x00080000 paddr 0x00080000 align 2**16
> > filesz 0x0000024c memsz 0x0000024c flags r-x
> > ...
> > [anton@samhain tmp]$ LD_SHOW_AUXV=1 ./a.out
> > AT_PHDR: 0x70034
> > ...
>
> Oh, I see!
>
> Perhaps the kernel is correct, in a very weird sort of way. The PHDR
> in this file is not loaded, so the kernel is quoting an address that
> it would be at if it was loaded.
>
> I believe that this is an invalid ELF file. The PHDR is supposed to
> be loaded. Certainly, glibc requires that it is.
...
Workaround: I have been able to link successfully with the text
segment at 0x100000 by changing TEXT_START_ADDR in
ld/emulparams/elf32ppc*.sh and remaking ld and using that (of course
the result still cannot deal with -Ttext <addr>, where addr is below
TEXT_START_ADDR).
I wonder using an ld script generated in this way (e.g., elf32ppc.x)
will be portable between GNU ld and between OS versions.
Background: I need the text segment in the first 32MB for the PowerPC
port of Gforth, because it needs to branch from anywhere into the text
segment with at most two instructions, and I use ba (branch absolute)
for that, which wants it's target in the first or last 32MB. I can
fall back to indirect threading if I don't have this feature, but that
has a 20% performance penalty on a PPC 604e.
Wish: When you fix the bug, it would be nice if you let the text
segment start well below 32MB by default, as this would reduce the
amount of custom configure testing I would have to do (no check
whether the linker accepts -Ttext and whether it works; just test
whether the default address is below 32MB). If using the ld script is
portable, that's not so important.
- anton