[committed] hppa64: Initial relro support for Linux

Message ID adFiHebpJSDE6SjN@mx3210.local
State New
Headers
Series [committed] hppa64: Initial relro support for Linux |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply

Commit Message

John David Anglin April 4, 2026, 7:10 p.m. UTC
  Tested on hppa-unknown-linux-gnu.  Committed to master.

Dave
---

hppa64: Initial relro support for Linux

This also fixes the alignment of the data segment on Linux target.
It must be page aligned to avoid inequivalent aliases.

2026-04-04  John David Anglin  <danglin@gcc.gnu.org>

	PR ld/12376

bfd/ChangeLog:

	* elf64-hppa.c (elf_backend_modify_segment_map): Don't
	use HP-UX specific routine on Linux.
	(elf_backend_want_dynrelro): Define to 1 on Linux.

ld/ChangeLog:

	* emulparams/hppa64linux.sh (COMMONPAGESIZE): Define.
	(DATA_SEGMENT_ALIGN, DATA_SEGMENT_END,
	DATA_SEGMENT_RELRO_END): Define if $LD_FLAG != "N".
	(DATA_SECTION_ALIGNMENT): Define.
	* scripttempl/elf64hppa.sc: Revise handling of data
	segment.
	* testsuite/ld-elf/orphan-region.d: Remove xfail on
	Linux.
  

Patch

diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c
index 470c28f75d3..38558abe9c2 100644
--- a/bfd/elf64-hppa.c
+++ b/bfd/elf64-hppa.c
@@ -4596,6 +4596,9 @@  static const struct elf_size_info hppa64_elf_size_info =
 #define elf64_bed			elf64_hppa_linux_bed
 #undef elf_backend_special_sections
 #define elf_backend_special_sections	(elf64_hppa_special_sections + 1)
+#undef elf_backend_modify_segment_map
 #undef elf_backend_want_p_paddr_set_to_zero
+#undef elf_backend_want_dynrelro
+#define elf_backend_want_dynrelro	1
 
 #include "elf64-target.h"
diff --git a/ld/emulparams/hppa64linux.sh b/ld/emulparams/hppa64linux.sh
index d72c6bb9a84..d0352b66f4f 100644
--- a/ld/emulparams/hppa64linux.sh
+++ b/ld/emulparams/hppa64linux.sh
@@ -5,6 +5,18 @@  NO_REL_RELOCS=yes
 TEXT_START_ADDR=0x10000
 TARGET_PAGE_SIZE=0x10000
 MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
+COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"
+if test "$LD_FLAG" = "N"; then
+  unset DATA_SEGMENT_ALIGN
+  unset DATA_SEGMENT_END
+  unset DATA_SEGMENT_RELRO_END
+else
+  DATA_SEGMENT_ALIGN="ALIGN(${MAXPAGESIZE});\
+  . = DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})"
+  DATA_SEGMENT_END=". = DATA_SEGMENT_END (.);"
+  DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (${SEPARATE_GOTPLT-0}, .);"
+fi
+DATA_SECTION_ALIGNMENT="${CREATE_SHLIB-${CREATE_PIE-ALIGN(8)}}"
 ARCH=hppa
 MACHINE=hppa2.0w
 NOP=0x08000240
diff --git a/ld/scripttempl/elf64hppa.sc b/ld/scripttempl/elf64hppa.sc
index d093f88b8fb..7be32d90c98 100644
--- a/ld/scripttempl/elf64hppa.sc
+++ b/ld/scripttempl/elf64hppa.sc
@@ -106,14 +106,25 @@  test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESI
 test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE=""
 test -n "$RELRO_NOW" && unset SEPARATE_GOTPLT
 test -z "$ATTRS_SECTIONS" && ATTRS_SECTIONS=".gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }"
-DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))"
-DATA_SEGMENT_RELRO_END=""
-DATA_SEGMENT_END=""
-if test -n "${COMMONPAGESIZE}"; then
-  DATA_SEGMENT_ALIGN="ALIGN (${SEGMENT_SIZE}) - ((${MAXPAGESIZE} - .) & (${MAXPAGESIZE} - 1)); . = DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})"
-  DATA_SEGMENT_END=". = DATA_SEGMENT_END (.);"
-  DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (${SEPARATE_GOTPLT-0}, .);"
+
+if test -z "$DATA_SEGMENT_ALIGN"; then
+  test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE=""
+  test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE=""
+  DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))"
+  DATA_SEGMENT_RELRO_END=""
+  DATA_SEGMENT_END=""
+  if test -n "${COMMONPAGESIZE}"; then
+    if test "${SEGMENT_SIZE}" != "${MAXPAGESIZE}"; then
+      DATA_SEGMENT_ALIGN="ALIGN (${SEGMENT_SIZE}) - ((${MAXPAGESIZE} - .) & (${MAXPAGESIZE} - 1)); \
+      . = DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})"
+    else
+      DATA_SEGMENT_ALIGN="DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})"
+    fi
+    DATA_SEGMENT_END=". = DATA_SEGMENT_END (.);"
+    DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (${SEPARATE_GOTPLT-0}, .);"
+  fi
 fi
+
 if test -z "${INITIAL_READONLY_SECTIONS}${CREATE_SHLIB}"; then
   INITIAL_READONLY_SECTIONS=".interp       ${RELOCATING-0} : { *(.interp) }"
 fi
diff --git a/ld/testsuite/ld-elf/orphan-region.d b/ld/testsuite/ld-elf/orphan-region.d
index ef21ec377cc..13fb31fff9f 100644
--- a/ld/testsuite/ld-elf/orphan-region.d
+++ b/ld/testsuite/ld-elf/orphan-region.d
@@ -1,7 +1,7 @@ 
 #source: orphan-region.s
 #ld: -T orphan-region.ld -N -z stack-size=0 --no-warn-rwx-segments
 #readelf: -S -l --wide
-#xfail: [uses_genelf] hppa*64*-*-* spu-*-*
+#xfail: [uses_genelf] hppa*64*-*-hpux* spu-*-*
 # if not using elf.em, you don't get fancy orphan handling
 # spu twiddles LOAD range, hppa64 adds PHDR