X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Freloc.c;h=856994b6b4fdb29c9c6cf8e536237e28b5b50df4;hb=f6af82bd4470673eef9562d4ed3a2717c1d749ab;hp=487be0e767f6b80064918196cd7f28819e220df0;hpb=1fb83be62b5f5a9003124a42c276b9821f58dce1;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/reloc.c b/bfd/reloc.c index 487be0e767..856994b6b4 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -1,5 +1,6 @@ /* 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, 97, 98, 1999 + Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -16,7 +17,7 @@ GNU General Public License for more details. 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 @@ -41,6 +42,10 @@ 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" @@ -101,7 +106,7 @@ CODE_FRAGMENT . bfd_vma addend; . . {* Pointer to how to perform the required relocation *} -. const struct reloc_howto_struct *howto; +. reloc_howto_type *howto; . .} arelent; @@ -134,7 +139,7 @@ DESCRIPTION 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 <> The <> is a value provided by the back end to be added (!) @@ -282,11 +287,9 @@ SUBSUBSECTION 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 @@ -334,17 +337,6 @@ CODE_FRAGMENT . 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; . @@ -376,7 +368,6 @@ CODE_FRAGMENT . boolean pcrel_offset; . .}; -.typedef struct reloc_howto_struct reloc_howto_type; */ @@ -389,9 +380,7 @@ DESCRIPTION .#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 @@ -400,6 +389,14 @@ DESCRIPTION .#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN) . + +DESCRIPTION + This is used to fill in an empty howto entry in an array. + +.#define EMPTY_HOWTO(C) \ +. HOWTO((C),0,0,0,false,0,complain_overflow_dont,NULL,NULL,false,0,0,false) +. + DESCRIPTION Helper routine to turn a symbol into a relocation value. @@ -422,16 +419,16 @@ FUNCTION bfd_get_reloc_size SYNOPSIS - int bfd_get_reloc_size (const 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) - const reloc_howto_type *howto; + reloc_howto_type *howto; { switch (howto->size) { @@ -440,6 +437,7 @@ bfd_get_reloc_size (howto) case 2: return 4; case 3: return 0; case 4: return 8; + case 8: return 16; case -2: return 4; default: abort (); } @@ -460,7 +458,94 @@ DESCRIPTION */ +/* N_ONES produces N one bits, without overflowing machine arithmetic. */ +#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1) +/* +FUNCTION + bfd_check_overflow + +SYNOPSIS + bfd_reloc_status_type + bfd_check_overflow + (enum complain_overflow how, + unsigned int bitsize, + unsigned int rightshift, + unsigned int addrsize, + 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, on a machine with addresses containing + @var{addrsize} significant 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, addrsize, relocation) + enum complain_overflow how; + unsigned int bitsize; + unsigned int rightshift; + unsigned int addrsize; + bfd_vma relocation; +{ + bfd_vma fieldmask, addrmask, signmask, ss, a; + bfd_reloc_status_type flag = bfd_reloc_ok; + + a = relocation; + + /* Note: BITSIZE should always be <= ADDRSIZE, but in case it's not, + we'll be permissive: extra bits in the field mask will + automatically extend the address mask for purposes of the + overflow check. */ + fieldmask = N_ONES (bitsize); + addrmask = N_ONES (addrsize) | fieldmask; + + switch (how) + { + case complain_overflow_dont: + break; + + case complain_overflow_signed: + /* If any sign bits are set, all sign bits must be set. That + is, A must be a valid negative address after shifting. */ + a = (a & addrmask) >> rightshift; + signmask = ~ (fieldmask >> 1); + ss = a & signmask; + if (ss != 0 && ss != ((addrmask >> rightshift) & signmask)) + flag = bfd_reloc_overflow; + break; + + case complain_overflow_unsigned: + /* We have an overflow if the address does not fit in the field. */ + a = (a & addrmask) >> rightshift; + if ((a & ~ fieldmask) != 0) + flag = bfd_reloc_overflow; + break; + + case complain_overflow_bitfield: + /* Bitfields are sometimes signed, sometimes unsigned. We + overflow if the value has some, but not all, bits set outside + the field, or if it has any bits set outside the field but + the sign bit is not set. */ + a >>= rightshift; + if ((a & ~ fieldmask) != 0) + { + signmask = (fieldmask >> 1) + 1; + ss = (signmask << rightshift) - 1; + if ((ss | relocation) != ~ (bfd_vma) 0) + flag = bfd_reloc_overflow; + } + break; + + default: + abort (); + } + + return flag; +} /* FUNCTION @@ -507,9 +592,9 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd, { bfd_vma relocation; bfd_reloc_status_type flag = bfd_reloc_ok; - bfd_size_type addr = reloc_entry->address; + bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte (abfd); 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; @@ -543,7 +628,8 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd, } /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > input_section->_cooked_size) + if (reloc_entry->address > input_section->_cooked_size / + bfd_octets_per_byte (abfd)) return bfd_reloc_outofrange; /* Work out which section the relocation is targetted at and the @@ -633,6 +719,7 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd, /* 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) { @@ -728,80 +815,404 @@ space consuming. For each target: 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) + if (howto->complain_on_overflow != complain_overflow_dont + && flag == bfd_reloc_ok) + flag = bfd_check_overflow (howto->complain_on_overflow, + howto->bitsize, + howto->rightshift, + bfd_arch_bits_per_address (abfd), + 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 + 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 + 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 + */ + +#define DOIT(x) \ + x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) + + switch (howto->size) + { + case 0: + { + char x = bfd_get_8 (abfd, (char *) data + octets); + DOIT (x); + bfd_put_8 (abfd, x, (unsigned char *) data + octets); + } + break; + + case 1: + { + short x = bfd_get_16 (abfd, (bfd_byte *) data + octets); + DOIT (x); + bfd_put_16 (abfd, x, (unsigned char *) data + octets); + } + break; + case 2: + { + long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); + DOIT (x); + bfd_put_32 (abfd, x, (bfd_byte *) data + octets); + } + break; + case -2: + { + long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); + relocation = -relocation; + DOIT (x); + bfd_put_32 (abfd, x, (bfd_byte *) data + octets); + } + break; + + case -1: + { + long x = bfd_get_16 (abfd, (bfd_byte *) data + octets); + relocation = -relocation; + DOIT (x); + bfd_put_16 (abfd, x, (bfd_byte *) data + octets); + } + break; + + case 3: + /* Do nothing */ + break; + + case 4: +#ifdef BFD64 + { + bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + octets); + DOIT (x); + bfd_put_64 (abfd, x, (bfd_byte *) data + octets); + } +#else + abort (); +#endif + break; + default: + return bfd_reloc_other; + } + + 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 <>, 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 octets = reloc_entry->address * bfd_octets_per_byte (abfd); + 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)) { - bfd_vma check; + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } - /* 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); + /* 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 - 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 (); + 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, + bfd_arch_bits_per_address (abfd), + 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 @@ -873,38 +1284,38 @@ space consuming. For each target: #define DOIT(x) \ x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) + data = (bfd_byte *) data_start + (octets - data_start_offset); + switch (howto->size) { case 0: { - char x = bfd_get_8 (abfd, (char *) data + addr); + char x = bfd_get_8 (abfd, (char *) data); DOIT (x); - bfd_put_8 (abfd, x, (unsigned char *) data + addr); + bfd_put_8 (abfd, x, (unsigned char *) data); } 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); + DOIT (x); + bfd_put_16 (abfd, x, (unsigned char *) data); + } 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); + DOIT (x); + bfd_put_32 (abfd, x, (bfd_byte *) data); + } break; case -2: { - long x = bfd_get_32 (abfd, (bfd_byte *) data + addr); + long x = bfd_get_32 (abfd, (bfd_byte *) data); relocation = -relocation; DOIT (x); - bfd_put_32 (abfd, x, (bfd_byte *) data + addr); + bfd_put_32 (abfd, x, (bfd_byte *) data); } break; @@ -913,16 +1324,11 @@ space consuming. For each target: 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); - } -#else - abort (); -#endif + { + 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; @@ -937,8 +1343,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 @@ -955,7 +1362,7 @@ space consuming. For each target: 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; @@ -966,7 +1373,7 @@ _bfd_final_link_relocate (howto, input_bfd, input_section, contents, address, 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 @@ -993,13 +1400,6 @@ _bfd_final_link_relocate (howto, input_bfd, input_section, contents, address, 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); } @@ -1008,14 +1408,16 @@ _bfd_final_link_relocate (howto, input_bfd, input_section, 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; { int size; - bfd_vma x; + bfd_vma x = 0; boolean overflow; + unsigned int rightshift = howto->rightshift; + unsigned int bitpos = howto->bitpos; /* If the size is negative, negate RELOCATION. This isn't very general. */ @@ -1054,114 +1456,148 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location) overflow = false; if (howto->complain_on_overflow != complain_overflow_dont) { - bfd_vma check; - bfd_signed_vma signed_check; - bfd_vma add; - bfd_signed_vma signed_add; + bfd_vma addrmask, fieldmask, signmask, ss; + bfd_vma a, b, sum; + + /* Get the values to be added together. For signed and unsigned + relocations, we assume that all values should be truncated to + the size of an address. For bitfields, all the bits matter. + See also bfd_check_overflow. */ + fieldmask = N_ONES (howto->bitsize); + addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask; + a = relocation; + b = x & howto->src_mask; - if (howto->rightshift == 0) - { - check = relocation; - signed_check = (bfd_signed_vma) relocation; - } - else + switch (howto->complain_on_overflow) { - /* Drop unwanted bits from the value we are relocating to. */ - check = relocation >> howto->rightshift; + case complain_overflow_signed: + a = (a & addrmask) >> rightshift; + + /* If any sign bits are set, all sign bits must be set. + That is, A must be a valid negative address after + shifting. */ + signmask = ~ (fieldmask >> 1); + ss = a & signmask; + if (ss != 0 && ss != ((addrmask >> rightshift) & signmask)) + overflow = true; + + /* We only need this next bit of code if the sign bit of B + is below the sign bit of A. This would only happen if + SRC_MASK had fewer bits than BITSIZE. Note that if + SRC_MASK has more bits than BITSIZE, we can get into + trouble; we would need to verify that B is in range, as + we do for A above. */ + signmask = ((~ howto->src_mask) >> 1) & howto->src_mask; + if ((b & signmask) != 0) + { + /* Set all the bits above the sign bit. */ + b -= signmask <<= 1; + } - /* If this is a signed value, the rightshift just dropped - leading 1 bits (assuming twos complement). */ - if ((bfd_signed_vma) relocation >= 0) - signed_check = check; - else - signed_check = (check - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->rightshift))); - } + b = (b & addrmask) >> bitpos; - /* Get the value from the object file. */ - add = x & howto->src_mask; - - /* Get the value from the object file with an appropriate sign. - The expression involving howto->src_mask isolates the upper - bit of src_mask. If that bit is set in the value we are - adding, it is negative, and we subtract out that number times - two. If src_mask includes the highest possible bit, then we - can not get the upper bit, but that does not matter since - signed_add needs no adjustment to become negative in that - case. */ - signed_add = add; - if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0) - signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1; - - /* Add the value from the object file, shifted so that it is a - straight number. */ - if (howto->bitpos == 0) - { - check += add; - signed_check += signed_add; - } - else - { - check += add >> howto->bitpos; + /* Now we can do the addition. */ + sum = a + b; - /* For the signed case we use ADD, rather than SIGNED_ADD, - to avoid warnings from SVR4 cc. This is OK since we - explictly handle the sign bits. */ - if (signed_add >= 0) - signed_check += add >> howto->bitpos; - else - signed_check += ((add >> howto->bitpos) - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->bitpos))); - } + /* See if the result has the correct sign. Bits above the + sign bit are junk now; ignore them. If the sum is + positive, make sure we did not have all negative inputs; + if the sum is negative, make sure we did not have all + positive inputs. The test below looks only at the sign + bits, and it really just + SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM) + */ + signmask = (fieldmask >> 1) + 1; + if (((~ (a ^ b)) & (a ^ sum)) & signmask) + overflow = true; - 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; - - if (signed_check > reloc_signed_max - || signed_check < reloc_signed_min) - overflow = true; - } 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 (check > reloc_unsigned_max) - overflow = true; - } + /* Checking for an unsigned overflow is relatively easy: + trim the addresses and add, and trim the result as well. + Overflow is normally indicated when the result does not + fit in the field. However, we also need to consider the + case when, e.g., fieldmask is 0x7fffffff or smaller, an + input is 0x80000000, and bfd_vma is only 32 bits; then we + will get sum == 0, but there is an overflow, since the + inputs did not fit in the field. Instead of doing a + separate test, we can check for this by or-ing in the + operands when testing for the sum overflowing its final + field. */ + a = (a & addrmask) >> rightshift; + b = (b & addrmask) >> bitpos; + sum = (a + b) & addrmask; + if ((a | b | sum) & ~ fieldmask) + overflow = true; + 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 ((check & ~reloc_bits) != 0 - && (((bfd_vma) signed_check & ~reloc_bits) - != (-1 & ~reloc_bits))) - overflow = true; - } + /* Much like unsigned, except no trimming with addrmask. In + addition, the sum overflows if there is a carry out of + the bfd_vma, i.e., the sum is less than either input + operand. */ + a >>= rightshift; + b >>= bitpos; + + /* Bitfields are sometimes used for signed numbers; for + example, a 13-bit field sometimes represents values in + 0..8191 and sometimes represents values in -4096..4095. + If the field is signed and a is -4095 (0x1001) and b is + -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 + + 0x1fff is 0x3000). It's not clear how to handle this + everywhere, since there is not way to know how many bits + are significant in the relocation, but the original code + assumed that it was fully sign extended, and we will keep + that assumption. */ + signmask = (fieldmask >> 1) + 1; + + if ((a & ~ fieldmask) != 0) + { + /* Some bits out of the field are set. This might not + be a problem: if this is a signed bitfield, it is OK + iff all the high bits are set, including the sign + bit. We'll try setting all but the most significant + bit in the original relocation value: if this is all + ones, we are OK, assuming a signed bitfield. */ + ss = (signmask << rightshift) - 1; + if ((ss | relocation) != ~ (bfd_vma) 0) + overflow = true; + a &= fieldmask; + } + + /* We just assume (b & ~ fieldmask) == 0. */ + + /* We explicitly permit wrap around if this relocation + covers the high bit of an address. The Linux kernel + 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 + rightshift + == bfd_arch_bits_per_address (input_bfd)) + break; + + sum = a + b; + if (sum < a || (sum & ~ fieldmask) != 0) + { + /* There was a carry out, or the field overflow. Test + for signed operands again. Here is the overflow test + is as for complain_overflow_signed. */ + if (((~ (a ^ b)) & (a ^ sum)) & signmask) + overflow = true; + } + break; + default: abort (); } } /* Put RELOCATION in the right bits. */ - relocation >>= (bfd_vma) howto->rightshift; - relocation <<= (bfd_vma) howto->bitpos; + relocation >>= (bfd_vma) rightshift; + relocation <<= (bfd_vma) bitpos; /* Add RELOCATION to the right bits of X. */ x = ((x & ~howto->dst_mask) @@ -1222,204 +1658,980 @@ DESCRIPTION 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 <>.) 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_SPARC_REV32 +ENUMDOC + SPARC little endian relocation + +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_USER_LITERAL +ENUMX + BFD_RELOC_ALPHA_USER_LITUSE_BASE +ENUMX + BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF +ENUMX + BFD_RELOC_ALPHA_USER_LITUSE_JSR +ENUMX + BFD_RELOC_ALPHA_USER_GPDISP +ENUMX + BFD_RELOC_ALPHA_USER_GPRELHIGH +ENUMX + BFD_RELOC_ALPHA_USER_GPRELLOW +ENUMDOC + The BFD_RELOC_ALPHA_USER_* relocations are used by the assembler to + process the explicit !!sequence relocations, and are mapped + into the normal relocations at the end of processing. + +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 +ENUMX + BFD_RELOC_MIPS_SUB +ENUMX + BFD_RELOC_MIPS_GOT_PAGE +ENUMX + BFD_RELOC_MIPS_GOT_OFST +ENUMX + BFD_RELOC_MIPS_GOT_DISP +COMMENT +ENUMDOC + MIPS ELF relocations. + +COMMENT + +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_PJ_CODE_HI16 +ENUMX + BFD_RELOC_PJ_CODE_LO16 +ENUMX + BFD_RELOC_PJ_CODE_DIR16 +ENUMX + BFD_RELOC_PJ_CODE_DIR32 +ENUMX + BFD_RELOC_PJ_CODE_REL16 +ENUMX + BFD_RELOC_PJ_CODE_REL32 +ENUMDOC + Picojava relocs. Not all of these appear in object files. + +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_ADRL_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 +ENUMX + BFD_RELOC_ARM_GOT12 +ENUMX + BFD_RELOC_ARM_GOT32 +ENUMX + BFD_RELOC_ARM_JUMP_SLOT +ENUMX + BFD_RELOC_ARM_COPY +ENUMX + BFD_RELOC_ARM_GLOB_DAT +ENUMX + BFD_RELOC_ARM_PLT32 +ENUMX + BFD_RELOC_ARM_RELATIVE +ENUMX + BFD_RELOC_ARM_GOTOFF +ENUMX + BFD_RELOC_ARM_GOTPC +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. + +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. + +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. + +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 +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 + +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. + +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. + +ENUM + BFD_RELOC_FR30_48 +ENUMDOC + This is a 48 bit reloc for the FR30 that stores 32 bits. +ENUM + BFD_RELOC_FR30_20 +ENUMDOC + This is a 32 bit reloc for the FR30 that stores 20 bits split up into + two sections. +ENUM + BFD_RELOC_FR30_6_IN_4 +ENUMDOC + This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in + 4 bits. +ENUM + BFD_RELOC_FR30_8_IN_8 +ENUMDOC + This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset + into 8 bits. +ENUM + BFD_RELOC_FR30_9_IN_8 +ENUMDOC + This is a 16 bit reloc for the FR30 that stores a 9 bit short offset + into 8 bits. +ENUM + BFD_RELOC_FR30_10_IN_8 +ENUMDOC + This is a 16 bit reloc for the FR30 that stores a 10 bit word offset + into 8 bits. +ENUM + BFD_RELOC_FR30_9_PCREL +ENUMDOC + This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative + short offset into 8 bits. +ENUM + BFD_RELOC_FR30_12_PCREL +ENUMDOC + This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative + short offset into 11 bits. + +ENUM + BFD_RELOC_MCORE_PCREL_IMM8BY4 +ENUMX + BFD_RELOC_MCORE_PCREL_IMM11BY2 +ENUMX + BFD_RELOC_MCORE_PCREL_IMM4BY2 +ENUMX + BFD_RELOC_MCORE_PCREL_32 +ENUMX + BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2 +ENUMX + BFD_RELOC_MCORE_RVA +ENUMDOC + Motorola Mcore relocations. + +ENUM + BFD_RELOC_VTABLE_INHERIT +ENUMX + BFD_RELOC_VTABLE_ENTRY +ENUMDOC + These two relocations are used by the linker to determine which of + the entries in a C++ virtual function table are actually used. When + the --gc-sections option is given, the linker will zero out the entries + that are not used, so that the code for those functions need not be + included in the output. + + VTABLE_INHERIT is a zero-space relocation used to describe to the + linker the inheritence tree of a C++ virtual function table. The + relocation's symbol should be the parent class' vtable, and the + relocation should be located at the child vtable. + + VTABLE_ENTRY is a zero-space relocation that describes the use of a + virtual function table entry. The reloc's symbol should refer to the + table of the class mentioned in the code. Off of that base, an offset + describes the entry that is being used. For Rela hosts, this offset + is stored in the reloc's addend. For Rel hosts, we are forced to put + this offset in the reloc's section offset. + +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; */ @@ -1428,7 +2640,7 @@ FUNCTION 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 @@ -1439,7 +2651,7 @@ DESCRIPTION */ -const struct reloc_howto_struct * +reloc_howto_type * bfd_reloc_type_lookup (abfd, code) bfd *abfd; bfd_reloc_code_real_type code; @@ -1456,7 +2668,7 @@ INTERNAL_FUNCTION 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 @@ -1465,7 +2677,7 @@ DESCRIPTION */ -const struct reloc_howto_struct * +reloc_howto_type * bfd_default_reloc_type_lookup (abfd, code) bfd *abfd; bfd_reloc_code_real_type code; @@ -1489,9 +2701,29 @@ bfd_default_reloc_type_lookup (abfd, 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 @@ -1512,15 +2744,37 @@ DESCRIPTION /*ARGSUSED*/ boolean bfd_generic_relax_section (abfd, section, link_info, again) - bfd *abfd; - asection *section; - struct bfd_link_info *link_info; + bfd *abfd ATTRIBUTE_UNUSED; + asection *section ATTRIBUTE_UNUSED; + struct bfd_link_info *link_info ATTRIBUTE_UNUSED; boolean *again; { *again = false; return true; } +/* +INTERNAL_FUNCTION + bfd_generic_gc_sections + +SYNOPSIS + boolean bfd_generic_gc_sections + (bfd *, struct bfd_link_info *); + +DESCRIPTION + Provides default handling for relaxing for back ends which + don't do section gc -- i.e., does nothing. +*/ + +/*ARGSUSED*/ +boolean +bfd_generic_gc_sections (abfd, link_info) + bfd *abfd ATTRIBUTE_UNUSED; + struct bfd_link_info *link_info ATTRIBUTE_UNUSED; +{ + return true; +} + /* INTERNAL_FUNCTION bfd_generic_get_relocated_section_contents @@ -1561,12 +2815,9 @@ bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data, 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,