aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <danglin@gcc.gnu.org>2024-04-01 23:00:52 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2024-04-01 23:00:52 +0000
commita82e3815dfffe60a257021c592e2dceca719a04a (patch)
tree16653fd88185bf95d787dc5f40bf8fe1decf6d88
parent159daa36fab5c2c0df88b6e9fd4cda4e560c3f9f (diff)
downloadgdb-a82e3815dfffe60a257021c592e2dceca719a04a.zip
gdb-a82e3815dfffe60a257021c592e2dceca719a04a.tar.gz
gdb-a82e3815dfffe60a257021c592e2dceca719a04a.tar.bz2
hppa: Implement PA 2.0 symbolic relocations for long displacements
The PA 2.0 architecture introduced several new load and store instructions with long displacements. These include floating point loads and stores for word mode, and integer and floating point loads and stores for double words. Currently, ld does not correctly support symbolic relocations for these instructions. If these are used, ld applies the standard R_PARISC_DPREL14R relocation and corrupts the instruction. This change uses bfd_hppa_insn2fmt to determine the correct relocation format. We need to check the computed displacement as the immediate value used in these instruction must be a multiple of 4 or 8 depending on whether the access is for a word or double word. A misaligned offset can potentially occur if the symbol is not properly aligned or if $global$ (the global pointer) is not double word aligned. $global$ is provided as a .data section start symbol. The patch adjusts elf.sc and hppalinux.sh to align .data to a 8-byte boundary in non-shared and non-pie links. 2024-04-01 John David Anglin <danglin@gcc.gnu.org> PR ld/31503 bfd/ChangeLog: * elf32-hppa.c (final_link_relocate): Output ld/ChangeLog: * emulparams/hppalinux.sh (DATA_SECTION_ALIGNMENT): Define. * scripttempl/elf.sc: Align .data section to DATA_SECTION_ALIGNMENT when relocating.
-rw-r--r--bfd/elf32-hppa.c46
-rw-r--r--ld/emulparams/hppalinux.sh1
-rw-r--r--ld/scripttempl/elf.sc2
3 files changed, 47 insertions, 2 deletions
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index bb4bfdc..e9b3ce2 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -3110,7 +3110,7 @@ final_link_relocate (asection *input_section,
unsigned int r_type = ELF32_R_TYPE (rela->r_info);
unsigned int orig_r_type = r_type;
reloc_howto_type *howto = elf_hppa_howto_table + r_type;
- int r_format = howto->bitsize;
+ int r_format;
enum hppa_reloc_field_selector_type_alt r_field;
bfd *input_bfd = input_section->owner;
bfd_vma offset = rela->r_offset;
@@ -3432,6 +3432,50 @@ final_link_relocate (asection *input_section,
break;
}
+ r_format = bfd_hppa_insn2fmt (input_bfd, insn);
+ switch (r_format)
+ {
+ case 10:
+ case -10:
+ if (val & 7)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): displacement %#x for insn %#x "
+ "is not a multiple of 8 (gp %#x)"),
+ input_bfd,
+ input_section,
+ (uint64_t) offset,
+ val,
+ insn,
+ (unsigned int) elf_gp (input_section->output_section->owner));
+ bfd_set_error (bfd_error_bad_value);
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case -11:
+ case -16:
+ if (val & 3)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): displacement %#x for insn %#x "
+ "is not a multiple of 4 (gp %#x)"),
+ input_bfd,
+ input_section,
+ (uint64_t) offset,
+ val,
+ insn,
+ (unsigned int) elf_gp (input_section->output_section->owner));
+ bfd_set_error (bfd_error_bad_value);
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ default:
+ break;
+ }
insn = hppa_rebuild_insn (insn, val, r_format);
/* Update the instruction word. */
diff --git a/ld/emulparams/hppalinux.sh b/ld/emulparams/hppalinux.sh
index 7892df9..5a46211 100644
--- a/ld/emulparams/hppalinux.sh
+++ b/ld/emulparams/hppalinux.sh
@@ -19,6 +19,7 @@ else
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=hppa1.1 # We use 1.1 specific features.
NOP=0x08000240
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index fae7c2a..d5022fa 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -669,7 +669,7 @@ cat <<EOF
${DATA_PLT+${PLT_BEFORE_GOT-${PLT}}}
- .data ${RELOCATING-0} :
+ .data ${RELOCATING-0}${RELOCATING+${DATA_SECTION_ALIGNMENT}} :
{
${RELOCATING+${DATA_START_SYMBOLS}}
*(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})