public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] gas/ELF: allow "inheriting" section attributes and type
@ 2023-08-25 12:56 Jan Beulich
  0 siblings, 0 replies; only message in thread
From: Jan Beulich @ 2023-08-25 12:56 UTC (permalink / raw)
  To: bfd-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cefaa117f7675ce690c0ec38c353e7e4195dedcb

commit cefaa117f7675ce690c0ec38c353e7e4195dedcb
Author: Jan Beulich <jbeulich@suse.com>
Date:   Fri Aug 25 14:55:12 2023 +0200

    gas/ELF: allow "inheriting" section attributes and type
    
    While --sectname-subst is nice, it isn't enough to e.g. mimic
    -f{function,data}-sections in assembly code, when such use is to be
    optional (e.g. dependent upon some configuration setting).
    
    Assign meaning to '+' and '-' as section attribute letters, allowing
    to inherit the prior section's attributes (and possibly type) along
    with adding or removing some. Note that documenting the interaction
    with '?' as undefined is a precautionary measure.
    
    While touching the function invocation, stop using |= on the result of
    obj_elf_parse_section_letters(): "attr" is firmly zero ahead of the
    call.

Diff:
---
 gas/config/obj-elf.c              | 53 +++++++++++++++++++++++++++++--
 gas/doc/as.texi                   | 12 +++++++
 gas/testsuite/gas/elf/elf.exp     |  5 +++
 gas/testsuite/gas/elf/section30.d | 28 ++++++++++++++++
 gas/testsuite/gas/elf/section30.s | 67 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 162 insertions(+), 3 deletions(-)

diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 142f004f0b6..a9258ce334c 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -822,10 +822,12 @@ obj_elf_change_section (const char *name,
 
 static bfd_vma
 obj_elf_parse_section_letters (char *str, size_t len,
-			       bool *is_clone, bfd_vma *gnu_attr)
+			       bool *is_clone, int *inherit, bfd_vma *gnu_attr)
 {
   bfd_vma attr = 0;
+
   *is_clone = false;
+  *inherit = 0;
 
   while (len > 0)
     {
@@ -923,6 +925,8 @@ obj_elf_parse_section_letters (char *str, size_t len,
 		  len -= (end - str);
 		  str = end;
 		}
+	      else if (!attr && !*gnu_attr && (*str == '+' || *str == '-'))
+		*inherit = *str == '+' ? 1 : -1;
 	      else
 		as_fatal ("%s", bad_msg);
 	  }
@@ -1171,6 +1175,7 @@ obj_elf_section (int push)
       if (*input_line_pointer == '"')
 	{
 	  bool is_clone;
+	  int inherit;
 
 	  beg = demand_copy_C_string (&dummy);
 	  if (beg == NULL)
@@ -1178,8 +1183,15 @@ obj_elf_section (int push)
 	      ignore_rest_of_line ();
 	      return;
 	    }
-	  attr |= obj_elf_parse_section_letters (beg, strlen (beg),
-						 &is_clone, &gnu_attr);
+	  attr = obj_elf_parse_section_letters (beg, strlen (beg), &is_clone,
+						&inherit, &gnu_attr);
+
+	  if (inherit > 0)
+	    attr |= elf_section_flags (now_seg);
+	  else if (inherit < 0)
+	    attr = elf_section_flags (now_seg) & ~attr;
+	  if (inherit)
+	    type = elf_section_type (now_seg);
 
 	  SKIP_WHITESPACE ();
 	  if (*input_line_pointer == ',')
@@ -1224,6 +1236,9 @@ obj_elf_section (int push)
 	    {
 	      ++input_line_pointer;
 	      SKIP_WHITESPACE ();
+	      if (inherit && *input_line_pointer == ','
+		  && (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
+		goto fetch_entsize;
 	      entsize = get_absolute_expression ();
 	      SKIP_WHITESPACE ();
 	      if (entsize < 0)
@@ -1233,6 +1248,12 @@ obj_elf_section (int push)
 		  entsize = 0;
 		}
 	    }
+	  else if ((attr & SHF_MERGE) != 0 && inherit
+		    && (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
+	    {
+	    fetch_entsize:
+	      entsize = now_seg->entsize;
+	    }
 	  else if ((attr & SHF_MERGE) != 0)
 	    {
 	      as_warn (_("entity size for SHF_MERGE not specified"));
@@ -1248,6 +1269,9 @@ obj_elf_section (int push)
 		{
 		  linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
 		}
+	      else if (inherit && *input_line_pointer == ','
+		       && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
+		goto fetch_linked_to;
 	      else
 		{
 		  char c;
@@ -1260,6 +1284,17 @@ obj_elf_section (int push)
 		    match.linked_to_symbol_name = xmemdup0 (beg, length);
 		}
 	    }
+	  else if ((attr & SHF_LINK_ORDER) != 0 && inherit
+		   && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
+	    {
+	    fetch_linked_to:
+	      if (now_seg->map_head.linked_to_symbol_name)
+		match.linked_to_symbol_name =
+		  now_seg->map_head.linked_to_symbol_name;
+	      else
+		linked_to_section_index =
+		  elf_section_data (now_seg)->this_hdr.sh_link;
+	    }
 
 	  if ((attr & SHF_GROUP) != 0 && is_clone)
 	    {
@@ -1270,6 +1305,10 @@ obj_elf_section (int push)
 	  if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
 	    {
 	      ++input_line_pointer;
+	      SKIP_WHITESPACE ();
+	      if (inherit && *input_line_pointer == ','
+		  && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
+		goto fetch_group;
 	      match.group_name = obj_elf_section_name ();
 	      if (match.group_name == NULL)
 		attr &= ~SHF_GROUP;
@@ -1286,6 +1325,14 @@ obj_elf_section (int push)
 	      else if (startswith (name, ".gnu.linkonce"))
 		linkonce = 1;
 	    }
+	  else if ((attr & SHF_GROUP) != 0 && inherit
+		   && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
+	    {
+	    fetch_group:
+	      match.group_name = elf_group_name (now_seg);
+	      linkonce =
+	        (bfd_section_flags (now_seg) & SEC_LINK_ONCE) != 0;
+	    }
 	  else if ((attr & SHF_GROUP) != 0)
 	    {
 	      as_warn (_("group name for SHF_GROUP not specified"));
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 15867dfcb5e..6a3e5eed39f 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -6818,6 +6818,12 @@ section is a member of a section group
 section is used for thread-local-storage
 @item ?
 section is a member of the previously-current section's group, if any
+@item +
+section inherits attributes and (unless explicitly specified) type from the
+previously-current section, adding other attributes as specified
+@item -
+section inherits attributes and (unless explicitly specified) type from the
+previously-current section, removing other attributes as specified
 @item R
 retained section (apply SHF_GNU_RETAIN to prevent linker garbage
 collection, GNU ELF extension)
@@ -6839,6 +6845,12 @@ section may have the executable (@code{x}) flag added.  Also note that the
 @code{.attach_to_group} directive can be used to add a section to a group even
 if the section was not originally declared to be part of that group.
 
+Note further that @code{+} and @code{-} need to come first and can only take
+the effect described here unless overridden by a target.  The attributes
+inherited are those in effect at the time the directive is processed.
+Attributes added later (see above) will not be inherited.  Using either
+together with @code{?} is undefined at this point.
+
 The optional @var{type} argument may contain one of the following constants:
 
 @table @code
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index 00eadc8c372..854c78aebd3 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -280,6 +280,11 @@ if { [is_elf_format] } then {
     run_dump_test "section27"
     run_dump_test "section28"
     run_dump_test "section29"
+    if { ![istarget "rx-*-*"] } then {
+	run_dump_test "section30"
+    } else {
+	run_dump_test "section30" {{as -muse-conventional-section-names}}
+    }
     run_dump_test "sh-link-zero"
     run_dump_test "size"
     run_dump_test "dwarf2-1" $dump_opts
diff --git a/gas/testsuite/gas/elf/section30.d b/gas/testsuite/gas/elf/section30.d
new file mode 100644
index 00000000000..821af1e2cd5
--- /dev/null
+++ b/gas/testsuite/gas/elf/section30.d
@@ -0,0 +1,28 @@
+#as: --sectname-subst
+#readelf: -SW
+#name: --sectname-subst plus section attr/type inherting
+# Targets setting NO_PSEUDO_DOT don't allow macros of certain names.
+#notarget: m681*-*-* m68hc1*-*-* s12z-*-* spu-*-* xgate-*-* z80-*-*
+
+#...
+  \[..\] \.group +GROUP +[0-9a-f]+ [0-9a-f]+ 0+c 04 +[1-9][0-9]* +[1-9][0-9]* +4
+  \[..\] \.text +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  AX  0   0 +[1-9][0-9]*
+  \[..\] \.data +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  WA  0   0 +[1-9][0-9]*
+  \[..\] \.bss +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  WA  0   0 +[1-9][0-9]*
+#...
+  \[..\] \.text\.func1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  AX  0   0 +[1-9][0-9]*
+  \[..\] \.text\.func2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  AX  0   0 +[1-9][0-9]*
+  \[..\] \.data\.data1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+1 00  WA  0   0  1
+#...
+  \[..\] \.bss\.data2 +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+2 00  WA  0   0  1
+  \[..\] \.rodata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00   A  0   0  1
+  \[..\] \.rodata\.data3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+3 00   A  0   0  1
+  \[..\] \.rodata\.str1\.1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 01 AMS  0   0  1
+  \[..\] \.rodata\.str1\.1\.str1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+8 01 AMS  0   0  1
+  \[..\] \.rodata\.2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  AL  [1-9]   0  1
+  \[..\] \.rodata\.2\.data4 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+4 00  AL  [1-9]   0  1
+  \[..\] \.bss\.data5 +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+5 00  WA  0   0  1
+  \[..\] \.rodata\.3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  AG  0   0  1
+  \[..\] \.rodata\.3\.data6 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+6 00  AG  0   0  1
+  \[..\] \.bss\.data7 +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+7 00  WA  0   0  1
+#pass
diff --git a/gas/testsuite/gas/elf/section30.s b/gas/testsuite/gas/elf/section30.s
new file mode 100644
index 00000000000..aeda04c6514
--- /dev/null
+++ b/gas/testsuite/gas/elf/section30.s
@@ -0,0 +1,67 @@
+	.macro func name:req
+	.pushsection %S.\name, "+"
+	.type \name, %function
+	.global \name
+	.hidden \name
+\name:
+	.endm
+
+	.macro data name:req
+	.pushsection %S.\name, "+"
+	.type \name, %object
+\name:
+	.endm
+
+	.macro end name:req
+	.size \name, . - \name
+	.popsection
+	.endm
+
+
+	.text
+	func func1
+	.nop
+	end func1
+
+	func func2
+	.nop
+	.nop
+	end func2
+
+	.data
+	data data1
+	.byte 1
+	end data1
+
+	.section .bss
+	data data2
+	.skip 2
+	end data2
+
+	.section .rodata, "a", %progbits
+	data data3
+	.byte 3, 3, 3
+	end data3
+
+	.section .rodata.str1.1, "aMS", %progbits, 1
+	data str1
+	.asciz "string1"
+	end str1
+
+	.section .rodata.2, "ao", %progbits, func1
+	data data4
+	.byte 4, 4, 4, 4
+	end data4
+	.pushsection .bss.data5, "-o", %nobits
+	.type data5, %object
+data5:	.fill 5
+	end data5
+
+	.section .rodata.3, "aG", %progbits, sig1, comdat
+	data data6
+	.byte 6, 6, 6, 6, 6, 6
+	end data6
+	.pushsection .bss.data7, "-G", %nobits
+	.type data7, %object
+data7:	.skip 7
+	end data7

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-08-25 12:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-25 12:56 [binutils-gdb] gas/ELF: allow "inheriting" section attributes and type Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).