From: Alan Modra Date: Sun, 24 Nov 2019 23:37:40 +0000 (+1030) Subject: Pass section when available to bfd_octets_per_byte X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=bb2942085c83289c56cc3ef8b9ab0ecf6267efa3;p=deliverable%2Fbinutils-gdb.git Pass section when available to bfd_octets_per_byte and other tidies. I think it's better to default to passing the section to bfd_octets_per_byte, even in cases where we know it won't make a difference. A number of the coff reloc functions used bfd_octets_per_byte wrongly, not factoring it into the offset into the data buffer. As it happens, the targets using those files always had bfd_octets_per_byte equal to one, so there wasn't any detectable wrong behaviour. However, it is wrong in the source and might cause trouble for anyone creating a new target. Besides fixing that, the patch also defines OCTETS_PER_BYTE as one in target files where that is appropriate. bfd/ * archures.c (bfd_octets_per_byte): Tail call bfd_arch_mach_octets_per_byte. * coff-arm.c (OCTETS_PER_BYTE): Define. (coff_arm_reloc): Introduce new "octets" temp. Use OCTETS_PER_BYTE with section. Correct "addr". Remove ATTRIBUTE_UNUSED. * coff-i386.c (coff_i386_reloc): Similarly. * coff-mips.c (mips_reflo_reloc): Similarly. * coff-x86_64.c (coff_amd64_reloc): Similarly. * elf32-msp430.c (OCTETS_PER_BYTE): Define. (rl78_sym_diff_handler): Use OCTETS_PER_BYTE, with section. * elf32-nds32.c (nds32_elf_get_relocated_section_contents): Similarly. * elf32-ppc.c (ppc_elf_addr16_ha_reloc): Similarly. * elf32-pru.c (pru_elf32_do_ldi32_relocate): Similarly. * elf32-s12z.c (opru18_reloc): Similarly. * elf32-sh.c (sh_elf_reloc): Similarly. * elf32-spu.c (spu_elf_rel9): Similarly. * elf32-xtensa.c (bfd_elf_xtensa_reloc): Similarly. * elf64-ppc.c (ppc64_elf_ha_reloc, ppc64_elf_brtaken_reloc), (ppc64_elf_toc64_reloc): Similarly. * bfd.c (bfd_get_section_limit): Pass section to bfd_octets_per_byte. * cofflink.c (_bfd_coff_link_input_bfd), (_bfd_coff_reloc_link_order): Likewise. * elf.c (_bfd_elf_section_offset): Likewise. * elflink.c (resolve_section, bfd_elf_perform_complex_relocation), (elf_link_input_bfd, elf_reloc_link_order, elf_fixup_link_order), (bfd_elf_final_link): Likewise. * elf.c (_bfd_elf_make_section_from_shdr): Don't strncmp twice to set SEC_ELF_OCTETS. * reloc.c (bfd_perform_relocation): Tidy SEC_ELF_OCTETS special case. (bfd_install_relocation): Likewise. (_bfd_final_link_relocate): Don't recalculate octets. * syms.c (_bfd_stab_section_find_nearest_line): Introduc new "octets" temp. * bfd-in2.h: Regenerate. ld/ * ldexp.c (fold_name): Pass section to bfd_octets_per_byte. * ldlang.c (init_opb): Don't call bfd_arch_mach_octets_per_byte unnecessarily. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c310fea4c7..9789016199 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,40 @@ +2019-11-25 Alan Modra + + * archures.c (bfd_octets_per_byte): Tail call + bfd_arch_mach_octets_per_byte. + * coff-arm.c (OCTETS_PER_BYTE): Define. + (coff_arm_reloc): Introduce new "octets" temp. Use OCTETS_PER_BYTE + with section. Correct "addr". Remove ATTRIBUTE_UNUSED. + * coff-i386.c (coff_i386_reloc): Similarly. + * coff-mips.c (mips_reflo_reloc): Similarly. + * coff-x86_64.c (coff_amd64_reloc): Similarly. + * elf32-msp430.c (OCTETS_PER_BYTE): Define. + (rl78_sym_diff_handler): Use OCTETS_PER_BYTE, with section. + * elf32-nds32.c (nds32_elf_get_relocated_section_contents): Similarly. + * elf32-ppc.c (ppc_elf_addr16_ha_reloc): Similarly. + * elf32-pru.c (pru_elf32_do_ldi32_relocate): Similarly. + * elf32-s12z.c (opru18_reloc): Similarly. + * elf32-sh.c (sh_elf_reloc): Similarly. + * elf32-spu.c (spu_elf_rel9): Similarly. + * elf32-xtensa.c (bfd_elf_xtensa_reloc): Similarly. + * elf64-ppc.c (ppc64_elf_ha_reloc, ppc64_elf_brtaken_reloc), + (ppc64_elf_toc64_reloc): Similarly. + * bfd.c (bfd_get_section_limit): Pass section to bfd_octets_per_byte. + * cofflink.c (_bfd_coff_link_input_bfd), + (_bfd_coff_reloc_link_order): Likewise. + * elf.c (_bfd_elf_section_offset): Likewise. + * elflink.c (resolve_section, bfd_elf_perform_complex_relocation), + (elf_link_input_bfd, elf_reloc_link_order, elf_fixup_link_order), + (bfd_elf_final_link): Likewise. + * elf.c (_bfd_elf_make_section_from_shdr): Don't strncmp twice + to set SEC_ELF_OCTETS. + * reloc.c (bfd_perform_relocation): Tidy SEC_ELF_OCTETS special case. + (bfd_install_relocation): Likewise. + (_bfd_final_link_relocate): Don't recalculate octets. + * syms.c (_bfd_stab_section_find_nearest_line): Introduc new + "octets" temp. + * bfd-in2.h: Regenerate. + 2019-11-25 Christian Eggers * section.c (struct bfd_section): New flag SEC_ELF_OCTETS. diff --git a/bfd/archures.c b/bfd/archures.c index 1e6611069c..7866c6095b 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -1391,15 +1391,13 @@ DESCRIPTION unsigned int bfd_octets_per_byte (const bfd *abfd, const asection *sec) { - unsigned int opb = bfd_arch_mach_octets_per_byte (bfd_get_arch (abfd), - bfd_get_mach (abfd)); - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour && sec != NULL && (sec->flags & SEC_ELF_OCTETS) != 0) - opb = 1; + return 1; - return opb; + return bfd_arch_mach_octets_per_byte (bfd_get_arch (abfd), + bfd_get_mach (abfd)); } /* diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 80ff8e89b5..44902fc8d0 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -6861,7 +6861,7 @@ static inline bfd_size_type bfd_get_section_limit (const bfd *abfd, const asection *sec) { return (bfd_get_section_limit_octets (abfd, sec) - / bfd_octets_per_byte (abfd, NULL)); + / bfd_octets_per_byte (abfd, sec)); } /* Functions to handle insertion and deletion of a bfd's sections. These diff --git a/bfd/bfd.c b/bfd/bfd.c index c1f3fcadd6..a3c522cbf8 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -493,7 +493,7 @@ CODE_FRAGMENT .bfd_get_section_limit (const bfd *abfd, const asection *sec) .{ . return (bfd_get_section_limit_octets (abfd, sec) -. / bfd_octets_per_byte (abfd, NULL)); +. / bfd_octets_per_byte (abfd, sec)); .} . .{* Functions to handle insertion and deletion of a bfd's sections. These diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index e297df27e8..242c90bf87 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -33,6 +33,9 @@ #include "libcoff.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + /* Macros for manipulation the bits in the flags field of the coff data structure. */ #define APCS_26_FLAG(abfd) \ @@ -96,7 +99,7 @@ coff_arm_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol ATTRIBUTE_UNUSED, void * data, - asection *input_section ATTRIBUTE_UNUSED, + asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) { @@ -114,11 +117,11 @@ coff_arm_reloc (bfd *abfd, if (diff != 0) { reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; + bfd_size_type octets = (reloc_entry->address + * OCTETS_PER_BYTE (abfd, input_section)); + unsigned char *addr = (unsigned char *) data + octets; - if (! bfd_reloc_offset_in_range (howto, abfd, input_section, - reloc_entry->address - * bfd_octets_per_byte (abfd, NULL))) + if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets)) return bfd_reloc_outofrange; switch (howto->size) diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c index f28eb8af0c..99f6079863 100644 --- a/bfd/coff-i386.c +++ b/bfd/coff-i386.c @@ -41,6 +41,9 @@ #include "libcoff.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + static reloc_howto_type *coff_i386_rtype_to_howto (bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, @@ -67,7 +70,7 @@ coff_i386_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void * data, - asection *input_section ATTRIBUTE_UNUSED, + asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) { @@ -142,11 +145,11 @@ coff_i386_reloc (bfd *abfd, if (diff != 0) { reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; + bfd_size_type octets = (reloc_entry->address + * OCTETS_PER_BYTE (abfd, input_section)); + unsigned char *addr = (unsigned char *) data + octets; - if (! bfd_reloc_offset_in_range (howto, abfd, input_section, - reloc_entry->address - * bfd_octets_per_byte (abfd, NULL))) + if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets)) return bfd_reloc_outofrange; switch (howto->size) diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c index c9c7fc66ba..76de32009a 100644 --- a/bfd/coff-mips.c +++ b/bfd/coff-mips.c @@ -31,6 +31,9 @@ #include "coff/mips.h" #include "libcoff.h" #include "libecoff.h" + +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 /* Prototypes for static functions. */ static bfd_reloc_status_type @@ -484,13 +487,13 @@ mips_refhi_reloc (bfd *abfd ATTRIBUTE_UNUSED, relocation described above. */ static bfd_reloc_status_type -mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED, +mips_reflo_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void * data, asection *input_section, bfd *output_bfd, - char **error_message ATTRIBUTE_UNUSED) + char **error_message) { if (mips_refhi_list != NULL) { @@ -503,11 +506,12 @@ mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED, unsigned long val; unsigned long vallo; struct mips_hi *next; + bfd_size_type octets = (reloc_entry->address + * OCTETS_PER_BYTE (abfd, input_section)); + bfd_byte *loc = (bfd_byte *) data + octets; - if (! bfd_reloc_offset_in_range (reloc_entry->howto, abfd, - input_section, - reloc_entry->address - * bfd_octets_per_byte (abfd, NULL))) + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, octets)) return bfd_reloc_outofrange; /* Do the REFHI relocation. Note that we actually don't @@ -515,8 +519,7 @@ mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED, where to find the low 16 bits of the addend needed by the REFHI. */ insn = bfd_get_32 (abfd, l->addr); - vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address) - & 0xffff); + vallo = bfd_get_32 (abfd, loc) & 0xffff; val = ((insn & 0xffff) << 16) + vallo; val += l->addend; @@ -544,7 +547,7 @@ mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED, /* Now do the REFLO reloc in the usual way. */ return mips_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); + input_section, output_bfd, error_message); } /* Do a GPREL relocation. This is a 16 bit value which must become diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c index 94fd7ac3e4..4edbd23609 100644 --- a/bfd/coff-x86_64.c +++ b/bfd/coff-x86_64.c @@ -52,6 +52,9 @@ #define COFF_PAGE_SIZE 0x1000 +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + /* For some reason when using AMD COFF the value stored in the .text section for a reference to a common symbol is the value itself plus any desired offset. Ian Taylor, Cygnus Support. */ @@ -141,11 +144,11 @@ coff_amd64_reloc (bfd *abfd, if (diff != 0) { reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; + bfd_size_type octets = (reloc_entry->address + * OCTETS_PER_BYTE (abfd, input_section)); + unsigned char *addr = (unsigned char *) data + octets; - if (! bfd_reloc_offset_in_range (howto, abfd, input_section, - reloc_entry->address - * bfd_octets_per_byte (abfd, NULL))) + if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets)) return bfd_reloc_outofrange; switch (howto->size) diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 23a8e6b226..0ca8649dff 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -2542,7 +2542,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) if (secdata == NULL || secdata->stab_info == NULL) { file_ptr loc = (o->output_offset - * bfd_octets_per_byte (output_bfd, NULL)); + * bfd_octets_per_byte (output_bfd, o)); if (! bfd_set_section_contents (output_bfd, o->output_section, contents, loc, o->size)) return FALSE; @@ -2834,7 +2834,7 @@ _bfd_coff_reloc_link_order (bfd *output_bfd, return FALSE; rstat = _bfd_relocate_contents (howto, output_bfd, - (bfd_vma) link_order->u.reloc.p->addend,\ + (bfd_vma) link_order->u.reloc.p->addend, buf); switch (rstat) { @@ -2853,7 +2853,8 @@ _bfd_coff_reloc_link_order (bfd *output_bfd, (bfd *) NULL, (asection *) NULL, (bfd_vma) 0); break; } - loc = link_order->offset * bfd_octets_per_byte (output_bfd, NULL); + loc = link_order->offset * bfd_octets_per_byte (output_bfd, + output_section); ok = bfd_set_section_contents (output_bfd, output_section, buf, loc, size); free (buf); diff --git a/bfd/elf.c b/bfd/elf.c index 43ef632fa7..a4f26dac71 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1102,33 +1102,17 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, not any sort of flag. Their SEC_ALLOC bits are cleared. */ if (name [0] == '.') { - const char *p; - int n; - if (name[1] == 'd') - p = ".debug", n = 6; - else if (name[1] == 'g' && name[2] == 'n') - p = ".gnu.linkonce.wi.", n = 17; - else if (name[1] == 'g' && name[2] == 'd') - p = ".gdb_index", n = 11; /* yes we really do mean 11. */ - else if (name[1] == 'l') - p = ".line", n = 5; - else if (name[1] == 's') - p = ".stab", n = 5; - else if (name[1] == 'z') - p = ".zdebug", n = 7; - else - p = NULL, n = 0; - if (p != NULL && strncmp (name, p, n) == 0) + if (strncmp (name, ".debug", 6) == 0 + || strncmp (name, ".gnu.linkonce.wi.", 17) == 0 + || strncmp (name, ".zdebug", 7) == 0) + flags |= SEC_DEBUGGING | SEC_ELF_OCTETS; + else if (strncmp (name, GNU_BUILD_ATTRS_SECTION_NAME, 21) == 0 + || strncmp (name, ".note.gnu", 9) == 0) + flags |= SEC_ELF_OCTETS; + else if (strncmp (name, ".line", 5) == 0 + || strncmp (name, ".stab", 5) == 0 + || strcmp (name, ".gdb_index") == 0) flags |= SEC_DEBUGGING; - - /* DWARF debug sections and ELF notes are organized in octets. */ - if (strncmp (name, ".debug", 6) == 0 || - strncmp (name, ".zdebug", 7) == 0 || - strncmp (name, GNU_BUILD_ATTRS_SECTION_NAME, 21) == 0 || - strncmp (name, ".note.gnu", 9) == 0) - { - flags |= SEC_ELF_OCTETS; - } } } @@ -12064,7 +12048,7 @@ _bfd_elf_section_offset (bfd *abfd, /* address_size and sec->size are in octets. Convert to bytes before subtracting the original offset. */ offset = ((sec->size - address_size) - / bfd_octets_per_byte (abfd, NULL) - offset); + / bfd_octets_per_byte (abfd, sec) - offset); } return offset; } diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c index 7f675fcc34..eeed0c6fc0 100644 --- a/bfd/elf32-msp430.c +++ b/bfd/elf32-msp430.c @@ -26,6 +26,9 @@ #include "elf-bfd.h" #include "elf/msp430.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + static bfd_reloc_status_type rl78_sym_diff_handler (bfd * abfd, arelent * reloc, @@ -36,7 +39,7 @@ rl78_sym_diff_handler (bfd * abfd, char ** error_message ATTRIBUTE_UNUSED) { bfd_size_type octets; - octets = reloc->address * bfd_octets_per_byte (abfd, NULL); + octets = reloc->address * OCTETS_PER_BYTE (abfd, input_sec); /* Catch the case where bfd_install_relocation would return bfd_reloc_outofrange because the SYM_DIFF reloc is being used in a very diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c index a47d98e270..cb8f7755dc 100644 --- a/bfd/elf32-nds32.c +++ b/bfd/elf32-nds32.c @@ -32,6 +32,9 @@ #include "opcode/cgen.h" #include "../opcodes/nds32-opc.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + /* Relocation HOWTO functions. */ static bfd_reloc_status_type nds32_elf_ignore_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); @@ -13220,7 +13223,8 @@ nds32_elf_get_relocated_section_contents (bfd *abfd, = HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, "unused", FALSE, 0, 0, FALSE); - off = (*parent)->address * bfd_octets_per_byte (input_bfd, NULL); + off = (*parent)->address * 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; diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 0e6a3476d2..162367afd5 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -37,6 +37,9 @@ #include "dwarf2.h" #include "opcode/ppc.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + typedef enum split16_format_type { split16a_type = 0, @@ -956,7 +959,7 @@ ppc_elf_addr16_ha_reloc (bfd *abfd, + input_section->output_section->vma); value >>= 16; - octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); + octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section); insn = bfd_get_32 (abfd, (bfd_byte *) data + octets); insn &= ~0x1fffc1; insn |= (value & 0xffc1) | ((value & 0x3e) << 15); diff --git a/bfd/elf32-pru.c b/bfd/elf32-pru.c index 98b2018621..dcf4adfa86 100644 --- a/bfd/elf32-pru.c +++ b/bfd/elf32-pru.c @@ -32,6 +32,9 @@ #include "opcode/pru.h" #include "libiberty.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + #define SWAP_VALS(A,B) \ do { \ (A) ^= (B); \ @@ -537,7 +540,7 @@ pru_elf32_do_ldi32_relocate (bfd *abfd, reloc_howto_type *howto, bfd_vma symbol_value, bfd_vma addend) { bfd_signed_vma relocation; - bfd_size_type octets = offset * bfd_octets_per_byte (abfd, NULL); + bfd_size_type octets = offset * OCTETS_PER_BYTE (abfd, input_section); bfd_byte *location; unsigned long in1, in2; @@ -557,7 +560,7 @@ pru_elf32_do_ldi32_relocate (bfd *abfd, reloc_howto_type *howto, BFD_ASSERT (!howto->pc_relative); /* A hacked-up version of _bfd_relocate_contents() follows. */ - location = data + offset * bfd_octets_per_byte (abfd, NULL); + location = data + octets; BFD_ASSERT (!howto->pc_relative); diff --git a/bfd/elf32-s12z.c b/bfd/elf32-s12z.c index 8b3099c26e..f8f46ba34b 100644 --- a/bfd/elf32-s12z.c +++ b/bfd/elf32-s12z.c @@ -27,6 +27,9 @@ #include "elf/s12z.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + /* Relocation functions. */ static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup (bfd *, bfd_reloc_code_real_type); @@ -44,7 +47,7 @@ opru18_reloc (bfd *abfd, arelent *reloc_entry, struct bfd_symbol *symbol, Appendix A.4 of the S12Z reference manual. */ bfd_size_type octets = (reloc_entry->address - * bfd_octets_per_byte (abfd, NULL)); + * OCTETS_PER_BYTE (abfd, input_section)); bfd_vma result = bfd_get_24 (abfd, (unsigned char *) data + octets); bfd_vma val = bfd_asymbol_value (symbol); diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 3dc25eefe5..8aa49b099c 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -30,6 +30,9 @@ #include "libiberty.h" #include "../opcodes/sh-opc.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + static bfd_reloc_status_type sh_elf_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type sh_elf_ignore_reloc @@ -233,7 +236,8 @@ sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in, bfd_vma sym_value; enum elf_sh_reloc_type r_type; bfd_vma addr = reloc_entry->address; - bfd_byte *hit_data = addr + (bfd_byte *) data; + bfd_size_type octets = addr * OCTETS_PER_BYTE (abfd, input_section); + bfd_byte *hit_data = (bfd_byte *) data + octets; r_type = (enum elf_sh_reloc_type) reloc_entry->howto->type; @@ -254,8 +258,7 @@ sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in, return bfd_reloc_undefined; /* PR 17512: file: 9891ca98. */ - if ((addr * bfd_octets_per_byte (abfd, NULL) - + bfd_get_reloc_size (reloc_entry->howto)) + if (octets + bfd_get_reloc_size (reloc_entry->howto) > bfd_get_section_limit_octets (abfd, input_section)) return bfd_reloc_outofrange; diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index 6f8b32ab58..823628898f 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -27,6 +27,9 @@ #include "elf/spu.h" #include "elf32-spu.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + /* We use RELA style relocs. Don't define USE_REL. */ static bfd_reloc_status_type spu_elf_rel9 (bfd *, arelent *, asymbol *, @@ -212,7 +215,7 @@ spu_elf_rel9 (bfd *abfd, arelent *reloc_entry, asymbol *symbol, if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) return bfd_reloc_outofrange; - octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); + octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section); /* Get symbol value. */ val = 0; diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 31e9530256..c42e95ab57 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -32,6 +32,9 @@ #include "xtensa-isa.h" #include "xtensa-config.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + #define XTENSA_NO_NOP_REMOVAL 0 /* Local helper functions. */ @@ -2104,7 +2107,7 @@ bfd_elf_xtensa_reloc (bfd *abfd, bfd_vma relocation; bfd_reloc_status_type flag; bfd_size_type octets = (reloc_entry->address - * bfd_octets_per_byte (abfd, NULL)); + * OCTETS_PER_BYTE (abfd, input_section)); bfd_vma output_base = 0; reloc_howto_type *howto = reloc_entry->howto; asection *reloc_target_output_section; diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 5c7f32315f..9a9374fab1 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -35,6 +35,9 @@ #include "elf64-ppc.h" #include "dwarf2.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + static bfd_reloc_status_type ppc64_elf_ha_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type ppc64_elf_branch_reloc @@ -1405,7 +1408,7 @@ ppc64_elf_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + input_section->output_section->vma); value = (bfd_signed_vma) value >> 16; - octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); + octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section); insn = bfd_get_32 (abfd, (bfd_byte *) data + octets); insn &= ~0x1fffc1; insn |= (value & 0xffc1) | ((value & 0x3e) << 15); @@ -1480,7 +1483,7 @@ ppc64_elf_brtaken_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); - octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); + octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section); insn = bfd_get_32 (abfd, (bfd_byte *) data + octets); insn &= ~(0x01 << 21); r_type = reloc_entry->howto->type; @@ -1630,7 +1633,7 @@ ppc64_elf_toc64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, if (TOCstart == 0) TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner); - octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); + octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section); bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets); return bfd_reloc_ok; } diff --git a/bfd/elflink.c b/bfd/elflink.c index 824669a536..554936124c 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -8457,7 +8457,7 @@ resolve_section (const char *name, if (strncmp (".end", name + len, 4) == 0) { *result = (curr->vma - + curr->size / bfd_octets_per_byte (abfd, NULL)); + + curr->size / bfd_octets_per_byte (abfd, curr)); return TRUE; } @@ -8752,7 +8752,7 @@ decode_complex_addend (unsigned long *start, /* in bits */ bfd_reloc_status_type bfd_elf_perform_complex_relocation (bfd *input_bfd, - asection *input_section ATTRIBUTE_UNUSED, + asection *input_section, bfd_byte *contents, Elf_Internal_Rela *rel, bfd_vma relocation) @@ -8760,6 +8760,7 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd, bfd_vma shift, x, mask; unsigned long start, oplen, len, wordsz, chunksz, lsb0_p, signed_p, trunc_p; bfd_reloc_status_type r; + bfd_size_type octets; /* Perform this reloc, since it is complex. (this is not to say that it necessarily refers to a complex @@ -8778,9 +8779,8 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd, else shift = (8 * wordsz) - (start + len); - x = get_value (wordsz, chunksz, input_bfd, - contents - + rel->r_offset * bfd_octets_per_byte (input_bfd, NULL)); + octets = rel->r_offset * bfd_octets_per_byte (input_bfd, input_section); + x = get_value (wordsz, chunksz, input_bfd, contents + octets); #ifdef DEBUG printf ("Doing complex reloc: " @@ -8812,8 +8812,7 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd, (unsigned long) relocation, (unsigned long) (mask << shift), (unsigned long) ((relocation & mask) << shift), (unsigned long) x); #endif - put_value (wordsz, chunksz, input_bfd, x, - contents + rel->r_offset * bfd_octets_per_byte (input_bfd, NULL)); + put_value (wordsz, chunksz, input_bfd, x, contents + octets); return r; } @@ -11305,7 +11304,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) file_ptr offset = (file_ptr) o->output_offset; bfd_size_type todo = o->size; - offset *= bfd_octets_per_byte (output_bfd, NULL); + offset *= bfd_octets_per_byte (output_bfd, o); if ((o->flags & SEC_ELF_REVERSE_COPY)) { @@ -11439,6 +11438,7 @@ elf_reloc_link_order (bfd *output_bfd, bfd_byte *buf; bfd_boolean ok; const char *sym_name; + bfd_size_type octets; size = (bfd_size_type) bfd_get_reloc_size (howto); buf = (bfd_byte *) bfd_zmalloc (size); @@ -11465,10 +11465,10 @@ elf_reloc_link_order (bfd *output_bfd, break; } + octets = link_order->offset * bfd_octets_per_byte (output_bfd, + output_section); ok = bfd_set_section_contents (output_bfd, output_section, buf, - link_order->offset - * bfd_octets_per_byte (output_bfd, NULL), - size); + octets, size); free (buf); if (! ok) return FALSE; @@ -11635,7 +11635,7 @@ elf_fixup_link_order (bfd *abfd, asection *o) s = sections[n]->u.indirect.section; mask = ~(bfd_vma) 0 << s->alignment_power; offset = (offset + ~mask) & mask; - s->output_offset = offset / bfd_octets_per_byte (abfd, NULL); + s->output_offset = offset / bfd_octets_per_byte (abfd, s); sections[n]->offset = offset; offset += sections[n]->size; } @@ -12856,12 +12856,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) continue; if (strcmp (o->name, ".dynstr") != 0) { - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, - (file_ptr) o->output_offset - * bfd_octets_per_byte (abfd, - NULL), - o->size)) + bfd_size_type octets = ((file_ptr) o->output_offset + * bfd_octets_per_byte (abfd, o)); + if (!bfd_set_section_contents (abfd, o->output_section, + o->contents, octets, o->size)) goto error_return; } else diff --git a/bfd/reloc.c b/bfd/reloc.c index e01cb5182e..b00b79f319 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -744,14 +744,14 @@ bfd_perform_relocation (bfd *abfd, else output_base = reloc_target_output_section->vma; - /* For sections where relocations are in octets, output_base and - output_offset must also be converted to octets. */ + 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)) - relocation += ((output_base + symbol->section->output_offset) - * bfd_octets_per_byte (abfd, NULL)); - else - relocation += output_base + symbol->section->output_offset; + output_base *= bfd_octets_per_byte (abfd, input_section); + + relocation += output_base; /* Add in supplied addend. */ relocation += reloc_entry->addend; @@ -1080,14 +1080,14 @@ bfd_install_relocation (bfd *abfd, else output_base = reloc_target_output_section->vma; - /* For sections where relocations are in octets, output_base and - output_offset must also be converted to octets. */ + 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)) - relocation += ((output_base + symbol->section->output_offset) - * bfd_octets_per_byte (abfd, NULL)); - else - relocation += output_base + symbol->section->output_offset; + output_base *= bfd_octets_per_byte (abfd, input_section); + + relocation += output_base; /* Add in supplied addend. */ relocation += reloc_entry->addend; @@ -1383,10 +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, - input_section)); + contents + octets); } /* Relocate a given location using a given value and howto. */ diff --git a/bfd/syms.c b/bfd/syms.c index ec7d2c8dba..f02cae9fc7 100644 --- a/bfd/syms.c +++ b/bfd/syms.c @@ -1078,20 +1078,21 @@ _bfd_stab_section_find_nearest_line (bfd *abfd, arelent *r; unsigned long val; asymbol *sym; + bfd_size_type octets; r = *pr; /* Ignore R_*_NONE relocs. */ if (r->howto->dst_mask == 0) continue; + octets = r->address * bfd_octets_per_byte (abfd, NULL); if (r->howto->rightshift != 0 || r->howto->size != 2 || r->howto->bitsize != 32 || r->howto->pc_relative || r->howto->bitpos != 0 || r->howto->dst_mask != 0xffffffff - || (r->address * bfd_octets_per_byte (abfd, NULL) + 4 - > stabsize)) + || octets + 4 > stabsize) { _bfd_error_handler (_("unsupported .stab relocation")); @@ -1101,14 +1102,11 @@ _bfd_stab_section_find_nearest_line (bfd *abfd, return FALSE; } - val = bfd_get_32 (abfd, info->stabs - + (r->address - * bfd_octets_per_byte (abfd, NULL))); + val = bfd_get_32 (abfd, info->stabs + octets); val &= r->howto->src_mask; sym = *r->sym_ptr_ptr; val += sym->value + sym->section->vma + r->addend; - bfd_put_32 (abfd, (bfd_vma) val, info->stabs - + r->address * bfd_octets_per_byte (abfd, NULL)); + bfd_put_32 (abfd, (bfd_vma) val, info->stabs + octets); } } diff --git a/ld/ChangeLog b/ld/ChangeLog index e969c0f1f7..029de5f0b9 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2019-11-25 Alan Modra + + * ldexp.c (fold_name): Pass section to bfd_octets_per_byte. + * ldlang.c (init_opb): Don't call bfd_arch_mach_octets_per_byte + unnecessarily. + 2019-11-25 Christian Eggers * ldexp.c (fold_name): Provide section parameter to diff --git a/ld/ldexp.c b/ld/ldexp.c index 8327a3f2bc..b287022f5a 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -852,7 +852,8 @@ fold_name (etree_type *tree) if (tree->type.node_code == SIZEOF) val = (os->bfd_section->size - / bfd_octets_per_byte (link_info.output_bfd, NULL)); + / bfd_octets_per_byte (link_info.output_bfd, + os->bfd_section)); else val = (bfd_vma)1 << os->bfd_section->alignment_power; diff --git a/ld/ldlang.c b/ld/ldlang.c index 3bcab7a876..191d8f1c61 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -3442,16 +3442,16 @@ ldlang_open_output (lang_statement_union_type *statement) static void init_opb (asection *s) { - unsigned x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); - if (s != NULL) - { - if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour - && (s->flags & SEC_ELF_OCTETS)) - x = 1; - } + unsigned int x; opb_shift = 0; + if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour + && s != NULL + && (s->flags & SEC_ELF_OCTETS) != 0) + return; + + x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); if (x > 1) while ((x & 1) == 0) {