Discussion:
ld -lgen -ladm causes assert failure in gnu ld 2.12.1 and 2.13 under Solaris 2.7 or 2.8
(too old to reply)
Nick Clifton
2002-09-19 21:42:51 UTC
Permalink
Hi Andrew,
What's going on is that there is a second, presumably unrelated,
problem, the existence of which I had forgotten. Following is a
shell script that reproduces the problem. When I execute it under
binutils 2.13, with or without the patch, it dumps core;
under binutils 2.12, it doesn't.
I wonder ... can you reproduce it on your end?
$CC $CFLAGS $SHFLAGS dyn.c -o dyn.so
$CC $CFLAGS main.c -o main -ldl
./main || exit $?
Well yes and no. I can run the script, but it works. But then it
uses the installed gcc (2.95.2) and linker (Software Generation
Utilities - Solaris-ELF (4.0)) not a binutils 2.13 one. (I only build
toolchains - I do not install them).

So I tried extracting the files from the script and building them by
hand. I used the installed gcc (2.95.2) to compile main.o and dyn.so
and then I used my newly built binutils-from-CVS-repository linker to
create main:

bash-2.01$ ../ld/ld-new -Y P,/usr/ccs/lib:/usr/lib -Qy -o main
/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/crt1.o
/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/crti.o
/usr/ccs/lib/values-Xa.o
/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/crtbegin.o
-L/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2 -L/usr/ccs/bin
-L/usr/ccs/lib -L/usr/local/lib main.o -ldl -lgcc -lc -lgcc
/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/crtend.o
/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/crtn.o

However this produced a version of 'main' that worked.

bash-2.01$ uname -a
SunOS tomorrow 5.7 Generic_106541-17 sun4u sparc SUNW,Ultra-30

bash-2.01$ ../ld/ld-new -V
GNU ld version 2.13.90 20020917
Supported emulations:
elf32_sparc
elf64_sparc

bash-2.01$ ./main
calling dlopen
calling dlsym
calling sym
in sym
done

So then I tried to create a dyn.so dynamic object from a compiled but
unlinked dyn.o object file, using the new linker:

bash-2.01$ ../ld/ld-new -G -dy -z text -Y P,/usr/ccs/lib:/usr/lib
-Qy -o dyn.so
/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/crti.o
/usr/ccs/lib/values-Xa.o
/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/crtbegin.o
-L/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2 -L/usr/ccs/bin
-L/usr/ccs/lib -L/usr/local/lib dyn.o -lgcc -lgcc
/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/crtend.o
/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/crtn.o

and..

bash-2.01$ ./main
calling dlopen
Segmentation Fault (core dumped)

bingo.

Using readelf -H to look at the secontions of the good dyn,so I see:

There are 25 section headers, starting at offset 0x111c:

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .hash HASH 00000094 000094 000074 04 A 2 0 4
[ 2] .dynsym DYNSYM 00000108 000108 0000e0 10 A 3 1 4
[ 3] .dynstr STRTAB 000001e8 0001e8 0000eb 00 A 0 0 1
[ 4] .rela.data RELA 000002d4 0002d4 00000c 0c A 2 e 4
[ 5] .rela.got RELA 000002e0 0002e0 000060 0c A 2 b 4
[ 6] .rela.plt RELA 00000340 000340 000024 0c A 2 c 4
[ 7] .text PROGBITS 00000364 000364 0001bc 00 AX 0 0 4
[ 8] .init PROGBITS 00000520 000520 00001c 00 AX 0 0 4
[ 9] .fini PROGBITS 0000053c 00053c 000014 00 AX 0 0 4
[10] .rodata PROGBITS 00000550 000550 00000f 00 A 0 0 8
[11] .got PROGBITS 00010560 000560 000024 04 WA 0 0 4
[12] .plt PROGBITS 00010584 000584 000058 0c WAX 0 0 4
[13] .dynamic DYNAMIC 000105dc 0005dc 0000c0 08 WA 3 0 4
[14] .data PROGBITS 0001069c 00069c 000008 00 WA 0 0 4
[15] .ctors PROGBITS 000106a4 0006a4 000008 00 WA 0 0 4
[16] .dtors PROGBITS 000106ac 0006ac 000008 00 WA 0 0 4
[17] .eh_frame PROGBITS 000106b8 0006b8 000004 00 WA 0 0 8
[18] .bss NOBITS 000106c0 0006c0 000018 00 WA 0 0 16
[19] .symtab SYMTAB 00000000 0006bc 000490 10 20 3c 4
[20] .strtab STRTAB 00000000 000b4c 000281 00 0 0 1
[21] .stab.index PROGBITS 00000000 000dd0 000024 0c 0 0 4
[22] .comment PROGBITS 00000000 000df4 0000f1 00 0 0 1
[23] .shstrtab STRTAB 00000000 000ee5 0000c4 00 0 0 1
[24] .stab.indexstr STRTAB 00000000 000fa9 000171 00 0 0 1

whereas for the bad one I see:

There are 24 section headers, starting at offset 0xaf4:

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .hash HASH 00000094 000094 0000d4 04 A 2 0 4
[ 2] .dynsym DYNSYM 00000168 000168 000220 10 A 3 15 4
[ 3] .dynstr STRTAB 00000388 000388 0000a2 00 A 0 0 1
[ 4] .rela.dyn RELA 0000042c 00042c 00006c 0c A 2 0 4
[ 5] .rela.plt RELA 00000498 000498 000024 0c A 2 f 4
[ 6] .init PROGBITS 000004bc 0004bc 00001c 00 AX 0 0 4
[ 7] .text PROGBITS 000004d8 0004d8 0001bc 00 AX 0 0 4
[ 8] .fini PROGBITS 00000694 000694 000014 00 AX 0 0 4
[ 9] .rodata PROGBITS 000006a8 0006a8 00000f 00 A 0 0 8
[10] .data PROGBITS 000106b8 0006b8 000008 00 WA 0 0 4
[11] .eh_frame PROGBITS 000106c0 0006c0 000004 00 WA 0 0 8
[12] .dynamic DYNAMIC 000106c4 0006c4 0000a0 08 WA 3 0 4
[13] .ctors PROGBITS 00010764 000764 000008 00 WA 0 0 4
[14] .dtors PROGBITS 0001076c 00076c 000008 00 WA 0 0 4
[15] .plt PROGBITS 00010774 000774 000058 0c WAX 0 0 4
[16] .got PROGBITS 000107cc 0007cc 000024 04 WA 0 0 4
[17] .bss NOBITS 000107f0 0007f0 000018 00 WA 0 0 16
[18] .stab.index PROGBITS 00000000 0007f0 000024 0c 19 0 4
[19] .stab.indexstr STRTAB 00000000 000814 000171 00 0 0 1
[20] .comment PROGBITS 00000000 000985 0000bb 00 0 0 1
[21] .shstrtab STRTAB 00000000 000a40 0000b4 00 0 0 1
[22] .symtab SYMTAB 00000000 000eb4 000450 10 23 38 4
[23] .strtab STRTAB 00000000 001304 000223 00 0 0 1

Which is completely different, and the ".rela.got" section has gone
missing!

Not sure where to go from here. I will try to find time to
investigate some more next week - but right now I am swamped. If you
have any insights, please post them to the list.

Cheers
Nick
Jakub Jelinek
2002-09-19 21:49:36 UTC
Permalink
Post by Nick Clifton
[ 4] .rela.dyn RELA 0000042c 00042c 00006c 0c A 2 0 4
[ 5] .rela.plt RELA 00000498 000498 000024 0c A 2 f 4
Which is completely different, and the ".rela.got" section has gone
missing!
That's because of -zcombreloc (now the default).
All SHF_ALLOC .rela.* sections but .rela.plt are merged into .rela.dyn and
sorted for faster runtime lookup.

Jakub
Nick Clifton
2002-09-20 07:07:34 UTC
Permalink
Hi Jakub,
Post by Jakub Jelinek
That's because of -zcombreloc (now the default).
All SHF_ALLOC .rela.* sections but .rela.plt are merged into .rela.dyn and
sorted for faster runtime lookup.
Thanks for the tip. This turns out to be a workaround to stop the
bug.

Andrew: if you add -znocombreloc to the linker command line then you
get a working dyn.so binary. I would suggest adding
-Wl,-znocombreloc to the SHFLAGS variable in your shell script.

Of course this does not fix the problem, but it does mean that
binutils 2.13 can now be used with Solaris 2.7 and 2.8.

Cheers
Nick
Alan Modra
2002-09-20 07:24:38 UTC
Permalink
Post by Nick Clifton
Andrew: if you add -znocombreloc to the linker command line then you
get a working dyn.so binary. I would suggest adding
-Wl,-znocombreloc to the SHFLAGS variable in your shell script.
Of course this does not fix the problem, but it does mean that
binutils 2.13 can now be used with Solaris 2.7 and 2.8.
The interesting question is whether this is a bug in solaris ld.so,
or in binutils. If it's ld.so, then I suppose we ought to default
to -znocombreloc on solaris.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
Jakub Jelinek
2002-09-20 09:53:42 UTC
Permalink
Post by Alan Modra
Post by Nick Clifton
Andrew: if you add -znocombreloc to the linker command line then you
get a working dyn.so binary. I would suggest adding
-Wl,-znocombreloc to the SHFLAGS variable in your shell script.
Of course this does not fix the problem, but it does mean that
binutils 2.13 can now be used with Solaris 2.7 and 2.8.
The interesting question is whether this is a bug in solaris ld.so,
or in binutils. If it's ld.so, then I suppose we ought to default
to -znocombreloc on solaris.
Yeah.
Interesting thing to try would be to wipe out the DT_RELACOUNT dynamic tag
(say in hex editor or using libelf) and see whether it works.
I think I remember Solaris ld.so was unsure whether DT_RELACOUNT is R_*_RELATIVE
relocs from start of .rela.dyn or from end of that section. Older versions
did it the latter way newer the right (former) way.
Maybe they even have patches to fix ld.so, somebody with Solaris
should check.

Jakub
Andrew Koenig
2002-09-20 13:27:51 UTC
Permalink
Nick> Andrew: if you add -znocombreloc to the linker command line then you
Nick> get a working dyn.so binary. I would suggest adding
Nick> -Wl,-znocombreloc to the SHFLAGS variable in your shell script.

Nick> Of course this does not fix the problem, but it does mean that
Nick> binutils 2.13 can now be used with Solaris 2.7 and 2.8.

I will give it a try and let you know. If it does work, making it work
for Python is a somewhat harder problem, as the linker options are
generated by a script that generates another script, etc...
However, I'll see if I can untangle it.

I suppose the thing to do is to find where it specifies --export-dynamic
to the linker and add -znocombreloc at that point?
Andrew Koenig
2002-09-20 17:08:00 UTC
Permalink
Nick> Andrew: if you add -znocombreloc to the linker command line then you
Nick> get a working dyn.so binary. I would suggest adding
Nick> -Wl,-znocombreloc to the SHFLAGS variable in your shell script.

That seems to do the trick; thanks!

I'll suggest this as a workaround to the Python folks while you
figure out what to do for the long term.
Andrew Koenig
2002-09-20 21:29:42 UTC
Permalink
Nick> Andrew: if you add -znocombreloc to the linker command line then
Nick> you get a working dyn.so binary. I would suggest adding
Nick> -Wl,-znocombreloc to the SHFLAGS variable in your shell script.

OK ... I now have Python working with binutils 2.13.

On the other hand, if I try to build tk 8.4, it dumps core :-(

I would not be at all surprised to see that the -zcombreloc problem
is affecting that build also. So I wonder whether you are planning
to make -znocombreloc the default again, or whether there might
be a Solaris patch to address the problem.

I tried installing patch 109147-18, which seems to be the latest
consolidated linker patch, but to no avail.
Jakub Jelinek
2002-09-20 21:33:16 UTC
Permalink
Post by Andrew Koenig
Nick> Andrew: if you add -znocombreloc to the linker command line then
Nick> you get a working dyn.so binary. I would suggest adding
Nick> -Wl,-znocombreloc to the SHFLAGS variable in your shell script.
OK ... I now have Python working with binutils 2.13.
On the other hand, if I try to build tk 8.4, it dumps core :-(
I would not be at all surprised to see that the -zcombreloc problem
is affecting that build also. So I wonder whether you are planning
to make -znocombreloc the default again, or whether there might
be a Solaris patch to address the problem.
I tried installing patch 109147-18, which seems to be the latest
consolidated linker patch, but to no avail.
I checked Solaris 2.8 today (though have no idea what patches were and
were not applied there) and the Solaris linker created RELATIVE relocs
first in .SUNW_reloc section and included them in DT_RELACOUNT, so either
ld.so is inconsistent with what their linker does, or the bug is somewhere
else.

Jakub
Andrew Koenig
2002-09-20 21:38:02 UTC
Permalink
Jakub> I checked Solaris 2.8 today (though have no idea what patches
Jakub> were and were not applied there) and the Solaris linker created
Jakub> RELATIVE relocs first in .SUNW_reloc section and included them
Jakub> in DT_RELACOUNT, so either ld.so is inconsistent with what
Jakub> their linker does, or the bug is somewhere else.

I'm afraid I'm way out of my depth here :-(
What I do know is that with the latest Solaris linker pagch
(dated August 9, 2002), the little test program still fails
unless -znocombreloc is in effect.
Jakub Jelinek
2002-09-20 21:40:01 UTC
Permalink
Post by Andrew Koenig
Jakub> I checked Solaris 2.8 today (though have no idea what patches
Jakub> were and were not applied there) and the Solaris linker created
Jakub> RELATIVE relocs first in .SUNW_reloc section and included them
Jakub> in DT_RELACOUNT, so either ld.so is inconsistent with what
Jakub> their linker does, or the bug is somewhere else.
I'm afraid I'm way out of my depth here :-(
What I do know is that with the latest Solaris linker pagch
(dated August 9, 2002), the little test program still fails
unless -znocombreloc is in effect.
If you're using binutils, Solaris linker patches probably don't change
iota anywhere. ld.so patches would.

Jakub
Andrew Koenig
2002-09-20 21:40:42 UTC
Permalink
Jakub> If you're using binutils, Solaris linker patches probably don't
Jakub> change iota anywhere. ld.so patches would.

The Solaris patch did replace /usr/lib/ld.so
Andrew Koenig
2002-09-22 16:23:19 UTC
Permalink
It looks like the -znocombreloc fix isn't good enough.
Here's a summary of what I tried. I started with binutils 2.12.1,
gcc 3.2, and python 2.1.1

1) Install binutils 2.13.

2) Rebuild python. The build fails.

3) Change the python build procedure to say -Wl,-znocombreloc
where it says -fPIC. Python now builds and seems to work.

4) Rebuild gcc 3.2 from scratch. The python executable now
crashes -- which means that rebuilding gcc 3.2 changed something
that python dynamically loads. I am guessing that it builds a
library somwhere with -zcombreloc, which then causes the dynamic
loader to fail when the python executable tries to use it.

5) Rebuild python with -Wl,-znocombreloc. The build fails,
not too surprisingly.

6) Reinstall binutils 2.12.1. The little test program I sent you
earlier *still fails*, even with -znocombreloc.

So apparently building gcc 3.2 with binutils 2.13 does something
that renders the -znocombreloc workaround ineffective, at least
for the purpose of building python.

I think we need a more effective fix to the problem -- either finding
out why -zcombreloc doesn't work under Solaris 2.8 or disabling it.
Daniel Jacobowitz
2002-09-22 16:30:52 UTC
Permalink
Post by Andrew Koenig
It looks like the -znocombreloc fix isn't good enough.
Here's a summary of what I tried. I started with binutils 2.12.1,
gcc 3.2, and python 2.1.1
1) Install binutils 2.13.
2) Rebuild python. The build fails.
3) Change the python build procedure to say -Wl,-znocombreloc
where it says -fPIC. Python now builds and seems to work.
4) Rebuild gcc 3.2 from scratch. The python executable now
crashes -- which means that rebuilding gcc 3.2 changed something
that python dynamically loads. I am guessing that it builds a
library somwhere with -zcombreloc, which then causes the dynamic
loader to fail when the python executable tries to use it.
5) Rebuild python with -Wl,-znocombreloc. The build fails,
not too surprisingly.
6) Reinstall binutils 2.12.1. The little test program I sent you
earlier *still fails*, even with -znocombreloc.
So apparently building gcc 3.2 with binutils 2.13 does something
that renders the -znocombreloc workaround ineffective, at least
for the purpose of building python.
I think we need a more effective fix to the problem -- either finding
out why -zcombreloc doesn't work under Solaris 2.8 or disabling it.
Preferably the former. Could you try wrapping the linker in a shell
script which adds -z nocombreloc (at the end of arguments, I think..)
and rebuilding both GCC 3.2 and Python? That way libgcc_s, libstdc++,
etc. will be built without combreloc.

My current plan is to disable combreloc on Solaris targets for 2.13.1,
unless someone figures out where the problem lies.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
Andrew Koenig
2002-09-22 16:37:29 UTC
Permalink
Daniel> Preferably the former. Could you try wrapping the linker in a shell
Daniel> script which adds -z nocombreloc (at the end of arguments, I think..)
Daniel> and rebuilding both GCC 3.2 and Python? That way libgcc_s, libstdc++,
Daniel> etc. will be built without combreloc.

I'm not quite sure how to do that, because in order to locate the end
of the arguments, the script would have to parse them. For example:

ld -foo bar baz

Is bar part of the arguments or not? The only way to know is by
understanding the meaning of -foo.
Jakub Jelinek
2002-09-22 17:03:56 UTC
Permalink
Post by Andrew Koenig
Daniel> Preferably the former. Could you try wrapping the linker in a shell
Daniel> script which adds -z nocombreloc (at the end of arguments, I think..)
Daniel> and rebuilding both GCC 3.2 and Python? That way libgcc_s, libstdc++,
Daniel> etc. will be built without combreloc.
I'm not quite sure how to do that, because in order to locate the end
Why do you need to parse the arguments?
cat > /foo/bar/ld <<"EOF"
#!/bin/sh
exec /opt/gnu/bin/ld -z nocombreloc "$@"
EOF
chmod +x /foo/bar/ld

Jakub
Daniel Jacobowitz
2002-09-22 17:06:32 UTC
Permalink
Post by Jakub Jelinek
Post by Andrew Koenig
Daniel> Preferably the former. Could you try wrapping the linker in a shell
Daniel> script which adds -z nocombreloc (at the end of arguments, I think..)
Daniel> and rebuilding both GCC 3.2 and Python? That way libgcc_s, libstdc++,
Daniel> etc. will be built without combreloc.
I'm not quite sure how to do that, because in order to locate the end
Why do you need to parse the arguments?
cat > /foo/bar/ld <<"EOF"
#!/bin/sh
EOF
chmod +x /foo/bar/ld
"$@" -z nocombreloc was what I was trying to convey, so that no one
adds -z combreloc... didn't some versions of GCC do so?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
Andrew Koenig
2002-09-22 17:06:51 UTC
Permalink
Jakub> On Sun, Sep 22, 2002 at 12:37:29PM -0400, Andrew Koenig wrote:
Daniel> Preferably the former. Could you try wrapping the linker in a shell
Daniel> script which adds -z nocombreloc (at the end of arguments, I think..)
Daniel> and rebuilding both GCC 3.2 and Python? That way libgcc_s, libstdc++,
Daniel> etc. will be built without combreloc.
Post by Andrew Koenig
I'm not quite sure how to do that, because in order to locate the end
Jakub> Why do you need to parse the arguments?

Are you certain that ld applies -z retroactively?

Part of the reason that I am reluctant to try this test is that it
takes about 8 hours to build gcc on my machine.
Daniel Jacobowitz
2002-09-22 17:04:26 UTC
Permalink
Post by Andrew Koenig
Daniel> Preferably the former. Could you try wrapping the linker in a shell
Daniel> script which adds -z nocombreloc (at the end of arguments, I think..)
Daniel> and rebuilding both GCC 3.2 and Python? That way libgcc_s, libstdc++,
Daniel> etc. will be built without combreloc.
I'm not quite sure how to do that, because in order to locate the end
ld -foo bar baz
Is bar part of the arguments or not? The only way to know is by
understanding the meaning of -foo.
Sorry, I meant at the very end - after all files to be linked, et
cetera. Should work fine.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
Andrew Koenig
2002-09-22 17:05:35 UTC
Permalink
Daniel> Preferably the former. Could you try wrapping the linker in a shell
Daniel> script which adds -z nocombreloc (at the end of arguments, I think..)
Daniel> and rebuilding both GCC 3.2 and Python? That way libgcc_s, libstdc++,
Daniel> etc. will be built without combreloc.

I have a simpler suggestion. I changed the test script to specify
zcombreloc explicitly, and as I expected, it crashes under binutils 2.12.1.
So the answer, I think, is to produce a version of binutils that will run
this script correctly before looking for other problems.


Here's the script:
---------------------------------------------

#! /bin/sh

mkdir /tmp/t.$$ || exit 3
cd /tmp/t.$$ || exit 3

cat >main.c <<'EOF'
#include <stdio.h>
#include <dlfcn.h>

int main(void)
{
void *handle, *sym;
char *error;

puts("calling dlopen");
handle = dlopen("./dyn.so", RTLD_NOW);
if (!handle) {
printf("%s\n", dlerror());
return 1;
}

puts("calling dlsym");
sym = dlsym(handle, "sym");
if ((error = dlerror()) != 0) {
printf("%s\n", error);
return 1;
}
puts("calling sym");
((void (*)(void))sym)();
puts("done");
return 0;
}
EOF

cat >dyn.c <<'EOF'
#include <stdio.h>
void sym(void)
{
puts("in sym");
}
EOF

[ -n "$SHFLAGS" ] || SHFLAGS="-fPIC -shared -Wl,-zcombreloc"
[ -n "$CC" ] || CC=gcc

set -x

$CC $CFLAGS $SHFLAGS dyn.c -o dyn.so
$CC $CFLAGS main.c -o main -ldl

./main || exit $?

cd /tmp
rm -rf t.$$
Jakub Jelinek
2002-09-23 10:37:44 UTC
Permalink
Post by Andrew Koenig
Daniel> Preferably the former. Could you try wrapping the linker in a shell
Daniel> script which adds -z nocombreloc (at the end of arguments, I think..)
Daniel> and rebuilding both GCC 3.2 and Python? That way libgcc_s, libstdc++,
Daniel> etc. will be built without combreloc.
I have a simpler suggestion. I changed the test script to specify
zcombreloc explicitly, and as I expected, it crashes under binutils 2.12.1.
So the answer, I think, is to produce a version of binutils that will run
this script correctly before looking for other problems.
Oh well, Sun changing the rules.
It seems like ld.so behaviour changes based on whether DT_RELACOUNT is
seen or not.
If DT_RELACOUNT is not seen, R_SPARC_RELATIVE relocs are resolved as
*(long *) rela->r_offset += l_addr + rela->r_addend;
while if DT_RELACOUNT is seen, it is resolved as:
*(long *) rela->r_offset = l_addr + rela->r_addend;

Traditionally, Sun ld (for elf32_sparc) created all .rela.got RELATIVE
relocations with r_addend 0 and the addend in memory pointed by it while other
RELATIVE had the addend in r_addend and *r_offset 0.

Great, how I love this. Now prelink -u will not work
properly on sparc-linux until everything is relinked :(.

Jakub
Andrew Koenig
2002-09-23 13:34:50 UTC
Permalink
Jakub> Oh well, Sun changing the rules.
Jakub> It seems like ld.so behaviour changes based on whether DT_RELACOUNT is
Jakub> seen or not.
Jakub> If DT_RELACOUNT is not seen, R_SPARC_RELATIVE relocs are resolved as
Jakub> *(long *) rela->r_offset += l_addr + rela->r_addend;
Jakub> while if DT_RELACOUNT is seen, it is resolved as:
Jakub> *(long *) rela->r_offset = l_addr + rela->r_addend;

Jakub> Traditionally, Sun ld (for elf32_sparc) created all .rela.got RELATIVE
Jakub> relocations with r_addend 0 and the addend in memory pointed by it while other
Jakub> RELATIVE had the addend in r_addend and *r_offset 0.

Don't know what DT_RELACOUNT is, but I get the idea.

Sounds like one implication is that -zcombreloc doesn't work on
Sparc, period, but that it may not be too hard to fix.

If someone has a patch I can try, I'd be glad to do so.
Jakub Jelinek
2002-09-23 13:43:25 UTC
Permalink
Post by Andrew Koenig
Jakub> Oh well, Sun changing the rules.
Jakub> It seems like ld.so behaviour changes based on whether DT_RELACOUNT is
Jakub> seen or not.
Jakub> If DT_RELACOUNT is not seen, R_SPARC_RELATIVE relocs are resolved as
Jakub> *(long *) rela->r_offset += l_addr + rela->r_addend;
Jakub> *(long *) rela->r_offset = l_addr + rela->r_addend;
Jakub> Traditionally, Sun ld (for elf32_sparc) created all .rela.got RELATIVE
Jakub> relocations with r_addend 0 and the addend in memory pointed by it while other
Jakub> RELATIVE had the addend in r_addend and *r_offset 0.
Don't know what DT_RELACOUNT is, but I get the idea.
DT_RELACOUNT is a .dynamic tag which allows the dynamic linker optimize
relative relocs - if it is present, it is the number of RELATIVE
relocs at the start of dynamic relocation section (and other types
of relocations must not occur in between).
Post by Andrew Koenig
Sounds like one implication is that -zcombreloc doesn't work on
Sparc, period, but that it may not be too hard to fix.
It is trivial to fix, the above was just rant about Sun changing
RELATIVE reloc resolving for the 3rd time (initially it used to be
that r_addend was not taken into account).
Post by Andrew Koenig
If someone has a patch I can try, I'd be glad to do so.
I'll commit a fix today.

Jakub
Andrew Koenig
2002-09-23 13:45:31 UTC
Permalink
Post by Andrew Koenig
If someone has a patch I can try, I'd be glad to do so.
Jakub> I'll commit a fix today.

If you can send me a patch that I can apply to vanilla 2.13, that will
enable me to verify that it suffices by itself to fix the problem.
Loading...