From 57698478b75319a962b899c3f8d3a03baa5eaab4 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 8 Jun 2022 09:49:09 +0930 Subject: [PATCH] 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. --- 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 -- 2.30.2