diff options
Diffstat (limited to 'contrib/binutils/bfd/reloc.c')
-rw-r--r-- | contrib/binutils/bfd/reloc.c | 781 |
1 files changed, 570 insertions, 211 deletions
diff --git a/contrib/binutils/bfd/reloc.c b/contrib/binutils/bfd/reloc.c index dda7624..ef2375a 100644 --- a/contrib/binutils/bfd/reloc.c +++ b/contrib/binutils/bfd/reloc.c @@ -1,5 +1,5 @@ /* BFD support for handling relocation entries. - Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. Written by Cygnus Support. @@ -25,7 +25,7 @@ SECTION BFD maintains relocations in much the same way it maintains symbols: they are left alone until required, then read in - en-mass and translated into an internal form. A common + en-masse and translated into an internal form. A common routine <<bfd_perform_relocation>> acts upon the canonical form to do the fixup. @@ -340,13 +340,26 @@ CODE_FRAGMENT . {* The textual name of the relocation type. *} . char *name; . -. {* When performing a partial link, some formats must modify the -. relocations rather than the data - this flag signals this.*} +. {* Some formats record a relocation addend in the section contents +. rather than with the relocation. For ELF formats this is the +. distinction between USE_REL and USE_RELA (though the code checks +. for USE_REL == 1/0). The value of this field is TRUE if the +. addend is recorded with the section contents; when performing a +. partial link (ld -r) the section contents (the data) will be +. modified. The value of this field is FALSE if addends are +. recorded with the relocation (in arelent.addend); when performing +. a partial link the relocation will be modified. +. All relocations for all ELF USE_RELA targets should set this field +. to FALSE (values of TRUE should be looked on with suspicion). +. However, the converse is not true: not all relocations of all ELF +. USE_REL targets set this field to TRUE. Why this is so is peculiar +. to each particular target. For relocs that aren't used in partial +. links (e.g. GOT stuff) it doesn't matter what this is set to. *} . boolean partial_inplace; . . {* The src_mask selects which parts of the read in data . are to be used in the relocation sum. E.g., if this was an 8 bit -. bit of data which we read and relocated, this would be +. byte of data which we read and relocated, this would be . 0x000000ff. When we have relocs which have an addend, such as . sun4 extended relocs, the value in the offset part of a . relocating field is garbage so we never use it. In this case @@ -389,6 +402,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. @@ -450,6 +471,8 @@ DESCRIPTION */ +/* N_ONES produces N one bits, without overflowing machine arithmetic. */ +#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1) /* FUNCTION @@ -461,28 +484,37 @@ SYNOPSIS (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. - The result is either of @code{bfd_reloc_ok} or - @code{bfd_reloc_overflow}. + 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, relocation) +bfd_check_overflow (how, bitsize, rightshift, addrsize, relocation) enum complain_overflow how; - unsigned int bitsize, rightshift; + unsigned int bitsize; + unsigned int rightshift; + unsigned int addrsize; bfd_vma relocation; { - bfd_vma check; + bfd_vma fieldmask, addrmask, signmask, ss, a; 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; + 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) { @@ -490,62 +522,32 @@ bfd_check_overflow (how, bitsize, rightshift, relocation) 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; - } + /* 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: - { - /* 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; - } + /* 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: - { - /* 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; - } - } + /* Bitfields are sometimes signed, sometimes unsigned. We + explicitly allow an address wrap too, which means a bitfield + of n bits is allowed to store -2**n to 2**n-1. Thus overflow + if the value has some, but not all, bits set outside the + field. */ + a >>= rightshift; + ss = a & ~ fieldmask; + if (ss != 0 && ss != (((bfd_vma) -1 >> rightshift) & ~ fieldmask)) + flag = bfd_reloc_overflow; break; default: @@ -555,7 +557,6 @@ bfd_check_overflow (how, bitsize, rightshift, relocation) return flag; } - /* FUNCTION bfd_perform_relocation @@ -601,7 +602,7 @@ 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; reloc_howto_type *howto = reloc_entry->howto; asection *reloc_target_output_section; @@ -637,7 +638,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 @@ -825,8 +827,11 @@ space consuming. For each target: adding in the value contained in the object file. */ if (howto->complain_on_overflow != complain_overflow_dont && flag == bfd_reloc_ok) - flag = bfd_check_overflow (howto->complain_on_overflow, howto->bitsize, - howto->rightshift, relocation); + 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 @@ -877,23 +882,23 @@ space consuming. For each target: 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 + (( 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 + = 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 + ( 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 + = B B B B B And then: - B B B B B - or A A A A A + ( 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> + = R R R R R R R R R R put into bfd_put<size> */ #define DOIT(x) \ @@ -903,41 +908,41 @@ space consuming. For each target: { case 0: { - char x = bfd_get_8 (abfd, (char *) data + addr); + char x = bfd_get_8 (abfd, (char *) data + octets); DOIT (x); - bfd_put_8 (abfd, x, (unsigned char *) data + addr); + bfd_put_8 (abfd, x, (unsigned char *) data + octets); } break; case 1: { - short x = bfd_get_16 (abfd, (bfd_byte *) data + addr); + short x = bfd_get_16 (abfd, (bfd_byte *) data + octets); DOIT (x); - bfd_put_16 (abfd, x, (unsigned char *) data + addr); + bfd_put_16 (abfd, x, (unsigned char *) data + octets); } break; case 2: { - long x = bfd_get_32 (abfd, (bfd_byte *) data + addr); + long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); DOIT (x); - bfd_put_32 (abfd, x, (bfd_byte *) data + addr); + bfd_put_32 (abfd, x, (bfd_byte *) data + octets); } break; case -2: { - long x = bfd_get_32 (abfd, (bfd_byte *) data + addr); + long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); relocation = -relocation; DOIT (x); - bfd_put_32 (abfd, x, (bfd_byte *) data + addr); + bfd_put_32 (abfd, x, (bfd_byte *) data + octets); } break; case -1: { - long x = bfd_get_16 (abfd, (bfd_byte *) data + addr); + long x = bfd_get_16 (abfd, (bfd_byte *) data + octets); relocation = -relocation; DOIT (x); - bfd_put_16 (abfd, x, (bfd_byte *) data + addr); + bfd_put_16 (abfd, x, (bfd_byte *) data + octets); } break; @@ -948,9 +953,9 @@ space consuming. For each target: case 4: #ifdef BFD64 { - bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + addr); + bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + octets); DOIT (x); - bfd_put_64 (abfd, x, (bfd_byte *) data + addr); + bfd_put_64 (abfd, x, (bfd_byte *) data + octets); } #else abort (); @@ -1000,7 +1005,7 @@ bfd_install_relocation (abfd, reloc_entry, data_start, data_start_offset, { 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; reloc_howto_type *howto = reloc_entry->howto; asection *reloc_target_output_section; @@ -1020,7 +1025,7 @@ bfd_install_relocation (abfd, reloc_entry, data_start, data_start_offset, if (howto->special_function) { bfd_reloc_status_type cont; - + /* XXX - The special_function calls haven't been fixed up to deal with creating new relocations and section contents. */ cont = howto->special_function (abfd, reloc_entry, symbol, @@ -1212,8 +1217,11 @@ space consuming. For each target: 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); + 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 @@ -1264,29 +1272,29 @@ space consuming. For each target: 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 + (( 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 + = 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 + ( 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 + = B B B B B And then: - B B B B B - or A A A A A + ( 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> + = 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); + data = (bfd_byte *) data_start + (octets - data_start_offset); switch (howto->size) { @@ -1416,8 +1424,10 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location) bfd_byte *location; { int size; - bfd_vma x; - boolean overflow; + bfd_vma x = 0; + bfd_reloc_status_type flag; + unsigned int rightshift = howto->rightshift; + unsigned int bitpos = howto->bitpos; /* If the size is negative, negate RELOCATION. This isn't very general. */ @@ -1453,117 +1463,124 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location) which we don't check for. We must either check at every single operation, which would be tedious, or we must do the computations in a type larger than bfd_vma, which would be inefficient. */ - overflow = false; + flag = bfd_reloc_ok; if (howto->complain_on_overflow != complain_overflow_dont) { - bfd_vma check; - bfd_signed_vma signed_check; - bfd_vma add; - bfd_signed_vma signed_add; - - if (howto->rightshift == 0) - { - check = relocation; - signed_check = (bfd_signed_vma) relocation; - } - else - { - /* Drop unwanted bits from the value we are relocating to. */ - check = relocation >> howto->rightshift; - - /* 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))); - } - - /* 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; - - /* 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))); - } + 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; 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; - } + 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)) + flag = bfd_reloc_overflow; + + /* 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; + + /* Set all the bits above the sign bit. */ + b = (b ^ signmask) - signmask; + + b = (b & addrmask) >> bitpos; + + /* Now we can do the addition. */ + sum = a + b; + + /* 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) + 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 (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) + 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 ((check & ~reloc_bits) != 0 - && (((bfd_vma) signed_check & ~reloc_bits) - != (-1 & ~reloc_bits))) - overflow = true; - } + /* Much like the signed check, but for a field one bit + wider, and no trimming inputs with addrmask. We allow a + bitfield to represent numbers in the range -2**n to + 2**n-1, where n is the number of bits in the field. + Note that when bfd_vma is 32 bits, a 32-bit reloc can't + overflow, which is exactly what we want. */ + a >>= rightshift; + + signmask = ~ fieldmask; + ss = a & signmask; + if (ss != 0 && ss != (((bfd_vma) -1 >> rightshift) & signmask)) + flag = bfd_reloc_overflow; + + signmask = ((~ howto->src_mask) >> 1) & howto->src_mask; + b = (b ^ signmask) - signmask; + + b >>= bitpos; + + sum = a + b; + + /* We mask with addrmask here to explicitly allow an address + wrap-around. 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. */ + signmask = fieldmask + 1; + if (((~ (a ^ b)) & (a ^ sum)) & signmask & addrmask) + flag = bfd_reloc_overflow; + 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) @@ -1593,7 +1610,7 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location) break; } - return overflow ? bfd_reloc_overflow : bfd_reloc_ok; + return flag; } /* @@ -1866,6 +1883,11 @@ 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 @@ -1923,6 +1945,25 @@ ENUMDOC 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 !<reloc>!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 @@ -2007,6 +2048,14 @@ 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. @@ -2060,6 +2109,21 @@ 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 @@ -2123,6 +2187,11 @@ ENUMDOC Power(rs6000) and PowerPC relocations. ENUM + BFD_RELOC_I370_D12 +ENUMDOC + IBM 370/390 relocations + +ENUM BFD_RELOC_CTOR ENUMDOC The type of reloc used to build a contructor table - at the moment @@ -2137,6 +2206,8 @@ ENUMDOC ENUM BFD_RELOC_ARM_IMMEDIATE ENUMX + BFD_RELOC_ARM_ADRL_IMMEDIATE +ENUMX BFD_RELOC_ARM_OFFSET_IMM ENUMX BFD_RELOC_ARM_SHIFT_IMM @@ -2166,6 +2237,24 @@ 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. @@ -2233,7 +2322,6 @@ ENUMDOC stored in the instruction. The high 24 bits are installed in bits 23 through 0. -COMMENT ENUM BFD_RELOC_D10V_10_PCREL_R ENUMDOC @@ -2258,9 +2346,66 @@ ENUM ENUMDOC This is an 18-bit reloc with the right 2 bits assumed to be 0. -COMMENT -COMMENT +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 @@ -2345,6 +2490,34 @@ ENUM 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 @@ -2364,6 +2537,169 @@ ENUMDOC 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_AVR_7_PCREL +ENUMDOC + This is a 16 bit reloc for the AVR that stores 8 bit pc relative + short offset into 7 bits. +ENUM + BFD_RELOC_AVR_13_PCREL +ENUMDOC + This is a 16 bit reloc for the AVR that stores 13 bit pc relative + short offset into 12 bits. +ENUM + BFD_RELOC_AVR_16_PM +ENUMDOC + This is a 16 bit reloc for the AVR that stores 17 bit value (usually + program memory address) into 16 bits. +ENUM + BFD_RELOC_AVR_LO8_LDI +ENUMDOC + This is a 16 bit reloc for the AVR that stores 8 bit value (usually + data memory address) into 8 bit immediate value of LDI insn. +ENUM + BFD_RELOC_AVR_HI8_LDI +ENUMDOC + This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit + of data memory address) into 8 bit immediate value of LDI insn. +ENUM + BFD_RELOC_AVR_HH8_LDI +ENUMDOC + This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit + of program memory address) into 8 bit immediate value of LDI insn. +ENUM + BFD_RELOC_AVR_LO8_LDI_NEG +ENUMDOC + This is a 16 bit reloc for the AVR that stores negated 8 bit value + (usually data memory address) into 8 bit immediate value of SUBI insn. +ENUM + BFD_RELOC_AVR_HI8_LDI_NEG +ENUMDOC + This is a 16 bit reloc for the AVR that stores negated 8 bit value + (high 8 bit of data memory address) into 8 bit immediate value of + SUBI insn. +ENUM + BFD_RELOC_AVR_HH8_LDI_NEG +ENUMDOC + This is a 16 bit reloc for the AVR that stores negated 8 bit value + (most high 8 bit of program memory address) into 8 bit immediate value + of LDI or SUBI insn. +ENUM + BFD_RELOC_AVR_LO8_LDI_PM +ENUMDOC + This is a 16 bit reloc for the AVR that stores 8 bit value (usually + command address) into 8 bit immediate value of LDI insn. +ENUM + BFD_RELOC_AVR_HI8_LDI_PM +ENUMDOC + This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit + of command address) into 8 bit immediate value of LDI insn. +ENUM + BFD_RELOC_AVR_HH8_LDI_PM +ENUMDOC + This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit + of command address) into 8 bit immediate value of LDI insn. +ENUM + BFD_RELOC_AVR_LO8_LDI_PM_NEG +ENUMDOC + This is a 16 bit reloc for the AVR that stores negated 8 bit value + (usually command address) into 8 bit immediate value of SUBI insn. +ENUM + BFD_RELOC_AVR_HI8_LDI_PM_NEG +ENUMDOC + This is a 16 bit reloc for the AVR that stores negated 8 bit value + (high 8 bit of 16 bit command address) into 8 bit immediate value + of SUBI insn. +ENUM + BFD_RELOC_AVR_HH8_LDI_PM_NEG +ENUMDOC + This is a 16 bit reloc for the AVR that stores negated 8 bit value + (high 6 bit of 22 bit command address) into 8 bit immediate + value of SUBI insn. +ENUM + BFD_RELOC_AVR_CALL +ENUMDOC + This is a 32 bit reloc for the AVR that stores 23 bit value + into 22 bits. + +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 @@ -2481,9 +2817,9 @@ 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; @@ -2492,6 +2828,28 @@ bfd_generic_relax_section (abfd, section, link_info, again) /* 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 SYNOPSIS @@ -2584,7 +2942,8 @@ bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data, case bfd_reloc_undefined: if (!((*link_info->callbacks->undefined_symbol) (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - input_bfd, input_section, (*parent)->address))) + input_bfd, input_section, (*parent)->address, + true))) goto error_return; break; case bfd_reloc_dangerous: |