hppa: Fix handling of relocations that apply to data

Commit d125f96753 introduced a bug
in handling relocations for data.  The R_PARISC_DIR32 relocation
operates on 32-bit data and not instructions.  The HOWTO table
needs to be used to determine the format of relocations that apply
to data.  The R_PARISC_SEGBASE relocation is another special case
as it only changes segment base.

This was noticed in Debian cmor package build.

2024-07-14  John David Anglin  <danglin@gcc.gnu.org>

bfd/ChangeLog:

	* elf32-hppa.c (final_link_relocate): Use HOWTO table to
	determine reload format for relocations that apply to data.
This commit is contained in:
John David Anglin 2024-07-14 07:22:13 -04:00
parent 7846287a38
commit a48e485c7c

View File

@ -3432,48 +3432,62 @@ final_link_relocate (asection *input_section,
break;
}
r_format = bfd_hppa_insn2fmt (input_bfd, insn);
switch (r_format)
switch (r_type)
{
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;
}
case R_PARISC_DIR32:
case R_PARISC_SECREL32:
case R_PARISC_SEGBASE:
case R_PARISC_SEGREL32:
case R_PARISC_PLABEL32:
/* These relocations apply to data. */
r_format = howto->bitsize;
break;
default:
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;
}
break;
}
insn = hppa_rebuild_insn (insn, val, r_format);