#include "sysdep.h"
#include "bfd.h"
+#include "libbfd.h"
#include "aout/aout64.h"
#include "ns32k.h"
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;
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;
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? */
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))
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. */
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, \
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
{
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);
}
break;
- case 1:
+ case 2:
{
short x = bfd_get_16 (abfd, addr);
DOIT (x);
}
break;
- case 2:
+ case 4:
{
long x = bfd_get_32 (abfd, addr);
DOIT (x);
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
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);
}
break;
- case 1:
+ case 2:
{
short x = bfd_get_16 (abfd, addr);
DOIT (x);
}
break;
- case 2:
+ case 4:
{
long x = bfd_get_32 (abfd, addr);
DOIT (x);
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;
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);
+ 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);
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);
}
break;
- case 1:
+ case 2:
{
short x = bfd_get_16 (abfd, addr);
DOIT (x);
}
break;
- case 2:
+ case 4:
{
long x = bfd_get_32 (abfd, addr);
DOIT (x);
}
break;
- case 4:
+ case 8:
{
uint64_t x = bfd_get_64 (abfd, addr);
DOIT (x);
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;
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.
+ 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;
}
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);
}
break;
- case 1:
+ case 2:
if (relocation)
{
bfd_vma x = get_data (location, 2);
put_data ((bfd_vma) x, location, 2);
}
break;
- case 2:
+ case 4:
if (relocation)
{
bfd_vma x = get_data (location, 4);
}
break;
- case 3:
- /* Do nothing. */
- break;
-
- case 4:
+ case 8:
#ifdef BFD64
if (relocation)
{
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);
}
/* 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);
{
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
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 ? */
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);
}
break;
- case 1:
+ case 2:
{
unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
DOIT (x);
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);
}
break;
- case 1:
+ case 2:
if (r_type == R_CR16_DISP16)
{
Rvalue |= (bfd_get_16 (input_bfd, hit_data));
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)
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,
/* 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;
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)
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
{
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:
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);
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)
{
addend += 1;
}
break;
- case 1:
+ case 2:
addend = bfd_get_16 (input_bfd, where);
if (howto->pc_relative)
{
addend += 2;
}
break;
- case 2:
+ case 4:
addend = bfd_get_32 (input_bfd, where);
if (howto->pc_relative)
{
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);
(((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);
(((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);
bfd_putb16 ((bfd_vma) x, inplace_address);
}
break;
- case 2:
+ case 4:
{
unsigned long x = bfd_getb32 (inplace_address);
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;
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;
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;
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;
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;
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))
. 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. *}
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, \
. 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
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 ();
}
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 ();
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