Pack reloc_howto_struct
This patch uses bitfields in reloc_howto_struct, reducing its size from 80 to 40 bytes on 64-bit hosts and from 52 to 32 bytes on 32-bit hosts (with a 32-bit bfd_vma). I've also added a new "negate" field rather than making the encoded "size" field do double duty as both a size and a flag. There was just one use of an encoded size of 8, which according to bfd_get_reloc_size meant 16 bytes, in vms-alpha.c ALPHA_R_LINKAGE. See git commitc3d8e071bf
adding ALPHA_R_LINKAGE and git commit8612a388f7
decoding size 8 in bfd_get_reloc_size. Since no other part of BFD handles 16 byte relocs, I've removed that encoding and special cased the ALPHA_R_LINKAGE size in vms-alpha.c. * 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.
This commit is contained in:
parent
487096bf0b
commit
706704c883
@ -1,3 +1,30 @@
|
|||||||
|
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>
|
2018-08-21 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* reloc.c (HOWTO): Revise comment.
|
* reloc.c (HOWTO): Revise comment.
|
||||||
|
@ -234,9 +234,6 @@ bfd_format;
|
|||||||
/* A count of carsyms (canonical archive symbols). */
|
/* A count of carsyms (canonical archive symbols). */
|
||||||
typedef unsigned long symindex;
|
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)
|
#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
|
||||||
|
|
||||||
/* General purpose part of a symbol X;
|
/* General purpose part of a symbol X;
|
||||||
|
100
bfd/bfd-in2.h
100
bfd/bfd-in2.h
@ -241,9 +241,6 @@ bfd_format;
|
|||||||
/* A count of carsyms (canonical archive symbols). */
|
/* A count of carsyms (canonical archive symbols). */
|
||||||
typedef unsigned long symindex;
|
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)
|
#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
|
||||||
|
|
||||||
/* General purpose part of a symbol X;
|
/* General purpose part of a symbol X;
|
||||||
@ -2535,6 +2532,7 @@ typedef enum bfd_reloc_status
|
|||||||
}
|
}
|
||||||
bfd_reloc_status_type;
|
bfd_reloc_status_type;
|
||||||
|
|
||||||
|
typedef const struct reloc_howto_struct reloc_howto_type;
|
||||||
|
|
||||||
typedef struct reloc_cache_entry
|
typedef struct reloc_cache_entry
|
||||||
{
|
{
|
||||||
@ -2572,51 +2570,39 @@ enum complain_overflow
|
|||||||
unsigned number. */
|
unsigned number. */
|
||||||
complain_overflow_unsigned
|
complain_overflow_unsigned
|
||||||
};
|
};
|
||||||
struct bfd_symbol; /* Forward declaration. */
|
|
||||||
|
|
||||||
struct reloc_howto_struct
|
struct reloc_howto_struct
|
||||||
{
|
{
|
||||||
/* The type field has mainly a documentary use - the back end can
|
/* The type field has mainly a documentary use - the back end can
|
||||||
do what it wants with it, though normally the back end's
|
do what it wants with it, though normally the back end's idea of
|
||||||
external idea of what a reloc number is stored
|
an external reloc number is stored in this field. */
|
||||||
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. */
|
|
||||||
unsigned int type;
|
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 number of bits in the field to be relocated. This is used
|
||||||
|
when doing overflow checking. */
|
||||||
|
unsigned int bitsize:7;
|
||||||
|
|
||||||
/* The value the final relocation is shifted right by. This drops
|
/* The value the final relocation is shifted right by. This drops
|
||||||
unwanted data from the relocation. */
|
unwanted data from the relocation. */
|
||||||
unsigned int rightshift;
|
unsigned int rightshift:6;
|
||||||
|
|
||||||
/* 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 item to be relocated. This is used
|
|
||||||
when doing overflow checking. */
|
|
||||||
unsigned int bitsize;
|
|
||||||
|
|
||||||
/* The relocation is relative to the field being relocated. */
|
|
||||||
bfd_boolean pc_relative;
|
|
||||||
|
|
||||||
/* The bit position of the reloc value in the destination.
|
/* The bit position of the reloc value in the destination.
|
||||||
The relocated value is left shifted by this amount. */
|
The relocated value is left shifted by this amount. */
|
||||||
unsigned int bitpos;
|
unsigned int bitpos:6;
|
||||||
|
|
||||||
/* What type of overflow error should be checked for when
|
/* What type of overflow error should be checked for when
|
||||||
relocating. */
|
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
|
/* The relocation value should be negated before applying. */
|
||||||
called rather than the normal function. This allows really
|
unsigned int negate:1;
|
||||||
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. */
|
/* The relocation is relative to the item being relocated. */
|
||||||
char *name;
|
unsigned int pc_relative:1;
|
||||||
|
|
||||||
/* Some formats record a relocation addend in the section contents
|
/* Some formats record a relocation addend in the section contents
|
||||||
rather than with the relocation. For ELF formats this is the
|
rather than with the relocation. For ELF formats this is the
|
||||||
@ -2633,21 +2619,7 @@ struct reloc_howto_struct
|
|||||||
USE_REL targets set this field to TRUE. Why this is so is peculiar
|
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
|
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. */
|
links (e.g. GOT stuff) it doesn't matter what this is set to. */
|
||||||
bfd_boolean partial_inplace;
|
unsigned int partial_inplace: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. */
|
|
||||||
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
|
/* When some formats create PC relative instructions, they leave
|
||||||
the value of the pc of the place being relocated in the offset
|
the value of the pc of the place being relocated in the offset
|
||||||
@ -2655,11 +2627,37 @@ struct reloc_howto_struct
|
|||||||
be made just by adding in an ordinary offset (e.g., sun3 a.out).
|
be made just by adding in an ordinary offset (e.g., sun3 a.out).
|
||||||
Some formats leave the displacement part of an instruction
|
Some formats leave the displacement part of an instruction
|
||||||
empty (e.g., ELF); this flag signals the fact. */
|
empty (e.g., ELF); this flag signals the fact. */
|
||||||
bfd_boolean pcrel_offset;
|
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 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;
|
||||||
|
|
||||||
|
/* 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) \
|
#define HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \
|
||||||
{ (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC }
|
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) \
|
#define EMPTY_HOWTO(C) \
|
||||||
HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
|
HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
|
||||||
NULL, FALSE, 0, 0, FALSE)
|
NULL, FALSE, 0, 0, FALSE)
|
||||||
|
@ -3090,7 +3090,7 @@ xcoff_complain_overflow_bitfield_func (bfd *input_bfd,
|
|||||||
relies on it, and it is the only way to write assembler
|
relies on it, and it is the only way to write assembler
|
||||||
code which can run when loaded at a location 0x80000000
|
code which can run when loaded at a location 0x80000000
|
||||||
away from the location at which it is linked. */
|
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))
|
== bfd_arch_bits_per_address (input_bfd))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -3458,10 +3458,6 @@ xcoff_ppc_relocate_section (bfd *output_bfd,
|
|||||||
operation, which would be tedious, or we must do the computations
|
operation, which would be tedious, or we must do the computations
|
||||||
in a type larger than bfd_vma, which would be inefficient. */
|
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])
|
if (((*xcoff_complain_overflow[howto.complain_on_overflow])
|
||||||
(input_bfd, value_to_relocate, relocation, &howto)))
|
(input_bfd, value_to_relocate, relocation, &howto)))
|
||||||
{
|
{
|
||||||
|
@ -1306,10 +1306,6 @@ xcoff64_ppc_relocate_section (bfd *output_bfd,
|
|||||||
operation, which would be tedious, or we must do the computations
|
operation, which would be tedious, or we must do the computations
|
||||||
in a type larger than bfd_vma, which would be inefficient. */
|
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])
|
if (((*xcoff_complain_overflow[howto.complain_on_overflow])
|
||||||
(input_bfd, value_to_relocate, relocation, &howto)))
|
(input_bfd, value_to_relocate, relocation, &howto)))
|
||||||
{
|
{
|
||||||
|
@ -501,6 +501,9 @@ do_ns32k_reloc (bfd * abfd,
|
|||||||
-----------------------
|
-----------------------
|
||||||
R R R R R R R R R R put into bfd_put<size>. */
|
R R R R R R R R R R put into bfd_put<size>. */
|
||||||
|
|
||||||
|
if (howto->negate)
|
||||||
|
relocation = -relocation;
|
||||||
|
|
||||||
#define DOIT(x) \
|
#define DOIT(x) \
|
||||||
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
|
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
|
||||||
|
|
||||||
@ -531,14 +534,6 @@ do_ns32k_reloc (bfd * abfd,
|
|||||||
put_data ((bfd_vma) x, location, 4);
|
put_data ((bfd_vma) x, location, 4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case -2:
|
|
||||||
{
|
|
||||||
bfd_vma x = get_data (location, 4);
|
|
||||||
relocation = -relocation;
|
|
||||||
DOIT(x);
|
|
||||||
put_data ((bfd_vma) x, location, 4);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
/* Do nothing. */
|
/* Do nothing. */
|
||||||
|
114
bfd/reloc.c
114
bfd/reloc.c
@ -94,6 +94,7 @@ CODE_FRAGMENT
|
|||||||
. }
|
. }
|
||||||
. bfd_reloc_status_type;
|
. bfd_reloc_status_type;
|
||||||
.
|
.
|
||||||
|
.typedef const struct reloc_howto_struct reloc_howto_type;
|
||||||
.
|
.
|
||||||
.typedef struct reloc_cache_entry
|
.typedef struct reloc_cache_entry
|
||||||
.{
|
.{
|
||||||
@ -279,51 +280,39 @@ SUBSUBSECTION
|
|||||||
information that libbfd needs to know to tie up a back end's data.
|
information that libbfd needs to know to tie up a back end's data.
|
||||||
|
|
||||||
CODE_FRAGMENT
|
CODE_FRAGMENT
|
||||||
.struct bfd_symbol; {* Forward declaration. *}
|
|
||||||
.
|
|
||||||
.struct reloc_howto_struct
|
.struct reloc_howto_struct
|
||||||
.{
|
.{
|
||||||
. {* The type field has mainly a documentary use - the back end can
|
. {* The type field has mainly a documentary use - the back end can
|
||||||
. do what it wants with it, though normally the back end's
|
. do what it wants with it, though normally the back end's idea of
|
||||||
. external idea of what a reloc number is stored
|
. an external reloc number is stored in this field. *}
|
||||||
. 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. *}
|
|
||||||
. unsigned int type;
|
. 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 number of bits in the field to be relocated. This is used
|
||||||
|
. when doing overflow checking. *}
|
||||||
|
. unsigned int bitsize:7;
|
||||||
|
.
|
||||||
. {* The value the final relocation is shifted right by. This drops
|
. {* The value the final relocation is shifted right by. This drops
|
||||||
. unwanted data from the relocation. *}
|
. unwanted data from the relocation. *}
|
||||||
. unsigned int rightshift;
|
. unsigned int rightshift:6;
|
||||||
.
|
|
||||||
. {* 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 item to be relocated. This is used
|
|
||||||
. when doing overflow checking. *}
|
|
||||||
. unsigned int bitsize;
|
|
||||||
.
|
|
||||||
. {* The relocation is relative to the field being relocated. *}
|
|
||||||
. bfd_boolean pc_relative;
|
|
||||||
.
|
.
|
||||||
. {* The bit position of the reloc value in the destination.
|
. {* The bit position of the reloc value in the destination.
|
||||||
. The relocated value is left shifted by this amount. *}
|
. The relocated value is left shifted by this amount. *}
|
||||||
. unsigned int bitpos;
|
. unsigned int bitpos:6;
|
||||||
.
|
.
|
||||||
. {* What type of overflow error should be checked for when
|
. {* What type of overflow error should be checked for when
|
||||||
. relocating. *}
|
. 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
|
. {* The relocation value should be negated before applying. *}
|
||||||
. called rather than the normal function. This allows really
|
. unsigned int negate:1;
|
||||||
. 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. *}
|
. {* The relocation is relative to the item being relocated. *}
|
||||||
. char *name;
|
. unsigned int pc_relative:1;
|
||||||
.
|
.
|
||||||
. {* Some formats record a relocation addend in the section contents
|
. {* Some formats record a relocation addend in the section contents
|
||||||
. rather than with the relocation. For ELF formats this is the
|
. rather than with the relocation. For ELF formats this is the
|
||||||
@ -340,21 +329,7 @@ CODE_FRAGMENT
|
|||||||
. USE_REL targets set this field to TRUE. Why this is so is peculiar
|
. 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
|
. 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. *}
|
. links (e.g. GOT stuff) it doesn't matter what this is set to. *}
|
||||||
. bfd_boolean partial_inplace;
|
. unsigned int partial_inplace: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. *}
|
|
||||||
. 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
|
. {* When some formats create PC relative instructions, they leave
|
||||||
. the value of the pc of the place being relocated in the offset
|
. the value of the pc of the place being relocated in the offset
|
||||||
@ -362,7 +337,31 @@ CODE_FRAGMENT
|
|||||||
. be made just by adding in an ordinary offset (e.g., sun3 a.out).
|
. be made just by adding in an ordinary offset (e.g., sun3 a.out).
|
||||||
. Some formats leave the displacement part of an instruction
|
. Some formats leave the displacement part of an instruction
|
||||||
. empty (e.g., ELF); this flag signals the fact. *}
|
. empty (e.g., ELF); this flag signals the fact. *}
|
||||||
. bfd_boolean pcrel_offset;
|
. 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 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;
|
||||||
|
.
|
||||||
|
. {* 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;
|
||||||
.};
|
.};
|
||||||
.
|
.
|
||||||
*/
|
*/
|
||||||
@ -375,8 +374,10 @@ DESCRIPTION
|
|||||||
The HOWTO macro fills in a reloc_howto_type (a typedef for
|
The HOWTO macro fills in a reloc_howto_type (a typedef for
|
||||||
const struct reloc_howto_struct).
|
const struct reloc_howto_struct).
|
||||||
|
|
||||||
.#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
|
.#define HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \
|
||||||
. { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC }
|
. 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
|
DESCRIPTION
|
||||||
This is used to fill in an empty howto entry in an array.
|
This is used to fill in an empty howto entry in an array.
|
||||||
@ -405,14 +406,11 @@ bfd_get_reloc_size (reloc_howto_type *howto)
|
|||||||
switch (howto->size)
|
switch (howto->size)
|
||||||
{
|
{
|
||||||
case 0: return 1;
|
case 0: return 1;
|
||||||
case 1:
|
case 1: return 2;
|
||||||
case -1: return 2;
|
case 2: return 4;
|
||||||
case 2:
|
|
||||||
case -2: return 4;
|
|
||||||
case 3: return 0;
|
case 3: return 0;
|
||||||
case 4: return 8;
|
case 4: return 8;
|
||||||
case 5: return 3;
|
case 5: return 3;
|
||||||
case 8: return 16;
|
|
||||||
default: abort ();
|
default: abort ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,11 +557,9 @@ read_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto)
|
|||||||
return bfd_get_8 (abfd, data);
|
return bfd_get_8 (abfd, data);
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
case -1:
|
|
||||||
return bfd_get_16 (abfd, data);
|
return bfd_get_16 (abfd, data);
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
case -2:
|
|
||||||
return bfd_get_32 (abfd, data);
|
return bfd_get_32 (abfd, data);
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
@ -596,12 +592,10 @@ write_reloc (bfd *abfd, bfd_vma val, bfd_byte *data, reloc_howto_type *howto)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
case -1:
|
|
||||||
bfd_put_16 (abfd, val, data);
|
bfd_put_16 (abfd, val, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
case -2:
|
|
||||||
bfd_put_32 (abfd, val, data);
|
bfd_put_32 (abfd, val, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -632,7 +626,7 @@ apply_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto,
|
|||||||
{
|
{
|
||||||
bfd_vma val = read_reloc (abfd, data, howto);
|
bfd_vma val = read_reloc (abfd, data, howto);
|
||||||
|
|
||||||
if (howto->size < 0)
|
if (howto->negate)
|
||||||
relocation = -relocation;
|
relocation = -relocation;
|
||||||
|
|
||||||
val = ((val & ~howto->dst_mask)
|
val = ((val & ~howto->dst_mask)
|
||||||
@ -1391,9 +1385,7 @@ _bfd_relocate_contents (reloc_howto_type *howto,
|
|||||||
unsigned int rightshift = howto->rightshift;
|
unsigned int rightshift = howto->rightshift;
|
||||||
unsigned int bitpos = howto->bitpos;
|
unsigned int bitpos = howto->bitpos;
|
||||||
|
|
||||||
/* If the size is negative, negate RELOCATION. This isn't very
|
if (howto->negate)
|
||||||
general. */
|
|
||||||
if (howto->size < 0)
|
|
||||||
relocation = -relocation;
|
relocation = -relocation;
|
||||||
|
|
||||||
/* Get the value we are going to relocate. */
|
/* Get the value we are going to relocate. */
|
||||||
|
@ -4001,6 +4001,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ALPHA_R_LINKAGE:
|
case ALPHA_R_LINKAGE:
|
||||||
|
size = 16;
|
||||||
etir_output_check (abfd, section, curr_addr, 64);
|
etir_output_check (abfd, section, curr_addr, 64);
|
||||||
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
|
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
|
||||||
_bfd_vms_output_long
|
_bfd_vms_output_long
|
||||||
@ -5157,6 +5158,7 @@ alpha_vms_slurp_relocs (bfd *abfd)
|
|||||||
asection *sec;
|
asection *sec;
|
||||||
struct vms_section_data_struct *vms_sec;
|
struct vms_section_data_struct *vms_sec;
|
||||||
arelent *reloc;
|
arelent *reloc;
|
||||||
|
bfd_size_type size;
|
||||||
|
|
||||||
/* Get section to which the relocation applies. */
|
/* Get section to which the relocation applies. */
|
||||||
if (cur_psect < 0 || cur_psect > (int)PRIV (section_count))
|
if (cur_psect < 0 || cur_psect > (int)PRIV (section_count))
|
||||||
@ -5237,7 +5239,11 @@ alpha_vms_slurp_relocs (bfd *abfd)
|
|||||||
reloc->address = cur_address;
|
reloc->address = cur_address;
|
||||||
reloc->addend = cur_addend;
|
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;
|
cur_addend = 0;
|
||||||
@ -5496,8 +5502,8 @@ static reloc_howto_type alpha_howto_table[] =
|
|||||||
/* Hack. Linkage is done by linker. */
|
/* Hack. Linkage is done by linker. */
|
||||||
HOWTO (ALPHA_R_LINKAGE, /* Type. */
|
HOWTO (ALPHA_R_LINKAGE, /* Type. */
|
||||||
0, /* Rightshift. */
|
0, /* Rightshift. */
|
||||||
8, /* Size (0 = byte, 1 = short, 2 = long). */
|
0, /* Size (0 = byte, 1 = short, 2 = long). */
|
||||||
256, /* Bitsize. */
|
0, /* Bitsize. */
|
||||||
FALSE, /* PC relative. */
|
FALSE, /* PC relative. */
|
||||||
0, /* Bitpos. */
|
0, /* Bitpos. */
|
||||||
complain_overflow_dont,/* Complain_on_overflow. */
|
complain_overflow_dont,/* Complain_on_overflow. */
|
||||||
|
Loading…
Reference in New Issue
Block a user