This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
sparc64 solaris different-brokenness patch
- To: binutils at sources dot redhat dot com
- Subject: sparc64 solaris different-brokenness patch
- From: Geoff Keating <geoffk at cygnus dot com>
- Date: Fri, 8 Sep 2000 15:29:58 -0700
The original reason for this line (in the sparc32, ppc, and probably
dozens of other backends) is that it's a workaround for a bug in the
sparc solaris ld.so. The correct way to process a R_*_RELATIVE RELA
reloc is to compute:
(base address of shared object) + addend
and stuff that into the location being relocated. The sparc32 Solaris
ld.so does:
(base address of shared object) + (contents of location being relocated)
so we have to put a copy of the addend at the location being
relocated.
The sparc64 Solaris ld.so does
(base address of shared object) + addend + (contents of location being relocated)
which is still wrong, but differently wrong, and the old work-around
won't work (we get the addend twice). So we use a new work-around.
OK to commit?
--
- Geoffrey Keating <geoffk@cygnus.com>
===File ~/patches/cygnus/sparc64-relative.patch=============
2000-08-30 Geoffrey Keating <geoffk@cygnus.com>
* elf64-sparc.c (sparc64_elf_relocate_section): Clear the location
of a GOT reloc.
Index: elf64-sparc.c
===================================================================
RCS file: /cvs/cvsfiles/devo/bfd/elf64-sparc.c,v
retrieving revision 1.48.2.2
diff -c -r1.48.2.2 elf64-sparc.c
*** elf64-sparc.c 2000/08/14 20:06:33 1.48.2.2
--- elf64-sparc.c 2000/08/31 03:23:54
***************
*** 2356,2362 ****
off &= ~1;
else
{
- bfd_put_64 (output_bfd, relocation, sgot->contents + off);
local_got_offsets[r_symndx] |= 1;
if (info->shared)
--- 2356,2361 ----
***************
*** 2364,2369 ****
--- 2363,2375 ----
asection *srelgot;
Elf_Internal_Rela outrel;
+ /* The Solaris 2.7 64-bit linker adds the contents
+ of the location to the value of the reloc.
+ Note this is different behaviour to the
+ 32-bit linker, which both adds the contents
+ and ignores the addend. So clear the location. */
+ bfd_put_64 (output_bfd, 0, sgot->contents + off);
+
/* We need to generate a R_SPARC_RELATIVE reloc
for the dynamic linker. */
srelgot = bfd_get_section_by_name(dynobj, ".rela.got");
***************
*** 2380,2385 ****
--- 2386,2393 ----
+ srelgot->reloc_count));
++srelgot->reloc_count;
}
+ else
+ bfd_put_64 (output_bfd, relocation, sgot->contents + off);
}
relocation = sgot->output_offset + off - got_base;
}
============================================================