public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v1] aarch64: Add new relocations and limit COFF AArch64 relocation offsets
@ 2024-02-16 23:30 Evgeny Karpov
  2024-02-19 12:20 ` Nick Clifton
  0 siblings, 1 reply; 2+ messages in thread
From: Evgeny Karpov @ 2024-02-16 23:30 UTC (permalink / raw)
  To: binutils; +Cc: Zac Walker, Ron Riddle, Radek Barton

[-- Attachment #1: Type: text/plain, Size: 672 bytes --]

Hello,

This patch is part of the work on adding the aarch64-w64-mingw32
target to GCC. During this work, COFF AArch64 relocation issues have
been discovered and fixed.

Co-author: Ron Riddle <ron.riddle@microsoft.com>

Refactored, prepared, and validated by 
Radek Barton <radek.barton@microsoft.com> and 
Evgeny Karpov <evgeny.karpov@microsoft.com>

Thank you for your review!

Regards,
Evgeny


Zac Walker (1):
  aarch64: Add new relocations and limit COFF AArch64 relocation offsets

 bfd/coff-aarch64.c | 31 +++++++++++++++++++++++++++++++
 gas/write.c        | 13 ++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

--
2.25.1

[-- Attachment #2: v1-0001-aarch64-Add-new-relocations-and-limit-COFF-AArch6.patch --]
[-- Type: application/octet-stream, Size: 4268 bytes --]

From ed19fdc36e4adfbed9d12f37a8d30c7ba1f266d8 Mon Sep 17 00:00:00 2001
From: Zac Walker <zacwalker@microsoft.com>
Date: Wed, 31 Jan 2024 20:15:48 +0100
Subject: [PATCH v1] 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.
---
 bfd/coff-aarch64.c | 31 +++++++++++++++++++++++++++++++
 gas/write.c        | 13 ++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/bfd/coff-aarch64.c b/bfd/coff-aarch64.c
index 825963c0378..06c22fc58fa 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;
diff --git a/gas/write.c b/gas/write.c
index 98ead0b991c..18cf18fc830 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -779,6 +779,7 @@ adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED,
 {
   segment_info_type *seginfo = seg_info (sec);
   fixS *fixp;
+  valueT val;
 
   if (seginfo == NULL)
     return;
@@ -890,10 +891,20 @@ adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED,
 	if ((symsec->flags & SEC_THREAD_LOCAL) != 0)
 	  continue;
 
+	val = S_GET_VALUE (sym);
+
+#if defined(TC_AARCH64) && defined(OBJ_COFF)
+	/* coff aarch64 relocation offsets need to be limited to 21bits.
+	   This is because addend may need to be stored in an ADRP instruction.
+	   In this case the addend cannot be stored down shifted otherwise rounding errors occur. */
+	if ((val + 0x100000) > 0x1fffff)
+	  continue;
+#endif
+
 	/* We refetch the segment when calling section_symbol, rather
 	   than using symsec, because S_GET_VALUE may wind up changing
 	   the section when it calls resolve_symbol_value.  */
-	fixp->fx_offset += S_GET_VALUE (sym);
+	fixp->fx_offset += val;
 	fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym));
 #ifdef DEBUG5
 	fprintf (stderr, "\nadjusted fixup:\n");
-- 
2.25.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH v1] aarch64: Add new relocations and limit COFF AArch64 relocation offsets
  2024-02-16 23:30 [PATCH v1] aarch64: Add new relocations and limit COFF AArch64 relocation offsets Evgeny Karpov
@ 2024-02-19 12:20 ` Nick Clifton
  0 siblings, 0 replies; 2+ messages in thread
From: Nick Clifton @ 2024-02-19 12:20 UTC (permalink / raw)
  To: Evgeny Karpov, binutils; +Cc: Zac Walker, Ron Riddle, Radek Barton

Hi Evgeny,

> Zac Walker (1):
>    aarch64: Add new relocations and limit COFF AArch64 relocation offsets
> 
>   bfd/coff-aarch64.c | 31 +++++++++++++++++++++++++++++++
>   gas/write.c        | 13 ++++++++++++-
>   2 files changed, 43 insertions(+), 1 deletion(-)

Approved - please apply.

Cheers
   Nick



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-02-19 12:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-16 23:30 [PATCH v1] aarch64: Add new relocations and limit COFF AArch64 relocation offsets Evgeny Karpov
2024-02-19 12:20 ` Nick Clifton

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).