aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorZac Walker <zacwalker@microsoft.com>2024-01-31 20:15:48 +0100
committerChristophe Lyon <christophe.lyon@linaro.org>2024-02-19 13:02:00 +0000
commitf87eaf8ff3995a5888c6dc4996a20c770e6bcd36 (patch)
treecdbae78664071dc1196fae6d6c9ed62f0db99619 /bfd
parent046a94c18c543793ab4a8f3f9b2cb0d1280e7b41 (diff)
downloadgdb-f87eaf8ff3995a5888c6dc4996a20c770e6bcd36.zip
gdb-f87eaf8ff3995a5888c6dc4996a20c770e6bcd36.tar.gz
gdb-f87eaf8ff3995a5888c6dc4996a20c770e6bcd36.tar.bz2
aarch64: Add new relocations and limit COFF AArch64 relocation offsets
The patch adds support for the IMAGE_REL_ARM64_REL32 coff relocation type. This is needed for 32-bit relative address. It also adds a check for relocation offsets over 21 bits. Offsets inside coff files are stored in instruction code. In the case of ADRP the actual value is stored, not a downshifted page offset. This means values over 21 bits would otherwise be truncated. Finally it adds a mapping for BFD_RELOC_AARCH64_ADR_GOT_PAGE and BFD_RELOC_AARCH64_LD64_GOT_LO12_NC that were previously skipped. ChangeLog: * bfd/coff-aarch64.c (coff_aarch64_reloc_type_lookup): Add BFD_RELOC_AARCH64_ADR_GOT_PAGE, BFD_RELOC_AARCH64_LD64_GOT_LO12_NC and IMAGE_REL_ARM64_REL32 relocations. (coff_pe_aarch64_relocate_section): Likewise. * gas/write.c (adjust_reloc_syms): COFF AArch64 relocation offsets need to be limited to 21bits (defined): Likewise.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/coff-aarch64.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/bfd/coff-aarch64.c b/bfd/coff-aarch64.c
index 825963c..06c22fc 100644
--- a/bfd/coff-aarch64.c
+++ b/bfd/coff-aarch64.c
@@ -352,6 +352,7 @@ coff_aarch64_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real
return &arm64_reloc_howto_branch26;
case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
return &arm64_reloc_howto_page21;
case BFD_RELOC_AARCH64_TSTBR14:
return &arm64_reloc_howto_branch14;
@@ -364,6 +365,7 @@ coff_aarch64_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real
case BFD_RELOC_AARCH64_LDST32_LO12:
case BFD_RELOC_AARCH64_LDST64_LO12:
case BFD_RELOC_AARCH64_LDST128_LO12:
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
return &arm64_reloc_howto_pgoff12l;
case BFD_RELOC_AARCH64_BRANCH19:
return &arm64_reloc_howto_branch19;
@@ -761,6 +763,35 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
break;
}
+ case IMAGE_REL_ARM64_REL32:
+ {
+ uint64_t cur_vma;
+ int64_t addend, val;
+
+ addend = bfd_getl32 (contents + rel->r_vaddr);
+
+ if (addend & 0x80000000)
+ addend |= 0xffffffff00000000;
+
+ dest_vma += addend;
+ cur_vma = input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_vaddr;
+
+ val = dest_vma - cur_vma;
+
+ if (val > 0xffffffff || val < -0x100000000)
+ (*info->callbacks->reloc_overflow)
+ (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
+ "IMAGE_REL_ARM64_REL32", addend, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma);
+
+ bfd_putl32 (val, contents + rel->r_vaddr);
+ rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+
+ break;
+ }
+
case IMAGE_REL_ARM64_PAGEOFFSET_12L:
{
uint32_t opcode, val;