/* BFD support for handling relocation entries.
- Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*
SECTION
@end menu
*/
+
+/* DO compile in the reloc_code name table from libbfd.h. */
+#define _BFD_MAKE_TABLE_bfd_reloc_code_real
+
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
. bfd_vma addend;
.
. {* Pointer to how to perform the required relocation *}
-. const struct reloc_howto_struct *howto;
+. reloc_howto_type *howto;
.
.} arelent;
type which modifies the bottom two bytes of a four byte word
would not touch the first byte pointed to in a big endian
world.
-
+
o <<addend>>
The <<addend>> is a value provided by the back end to be added (!)
CODE_FRAGMENT
.struct symbol_cache_entry; {* Forward declaration *}
.
-.typedef unsigned char bfd_byte;
-.
.struct reloc_howto_struct
.{
-. {* The type field has mainly a documetary 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
. external idea of what a reloc number is stored
. in this field. For example, a PC relative word relocation
. bfd *output_bfd,
. char **error_message));
.
-.
-. {* If this field is non null, then the supplied function is
-. called rather than the normal function. This is similar
-. to special_function (previous), but takes different arguments,
-. and is used for the new linking code. *}
-. bfd_reloc_status_type (*special_function1)
-. PARAMS((const reloc_howto_type *howto,
-. bfd *input_bfd,
-. bfd_vma relocation,
-. bfd_byte *location));
-.
. {* The textual name of the relocation type. *}
. char *name;
.
. boolean pcrel_offset;
.
.};
-.typedef struct reloc_howto_struct reloc_howto_type;
*/
.#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
-. {(unsigned)C,R,S,B, P, BI, O,SF, 0,NAME,INPLACE,MASKSRC,MASKDST,PC}
-.#define HOWTO2(C, R,S,B, P, BI, O, SF, SF1,NAME, INPLACE, MASKSRC, MASKDST, PC) \
-. {(unsigned)C,R,S,B, P, BI, O,SF, SF1,NAME,INPLACE,MASKSRC,MASKDST,PC}
+. {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
DESCRIPTION
And will be replaced with the totally magic way. But for the
bfd_get_reloc_size
SYNOPSIS
- int bfd_get_reloc_size (const reloc_howto_type *);
+ int bfd_get_reloc_size (reloc_howto_type *);
DESCRIPTION
For a reloc_howto_type that operates on a fixed number of bytes,
int
bfd_get_reloc_size (howto)
- const reloc_howto_type *howto;
+ reloc_howto_type *howto;
{
switch (howto->size)
{
case 2: return 4;
case 3: return 0;
case 4: return 8;
+ case 8: return 16;
case -2: return 4;
default: abort ();
}
*/
+/*
+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
bfd_reloc_status_type flag = bfd_reloc_ok;
bfd_size_type addr = reloc_entry->address;
bfd_vma output_base = 0;
- const reloc_howto_type *howto = reloc_entry->howto;
+ reloc_howto_type *howto = reloc_entry->howto;
asection *reloc_target_output_section;
asymbol *symbol;
/* WTF?? */
if (abfd->xvec->flavour == bfd_target_coff_flavour
&& strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0
+ && strcmp (abfd->xvec->name, "xcoff-powermac") != 0
&& strcmp (abfd->xvec->name, "coff-Intel-little") != 0
&& strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
{
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. */
- if (howto->rightshift > howto->bitpos)
- check = relocation >> (howto->rightshift - howto->bitpos);
- else
- check = relocation << (howto->bitpos - 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 > howto->bitpos
- && (bfd_signed_vma) relocation < 0)
- check |= ((bfd_vma) - 1
- & ~((bfd_vma) - 1
- >> (howto->rightshift - howto->bitpos)));
- 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 > howto->bitpos
- && (bfd_signed_vma) relocation < 0)
- {
- check |= ((bfd_vma) - 1
- & ~((bfd_vma) - 1
- >> (howto->rightshift - howto->bitpos)));
- if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
- flag = bfd_reloc_overflow;
- }
- else
- flag = bfd_reloc_overflow;
- }
- }
- break;
- default:
- abort ();
- }
- }
+ if (howto->complain_on_overflow != complain_overflow_dont
+ && flag == bfd_reloc_ok)
+ 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
break;
case 1:
- if (relocation)
- {
- short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
- DOIT (x);
- bfd_put_16 (abfd, x, (unsigned char *) data + addr);
- }
+ {
+ short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+ DOIT (x);
+ bfd_put_16 (abfd, x, (unsigned char *) data + addr);
+ }
break;
case 2:
- if (relocation)
- {
- long x = bfd_get_32 (abfd, (bfd_byte *) data + addr);
- DOIT (x);
- bfd_put_32 (abfd, x, (bfd_byte *) data + addr);
- }
+ {
+ long x = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+ DOIT (x);
+ bfd_put_32 (abfd, x, (bfd_byte *) data + addr);
+ }
break;
case -2:
{
}
break;
+ case -1:
+ {
+ long x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+ relocation = -relocation;
+ DOIT (x);
+ bfd_put_16 (abfd, x, (bfd_byte *) data + addr);
+ }
+ break;
+
case 3:
/* Do nothing */
break;
case 4:
#ifdef BFD64
- if (relocation)
- {
- bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + addr);
- DOIT (x);
- bfd_put_64 (abfd, x, (bfd_byte *) data + addr);
- }
+ {
+ bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + addr);
+ DOIT (x);
+ bfd_put_64 (abfd, x, (bfd_byte *) data + addr);
+ }
#else
abort ();
#endif
return flag;
}
+/*
+FUNCTION
+ bfd_install_relocation
+
+SYNOPSIS
+ bfd_reloc_status_type
+ bfd_install_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ PTR data, bfd_vma data_start,
+ asection *input_section,
+ char **error_message);
+
+DESCRIPTION
+ This looks remarkably like <<bfd_perform_relocation>>, except it
+ does not expect that the section contents have been filled in.
+ I.e., it's suitable for use when creating, rather than applying
+ a relocation.
+
+ For now, this function should be considered reserved for the
+ assembler.
+
+*/
+
+
+bfd_reloc_status_type
+bfd_install_relocation (abfd, reloc_entry, data_start, data_start_offset,
+ input_section, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ PTR data_start;
+ bfd_vma data_start_offset;
+ asection *input_section;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ asection *reloc_target_output_section;
+ asymbol *symbol;
+ bfd_byte *data;
+
+ symbol = *(reloc_entry->sym_ptr_ptr);
+ if (bfd_is_abs_section (symbol->section))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* If there is a function supplied to handle this relocation type,
+ call it. It'll return `bfd_reloc_continue' if further processing
+ can be done. */
+ 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,
+ /* XXX - Non-portable! */
+ ((bfd_byte *) data_start
+ - data_start_offset),
+ input_section, abfd, error_message);
+ if (cont != bfd_reloc_continue)
+ return cont;
+ }
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targetted at and the
+ initial relocation command value. */
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ reloc_target_output_section = symbol->section->output_section;
+
+ /* Convert input-section-relative symbol value to absolute. */
+ if (howto->partial_inplace == false)
+ output_base = 0;
+ else
+ output_base = reloc_target_output_section->vma;
+
+ relocation += output_base + symbol->section->output_offset;
+
+ /* Add in supplied addend. */
+ relocation += reloc_entry->addend;
+
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+
+ if (howto->pc_relative == true)
+ {
+ /* This is a PC relative relocation. We want to set RELOCATION
+ to the distance between the address of the symbol and the
+ location. RELOCATION is already the address of the symbol.
+
+ We start by subtracting the address of the section containing
+ the location.
+
+ If pcrel_offset is set, we must further subtract the position
+ of the location within the section. Some targets arrange for
+ the addend to be the negative of the position of the location
+ within the section; for example, i386-aout does this. For
+ i386-aout, pcrel_offset is false. Some other targets do not
+ include the position of the location; for example, m88kbcs,
+ or ELF. For those targets, pcrel_offset is true.
+
+ If we are producing relocateable output, then we must ensure
+ that this reloc will be correctly computed when the final
+ relocation is done. If pcrel_offset is false we want to wind
+ up with the negative of the location within the section,
+ which means we must adjust the existing addend by the change
+ in the location within the section. If pcrel_offset is true
+ we do not want to adjust the existing addend at all.
+
+ FIXME: This seems logical to me, but for the case of
+ producing relocateable output it is not what the code
+ actually does. I don't want to change it, because it seems
+ far too likely that something will break. */
+
+ relocation -=
+ input_section->output_section->vma + input_section->output_offset;
+
+ if (howto->pcrel_offset == true && howto->partial_inplace == true)
+ relocation -= reloc_entry->address;
+ }
+
+ if (howto->partial_inplace == false)
+ {
+ /* This is a partial relocation, and we want to apply the relocation
+ to the reloc entry rather than the raw data. Modify the reloc
+ inplace to reflect what we now know. */
+ reloc_entry->addend = relocation;
+ reloc_entry->address += input_section->output_offset;
+ return flag;
+ }
+ else
+ {
+ /* This is a partial relocation, but inplace, so modify the
+ reloc record a bit.
+
+ If we've relocated with a symbol with a section, change
+ into a ref to the section belonging to the symbol. */
+
+ reloc_entry->address += input_section->output_offset;
+
+ /* WTF?? */
+ if (abfd->xvec->flavour == bfd_target_coff_flavour
+ && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0
+ && strcmp (abfd->xvec->name, "xcoff-powermac") != 0
+ && strcmp (abfd->xvec->name, "coff-Intel-little") != 0
+ && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
+ {
+#if 1
+/* For m68k-coff, the addend was being subtracted twice during
+ relocation with -r. Removing the line below this comment
+ fixes that problem; see PR 2953.
+
+However, Ian wrote the following, regarding removing the line below,
+which explains why it is still enabled: --djm
+
+If you put a patch like that into BFD you need to check all the COFF
+linkers. I am fairly certain that patch will break coff-i386 (e.g.,
+SCO); see coff_i386_reloc in coff-i386.c where I worked around the
+problem in a different way. There may very well be a reason that the
+code works as it does.
+
+Hmmm. The first obvious point is that bfd_install_relocation should
+not have any tests that depend upon the flavour. It's seem like
+entirely the wrong place for such a thing. The second obvious point
+is that the current code ignores the reloc addend when producing
+relocateable output for COFF. That's peculiar. In fact, I really
+have no idea what the point of the line you want to remove is.
+
+A typical COFF reloc subtracts the old value of the symbol and adds in
+the new value to the location in the object file (if it's a pc
+relative reloc it adds the difference between the symbol value and the
+location). When relocating we need to preserve that property.
+
+BFD handles this by setting the addend to the negative of the old
+value of the symbol. Unfortunately it handles common symbols in a
+non-standard way (it doesn't subtract the old value) but that's a
+different story (we can't change it without losing backward
+compatibility with old object files) (coff-i386 does subtract the old
+value, to be compatible with existing coff-i386 targets, like SCO).
+
+So everything works fine when not producing relocateable output. When
+we are producing relocateable output, logically we should do exactly
+what we do when not producing relocateable output. Therefore, your
+patch is correct. In fact, it should probably always just set
+reloc_entry->addend to 0 for all cases, since it is, in fact, going to
+add the value into the object file. This won't hurt the COFF code,
+which doesn't use the addend; I'm not sure what it will do to other
+formats (the thing to check for would be whether any formats both use
+the addend and set partial_inplace).
+
+When I wanted to make coff-i386 produce relocateable output, I ran
+into the problem that you are running into: I wanted to remove that
+line. Rather than risk it, I made the coff-i386 relocs use a special
+function; it's coff_i386_reloc in coff-i386.c. The function
+specifically adds the addend field into the object file, knowing that
+bfd_install_relocation is not going to. If you remove that line, then
+coff-i386.c will wind up adding the addend field in twice. It's
+trivial to fix; it just needs to be done.
+
+The problem with removing the line is just that it may break some
+working code. With BFD it's hard to be sure of anything. The right
+way to deal with this is simply to build and test at least all the
+supported COFF targets. It should be straightforward if time and disk
+space consuming. For each target:
+ 1) build the linker
+ 2) generate some executable, and link it using -r (I would
+ probably use paranoia.o and link against newlib/libc.a, which
+ for all the supported targets would be available in
+ /usr/cygnus/progressive/H-host/target/lib/libc.a).
+ 3) make the change to reloc.c
+ 4) rebuild the linker
+ 5) repeat step 2
+ 6) if the resulting object files are the same, you have at least
+ made it no worse
+ 7) if they are different you have to figure out which version is
+ right
+*/
+ relocation -= reloc_entry->addend;
+#endif
+ reloc_entry->addend = 0;
+ }
+ else
+ {
+ reloc_entry->addend = relocation;
+ }
+ }
+
+ /* FIXME: This overflow checking is incomplete, because the value
+ might have overflowed before we get here. For a correct check we
+ 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)
+ 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
+ the relocation to the reloc entry (probably because there isn't
+ any room in the output format to describe addends to relocs)
+ */
+
+ /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
+ (OSF version 1.3, compiler version 3.11). It miscompiles the
+ following program:
+
+ struct str
+ {
+ unsigned int i0;
+ } s = { 0 };
+
+ int
+ main ()
+ {
+ unsigned long x;
+
+ x = 0x100000000;
+ x <<= (unsigned long) s.i0;
+ if (x == 0)
+ printf ("failed\n");
+ else
+ printf ("succeeded (%lx)\n", x);
+ }
+ */
+
+ relocation >>= (bfd_vma) howto->rightshift;
+
+ /* Shift everything up to where it's going to be used */
+
+ relocation <<= (bfd_vma) howto->bitpos;
+
+ /* Wait for the day when all have the mask in them */
+
+ /* What we do:
+ i instruction to be left alone
+ o offset within instruction
+ r relocation offset to apply
+ S src mask
+ D dst mask
+ N ~dst mask
+ A part 1
+ B part 2
+ R result
+
+ Do this:
+ i i i i i o o o o o from bfd_get<size>
+ and S S S S S to get the size offset we want
+ + r r r r r r r r r r to get the final value to place
+ and D D D D D to chop to right size
+ -----------------------
+ A A A A A
+ And this:
+ ... i i i i i o o o o o from bfd_get<size>
+ and N N N N N get instruction
+ -----------------------
+ ... B B B B B
+
+ And then:
+ B B B B B
+ or A A A A A
+ -----------------------
+ R R R R R R R R R R put into bfd_put<size>
+ */
+
+#define DOIT(x) \
+ x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
+
+ data = (bfd_byte *) data_start + (addr - data_start_offset);
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, (char *) data);
+ DOIT (x);
+ bfd_put_8 (abfd, x, (unsigned char *) data);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, (bfd_byte *) data);
+ DOIT (x);
+ bfd_put_16 (abfd, x, (unsigned char *) data);
+ }
+ break;
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, (bfd_byte *) data);
+ DOIT (x);
+ bfd_put_32 (abfd, x, (bfd_byte *) data);
+ }
+ break;
+ case -2:
+ {
+ long x = bfd_get_32 (abfd, (bfd_byte *) data);
+ relocation = -relocation;
+ DOIT (x);
+ bfd_put_32 (abfd, x, (bfd_byte *) data);
+ }
+ break;
+
+ case 3:
+ /* Do nothing */
+ break;
+
+ case 4:
+ {
+ bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data);
+ DOIT (x);
+ bfd_put_64 (abfd, x, (bfd_byte *) data);
+ }
+ break;
+ default:
+ return bfd_reloc_other;
+ }
+
+ return flag;
+}
+
/* This relocation routine is used by some of the backend linkers.
They do not construct asymbol or arelent structures, so there is no
reason for them to use bfd_perform_relocation. Also,
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
bfd_reloc_status_type
_bfd_final_link_relocate (howto, input_bfd, input_section, contents, address,
value, addend)
- const reloc_howto_type *howto;
+ reloc_howto_type *howto;
bfd *input_bfd;
asection *input_section;
bfd_byte *contents;
bfd_vma relocation;
/* Sanity check the address. */
- if (address > input_section->_cooked_size)
+ if (address > input_section->_raw_size)
return bfd_reloc_outofrange;
/* This function assumes that we are dealing with a basic relocation
relocation -= address;
}
- if(howto->special_function1) {
- bfd_reloc_status_type cont;
- cont = (*howto->special_function1)(howto, input_bfd, relocation,
- contents + address);
- if (cont != bfd_reloc_continue)
- return cont;
- }
return _bfd_relocate_contents (howto, input_bfd, relocation,
contents + address);
}
bfd_reloc_status_type
_bfd_relocate_contents (howto, input_bfd, relocation, location)
- const reloc_howto_type *howto;
+ reloc_howto_type *howto;
bfd *input_bfd;
bfd_vma relocation;
bfd_byte *location;
enumerator value; you can't get a howto pointer from a random set
of attributes.
+SENUM
+ bfd_reloc_code_real
+
+ENUM
+ BFD_RELOC_64
+ENUMX
+ BFD_RELOC_32
+ENUMX
+ BFD_RELOC_26
+ENUMX
+ BFD_RELOC_24
+ENUMX
+ BFD_RELOC_16
+ENUMX
+ BFD_RELOC_14
+ENUMX
+ BFD_RELOC_8
+ENUMDOC
+ Basic absolute relocations of N bits.
+
+ENUM
+ BFD_RELOC_64_PCREL
+ENUMX
+ BFD_RELOC_32_PCREL
+ENUMX
+ BFD_RELOC_24_PCREL
+ENUMX
+ BFD_RELOC_16_PCREL
+ENUMX
+ BFD_RELOC_12_PCREL
+ENUMX
+ BFD_RELOC_8_PCREL
+ENUMDOC
+ PC-relative relocations. Sometimes these are relative to the address
+of the relocation itself; sometimes they are relative to the start of
+the section containing the relocation. It depends on the specific target.
+
+The 24-bit relocation is used in some Intel 960 configurations.
+
+ENUM
+ BFD_RELOC_32_GOT_PCREL
+ENUMX
+ BFD_RELOC_16_GOT_PCREL
+ENUMX
+ BFD_RELOC_8_GOT_PCREL
+ENUMX
+ BFD_RELOC_32_GOTOFF
+ENUMX
+ BFD_RELOC_16_GOTOFF
+ENUMX
+ BFD_RELOC_LO16_GOTOFF
+ENUMX
+ BFD_RELOC_HI16_GOTOFF
+ENUMX
+ BFD_RELOC_HI16_S_GOTOFF
+ENUMX
+ BFD_RELOC_8_GOTOFF
+ENUMX
+ BFD_RELOC_32_PLT_PCREL
+ENUMX
+ BFD_RELOC_24_PLT_PCREL
+ENUMX
+ BFD_RELOC_16_PLT_PCREL
+ENUMX
+ BFD_RELOC_8_PLT_PCREL
+ENUMX
+ BFD_RELOC_32_PLTOFF
+ENUMX
+ BFD_RELOC_16_PLTOFF
+ENUMX
+ BFD_RELOC_LO16_PLTOFF
+ENUMX
+ BFD_RELOC_HI16_PLTOFF
+ENUMX
+ BFD_RELOC_HI16_S_PLTOFF
+ENUMX
+ BFD_RELOC_8_PLTOFF
+ENUMDOC
+ For ELF.
+
+ENUM
+ BFD_RELOC_68K_GLOB_DAT
+ENUMX
+ BFD_RELOC_68K_JMP_SLOT
+ENUMX
+ BFD_RELOC_68K_RELATIVE
+ENUMDOC
+ Relocations used by 68K ELF.
+
+ENUM
+ BFD_RELOC_32_BASEREL
+ENUMX
+ BFD_RELOC_16_BASEREL
+ENUMX
+ BFD_RELOC_LO16_BASEREL
+ENUMX
+ BFD_RELOC_HI16_BASEREL
+ENUMX
+ BFD_RELOC_HI16_S_BASEREL
+ENUMX
+ BFD_RELOC_8_BASEREL
+ENUMX
+ BFD_RELOC_RVA
+ENUMDOC
+ Linkage-table relative.
+
+ENUM
+ BFD_RELOC_8_FFnn
+ENUMDOC
+ Absolute 8-bit relocation, but used to form an address like 0xFFnn.
+
+ENUM
+ BFD_RELOC_32_PCREL_S2
+ENUMX
+ BFD_RELOC_16_PCREL_S2
+ENUMX
+ BFD_RELOC_23_PCREL_S2
+ENUMDOC
+ These PC-relative relocations are stored as word displacements --
+i.e., byte displacements shifted right two bits. The 30-bit word
+displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the
+SPARC. (SPARC tools generally refer to this as <<WDISP30>>.) The
+signed 16-bit displacement is used on the MIPS, and the 23-bit
+displacement is used on the Alpha.
+
+ENUM
+ BFD_RELOC_HI22
+ENUMX
+ BFD_RELOC_LO10
+ENUMDOC
+ High 22 bits and low 10 bits of 32-bit value, placed into lower bits of
+the target word. These are used on the SPARC.
+
+ENUM
+ BFD_RELOC_GPREL16
+ENUMX
+ BFD_RELOC_GPREL32
+ENUMDOC
+ For systems that allocate a Global Pointer register, these are
+displacements off that register. These relocation types are
+handled specially, because the value the register will have is
+decided relatively late.
+
+
+ENUM
+ BFD_RELOC_I960_CALLJ
+ENUMDOC
+ Reloc types used for i960/b.out.
+
+ENUM
+ BFD_RELOC_NONE
+ENUMX
+ BFD_RELOC_SPARC_WDISP22
+ENUMX
+ BFD_RELOC_SPARC22
+ENUMX
+ BFD_RELOC_SPARC13
+ENUMX
+ BFD_RELOC_SPARC_GOT10
+ENUMX
+ BFD_RELOC_SPARC_GOT13
+ENUMX
+ BFD_RELOC_SPARC_GOT22
+ENUMX
+ BFD_RELOC_SPARC_PC10
+ENUMX
+ BFD_RELOC_SPARC_PC22
+ENUMX
+ BFD_RELOC_SPARC_WPLT30
+ENUMX
+ BFD_RELOC_SPARC_COPY
+ENUMX
+ BFD_RELOC_SPARC_GLOB_DAT
+ENUMX
+ BFD_RELOC_SPARC_JMP_SLOT
+ENUMX
+ BFD_RELOC_SPARC_RELATIVE
+ENUMX
+ BFD_RELOC_SPARC_UA32
+ENUMDOC
+ SPARC ELF relocations. There is probably some overlap with other
+ relocation types already defined.
+
+ENUM
+ BFD_RELOC_SPARC_BASE13
+ENUMX
+ BFD_RELOC_SPARC_BASE22
+ENUMDOC
+ I think these are specific to SPARC a.out (e.g., Sun 4).
+
+ENUMEQ
+ BFD_RELOC_SPARC_64
+ BFD_RELOC_64
+ENUMX
+ BFD_RELOC_SPARC_10
+ENUMX
+ BFD_RELOC_SPARC_11
+ENUMX
+ BFD_RELOC_SPARC_OLO10
+ENUMX
+ BFD_RELOC_SPARC_HH22
+ENUMX
+ BFD_RELOC_SPARC_HM10
+ENUMX
+ BFD_RELOC_SPARC_LM22
+ENUMX
+ BFD_RELOC_SPARC_PC_HH22
+ENUMX
+ BFD_RELOC_SPARC_PC_HM10
+ENUMX
+ BFD_RELOC_SPARC_PC_LM22
+ENUMX
+ BFD_RELOC_SPARC_WDISP16
+ENUMX
+ BFD_RELOC_SPARC_WDISP19
+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
+ SPARC64 relocations
+
+ENUM
+ BFD_RELOC_ALPHA_GPDISP_HI16
+ENUMDOC
+ Alpha ECOFF and ELF relocations. Some of these treat the symbol or
+ "addend" in some special way.
+ For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when
+ writing; when reading, it will be the absolute section symbol. The
+ addend is the displacement in bytes of the "lda" instruction from
+ the "ldah" instruction (which is at the address of this reloc).
+ENUM
+ BFD_RELOC_ALPHA_GPDISP_LO16
+ENUMDOC
+ For GPDISP_LO16 ("ignore") relocations, the symbol is handled as
+ with GPDISP_HI16 relocs. The addend is ignored when writing the
+ relocations out, and is filled in with the file's GP value on
+ reading, for convenience.
+
+ENUM
+ BFD_RELOC_ALPHA_GPDISP
+ENUMDOC
+ The ELF GPDISP relocation is exactly the same as the GPDISP_HI16
+ relocation except that there is no accompanying GPDISP_LO16
+ relocation.
+
+ENUM
+ BFD_RELOC_ALPHA_LITERAL
+ENUMX
+ BFD_RELOC_ALPHA_ELF_LITERAL
+ENUMX
+ BFD_RELOC_ALPHA_LITUSE
+ENUMDOC
+ The Alpha LITERAL/LITUSE relocs are produced by a symbol reference;
+ the assembler turns it into a LDQ instruction to load the address of
+ the symbol, and then fills in a register in the real instruction.
+
+ The LITERAL reloc, at the LDQ instruction, refers to the .lita
+ section symbol. The addend is ignored when writing, but is filled
+ in with the file's GP value on reading, for convenience, as with the
+ GPDISP_LO16 reloc.
+
+ The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16.
+ It should refer to the symbol to be referenced, as with 16_GOTOFF,
+ but it generates output not based on the position within the .got
+ section, but relative to the GP value chosen for the file during the
+ final link stage.
+
+ The LITUSE reloc, on the instruction using the loaded address, gives
+ information to the linker that it might be able to use to optimize
+ away some literal section references. The symbol is ignored (read
+ as the absolute section symbol), and the "addend" indicates the type
+ of instruction using the register:
+ 1 - "memory" fmt insn
+ 2 - byte-manipulation (byte offset reg)
+ 3 - jsr (target of branch)
+
+ The GNU linker currently doesn't do any of this optimizing.
+
+ENUM
+ BFD_RELOC_ALPHA_HINT
+ENUMDOC
+ The HINT relocation indicates a value that should be filled into the
+ "hint" field of a jmp/jsr/ret instruction, for possible branch-
+ prediction logic which may be provided on some processors.
+
+ENUM
+ BFD_RELOC_ALPHA_LINKAGE
+ENUMDOC
+ The LINKAGE relocation outputs a linkage pair in the object file,
+ which is filled by the linker.
+
+ENUM
+ BFD_RELOC_ALPHA_CODEADDR
+ENUMDOC
+ The CODEADDR relocation outputs a STO_CA in the object file,
+ which is filled by the linker.
+
+ENUM
+ BFD_RELOC_MIPS_JMP
+ENUMDOC
+ Bits 27..2 of the relocation address shifted right 2 bits;
+ simple reloc otherwise.
+
+ENUM
+ BFD_RELOC_MIPS16_JMP
+ENUMDOC
+ The MIPS16 jump instruction.
+
+ENUM
+ BFD_RELOC_MIPS16_GPREL
+ENUMDOC
+ MIPS16 GP relative reloc.
+
+ENUM
+ BFD_RELOC_HI16
+ENUMDOC
+ High 16 bits of 32-bit value; simple reloc.
+ENUM
+ BFD_RELOC_HI16_S
+ENUMDOC
+ High 16 bits of 32-bit value but the low 16 bits will be sign
+ extended and added to form the final result. If the low 16
+ bits form a negative number, we need to add one to the high value
+ to compensate for the borrow when the low bits are added.
+ENUM
+ BFD_RELOC_LO16
+ENUMDOC
+ Low 16 bits.
+ENUM
+ BFD_RELOC_PCREL_HI16_S
+ENUMDOC
+ Like BFD_RELOC_HI16_S, but PC relative.
+ENUM
+ BFD_RELOC_PCREL_LO16
+ENUMDOC
+ Like BFD_RELOC_LO16, but PC relative.
+
+ENUMEQ
+ BFD_RELOC_MIPS_GPREL
+ BFD_RELOC_GPREL16
+ENUMDOC
+ Relocation relative to the global pointer.
+
+ENUM
+ BFD_RELOC_MIPS_LITERAL
+ENUMDOC
+ Relocation against a MIPS literal section.
+
+ENUM
+ BFD_RELOC_MIPS_GOT16
+ENUMX
+ BFD_RELOC_MIPS_CALL16
+ENUMEQX
+ BFD_RELOC_MIPS_GPREL32
+ BFD_RELOC_GPREL32
+ENUMX
+ BFD_RELOC_MIPS_GOT_HI16
+ENUMX
+ BFD_RELOC_MIPS_GOT_LO16
+ENUMX
+ BFD_RELOC_MIPS_CALL_HI16
+ENUMX
+ BFD_RELOC_MIPS_CALL_LO16
+ENUMDOC
+ MIPS ELF relocations.
+
+ENUM
+ BFD_RELOC_386_GOT32
+ENUMX
+ BFD_RELOC_386_PLT32
+ENUMX
+ BFD_RELOC_386_COPY
+ENUMX
+ BFD_RELOC_386_GLOB_DAT
+ENUMX
+ BFD_RELOC_386_JUMP_SLOT
+ENUMX
+ BFD_RELOC_386_RELATIVE
+ENUMX
+ BFD_RELOC_386_GOTOFF
+ENUMX
+ BFD_RELOC_386_GOTPC
+ENUMDOC
+ i386/elf relocations
+
+ENUM
+ BFD_RELOC_NS32K_IMM_8
+ENUMX
+ BFD_RELOC_NS32K_IMM_16
+ENUMX
+ BFD_RELOC_NS32K_IMM_32
+ENUMX
+ BFD_RELOC_NS32K_IMM_8_PCREL
+ENUMX
+ BFD_RELOC_NS32K_IMM_16_PCREL
+ENUMX
+ BFD_RELOC_NS32K_IMM_32_PCREL
+ENUMX
+ BFD_RELOC_NS32K_DISP_8
+ENUMX
+ BFD_RELOC_NS32K_DISP_16
+ENUMX
+ BFD_RELOC_NS32K_DISP_32
+ENUMX
+ BFD_RELOC_NS32K_DISP_8_PCREL
+ENUMX
+ BFD_RELOC_NS32K_DISP_16_PCREL
+ENUMX
+ BFD_RELOC_NS32K_DISP_32_PCREL
+ENUMDOC
+ ns32k relocations
+
+ENUM
+ BFD_RELOC_PPC_B26
+ENUMX
+ BFD_RELOC_PPC_BA26
+ENUMX
+ BFD_RELOC_PPC_TOC16
+ENUMX
+ BFD_RELOC_PPC_B16
+ENUMX
+ BFD_RELOC_PPC_B16_BRTAKEN
+ENUMX
+ BFD_RELOC_PPC_B16_BRNTAKEN
+ENUMX
+ BFD_RELOC_PPC_BA16
+ENUMX
+ BFD_RELOC_PPC_BA16_BRTAKEN
+ENUMX
+ BFD_RELOC_PPC_BA16_BRNTAKEN
+ENUMX
+ BFD_RELOC_PPC_COPY
+ENUMX
+ BFD_RELOC_PPC_GLOB_DAT
+ENUMX
+ BFD_RELOC_PPC_JMP_SLOT
+ENUMX
+ BFD_RELOC_PPC_RELATIVE
+ENUMX
+ BFD_RELOC_PPC_LOCAL24PC
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR32
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR16
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR16_LO
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR16_HI
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR16_HA
+ENUMX
+ BFD_RELOC_PPC_EMB_SDAI16
+ENUMX
+ BFD_RELOC_PPC_EMB_SDA2I16
+ENUMX
+ BFD_RELOC_PPC_EMB_SDA2REL
+ENUMX
+ BFD_RELOC_PPC_EMB_SDA21
+ENUMX
+ BFD_RELOC_PPC_EMB_MRKREF
+ENUMX
+ BFD_RELOC_PPC_EMB_RELSEC16
+ENUMX
+ BFD_RELOC_PPC_EMB_RELST_LO
+ENUMX
+ BFD_RELOC_PPC_EMB_RELST_HI
+ENUMX
+ BFD_RELOC_PPC_EMB_RELST_HA
+ENUMX
+ BFD_RELOC_PPC_EMB_BIT_FLD
+ENUMX
+ BFD_RELOC_PPC_EMB_RELSDA
+ENUMDOC
+ Power(rs6000) and PowerPC relocations.
+
+ENUM
+ BFD_RELOC_CTOR
+ENUMDOC
+ The type of reloc used to build a contructor table - at the moment
+ probably a 32 bit wide absolute relocation, but the target can choose.
+ It generally does map to one of the other relocation types.
+
+ENUM
+ BFD_RELOC_ARM_PCREL_BRANCH
+ENUMDOC
+ ARM 26 bit pc-relative branch. The lowest two bits must be zero and are
+ not stored in the instruction.
+ENUM
+ BFD_RELOC_ARM_IMMEDIATE
+ENUMX
+ BFD_RELOC_ARM_OFFSET_IMM
+ENUMX
+ BFD_RELOC_ARM_SHIFT_IMM
+ENUMX
+ BFD_RELOC_ARM_SWI
+ENUMX
+ BFD_RELOC_ARM_MULTI
+ENUMX
+ BFD_RELOC_ARM_CP_OFF_IMM
+ENUMX
+ BFD_RELOC_ARM_ADR_IMM
+ENUMX
+ BFD_RELOC_ARM_LDR_IMM
+ENUMX
+ BFD_RELOC_ARM_LITERAL
+ENUMX
+ BFD_RELOC_ARM_IN_POOL
+ENUMX
+ BFD_RELOC_ARM_OFFSET_IMM8
+ENUMX
+ BFD_RELOC_ARM_HWLITERAL
+ENUMX
+ BFD_RELOC_ARM_THUMB_ADD
+ENUMX
+ BFD_RELOC_ARM_THUMB_IMM
+ENUMX
+ BFD_RELOC_ARM_THUMB_SHIFT
+ENUMX
+ BFD_RELOC_ARM_THUMB_OFFSET
+ENUMDOC
+ These relocs are only used within the ARM assembler. They are not
+ (at present) written to any object files.
+
+ENUM
+ BFD_RELOC_SH_PCDISP8BY2
+ENUMX
+ BFD_RELOC_SH_PCDISP12BY2
+ENUMX
+ BFD_RELOC_SH_IMM4
+ENUMX
+ BFD_RELOC_SH_IMM4BY2
+ENUMX
+ BFD_RELOC_SH_IMM4BY4
+ENUMX
+ BFD_RELOC_SH_IMM8
+ENUMX
+ BFD_RELOC_SH_IMM8BY2
+ENUMX
+ BFD_RELOC_SH_IMM8BY4
+ENUMX
+ BFD_RELOC_SH_PCRELIMM8BY2
+ENUMX
+ BFD_RELOC_SH_PCRELIMM8BY4
+ENUMX
+ BFD_RELOC_SH_SWITCH16
+ENUMX
+ BFD_RELOC_SH_SWITCH32
+ENUMX
+ BFD_RELOC_SH_USES
+ENUMX
+ BFD_RELOC_SH_COUNT
+ENUMX
+ BFD_RELOC_SH_ALIGN
+ENUMX
+ BFD_RELOC_SH_CODE
+ENUMX
+ BFD_RELOC_SH_DATA
+ENUMX
+ BFD_RELOC_SH_LABEL
+ENUMDOC
+ Hitachi SH relocs. Not all of these appear in object files.
+
+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
+ BFD_RELOC_D10V_10_PCREL_R
+ENUMDOC
+ Mitsubishi D10V relocs.
+ This is a 10-bit reloc with the right 2 bits
+ assumed to be 0.
+ENUM
+ BFD_RELOC_D10V_10_PCREL_L
+ENUMDOC
+ Mitsubishi D10V relocs.
+ This is a 10-bit reloc with the right 2 bits
+ assumed to be 0. This is the same as the previous reloc
+ except it is in the left container, i.e.,
+ shifted left 15 bits.
+ENUM
+ BFD_RELOC_D10V_18
+ENUMDOC
+ This is an 18-bit reloc with the right 2 bits
+ assumed to be 0.
+ENUM
+ BFD_RELOC_D10V_18_PCREL
+ENUMDOC
+ This is an 18-bit reloc with the right 2 bits
+ assumed to be 0.
+COMMENT
+
+COMMENT
+{* start-sanitize-d30v *}
+ENUM
+ BFD_RELOC_D30V_6
+ENUMDOC
+ Mitsubishi D30V relocs.
+ This is a 6-bit absolute reloc.
+ENUM
+ BFD_RELOC_D30V_9_PCREL
+ENUMDOC
+ This is a 6-bit pc-relative reloc with
+ the right 3 bits assumed to be 0.
+ENUM
+ BFD_RELOC_D30V_9_PCREL_R
+ENUMDOC
+ This is a 6-bit pc-relative reloc with
+ the right 3 bits assumed to be 0. Same
+ as the previous reloc but on the right side
+ of the container.
+ENUM
+ BFD_RELOC_D30V_15
+ENUMDOC
+ This is a 12-bit absolute reloc with the
+ right 3 bitsassumed to be 0.
+ENUM
+ BFD_RELOC_D30V_15_PCREL
+ENUMDOC
+ This is a 12-bit pc-relative reloc with
+ the right 3 bits assumed to be 0.
+ENUM
+ BFD_RELOC_D30V_15_PCREL_R
+ENUMDOC
+ This is a 12-bit pc-relative reloc with
+ the right 3 bits assumed to be 0. Same
+ as the previous reloc but on the right side
+ of the container.
+ENUM
+ BFD_RELOC_D30V_21
+ENUMDOC
+ This is an 18-bit absolute reloc with
+ the right 3 bits assumed to be 0.
+ENUM
+ BFD_RELOC_D30V_21_PCREL
+ENUMDOC
+ This is an 18-bit pc-relative reloc with
+ the right 3 bits assumed to be 0.
+ENUM
+ BFD_RELOC_D30V_21_PCREL_R
+ENUMDOC
+ This is an 18-bit pc-relative reloc with
+ the right 3 bits assumed to be 0. Same
+ as the previous reloc but on the right side
+ of the container.
+ENUM
+ BFD_RELOC_D30V_32
+ENUMDOC
+ This is a 32-bit absolute reloc.
+ENUM
+ BFD_RELOC_D30V_32_PCREL
+ENUMDOC
+ This is a 32-bit pc-relative reloc.
+COMMENT
+{* end-sanitize-d30v *}
+
+ENUM
+ BFD_RELOC_M32R_24
+ENUMDOC
+ Mitsubishi M32R relocs.
+ This is a 24 bit absolute address.
+ENUM
+ BFD_RELOC_M32R_10_PCREL
+ENUMDOC
+ This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0.
+ENUM
+ BFD_RELOC_M32R_18_PCREL
+ENUMDOC
+ This is an 18-bit reloc with the right 2 bits assumed to be 0.
+ENUM
+ BFD_RELOC_M32R_26_PCREL
+ENUMDOC
+ This is a 26-bit reloc with the right 2 bits assumed to be 0.
+ENUM
+ BFD_RELOC_M32R_HI16_ULO
+ENUMDOC
+ This is a 16-bit reloc containing the high 16 bits of an address
+ used when the lower 16 bits are treated as unsigned.
+ENUM
+ BFD_RELOC_M32R_HI16_SLO
+ENUMDOC
+ This is a 16-bit reloc containing the high 16 bits of an address
+ used when the lower 16 bits are treated as signed.
+ENUM
+ BFD_RELOC_M32R_LO16
+ENUMDOC
+ This is a 16-bit reloc containing the lower 16 bits of an address.
+ENUM
+ BFD_RELOC_M32R_SDA16
+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
+{* start-sanitize-v850e *}
+ENUM
+ BFD_RELOC_V850_TDA_4_5_OFFSET
+ENUMDOC
+ This is a 5 bit offset (of which only 4 bits are used) from the tiny
+ data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_4_4_OFFSET
+ENUMDOC
+ This is a 4 bit offset from the tiny data area pointer.
+ENUM
+ BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the short data area pointer, with the
+ bits placed non-contigously in the instruction.
+ENUM
+ BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the zero data area pointer, with the
+ bits placed non-contigously in the instruction.
+ENUM
+ BFD_RELOC_V850_CALLT_6_7_OFFSET
+ENUMDOC
+ This is a 6 bit offset from the call table base pointer.
+ENUM
+ BFD_RELOC_V850_CALLT_16_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the call table base pointer.
+COMMENT
+{* end-sanitize-v850e *}
+
+ENUM
+ BFD_RELOC_MN10300_32_PCREL
+ENUMDOC
+ This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
+ instruction.
+ENUM
+ BFD_RELOC_MN10300_16_PCREL
+ENUMDOC
+ This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the
+ instruction.
+
+COMMENT
+{* start-sanitize-sky *}
+ENUM
+ BFD_RELOC_TXVU_11_PCREL
+ENUMDOC
+ SKY TXVU Relocations.
+ This is an 11-bit pc relative reloc. The recorded address is for the
+ lower instruction word.
+COMMENT
+{* end-sanitize-sky *}
+
+ENDSENUM
+ BFD_RELOC_UNUSED
CODE_FRAGMENT
.
-.typedef enum bfd_reloc_code_real
-.{
-. {* Basic absolute relocations *}
-. BFD_RELOC_64,
-. BFD_RELOC_32,
-. BFD_RELOC_26,
-. BFD_RELOC_16,
-. BFD_RELOC_14,
-. BFD_RELOC_8,
-.
-. {* PC-relative relocations *}
-. BFD_RELOC_64_PCREL,
-. BFD_RELOC_32_PCREL,
-. BFD_RELOC_24_PCREL, {* used by i960 *}
-. BFD_RELOC_16_PCREL,
-. BFD_RELOC_8_PCREL,
-.
-. {* Linkage-table relative *}
-. BFD_RELOC_32_BASEREL,
-. BFD_RELOC_16_BASEREL,
-. BFD_RELOC_8_BASEREL,
-.
-. {* The type of reloc used to build a contructor table - at the moment
-. probably a 32 bit wide abs address, but the cpu can choose. *}
-. BFD_RELOC_CTOR,
-.
-. {* 8 bits wide, but used to form an address like 0xffnn *}
-. BFD_RELOC_8_FFnn,
-.
-. {* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit
-. word displacement, e.g. for SPARC) *}
-. BFD_RELOC_32_PCREL_S2,
-. {* signed 16-bit pc-relative, shifted right 2 bits (e.g. for MIPS) *}
-. BFD_RELOC_16_PCREL_S2,
-. {* this is used on the Alpha *}
-. BFD_RELOC_23_PCREL_S2,
-.
-. {* High 22 bits of 32-bit value, placed into lower 22 bits of
-. target word; simple reloc. *}
-. BFD_RELOC_HI22,
-. {* Low 10 bits. *}
-. BFD_RELOC_LO10,
-.
-. {* For systems that allocate a Global Pointer register, these are
-. displacements off that register. These relocation types are
-. handled specially, because the value the register will have is
-. decided relatively late. *}
-. BFD_RELOC_GPREL16,
-. BFD_RELOC_GPREL32,
-.
-. {* Reloc types used for i960/b.out. *}
-. BFD_RELOC_I960_CALLJ,
-.
-. {* now for the sparc/elf codes *}
-. BFD_RELOC_NONE, {* actually used *}
-. BFD_RELOC_SPARC_WDISP22,
-. BFD_RELOC_SPARC22,
-. BFD_RELOC_SPARC13,
-. BFD_RELOC_SPARC_GOT10,
-. BFD_RELOC_SPARC_GOT13,
-. BFD_RELOC_SPARC_GOT22,
-. BFD_RELOC_SPARC_PC10,
-. BFD_RELOC_SPARC_PC22,
-. BFD_RELOC_SPARC_WPLT30,
-. BFD_RELOC_SPARC_COPY,
-. BFD_RELOC_SPARC_GLOB_DAT,
-. BFD_RELOC_SPARC_JMP_SLOT,
-. BFD_RELOC_SPARC_RELATIVE,
-. BFD_RELOC_SPARC_UA32,
-.
-. {* these are a.out specific? *}
-. BFD_RELOC_SPARC_BASE13,
-. BFD_RELOC_SPARC_BASE22,
-.
-. {* some relocations we're using for sparc v9
-. -- subject to change *}
-. BFD_RELOC_SPARC_10,
-. BFD_RELOC_SPARC_11,
-.#define BFD_RELOC_SPARC_64 BFD_RELOC_64
-. BFD_RELOC_SPARC_OLO10,
-. BFD_RELOC_SPARC_HH22,
-. BFD_RELOC_SPARC_HM10,
-. BFD_RELOC_SPARC_LM22,
-. BFD_RELOC_SPARC_PC_HH22,
-. BFD_RELOC_SPARC_PC_HM10,
-. BFD_RELOC_SPARC_PC_LM22,
-. BFD_RELOC_SPARC_WDISP16,
-. BFD_RELOC_SPARC_WDISP19,
-. BFD_RELOC_SPARC_GLOB_JMP,
-. BFD_RELOC_SPARC_LO7,
-.
-. {* Alpha ECOFF relocations. Some of these treat the symbol or "addend"
-. in some special way. *}
-. {* For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when
-. writing; when reading, it will be the absolute section symbol. The
-. addend is the displacement in bytes of the "lda" instruction from
-. the "ldah" instruction (which is at the address of this reloc). *}
-. BFD_RELOC_ALPHA_GPDISP_HI16,
-. {* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as
-. with GPDISP_HI16 relocs. The addend is ignored when writing the
-. relocations out, and is filled in with the file's GP value on
-. reading, for convenience. *}
-. BFD_RELOC_ALPHA_GPDISP_LO16,
-.
-. {* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference;
-. the assembler turns it into a LDQ instruction to load the address of
-. the symbol, and then fills in a register in the real instruction.
-.
-. The LITERAL reloc, at the LDQ instruction, refers to the .lita
-. section symbol. The addend is ignored when writing, but is filled
-. in with the file's GP value on reading, for convenience, as with the
-. GPDISP_LO16 reloc.
-.
-. The LITUSE reloc, on the instruction using the loaded address, gives
-. information to the linker that it might be able to use to optimize
-. away some literal section references. The symbol is ignored (read
-. as the absolute section symbol), and the "addend" indicates the type
-. of instruction using the register:
-. 1 - "memory" fmt insn
-. 2 - byte-manipulation (byte offset reg)
-. 3 - jsr (target of branch)
-.
-. The GNU linker currently doesn't do any of this optimizing. *}
-. BFD_RELOC_ALPHA_LITERAL,
-. BFD_RELOC_ALPHA_LITUSE,
-.
-. {* The HINT relocation indicates a value that should be filled into the
-. "hint" field of a jmp/jsr/ret instruction, for possible branch-
-. prediction logic which may be provided on some processors. *}
-. BFD_RELOC_ALPHA_HINT,
-.
-. {* Bits 27..2 of the relocation address shifted right 2 bits;
-. simple reloc otherwise. *}
-. BFD_RELOC_MIPS_JMP,
-.
-. {* High 16 bits of 32-bit value; simple reloc. *}
-. BFD_RELOC_HI16,
-. {* High 16 bits of 32-bit value but the low 16 bits will be sign
-. extended and added to form the final result. If the low 16
-. bits form a negative number, we need to add one to the high value
-. to compensate for the borrow when the low bits are added. *}
-. BFD_RELOC_HI16_S,
-. {* Low 16 bits. *}
-. BFD_RELOC_LO16,
-. {* Like BFD_RELOC_HI16_S, but PC relative. *}
-. BFD_RELOC_PCREL_HI16_S,
-. {* Like BFD_RELOC_LO16, but PC relative. *}
-. BFD_RELOC_PCREL_LO16,
-.
-. {* relocation relative to the global pointer. *}
-.#define BFD_RELOC_MIPS_GPREL BFD_RELOC_GPREL16
-.
-. {* Relocation against a MIPS literal section. *}
-. BFD_RELOC_MIPS_LITERAL,
-.
-. {* MIPS ELF relocations. *}
-. BFD_RELOC_MIPS_GOT16,
-. BFD_RELOC_MIPS_CALL16,
-.#define BFD_RELOC_MIPS_GPREL32 BFD_RELOC_GPREL32
-.
-. {* i386/elf relocations *}
-. BFD_RELOC_386_GOT32,
-. BFD_RELOC_386_PLT32,
-. BFD_RELOC_386_COPY,
-. BFD_RELOC_386_GLOB_DAT,
-. BFD_RELOC_386_JUMP_SLOT,
-. BFD_RELOC_386_RELATIVE,
-. BFD_RELOC_386_GOTOFF,
-. BFD_RELOC_386_GOTPC,
-.
-. {* ns32k relocations *}
-. BFD_RELOC_NS32K_IMM_8,
-. BFD_RELOC_NS32K_IMM_16,
-. BFD_RELOC_NS32K_IMM_32,
-. BFD_RELOC_NS32K_IMM_8_PCREL,
-. BFD_RELOC_NS32K_IMM_16_PCREL,
-. BFD_RELOC_NS32K_IMM_32_PCREL,
-. BFD_RELOC_NS32K_DISP_8,
-. BFD_RELOC_NS32K_DISP_16,
-. BFD_RELOC_NS32K_DISP_32,
-. BFD_RELOC_NS32K_DISP_8_PCREL,
-. BFD_RELOC_NS32K_DISP_16_PCREL,
-. BFD_RELOC_NS32K_DISP_32_PCREL,
-.
-. {* PowerPC/POWER (RS/6000) relocs. *}
-. {* 26 bit relative branch. Low two bits must be zero. High 24
-. bits installed in bits 6 through 29 of instruction. *}
-. BFD_RELOC_PPC_B26,
-. {* 26 bit absolute branch, like BFD_RELOC_PPC_B26 but absolute. *}
-. BFD_RELOC_PPC_BA26,
-. {* 16 bit TOC relative reference. *}
-. BFD_RELOC_PPC_TOC16,
-.
-. {* this must be the highest numeric value *}
-. BFD_RELOC_UNUSED
-. } bfd_reloc_code_real_type;
+.typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
*/
bfd_reloc_type_lookup
SYNOPSIS
- const struct reloc_howto_struct *
+ reloc_howto_type *
bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code);
DESCRIPTION
*/
-const struct reloc_howto_struct *
+reloc_howto_type *
bfd_reloc_type_lookup (abfd, code)
bfd *abfd;
bfd_reloc_code_real_type code;
bfd_default_reloc_type_lookup
SYNOPSIS
- const struct reloc_howto_struct *bfd_default_reloc_type_lookup
+ reloc_howto_type *bfd_default_reloc_type_lookup
(bfd *abfd, bfd_reloc_code_real_type code);
DESCRIPTION
*/
-const struct reloc_howto_struct *
+reloc_howto_type *
bfd_default_reloc_type_lookup (abfd, code)
bfd *abfd;
bfd_reloc_code_real_type code;
default:
BFD_FAIL ();
}
- return (const struct reloc_howto_struct *) NULL;
+ return (reloc_howto_type *) NULL;
}
+/*
+FUNCTION
+ bfd_get_reloc_code_name
+
+SYNOPSIS
+ const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code);
+
+DESCRIPTION
+ Provides a printable name for the supplied relocation code.
+ Useful mainly for printing error messages.
+*/
+
+const char *
+bfd_get_reloc_code_name (code)
+ bfd_reloc_code_real_type code;
+{
+ if (code > BFD_RELOC_UNUSED)
+ return 0;
+ return bfd_reloc_code_real_names[(int)code];
+}
/*
INTERNAL_FUNCTION
if (reloc_size < 0)
goto error_return;
- reloc_vector = (arelent **) malloc (reloc_size);
+ reloc_vector = (arelent **) bfd_malloc ((size_t) reloc_size);
if (reloc_vector == NULL && reloc_size != 0)
- {
- bfd_set_error (bfd_error_no_memory);
- goto error_return;
- }
+ goto error_return;
/* read in the section */
if (!bfd_get_section_contents (input_bfd,