aboutsummaryrefslogtreecommitdiff
path: root/contrib/binutils/bfd/reloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/binutils/bfd/reloc.c')
-rw-r--r--contrib/binutils/bfd/reloc.c361
1 files changed, 212 insertions, 149 deletions
diff --git a/contrib/binutils/bfd/reloc.c b/contrib/binutils/bfd/reloc.c
index c2a94edc0688..dda7624c585f 100644
--- a/contrib/binutils/bfd/reloc.c
+++ b/contrib/binutils/bfd/reloc.c
@@ -1,5 +1,5 @@
/* BFD support for handling relocation entries.
- Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
Written by Cygnus Support.
@@ -411,14 +411,14 @@ FUNCTION
bfd_get_reloc_size
SYNOPSIS
- int bfd_get_reloc_size (reloc_howto_type *);
+ 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.
*/
-int
+unsigned int
bfd_get_reloc_size (howto)
reloc_howto_type *howto;
{
@@ -451,6 +451,110 @@ DESCRIPTION
*/
+/*
+FUNCTION
+ bfd_check_overflow
+
+SYNOPSIS
+ bfd_reloc_status_type
+ bfd_check_overflow
+ (enum complain_overflow how,
+ unsigned int bitsize,
+ unsigned int rightshift,
+ bfd_vma relocation);
+
+DESCRIPTION
+ Perform overflow checking on @var{relocation} which has @var{bitsize}
+ significant bits and will be shifted right by @var{rightshift} bits.
+ The result is either of @code{bfd_reloc_ok} or
+ @code{bfd_reloc_overflow}.
+
+*/
+
+bfd_reloc_status_type
+bfd_check_overflow (how, bitsize, rightshift, relocation)
+ enum complain_overflow how;
+ unsigned int bitsize, rightshift;
+ bfd_vma relocation;
+{
+ bfd_vma check;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+
+ /* Get the value that will be used for the relocation, but
+ starting at bit position zero. */
+ check = relocation >> rightshift;
+
+ switch (how)
+ {
+ case complain_overflow_dont:
+ break;
+
+ case complain_overflow_signed:
+ {
+ /* Assumes two's complement. */
+ bfd_signed_vma reloc_signed_max = (1 << (bitsize - 1)) - 1;
+ bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
+
+ /* The above right shift is incorrect for a signed value.
+ Fix it up by forcing on the upper bits. */
+ if (rightshift > 0
+ && (bfd_signed_vma) relocation < 0)
+ check |= ((bfd_vma) - 1
+ & ~((bfd_vma) - 1
+ >> rightshift));
+ if ((bfd_signed_vma) check > reloc_signed_max
+ || (bfd_signed_vma) check < reloc_signed_min)
+ flag = bfd_reloc_overflow;
+ }
+ break;
+
+ case complain_overflow_unsigned:
+ {
+ /* Assumes two's complement. This expression avoids
+ overflow if `bitsize' is the number of bits in
+ bfd_vma. */
+ bfd_vma reloc_unsigned_max = (((1 << (bitsize - 1)) - 1) << 1) | 1;
+
+ if ((bfd_vma) check > reloc_unsigned_max)
+ flag = bfd_reloc_overflow;
+ }
+ break;
+
+ case complain_overflow_bitfield:
+ {
+ /* Assumes two's complement. This expression avoids
+ overflow if `bitsize' is the number of bits in
+ bfd_vma. */
+ bfd_vma reloc_bits = (((1 << (bitsize - 1)) - 1) << 1) | 1;
+
+ if (((bfd_vma) check & ~reloc_bits) != 0
+ && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+ {
+ /* The above right shift is incorrect for a signed
+ value. See if turning on the upper bits fixes the
+ overflow. */
+ if (rightshift > 0
+ && (bfd_signed_vma) relocation < 0)
+ {
+ check |= ((bfd_vma) - 1
+ & ~((bfd_vma) - 1
+ >> rightshift));
+ if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+ flag = bfd_reloc_overflow;
+ }
+ else
+ flag = bfd_reloc_overflow;
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return flag;
+}
+
/*
FUNCTION
@@ -721,75 +825,8 @@ space consuming. For each target:
adding in the value contained in the object file. */
if (howto->complain_on_overflow != complain_overflow_dont
&& flag == bfd_reloc_ok)
- {
- bfd_vma check;
-
- /* Get the value that will be used for the relocation, but
- starting at bit position zero. */
- check = relocation >> howto->rightshift;
- switch (howto->complain_on_overflow)
- {
- case complain_overflow_signed:
- {
- /* Assumes two's complement. */
- bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
- bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
-
- /* The above right shift is incorrect for a signed value.
- Fix it up by forcing on the upper bits. */
- if (howto->rightshift > 0
- && (bfd_signed_vma) relocation < 0)
- check |= ((bfd_vma) - 1
- & ~((bfd_vma) - 1
- >> howto->rightshift));
- if ((bfd_signed_vma) check > reloc_signed_max
- || (bfd_signed_vma) check < reloc_signed_min)
- flag = bfd_reloc_overflow;
- }
- break;
- case complain_overflow_unsigned:
- {
- /* Assumes two's complement. This expression avoids
- overflow if howto->bitsize is the number of bits in
- bfd_vma. */
- bfd_vma reloc_unsigned_max =
- (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
-
- if ((bfd_vma) check > reloc_unsigned_max)
- flag = bfd_reloc_overflow;
- }
- break;
- case complain_overflow_bitfield:
- {
- /* Assumes two's complement. This expression avoids
- overflow if howto->bitsize is the number of bits in
- bfd_vma. */
- bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
-
- if (((bfd_vma) check & ~reloc_bits) != 0
- && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
- {
- /* The above right shift is incorrect for a signed
- value. See if turning on the upper bits fixes the
- overflow. */
- if (howto->rightshift > 0
- && (bfd_signed_vma) relocation < 0)
- {
- check |= ((bfd_vma) - 1
- & ~((bfd_vma) - 1
- >> howto->rightshift));
- if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
- flag = bfd_reloc_overflow;
- }
- else
- flag = bfd_reloc_overflow;
- }
- }
- break;
- default:
- abort ();
- }
- }
+ flag = bfd_check_overflow (howto->complain_on_overflow, howto->bitsize,
+ howto->rightshift, relocation);
/*
Either we are relocating all the way, or we don't want to apply
@@ -983,6 +1020,7 @@ bfd_install_relocation (abfd, reloc_entry, data_start, data_start_offset,
if (howto->special_function)
{
bfd_reloc_status_type cont;
+
/* XXX - The special_function calls haven't been fixed up to deal
with creating new relocations and section contents. */
cont = howto->special_function (abfd, reloc_entry, symbol,
@@ -1007,7 +1045,6 @@ bfd_install_relocation (abfd, reloc_entry, data_start, data_start_offset,
else
relocation = symbol->value;
-
reloc_target_output_section = symbol->section->output_section;
/* Convert input-section-relative symbol value to absolute. */
@@ -1172,79 +1209,11 @@ space consuming. For each target:
need to compute the value in a size larger than bitsize, but we
can't reasonably do that for a reloc the same size as a host
machine word.
-
FIXME: We should also do overflow checking on the result after
adding in the value contained in the object file. */
if (howto->complain_on_overflow != complain_overflow_dont)
- {
- bfd_vma check;
-
- /* Get the value that will be used for the relocation, but
- starting at bit position zero. */
- check = relocation >> howto->rightshift;
- switch (howto->complain_on_overflow)
- {
- case complain_overflow_signed:
- {
- /* Assumes two's complement. */
- bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
- bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
-
- /* The above right shift is incorrect for a signed value.
- Fix it up by forcing on the upper bits. */
- if (howto->rightshift > 0
- && (bfd_signed_vma) relocation < 0)
- check |= ((bfd_vma) - 1
- & ~((bfd_vma) - 1
- >> howto->rightshift));
- if ((bfd_signed_vma) check > reloc_signed_max
- || (bfd_signed_vma) check < reloc_signed_min)
- flag = bfd_reloc_overflow;
- }
- break;
- case complain_overflow_unsigned:
- {
- /* Assumes two's complement. This expression avoids
- overflow if howto->bitsize is the number of bits in
- bfd_vma. */
- bfd_vma reloc_unsigned_max =
- (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
-
- if ((bfd_vma) check > reloc_unsigned_max)
- flag = bfd_reloc_overflow;
- }
- break;
- case complain_overflow_bitfield:
- {
- /* Assumes two's complement. This expression avoids
- overflow if howto->bitsize is the number of bits in
- bfd_vma. */
- bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
-
- if (((bfd_vma) check & ~reloc_bits) != 0
- && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
- {
- /* The above right shift is incorrect for a signed
- value. See if turning on the upper bits fixes the
- overflow. */
- if (howto->rightshift > 0
- && (bfd_signed_vma) relocation < 0)
- {
- check |= ((bfd_vma) - 1
- & ~((bfd_vma) - 1
- >> howto->rightshift));
- if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
- flag = bfd_reloc_overflow;
- }
- else
- flag = bfd_reloc_overflow;
- }
- }
- break;
- default:
- abort ();
- }
- }
+ flag = bfd_check_overflow (howto->complain_on_overflow, howto->bitsize,
+ howto->rightshift, relocation);
/*
Either we are relocating all the way, or we don't want to apply
@@ -1376,8 +1345,9 @@ space consuming. For each target:
bfd_perform_relocation is so hacked up it is easier to write a new
function than to try to deal with it.
- This routine does a final relocation. It should not be used when
- generating relocateable output.
+ This routine does a final relocation. Whether it is useful for a
+ relocateable link depends upon how the object format defines
+ relocations.
FIXME: This routine ignores any special_function in the HOWTO,
since the existing special_function values have been written for
@@ -1870,15 +1840,30 @@ ENUMX
ENUMX
BFD_RELOC_SPARC_WDISP19
ENUMX
- BFD_RELOC_SPARC_GLOB_JMP
-ENUMX
BFD_RELOC_SPARC_7
ENUMX
BFD_RELOC_SPARC_6
ENUMX
BFD_RELOC_SPARC_5
+ENUMEQX
+ BFD_RELOC_SPARC_DISP64
+ BFD_RELOC_64_PCREL
+ENUMX
+ BFD_RELOC_SPARC_PLT64
+ENUMX
+ BFD_RELOC_SPARC_HIX22
+ENUMX
+ BFD_RELOC_SPARC_LOX10
+ENUMX
+ BFD_RELOC_SPARC_H44
+ENUMX
+ BFD_RELOC_SPARC_M44
+ENUMX
+ BFD_RELOC_SPARC_L44
+ENUMX
+ BFD_RELOC_SPARC_REGISTER
ENUMDOC
- Some relocations we're using for SPARC V9 -- subject to change.
+ SPARC64 relocations
ENUM
BFD_RELOC_ALPHA_GPDISP_HI16
@@ -2022,9 +2007,12 @@ ENUMX
BFD_RELOC_MIPS_CALL_HI16
ENUMX
BFD_RELOC_MIPS_CALL_LO16
+COMMENT
ENUMDOC
MIPS ELF relocations.
+COMMENT
+
ENUM
BFD_RELOC_386_GOT32
ENUMX
@@ -2221,7 +2209,29 @@ ENUMX
ENUMDOC
Hitachi SH relocs. Not all of these appear in object files.
-COMMENT
+ENUM
+ BFD_RELOC_THUMB_PCREL_BRANCH9
+ENUMX
+ BFD_RELOC_THUMB_PCREL_BRANCH12
+ENUMX
+ BFD_RELOC_THUMB_PCREL_BRANCH23
+ENUMDOC
+ Thumb 23-, 12- and 9-bit pc-relative branches. The lowest bit must
+ be zero and is not stored in the instruction.
+
+ENUM
+ BFD_RELOC_ARC_B22_PCREL
+ENUMDOC
+ Argonaut RISC Core (ARC) relocs.
+ ARC 22 bit pc-relative branch. The lowest two bits must be zero and are
+ not stored in the instruction. The high 20 bits are installed in bits 26
+ through 7 of the instruction.
+ENUM
+ BFD_RELOC_ARC_B26
+ENUMDOC
+ ARC 26 bit absolute branch. The lowest two bits must be zero and are not
+ stored in the instruction. The high 24 bits are installed in bits 23
+ through 0.
COMMENT
ENUM
@@ -2289,6 +2299,51 @@ ENUMDOC
This is a 16-bit reloc containing the small data area offset for use in
add3, load, and store instructions.
+ENUM
+ BFD_RELOC_V850_9_PCREL
+ENUMDOC
+ This is a 9-bit reloc
+ENUM
+ BFD_RELOC_V850_22_PCREL
+ENUMDOC
+ This is a 22-bit reloc
+
+ENUM
+ BFD_RELOC_V850_SDA_16_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the short data area pointer.
+ENUM
+ BFD_RELOC_V850_SDA_15_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset (of which only 15 bits are used) from the
+ short data area pointer.
+ENUM
+ BFD_RELOC_V850_ZDA_16_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the zero data area pointer.
+ENUM
+ BFD_RELOC_V850_ZDA_15_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset (of which only 15 bits are used) from the
+ zero data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_6_8_OFFSET
+ENUMDOC
+ This is an 8 bit offset (of which only 6 bits are used) from the
+ tiny data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_7_8_OFFSET
+ENUMDOC
+ This is an 8bit offset (of which only 7 bits are used) from the tiny
+ data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_7_7_OFFSET
+ENUMDOC
+ This is a 7 bit offset from the tiny data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_16_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the tiny data area pointer.
COMMENT
ENUM
@@ -2301,6 +2356,14 @@ ENUM
ENUMDOC
This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the
instruction.
+
+ENUM
+ BFD_RELOC_TIC30_LDP
+ENUMDOC
+ This is a 8bit DP reloc for the tms320c30, where the most
+ significant 8 bits of a 24 bit word are placed into the least
+ significant 8 bits of the opcode.
+
ENDSENUM
BFD_RELOC_UNUSED
CODE_FRAGMENT