[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