[3/3] MIPS/LD: Accept high-part relocations in PIC code with absolute symbols

Message ID alpine.LFD.2.21.1811252220390.27071@eddie.linux-mips.org
State New
Headers show
Series
  • MIPS/LD: Fix high-part relocations in PIC code with absolute symbols
Related show

Commit Message

Maciej W. Rozycki Nov. 25, 2018, 10:52 p.m.
Accept R_MIPS_HI16, R_MIPS_HIGHER and R_MIPS_HIGHEST relocations and 
their compressed counterparts in PIC code where the symbol referred is 
absolute.  Such an operation is meaningful, because an absolute symbol 
effectively is a constant the calculation of the value of which has been 
deferred to the static link time, and which is not going to change any 
further at the dynamic load time.  Therefore there is no need ever to 
refuse the use of these relocations with such symbols, as the resulting 
run-time value observed by the program will be correct even in PIC code.

This is not the case with R_MIPS_26 and its compressed counterparts, 
because the run-time value calculated by the instructions these 
relocations are used with depends on the address of the instruction 
itself, and that can change according to the base address used by the 
dynamic loader.  Therefore these relocations have to continue being 
rejected in PIC code even with absolute symbols.

This allows successful linking of code that relies on previous linker 
behavior up to commit 861fb55ab50a ("Defer allocation of R_MIPS_REL32 
GOT slots"), <https://sourceware.org/ml/binutils/2008-08/msg00096.html>, 
which introduced the problematic check missing this special exception 
for absolute symbols.

	bfd/
	* elfxx-mips.c (_bfd_mips_elf_check_relocs) <R_MIPS16_HI16>
	<R_MIPS_HI16, R_MIPS_HIGHER, R_MIPS_HIGHEST, R_MICROMIPS_HI16>
	<R_MICROMIPS_HIGHER, R_MICROMIPS_HIGHEST>: Also accept an 
	absolute symbol in PIC code.

	ld/
	* testsuite/ld-mips-elf/pic-reloc-0.d: New test.
	* testsuite/ld-mips-elf/pic-reloc-1.d: New test.
	* testsuite/ld-mips-elf/pic-reloc-2.d: New test.
	* testsuite/ld-mips-elf/pic-reloc-3.d: New test.
	* testsuite/ld-mips-elf/pic-reloc-4.d: New test.
	* testsuite/ld-mips-elf/pic-reloc-absolute-hi.ld: New test 
	linker script.
	* testsuite/ld-mips-elf/pic-reloc-absolute-lo.ld: New test
	linker script.
	* testsuite/ld-mips-elf/pic-reloc-ordinary.ld: New test linker 
	script.
	* testsuite/ld-mips-elf/pic-reloc-j.s: New test source.
	* testsuite/ld-mips-elf/pic-reloc-lui.s: New test source.
	* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
---
 bfd/elfxx-mips.c                                  |    4 ++++
 ld/testsuite/ld-mips-elf/mips-elf.exp             |    7 +++++++
 ld/testsuite/ld-mips-elf/pic-reloc-0.d            |    7 +++++++
 ld/testsuite/ld-mips-elf/pic-reloc-1.d            |   14 ++++++++++++++
 ld/testsuite/ld-mips-elf/pic-reloc-2.d            |    7 +++++++
 ld/testsuite/ld-mips-elf/pic-reloc-3.d            |    7 +++++++
 ld/testsuite/ld-mips-elf/pic-reloc-4.d            |    9 +++++++++
 ld/testsuite/ld-mips-elf/pic-reloc-absolute-hi.ld |    6 ++++++
 ld/testsuite/ld-mips-elf/pic-reloc-absolute-lo.ld |    6 ++++++
 ld/testsuite/ld-mips-elf/pic-reloc-j.s            |   11 +++++++++++
 ld/testsuite/ld-mips-elf/pic-reloc-lui.s          |   13 +++++++++++++
 ld/testsuite/ld-mips-elf/pic-reloc-ordinary.ld    |    6 ++++++
 12 files changed, 97 insertions(+)

binutils-mips-reloc-pic-absolute.diff

Patch

Index: src/bfd/elfxx-mips.c
===================================================================
--- src.orig/bfd/elfxx-mips.c
+++ src/bfd/elfxx-mips.c
@@ -9061,6 +9061,10 @@  _bfd_mips_elf_check_relocs (bfd *abfd, s
 	      if (r_symndx == STN_UNDEF)
 		break;
 
+	      /* Likewise an absolute symbol.  */
+	      if (bfd_is_abs_symbol (&h->root))
+		break;
+
 	      /* R_MIPS_HI16 against _gp_disp is used for $gp setup,
 		 and has a special meaning.  */
 	      if (!NEWABI_P (abfd) && h != NULL
Index: src/ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
--- src.orig/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ src/ld/testsuite/ld-mips-elf/mips-elf.exp
@@ -1629,3 +1629,10 @@  if $has_abi(n64) {
     run_mips_undefweak_test "shared library (n64, microMIPS, hidden)" \
 						    n64 dso umips hidden
 }
+
+# PIC relocation acceptance tests.
+run_dump_test "pic-reloc-0"
+run_dump_test "pic-reloc-1"
+run_dump_test "pic-reloc-2"
+run_dump_test "pic-reloc-3"
+run_dump_test "pic-reloc-4"
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-0.d
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-0.d
@@ -0,0 +1,7 @@ 
+#name: MIPS PIC relocation 0
+#ld: -shared -T pic-reloc-ordinary.ld
+#target: [check_shared_lib_support]
+#source: pic-reloc-lui.s
+#error: \A[^\n]*: in function `foo':\n
+#error:   \(\.text\+0x0\): relocation R_MIPS_HI16 against `bar' cannot be used when making a shared object; recompile with -fPIC\n
+#error:   \(\.text\+0x8\): relocation R_MIPS_HI16 against `bar' cannot be used when making a shared object; recompile with -fPIC\Z
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-1.d
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-1.d
@@ -0,0 +1,14 @@ 
+#name: MIPS PIC relocation 1
+#ld: -shared -T pic-reloc-absolute-hi.ld
+#objdump: -d --prefix-addresses --show-raw-insn
+#target: [check_shared_lib_support]
+#source: pic-reloc-lui.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 3c021234 	lui	v0,0x1234
+[0-9a-f]+ <[^>]*> 24425678 	addiu	v0,v0,22136
+[0-9a-f]+ <[^>]*> 3c021234 	lui	v0,0x1234
+[0-9a-f]+ <[^>]*> 24425678 	addiu	v0,v0,22136
+	\.\.\.
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-2.d
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-2.d
@@ -0,0 +1,7 @@ 
+#name: MIPS PIC relocation 2
+#ld: -shared -T pic-reloc-ordinary.ld
+#target: [check_shared_lib_support]
+#source: pic-reloc-j.s
+#error: \A[^\n]*: in function `foo':\n
+#error:   \(\.text\+0x0\): relocation R_MIPS_26 against `bar' cannot be used when making a shared object; recompile with -fPIC\n
+#error:   \(\.text\+0x8\): relocation R_MIPS_26 against `bar' cannot be used when making a shared object; recompile with -fPIC\Z
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-3.d
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-3.d
@@ -0,0 +1,7 @@ 
+#name: MIPS PIC relocation 3
+#ld: -shared -T pic-reloc-absolute-lo.ld
+#target: [check_shared_lib_support]
+#source: pic-reloc-j.s
+#error: \A[^\n]*: in function `foo':\n
+#error:   \(\.text\+0x0\): relocation R_MIPS_26 against `bar' cannot be used when making a shared object; recompile with -fPIC\n
+#error:   \(\.text\+0x8\): relocation R_MIPS_26 against `bar' cannot be used when making a shared object; recompile with -fPIC\Z
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-4.d
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-4.d
@@ -0,0 +1,9 @@ 
+#name: MIPS PIC relocation 4
+#ld: -shared -T pic-reloc-absolute-hi.ld
+#target: [check_shared_lib_support]
+#source: pic-reloc-j.s
+#error: \A[^\n]*: in function `foo':\n
+#error:   \(\.text\+0x0\): relocation R_MIPS_26 against `bar' cannot be used when making a shared object; recompile with -fPIC\n
+#error:   \(\.text\+0x8\): relocation R_MIPS_26 against `bar' cannot be used when making a shared object; recompile with -fPIC\n
+#error:   \(\.text\+0x0\): relocation truncated to fit: R_MIPS_26 against `bar'\n
+#error:   \(\.text\+0x8\): relocation truncated to fit: R_MIPS_26 against `bar'\Z
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-absolute-hi.ld
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-absolute-hi.ld
@@ -0,0 +1,6 @@ 
+SECTIONS
+{
+  bar = 0x12345678;
+  .text : { *(.text) }
+  /DISCARD/ : { *(*) }
+}
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-absolute-lo.ld
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-absolute-lo.ld
@@ -0,0 +1,6 @@ 
+SECTIONS
+{
+  bar = 0x2345678;
+  .text : { *(.text) }
+  /DISCARD/ : { *(*) }
+}
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-j.s
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-j.s
@@ -0,0 +1,11 @@ 
+	.text
+	.globl	foo
+	.ent	foo
+foo:
+	j	bar
+	j	bar
+	.end	foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-lui.s
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-lui.s
@@ -0,0 +1,13 @@ 
+	.text
+	.globl	foo
+	.ent	foo
+foo:
+	lui	$2, %hi(bar)
+	addiu	$2, %lo(bar)
+	lui	$2, %hi(bar)
+	addiu	$2, %lo(bar)
+	.end	foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
Index: src/ld/testsuite/ld-mips-elf/pic-reloc-ordinary.ld
===================================================================
--- /dev/null
+++ src/ld/testsuite/ld-mips-elf/pic-reloc-ordinary.ld
@@ -0,0 +1,6 @@ 
+SECTIONS
+{
+  bar = foo;
+  .text : { *(.text) }
+  /DISCARD/ : { *(*) }
+}