[PATCH] bfd: Fix 64-bit relocation handling for a.out

Gunther Nikl gnikl@justmail.de
Mon May 4 19:14:01 GMT 2020


Nick Clifton <nickc@redhat.com> wrote:
> 
> > 2020-04-XX  Gunther Nikl  <gnikl@justmail.de>
> > 
> > 	* aoutx.h (NAME (aout, swap_std_reloc_out)): Special case
> > 64 bit relocations.
> > 	(aout_link_reloc_link_order): Likewise. Make r_length an
> > unsigned.
> 
> Approved and applied.

Thank you.

I have an update which ensures only supported sizes are permitted. I believe
for swap_std_reloc_out this change is recommended since the howto might
reference foreign relocations. The similar change to aout_link_reloc_link_order
might not be necessary if the howto can only be from the generic a.out backend
since then only a size of 1, 2, 4 and 8 is possible. This is handled fine with
the current code.

Thoughts?

Thank you,
Gunther

---
modification to aout_link_reloc_link_order needed? If howto is from tabe_std
only size of 0, 1, 2 and 4 are possible and the code is fine.

2020-04-XX  Gunther Nikl  <gnikl@justmail.de>

	* aoutx.h (NAME (aout, swap_std_reloc_out)): Reject an unsupported
	relocation size.
	(aout_link_reloc_link_order): Likewise.

diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index d5457461ab..7cfb894281 100644
--- a/bfd/aoutx.h
+++ b/bfd/aoutx.h
@@ -1946,10 +1946,19 @@ NAME (aout, swap_std_reloc_out) (bfd *abfd,
 
   BFD_ASSERT (g->howto != NULL);
 
-  if (bfd_get_reloc_size (g->howto) != 8)
-    r_length = g->howto->size;	/* Size as a power of two.  */
-  else
-    r_length = 3;
+  switch (bfd_get_reloc_size (g->howto))
+    {
+      default:
+	_bfd_error_handler (_("%pB: unsupported relocation size"), abfd);
+	bfd_set_error (bfd_error_bad_value);
+	return;
+      case 1: case 2: case 4:
+	r_length = g->howto->size;	/* Size as a power of two.  */
+	break;
+      case 8:
+	r_length = 3;
+	break;
+    }
 
   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC?  */
   /* XXX This relies on relocs coming from a.out files.  */
@@ -3814,10 +3823,17 @@ aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
 	r_baserel = (howto->type & 8) != 0;
 	r_jmptable = (howto->type & 16) != 0;
 	r_relative = (howto->type & 32) != 0;
-	if (bfd_get_reloc_size (howto) != 8)
-	  r_length = howto->size;	/* Size as a power of two.  */
-	else
-	  r_length = 3;
+	switch (bfd_get_reloc_size (howto))
+	  {
+	    default:
+	      abort ();
+	    case 1: case 2: case 4:
+	      r_length = howto->size;	/* Size as a power of two.  */
+	      break;
+	    case 8:
+	      r_length = 3;
+	      break;
+	  }
 
 	PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
 	if (bfd_header_big_endian (flaginfo->output_bfd))
---


More information about the Binutils mailing list