X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Freloc.c;h=f5df8e2ab3eb4ff618fe5a92a3af60820d249869;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=f7e34a993aef31faabb2bcf463e1f9e51d1ece69;hpb=5c5a4843ec385a60954fbbc4bcf5b64763639bd3;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/reloc.c b/bfd/reloc.c index f7e34a993a..f5df8e2ab3 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -1,5 +1,5 @@ /* BFD support for handling relocation entries. - Copyright (C) 1990-2018 Free Software Foundation, Inc. + Copyright (C) 1990-2020 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -94,6 +94,7 @@ CODE_FRAGMENT . } . bfd_reloc_status_type; . +.typedef const struct reloc_howto_struct reloc_howto_type; . .typedef struct reloc_cache_entry .{ @@ -279,51 +280,39 @@ SUBSUBSECTION information that libbfd needs to know to tie up a back end's data. CODE_FRAGMENT -.struct bfd_symbol; {* Forward declaration. *} -. .struct reloc_howto_struct .{ -. {* 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 -. in a coff environment has the type 023 - because that's -. what the outside world calls a R_PCRWORD reloc. *} +. {* The type field has mainly a documentary use - the back end can +. do what it wants with it, though normally the back end's idea of +. an external reloc number is stored in this field. *} . unsigned int type; . -. {* The value the final relocation is shifted right by. This drops -. unwanted data from the relocation. *} -. unsigned int rightshift; -. -. {* The size of the item to be relocated. This is *not* a -. power-of-two measure. To get the number of bytes operated -. on by a type of relocation, use bfd_get_reloc_size. *} -. int size; +. {* The encoded size of the item to be relocated. This is *not* a +. power-of-two measure. Use bfd_get_reloc_size to find the size +. of the item in bytes. *} +. unsigned int size:3; . -. {* The number of bits in the item to be relocated. This is used -. when doing overflow checking. *} -. unsigned int bitsize; +. {* The number of bits in the field to be relocated. This is used +. when doing overflow checking. *} +. unsigned int bitsize:7; . -. {* The relocation is relative to the field being relocated. *} -. bfd_boolean pc_relative; +. {* The value the final relocation is shifted right by. This drops +. unwanted data from the relocation. *} +. unsigned int rightshift:6; . -. {* The bit position of the reloc value in the destination. -. The relocated value is left shifted by this amount. *} -. unsigned int bitpos; +. {* The bit position of the reloc value in the destination. +. The relocated value is left shifted by this amount. *} +. unsigned int bitpos:6; . . {* What type of overflow error should be checked for when . relocating. *} -. enum complain_overflow complain_on_overflow; +. ENUM_BITFIELD (complain_overflow) complain_on_overflow:2; . -. {* If this field is non null, then the supplied function is -. called rather than the normal function. This allows really -. strange relocation methods to be accommodated. *} -. bfd_reloc_status_type (*special_function) -. (bfd *, arelent *, struct bfd_symbol *, void *, asection *, -. bfd *, char **); +. {* The relocation value should be negated before applying. *} +. unsigned int negate:1; . -. {* The textual name of the relocation type. *} -. char *name; +. {* The relocation is relative to the item being relocated. *} +. unsigned int pc_relative:1; . . {* Some formats record a relocation addend in the section contents . rather than with the relocation. For ELF formats this is the @@ -340,29 +329,39 @@ CODE_FRAGMENT . 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. *} -. bfd_boolean partial_inplace; +. unsigned int partial_inplace:1; +. +. {* When some formats create PC relative instructions, they leave +. the value of the pc of the place being relocated in the offset +. slot of the instruction, so that a PC relative relocation can +. be made just by adding in an ordinary offset (e.g., sun3 a.out). +. Some formats leave the displacement part of an instruction +. empty (e.g., ELF); this flag signals the fact. *} +. unsigned int pcrel_offset:1; . . {* src_mask selects the part of the instruction (or data) to be used . in the relocation sum. If the target relocations don't have an . addend in the reloc, eg. ELF USE_REL, src_mask will normally equal . dst_mask to extract the addend from the section contents. If . relocations do have an addend in the reloc, eg. ELF USE_RELA, this -. field should be zero. Non-zero values for ELF USE_RELA targets are -. bogus as in those cases the value in the dst_mask part of the -. section contents should be treated as garbage. *} +. field should normally be zero. Non-zero values for ELF USE_RELA +. targets should be viewed with suspicion as normally the value in +. the dst_mask part of the section contents should be ignored. *} . bfd_vma src_mask; . . {* dst_mask selects which parts of the instruction (or data) are . replaced with a relocated value. *} . bfd_vma dst_mask; . -. {* When some formats create PC relative instructions, they leave -. the value of the pc of the place being relocated in the offset -. slot of the instruction, so that a PC relative relocation can -. be made just by adding in an ordinary offset (e.g., sun3 a.out). -. Some formats leave the displacement part of an instruction -. empty (e.g., ELF); this flag signals the fact. *} -. bfd_boolean pcrel_offset; +. {* If this field is non null, then the supplied function is +. called rather than the normal function. This allows really +. strange relocation methods to be accommodated. *} +. bfd_reloc_status_type (*special_function) +. (bfd *, arelent *, struct bfd_symbol *, void *, asection *, +. bfd *, char **); +. +. {* The textual name of the relocation type. *} +. const char *name; .}; . */ @@ -372,19 +371,13 @@ FUNCTION The HOWTO Macro DESCRIPTION - The HOWTO define is horrible and will go away. + The HOWTO macro fills in a reloc_howto_type (a typedef for + const struct reloc_howto_struct). -.#define HOWTO(C, R, S, B, P, BI, O, SF, 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 - moment, we are compatible, so do it this way. - -.#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \ -. HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \ -. NAME, FALSE, 0, 0, IN) -. +.#define HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \ +. inplace, src_mask, dst_mask, pcrel_off) \ +. { (unsigned) type, size < 0 ? -size : size, bits, right, left, ovf, \ +. size < 0, pcrel, inplace, pcrel_off, src_mask, dst_mask, func, name } DESCRIPTION This is used to fill in an empty howto entry in an array. @@ -393,25 +386,6 @@ DESCRIPTION . 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. - -.#define HOWTO_PREPARE(relocation, symbol) \ -. { \ -. if (symbol != NULL) \ -. { \ -. if (bfd_is_com_section (symbol->section)) \ -. { \ -. relocation = 0; \ -. } \ -. else \ -. { \ -. relocation = symbol->value; \ -. } \ -. } \ -. } -. */ /* @@ -436,9 +410,7 @@ bfd_get_reloc_size (reloc_howto_type *howto) case 2: return 4; case 3: return 0; case 4: return 8; - case 8: return 16; - case -1: return 2; - case -2: return 4; + case 5: return 3; default: abort (); } } @@ -573,6 +545,96 @@ bfd_reloc_offset_in_range (reloc_howto_type *howto, return octet <= octet_end && octet + reloc_size <= octet_end; } +/* Read and return the section contents at DATA converted to a host + integer (bfd_vma). The number of bytes read is given by the HOWTO. */ + +static bfd_vma +read_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto) +{ + switch (howto->size) + { + case 0: + return bfd_get_8 (abfd, data); + + case 1: + return bfd_get_16 (abfd, data); + + case 2: + return bfd_get_32 (abfd, data); + + case 3: + break; + +#ifdef BFD64 + case 4: + return bfd_get_64 (abfd, data); +#endif + + case 5: + return bfd_get_24 (abfd, data); + + default: + abort (); + } + return 0; +} + +/* Convert VAL to target format and write to DATA. The number of + bytes written is given by the HOWTO. */ + +static void +write_reloc (bfd *abfd, bfd_vma val, bfd_byte *data, reloc_howto_type *howto) +{ + switch (howto->size) + { + case 0: + bfd_put_8 (abfd, val, data); + break; + + case 1: + bfd_put_16 (abfd, val, data); + break; + + case 2: + bfd_put_32 (abfd, val, data); + break; + + case 3: + break; + +#ifdef BFD64 + case 4: + bfd_put_64 (abfd, val, data); + break; +#endif + + case 5: + bfd_put_24 (abfd, val, data); + break; + + default: + abort (); + } +} + +/* Apply RELOCATION value to target bytes at DATA, according to + HOWTO. */ + +static void +apply_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto, + bfd_vma relocation) +{ + bfd_vma val = read_reloc (abfd, data, howto); + + if (howto->negate) + relocation = -relocation; + + val = ((val & ~howto->dst_mask) + | (((val & howto->src_mask) + relocation) & howto->dst_mask)); + + write_reloc (abfd, val, data, howto); +} + /* FUNCTION bfd_perform_relocation @@ -660,7 +722,7 @@ bfd_perform_relocation (bfd *abfd, return bfd_reloc_undefined; /* Is the address of the relocation really within the section? */ - octets = reloc_entry->address * bfd_octets_per_byte (abfd); + octets = reloc_entry->address * bfd_octets_per_byte (abfd, input_section); if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets)) return bfd_reloc_outofrange; @@ -682,7 +744,14 @@ bfd_perform_relocation (bfd *abfd, else output_base = reloc_target_output_section->vma; - relocation += output_base + symbol->section->output_offset; + output_base += symbol->section->output_offset; + + /* If symbol addresses are in octets, convert to bytes. */ + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour + && (symbol->section->flags & SEC_ELF_OCTETS)) + output_base *= bfd_octets_per_byte (abfd, input_section); + + relocation += output_base; /* Add in supplied addend. */ relocation += reloc_entry->addend; @@ -912,70 +981,8 @@ space consuming. For each target: = 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, (bfd_vma) x, (unsigned char *) data + octets); - } - break; - case 2: - { - long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); - DOIT (x); - bfd_put_32 (abfd, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 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; - } - + data = (bfd_byte *) data + octets; + apply_reloc (abfd, data, howto, relocation); return flag; } @@ -1052,7 +1059,7 @@ bfd_install_relocation (bfd *abfd, it will have been checked in `bfd_perform_relocation already'. */ /* Is the address of the relocation really within the section? */ - octets = reloc_entry->address * bfd_octets_per_byte (abfd); + octets = reloc_entry->address * bfd_octets_per_byte (abfd, input_section); if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets)) return bfd_reloc_outofrange; @@ -1073,7 +1080,14 @@ bfd_install_relocation (bfd *abfd, else output_base = reloc_target_output_section->vma; - relocation += output_base + symbol->section->output_offset; + output_base += symbol->section->output_offset; + + /* If symbol addresses are in octets, convert to bytes. */ + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour + && (symbol->section->flags & SEC_ELF_OCTETS)) + output_base *= bfd_octets_per_byte (abfd, input_section); + + relocation += output_base; /* Add in supplied addend. */ relocation += reloc_entry->addend; @@ -1300,59 +1314,8 @@ space consuming. For each target: = 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)) - data = (bfd_byte *) data_start + (octets - data_start_offset); - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, data); - DOIT (x); - bfd_put_8 (abfd, x, data); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, data); - DOIT (x); - bfd_put_16 (abfd, (bfd_vma) x, data); - } - break; - case 2: - { - long x = bfd_get_32 (abfd, data); - DOIT (x); - bfd_put_32 (abfd, (bfd_vma) x, data); - } - break; - case -2: - { - long x = bfd_get_32 (abfd, data); - relocation = -relocation; - DOIT (x); - bfd_put_32 (abfd, (bfd_vma) x, data); - } - break; - - case 3: - /* Do nothing */ - break; - - case 4: - { - bfd_vma x = bfd_get_64 (abfd, data); - DOIT (x); - bfd_put_64 (abfd, x, data); - } - break; - default: - return bfd_reloc_other; - } - + apply_reloc (abfd, data, howto, relocation); return flag; } @@ -1388,7 +1351,8 @@ _bfd_final_link_relocate (reloc_howto_type *howto, bfd_vma addend) { bfd_vma relocation; - bfd_size_type octets = address * bfd_octets_per_byte (input_bfd); + bfd_size_type octets = (address + * bfd_octets_per_byte (input_bfd, input_section)); /* Sanity check the address. */ if (!bfd_reloc_offset_in_range (howto, input_bfd, input_section, octets)) @@ -1419,8 +1383,7 @@ _bfd_final_link_relocate (reloc_howto_type *howto, } return _bfd_relocate_contents (howto, input_bfd, relocation, - contents - + address * bfd_octets_per_byte (input_bfd)); + contents + octets); } /* Relocate a given location using a given value and howto. */ @@ -1431,42 +1394,16 @@ _bfd_relocate_contents (reloc_howto_type *howto, bfd_vma relocation, bfd_byte *location) { - int size; - bfd_vma x = 0; + bfd_vma x; 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. */ - if (howto->size < 0) + if (howto->negate) relocation = -relocation; /* Get the value we are going to relocate. */ - size = bfd_get_reloc_size (howto); - switch (size) - { - default: - abort (); - case 0: - return bfd_reloc_ok; - case 1: - x = bfd_get_8 (input_bfd, location); - break; - case 2: - x = bfd_get_16 (input_bfd, location); - break; - case 4: - x = bfd_get_32 (input_bfd, location); - break; - case 8: -#ifdef BFD64 - x = bfd_get_64 (input_bfd, location); -#else - abort (); -#endif - break; - } + x = read_reloc (input_bfd, location, howto); /* Check for overflow. FIXME: We may drop bits during the addition which we don't check for. We must either check at every single @@ -1572,28 +1509,7 @@ _bfd_relocate_contents (reloc_howto_type *howto, | (((x & howto->src_mask) + relocation) & howto->dst_mask)); /* Put the relocated value back in the object file. */ - switch (size) - { - default: - abort (); - case 1: - bfd_put_8 (input_bfd, x, location); - break; - case 2: - bfd_put_16 (input_bfd, x, location); - break; - case 4: - bfd_put_32 (input_bfd, x, location); - break; - case 8: -#ifdef BFD64 - bfd_put_64 (input_bfd, x, location); -#else - abort (); -#endif - break; - } - + write_reloc (input_bfd, x, location, howto); return flag; } @@ -1602,74 +1518,35 @@ _bfd_relocate_contents (reloc_howto_type *howto, relocations against discarded symbols, to make ignorable debug or unwind information more obvious. */ -void +bfd_reloc_status_type _bfd_clear_contents (reloc_howto_type *howto, bfd *input_bfd, asection *input_section, - bfd_byte *location) + bfd_byte *buf, + bfd_vma off) { - int size; - bfd_vma x = 0; + bfd_vma x; + bfd_byte *location; + + if (!bfd_reloc_offset_in_range (howto, input_bfd, input_section, off)) + return bfd_reloc_outofrange; /* Get the value we are going to relocate. */ - size = bfd_get_reloc_size (howto); - switch (size) - { - default: - abort (); - case 0: - return; - case 1: - x = bfd_get_8 (input_bfd, location); - break; - case 2: - x = bfd_get_16 (input_bfd, location); - break; - case 4: - x = bfd_get_32 (input_bfd, location); - break; - case 8: -#ifdef BFD64 - x = bfd_get_64 (input_bfd, location); -#else - abort (); -#endif - break; - } + location = buf + off; + x = read_reloc (input_bfd, location, howto); /* Zero out the unwanted bits of X. */ x &= ~howto->dst_mask; /* For a range list, use 1 instead of 0 as placeholder. 0 would terminate the list, hiding any later entries. */ - if (strcmp (bfd_get_section_name (input_bfd, input_section), - ".debug_ranges") == 0 + if (strcmp (bfd_section_name (input_section), ".debug_ranges") == 0 && (howto->dst_mask & 1) != 0) x |= 1; /* Put the relocated value back in the object file. */ - switch (size) - { - default: - case 0: - abort (); - case 1: - bfd_put_8 (input_bfd, x, location); - break; - case 2: - bfd_put_16 (input_bfd, x, location); - break; - case 4: - bfd_put_32 (input_bfd, x, location); - break; - case 8: -#ifdef BFD64 - bfd_put_64 (input_bfd, x, location); -#else - abort (); -#endif - break; - } + write_reloc (input_bfd, x, location, howto); + return bfd_reloc_ok; } /* @@ -2996,10 +2873,58 @@ ENUMX BFD_RELOC_PPC64_ADDR16_HIGH ENUMX BFD_RELOC_PPC64_ADDR16_HIGHA +ENUMX + BFD_RELOC_PPC64_REL16_HIGH +ENUMX + BFD_RELOC_PPC64_REL16_HIGHA +ENUMX + BFD_RELOC_PPC64_REL16_HIGHER +ENUMX + BFD_RELOC_PPC64_REL16_HIGHERA +ENUMX + BFD_RELOC_PPC64_REL16_HIGHEST +ENUMX + BFD_RELOC_PPC64_REL16_HIGHESTA ENUMX BFD_RELOC_PPC64_ADDR64_LOCAL ENUMX BFD_RELOC_PPC64_ENTRY +ENUMX + BFD_RELOC_PPC64_REL24_NOTOC +ENUMX + BFD_RELOC_PPC64_D34 +ENUMX + BFD_RELOC_PPC64_D34_LO +ENUMX + BFD_RELOC_PPC64_D34_HI30 +ENUMX + BFD_RELOC_PPC64_D34_HA30 +ENUMX + BFD_RELOC_PPC64_PCREL34 +ENUMX + BFD_RELOC_PPC64_GOT_PCREL34 +ENUMX + BFD_RELOC_PPC64_PLT_PCREL34 +ENUMX + BFD_RELOC_PPC64_ADDR16_HIGHER34 +ENUMX + BFD_RELOC_PPC64_ADDR16_HIGHERA34 +ENUMX + BFD_RELOC_PPC64_ADDR16_HIGHEST34 +ENUMX + BFD_RELOC_PPC64_ADDR16_HIGHESTA34 +ENUMX + BFD_RELOC_PPC64_REL16_HIGHER34 +ENUMX + BFD_RELOC_PPC64_REL16_HIGHERA34 +ENUMX + BFD_RELOC_PPC64_REL16_HIGHEST34 +ENUMX + BFD_RELOC_PPC64_REL16_HIGHESTA34 +ENUMX + BFD_RELOC_PPC64_D28 +ENUMX + BFD_RELOC_PPC64_PCREL28 ENUMDOC Power(rs6000) and PowerPC relocations. @@ -3067,6 +2992,10 @@ ENUMX BFD_RELOC_PPC64_TPREL16_DS ENUMX BFD_RELOC_PPC64_TPREL16_LO_DS +ENUMX + BFD_RELOC_PPC64_TPREL16_HIGH +ENUMX + BFD_RELOC_PPC64_TPREL16_HIGHA ENUMX BFD_RELOC_PPC64_TPREL16_HIGHER ENUMX @@ -3079,6 +3008,10 @@ ENUMX BFD_RELOC_PPC64_DTPREL16_DS ENUMX BFD_RELOC_PPC64_DTPREL16_LO_DS +ENUMX + BFD_RELOC_PPC64_DTPREL16_HIGH +ENUMX + BFD_RELOC_PPC64_DTPREL16_HIGHA ENUMX BFD_RELOC_PPC64_DTPREL16_HIGHER ENUMX @@ -3088,13 +3021,19 @@ ENUMX ENUMX BFD_RELOC_PPC64_DTPREL16_HIGHESTA ENUMX - BFD_RELOC_PPC64_TPREL16_HIGH + BFD_RELOC_PPC64_TPREL34 ENUMX - BFD_RELOC_PPC64_TPREL16_HIGHA + BFD_RELOC_PPC64_DTPREL34 ENUMX - BFD_RELOC_PPC64_DTPREL16_HIGH + BFD_RELOC_PPC64_GOT_TLSGD34 ENUMX - BFD_RELOC_PPC64_DTPREL16_HIGHA + BFD_RELOC_PPC64_GOT_TLSLD34 +ENUMX + BFD_RELOC_PPC64_GOT_TPREL34 +ENUMX + BFD_RELOC_PPC64_GOT_DTPREL34 +ENUMX + BFD_RELOC_PPC64_TLS_PCREL ENUMDOC PowerPC and PowerPC64 thread-local storage relocations. @@ -3136,6 +3075,36 @@ ENUM ENUMDOC ARM 26-bit pc-relative branch for B or conditional BL instruction. +ENUM + BFD_RELOC_THUMB_PCREL_BRANCH5 +ENUMDOC + ARM 5-bit pc-relative branch for Branch Future instructions. + +ENUM + BFD_RELOC_THUMB_PCREL_BFCSEL +ENUMDOC + ARM 6-bit pc-relative branch for BFCSEL instruction. + +ENUM + BFD_RELOC_ARM_THUMB_BF17 +ENUMDOC + ARM 17-bit pc-relative branch for Branch Future instructions. + +ENUM + BFD_RELOC_ARM_THUMB_BF13 +ENUMDOC + ARM 13-bit pc-relative branch for BFCSEL instruction. + +ENUM + BFD_RELOC_ARM_THUMB_BF19 +ENUMDOC + ARM 19-bit pc-relative branch for Branch Future Link instruction. + +ENUM + BFD_RELOC_ARM_THUMB_LOOP12 +ENUMDOC + ARM 12-bit pc-relative branch for Low Overhead Loop instructions. + ENUM BFD_RELOC_THUMB_PCREL_BRANCH7 ENUMX @@ -3384,6 +3353,8 @@ ENUMX BFD_RELOC_ARM_T32_CP_OFF_IMM ENUMX BFD_RELOC_ARM_T32_CP_OFF_IMM_S2 +ENUMX + BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM ENUMX BFD_RELOC_ARM_ADR_IMM ENUMX @@ -4382,32 +4353,66 @@ ENUMDOC For ex9 and ifc using. ENUM BFD_RELOC_NDS32_TPOFF +ENUMX + BFD_RELOC_NDS32_GOTTPOFF ENUMX BFD_RELOC_NDS32_TLS_LE_HI20 ENUMX BFD_RELOC_NDS32_TLS_LE_LO12 +ENUMX + BFD_RELOC_NDS32_TLS_LE_20 +ENUMX + BFD_RELOC_NDS32_TLS_LE_15S0 +ENUMX + BFD_RELOC_NDS32_TLS_LE_15S1 +ENUMX + BFD_RELOC_NDS32_TLS_LE_15S2 ENUMX BFD_RELOC_NDS32_TLS_LE_ADD ENUMX BFD_RELOC_NDS32_TLS_LE_LS -ENUMX - BFD_RELOC_NDS32_GOTTPOFF ENUMX BFD_RELOC_NDS32_TLS_IE_HI20 +ENUMX + BFD_RELOC_NDS32_TLS_IE_LO12 ENUMX BFD_RELOC_NDS32_TLS_IE_LO12S2 ENUMX - BFD_RELOC_NDS32_TLS_TPOFF + BFD_RELOC_NDS32_TLS_IEGP_HI20 ENUMX - BFD_RELOC_NDS32_TLS_LE_20 + BFD_RELOC_NDS32_TLS_IEGP_LO12 ENUMX - BFD_RELOC_NDS32_TLS_LE_15S0 + BFD_RELOC_NDS32_TLS_IEGP_LO12S2 ENUMX - BFD_RELOC_NDS32_TLS_LE_15S1 + BFD_RELOC_NDS32_TLS_IEGP_LW ENUMX - BFD_RELOC_NDS32_TLS_LE_15S2 + BFD_RELOC_NDS32_TLS_DESC +ENUMX + BFD_RELOC_NDS32_TLS_DESC_HI20 +ENUMX + BFD_RELOC_NDS32_TLS_DESC_LO12 +ENUMX + BFD_RELOC_NDS32_TLS_DESC_20 +ENUMX + BFD_RELOC_NDS32_TLS_DESC_SDA17S2 +ENUMX + BFD_RELOC_NDS32_TLS_DESC_ADD +ENUMX + BFD_RELOC_NDS32_TLS_DESC_FUNC +ENUMX + BFD_RELOC_NDS32_TLS_DESC_CALL +ENUMX + BFD_RELOC_NDS32_TLS_DESC_MEM +ENUMX + BFD_RELOC_NDS32_REMOVE +ENUMX + BFD_RELOC_NDS32_GROUP ENUMDOC For TLS. +ENUM + BFD_RELOC_NDS32_LSI +ENUMDOC + For floating load store relaxation. ENUM @@ -5949,87 +5954,11 @@ ENUMDOC This is the 8 bit high part of an absolute address and immediately follows a matching LO8XG part. ENUM - BFD_RELOC_16C_NUM08 -ENUMX - BFD_RELOC_16C_NUM08_C -ENUMX - BFD_RELOC_16C_NUM16 -ENUMX - BFD_RELOC_16C_NUM16_C -ENUMX - BFD_RELOC_16C_NUM32 -ENUMX - BFD_RELOC_16C_NUM32_C -ENUMX - BFD_RELOC_16C_DISP04 -ENUMX - BFD_RELOC_16C_DISP04_C -ENUMX - BFD_RELOC_16C_DISP08 -ENUMX - BFD_RELOC_16C_DISP08_C -ENUMX - BFD_RELOC_16C_DISP16 -ENUMX - BFD_RELOC_16C_DISP16_C -ENUMX - BFD_RELOC_16C_DISP24 -ENUMX - BFD_RELOC_16C_DISP24_C -ENUMX - BFD_RELOC_16C_DISP24a -ENUMX - BFD_RELOC_16C_DISP24a_C -ENUMX - BFD_RELOC_16C_REG04 -ENUMX - BFD_RELOC_16C_REG04_C -ENUMX - BFD_RELOC_16C_REG04a -ENUMX - BFD_RELOC_16C_REG04a_C -ENUMX - BFD_RELOC_16C_REG14 -ENUMX - BFD_RELOC_16C_REG14_C -ENUMX - BFD_RELOC_16C_REG16 -ENUMX - BFD_RELOC_16C_REG16_C -ENUMX - BFD_RELOC_16C_REG20 -ENUMX - BFD_RELOC_16C_REG20_C -ENUMX - BFD_RELOC_16C_ABS20 -ENUMX - BFD_RELOC_16C_ABS20_C -ENUMX - BFD_RELOC_16C_ABS24 -ENUMX - BFD_RELOC_16C_ABS24_C -ENUMX - BFD_RELOC_16C_IMM04 -ENUMX - BFD_RELOC_16C_IMM04_C -ENUMX - BFD_RELOC_16C_IMM16 -ENUMX - BFD_RELOC_16C_IMM16_C -ENUMX - BFD_RELOC_16C_IMM20 -ENUMX - BFD_RELOC_16C_IMM20_C -ENUMX - BFD_RELOC_16C_IMM24 -ENUMX - BFD_RELOC_16C_IMM24_C -ENUMX - BFD_RELOC_16C_IMM32 -ENUMX - BFD_RELOC_16C_IMM32_C + BFD_RELOC_S12Z_15_PCREL ENUMDOC - NS CR16C Relocations. + Freescale S12Z reloc. + This is a 15 bit relative address. If the most significant bits are all zero + then it may be truncated to 8 bits. ENUM BFD_RELOC_CR16_NUM8 @@ -6234,18 +6163,30 @@ ENUMDOC ENUM BFD_RELOC_OR1K_REL_26 +ENUMX + BFD_RELOC_OR1K_SLO16 +ENUMX + BFD_RELOC_OR1K_PCREL_PG21 +ENUMX + BFD_RELOC_OR1K_LO13 +ENUMX + BFD_RELOC_OR1K_SLO13 ENUMX BFD_RELOC_OR1K_GOTPC_HI16 ENUMX BFD_RELOC_OR1K_GOTPC_LO16 ENUMX BFD_RELOC_OR1K_GOT16 +ENUMX + BFD_RELOC_OR1K_GOT_PG21 +ENUMX + BFD_RELOC_OR1K_GOT_LO13 ENUMX BFD_RELOC_OR1K_PLT26 ENUMX - BFD_RELOC_OR1K_GOTOFF_HI16 + BFD_RELOC_OR1K_PLTA26 ENUMX - BFD_RELOC_OR1K_GOTOFF_LO16 + BFD_RELOC_OR1K_GOTOFF_SLO16 ENUMX BFD_RELOC_OR1K_COPY ENUMX @@ -6258,22 +6199,40 @@ ENUMX BFD_RELOC_OR1K_TLS_GD_HI16 ENUMX BFD_RELOC_OR1K_TLS_GD_LO16 +ENUMX + BFD_RELOC_OR1K_TLS_GD_PG21 +ENUMX + BFD_RELOC_OR1K_TLS_GD_LO13 ENUMX BFD_RELOC_OR1K_TLS_LDM_HI16 ENUMX BFD_RELOC_OR1K_TLS_LDM_LO16 +ENUMX + BFD_RELOC_OR1K_TLS_LDM_PG21 +ENUMX + BFD_RELOC_OR1K_TLS_LDM_LO13 ENUMX BFD_RELOC_OR1K_TLS_LDO_HI16 ENUMX BFD_RELOC_OR1K_TLS_LDO_LO16 ENUMX BFD_RELOC_OR1K_TLS_IE_HI16 +ENUMX + BFD_RELOC_OR1K_TLS_IE_AHI16 ENUMX BFD_RELOC_OR1K_TLS_IE_LO16 +ENUMX + BFD_RELOC_OR1K_TLS_IE_PG21 +ENUMX + BFD_RELOC_OR1K_TLS_IE_LO13 ENUMX BFD_RELOC_OR1K_TLS_LE_HI16 +ENUMX + BFD_RELOC_OR1K_TLS_LE_AHI16 ENUMX BFD_RELOC_OR1K_TLS_LE_LO16 +ENUMX + BFD_RELOC_OR1K_TLS_LE_SLO16 ENUMX BFD_RELOC_OR1K_TLS_TPOFF ENUMX @@ -6597,6 +6556,8 @@ ENUMX ENUMX BFD_RELOC_XTENSA_DIFF32 ENUMDOC + Xtensa relocations for backward compatibility. These have been replaced + by BFD_RELOC_XTENSA_PDIFF and BFD_RELOC_XTENSA_NDIFF. Xtensa relocations to mark the difference of two local symbols. These are only needed to support linker relaxation and can be ignored when not relaxing. The field is set to the value of the difference @@ -6709,11 +6670,61 @@ ENUMX BFD_RELOC_XTENSA_TLS_CALL ENUMDOC Xtensa TLS relocations. +ENUM + BFD_RELOC_XTENSA_PDIFF8 +ENUMX + BFD_RELOC_XTENSA_PDIFF16 +ENUMX + BFD_RELOC_XTENSA_PDIFF32 +ENUMX + BFD_RELOC_XTENSA_NDIFF8 +ENUMX + BFD_RELOC_XTENSA_NDIFF16 +ENUMX + BFD_RELOC_XTENSA_NDIFF32 +ENUMDOC + Xtensa relocations to mark the difference of two local symbols. + These are only needed to support linker relaxation and can be ignored + when not relaxing. The field is set to the value of the difference + assuming no relaxation. The relocation encodes the position of the + subtracted symbol so the linker can determine whether to adjust the field + value. PDIFF relocations are used for positive differences, NDIFF + relocations are used for negative differences. The difference value + is treated as unsigned with these relocation types, giving full + 8/16 value ranges. ENUM BFD_RELOC_Z80_DISP8 ENUMDOC 8 bit signed offset in (ix+d) or (iy+d). +ENUM + BFD_RELOC_Z80_BYTE0 +ENUMDOC + First 8 bits of multibyte (32, 24 or 16 bit) value. +ENUM + BFD_RELOC_Z80_BYTE1 +ENUMDOC + Second 8 bits of multibyte (32, 24 or 16 bit) value. +ENUM + BFD_RELOC_Z80_BYTE2 +ENUMDOC + Third 8 bits of multibyte (32 or 24 bit) value. +ENUM + BFD_RELOC_Z80_BYTE3 +ENUMDOC + Fourth 8 bits of multibyte (32 bit) value. +ENUM + BFD_RELOC_Z80_WORD0 +ENUMDOC + Lowest 16 bits of multibyte (32 or 24 bit) value. +ENUM + BFD_RELOC_Z80_WORD1 +ENUMDOC + Highest 16 bits of multibyte (32 or 24 bit) value. +ENUM + BFD_RELOC_Z80_16_BE +ENUMDOC + Like BFD_RELOC_16 but big-endian. ENUM BFD_RELOC_Z8K_DISP7 @@ -6799,6 +6810,10 @@ ENUM BFD_RELOC_MACH_O_X86_64_PCREL32_4 ENUMDOC Same as BFD_RELOC_32_PCREL but with an implicit -4 addend. +ENUM + BFD_RELOC_MACH_O_X86_64_TLV +ENUMDOC + Used when referencing a TLV entry. ENUM @@ -7898,6 +7913,19 @@ ENUMX ENUMDOC Tilera TILE-Gx Relocations. +ENUM + BFD_RELOC_BPF_64 +ENUMX + BFD_RELOC_BPF_32 +ENUMX + BFD_RELOC_BPF_16 +ENUMX + BFD_RELOC_BPF_DISP16 +ENUMX + BFD_RELOC_BPF_DISP32 +ENUMDOC + Linux eBPF relocations. + ENUM BFD_RELOC_EPIPHANY_SIMM8 ENUMDOC @@ -7967,6 +7995,144 @@ ENUMX ENUMDOC WebAssembly relocations. +ENUM + BFD_RELOC_CKCORE_NONE +ENUMX + BFD_RELOC_CKCORE_ADDR32 +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM8BY4 +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM11BY2 +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM4BY2 +ENUMX + BFD_RELOC_CKCORE_PCREL32 +ENUMX + BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2 +ENUMX + BFD_RELOC_CKCORE_GNU_VTINHERIT +ENUMX + BFD_RELOC_CKCORE_GNU_VTENTRY +ENUMX + BFD_RELOC_CKCORE_RELATIVE +ENUMX + BFD_RELOC_CKCORE_COPY +ENUMX + BFD_RELOC_CKCORE_GLOB_DAT +ENUMX + BFD_RELOC_CKCORE_JUMP_SLOT +ENUMX + BFD_RELOC_CKCORE_GOTOFF +ENUMX + BFD_RELOC_CKCORE_GOTPC +ENUMX + BFD_RELOC_CKCORE_GOT32 +ENUMX + BFD_RELOC_CKCORE_PLT32 +ENUMX + BFD_RELOC_CKCORE_ADDRGOT +ENUMX + BFD_RELOC_CKCORE_ADDRPLT +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM26BY2 +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM16BY2 +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM16BY4 +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM10BY2 +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM10BY4 +ENUMX + BFD_RELOC_CKCORE_ADDR_HI16 +ENUMX + BFD_RELOC_CKCORE_ADDR_LO16 +ENUMX + BFD_RELOC_CKCORE_GOTPC_HI16 +ENUMX + BFD_RELOC_CKCORE_GOTPC_LO16 +ENUMX + BFD_RELOC_CKCORE_GOTOFF_HI16 +ENUMX + BFD_RELOC_CKCORE_GOTOFF_LO16 +ENUMX + BFD_RELOC_CKCORE_GOT12 +ENUMX + BFD_RELOC_CKCORE_GOT_HI16 +ENUMX + BFD_RELOC_CKCORE_GOT_LO16 +ENUMX + BFD_RELOC_CKCORE_PLT12 +ENUMX + BFD_RELOC_CKCORE_PLT_HI16 +ENUMX + BFD_RELOC_CKCORE_PLT_LO16 +ENUMX + BFD_RELOC_CKCORE_ADDRGOT_HI16 +ENUMX + BFD_RELOC_CKCORE_ADDRGOT_LO16 +ENUMX + BFD_RELOC_CKCORE_ADDRPLT_HI16 +ENUMX + BFD_RELOC_CKCORE_ADDRPLT_LO16 +ENUMX + BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2 +ENUMX + BFD_RELOC_CKCORE_TOFFSET_LO16 +ENUMX + BFD_RELOC_CKCORE_DOFFSET_LO16 +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM18BY2 +ENUMX + BFD_RELOC_CKCORE_DOFFSET_IMM18 +ENUMX + BFD_RELOC_CKCORE_DOFFSET_IMM18BY2 +ENUMX + BFD_RELOC_CKCORE_DOFFSET_IMM18BY4 +ENUMX + BFD_RELOC_CKCORE_GOTOFF_IMM18 +ENUMX + BFD_RELOC_CKCORE_GOT_IMM18BY4 +ENUMX + BFD_RELOC_CKCORE_PLT_IMM18BY4 +ENUMX + BFD_RELOC_CKCORE_PCREL_IMM7BY4 +ENUMX + BFD_RELOC_CKCORE_TLS_LE32 +ENUMX + BFD_RELOC_CKCORE_TLS_IE32 +ENUMX + BFD_RELOC_CKCORE_TLS_GD32 +ENUMX + BFD_RELOC_CKCORE_TLS_LDM32 +ENUMX + BFD_RELOC_CKCORE_TLS_LDO32 +ENUMX + BFD_RELOC_CKCORE_TLS_DTPMOD32 +ENUMX + BFD_RELOC_CKCORE_TLS_DTPOFF32 +ENUMX + BFD_RELOC_CKCORE_TLS_TPOFF32 +ENUMX + BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4 +ENUMX + BFD_RELOC_CKCORE_NOJSRI +ENUMX + BFD_RELOC_CKCORE_CALLGRAPH +ENUMX + BFD_RELOC_CKCORE_IRELATIVE +ENUMX + BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4 +ENUMX + BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4 +ENUMDOC + C-SKY relocations. + +ENUM + BFD_RELOC_S12Z_OPR +ENUMDOC + S12Z relocations. + ENDSENUM BFD_RELOC_UNUSED CODE_FRAGMENT @@ -8023,28 +8189,11 @@ DESCRIPTION reloc_howto_type * bfd_default_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code) { - switch (code) - { - case BFD_RELOC_CTOR: - /* The type of reloc used in a ctor, which will be as wide as the - address - so either a 64, 32, or 16 bitter. */ - switch (bfd_arch_bits_per_address (abfd)) - { - case 64: - BFD_FAIL (); - break; - case 32: - return &bfd_howto_32; - case 16: - BFD_FAIL (); - break; - default: - BFD_FAIL (); - } - break; - default: - BFD_FAIL (); - } + /* Very limited support is provided for relocs in generic targets + such as elf32-little. FIXME: Should we always return NULL? */ + if (code == BFD_RELOC_CTOR + && bfd_arch_bits_per_address (abfd) == 32) + return &bfd_howto_32; return NULL; } @@ -8245,16 +8394,28 @@ bfd_generic_get_relocated_section_contents (bfd *abfd, goto error_return; } - if (symbol->section && discarded_section (symbol->section)) + /* Zap reloc field when the symbol is from a discarded + section, ignoring any addend. Do the same when called + from bfd_simple_get_relocated_section_contents for + undefined symbols in debug sections. This is to keep + debug info reasonably sane, in particular so that + DW_FORM_ref_addr to another file's .debug_info isn't + confused with an offset into the current file's + .debug_info. */ + if ((symbol->section != NULL && discarded_section (symbol->section)) + || (symbol->section == bfd_und_section_ptr + && (input_section->flags & SEC_DEBUGGING) != 0 + && link_info->input_bfds == link_info->output_bfd)) { - bfd_byte *p; + bfd_vma off; static reloc_howto_type none_howto = HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, "unused", FALSE, 0, 0, FALSE); - p = data + (*parent)->address * bfd_octets_per_byte (input_bfd); - _bfd_clear_contents ((*parent)->howto, input_bfd, input_section, - p); + off = ((*parent)->address + * bfd_octets_per_byte (input_bfd, input_section)); + _bfd_clear_contents ((*parent)->howto, input_bfd, + input_section, data, off); (*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; (*parent)->addend = 0; (*parent)->howto = &none_howto; @@ -8337,7 +8498,7 @@ bfd_generic_get_relocated_section_contents (bfd *abfd, free (reloc_vector); return data; -error_return: + error_return: free (reloc_vector); return NULL; }