Don't encode reloc.size
authorAlan Modra <amodra@gmail.com>
Wed, 8 Jun 2022 00:19:09 +0000 (09:49 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 8 Jun 2022 12:03:00 +0000 (21:33 +0930)
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.

25 files changed:
bfd/aout-ns32k.c
bfd/aoutx.h
bfd/bfd-in2.h
bfd/coff-arm.c
bfd/coff-i386.c
bfd/coff-rs6000.c
bfd/coff-x86_64.c
bfd/coff64-rs6000.c
bfd/cpu-ns32k.c
bfd/elf32-arc.c
bfd/elf32-arm.c
bfd/elf32-bfin.c
bfd/elf32-cr16.c
bfd/elf32-cris.c
bfd/elf32-crx.c
bfd/elf32-csky.c
bfd/elf32-d10v.c
bfd/elf32-i386.c
bfd/elf32-m32r.c
bfd/elf32-nds32.c
bfd/i386lynx.c
bfd/mach-o-i386.c
bfd/pdp11.c
bfd/reloc.c
bfd/syms.c

index 1dce76446521bf1cb5ab361a0b93894100802fe4..f4c447dcc377eddca1db94cf67d683ee7e5e1f37 100644 (file)
@@ -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;
 
index 2bff7a8d8b26376e413064909e7fe5a7c1179927..e9b5188e8e79c31f9221ac3083ed0e20e4c06b28 100644 (file)
@@ -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))
index f18c2faece14130de7a12336353a5ec0e76e5d29..64e74adff73b90b4dd83320e0c544c3f40a85c1a 100644 (file)
@@ -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
 {
index f9e117ace52b7e84c6982411b83306fdef7577f3..65cb946510e7f11e6216c65709fa52a856aa5d9a 100644 (file)
@@ -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);
index 9e5dbab38ce27449883f81f17d048f41c4f1b1d1..92cc5c207bf6aff5e48e8511c371760abefebc6e 100644 (file)
@@ -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);
index f39a85a46a080fbd1fc44ad16023811c4c8d0de4..6ad77ba77c417434d947e82c204def4beebfcd7b 100644 (file)
@@ -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);
index bc9c3d43699a6e9126148b0c7311719d2757e062..c2b2d0e4d58307d0845e6092399d61439cf36376 100644 (file)
@@ -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);
index 5df3dc199529e77c3cf2bf2066475846ca5273ab..ce1c518282ea04bf2e7f35d6ac980ced27597060 100644 (file)
@@ -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;
 }
index feffd48cf49425282c7c0817c0958788ef349e2b..17f06c2440ebfcdbb11df6996b69141d088e7d5c 100644 (file)
@@ -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)
        {
index a4eaee6e6d13d91bf96bb424534dd5f70ae92489..4c9fc0128fa607e6bcbce241df2ec2bae9006298 100644 (file)
@@ -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);
index b8c480fb1c1aa54765db244813d6af1aacc33621..60f89ec61179a3ccf398cec83ae426ce28ebdbe2 100644 (file)
@@ -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 ?  */
index babc57e3955b23e2b890db49206e6ae998e4ff29..991083095727da33eccc3a62c826b63a482e2bad 100644 (file)
@@ -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);
index 88659dd7c8c0dd474f50062d642db81acb49c03c..88d161eeef71bbdcbee8aa49c2c9bad165523b1e 100644 (file)
@@ -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)
index da81024f8da204508aadf638d4474088b6b44fe1..747de318de1febdcbdd6781ba06000173bc715d6 100644 (file)
@@ -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,
index b4ec02a639ff70600c7e0d3cd51762fa5147842d..cc6962f7b0e01dc9a7dc5e9720c28a55bae4889c 100644 (file)
@@ -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)
index b312fe312becfb1872e6b9f6b6f80259824216d0..3333eec9e7fd475522c2996c7fc8eb2bb7d2f3b3 100644 (file)
@@ -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
index 2a6c5c6cb46655dc0b501b3de422cbc732415514..cc9985566a99052df22323bdda02406ce1a298bf 100644 (file)
@@ -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);
index b8f98276506ef69130827ecbebd7ed4aff395f2c..e4106d9fd3b89fed18c9b9d1544c7db0af8f379d 100644 (file)
@@ -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);
index 4e13f962f7c9857e0eb081665b3defc049f9de2b..5ba509a6015218d8903e7018ed03b0e52e1722ea 100644 (file)
@@ -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);
index e185ddda83e84aecc188ed8a7c4c9c2b07ca02c1..82c20592d6d3af60a4836795cf1cb31bea218465 100644 (file)
@@ -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);
 
index e5aa6f31bd3d633c5ded5ed5dcad68263ca94beb..840be8fd36d145a7f317c3bc9d2d434178a8f025 100644 (file)
@@ -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;
index f3a66a9c896acfe132bf931d62b4c23947d2908e..01c1691916b989536ac2e5df03359aeb6697a007 100644 (file)
@@ -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;
index 17cdbd4cff3c0200fb1e64c862dea25f88bc84b6..9ef63cc311cb64a855a958750ee2c93af34938a1 100644 (file)
@@ -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))
index 4ad1b858d69d94228b3b0113513d7fd7cea66911..76c309bc9035f57dc504e6203ca37f3e7bf35edf 100644 (file)
@@ -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 ();
index 9fc0c467207a3d3c7e92618cda30678c822df062..b284cb294ffe782b42aac18bdb95da2b2aed22c2 100644 (file)
@@ -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