Re: [PATCH v3 1/1] aarch64: mingw: Prevent relocation types from being overwritten

Alan Modra <[email protected]> Sat, 25 Jul 2026 21:37:01 +0930
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
On Thu, Jul 23, 2026 at 12:03:10PM +0200, Evgeny Karpov wrote:
> On Thu, 23 Jul 2026, Alan Modra wrote:
> > On Wed, Jul 22, 2026 at 10:34:08PM +0930, Alan Modra wrote:
> > > Firstly, is it really necessary?  What exactly goes wrong with the
> > > current code?
> > 
> > I am asking for some details on the following statement:
> > 
> > > On Wed, Jul 22, 2026 at 01:04:00PM +0200, Evgeny Karpov wrote:
> > > > However, it impacts another relocation logic, as the initial relocation type
> > > > is no longer known.
> > 
> > This is the patch I'll commit if you convince me.
> 
> Thank you for the patch and for the suggestion.
>  
> It was possible to change auto import implementation while looking
> for strong evidence by using a similar approach,
> rel->r_type = IMAGE_REL_ARM64_ABSOLUTE.
> 
> It might change later, however for now it can stay like this.
> However as a personal opinion, "rel->r_type = IMAGE_REL_ARM64_ABSOLUTE"
> looks like a workaround and "rel->r_ignore = 1" looks more clear
> on what happens.

Changing r_type to a "do-nothing" code is the way x86 did things, and
in both coff-i386.c and coff-x86_64.c you'll see r_type set to zero
with the reloc howto_table having entry 0 an EMPTY_HOWTO.  The
coff-aarch64.c howto for IMAGE_REL_ARM64_ABSOLUTE also does nothing.

Well, they are do-nothing except for various checks.  Hmm, and
emitting a reloc address for dlltool to process.  In fact, I think
things go wrong there.  When the x86 backend changes an R_SECTION
to 0, in_reloc_p will return true because howto_table[0].pc_relative
is false and howto->type is no longer R_SECTION.  That will result in
the address of these relocs being emitted, which is wrong.  The value
is an index that shouldn't be relocated.

aarch64 would have had a similar problem.  So I'm going to apply the
patch I posted plus the following.

==
Make use of coff internal_reloc r_ignore

Set r_ignore on relocs already handled by a backend relocate_section,
rather than choosing a "do nothing" r_type.  This avoids bugs in all
three targets with in_reloc_p, which resulted in addresses being
emitted for dynamic relocs at all of these "do nothing" relocs.

	* coff-aarch64.c (coff_pe_aarch64_relocate_section): Leave r_type
	unchanged on relocs handled here.  Set r_ignore instead.
	* coff-i386.c (coff_pe_i386_relocate_section): Likewise.
	* coff-x86_64.c (coff_pe_amd64_relocate_section): Likewise.
	Cosmetic fix in r_type handled here.  Formatting.

diff --git a/bfd/coff-aarch64.c b/bfd/coff-aarch64.c
index c00448efc82..d889359a6fc 100644
--- a/bfd/coff-aarch64.c
+++ b/bfd/coff-aarch64.c
@@ -578,7 +578,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 		input_section, rel->r_vaddr - input_section->vma);
 
 	    bfd_putl32 (val, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -613,7 +613,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 	    opcode |= val & 0x3ffffff;
 
 	    bfd_putl32 (opcode, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -648,7 +648,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 	    opcode |= (val & 0x7ffff) << 5;
 
 	    bfd_putl32 (opcode, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -683,7 +683,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 	    opcode |= (val & 0x3fff) << 5;
 
 	    bfd_putl32 (opcode, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -720,7 +720,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 	    opcode |= (val & 0x1ffffc) << 3;
 
 	    bfd_putl32 (opcode, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -757,7 +757,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 	    opcode |= (val & 0x1ffffc) << 3;
 
 	    bfd_putl32 (opcode, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -786,7 +786,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 		input_section, rel->r_vaddr - input_section->vma);
 
 	    bfd_putl32 (val, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -831,7 +831,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 	    opcode |= val << 10;
 
 	    bfd_putl32 (opcode, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -854,7 +854,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 	    opcode |= val << 10;
 
 	    bfd_putl32 (opcode, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -875,7 +875,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 		input_section, rel->r_vaddr - input_section->vma);
 
 	    bfd_putl32 (val, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
@@ -900,7 +900,7 @@ coff_pe_aarch64_relocate_section (bfd *output_bfd,
 
 
 	    bfd_putl16 (idx, contents + rel->r_vaddr);
-	    rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+	    rel->r_ignore = 1;
 
 	    break;
 	  }
diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
index d9177c51c79..0e296a3400b 100644
--- a/bfd/coff-i386.c
+++ b/bfd/coff-i386.c
@@ -459,7 +459,7 @@ coff_pe_i386_relocate_section (bfd *output_bfd,
 
       /* Make sure that _bfd_coff_generic_relocate_section won't parse
          this reloc after us.  */
-      rel->r_type = 0;
+      rel->r_ignore = 1;
 
       symndx = rel->r_symndx;
 
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index 78836a5c267..2c434624052 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -591,12 +591,12 @@ coff_pe_amd64_relocate_section (bfd *output_bfd,
       asection *sec, *s;
       uint16_t idx = 0, i = 1;
 
-      if (rel->r_type != R_SECTION)
+      if (rel->r_type != R_AMD64_SECTION)
 	continue;
 
       /* Make sure that _bfd_coff_generic_relocate_section won't parse
          this reloc after us.  */
-      rel->r_type = 0;
+      rel->r_ignore = 1;
 
       symndx = rel->r_symndx;
 
@@ -647,7 +647,9 @@ coff_pe_amd64_relocate_section (bfd *output_bfd,
       bfd_putl16 (idx, contents + rel->r_vaddr - input_section->vma);
     }
 
-  return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,input_section, contents,relocs, syms, sections);
+  return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
+					     input_section, contents,
+					     relocs, syms, sections);
 }
 
 #define coff_relocate_section coff_pe_amd64_relocate_section

-- 
Alan Modra