PowerPC64 undefined weak visibility vs GOT optimisation

Alan Modra amodra@gmail.com
Tue Mar 2 11:10:34 GMT 2021


Undefined weak symbols with non-default visibility are seen as local
by SYMBOL_REFERENCES_LOCAL.  This stops a got indirect to relative
optimisation for them, so that pies and dlls don't get non-zero values
when loading somewhere other than the address they are linked at
(which always happens).  The optimisation could be allowed for pdes,
but I thought it best not to allow it there too.

bfd/
	* elf64-ppc.c (ppc64_elf_relocate_section): Don't optimise got
	indirect to pc-relative or toc-relative for undefined symbols.
ld/
	* testsuite/ld-powerpc/startstop.d,
	* testsuite/ld-powerpc/startstop.r,
	* testsuite/ld-powerpc/startstop.s: New test.
	* testsuite/ld-powerpc/weak1.d,
	* testsuite/ld-powerpc/weak1.r,
	* testsuite/ld-powerpc/weak1.s,
	* testsuite/ld-powerpc/weak1so.d,
	* testsuite/ld-powerpc/weak1so.r: New tests.
	* testsuite/ld-powerpc/powerpc.exp: Run them.

diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 8a32fa47f7..ab0e0d33aa 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -16084,6 +16084,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 	    break;
 	  from = TOCstart + htab->sec_info[input_section->id].toc_off;
 	  if (relocation + addend - from + 0x8000 < 0x10000
+	      && sec != NULL
+	      && sec->output_section != NULL
+	      && !discarded_section (sec)
 	      && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
 	    {
 	      insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
@@ -16104,6 +16107,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 	    break;
 	  from = TOCstart + htab->sec_info[input_section->id].toc_off;
 	  if (relocation + addend - from + 0x80008000ULL < 0x100000000ULL
+	      && sec != NULL
+	      && sec->output_section != NULL
+	      && !discarded_section (sec)
 	      && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
 	    {
 	      insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
@@ -16132,6 +16138,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 		  + input_section->output_section->vma
 		  + input_section->output_offset);
 	  if (!(relocation - from + (1ULL << 33) < 1ULL << 34
+		&& sec != NULL
+		&& sec->output_section != NULL
+		&& !discarded_section (sec)
 		&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf))))
 	    break;
 
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index 45485e6c5d..2ac02b1c02 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -344,6 +344,15 @@ set ppc64elftests {
     {"group3" "-melf64ppc -e foo" "" "-a64" {group3.s group2.s group1.s}
 	{{objdump {-d} group2.d}
 	 {readelf {-s} group3.sym}} "group3"}
+    {"weak1" "-melf64ppc --hash-style=both" ""
+	"-a64 -mpower10" {weak1.s}
+	{{objdump -d weak1.d} {readelf {-srW} weak1.r}} "weak1"}
+    {"weak1.so" "-shared -melf64ppc --hash-style=both" ""
+	"-a64 -mpower10" {weak1.s}
+	{{objdump -d weak1so.d} {readelf {-srW} weak1so.r}} "weak1.so"}
+    {"startstop" "-shared -melf64ppc --hash-style=sysv --gc-sections -z start-stop-gc" ""
+	"-a64 -mpower10" {startstop.s}
+	{{objdump -d startstop.d} {readelf {-rW} startstop.r}} "startstop.so"}
 }
 
 set ppceabitests {
diff --git a/ld/testsuite/ld-powerpc/startstop.d b/ld/testsuite/ld-powerpc/startstop.d
new file mode 100644
index 0000000000..2bf4c73cbf
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/startstop.d
@@ -0,0 +1,10 @@
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+140 <_start>:
+ 140:	(04 10 00 01|01 00 10 04) 	pld     r3,66000
+ 144:	(e4 60 01 d0|d0 01 60 e4) 
+ 148:	(04 10 00 01|01 00 10 04) 	pld     r4,65984
+ 14c:	(e4 80 01 c0|c0 01 80 e4) 
diff --git a/ld/testsuite/ld-powerpc/startstop.r b/ld/testsuite/ld-powerpc/startstop.r
new file mode 100644
index 0000000000..9a583fbfad
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/startstop.r
@@ -0,0 +1,2 @@
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-powerpc/startstop.s b/ld/testsuite/ld-powerpc/startstop.s
new file mode 100644
index 0000000000..8e88a72157
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/startstop.s
@@ -0,0 +1,16 @@
+ .weak __start_xx
+ .weak __stop_xx
+
+ .global _start
+_start:
+  pld 3,__start_xx@got@pcrel
+  pld 4,__stop_xx@got@pcrel
+
+ .section xx,"a",unique,0
+ .byte 0
+
+ .section xx,"a",unique,1
+ .byte 1
+
+ .section xx,"a",unique,2
+ .byte 2
diff --git a/ld/testsuite/ld-powerpc/weak1.d b/ld/testsuite/ld-powerpc/weak1.d
new file mode 100644
index 0000000000..c0127539dd
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/weak1.d
@@ -0,0 +1,26 @@
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+.*0c0 <_start>:
+.*0c0:	(04 10 00 01|01 00 10 04) 	pld     r3,65888
+.*0c4:	(e4 60 01 60|60 01 60 e4) 
+.*0c8:	(04 10 00 01|01 00 10 04) 	pld     r3,65856
+.*0cc:	(e4 60 01 40|40 01 60 e4) 
+.*0d0:	(04 10 00 01|01 00 10 04) 	pld     r3,65864
+.*0d4:	(e4 60 01 48|48 01 60 e4) 
+.*0d8:	(04 10 00 01|01 00 10 04) 	pld     r3,65848
+.*0dc:	(e4 60 01 38|38 01 60 e4) 
+.*0e0:	(e8 62 80 20|20 80 62 e8) 	ld      r3,-32736\(r2\)
+.*0e4:	(e8 62 80 08|08 80 62 e8) 	ld      r3,-32760\(r2\)
+.*0e8:	(e8 62 80 18|18 80 62 e8) 	ld      r3,-32744\(r2\)
+.*0ec:	(e8 62 80 10|10 80 62 e8) 	ld      r3,-32752\(r2\)
+.*0f0:	(60 00 00 00|00 00 00 60) 	nop
+.*0f4:	(e8 62 80 20|20 80 62 e8) 	ld      r3,-32736\(r2\)
+.*0f8:	(60 00 00 00|00 00 00 60) 	nop
+.*0fc:	(e8 62 80 08|08 80 62 e8) 	ld      r3,-32760\(r2\)
+.*100:	(60 00 00 00|00 00 00 60) 	nop
+.*104:	(e8 62 80 18|18 80 62 e8) 	ld      r3,-32744\(r2\)
+.*108:	(60 00 00 00|00 00 00 60) 	nop
+.*10c:	(e8 62 80 10|10 80 62 e8) 	ld      r3,-32752\(r2\)
diff --git a/ld/testsuite/ld-powerpc/weak1.r b/ld/testsuite/ld-powerpc/weak1.r
new file mode 100644
index 0000000000..7d73f38cbb
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/weak1.r
@@ -0,0 +1,5 @@
+
+There are no relocations in this file.
+
+Symbol table '\.symtab' .*
+#pass
diff --git a/ld/testsuite/ld-powerpc/weak1.s b/ld/testsuite/ld-powerpc/weak1.s
new file mode 100644
index 0000000000..0f370d974b
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/weak1.s
@@ -0,0 +1,22 @@
+ .weak x1, x2, x3, x4
+ .protected x2
+ .hidden x3
+ .internal x4
+ .global _start
+_start:
+ pld 3,x1@got@pcrel
+ pld 3,x2@got@pcrel
+ pld 3,x3@got@pcrel
+ pld 3,x4@got@pcrel
+ ld 3,x1@got(2)
+ ld 3,x2@got(2)
+ ld 3,x3@got(2)
+ ld 3,x4@got(2)
+ addis 9,2,x1@got@ha
+ ld 3,x1@got@l(9)
+ addis 9,2,x2@got@ha
+ ld 3,x2@got@l(9)
+ addis 9,2,x3@got@ha
+ ld 3,x3@got@l(9)
+ addis 9,2,x4@got@ha
+ ld 3,x4@got@l(9)
diff --git a/ld/testsuite/ld-powerpc/weak1so.d b/ld/testsuite/ld-powerpc/weak1so.d
new file mode 100644
index 0000000000..0d34b3b484
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/weak1so.d
@@ -0,0 +1,26 @@
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+1c0 <_start>:
+ 1c0:	(04 10 00 01|01 00 10 04) 	pld     r3,66144
+ 1c4:	(e4 60 02 60|60 02 60 e4) 
+ 1c8:	(04 10 00 01|01 00 10 04) 	pld     r3,66112
+ 1cc:	(e4 60 02 40|40 02 60 e4) 
+ 1d0:	(04 10 00 01|01 00 10 04) 	pld     r3,66120
+ 1d4:	(e4 60 02 48|48 02 60 e4) 
+ 1d8:	(04 10 00 01|01 00 10 04) 	pld     r3,66104
+ 1dc:	(e4 60 02 38|38 02 60 e4) 
+ 1e0:	(e8 62 80 20|20 80 62 e8) 	ld      r3,-32736\(r2\)
+ 1e4:	(e8 62 80 08|08 80 62 e8) 	ld      r3,-32760\(r2\)
+ 1e8:	(e8 62 80 18|18 80 62 e8) 	ld      r3,-32744\(r2\)
+ 1ec:	(e8 62 80 10|10 80 62 e8) 	ld      r3,-32752\(r2\)
+ 1f0:	(60 00 00 00|00 00 00 60) 	nop
+ 1f4:	(e8 62 80 20|20 80 62 e8) 	ld      r3,-32736\(r2\)
+ 1f8:	(60 00 00 00|00 00 00 60) 	nop
+ 1fc:	(e8 62 80 08|08 80 62 e8) 	ld      r3,-32760\(r2\)
+ 200:	(60 00 00 00|00 00 00 60) 	nop
+ 204:	(e8 62 80 18|18 80 62 e8) 	ld      r3,-32744\(r2\)
+ 208:	(60 00 00 00|00 00 00 60) 	nop
+ 20c:	(e8 62 80 10|10 80 62 e8) 	ld      r3,-32752\(r2\)
diff --git a/ld/testsuite/ld-powerpc/weak1so.r b/ld/testsuite/ld-powerpc/weak1so.r
new file mode 100644
index 0000000000..dcc91f1879
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/weak1so.r
@@ -0,0 +1,7 @@
+#...
+.* R_PPC64_GLOB_DAT +0+ x1 \+ 0
+#...
+.* 0+ +0 NOTYPE +WEAK +DEFAULT +UND x1
+#...
+.* 0+ +0 NOTYPE +WEAK +DEFAULT +UND x1
+#pass

-- 
Alan Modra
Australia Development Lab, IBM


More information about the Binutils mailing list