Stabilize .rel.dyn sort on MIPS

Richard Sandiford richard@codesourcery.com
Thu Oct 19 14:07:00 GMT 2006


Since I'm altering a lot of the MIPS ld testsuite anyway, I thought I
might as well fix something that has been bugging me for a while, namely
that elfxx-mips.c's sort of .rel.dyn is unstable.  It orders entries by
increasing symbol index, but the relative order of entries with the same
index is arbitrary.

The patch below sorts entries against the same symbol by increasing
r_offset.  As well as making the results predictable between hosts,
it should also help the dynamic linker make slightly better use of cache.

In a fit of excess analness, I also fixed a case where the difference
between two unsigned 32-bit values was being converted to an int
comparison result.  This is hardly likely to trigger in practice,
but...

Tested on mips{,64}{,el}-{elf,linux-gnu} and mips-sgi-irix6.5.
OK to install?

Richard


bfd/
	* elfxx-mips.c (sort_dynamic_relocs): Sort relocations against the
	same symbol by increasing r_offset.
	(sort_dynamic_relocs_64): Likewise.  Fix comparisons between very
	large and very small symbol indexes.

ld/testsuite/
	* ld-mips-elf/tlslib-o32-hidden.got: Sort relocations against the
	same symbol in order of increasing r_offset.
	* ld-mips-elf/tls-multi-got-1.got: Likewise.
	* ld-mips-elf/tls-hidden3.r: Likewise.
	* ld-mips-elf/tls-hidden4.r: Likewise.

diff -udpr ../src.1/bfd/elfxx-mips.c ./bfd/elfxx-mips.c
--- ./bfd/elfxx-mips.c	2006-10-18 06:09:40.000000000 -0700
+++ ./bfd/elfxx-mips.c	2006-10-19 01:25:27.000000000 -0700
@@ -1692,11 +1692,20 @@ sort_dynamic_relocs (const void *arg1, c
 {
   Elf_Internal_Rela int_reloc1;
   Elf_Internal_Rela int_reloc2;
+  int diff;
 
   bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
   bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
 
-  return ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info);
+  diff = ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info);
+  if (diff != 0)
+    return diff;
+
+  if (int_reloc1.r_offset < int_reloc2.r_offset)
+    return -1;
+  if (int_reloc1.r_offset > int_reloc2.r_offset)
+    return 1;
+  return 0;
 }
 
 /* Like sort_dynamic_relocs, but used for elf64 relocations.  */
@@ -1714,8 +1723,16 @@ sort_dynamic_relocs_64 (const void *arg1
   (*get_elf_backend_data (reldyn_sorting_bfd)->s->swap_reloc_in)
     (reldyn_sorting_bfd, arg2, int_reloc2);
 
-  return (ELF64_R_SYM (int_reloc1[0].r_info)
-	  - ELF64_R_SYM (int_reloc2[0].r_info));
+  if (ELF64_R_SYM (int_reloc1[0].r_info) < ELF64_R_SYM (int_reloc2[0].r_info))
+    return -1;
+  if (ELF64_R_SYM (int_reloc1[0].r_info) > ELF64_R_SYM (int_reloc2[0].r_info))
+    return 1;
+
+  if (int_reloc1[0].r_offset < int_reloc2[0].r_offset)
+    return -1;
+  if (int_reloc1[0].r_offset > int_reloc2[0].r_offset)
+    return 1;
+  return 0;
 #else
   abort ();
 #endif
diff -udpr ../src.1/ld/testsuite/ld-mips-elf/tls-hidden3.r ./ld/testsuite/ld-mips-elf/tls-hidden3.r
--- ./ld/testsuite/ld-mips-elf/tls-hidden3.r	2006-03-27 03:30:54.000000000 -0800
+++ ./ld/testsuite/ld-mips-elf/tls-hidden3.r	2006-10-19 02:13:03.000000000 -0700
@@ -7,7 +7,7 @@ Relocation section '\.rel\.dyn' at offse
 # is that there is exactly one entry per GOT TLS slot.
 #
 00090020  0000002f R_MIPS_TLS_TPREL3
-0009002c  0000002f R_MIPS_TLS_TPREL3
 00090024  0000002f R_MIPS_TLS_TPREL3
 00090028  0000002f R_MIPS_TLS_TPREL3
+0009002c  0000002f R_MIPS_TLS_TPREL3
 00090030  .*03 R_MIPS_REL32      00000000   undef
diff -udpr ../src.1/ld/testsuite/ld-mips-elf/tls-hidden4.r ./ld/testsuite/ld-mips-elf/tls-hidden4.r
--- ./ld/testsuite/ld-mips-elf/tls-hidden4.r	2006-03-27 03:30:54.000000000 -0800
+++ ./ld/testsuite/ld-mips-elf/tls-hidden4.r	2006-10-19 02:16:14.000000000 -0700
@@ -7,13 +7,13 @@ Relocation section '\.rel\.dyn' at offse
 # important thing is that there is exactly one entry per GOT TLS slot
 # and that the addresses match those in the .got dump.
 #
-001d00d4  0000002f R_MIPS_TLS_TPREL3
-001d00d8  0000002f R_MIPS_TLS_TPREL3
-001d00d0  0000002f R_MIPS_TLS_TPREL3
-001d00cc  0000002f R_MIPS_TLS_TPREL3
-001c4088  0000002f R_MIPS_TLS_TPREL3
-001c408c  0000002f R_MIPS_TLS_TPREL3
 001c4080  0000002f R_MIPS_TLS_TPREL3
 001c4084  0000002f R_MIPS_TLS_TPREL3
+001c4088  0000002f R_MIPS_TLS_TPREL3
+001c408c  0000002f R_MIPS_TLS_TPREL3
+001d00cc  0000002f R_MIPS_TLS_TPREL3
+001d00d0  0000002f R_MIPS_TLS_TPREL3
+001d00d4  0000002f R_MIPS_TLS_TPREL3
+001d00d8  0000002f R_MIPS_TLS_TPREL3
 .* R_MIPS_REL32 .*
 #pass
diff -udpr ../src.1/ld/testsuite/ld-mips-elf/tlslib-o32-hidden.got ./ld/testsuite/ld-mips-elf/tlslib-o32-hidden.got
--- ./ld/testsuite/ld-mips-elf/tlslib-o32-hidden.got	2006-10-18 07:32:42.000000000 -0700
+++ ./ld/testsuite/ld-mips-elf/tlslib-o32-hidden.got	2006-10-19 02:13:54.000000000 -0700
@@ -4,9 +4,9 @@
 DYNAMIC RELOCATION RECORDS
 OFFSET   TYPE              VALUE 
 00000000 R_MIPS_NONE       \*ABS\*
-000403bc R_MIPS_TLS_DTPMOD32  \*ABS\*
-000403b4 R_MIPS_TLS_DTPMOD32  \*ABS\*
 000403b0 R_MIPS_TLS_TPREL32  \*ABS\*
+000403b4 R_MIPS_TLS_DTPMOD32  \*ABS\*
+000403bc R_MIPS_TLS_DTPMOD32  \*ABS\*
 
 
 Contents of section .got:
diff -udpr ../src.1/ld/testsuite/ld-mips-elf/tls-multi-got-1.got ./ld/testsuite/ld-mips-elf/tls-multi-got-1.got
--- ./ld/testsuite/ld-mips-elf/tls-multi-got-1.got	2006-10-18 06:29:24.000000000 -0700
+++ ./ld/testsuite/ld-mips-elf/tls-multi-got-1.got	2006-10-19 02:15:15.000000000 -0700
@@ -4,14 +4,14 @@
 DYNAMIC RELOCATION RECORDS
 OFFSET   TYPE              VALUE 
 00000000 R_MIPS_NONE       \*ABS\*
-001495b0 R_MIPS_TLS_DTPMOD32  \*ABS\*
 0013f928 R_MIPS_TLS_DTPMOD32  \*ABS\*
-001495bc R_MIPS_TLS_DTPMOD32  tlsvar_gd
-001495c0 R_MIPS_TLS_DTPREL32  tlsvar_gd
+001495b0 R_MIPS_TLS_DTPMOD32  \*ABS\*
 0013f934 R_MIPS_TLS_DTPMOD32  tlsvar_gd
 0013f938 R_MIPS_TLS_DTPREL32  tlsvar_gd
-001495b8 R_MIPS_TLS_TPREL32  tlsvar_ie
+001495bc R_MIPS_TLS_DTPMOD32  tlsvar_gd
+001495c0 R_MIPS_TLS_DTPREL32  tlsvar_gd
 0013f930 R_MIPS_TLS_TPREL32  tlsvar_ie
+001495b8 R_MIPS_TLS_TPREL32  tlsvar_ie
 00143f5c R_MIPS_REL32      sym_1_9526
 #...
 00139bb0 R_MIPS_REL32      sym_2_8654



More information about the Binutils mailing list