This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]