public inbox for binutils-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Don't encode reloc.size
@ 2022-06-08 12:04 Alan Modra
  0 siblings, 0 replies; only message in thread
From: Alan Modra @ 2022-06-08 12:04 UTC (permalink / raw)
  To: bfd-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=57698478b75319a962b899c3f8d3a03baa5eaab4

commit 57698478b75319a962b899c3f8d3a03baa5eaab4
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Jun 8 09:49:09 2022 +0930

    Don't encode reloc.size
    
    I expect the encoded reloc.size field originally came from aout
    r_length ecoding, but somehow went wrong for 64-bit relocs (which
    should have been encoded as 3).  Toss all that out, just use a byte
    size instead.  The changes outside of reloc.c in this patch should
    make the code independent of how reloc.size is encoded.
    
            * reloc.c (struct reloc_howto_struct): Increase size field by
            one bit.  Comment.
            (HOWTO_RSIZE): Don't encode size.
            (bfd_get_reloc_size): Adjust, and make it an inline function.
            (read_reloc, write_reloc): Adjust.
            * bfd-in2.h: Regenerate.
            * aout-ns32k.c: Include libbfd.h.
            (put_reloc): Don't use howto->size directly.  Calculate r_length
            using bfd_log2 and bfd_get_reloc_size.
            * aoutx.h (swap_std_reloc_out): Likewise.
            (aout_link_reloc_link_order): Likewise.
            * i386lynx.c (swap_std_reloc_out
            * mach-o-i386.c (bfd_mach_o_i386_swap_reloc_out
            * pdp11.c (aout_link_reloc_link_order
            * coff-arm.c (coff_arm_reloc): Don't use howto->size directly,
            use bfd_get_reloc_size instead and adjust switch cases.
            * coff-i386.c (coff_i386_reloc): Similarly.
            * coff-x86_64.c (coff_amd64_reloc): Likewise.
            * cpu-ns32k.c (do_ns32k_reloc): Likewise.
            * elf32-arc.c (arc_do_relocation): Likewise.
            * elf32-arm.c (elf32_arm_final_link_relocate): Likewise.
            * elf32-bfin.c (bfin_bfd_reloc): Likewise.
            * elf32-cr16.c (cr16_elf_final_link_relocate): Likewise.
            * elf32-cris.c (cris_elf_pcrel_reloc): Likewise.
            * elf32-crx.c (crx_elf_final_link_relocate): Likewise.
            * elf32-csky.c (csky_elf_relocate_section): Likewise.
            * elf32-d10v.c (extract_rel_addend, insert_rel_addend): Likewise.
            * elf32-i386.c (elf_i386_relocate_section): Likewise.
            * elf32-m32r.c (m32r_elf_generic_reloc): Likewise.
            * elf32-nds32.c (nds32_elf_generic_reloc): Likewise.
            * syms.c (_bfd_stab_section_find_nearest_line): Likewise.
            * coff-rs6000.c (xcoff_ppc_relocate_section): Adjust howto.size.
            * coff64-rs6000.c (xcoff64_ppc_relocate_section): Likewise.

Diff:
---
 bfd/aout-ns32k.c    |  3 ++-
 bfd/aoutx.h         | 22 +++++----------
 bfd/bfd-in2.h       | 14 +++++-----
 bfd/coff-arm.c      |  8 +++---
 bfd/coff-i386.c     | 12 ++++-----
 bfd/coff-rs6000.c   |  6 ++---
 bfd/coff-x86_64.c   | 10 +++----
 bfd/coff64-rs6000.c | 41 ++++++++++++++++++----------
 bfd/cpu-ns32k.c     | 15 +++++------
 bfd/elf32-arc.c     | 16 +++++------
 bfd/elf32-arm.c     | 10 +++----
 bfd/elf32-bfin.c    |  6 ++---
 bfd/elf32-cr16.c    |  8 +++---
 bfd/elf32-cris.c    |  2 +-
 bfd/elf32-crx.c     |  8 +++---
 bfd/elf32-csky.c    |  2 +-
 bfd/elf32-d10v.c    | 16 +++++------
 bfd/elf32-i386.c    | 16 +++++------
 bfd/elf32-m32r.c    |  6 ++---
 bfd/elf32-nds32.c   |  6 ++---
 bfd/i386lynx.c      |  2 +-
 bfd/mach-o-i386.c   |  8 +++---
 bfd/pdp11.c         |  2 +-
 bfd/reloc.c         | 77 +++++++++++++++++++----------------------------------
 bfd/syms.c          |  2 +-
 25 files changed, 150 insertions(+), 168 deletions(-)

diff --git a/bfd/aout-ns32k.c b/bfd/aout-ns32k.c
index 1dce7644652..f4c447dcc37 100644
--- a/bfd/aout-ns32k.c
+++ b/bfd/aout-ns32k.c
@@ -21,6 +21,7 @@
 
 #include "sysdep.h"
 #include "bfd.h"
+#include "libbfd.h"
 #include "aout/aout64.h"
 #include "ns32k.h"
 
@@ -180,7 +181,7 @@ MY (put_reloc) (bfd *abfd,
   int r_ns32k_type;
 
   PUT_WORD (abfd, value, reloc->r_address);
-  r_length = howto->size ;	/* Size as a power of two.  */
+  r_length = bfd_log2 (bfd_get_reloc_size (howto));
   r_pcrel  = (int) howto->pc_relative; /* Relative to PC?  */
   r_ns32k_type = (howto - MY (howto_table) )/6;
 
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index 2bff7a8d8b2..e9b5188e8e7 100644
--- a/bfd/aoutx.h
+++ b/bfd/aoutx.h
@@ -1947,7 +1947,7 @@ NAME (aout, swap_std_reloc_out) (bfd *abfd,
   int r_index;
   asymbol *sym = *(g->sym_ptr_ptr);
   int r_extern;
-  unsigned int r_length;
+  unsigned int r_length, r_size;
   int r_pcrel;
   int r_baserel, r_jmptable, r_relative;
   asection *output_section = sym->section->output_section;
@@ -1956,21 +1956,14 @@ NAME (aout, swap_std_reloc_out) (bfd *abfd,
 
   BFD_ASSERT (g->howto != NULL);
 
-  switch (bfd_get_reloc_size (g->howto))
+  r_size = bfd_get_reloc_size (g->howto);
+  r_length = bfd_log2 (r_size);
+  if (1u << r_length != r_size)
     {
-    default:
       _bfd_error_handler (_("%pB: unsupported AOUT relocation size: %d"),
-			  abfd, bfd_get_reloc_size (g->howto));
+			  abfd, r_size);
       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?  */
@@ -3835,10 +3828,7 @@ 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;
+	r_length = bfd_log2 (bfd_get_reloc_size (howto));
 
 	PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
 	if (bfd_header_big_endian (flaginfo->output_bfd))
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index f18c2faece1..64e74adff73 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2058,10 +2058,8 @@ struct reloc_howto_struct
      an external reloc number is stored in this field.  */
   unsigned int type;
 
-  /* The encoded size of the item to be relocated.  This is *not* a
-     power-of-two measure.  Use bfd_get_reloc_size to find the size
-     of the item in bytes.  */
-  unsigned int size:3;
+  /* The size of the item to be relocated in bytes.  */
+  unsigned int size:4;
 
   /* The number of bits in the field to be relocated.  This is used
      when doing overflow checking.  */
@@ -2135,7 +2133,7 @@ struct reloc_howto_struct
   const char *name;
 };
 
-#define HOWTO_RSIZE(sz) (sz == 1 || sz == -1 ? 0 : sz == 2 || sz == -2 ? 1 : sz == 4 || sz == -4 ? 2 : sz == 0 ? 3 : sz == 8 || sz == -8 ? 4 : sz == 3 || sz == -3 ? 5 : 0x777)
+#define HOWTO_RSIZE(sz) ((sz) < 0 ? -(sz) : (sz))
 #define HOWTO(type, right, size, bits, pcrel, left, ovf, func, name,   \
               inplace, src_mask, dst_mask, pcrel_off)                  \
   { (unsigned) type, HOWTO_RSIZE (size), bits, right, left, ovf,       \
@@ -2144,7 +2142,11 @@ struct reloc_howto_struct
   HOWTO ((C), 0, 1, 0, false, 0, complain_overflow_dont, NULL, \
          NULL, false, 0, 0, false)
 
-unsigned int bfd_get_reloc_size (reloc_howto_type *);
+static inline unsigned int
+bfd_get_reloc_size (reloc_howto_type *howto)
+{
+  return howto->size;
+}
 
 typedef struct relent_chain
 {
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
index f9e117ace52..65cb946510e 100644
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -124,9 +124,9 @@ coff_arm_reloc (bfd *abfd,
       if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
 	return bfd_reloc_outofrange;
 
-      switch (howto->size)
+      switch (bfd_get_reloc_size (howto))
 	{
-	case 0:
+	case 1:
 	  {
 	    char x = bfd_get_8 (abfd, addr);
 	    DOIT (x);
@@ -134,7 +134,7 @@ coff_arm_reloc (bfd *abfd,
 	  }
 	  break;
 
-	case 1:
+	case 2:
 	  {
 	    short x = bfd_get_16 (abfd, addr);
 	    DOIT (x);
@@ -142,7 +142,7 @@ coff_arm_reloc (bfd *abfd,
 	  }
 	  break;
 
-	case 2:
+	case 4:
 	  {
 	    long x = bfd_get_32 (abfd, addr);
 	    DOIT (x);
diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
index 9e5dbab38ce..92cc5c207bf 100644
--- a/bfd/coff-i386.c
+++ b/bfd/coff-i386.c
@@ -109,14 +109,14 @@ coff_i386_reloc (bfd *abfd,
 	  reloc_howto_type *howto = reloc_entry->howto;
 
 	  /* Although PC relative relocations are very similar between
-	     PE and non-PE formats, but they are off by 1 << howto->size
+	     PE and non-PE formats, but they are off by howto->size
 	     bytes. For the external relocation, PE is very different
 	     from others. See md_apply_fix3 () in gas/config/tc-i386.c.
 	     When we link PE and non-PE object files together to
 	     generate a non-PE executable, we have to compensate it
 	     here.  */
 	  if (howto->pc_relative && howto->pcrel_offset)
-	    diff = -(1 << howto->size);
+	    diff = -bfd_get_reloc_size (howto);
 	  else if (symbol->flags & BSF_WEAK)
 	    diff = reloc_entry->addend - symbol->value;
 	  else
@@ -148,9 +148,9 @@ coff_i386_reloc (bfd *abfd,
       if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
 	return bfd_reloc_outofrange;
 
-      switch (howto->size)
+      switch (bfd_get_reloc_size (howto))
 	{
-	case 0:
+	case 1:
 	  {
 	    char x = bfd_get_8 (abfd, addr);
 	    DOIT (x);
@@ -158,7 +158,7 @@ coff_i386_reloc (bfd *abfd,
 	  }
 	  break;
 
-	case 1:
+	case 2:
 	  {
 	    short x = bfd_get_16 (abfd, addr);
 	    DOIT (x);
@@ -166,7 +166,7 @@ coff_i386_reloc (bfd *abfd,
 	  }
 	  break;
 
-	case 2:
+	case 4:
 	  {
 	    long x = bfd_get_32 (abfd, addr);
 	    DOIT (x);
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index f39a85a46a0..6ad77ba77c4 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -3700,7 +3700,7 @@ xcoff_ppc_relocate_section (bfd *output_bfd,
 	    case R_POS:
 	    case R_NEG:
 	      howto.bitsize = (rel->r_size & 0x1f) + 1;
-	      howto.size = howto.bitsize > 16 ? 2 : 1;
+	      howto.size = HOWTO_RSIZE (howto.bitsize > 16 ? 4 : 2);
 	      howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
 	      break;
 
@@ -3801,7 +3801,7 @@ xcoff_ppc_relocate_section (bfd *output_bfd,
 	abort ();
 
       /* Get the value we are going to relocate.  */
-      if (1 == howto.size)
+      if (2 == bfd_get_reloc_size (&howto))
 	value_to_relocate = bfd_get_16 (input_bfd, location);
       else
 	value_to_relocate = bfd_get_32 (input_bfd, location);
@@ -3848,7 +3848,7 @@ xcoff_ppc_relocate_section (bfd *output_bfd,
 			       + relocation) & howto.dst_mask));
 
       /* Put the value back in the object file.  */
-      if (1 == howto.size)
+      if (2 == bfd_get_reloc_size (&howto))
 	bfd_put_16 (input_bfd, value_to_relocate, location);
       else
 	bfd_put_32 (input_bfd, value_to_relocate, location);
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index bc9c3d43699..c2b2d0e4d58 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -173,9 +173,9 @@ coff_amd64_reloc (bfd *abfd,
       if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
 	return bfd_reloc_outofrange;
 
-      switch (howto->size)
+      switch (bfd_get_reloc_size (howto))
 	{
-	case 0:
+	case 1:
 	  {
 	    char x = bfd_get_8 (abfd, addr);
 	    DOIT (x);
@@ -183,7 +183,7 @@ coff_amd64_reloc (bfd *abfd,
 	  }
 	  break;
 
-	case 1:
+	case 2:
 	  {
 	    short x = bfd_get_16 (abfd, addr);
 	    DOIT (x);
@@ -191,7 +191,7 @@ coff_amd64_reloc (bfd *abfd,
 	  }
 	  break;
 
-	case 2:
+	case 4:
 	  {
 	    long x = bfd_get_32 (abfd, addr);
 	    DOIT (x);
@@ -199,7 +199,7 @@ coff_amd64_reloc (bfd *abfd,
 	  }
 	  break;
 
-	case 4:
+	case 8:
 	  {
 	    uint64_t x = bfd_get_64 (abfd, addr);
 	    DOIT (x);
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 5df3dc19952..ce1c518282e 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -1587,7 +1587,9 @@ xcoff64_ppc_relocate_section (bfd *output_bfd,
 	    case R_POS:
 	    case R_NEG:
 	      howto.bitsize = (rel->r_size & 0x3f) + 1;
-	      howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
+	      howto.size = HOWTO_RSIZE (howto.bitsize <= 16
+					? 2 : howto.bitsize <= 32
+					? 4 : 8);
 	      howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
 	      break;
 
@@ -1680,12 +1682,18 @@ xcoff64_ppc_relocate_section (bfd *output_bfd,
 	abort ();
 
       /* Get the value we are going to relocate.  */
-      if (1 == howto.size)
-	value_to_relocate = bfd_get_16 (input_bfd, location);
-      else if (2 == howto.size)
-	value_to_relocate = bfd_get_32 (input_bfd, location);
-      else
-	value_to_relocate = bfd_get_64 (input_bfd, location);
+      switch (bfd_get_reloc_size (&howto))
+	{
+	case 2:
+	  value_to_relocate = bfd_get_16 (input_bfd, location);
+	  break;
+	case 4:
+	  value_to_relocate = bfd_get_32 (input_bfd, location);
+	  break;
+	default:
+	  value_to_relocate = bfd_get_64 (input_bfd, location);
+	  break;
+	}
 
       /* overflow.
 
@@ -1729,13 +1737,18 @@ xcoff64_ppc_relocate_section (bfd *output_bfd,
 			       + relocation) & howto.dst_mask));
 
       /* Put the value back in the object file.  */
-      if (1 == howto.size)
-	bfd_put_16 (input_bfd, value_to_relocate, location);
-      else if (2 == howto.size)
-	bfd_put_32 (input_bfd, value_to_relocate, location);
-      else
-	bfd_put_64 (input_bfd, value_to_relocate, location);
-
+      switch (bfd_get_reloc_size (&howto))
+	{
+	case 2:
+	  bfd_put_16 (input_bfd, value_to_relocate, location);
+	  break;
+	case 4:
+	  bfd_put_32 (input_bfd, value_to_relocate, location);
+	  break;
+	default:
+	  bfd_put_64 (input_bfd, value_to_relocate, location);
+	  break;
+	}
     }
   return true;
 }
diff --git a/bfd/cpu-ns32k.c b/bfd/cpu-ns32k.c
index feffd48cf49..17f06c2440e 100644
--- a/bfd/cpu-ns32k.c
+++ b/bfd/cpu-ns32k.c
@@ -508,9 +508,12 @@ do_ns32k_reloc (bfd *      abfd,
   x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
 
   location = (bfd_byte *) data + addr;
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
     case 0:
+      break;
+
+    case 1:
       {
 	bfd_vma x = get_data (location, 1);
 	DOIT (x);
@@ -518,7 +521,7 @@ do_ns32k_reloc (bfd *      abfd,
       }
       break;
 
-    case 1:
+    case 2:
       if (relocation)
 	{
 	  bfd_vma x = get_data (location, 2);
@@ -526,7 +529,7 @@ do_ns32k_reloc (bfd *      abfd,
 	  put_data ((bfd_vma) x, location, 2);
 	}
       break;
-    case 2:
+    case 4:
       if (relocation)
 	{
 	  bfd_vma x = get_data (location, 4);
@@ -535,11 +538,7 @@ do_ns32k_reloc (bfd *      abfd,
 	}
       break;
 
-    case 3:
-      /* Do nothing.  */
-      break;
-
-    case 4:
+    case 8:
 #ifdef BFD64
       if (relocation)
 	{
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
index a4eaee6e6d1..4c9fc0128fa 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -1311,19 +1311,19 @@ arc_do_relocation (bfd_byte * contents,
   if (!reloc_data.should_relocate)
     return bfd_reloc_ok;
 
-  switch (reloc_data.howto->size)
+  switch (bfd_get_reloc_size (reloc_data.howto))
     {
-    case 2:
+    case 4:
       insn = arc_bfd_get_32 (abfd,
 			     contents + reloc_data.reloc_offset,
 			     reloc_data.input_section);
       break;
-    case 1:
+    case 2:
       insn = arc_bfd_get_16 (abfd,
 			     contents + reloc_data.reloc_offset,
 			     reloc_data.input_section);
       break;
-    case 0:
+    case 1:
       insn = arc_bfd_get_8 (abfd,
 			    contents + reloc_data.reloc_offset,
 			    reloc_data.input_section);
@@ -1367,19 +1367,19 @@ arc_do_relocation (bfd_byte * contents,
     }
 
   /* Write updated instruction back to memory.  */
-  switch (reloc_data.howto->size)
+  switch (bfd_get_reloc_size (reloc_data.howto))
     {
-    case 2:
+    case 4:
       arc_bfd_put_32 (abfd, insn,
 		      contents + reloc_data.reloc_offset,
 		      reloc_data.input_section);
       break;
-    case 1:
+    case 2:
 	arc_bfd_put_16 (abfd, insn,
 			contents + reloc_data.reloc_offset,
 			reloc_data.input_section);
 	break;
-    case 0:
+    case 1:
       arc_bfd_put_8 (abfd, insn,
 		     contents + reloc_data.reloc_offset,
 		     reloc_data.input_section);
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index b8c480fb1c1..60f89ec6117 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -10357,11 +10357,11 @@ elf32_arm_final_link_relocate (reloc_howto_type *	    howto,
     {
       bfd_vma sign;
 
-      switch (howto->size)
+      switch (bfd_get_reloc_size (howto))
 	{
-	case 0: addend = bfd_get_8 (input_bfd, hit_data); break;
-	case 1: addend = bfd_get_16 (input_bfd, hit_data); break;
-	case 2: addend = bfd_get_32 (input_bfd, hit_data); break;
+	case 1: addend = bfd_get_8 (input_bfd, hit_data); break;
+	case 2: addend = bfd_get_16 (input_bfd, hit_data); break;
+	case 4: addend = bfd_get_32 (input_bfd, hit_data); break;
 	default: addend = 0; break;
 	}
       /* Note: the addend and signed_addend calculated here are
@@ -13059,7 +13059,7 @@ arm_add_to_rel (bfd *		   abfd,
 	case R_ARM_PLT32:
 	case R_ARM_CALL:
 	case R_ARM_JUMP24:
-	  addend <<= howto->size;
+	  addend *= bfd_get_reloc_size (howto);
 	  addend += increment;
 
 	  /* Should we check for overflow here ?  */
diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c
index babc57e3955..99108309572 100644
--- a/bfd/elf32-bfin.c
+++ b/bfd/elf32-bfin.c
@@ -375,9 +375,9 @@ bfin_bfd_reloc (bfd *abfd,
   x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
 
   /* handle 8 and 16 bit relocations here. */
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
-    case 0:
+    case 1:
       {
 	char x = bfd_get_8 (abfd, (char *) data + addr);
 	DOIT (x);
@@ -385,7 +385,7 @@ bfin_bfd_reloc (bfd *abfd,
       }
       break;
 
-    case 1:
+    case 2:
       {
 	unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
 	DOIT (x);
diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c
index 88659dd7c8c..88d161eeef7 100644
--- a/bfd/elf32-cr16.c
+++ b/bfd/elf32-cr16.c
@@ -952,9 +952,9 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
       Rvalue &= howto->dst_mask;
     }
 
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
-    case 0:
+    case 1:
       if (r_type == R_CR16_DISP8)
 	{
 	  Rvalue1 = bfd_get_16 (input_bfd, hit_data);
@@ -981,7 +981,7 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
 	}
       break;
 
-    case 1:
+    case 2:
       if (r_type == R_CR16_DISP16)
 	{
 	  Rvalue |= (bfd_get_16 (input_bfd, hit_data));
@@ -1002,7 +1002,7 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
       bfd_put_16 (input_bfd, Rvalue, hit_data);
       break;
 
-    case 2:
+    case 4:
       if ((r_type == R_CR16_ABS20) || (r_type == R_CR16_IMM20))
 	{
 	  Rvalue1 = (bfd_get_16 (input_bfd, hit_data + 2)
diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c
index da81024f8da..747de318de1 100644
--- a/bfd/elf32-cris.c
+++ b/bfd/elf32-cris.c
@@ -492,7 +492,7 @@ cris_elf_pcrel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
 
      Only adjust when doing a final link.  */
   if (output_bfd == (bfd *) NULL)
-    reloc_entry->addend -= 1 << reloc_entry->howto->size;
+    reloc_entry->addend -= bfd_get_reloc_size (reloc_entry->howto);
 
   return
     bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
diff --git a/bfd/elf32-crx.c b/bfd/elf32-crx.c
index b4ec02a639f..cc6962f7b0e 100644
--- a/bfd/elf32-crx.c
+++ b/bfd/elf32-crx.c
@@ -530,9 +530,9 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
   /* Apply dst_mask to select only relocatable part of the insn.  */
   Rvalue &= howto->dst_mask;
 
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
-     case 0:
+     case 1:
        if (r_type == R_CRX_REL4)
 	 {
 	   Rvalue <<= 4;
@@ -542,14 +542,14 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
        bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
        break;
 
-     case 1:
+     case 2:
        if (r_type == R_CRX_REGREL12)
 	 Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
 
        bfd_put_16 (input_bfd, Rvalue, hit_data);
        break;
 
-     case 2:
+     case 4:
        if (r_type == R_CRX_REL24
 	   || r_type == R_CRX_REGREL22
 	   || r_type == R_CRX_REGREL28)
diff --git a/bfd/elf32-csky.c b/bfd/elf32-csky.c
index b312fe312be..3333eec9e7f 100644
--- a/bfd/elf32-csky.c
+++ b/bfd/elf32-csky.c
@@ -5146,7 +5146,7 @@ csky_elf_relocate_section (bfd *                  output_bfd,
 	 does no change with the data read. But we may need this mechanism in
 	 the future.  */
 
-      if (howto->size == 2
+      if (bfd_get_reloc_size (howto) == 4
 	  && (howto->type == R_CKCORE_ADDR32
 	      || howto->type == R_CKCORE_PCREL32
 	      || howto->type == R_CKCORE_GOT32
diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c
index 2a6c5c6cb46..cc9985566a9 100644
--- a/bfd/elf32-d10v.c
+++ b/bfd/elf32-d10v.c
@@ -324,15 +324,15 @@ extract_rel_addend (bfd *abfd,
 {
   bfd_vma insn, val;
 
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
-    case 0:
+    case 1:
       insn = bfd_get_8 (abfd, where);
       break;
-    case 1:
+    case 2:
       insn = bfd_get_16 (abfd, where);
       break;
-    case 2:
+    case 4:
       insn = bfd_get_32 (abfd, where);
       break;
     default:
@@ -362,19 +362,19 @@ insert_rel_addend (bfd *abfd,
 
   addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
   insn = ~howto->dst_mask;
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
-    case 0:
+    case 1:
       insn &= bfd_get_8 (abfd, where);
       insn |= addend;
       bfd_put_8 (abfd, insn, where);
       break;
-    case 1:
+    case 2:
       insn &= bfd_get_16 (abfd, where);
       insn |= addend;
       bfd_put_16 (abfd, insn, where);
       break;
-    case 2:
+    case 4:
       insn &= bfd_get_32 (abfd, where);
       insn |= addend;
       bfd_put_32 (abfd, insn, where);
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index b8f98276506..e4106d9fd3b 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2110,9 +2110,9 @@ elf_i386_relocate_section (bfd *output_bfd,
 	      bfd_vma addend;
 	      bfd_byte *where = contents + rel->r_offset;
 
-	      switch (howto->size)
+	      switch (bfd_get_reloc_size (howto))
 		{
-		case 0:
+		case 1:
 		  addend = bfd_get_8 (input_bfd, where);
 		  if (howto->pc_relative)
 		    {
@@ -2120,7 +2120,7 @@ elf_i386_relocate_section (bfd *output_bfd,
 		      addend += 1;
 		    }
 		  break;
-		case 1:
+		case 2:
 		  addend = bfd_get_16 (input_bfd, where);
 		  if (howto->pc_relative)
 		    {
@@ -2128,7 +2128,7 @@ elf_i386_relocate_section (bfd *output_bfd,
 		      addend += 2;
 		    }
 		  break;
-		case 2:
+		case 4:
 		  addend = bfd_get_32 (input_bfd, where);
 		  if (howto->pc_relative)
 		    {
@@ -2151,20 +2151,20 @@ elf_i386_relocate_section (bfd *output_bfd,
 		  addend += msec->output_section->vma + msec->output_offset;
 		}
 
-	      switch (howto->size)
+	      switch (bfd_get_reloc_size (howto))
 		{
-		case 0:
+		case 1:
 		  /* FIXME: overflow checks.  */
 		  if (howto->pc_relative)
 		    addend -= 1;
 		  bfd_put_8 (input_bfd, addend, where);
 		  break;
-		case 1:
+		case 2:
 		  if (howto->pc_relative)
 		    addend -= 2;
 		  bfd_put_16 (input_bfd, addend, where);
 		  break;
-		case 2:
+		case 4:
 		  if (howto->pc_relative)
 		    addend -= 4;
 		  bfd_put_32 (input_bfd, addend, where);
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index 4e13f962f7c..5ba509a6015 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -221,16 +221,16 @@ m32r_elf_generic_reloc (bfd *input_bfd,
   (((x & reloc_entry->howto->src_mask) +  relocation) &	\
   reloc_entry->howto->dst_mask))
 
-  switch (reloc_entry->howto->size)
+  switch (bfd_get_reloc_size (reloc_entry->howto))
     {
-    case 1:
+    case 2:
       {
 	short x = bfd_get_16 (input_bfd, inplace_address);
 	DOIT (x);
 	bfd_put_16 (input_bfd, (bfd_vma) x, inplace_address);
       }
       break;
-    case 2:
+    case 4:
       {
 	unsigned long x = bfd_get_32 (input_bfd, inplace_address);
 	DOIT (x);
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
index e185ddda83e..82c20592d6d 100644
--- a/bfd/elf32-nds32.c
+++ b/bfd/elf32-nds32.c
@@ -2986,9 +2986,9 @@ nds32_elf_generic_reloc (bfd *input_bfd, arelent *reloc_entry,
   (((x & reloc_entry->howto->src_mask) +  relocation) &	\
   reloc_entry->howto->dst_mask))
 
-  switch (reloc_entry->howto->size)
+  switch (bfd_get_reloc_size (reloc_entry->howto))
     {
-    case 1:
+    case 2:
       {
 	short x = bfd_getb16 (inplace_address);
 
@@ -2996,7 +2996,7 @@ nds32_elf_generic_reloc (bfd *input_bfd, arelent *reloc_entry,
 	bfd_putb16 ((bfd_vma) x, inplace_address);
       }
       break;
-    case 2:
+    case 4:
       {
 	unsigned long x = bfd_getb32 (inplace_address);
 
diff --git a/bfd/i386lynx.c b/bfd/i386lynx.c
index e5aa6f31bd3..840be8fd36d 100644
--- a/bfd/i386lynx.c
+++ b/bfd/i386lynx.c
@@ -120,7 +120,7 @@ NAME(lynx,swap_std_reloc_out) (bfd *abfd,
 
   PUT_WORD (abfd, g->address, natptr->r_address);
 
-  r_length = g->howto->size;	/* Size as a power of two */
+  r_length = bfd_log2 (bfd_get_reloc_size (g->howto));
   r_pcrel = (int) g->howto->pc_relative;	/* Relative to PC? */
   /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
   r_baserel = 0;
diff --git a/bfd/mach-o-i386.c b/bfd/mach-o-i386.c
index f3a66a9c896..01c1691916b 100644
--- a/bfd/mach-o-i386.c
+++ b/bfd/mach-o-i386.c
@@ -218,7 +218,7 @@ bfd_mach_o_i386_swap_reloc_out (arelent *rel, bfd_mach_o_reloc_info *rinfo)
       rinfo->r_scattered = 0;
       rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_VANILLA;
       rinfo->r_pcrel = rel->howto->pc_relative;
-      rinfo->r_length = rel->howto->size; /* Correct in practice.  */
+      rinfo->r_length = bfd_log2 (bfd_get_reloc_size (rel->howto));
       if ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
 	{
 	  rinfo->r_extern = 0;
@@ -235,7 +235,7 @@ bfd_mach_o_i386_swap_reloc_out (arelent *rel, bfd_mach_o_reloc_info *rinfo)
       rinfo->r_scattered = 1;
       rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_SECTDIFF;
       rinfo->r_pcrel = 0;
-      rinfo->r_length = rel->howto->size;
+      rinfo->r_length = bfd_log2 (bfd_get_reloc_size (rel->howto));
       rinfo->r_extern = 0;
       rinfo->r_value = rel->addend;
       break;
@@ -243,7 +243,7 @@ bfd_mach_o_i386_swap_reloc_out (arelent *rel, bfd_mach_o_reloc_info *rinfo)
       rinfo->r_scattered = 1;
       rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_LOCAL_SECTDIFF;
       rinfo->r_pcrel = 0;
-      rinfo->r_length = rel->howto->size;
+      rinfo->r_length = bfd_log2 (bfd_get_reloc_size (rel->howto));
       rinfo->r_extern = 0;
       rinfo->r_value = rel->addend;
       break;
@@ -252,7 +252,7 @@ bfd_mach_o_i386_swap_reloc_out (arelent *rel, bfd_mach_o_reloc_info *rinfo)
       rinfo->r_scattered = 1;
       rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_PAIR;
       rinfo->r_pcrel = 0;
-      rinfo->r_length = rel->howto->size;
+      rinfo->r_length = bfd_log2 (bfd_get_reloc_size (rel->howto));
       rinfo->r_extern = 0;
       rinfo->r_value = rel->addend;
       break;
diff --git a/bfd/pdp11.c b/bfd/pdp11.c
index 17cdbd4cff3..9ef63cc311c 100644
--- a/bfd/pdp11.c
+++ b/bfd/pdp11.c
@@ -3261,7 +3261,7 @@ 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;
-    r_length = howto->size;
+    r_length = bfd_log2 (bfd_get_reloc_size (howto));
 
     PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
     if (bfd_header_big_endian (flaginfo->output_bfd))
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 4ad1b858d69..76c309bc903 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -288,10 +288,8 @@ CODE_FRAGMENT
 .     an external reloc number is stored in this field.  *}
 .  unsigned int type;
 .
-.  {* The encoded size of the item to be relocated.  This is *not* a
-.     power-of-two measure.  Use bfd_get_reloc_size to find the size
-.     of the item in bytes.  *}
-.  unsigned int size:3;
+.  {* The size of the item to be relocated in bytes.  *}
+.  unsigned int size:4;
 .
 .  {* The number of bits in the field to be relocated.  This is used
 .     when doing overflow checking.  *}
@@ -375,7 +373,7 @@ DESCRIPTION
 	The HOWTO macro fills in a reloc_howto_type (a typedef for
 	const struct reloc_howto_struct).
 
-.#define HOWTO_RSIZE(sz) (sz == 1 || sz == -1 ? 0 : sz == 2 || sz == -2 ? 1 : sz == 4 || sz == -4 ? 2 : sz == 0 ? 3 : sz == 8 || sz == -8 ? 4 : sz == 3 || sz == -3 ? 5 : 0x777)
+.#define HOWTO_RSIZE(sz) ((sz) < 0 ? -(sz) : (sz))
 .#define HOWTO(type, right, size, bits, pcrel, left, ovf, func, name,	\
 .              inplace, src_mask, dst_mask, pcrel_off)			\
 .  { (unsigned) type, HOWTO_RSIZE (size), bits, right, left, ovf,	\
@@ -388,35 +386,14 @@ DESCRIPTION
 .  HOWTO ((C), 0, 1, 0, false, 0, complain_overflow_dont, NULL, \
 .	  NULL, false, 0, 0, false)
 .
+.static inline unsigned int
+.bfd_get_reloc_size (reloc_howto_type *howto)
+.{
+.  return howto->size;
+.}
+.
 */
 
-/*
-FUNCTION
-	bfd_get_reloc_size
-
-SYNOPSIS
-	unsigned int bfd_get_reloc_size (reloc_howto_type *);
-
-DESCRIPTION
-	For a reloc_howto_type that operates on a fixed number of bytes,
-	this returns the number of bytes operated on.
- */
-
-unsigned int
-bfd_get_reloc_size (reloc_howto_type *howto)
-{
-  switch (howto->size)
-    {
-    case 0: return 1;
-    case 1: return 2;
-    case 2: return 4;
-    case 3: return 0;
-    case 4: return 8;
-    case 5: return 3;
-    default: abort ();
-    }
-}
-
 /*
 TYPEDEF
 	arelent_chain
@@ -557,28 +534,28 @@ bfd_reloc_offset_in_range (reloc_howto_type *howto,
 static bfd_vma
 read_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto)
 {
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
     case 0:
-      return bfd_get_8 (abfd, data);
+      break;
 
     case 1:
-      return bfd_get_16 (abfd, data);
+      return bfd_get_8 (abfd, data);
 
     case 2:
-      return bfd_get_32 (abfd, data);
+      return bfd_get_16 (abfd, data);
 
     case 3:
-      break;
+      return bfd_get_24 (abfd, data);
 
-#ifdef BFD64
     case 4:
+      return bfd_get_32 (abfd, data);
+
+#ifdef BFD64
+    case 8:
       return bfd_get_64 (abfd, data);
 #endif
 
-    case 5:
-      return bfd_get_24 (abfd, data);
-
     default:
       abort ();
     }
@@ -591,32 +568,32 @@ read_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto)
 static void
 write_reloc (bfd *abfd, bfd_vma val, bfd_byte *data, reloc_howto_type *howto)
 {
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
     case 0:
-      bfd_put_8 (abfd, val, data);
       break;
 
     case 1:
-      bfd_put_16 (abfd, val, data);
+      bfd_put_8 (abfd, val, data);
       break;
 
     case 2:
-      bfd_put_32 (abfd, val, data);
+      bfd_put_16 (abfd, val, data);
       break;
 
     case 3:
+      bfd_put_24 (abfd, val, data);
       break;
 
-#ifdef BFD64
     case 4:
-      bfd_put_64 (abfd, val, data);
+      bfd_put_32 (abfd, val, data);
       break;
-#endif
 
-    case 5:
-      bfd_put_24 (abfd, val, data);
+#ifdef BFD64
+    case 8:
+      bfd_put_64 (abfd, val, data);
       break;
+#endif
 
     default:
       abort ();
diff --git a/bfd/syms.c b/bfd/syms.c
index 9fc0c467207..b284cb294ff 100644
--- a/bfd/syms.c
+++ b/bfd/syms.c
@@ -1081,7 +1081,7 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
 
 	      octets = r->address * bfd_octets_per_byte (abfd, NULL);
 	      if (r->howto->rightshift != 0
-		  || r->howto->size != 2
+		  || bfd_get_reloc_size (r->howto) != 4
 		  || r->howto->bitsize != 32
 		  || r->howto->pc_relative
 		  || r->howto->bitpos != 0


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:04 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:04 [binutils-gdb] Don't encode reloc.size Alan Modra

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