This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
A relocation problem in shared objects for SH
- To: binutils at sourceware dot cygnus dot com
- Subject: A relocation problem in shared objects for SH
- From: kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- Date: Fri, 15 Sep 2000 07:41:36 +0900
Hi,
We have a problem when making libc.so for sh-unknown-linux-gnu target. This
comes from that SH ELF uses both rela relocation and the implicit rel value
in memory (to support COFF, I think). The next lists and relocs show what
happened.
[libc_pic.os: relocateable object]
2ea22: 30 d1 mov.l 2eae4 <_IO_vfprintf+0x384>,r1 ! 0x1fa0
2ea24: 2c 31 add r2,r1
2ea26: 2b 41 jmp @r1
Offset Info Type Symbol's Value Symbol's Name Addend
0002eae4 00101 R_SH_DIR32 00000000 .text 0002e760
Here, 2e760(addend) + 1fa0(rel value in memory) is the correct address
of the branch table. Corresponding list and reloc in the shared library
generated from libc_pic.os are
[libc.so: shared lib]
4c576: 0b d1 mov.l 4c5a4 <_IO_vfprintf+0x384>,r1 ! 0x1fa60
4c578: 2c 31 add r2,r1
4c57a: 2b 41 jmp @r1
Offset Info Type Symbol's Value Symbol's Name Addend
0004c5a4 0000f R_SH_RELATIVE 0004c220
At this point, 1fa60 seems a garbage value and the correct address
4c220 + 1fa0 is missing.
The following work around modifies the addend in sh_elf_relocate_section
when generating a shared object. In the above example, it changes the reloc
so that the addend shows the correct address of branch table:
Offset Info Type Symbol's Value Symbol's Name Addend
0004c5a4 0000f R_SH_RELATIVE 0004e1c0
This is a really ugly hack, though anyway works. This effects the generation
of the shared library only.
kaz
--
2000-09-15 Kaz Kojima <kkojima@rr.iij4u.or.jp>
* bfd/elf32-sh.c (sh_elf_relocate_section): Modify addend by
the implicit relocation when generating a shared object.
diff -pu /cvs/src/bfd/elf32-sh.c elf32-sh.c
--- /cvs/src/bfd/elf32-sh.c Fri Sep 15 00:50:21 2000
+++ elf32-sh.c Fri Sep 15 16:11:17 2000
@@ -3115,6 +3115,11 @@ sh_elf_relocate_section (output_bfd, inf
}
else
{
+ /* We fish out the additional addend from the data. */
+ addend = bfd_get_32 (input_bfd,
+ contents + rel->r_offset);
+ rel->r_addend += addend;
+
/* h->dynindx may be -1 if this symbol was marked to
become local. */
if (h == NULL