diff options
39 files changed, 279 insertions, 81 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a1ef734..c310fea 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,59 @@ +2019-11-25 Christian Eggers <ceggers@gmx.de> + + * section.c (struct bfd_section): New flag SEC_ELF_OCTETS. + * archures.c (bfd_octets_per_byte): New parameter sec. + If section is not NULL and SEC_ELF_OCTETS is set, one octet es + returned [ELF targets only]. + * bfd.c (bfd_get_section_limit): Provide section parameter to + bfd_octets_per_byte. + * bfd-in2.h: regenerate. + * binary.c (binary_set_section_contents): Move call to + bfd_octets_per_byte into section loop. Provide section parameter + to bfd_octets_per_byte. + * coff-arm.c (coff_arm_reloc): Provide section parameter + to bfd_octets_per_byte. + * coff-i386.c (coff_i386_reloc): likewise. + * coff-mips.c (mips_reflo_reloc): likewise. + * coff-x86_64.c (coff_amd64_reloc): likewise. + * cofflink.c (_bfd_coff_link_input_bfd): likewise. + (_bfd_coff_reloc_link_order): likewise. + * elf.c (_bfd_elf_section_offset): likewise. + (_bfd_elf_make_section_from_shdr): likewise. + Set SEC_ELF_OCTETS for sections with names .gnu.build.attributes, + .debug*, .zdebug* and .note.gnu*. + * elf32-msp430.c (rl78_sym_diff_handler): Provide section parameter + to bfd_octets_per_byte. + * elf32-nds.c (nds32_elf_get_relocated_section_contents): likewise. + * elf32-ppc.c (ppc_elf_addr16_ha_reloc): likewise. + * elf32-pru.c (pru_elf32_do_ldi32_relocate): likewise. + * elf32-s12z.c (opru18_reloc): likewise. + * elf32-sh.c (sh_elf_reloc): likewise. + * elf32-spu.c (spu_elf_rel9): likewise. + * elf32-xtensa.c (bfd_elf_xtensa_reloc): likewise + * elf64-ppc.c (ppc64_elf_brtaken_reloc): likewise. + (ppc64_elf_addr16_ha_reloc): likewise. + (ppc64_elf_toc64_reloc): likewise. + * elflink.c (bfd_elf_final_link): likewise. + (bfd_elf_perform_complex_relocation): likewise. + (elf_fixup_link_order): likewise. + (elf_link_input_bfd): likewise. + (elf_link_sort_relocs): likewise. + (elf_reloc_link_order): likewise. + (resolve_section): likewise. + * linker.c (_bfd_generic_reloc_link_order): likewise. + (bfd_generic_define_common_symbol): likewise. + (default_data_link_order): likewise. + (default_indirect_link_order): likewise. + * srec.c (srec_set_section_contents): likewise. + (srec_write_section): likewise. + * syms.c (_bfd_stab_section_find_nearest_line): likewise. + * reloc.c (_bfd_final_link_relocate): likewise. + (bfd_generic_get_relocated_section_contents): likewise. + (bfd_install_relocation): likewise. + For section which have SEC_ELF_OCTETS set, multiply output_base + and output_offset with bfd_octets_per_byte. + (bfd_perform_relocation): likewise. + 2019-11-21 Alan Modra <amodra@gmail.com> * elf32-arm.c (elf32_arm_size_stubs): Exclude dynamic library diff --git a/bfd/archures.c b/bfd/archures.c index 569876e..1e66110 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -1379,7 +1379,8 @@ FUNCTION bfd_octets_per_byte SYNOPSIS - unsigned int bfd_octets_per_byte (const bfd *abfd); + unsigned int bfd_octets_per_byte (const bfd *abfd, + const asection *sec); DESCRIPTION Return the number of octets (8-bit quantities) per target byte @@ -1388,10 +1389,17 @@ DESCRIPTION */ unsigned int -bfd_octets_per_byte (const bfd *abfd) +bfd_octets_per_byte (const bfd *abfd, const asection *sec) { - return bfd_arch_mach_octets_per_byte (bfd_get_arch (abfd), - bfd_get_mach (abfd)); + 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 opb; } /* diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index a00dfa35..80ff8e8 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -992,6 +992,11 @@ typedef struct bfd_section /* This section contains vliw code. This is for Toshiba MeP only. */ #define SEC_MEP_VLIW 0x20000000 + /* All symbols, sizes and relocations in this section are octets + instead of bytes. Required for DWARF debug sections as DWARF + information is organized in octets, not bytes. */ +#define SEC_ELF_OCTETS 0x40000000 + /* Indicate that section has the no read flag set. This happens when memory read flag isn't set. */ #define SEC_COFF_NOREAD 0x40000000 @@ -1993,7 +1998,8 @@ const bfd_arch_info_type *bfd_lookup_arch const char *bfd_printable_arch_mach (enum bfd_architecture arch, unsigned long machine); -unsigned int bfd_octets_per_byte (const bfd *abfd); +unsigned int bfd_octets_per_byte (const bfd *abfd, + const asection *sec); unsigned int bfd_arch_mach_octets_per_byte (enum bfd_architecture arch, unsigned long machine); @@ -6854,7 +6860,8 @@ bfd_get_section_limit_octets (const bfd *abfd, const asection *sec) 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); + return (bfd_get_section_limit_octets (abfd, sec) + / bfd_octets_per_byte (abfd, NULL)); } /* Functions to handle insertion and deletion of a bfd's sections. These @@ -492,7 +492,8 @@ CODE_FRAGMENT .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); +. return (bfd_get_section_limit_octets (abfd, sec) +. / bfd_octets_per_byte (abfd, NULL)); .} . .{* Functions to handle insertion and deletion of a bfd's sections. These diff --git a/bfd/binary.c b/bfd/binary.c index eb87d11..06dfdf7 100644 --- a/bfd/binary.c +++ b/bfd/binary.c @@ -230,7 +230,6 @@ binary_set_section_contents (bfd *abfd, if (! abfd->output_has_begun) { - unsigned int opb; bfd_boolean found_low; bfd_vma low; asection *s; @@ -251,9 +250,10 @@ binary_set_section_contents (bfd *abfd, found_low = TRUE; } - opb = bfd_octets_per_byte (abfd); for (s = abfd->sections; s != NULL; s = s->next) { + unsigned int opb = bfd_octets_per_byte (abfd, s); + s->filepos = (s->lma - low) * opb; /* Skip following warning check for sections that will not diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index c9a7c09..e297df2 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -118,7 +118,7 @@ coff_arm_reloc (bfd *abfd, if (! bfd_reloc_offset_in_range (howto, abfd, input_section, reloc_entry->address - * bfd_octets_per_byte (abfd))) + * bfd_octets_per_byte (abfd, NULL))) return bfd_reloc_outofrange; switch (howto->size) diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c index 9810fd7..f28eb8a 100644 --- a/bfd/coff-i386.c +++ b/bfd/coff-i386.c @@ -146,7 +146,7 @@ coff_i386_reloc (bfd *abfd, if (! bfd_reloc_offset_in_range (howto, abfd, input_section, reloc_entry->address - * bfd_octets_per_byte (abfd))) + * bfd_octets_per_byte (abfd, NULL))) return bfd_reloc_outofrange; switch (howto->size) diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c index c6fe679..c9c7fc6 100644 --- a/bfd/coff-mips.c +++ b/bfd/coff-mips.c @@ -507,7 +507,7 @@ mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED, if (! bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section, reloc_entry->address - * bfd_octets_per_byte (abfd))) + * bfd_octets_per_byte (abfd, NULL))) return bfd_reloc_outofrange; /* Do the REFHI relocation. Note that we actually don't diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c index c5e9a34..94fd7ac 100644 --- a/bfd/coff-x86_64.c +++ b/bfd/coff-x86_64.c @@ -145,7 +145,7 @@ coff_amd64_reloc (bfd *abfd, if (! bfd_reloc_offset_in_range (howto, abfd, input_section, reloc_entry->address - * bfd_octets_per_byte (abfd))) + * bfd_octets_per_byte (abfd, NULL))) return bfd_reloc_outofrange; switch (howto->size) diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 2115e9c..23a8e6b 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -2541,7 +2541,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) /* Write out the modified section contents. */ if (secdata == NULL || secdata->stab_info == NULL) { - file_ptr loc = o->output_offset * bfd_octets_per_byte (output_bfd); + file_ptr loc = (o->output_offset + * bfd_octets_per_byte (output_bfd, NULL)); if (! bfd_set_section_contents (output_bfd, o->output_section, contents, loc, o->size)) return FALSE; @@ -2852,7 +2853,7 @@ _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); + loc = link_order->offset * bfd_octets_per_byte (output_bfd, NULL); ok = bfd_set_section_contents (output_bfd, output_section, buf, loc, size); free (buf); @@ -1120,6 +1120,15 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, p = NULL, n = 0; if (p != NULL && strncmp (name, p, n) == 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; + } } } @@ -12054,7 +12063,8 @@ _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) - offset; + offset = ((sec->size - address_size) + / bfd_octets_per_byte (abfd, NULL) - offset); } return offset; } diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c index d581dbc..7f675fc 100644 --- a/bfd/elf32-msp430.c +++ b/bfd/elf32-msp430.c @@ -36,7 +36,7 @@ rl78_sym_diff_handler (bfd * abfd, char ** error_message ATTRIBUTE_UNUSED) { bfd_size_type octets; - octets = reloc->address * bfd_octets_per_byte (abfd); + octets = reloc->address * bfd_octets_per_byte (abfd, NULL); /* 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 482fb29..a47d98e 100644 --- a/bfd/elf32-nds32.c +++ b/bfd/elf32-nds32.c @@ -13220,7 +13220,7 @@ 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); + off = (*parent)->address * bfd_octets_per_byte (input_bfd, NULL); _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 b9bcc50..0e6a347 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -956,7 +956,7 @@ ppc_elf_addr16_ha_reloc (bfd *abfd, + input_section->output_section->vma); value >>= 16; - octets = reloc_entry->address * bfd_octets_per_byte (abfd); + octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); 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 054f165..98b2018 100644 --- a/bfd/elf32-pru.c +++ b/bfd/elf32-pru.c @@ -537,7 +537,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); + bfd_size_type octets = offset * bfd_octets_per_byte (abfd, NULL); bfd_byte *location; unsigned long in1, in2; @@ -557,7 +557,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); + location = data + offset * bfd_octets_per_byte (abfd, NULL); BFD_ASSERT (!howto->pc_relative); diff --git a/bfd/elf32-s12z.c b/bfd/elf32-s12z.c index ba64985..8b3099c 100644 --- a/bfd/elf32-s12z.c +++ b/bfd/elf32-s12z.c @@ -43,7 +43,8 @@ opru18_reloc (bfd *abfd, arelent *reloc_entry, struct bfd_symbol *symbol, is shifted one place to the left of where it would normally be. See Appendix A.4 of the S12Z reference manual. */ - bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte (abfd); + bfd_size_type octets = (reloc_entry->address + * bfd_octets_per_byte (abfd, NULL)); 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 c10691e..3dc25ee 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -254,7 +254,8 @@ 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) + bfd_get_reloc_size (reloc_entry->howto) + if ((addr * bfd_octets_per_byte (abfd, NULL) + + 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 9a1648f..6f8b32a 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -212,7 +212,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); + octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); /* Get symbol value. */ val = 0; diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 306b18b..31e9530 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -2103,7 +2103,8 @@ 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); + bfd_size_type octets = (reloc_entry->address + * bfd_octets_per_byte (abfd, NULL)); 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 4ece6fb..5c7f323 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -1405,7 +1405,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); + octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); insn = bfd_get_32 (abfd, (bfd_byte *) data + octets); insn &= ~0x1fffc1; insn |= (value & 0xffc1) | ((value & 0x3e) << 15); @@ -1480,7 +1480,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); + octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); insn = bfd_get_32 (abfd, (bfd_byte *) data + octets); insn &= ~(0x01 << 21); r_type = reloc_entry->howto->type; @@ -1630,7 +1630,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); + octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL); 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 9d7f69a..824669a 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -8456,7 +8456,8 @@ resolve_section (const char *name, { if (strncmp (".end", name + len, 4) == 0) { - *result = curr->vma + curr->size / bfd_octets_per_byte (abfd); + *result = (curr->vma + + curr->size / bfd_octets_per_byte (abfd, NULL)); return TRUE; } @@ -8778,7 +8779,8 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd, shift = (8 * wordsz) - (start + len); x = get_value (wordsz, chunksz, input_bfd, - contents + rel->r_offset * bfd_octets_per_byte (input_bfd)); + contents + + rel->r_offset * bfd_octets_per_byte (input_bfd, NULL)); #ifdef DEBUG printf ("Doing complex reloc: " @@ -8811,7 +8813,7 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd, (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)); + contents + rel->r_offset * bfd_octets_per_byte (input_bfd, NULL)); return r; } @@ -9175,7 +9177,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) struct elf_link_sort_rela *sq; const struct elf_backend_data *bed = get_elf_backend_data (abfd); int i2e = bed->s->int_rels_per_ext_rel; - unsigned int opb = bfd_octets_per_byte (abfd); + unsigned int opb = bfd_octets_per_byte (abfd, NULL); void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); struct bfd_link_order *lo; @@ -11303,7 +11305,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); + offset *= bfd_octets_per_byte (output_bfd, NULL); if ((o->flags & SEC_ELF_REVERSE_COPY)) { @@ -11465,7 +11467,7 @@ elf_reloc_link_order (bfd *output_bfd, ok = bfd_set_section_contents (output_bfd, output_section, buf, link_order->offset - * bfd_octets_per_byte (output_bfd), + * bfd_octets_per_byte (output_bfd, NULL), size); free (buf); if (! ok) @@ -11633,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); + s->output_offset = offset / bfd_octets_per_byte (abfd, NULL); sections[n]->offset = offset; offset += sections[n]->size; } @@ -12857,7 +12859,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (! bfd_set_section_contents (abfd, o->output_section, o->contents, (file_ptr) o->output_offset - * bfd_octets_per_byte (abfd), + * bfd_octets_per_byte (abfd, + NULL), o->size)) goto error_return; } diff --git a/bfd/linker.c b/bfd/linker.c index 382b69d..b247cf5 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -2402,7 +2402,7 @@ _bfd_generic_reloc_link_order (bfd *abfd, NULL, NULL, 0); break; } - loc = link_order->offset * bfd_octets_per_byte (abfd); + loc = link_order->offset * bfd_octets_per_byte (abfd, sec); ok = bfd_set_section_contents (abfd, sec, buf, loc, size); free (buf); if (! ok) @@ -2518,7 +2518,7 @@ default_data_link_order (bfd *abfd, } } - loc = link_order->offset * bfd_octets_per_byte (abfd); + loc = link_order->offset * bfd_octets_per_byte (abfd, sec); result = bfd_set_section_contents (abfd, sec, fill, loc, size); if (fill != link_order->u.data.contents) @@ -2655,7 +2655,8 @@ default_indirect_link_order (bfd *output_bfd, } /* Output the section contents. */ - loc = input_section->output_offset * bfd_octets_per_byte (output_bfd); + loc = (input_section->output_offset + * bfd_octets_per_byte (output_bfd, output_section)); if (! bfd_set_section_contents (output_bfd, output_section, new_contents, loc, input_section->size)) goto error_return; @@ -3099,7 +3100,7 @@ bfd_generic_define_common_symbol (bfd *output_bfd, /* Increase the size of the section to align the common symbol. The alignment must be a power of two. */ - alignment = bfd_octets_per_byte (output_bfd) << power_of_two; + alignment = bfd_octets_per_byte (output_bfd, section) << power_of_two; BFD_ASSERT (alignment != 0 && (alignment & -alignment) == alignment); section->size += alignment - 1; section->size &= -alignment; diff --git a/bfd/reloc.c b/bfd/reloc.c index cc842d7514..e01cb51 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -722,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; @@ -744,7 +744,14 @@ bfd_perform_relocation (bfd *abfd, else output_base = reloc_target_output_section->vma; - relocation += output_base + symbol->section->output_offset; + /* For sections where relocations are in octets, output_base and + output_offset must also be converted to octets. */ + 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; /* Add in supplied addend. */ relocation += reloc_entry->addend; @@ -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; + /* For sections where relocations are in octets, output_base and + output_offset must also be converted to octets. */ + 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; /* Add in supplied addend. */ relocation += reloc_entry->addend; @@ -1337,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)) @@ -1369,7 +1384,9 @@ _bfd_final_link_relocate (reloc_howto_type *howto, return _bfd_relocate_contents (howto, input_bfd, relocation, contents - + address * bfd_octets_per_byte (input_bfd)); + + address + * bfd_octets_per_byte (input_bfd, + input_section)); } /* Relocate a given location using a given value and howto. */ @@ -8346,7 +8363,8 @@ bfd_generic_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); + 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; diff --git a/bfd/section.c b/bfd/section.c index 34e08ae..470792d 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -351,6 +351,11 @@ CODE_FRAGMENT . {* This section contains vliw code. This is for Toshiba MeP only. *} .#define SEC_MEP_VLIW 0x20000000 . +. {* All symbols, sizes and relocations in this section are octets +. instead of bytes. Required for DWARF debug sections as DWARF +. information is organized in octets, not bytes. *} +.#define SEC_ELF_OCTETS 0x40000000 +. . {* Indicate that section has the no read flag set. This happens . when memory read flag isn't set. *} .#define SEC_COFF_NOREAD 0x40000000 @@ -885,7 +885,7 @@ srec_set_section_contents (bfd *abfd, file_ptr offset, bfd_size_type bytes_to_do) { - int opb = bfd_octets_per_byte (abfd); + int opb = bfd_octets_per_byte (abfd, NULL); tdata_type *tdata = abfd->tdata.srec_data; srec_data_list_type *entry; @@ -1053,7 +1053,8 @@ srec_write_section (bfd *abfd, if (octets_this_chunk > _bfd_srec_len) octets_this_chunk = _bfd_srec_len; - address = list->where + octets_written / bfd_octets_per_byte (abfd); + address = list->where + (octets_written + / bfd_octets_per_byte (abfd, NULL)); if (! srec_write_record (abfd, tdata->type, @@ -1090,7 +1090,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd, || r->howto->pc_relative || r->howto->bitpos != 0 || r->howto->dst_mask != 0xffffffff - || r->address * bfd_octets_per_byte (abfd) + 4 > stabsize) + || (r->address * bfd_octets_per_byte (abfd, NULL) + 4 + > stabsize)) { _bfd_error_handler (_("unsupported .stab relocation")); @@ -1101,12 +1102,13 @@ _bfd_stab_section_find_nearest_line (bfd *abfd, } val = bfd_get_32 (abfd, info->stabs - + r->address * bfd_octets_per_byte (abfd)); + + (r->address + * bfd_octets_per_byte (abfd, NULL))); 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)); + + r->address * bfd_octets_per_byte (abfd, NULL)); } } diff --git a/binutils/ChangeLog b/binutils/ChangeLog index c4f7e3d..7c0d0fe 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,10 @@ +2019-11-25 Christian Eggers <ceggers@gmx.de> + + * objdump.c (disassemble_data): Provide section parameter to + bfd_octets_per_byte. + (dump_section): likewise + (dump_section_header): likewise. Show SEC_ELF_OCTETS flag if set. + 2019-11-21 Alan Modra <amodra@gmail.com> PR 273 diff --git a/binutils/objdump.c b/binutils/objdump.c index 1be3b23..115f1fc 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -532,7 +532,7 @@ static void dump_section_header (bfd *abfd, asection *section, void *data) { char *comma = ""; - unsigned int opb = bfd_octets_per_byte (abfd); + unsigned int opb = bfd_octets_per_byte (abfd, section); int longest_section_name = *((int *) data); /* Ignore linker created section. See elfNN_ia64_object_p in @@ -584,7 +584,10 @@ dump_section_header (bfd *abfd, asection *section, void *data) PF (SEC_COFF_NOREAD, "NOREAD"); } else if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - PF (SEC_ELF_PURECODE, "PURECODE"); + { + PF (SEC_ELF_OCTETS, "OCTETS"); + PF (SEC_ELF_PURECODE, "PURECODE"); + } PF (SEC_THREAD_LOCAL, "THREAD_LOCAL"); PF (SEC_GROUP, "GROUP"); if (bfd_get_arch (abfd) == bfd_arch_mep) @@ -2682,7 +2685,7 @@ disassemble_data (bfd *abfd) disasm_info.arch = bfd_get_arch (abfd); disasm_info.mach = bfd_get_mach (abfd); disasm_info.disassembler_options = disassembler_options; - disasm_info.octets_per_byte = bfd_octets_per_byte (abfd); + disasm_info.octets_per_byte = bfd_octets_per_byte (abfd, NULL); disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES; disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END; disasm_info.disassembler_needs_relocs = FALSE; @@ -3459,7 +3462,7 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) bfd_vma addr_offset; bfd_vma start_offset; bfd_vma stop_offset; - unsigned int opb = bfd_octets_per_byte (abfd); + unsigned int opb = bfd_octets_per_byte (abfd, section); /* Bytes per line. */ const int onaline = 16; char buf[64]; diff --git a/gas/ChangeLog b/gas/ChangeLog index 1751b00..b3affbb 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,17 @@ 2019-11-25 Christian Eggers <ceggers@gmx.de> + * as.h: Define SEC_OCTETS as SEC_ELF_OCTETS if OBJ_ELF. + * dwarf2dbg.c: (dwarf2_finish): Set section flag SEC_OCTETS for + .debug_line, .debug_info, .debug_abbrev, .debug_aranges, .debug_str + and .debug_ranges sections. + * write.c (maybe_generate_build_notes): Set section flag + SEC_OCTETS for .gnu.build.attributes section. + * frags.c (frag_now_fix): Don't divide by OCTETS_PER_BYTE if + SEC_OCTETS is set. + * symbols.c (resolve_symbol_value): Likewise. + +2019-11-25 Christian Eggers <ceggers@gmx.de> + * dwarf2dbg.c (out_set_addr): Revert 2019-03-13 change. (out_debug_line, out_debug_aranges, out_debug_info): Likewise. * symbols.h (symbol_set_value_now_octets, symbol_octets_p): Remove. @@ -649,4 +649,11 @@ COMMON int flag_sectname_subst; #error "Octets per byte conflicts with its power-of-two definition!" #endif +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF +/* On ELF platforms, mark debug sections with SEC_ELF_OCTETS */ +#define SEC_OCTETS (IS_ELF ? SEC_ELF_OCTETS : 0) +#else +#define SEC_OCTETS 0 +#endif + #endif /* GAS */ diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c index dce9603..001e2a1 100644 --- a/gas/dwarf2dbg.c +++ b/gas/dwarf2dbg.c @@ -2215,7 +2215,7 @@ dwarf2_finish (void) /* Create and switch to the line number section. */ line_seg = subseg_new (".debug_line", 0); - bfd_set_section_flags (line_seg, SEC_READONLY | SEC_DEBUGGING); + bfd_set_section_flags (line_seg, SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS); /* For each subsection, chain the debug entries together. */ for (s = all_segs; s; s = s->next) @@ -2261,11 +2261,15 @@ dwarf2_finish (void) aranges_seg = subseg_new (".debug_aranges", 0); str_seg = subseg_new (".debug_str", 0); - bfd_set_section_flags (info_seg, SEC_READONLY | SEC_DEBUGGING); - bfd_set_section_flags (abbrev_seg, SEC_READONLY | SEC_DEBUGGING); - bfd_set_section_flags (aranges_seg, SEC_READONLY | SEC_DEBUGGING); - bfd_set_section_flags (str_seg, (SEC_READONLY | SEC_DEBUGGING - | SEC_MERGE | SEC_STRINGS)); + bfd_set_section_flags (info_seg, + SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS); + bfd_set_section_flags (abbrev_seg, + SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS); + bfd_set_section_flags (aranges_seg, + SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS); + bfd_set_section_flags (str_seg, + SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS + | SEC_MERGE | SEC_STRINGS); str_seg->entsize = 1; record_alignment (aranges_seg, ffs (2 * sizeof_address) - 1); @@ -2275,7 +2279,8 @@ dwarf2_finish (void) else { ranges_seg = subseg_new (".debug_ranges", 0); - bfd_set_section_flags (ranges_seg, SEC_READONLY | SEC_DEBUGGING); + bfd_set_section_flags (ranges_seg, + SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS); record_alignment (ranges_seg, ffs (2 * sizeof_address) - 1); out_debug_ranges (ranges_seg); } diff --git a/gas/frags.c b/gas/frags.c index 2f21b9d..f35cc80 100644 --- a/gas/frags.c +++ b/gas/frags.c @@ -395,7 +395,12 @@ frag_now_fix_octets (void) addressT frag_now_fix (void) { - return frag_now_fix_octets () / OCTETS_PER_BYTE; + /* Symbols whose section has SEC_ELF_OCTETS set, + resolve to octets instead of target bytes. */ + if (now_seg->flags & SEC_OCTETS) + return frag_now_fix_octets (); + else + return frag_now_fix_octets () / OCTETS_PER_BYTE; } void diff --git a/gas/symbols.c b/gas/symbols.c index cff2405..857a3e6 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1217,7 +1217,13 @@ resolve_symbol_value (symbolS *symp) if (local_symbol_resolved_p (locsym)) return final_val; - final_val += local_symbol_get_frag (locsym)->fr_address / OCTETS_PER_BYTE; + /* Symbols whose section has SEC_ELF_OCTETS set, + resolve to octets instead of target bytes. */ + if (locsym->lsy_section->flags & SEC_OCTETS) + final_val += local_symbol_get_frag (locsym)->fr_address; + else + final_val += (local_symbol_get_frag (locsym)->fr_address + / OCTETS_PER_BYTE); if (finalize_syms) { @@ -1330,7 +1336,12 @@ resolve_symbol_value (symbolS *symp) /* Fall through. */ case O_constant: - final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE; + /* Symbols whose section has SEC_ELF_OCTETS set, + resolve to octets instead of target bytes. */ + if (symp->bsym->section->flags & SEC_OCTETS) + final_val += symp->sy_frag->fr_address; + else + final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE; if (final_seg == expr_section) final_seg = absolute_section; /* Fall through. */ diff --git a/gas/write.c b/gas/write.c index 8f7786e..d5da418 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1960,7 +1960,8 @@ maybe_generate_build_notes (void) /* Create a GNU Build Attribute section. */ sec = subseg_new (GNU_BUILD_ATTRS_SECTION_NAME, FALSE); elf_section_type (sec) = SHT_NOTE; - bfd_set_section_flags (sec, SEC_READONLY | SEC_HAS_CONTENTS | SEC_DATA); + bfd_set_section_flags (sec, (SEC_READONLY | SEC_HAS_CONTENTS | SEC_DATA + | SEC_OCTETS)); bfd_set_section_alignment (sec, 2); /* Work out the size of the notes that we will create, diff --git a/include/ChangeLog b/include/ChangeLog index 3ead011..47bb86c 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2019-11-25 Alan Modra <amodra@gmail.com> + + * coff/ti.h (GET_SCNHDR_SIZE, PUT_SCNHDR_SIZE, GET_SCN_SCNLEN), + (PUT_SCN_SCNLEN): Adjust bfd_octets_per_byte calls. + 2019-11-22 Mihail Ionescu <mihail.ionescu@arm.com> * opcode/arm.h (ARM_EXT2_CRC): New extension feature @@ -26,7 +31,7 @@ instructions that do not require special handling. 2019-11-07 Mihail Ionescu <mihail.ionescu@arm.com> -2019-11-07 Matthew Malcomson <matthew.malcomson@arm.com> + Matthew Malcomson <matthew.malcomson@arm.com> * opcode/arm.h (ARM_EXT2_V8_6A, ARM_AEXT2_V8_6A, ARM_ARCH_V8_6A): New. @@ -34,7 +39,7 @@ (ARM_AEXT2_V8_6A): Include above macro in definition. 2019-11-07 Mihail Ionescu <mihail.ionescu@arm.com> -2019-11-07 Matthew Malcomson <matthew.malcomson@arm.com> + Matthew Malcomson <matthew.malcomson@arm.com> * opcode/aarch64.h (AARCH64_FEATURE_BFLOAT16): New feature macros. (AARCH64_ARCH_V8_6): Include BFloat16 feature macros. @@ -45,7 +50,7 @@ instructions to support the movprfx constraint. 2019-11-07 Mihail Ionescu <mihail.ionescu@arm.com> -2019-11-07 Matthew Malcomson <matthew.malcomson@arm.com> + Matthew Malcomson <matthew.malcomson@arm.com> * opcode/aarch64.h (AARCH64_FEATURE_V8_6): New. (AARCH64_ARCH_V8_6): New. diff --git a/include/coff/ti.h b/include/coff/ti.h index 0e8f532..17bac8c 100644 --- a/include/coff/ti.h +++ b/include/coff/ti.h @@ -313,9 +313,9 @@ struct external_scnhdr { /* TI COFF stores section size as number of bytes (address units, not octets), so adjust to be number of octets, which is what BFD expects */ #define GET_SCNHDR_SIZE(ABFD, SZP) \ - (H_GET_32 (ABFD, SZP) * bfd_octets_per_byte (ABFD)) + (H_GET_32 (ABFD, SZP) * bfd_octets_per_byte (ABFD, NULL)) #define PUT_SCNHDR_SIZE(ABFD, SZ, SZP) \ - H_PUT_32 (ABFD, (SZ) / bfd_octets_per_byte (ABFD), SZP) + H_PUT_32 (ABFD, (SZ) / bfd_octets_per_byte (ABFD, NULL), SZP) #define COFF_ADJUST_SCNHDR_IN_POST(ABFD, EXT, INT) \ do \ @@ -471,9 +471,9 @@ union external_auxent { /* section lengths are in target bytes (not host bytes) */ #define GET_SCN_SCNLEN(ABFD, EXT) \ - (H_GET_32 (ABFD, (EXT)->x_scn.x_scnlen) * bfd_octets_per_byte (ABFD)) + (H_GET_32 (ABFD, (EXT)->x_scn.x_scnlen) * bfd_octets_per_byte (ABFD, NULL)) #define PUT_SCN_SCNLEN(ABFD, INT, EXT) \ - H_PUT_32 (ABFD, (INT) / bfd_octets_per_byte (ABFD), (EXT)->x_scn.x_scnlen) + H_PUT_32 (ABFD, (INT) / bfd_octets_per_byte (ABFD, NULL), (EXT)->x_scn.x_scnlen) /* lnsz size is in bits in COFF file, in bytes in BFD */ #define GET_LNSZ_SIZE(abfd, ext) \ diff --git a/ld/ChangeLog b/ld/ChangeLog index 6498fb0..e969c0f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,18 @@ +2019-11-25 Christian Eggers <ceggers@gmx.de> + + * ldexp.c (fold_name): Provide section parameter to + bfd_octets_per_byte. + * ldlang (init_opb): New argument s. Set opb_shift to 0 if + SEC_ELF_OCTETS for the current section is set. + (print_input_section): Pass current section to init_opb. + (print_data_statement,print_reloc_statement, + print_padding_statement): Likewise. + (lang_check_section_addresses): Call init_opb for each + section. + (lang_size_sections_1,lang_size_sections_1, + lang_do_assignments_1): Likewise. + (lang_process): Pass NULL to init_opb. + 2019-11-22 Nick Clifton <nickc@redhat.com> * ld.texi (Output Section Discarding): Add note indicating that @@ -852,7 +852,7 @@ fold_name (etree_type *tree) if (tree->type.node_code == SIZEOF) val = (os->bfd_section->size - / bfd_octets_per_byte (link_info.output_bfd)); + / bfd_octets_per_byte (link_info.output_bfd, NULL)); else val = (bfd_vma)1 << os->bfd_section->alignment_power; diff --git a/ld/ldlang.c b/ld/ldlang.c index eedcb7f..3bcab7a 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -3440,10 +3440,17 @@ ldlang_open_output (lang_statement_union_type *statement) } static void -init_opb (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; + } + opb_shift = 0; if (x > 1) while ((x & 1) == 0) @@ -4626,7 +4633,7 @@ print_input_section (asection *i, bfd_boolean is_discarded) int len; bfd_vma addr; - init_opb (); + init_opb (i); print_space (); minfo ("%s", i->name); @@ -4707,7 +4714,7 @@ print_data_statement (lang_data_statement_type *data) bfd_size_type size; const char *name; - init_opb (); + init_opb (data->output_section); for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) print_space (); @@ -4776,7 +4783,7 @@ print_reloc_statement (lang_reloc_statement_type *reloc) bfd_vma addr; bfd_size_type size; - init_opb (); + init_opb (reloc->output_section); for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) print_space (); @@ -4806,7 +4813,7 @@ print_padding_statement (lang_padding_statement_type *s) int len; bfd_vma addr; - init_opb (); + init_opb (s->output_section); minfo (" *fill*"); len = sizeof " *fill*" - 1; @@ -5276,6 +5283,7 @@ lang_check_section_addresses (void) for (p = NULL, i = 0; i < count; i++) { s = sections[i].sec; + init_opb (s); if ((s->flags & SEC_LOAD) != 0) { s_start = s->lma; @@ -5326,6 +5334,7 @@ lang_check_section_addresses (void) for (p = NULL, i = 0; i < count; i++) { s = sections[i].sec; + init_opb (s); s_start = s->vma; s_end = s_start + TO_ADDR (s->size) - 1; @@ -5450,6 +5459,7 @@ lang_size_sections_1 int section_alignment = 0; os = &s->output_section_statement; + init_opb (os->bfd_section); if (os->constraint == -1) break; @@ -6191,6 +6201,7 @@ lang_do_assignments_1 (lang_statement_union_type *s, os = &(s->output_section_statement); os->after_end = *found_end; + init_opb (os->bfd_section); if (os->bfd_section != NULL && !os->ignored) { if ((os->bfd_section->flags & SEC_ALLOC) != 0) @@ -7622,7 +7633,7 @@ lang_process (void) /* Open the output file. */ lang_for_each_statement (ldlang_open_output); - init_opb (); + init_opb (NULL); ldemul_create_output_section_statements (); |