This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Stabilize .rel.dyn sort on MIPS
- From: Richard Sandiford <richard at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Thu, 19 Oct 2006 10:24:17 +0100
- Subject: Stabilize .rel.dyn sort on MIPS
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