[PATCH] Let more MIPS relocs refer to __gnu_local_gp
Richard Sandiford
rdsandiford@googlemail.com
Sat Jun 28 16:31:00 GMT 2008
__gnu_local_gp is a special symbol that always evaluates to the
current value of GP. We currently hard-code the list of relocations
that can refer to it:
case R_MIPS_HI16:
case R_MIPS_LO16:
case R_MIPS_GPREL16:
case R_MIPS_GPREL32:
case R_MIPS_LITERAL:
case R_MIPS16_HI16:
case R_MIPS16_LO16:
case R_MIPS16_GPREL:
gp0 = _bfd_get_gp_value (input_bfd);
gp = _bfd_get_gp_value (abfd);
if (dynobj)
gp += mips_elf_adjust_gp (abfd, mips_elf_got_info (dynobj, NULL),
input_bfd);
break;
Other relocations treat __gnu_local_gp as -1.
I want to be able to load __gnu_local_gp from a MIPS16 constant pool.
Rather than extending the list, I think we should allow all relocation
types to refer to __gnu_local_gp.
The real only downside is that there will be more needless calculations
of GP and GP0. (The current calculations are already redundant in many
cases; the patch just makes them more so.)
On the other hand, the sequence is relatively cheap, and it becomes
even cheaper after if we cache the GOT information in the hash table.
I'll send a patch for that in a sec.
Tested on mips64-linux-gnu and mips64el-linux-gnu. OK to install?
Richard
bfd/
* elfxx-mips.c (mips_elf_calculate_relocation): Calculate GP and GP0
for all relocation types. Allow any type of relocation to refer to
__gnu_local_gp.
ld/testsuite/
* ld-mips-elf/no-shared-1-o32.s,
ld-mips-elf/no-shared-1-o32.d,
ld-mips-elf/no-shared-1-n32.d,
ld-mips-elf/no-shared-1-n64.s,
ld-mips-elf/no-shared-1-n64.d,
ld-mips-elf/no-shared-1.ld: New tests.
* ld-mips-elf/mips-elf.exp: Run them.
Index: bfd/elfxx-mips.c
===================================================================
--- bfd/elfxx-mips.c 2008-06-28 17:14:12.000000000 +0100
+++ bfd/elfxx-mips.c 2008-06-28 17:14:15.000000000 +0100
@@ -4099,12 +4099,12 @@ mips_elf_calculate_relocation (bfd *abfd
bfd_vma symbol = 0;
/* The final GP value to be used for the relocatable, executable, or
shared object file being produced. */
- bfd_vma gp = MINUS_ONE;
+ bfd_vma gp;
/* The place (section offset or address) of the storage unit being
relocated. */
bfd_vma p;
/* The value of GP used to create the relocatable object. */
- bfd_vma gp0 = MINUS_ONE;
+ bfd_vma gp0;
/* The offset into the global offset table at which the address of
the relocation entry symbol, adjusted by the addend, resides
during execution. */
@@ -4367,8 +4367,17 @@ mips_elf_calculate_relocation (bfd *abfd
local_p = mips_elf_local_relocation_p (input_bfd, relocation,
local_sections, TRUE);
- /* If we haven't already determined the GOT offset, or the GP value,
- and we're going to need it, get it now. */
+ gp0 = _bfd_get_gp_value (input_bfd);
+ gp = _bfd_get_gp_value (abfd);
+ if (dynobj)
+ gp += mips_elf_adjust_gp (abfd, mips_elf_got_info (dynobj, NULL),
+ input_bfd);
+
+ if (gnu_local_gp_p)
+ symbol = gp;
+
+ /* If we haven't already determined the GOT offset, oand we're going
+ to need it, get it now. */
switch (r_type)
{
case R_MIPS_GOT_PAGE:
@@ -4449,29 +4458,8 @@ mips_elf_calculate_relocation (bfd *abfd
/* Convert GOT indices to actual offsets. */
g = mips_elf_got_offset_from_index (dynobj, abfd, input_bfd, g);
break;
-
- case R_MIPS_HI16:
- case R_MIPS_LO16:
- case R_MIPS_GPREL16:
- case R_MIPS_GPREL32:
- case R_MIPS_LITERAL:
- case R_MIPS16_HI16:
- case R_MIPS16_LO16:
- case R_MIPS16_GPREL:
- gp0 = _bfd_get_gp_value (input_bfd);
- gp = _bfd_get_gp_value (abfd);
- if (dynobj)
- gp += mips_elf_adjust_gp (abfd, mips_elf_got_info (dynobj, NULL),
- input_bfd);
- break;
-
- default:
- break;
}
- if (gnu_local_gp_p)
- symbol = gp;
-
/* Relocations against the VxWorks __GOTT_BASE__ and __GOTT_INDEX__
symbols are resolved by the loader. Add them to .rela.dyn. */
if (h != NULL && is_gott_symbol (info, &h->root))
Index: ld/testsuite/ld-mips-elf/no-shared-1-o32.s
===================================================================
--- /dev/null 2008-06-21 07:33:38.548096750 +0100
+++ ld/testsuite/ld-mips-elf/no-shared-1-o32.s 2008-06-28 17:14:15.000000000 +0100
@@ -0,0 +1,13 @@
+ .abicalls
+ .text
+ .globl __start
+ .ent __start
+__start:
+ lui $2,%hi(__gnu_local_gp)
+ addiu $2,$2,%lo(__gnu_local_gp)
+ lw $2,%got(__gnu_local_gp)($gp)
+ lw $2,%call16(__gnu_local_gp)($gp)
+ .end __start
+
+ .data
+ .4byte __gnu_local_gp
Index: ld/testsuite/ld-mips-elf/no-shared-1-o32.d
===================================================================
--- /dev/null 2008-06-21 07:33:38.548096750 +0100
+++ ld/testsuite/ld-mips-elf/no-shared-1-o32.d 2008-06-28 17:14:15.000000000 +0100
@@ -0,0 +1,24 @@
+#as: -mabi=32 -EB
+#ld: -melf32btsmip -T no-shared-1.ld
+#objdump: -dr -j.text -j.data -j.got
+
+.*
+
+
+Disassembly of section \.text:
+
+00050000 <__start>:
+ 50000: 3c020007 lui v0,0x7
+ 50004: 24428000 addiu v0,v0,-32768
+ 50008: 8f828018 lw v0,-32744\(gp\)
+ 5000c: 8f828018 lw v0,-32744\(gp\)
+#...
+Disassembly of section \.data:
+
+00060000 <\.data>:
+ 60000: 00068000 .*
+#...
+Disassembly of section \.got:
+
+00060010 <_GLOBAL_OFFSET_TABLE_>:
+ 60010: 00000000 80000000 00068000 .*
Index: ld/testsuite/ld-mips-elf/no-shared-1-n32.d
===================================================================
--- /dev/null 2008-06-21 07:33:38.548096750 +0100
+++ ld/testsuite/ld-mips-elf/no-shared-1-n32.d 2008-06-28 17:14:15.000000000 +0100
@@ -0,0 +1,25 @@
+#as: -mabi=n32 -EB
+#source: no-shared-1-o32.s
+#ld: -melf32btsmipn32 -T no-shared-1.ld
+#objdump: -dr -j.text -j.data -j.got
+
+.*
+
+
+Disassembly of section \.text:
+
+00050000 <__start>:
+ 50000: 3c020007 lui v0,0x7
+ 50004: 24428000 addiu v0,v0,-32768
+ 50008: 8f828018 lw v0,-32744\(gp\)
+ 5000c: 8f828018 lw v0,-32744\(gp\)
+#...
+Disassembly of section \.data:
+
+00060000 <\.data>:
+ 60000: 00068000 .*
+#...
+Disassembly of section \.got:
+
+00060010 <_GLOBAL_OFFSET_TABLE_>:
+ 60010: 00000000 80000000 00068000 .*
Index: ld/testsuite/ld-mips-elf/no-shared-1-n64.s
===================================================================
--- /dev/null 2008-06-21 07:33:38.548096750 +0100
+++ ld/testsuite/ld-mips-elf/no-shared-1-n64.s 2008-06-28 17:14:15.000000000 +0100
@@ -0,0 +1,13 @@
+ .abicalls
+ .text
+ .globl __start
+ .ent __start
+__start:
+ lui $2,%hi(__gnu_local_gp)
+ daddiu $2,$2,%lo(__gnu_local_gp)
+ ld $2,%got(__gnu_local_gp)($gp)
+ ld $2,%call16(__gnu_local_gp)($gp)
+ .end __start
+
+ .data
+ .8byte __gnu_local_gp
Index: ld/testsuite/ld-mips-elf/no-shared-1-n64.d
===================================================================
--- /dev/null 2008-06-21 07:33:38.548096750 +0100
+++ ld/testsuite/ld-mips-elf/no-shared-1-n64.d 2008-06-28 17:14:15.000000000 +0100
@@ -0,0 +1,26 @@
+#as: -mabi=64 -EB
+#ld: -melf64btsmip -T no-shared-1.ld
+#objdump: -dr -j.text -j.data -j.got
+
+.*
+
+
+Disassembly of section \.text:
+
+0000000000050000 <__start>:
+ 50000: 3c020007 lui v0,0x7
+ 50004: 64428000 daddiu v0,v0,-32768
+ 50008: df828020 ld v0,-32736\(gp\)
+ 5000c: df828020 ld v0,-32736\(gp\)
+#...
+Disassembly of section \.data:
+
+0000000000060000 <\.data>:
+ 60000: 00000000 .*
+ 60004: 00068000 .*
+#...
+Disassembly of section \.got:
+
+0000000000060010 <_GLOBAL_OFFSET_TABLE_>:
+ \.\.\.
+ 60018: 80000000 00000000 00000000 00068000 .*
Index: ld/testsuite/ld-mips-elf/no-shared-1.ld
===================================================================
--- /dev/null 2008-06-21 07:33:38.548096750 +0100
+++ ld/testsuite/ld-mips-elf/no-shared-1.ld 2008-06-28 17:14:15.000000000 +0100
@@ -0,0 +1,11 @@
+SECTIONS
+{
+ . = 0x50000;
+ .text : { *(.text) }
+ .MIPS.stubs : { *(.MIPS.stubs) }
+
+ . = 0x60000;
+ .data : { *(.data) }
+ _gp = ALIGN (16) + 0x7ff0;
+ .got : { *(.got) }
+}
Index: ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
--- ld/testsuite/ld-mips-elf/mips-elf.exp 2008-06-28 17:09:21.000000000 +0100
+++ ld/testsuite/ld-mips-elf/mips-elf.exp 2008-06-28 17:14:15.000000000 +0100
@@ -79,6 +79,15 @@ if { $linux_gnu } {
run_dump_test "multi-got-hidden-2"
}
+# Test __gnu_local_gp accesses
+if { $linux_gnu } {
+ run_dump_test "no-shared-1-o32"
+ if { $has_newabi } {
+ run_dump_test "no-shared-1-n32"
+ run_dump_test "no-shared-1-n64"
+ }
+}
+
if $has_newabi {
run_dump_test "elf-rel-got-n32"
run_dump_test "elf-rel-xgot-n32"
More information about the Binutils
mailing list