+2018-08-21 Alan Modra <amodra@gmail.com>
+
+ * reloc.c (reloc_howto_type): Typedef.
+ (bfd_symbol): Delete forward declaration.
+ (struct reloc_howto_struct): Add "negate" field. Make "size",
+ "bitsize", "rightshift", "bitpos", "complain_on_overflow",
+ "pc_relative", "partial_inplace", and "pcrel_offset" bitfields.
+ Rearrange for better packing. Revise comments.
+ (HOWTO): Map to rearranged reloc_howto_struct.
+ (bfd_get_reloc_size): Delete now unused cases.
+ (read_reloc, write_reloc): Likewise.
+ (apply_reloc, _bfd_relocate_contents): Test howto->negate
+ rather than howto->size < 0 for negated relocation values.
+ * coff-rs6000.c (xcoff_complain_overflow_bitfield_func): Avoid
+ signed/unsigned warning.
+ (xcoff_ppc_relocate_section): Delete "condition is always false"
+ code.
+ * coff64-rs6000.c (xcoff64_ppc_relocate_section): Likewise.
+ * cpu-ns32k.c (do_ns32k_reloc): Adjust to suit reloc_howto_struct
+ changes.
+ * vms-alpha.c (_bfd_vms_write_etir, alpha_vms_slurp_relocs): Use
+ size 16 for ALPHA_R_LINKAGE.
+ (alpha_howto_table <ALPHA_R_LINKAGE>): Set encoded size and
+ bitsize to zero.
+ * bfd-in.h (reloc_howto_type): Delete.
+ * bfd-in2.h: Regenerate.
+
2018-08-21 Alan Modra <amodra@gmail.com>
* reloc.c (HOWTO): Revise comment.
/* A count of carsyms (canonical archive symbols). */
typedef unsigned long symindex;
-/* How to perform a relocation. */
-typedef const struct reloc_howto_struct reloc_howto_type;
-
#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
/* General purpose part of a symbol X;
/* A count of carsyms (canonical archive symbols). */
typedef unsigned long symindex;
-/* How to perform a relocation. */
-typedef const struct reloc_howto_struct reloc_howto_type;
-
#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
/* General purpose part of a symbol X;
}
bfd_reloc_status_type;
+typedef const struct reloc_howto_struct reloc_howto_type;
typedef struct reloc_cache_entry
{
unsigned number. */
complain_overflow_unsigned
};
-struct bfd_symbol; /* Forward declaration. */
-
struct reloc_howto_struct
{
- /* The type field has mainly a documentary use - the back end can
- do what it wants with it, though normally the back end's
- external idea of what a reloc number is stored
- in this field. For example, a PC relative word relocation
- in a coff environment has the type 023 - because that's
- what the outside world calls a R_PCRWORD reloc. */
+ /* The type field has mainly a documentary use - the back end can
+ do what it wants with it, though normally the back end's idea of
+ an external reloc number is stored in this field. */
unsigned int type;
- /* The value the final relocation is shifted right by. This drops
- unwanted data from the relocation. */
- unsigned int rightshift;
+ /* 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. This is *not* a
- power-of-two measure. To get the number of bytes operated
- on by a type of relocation, use bfd_get_reloc_size. */
- int size;
+ /* The number of bits in the field to be relocated. This is used
+ when doing overflow checking. */
+ unsigned int bitsize:7;
- /* The number of bits in the item to be relocated. This is used
- when doing overflow checking. */
- unsigned int bitsize;
+ /* The value the final relocation is shifted right by. This drops
+ unwanted data from the relocation. */
+ unsigned int rightshift:6;
- /* The relocation is relative to the field being relocated. */
- bfd_boolean pc_relative;
-
- /* The bit position of the reloc value in the destination.
- The relocated value is left shifted by this amount. */
- unsigned int bitpos;
+ /* The bit position of the reloc value in the destination.
+ The relocated value is left shifted by this amount. */
+ unsigned int bitpos:6;
/* What type of overflow error should be checked for when
relocating. */
- enum complain_overflow complain_on_overflow;
+ ENUM_BITFIELD (complain_overflow) complain_on_overflow:2;
- /* If this field is non null, then the supplied function is
- called rather than the normal function. This allows really
- strange relocation methods to be accommodated. */
- bfd_reloc_status_type (*special_function)
- (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
- bfd *, char **);
+ /* The relocation value should be negated before applying. */
+ unsigned int negate:1;
- /* The textual name of the relocation type. */
- char *name;
+ /* The relocation is relative to the item being relocated. */
+ unsigned int pc_relative:1;
/* Some formats record a relocation addend in the section contents
rather than with the relocation. For ELF formats this is the
USE_REL targets set this field to TRUE. Why this is so is peculiar
to each particular target. For relocs that aren't used in partial
links (e.g. GOT stuff) it doesn't matter what this is set to. */
- bfd_boolean partial_inplace;
+ unsigned int partial_inplace:1;
+
+ /* When some formats create PC relative instructions, they leave
+ the value of the pc of the place being relocated in the offset
+ slot of the instruction, so that a PC relative relocation can
+ be made just by adding in an ordinary offset (e.g., sun3 a.out).
+ Some formats leave the displacement part of an instruction
+ empty (e.g., ELF); this flag signals the fact. */
+ unsigned int pcrel_offset:1;
/* src_mask selects the part of the instruction (or data) to be used
in the relocation sum. If the target relocations don't have an
addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
dst_mask to extract the addend from the section contents. If
relocations do have an addend in the reloc, eg. ELF USE_RELA, this
- field should be zero. Non-zero values for ELF USE_RELA targets are
- bogus as in those cases the value in the dst_mask part of the
- section contents should be treated as garbage. */
+ field should normally be zero. Non-zero values for ELF USE_RELA
+ targets should be viewed with suspicion as normally the value in
+ the dst_mask part of the section contents should be ignored. */
bfd_vma src_mask;
/* dst_mask selects which parts of the instruction (or data) are
replaced with a relocated value. */
bfd_vma dst_mask;
- /* When some formats create PC relative instructions, they leave
- the value of the pc of the place being relocated in the offset
- slot of the instruction, so that a PC relative relocation can
- be made just by adding in an ordinary offset (e.g., sun3 a.out).
- Some formats leave the displacement part of an instruction
- empty (e.g., ELF); this flag signals the fact. */
- bfd_boolean pcrel_offset;
+ /* If this field is non null, then the supplied function is
+ called rather than the normal function. This allows really
+ strange relocation methods to be accommodated. */
+ bfd_reloc_status_type (*special_function)
+ (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
+ bfd *, char **);
+
+ /* The textual name of the relocation type. */
+ char *name;
};
-#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
- { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC }
+#define HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \
+ inplace, src_mask, dst_mask, pcrel_off) \
+ { (unsigned) type, size < 0 ? -size : size, bits, right, left, ovf, \
+ size < 0, pcrel, inplace, pcrel_off, src_mask, dst_mask, func, name }
#define EMPTY_HOWTO(C) \
HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
NULL, FALSE, 0, 0, FALSE)
relies on it, and it is the only way to write assembler
code which can run when loaded at a location 0x80000000
away from the location at which it is linked. */
- if (howto->bitsize + howto->rightshift
+ if ((unsigned) howto->bitsize + howto->rightshift
== bfd_arch_bits_per_address (input_bfd))
return FALSE;
operation, which would be tedious, or we must do the computations
in a type larger than bfd_vma, which would be inefficient. */
- if ((unsigned int) howto.complain_on_overflow
- >= XCOFF_MAX_COMPLAIN_OVERFLOW)
- abort ();
-
if (((*xcoff_complain_overflow[howto.complain_on_overflow])
(input_bfd, value_to_relocate, relocation, &howto)))
{
operation, which would be tedious, or we must do the computations
in a type larger than bfd_vma, which would be inefficient. */
- if ((unsigned int) howto.complain_on_overflow
- >= XCOFF_MAX_COMPLAIN_OVERFLOW)
- abort ();
-
if (((*xcoff_complain_overflow[howto.complain_on_overflow])
(input_bfd, value_to_relocate, relocation, &howto)))
{
-----------------------
R R R R R R R R R R put into bfd_put<size>. */
+ if (howto->negate)
+ relocation = -relocation;
+
#define DOIT(x) \
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
put_data ((bfd_vma) x, location, 4);
}
break;
- case -2:
- {
- bfd_vma x = get_data (location, 4);
- relocation = -relocation;
- DOIT(x);
- put_data ((bfd_vma) x, location, 4);
- }
- break;
case 3:
/* Do nothing. */
. }
. bfd_reloc_status_type;
.
+.typedef const struct reloc_howto_struct reloc_howto_type;
.
.typedef struct reloc_cache_entry
.{
information that libbfd needs to know to tie up a back end's data.
CODE_FRAGMENT
-.struct bfd_symbol; {* Forward declaration. *}
-.
.struct reloc_howto_struct
.{
-. {* The type field has mainly a documentary use - the back end can
-. do what it wants with it, though normally the back end's
-. external idea of what a reloc number is stored
-. in this field. For example, a PC relative word relocation
-. in a coff environment has the type 023 - because that's
-. what the outside world calls a R_PCRWORD reloc. *}
+. {* The type field has mainly a documentary use - the back end can
+. do what it wants with it, though normally the back end's idea of
+. an external reloc number is stored in this field. *}
. unsigned int type;
.
-. {* The value the final relocation is shifted right by. This drops
-. unwanted data from the relocation. *}
-. unsigned int rightshift;
-.
-. {* The size of the item to be relocated. This is *not* a
-. power-of-two measure. To get the number of bytes operated
-. on by a type of relocation, use bfd_get_reloc_size. *}
-. int size;
+. {* 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 number of bits in the item to be relocated. This is used
-. when doing overflow checking. *}
-. unsigned int bitsize;
+. {* The number of bits in the field to be relocated. This is used
+. when doing overflow checking. *}
+. unsigned int bitsize:7;
.
-. {* The relocation is relative to the field being relocated. *}
-. bfd_boolean pc_relative;
+. {* The value the final relocation is shifted right by. This drops
+. unwanted data from the relocation. *}
+. unsigned int rightshift:6;
.
-. {* The bit position of the reloc value in the destination.
-. The relocated value is left shifted by this amount. *}
-. unsigned int bitpos;
+. {* The bit position of the reloc value in the destination.
+. The relocated value is left shifted by this amount. *}
+. unsigned int bitpos:6;
.
. {* What type of overflow error should be checked for when
. relocating. *}
-. enum complain_overflow complain_on_overflow;
+. ENUM_BITFIELD (complain_overflow) complain_on_overflow:2;
.
-. {* If this field is non null, then the supplied function is
-. called rather than the normal function. This allows really
-. strange relocation methods to be accommodated. *}
-. bfd_reloc_status_type (*special_function)
-. (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
-. bfd *, char **);
+. {* The relocation value should be negated before applying. *}
+. unsigned int negate:1;
.
-. {* The textual name of the relocation type. *}
-. char *name;
+. {* The relocation is relative to the item being relocated. *}
+. unsigned int pc_relative:1;
.
. {* Some formats record a relocation addend in the section contents
. rather than with the relocation. For ELF formats this is the
. USE_REL targets set this field to TRUE. Why this is so is peculiar
. to each particular target. For relocs that aren't used in partial
. links (e.g. GOT stuff) it doesn't matter what this is set to. *}
-. bfd_boolean partial_inplace;
+. unsigned int partial_inplace:1;
+.
+. {* When some formats create PC relative instructions, they leave
+. the value of the pc of the place being relocated in the offset
+. slot of the instruction, so that a PC relative relocation can
+. be made just by adding in an ordinary offset (e.g., sun3 a.out).
+. Some formats leave the displacement part of an instruction
+. empty (e.g., ELF); this flag signals the fact. *}
+. unsigned int pcrel_offset:1;
.
. {* src_mask selects the part of the instruction (or data) to be used
. in the relocation sum. If the target relocations don't have an
. addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
. dst_mask to extract the addend from the section contents. If
. relocations do have an addend in the reloc, eg. ELF USE_RELA, this
-. field should be zero. Non-zero values for ELF USE_RELA targets are
-. bogus as in those cases the value in the dst_mask part of the
-. section contents should be treated as garbage. *}
+. field should normally be zero. Non-zero values for ELF USE_RELA
+. targets should be viewed with suspicion as normally the value in
+. the dst_mask part of the section contents should be ignored. *}
. bfd_vma src_mask;
.
. {* dst_mask selects which parts of the instruction (or data) are
. replaced with a relocated value. *}
. bfd_vma dst_mask;
.
-. {* When some formats create PC relative instructions, they leave
-. the value of the pc of the place being relocated in the offset
-. slot of the instruction, so that a PC relative relocation can
-. be made just by adding in an ordinary offset (e.g., sun3 a.out).
-. Some formats leave the displacement part of an instruction
-. empty (e.g., ELF); this flag signals the fact. *}
-. bfd_boolean pcrel_offset;
+. {* If this field is non null, then the supplied function is
+. called rather than the normal function. This allows really
+. strange relocation methods to be accommodated. *}
+. bfd_reloc_status_type (*special_function)
+. (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
+. bfd *, char **);
+.
+. {* The textual name of the relocation type. *}
+. char *name;
.};
.
*/
The HOWTO macro fills in a reloc_howto_type (a typedef for
const struct reloc_howto_struct).
-.#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
-. { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC }
+.#define HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \
+. inplace, src_mask, dst_mask, pcrel_off) \
+. { (unsigned) type, size < 0 ? -size : size, bits, right, left, ovf, \
+. size < 0, pcrel, inplace, pcrel_off, src_mask, dst_mask, func, name }
DESCRIPTION
This is used to fill in an empty howto entry in an array.
switch (howto->size)
{
case 0: return 1;
- case 1:
- case -1: return 2;
- case 2:
- case -2: return 4;
+ case 1: return 2;
+ case 2: return 4;
case 3: return 0;
case 4: return 8;
case 5: return 3;
- case 8: return 16;
default: abort ();
}
}
return bfd_get_8 (abfd, data);
case 1:
- case -1:
return bfd_get_16 (abfd, data);
case 2:
- case -2:
return bfd_get_32 (abfd, data);
case 3:
break;
case 1:
- case -1:
bfd_put_16 (abfd, val, data);
break;
case 2:
- case -2:
bfd_put_32 (abfd, val, data);
break;
{
bfd_vma val = read_reloc (abfd, data, howto);
- if (howto->size < 0)
+ if (howto->negate)
relocation = -relocation;
val = ((val & ~howto->dst_mask)
unsigned int rightshift = howto->rightshift;
unsigned int bitpos = howto->bitpos;
- /* If the size is negative, negate RELOCATION. This isn't very
- general. */
- if (howto->size < 0)
+ if (howto->negate)
relocation = -relocation;
/* Get the value we are going to relocate. */
break;
case ALPHA_R_LINKAGE:
+ size = 16;
etir_output_check (abfd, section, curr_addr, 64);
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
_bfd_vms_output_long
asection *sec;
struct vms_section_data_struct *vms_sec;
arelent *reloc;
+ bfd_size_type size;
/* Get section to which the relocation applies. */
if (cur_psect < 0 || cur_psect > (int)PRIV (section_count))
reloc->address = cur_address;
reloc->addend = cur_addend;
- vaddr += bfd_get_reloc_size (reloc->howto);
+ if (reloc_code == ALPHA_R_LINKAGE)
+ size = 16;
+ else
+ size = bfd_get_reloc_size (reloc->howto);
+ vaddr += size;
}
cur_addend = 0;
/* Hack. Linkage is done by linker. */
HOWTO (ALPHA_R_LINKAGE, /* Type. */
0, /* Rightshift. */
- 8, /* Size (0 = byte, 1 = short, 2 = long). */
- 256, /* Bitsize. */
+ 0, /* Size (0 = byte, 1 = short, 2 = long). */
+ 0, /* Bitsize. */
FALSE, /* PC relative. */
0, /* Bitpos. */
complain_overflow_dont,/* Complain_on_overflow. */