[8/9,gas] Introduce new section flag: SEC_ELF_OCTETS

Message ID 20191116232130.14278-9-ceggers@gmx.de
State Superseded
Headers show
Series
  • ELF support for targets with octets_per_byte>1
Related show

Commit Message

Christian Eggers Nov. 16, 2019, 11:21 p.m.
All symbols, sizes and relocations in this sections are octets instead of
bytes. Required for DWARF debug sections as DWARF information is
organized in octets, not bytes.

	* dwarf2dbg.c: Define SEC_OCTETS as SEC_ELF_OCTETS if OBJ_ELF.
	(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_ELF_OCTETS for .gnu.build.attributes section.
	* frags.c (frag_now_fix): Don't divide by OCTETS_PER_BYTE if
	SEC_ELF_OCTETS is set.
	* symbols.c (resolve_symbol_value): Likewise.

Signed-off-by: Christian Eggers <ceggers@gmx.de>

---
 gas/dwarf2dbg.c | 26 +++++++++++++++++++-------
 gas/frags.c     |  9 ++++++++-
 gas/symbols.c   | 18 ++++++++++++++++--
 gas/write.c     |  6 +++++-
 4 files changed, 48 insertions(+), 11 deletions(-)

--
2.16.4

Comments

Alan Modra Nov. 20, 2019, 12:18 a.m. | #1
On Sun, Nov 17, 2019 at 12:21:29AM +0100, Christian Eggers wrote:
> --- a/gas/dwarf2dbg.c

> +++ b/gas/dwarf2dbg.c

> @@ -162,6 +162,13 @@

>  #define TC_PARSE_CONS_RETURN_NONE BFD_RELOC_NONE

>  #endif

> 

> +#ifdef OBJ_ELF

> +/* On ELF platforms, mark debug sections with SEC_ELF_OCTETS */

> +#define SEC_OCTETS SEC_ELF_OCTETS

> +#else

> +#define SEC_OCTETS 0

> +#endif

> +


This isn't quite correct.  The right way to conditionally set flags is
like the following from write.c:

#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
  if (IS_ELF && flag_use_elf_stt_common)
    stdoutput->flags |= BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON;
#endif

So you probably should use

#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

Pedantically, it's fine to just use #ifdef OBJ_ELF rather than the
explicit #if defined OBJ_ELF || defined OBJ_MAYBE_ELF since it happens
that OBJ_MAYBE_ELF results in gas/config/obj-elf.h being included from
gas/config/obj-multi.h and OBJ_ELF being defined, but I think it's
better to reference OBJ_MAYBE_ELF to make the code clearer.

I don't know whether we should worry too much about continuing to
support multi-object emulation..  One of the configurations that
supported multiple object formats in gas, --target=i586-elf
--enable-targets=i586-coff,i586-aout, is no longer supported.
However, you can still get an x86 gas that supports multiple 
emulations with --target=i586-elf --enable-targets=all.

-- 
Alan Modra
Australia Development Lab, IBM



-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index dce96033df..6ae65dc874 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -162,6 +162,13 @@ 
 #define TC_PARSE_CONS_RETURN_NONE BFD_RELOC_NONE
 #endif

+#ifdef OBJ_ELF
+/* On ELF platforms, mark debug sections with SEC_ELF_OCTETS */
+#define SEC_OCTETS SEC_ELF_OCTETS
+#else
+#define SEC_OCTETS 0
+#endif
+
 struct line_entry
 {
   struct line_entry *next;
@@ -2215,7 +2222,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 +2268,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 +2286,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 2f21b9db20..71e77e5811 100644
--- a/gas/frags.c
+++ b/gas/frags.c
@@ -395,7 +395,14 @@  frag_now_fix_octets (void)
 addressT
 frag_now_fix (void)
 {
-  return frag_now_fix_octets () / OCTETS_PER_BYTE;
+#if OBJ_ELF
+  /* Symbols whose section has SEC_ELF_OCTETS set,
+   * resolve to octets instead of target bytes. */
+  if (now_seg->flags & SEC_ELF_OCTETS)
+    return frag_now_fix_octets ();
+  else
+#endif
+    return frag_now_fix_octets () / OCTETS_PER_BYTE;
 }

 void
diff --git a/gas/symbols.c b/gas/symbols.c
index cff24059e6..b40d528c0d 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -1217,7 +1217,14 @@  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;
+#if OBJ_ELF
+      /* Symbols whose section has SEC_ELF_OCTETS set,
+       * resolve to octets instead of target bytes. */
+      if (locsym->lsy_section->flags & SEC_ELF_OCTETS)
+	final_val += local_symbol_get_frag (locsym)->fr_address;
+      else
+#endif
+	final_val += local_symbol_get_frag (locsym)->fr_address / OCTETS_PER_BYTE;

       if (finalize_syms)
 	{
@@ -1330,7 +1337,14 @@  resolve_symbol_value (symbolS *symp)
 	  /* Fall through.  */

 	case O_constant:
-	  final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE;
+#if OBJ_ELF
+	  /* Symbols whose section has SEC_ELF_OCTETS set,
+	   * resolve to octets instead of target bytes. */
+	  if (symp->bsym->section->flags & SEC_ELF_OCTETS)
+	    final_val += symp->sy_frag->fr_address;
+	  else
+#endif
+	    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 8f7786eb36..a161520d2c 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -1960,7 +1960,11 @@  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
+#ifdef OBJ_ELF
+      | SEC_ELF_OCTETS
+#endif
+      );
   bfd_set_section_alignment (sec, 2);

   /* Work out the size of the notes that we will create,