public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [Committed] s390: Avoid reloc overflows on undefined weak symbols
@ 2024-02-27 13:09 Andreas Krebbel
  0 siblings, 0 replies; only message in thread
From: Andreas Krebbel @ 2024-02-27 13:09 UTC (permalink / raw)
  To: binutils

Replace relative long addressing instructions of weak symbols, which
will definitely resolve to zero, with either a load address of 0, a
NOP, or a trapping insn.

This prevents the PC32DBL relocation from overflowing in case the
binary will be loaded at 4GB or more.

Committed to mainline. I'll push that also to release branches after
giving it some time in mainline.

bfd/ChangeLog:

	* bfd/elf64-s390.c (elf_s390_relocate_section): Replace
	instructions using undefined weak symbols with relative addressing
	to avoid relocation overflows.

ld/ChangeLog:
	* ld/testsuite/ld-s390/s390.exp:
	* ld/testsuite/ld-s390/8GB.ld: New test.
	* ld/testsuite/ld-s390/weakundef-1.dd: New test.
	* ld/testsuite/ld-s390/weakundef-1.s: New test.
---
 bfd/elf64-s390.c                    | 54 +++++++++++++++++++++++++++++
 ld/testsuite/ld-s390/8GB.ld         |  1 +
 ld/testsuite/ld-s390/s390.exp       |  3 ++
 ld/testsuite/ld-s390/weakundef-1.dd | 15 ++++++++
 ld/testsuite/ld-s390/weakundef-1.s  | 18 ++++++++++
 5 files changed, 91 insertions(+)
 create mode 100644 ld/testsuite/ld-s390/8GB.ld
 create mode 100644 ld/testsuite/ld-s390/weakundef-1.dd
 create mode 100644 ld/testsuite/ld-s390/weakundef-1.s

diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index ab9ec3f5b48..74ac0180bf8 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -2475,6 +2475,60 @@ elf_s390_relocate_section (bfd *output_bfd,
 			    + h->plt.offset);
 	      goto do_relocation;
 	    }
+
+	  /* Replace relative long addressing instructions of weak
+	     symbols, which will definitely resolve to zero, with
+	     either a load address of 0, a NOP, or a trapping insn.
+	     This prevents the PC32DBL relocation from overflowing in
+	     case the binary will be loaded at 4GB or more.  */
+	  if (h != NULL
+	      && h->root.type == bfd_link_hash_undefweak
+	      && !h->root.linker_def
+	      && (bfd_link_executable (info)
+		  || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	      && r_type == R_390_PC32DBL)
+	    {
+	      void *insn_start = contents + rel->r_offset - 2;
+	      uint16_t op = bfd_get_16 (input_bfd, insn_start) & 0xff0f;
+	      uint8_t reg = bfd_get_8 (input_bfd, insn_start + 1) & 0xf0;
+
+	      /* NOTE: The order of the if's is important!  */
+	      /* Replace load address relative long (larl) with load
+		 address (lay) */
+	      if (op == 0xc000)
+		{
+		  /* larl rX,<weak sym> -> lay rX,0(0)  */
+		  bfd_put_16 (output_bfd, 0xe300 | reg, insn_start);
+		  bfd_put_32 (output_bfd, 0x71, insn_start + 2);
+		  continue;
+		}
+	      /* Replace prefetch data relative long (pfdrl) with a NOP  */
+	      else if (op == 0xc602)
+		{
+		  /* Emit a 6-byte NOP: jgnop .  */
+		  bfd_put_16 (output_bfd, 0xc004, insn_start);
+		  bfd_put_32 (output_bfd, 0x0, insn_start + 2);
+		  continue;
+		}
+	      /* Replace the following instructions with a trap:
+		 - branch relative and save long (brasl)
+		 - load (logical) relative long (lrl, lgrl, lgfrl, llgfrl)
+		 - load (logical) halfword relative long (lhrl, lghrl, llhrl, llghrl)
+		 - store relative long (strl, stgrl)
+		 - store halfword relative long (sthrl)
+		 - execute relative long (exrl)
+		 - compare (logical) relative long (crl, clrl, cgrl, clgrl, cgfrl, clgfrl)
+		 - compare (logical) halfword relative long (chrl, cghrl, clhrl, clghrl)
+		 - branch relative on count high (brcth)  */
+	      else if (op == 0xc005 || (op & 0xff00) == 0xc400
+		       || (op & 0xff00) == 0xc600 || op == 0xcc06)
+		{
+		  /* Emit a 6-byte trap: jg .+2  */
+		  bfd_put_16 (output_bfd, 0xc0f4, insn_start);
+		  bfd_put_32 (output_bfd, 0x1, insn_start + 2);
+		  continue;
+		}
+	    }
 	  /* Fall through.  */
 
 	case R_390_8:
diff --git a/ld/testsuite/ld-s390/8GB.ld b/ld/testsuite/ld-s390/8GB.ld
new file mode 100644
index 00000000000..7ab94cb3ea5
--- /dev/null
+++ b/ld/testsuite/ld-s390/8GB.ld
@@ -0,0 +1 @@
+SECTIONS { . = 0x200000000; }
diff --git a/ld/testsuite/ld-s390/s390.exp b/ld/testsuite/ld-s390/s390.exp
index 27bfdeec275..6b97b6c07d9 100644
--- a/ld/testsuite/ld-s390/s390.exp
+++ b/ld/testsuite/ld-s390/s390.exp
@@ -85,6 +85,9 @@ set s390xtests {
      "-m64" {pltoffset-1.s}
      {{objdump "-dzrj.text --stop-address=16" pltoffset-1.dd}}
      "pltoffset-1"}
+    {"WEAKUNDEF1: overflow test"
+     "-m elf64_s390 -dT 8GB.ld --no-error-rwx-segments" "" "-m64" {weakundef-1.s}
+     {{objdump "-dzrj.text" weakundef-1.dd}} "weakundef-1"}
 }
 
 if [istarget "s390-*-*"] {
diff --git a/ld/testsuite/ld-s390/weakundef-1.dd b/ld/testsuite/ld-s390/weakundef-1.dd
new file mode 100644
index 00000000000..e5145245602
--- /dev/null
+++ b/ld/testsuite/ld-s390/weakundef-1.dd
@@ -0,0 +1,15 @@
+tmpdir/weakundef-1:     file format elf64-s390
+
+Disassembly of section .text:
+
+.* <foo>:
+.*:	c0 10 00 00 00 1e [	 ]*larl	%r1,20000003c <d>
+.*:	c0 10 00 00 00 1f [	 ]*larl	%r1,200000044 <wd>
+.*:	e3 10 00 00 00 71 [	 ]*lay	%r1,0
+.*:	c0 f4 00 00 00 01 [	 ]*jg	.*
+.*:	c0 f4 00 00 00 01 [	 ]*jg	.*
+.*:	c0 f4 00 00 00 01 [	 ]*jg	.*
+.*:	c0 f4 00 00 00 01 [	 ]*jg	.*
+.*:	c0 f4 00 00 00 01 [	 ]*jg	.*
+.*:	c0 f4 00 00 00 01 [	 ]*jg	.*
+.*:	c0 04 00 00 00 00 [	 ]*jgnop	.*
diff --git a/ld/testsuite/ld-s390/weakundef-1.s b/ld/testsuite/ld-s390/weakundef-1.s
new file mode 100644
index 00000000000..aeaef8d2456
--- /dev/null
+++ b/ld/testsuite/ld-s390/weakundef-1.s
@@ -0,0 +1,18 @@
+.text
+	.globl foo
+foo:
+	larl	%r1,d
+	larl	%r1,wd
+	larl	%r1,wu
+	brasl	%r1,wu
+	crl	%r1,wu
+	lrl	%r1,wu
+	strl	%r1,wu
+	exrl	%r1,wu
+	brcth	%r1,wu
+	pfdrl	%r1,wu
+	.weak	wd
+	.weak	wu
+.data
+d:	.quad 0x123
+wd:	.quad 0x123
-- 
2.43.0


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-02-27 13:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-27 13:09 [Committed] s390: Avoid reloc overflows on undefined weak symbols Andreas Krebbel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).