This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Committed: fix CRIS .rela.plt index miscalculation
- From: Hans-Peter Nilsson <hans-peter dot nilsson at axis dot com>
- To: binutils at sourceware dot org
- Date: Sat, 3 Jan 2009 06:01:49 +0100
- Subject: Committed: fix CRIS .rela.plt index miscalculation
See the test-case. The "shift" in .rela.plt entries caused two
R_CRIS_NONE entries to appear at its beginning (with the "real"
entries overwriting something after it, though not "bad" enough
to cause valgrind to complain). R_CRIS_NONE entries in
.rela.plt caused ld.so.1 to barf. And it shouldn't have to
handle them: there's no way they can legitimately appear there,
as opposed to elsewhere (e.g. .rela.dyn), where for example
warts in the eh-frame optimization machinery may leave those.
Maybe I'll fix that within this year...
With this and updates to the simulator I can run a dynlinked
hello-world there with eglibc-2.9 (and of course an updated CRIS
glibc port) with only two GCC bugs needing to be worked around.
(Oops, and two others fixed locally IIRC, and not using .dtpoffd
as it causes linker indigestion). And the also yet
uncontributed GCC port-specific TLS stuff. Still, yay.
Committed.
ld/testsuite:
* ld-cris/tls-js1.d: New test.
bfd:
* elf32-cris.c (elf_cris_finish_dynamic_symbol): Rename
gotplt_index to rela_plt_index. Adjust for R_CRIS_DTPMOD entry.
Index: ld-cris/tls-js1.d
===================================================================
RCS file: ld-cris/tls-js1.d
diff -N ld-cris/tls-js1.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld-cris/tls-js1.d 3 Jan 2009 04:43:12 -0000
@@ -0,0 +1,32 @@
+#source: dsov32-1.s
+#source: tls-ld-4.s
+#source: dsov32-2.s
+#source: expdyn1.s
+#source: tls-hx.s
+#source: dso-1.s
+#as: --pic --no-underscore --em=criself --march=v32
+#ld: --shared -m crislinux
+#readelf: -a
+
+# DSO with a R_CRIS_16_DTPREL and a R_CRIS_32_PLT_PCREL. The .got.plt
+# byte index (a) and .rela.plt item index (b) are in sync as b=a/4-3
+# *except* when there's a R_CRIS_DTPMOD, because while the relocated
+# contents goes in .got.plt, the relocation goes in .rela.got, not
+# .rela.plt. And, it'd cover 8 bytes in .got.plt, not 4 bytes.
+# Making sure .rela.plt has the right contents; no R_CRIS_NONE entries.
+
+#...
+ .* .got[ ]+PROGBITS[ ]+0+2348 0+348 0+20 04 WA 0 0 4
+#...
+Relocation section '\.rela\.dyn' at offset 0x20c contains 2 entries:
+ Offset Info Type Sym\.Value Sym\. Name \+ Addend
+00002354 0000001e R_CRIS_DTPMOD 00000000
+00002364 0000050a R_CRIS_GLOB_DAT 00002368 expobj \+ 0
+
+Relocation section '\.rela\.plt' at offset 0x224 contains 2 entries:
+ Offset Info Type Sym\.Value Sym\. Name \+ Addend
+0000235c 0000030b R_CRIS_JUMP_SLOT 00000296 dsofn4 \+ 0
+00002360 00000c0b R_CRIS_JUMP_SLOT 000002ae dsofn \+ 0
+
+There are no unwind sections in this file.
+#pass
Index: elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.94
diff -p -u -r1.94 elf32-cris.c
--- elf32-cris.c 20 Dec 2008 00:26:36 -0000 1.94
+++ elf32-cris.c 3 Jan 2009 04:40:14 -0000
@@ -2146,13 +2146,19 @@ elf_cris_finish_dynamic_symbol (output_b
bfd_byte *loc;
bfd_boolean has_gotplt = gotplt_offset != 0;
- /* Get the index in the procedure linkage table which
- corresponds to this symbol. This is the index of this symbol
- in all the symbols for which we are making plt entries. The
- first entry in the procedure linkage table is reserved. */
- /* We have to count backwards here, and the result is only valid as
- an index into .got.plt and its relocations. FIXME: Constants... */
- bfd_vma gotplt_index = gotplt_offset/4 - 3;
+ /* Get the index in the .rela.plt relocations for the .got.plt
+ entry that corresponds to this symbol.
+ We have to count backwards here, and the result is only valid
+ as an index into .rela.plt. We also have to undo the effect
+ of the R_CRIS_DTPMOD entry at .got index 3 (offset 12 into
+ .got.plt) for which gotplt_offset is adjusted, because while
+ that entry goes into .got.plt, its relocation goes into
+ .rela.got, not .rela.plt. (It's not PLT-specific; not to be
+ processed as part of the runtime lazy .rela.plt relocation).
+ FIXME: There be literal constants here... */
+ bfd_vma rela_plt_index
+ = (elf_cris_hash_table (info)->dtpmod_refcount != 0
+ ? gotplt_offset/4 - 2 - 3 : gotplt_offset/4 - 3);
/* Get the offset into the .got table of the entry that corresponds
to this function. Note that we embed knowledge that "incoming"
@@ -2202,7 +2208,7 @@ elf_cris_finish_dynamic_symbol (output_b
{
/* Fill in the offset to the reloc table. */
bfd_put_32 (output_bfd,
- gotplt_index * sizeof (Elf32_External_Rela),
+ rela_plt_index * sizeof (Elf32_External_Rela),
splt->contents + h->plt.offset + plt_off2);
/* Fill in the offset to the first PLT entry, where to "jump". */
@@ -2225,7 +2231,7 @@ elf_cris_finish_dynamic_symbol (output_b
+ got_offset);
rela.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_JUMP_SLOT);
rela.r_addend = 0;
- loc = srela->contents + gotplt_index * sizeof (Elf32_External_Rela);
+ loc = srela->contents + rela_plt_index * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
}
brgds, H-P