This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 6/9] [bfd] Introduce new section flag: SEC_ELF_OCTETS
- From: Christian Eggers <ceggers at gmx dot de>
- To: binutils at sourceware dot org
- Cc: Christian Eggers <ceggers at gmx dot de>
- Date: Sun, 17 Nov 2019 00:21:27 +0100
- Subject: [PATCH 6/9] [bfd] Introduce new section flag: SEC_ELF_OCTETS
- References: <20191116232130.14278-1-ceggers@gmx.de>
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.
* section.c (struct bfd_section): New flag SEC_ELF_OCTETS.
* bfd-in2.h: Regenerate.
* elf.c (_bfd_elf_make_section_from_shdr): Set SEC_ELF_OCTETS
for sections with names .gnu.build.attributes, .debug*,
.zdebug* and .note.gnu*.
* archures.c (bfd_section_octets_per_byte): New function.
* binary.c (binary_set_section_contents): Call
bfd_section_octets_per_byte() for each section.
* linker.c (_bfd_generic_reloc_link_order): Use
bfd_section_octets_per_byte() instead of bfd_octets_per_byte().
(default_data_link_order): Likewise.
(default_indirect_link_order): Likewise.
(bfd_generic_define_common_symbol): Likewise. Set ATTRIBUTE_UNUSED
for argument argument output_bfd.
* reloc.c (bfd_perform_relocation): Use
bfd_section_octets_per_byte() instead of bfd_octets_per_byte().
For section which have SEC_ELF_OCTETS set, multiply output_base
and output_offset with bfd_octets_per_byte().
(bfd_install_relocation): Likewise.
(_bfd_final_link_relocate): Use bfd_section_octets_per_byte().
(bfd_generic_get_relocated_section_contents): Likewise.
Signed-off-by: Christian Eggers <ceggers@gmx.de>
---
bfd/archures.c | 27 +++++++++++++++++++++++++++
bfd/bfd-in2.h | 8 ++++++++
bfd/binary.c | 4 ++--
bfd/elf.c | 9 +++++++++
bfd/linker.c | 11 ++++++-----
bfd/reloc.c | 30 +++++++++++++++++++++++-------
bfd/section.c | 5 +++++
7 files changed, 80 insertions(+), 14 deletions(-)
diff --git a/bfd/archures.c b/bfd/archures.c
index 569876eed0..c949c1a789 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -1374,6 +1374,33 @@ bfd_printable_arch_mach (enum bfd_architecture arch, unsigned long machine)
return "UNKNOWN!";
}
+/*
+FUNCTION
+ bfd_section_octets_per_byte
+
+SYNOPSIS
+ unsigned int bfd_section_octets_per_byte (const asection *sec);
+
+DESCRIPTION
+ Return the number of octets (8-bit quantities) per target byte
+ (minimum addressable unit) for a particular section. A target can use
+ more than one octet per byte for normal sections (like ".text", ".data"
+ or ".bss), but nevertheless use only one octet per byte for special
+ sections like ".(z)debug*" or ".gnu.build.attributes".
+*/
+
+unsigned int
+bfd_section_octets_per_byte (const asection *sec)
+{
+ unsigned int opb = bfd_octets_per_byte (sec->owner);
+
+ if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour &&
+ sec && (sec->flags & SEC_ELF_OCTETS))
+ opb = 1;
+
+ return opb;
+}
+
/*
FUNCTION
bfd_octets_per_byte
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 3244905b45..714a4dd423 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,6 +1998,9 @@ const bfd_arch_info_type *bfd_lookup_arch
const char *bfd_printable_arch_mach
(enum bfd_architecture arch, unsigned long machine);
+unsigned int bfd_section_octets_per_byte
+ (const asection *sec);
+
unsigned int bfd_octets_per_byte (const bfd *abfd);
unsigned int bfd_arch_mach_octets_per_byte
diff --git a/bfd/binary.c b/bfd/binary.c
index eb87d11b6e..c0cd0852ba 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_section_octets_per_byte (s);
+
s->filepos = (s->lma - low) * opb;
/* Skip following warning check for sections that will not
diff --git a/bfd/elf.c b/bfd/elf.c
index be060d579c..21e734f95e 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1121,6 +1121,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;
+ }
}
}
diff --git a/bfd/linker.c b/bfd/linker.c
index 382b69d8c3..533ef361cb 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_section_octets_per_byte (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_section_octets_per_byte (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_section_octets_per_byte (output_section);
if (! bfd_set_section_contents (output_bfd, output_section,
new_contents, loc, input_section->size))
goto error_return;
@@ -3083,7 +3084,7 @@ DESCRIPTION
*/
bfd_boolean
-bfd_generic_define_common_symbol (bfd *output_bfd,
+bfd_generic_define_common_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info ATTRIBUTE_UNUSED,
struct bfd_link_hash_entry *h)
{
@@ -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_section_octets_per_byte (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 ae71f6b005..534b47b459 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_section_octets_per_byte (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);
+ 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_section_octets_per_byte (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);
+ else
+ relocation += output_base + symbol->section->output_offset;
/* Add in supplied addend. */
relocation += reloc_entry->addend;
@@ -1337,7 +1351,7 @@ _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_section_octets_per_byte (input_section);
/* Sanity check the address. */
if (!bfd_reloc_offset_in_range (howto, input_bfd, input_section, octets))
@@ -1369,7 +1383,8 @@ _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_section_octets_per_byte (
+ input_section));
}
/* Relocate a given location using a given value and howto. */
@@ -8363,7 +8378,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_section_octets_per_byte (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 34e08aef57..a7906e891a 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
--
2.16.4