public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Jan Beulich <jbeulich@suse.com>
To: Binutils <binutils@sourceware.org>
Cc: Nick Clifton <nickc@redhat.com>, Alan Modra <amodra@gmail.com>
Subject: [PATCH 1/2] gas/ELF: allow "inheriting" section attributes and type
Date: Mon, 14 Aug 2023 15:48:21 +0200	[thread overview]
Message-ID: <61c83a56-fe09-1c86-32d0-25535dd7e96f@suse.com> (raw)
In-Reply-To: <9ccf6770-66bd-c924-93e1-fd54a6daf610@suse.com>

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.
---
The change ends up much simpler than I expected, and hence I fear it's
overly simplistic (i.e. I'm overlooking something that would break). In
any event the optional settings beyond the group are becoming hard to
handle: For SHF_GNU_MBIND it is not an error when no corresponding
number follows. So it may be necessary to simply document restrictions,
or to refuse to accept anything past the group. Of course it is also an
option to allow nothing past (e.g.) type when inheriting is used.

I didn't extend obj_elf_parse_section_letters()'es bad_msg: It's missing
a number of other characters already. And if doing so, a couple of
config/tc-*.c would also need adjustment. Perhaps this could do with an
overhaul anyway, having the target hook pass back merely the extra
letters it understands, with common code then synthesizing a message.

Initially I considered tying the functionality to --sectname-subst's,
which made me look at users of obj_elf_section_name(). How come
obj_elf_attach_to_group() and group name handling in obj_elf_section()
use that function? The names there are symbol names, not section ones,
aiui (in fact when using section names, the names are lost, as section
symbols are emitted without names), and at least in the former case it
also looks bogus to allow name substitution there (because of then
deriving the name from that of the section itself, rather than some
other one).

--- 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
 @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
--- 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
 		  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"));
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -279,6 +279,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
--- /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
--- /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


  reply	other threads:[~2023-08-14 13:48 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-14 13:47 [PATCH 0/2] " Jan Beulich
2023-08-14 13:48 ` Jan Beulich [this message]
2023-08-14 13:48 ` [PATCH 2/2] gas/ELF: widen use of $dump_opts in testsuite Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=61c83a56-fe09-1c86-32d0-25535dd7e96f@suse.com \
    --to=jbeulich@suse.com \
    --cc=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    --cc=nickc@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).