This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 6/9] [bfd] Introduce new section flag: SEC_ELF_OCTETS


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]