[PATCH] gas: Generate a new section for SHF_GNU_RETAIN

H.J. Lu hjl.tools@gmail.com
Fri Dec 4 13:52:54 GMT 2020


For
	.globl	foo2
	.section	.data.foo,"aR"
	.align 4
	.type	foo2, @object
	.size	foo2, 4
foo2:
	.long	2
	.globl	foo1
	.section	.data.foo
	.align 4
	.type	foo1, @object
	.size	foo1, 4
foo1:
	.long	1

generate a new section if the SHF_GNU_RETAIN bit doesn't match.

	* config/obj-elf.c (SEC_ASSEMBLER_SHF_MASK): New.
	(get_section_by_match): Also check if SEC_ASSEMBLER_SHF_MASK of
	sh_flags matches.  Rename info to sh_info.
	(obj_elf_change_section): Rename info to sh_info.
	(obj_elf_section): Rename info to sh_info.  Set sh_flags for
	SHF_GNU_RETAIN.
	* config/obj-elf.h (elf_section_match): Rename info to sh_info.
	Add sh_flags.
	* testsuite/gas/elf/elf.exp: Run section27.
	* testsuite/gas/elf/section24b.d: Updated.
	* testsuite/gas/elf/section27.d: New file.
	* testsuite/gas/elf/section27.s: Likewise.
---
 gas/config/obj-elf.c               | 21 ++++++++++++------
 gas/config/obj-elf.h               |  3 ++-
 gas/testsuite/gas/elf/elf.exp      |  1 +
 gas/testsuite/gas/elf/section24b.d | 10 ++++++---
 gas/testsuite/gas/elf/section27.d  | 14 ++++++++++++
 gas/testsuite/gas/elf/section27.s  | 34 ++++++++++++++++++++++++++++++
 6 files changed, 73 insertions(+), 10 deletions(-)
 create mode 100644 gas/testsuite/gas/elf/section27.d
 create mode 100644 gas/testsuite/gas/elf/section27.s

diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 54d42d9ecb..58aaac4b11 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -519,6 +519,9 @@ struct section_stack
 
 static struct section_stack *section_stack;
 
+/* ELF section flags for unique sections.  */
+#define SEC_ASSEMBLER_SHF_MASK SHF_GNU_RETAIN
+
 /* Return TRUE iff SEC matches the section info INF.  */
 
 static bfd_boolean
@@ -529,9 +532,12 @@ get_section_by_match (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
   const char *group_name = elf_group_name (sec);
   const char *linked_to_symbol_name
     = sec->map_head.linked_to_symbol_name;
-  unsigned int info = elf_section_data (sec)->this_hdr.sh_info;
+  unsigned int sh_info = elf_section_data (sec)->this_hdr.sh_info;
+  bfd_vma sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
+		      & SEC_ASSEMBLER_SHF_MASK);
 
-  return (info == match->info
+  return (sh_info == match->sh_info
+	  && sh_flags == match->sh_flags
 	  && ((bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID)
 	       == (match->flags & SEC_ASSEMBLER_SECTION_ID))
 	  && sec->section_id == match->section_id
@@ -740,7 +746,7 @@ obj_elf_change_section (const char *name,
 	type = bfd_elf_get_default_section_type (flags);
       elf_section_type (sec) = type;
       elf_section_flags (sec) = attr;
-      elf_section_data (sec)->this_hdr.sh_info = match_p->info;
+      elf_section_data (sec)->this_hdr.sh_info = match_p->sh_info;
 
       /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
       if (type == SHT_NOBITS)
@@ -1322,18 +1328,21 @@ obj_elf_section (int push)
 	      if (ISDIGIT (* input_line_pointer))
 		{
 		  char *t = input_line_pointer;
-		  match.info = strtoul (input_line_pointer,
+		  match.sh_info = strtoul (input_line_pointer,
 					&input_line_pointer, 0);
-		  if (match.info == (unsigned int) -1)
+		  if (match.sh_info == (unsigned int) -1)
 		    {
 		      as_warn (_("unsupported mbind section info: %s"), t);
-		      match.info = 0;
+		      match.sh_info = 0;
 		    }
 		}
 	      else
 		input_line_pointer = save;
 	    }
 
+	  if ((gnu_attr & SHF_GNU_RETAIN) != 0)
+	    match.sh_flags |= SHF_GNU_RETAIN;
+
 	  if (*input_line_pointer == ',')
 	    {
 	      char *save = input_line_pointer;
diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h
index 4f29572eef..c714ba7a70 100644
--- a/gas/config/obj-elf.h
+++ b/gas/config/obj-elf.h
@@ -106,8 +106,9 @@ struct elf_section_match
 {
   const char *   group_name;
   const char *   linked_to_symbol_name;
-  unsigned int   info;
   unsigned int   section_id;
+  unsigned int   sh_info;		/* ELF section information.  */
+  bfd_vma        sh_flags;		/* ELF section flags.  */
   flagword       flags;
 };
 
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index 25c40a2810..80dec4effc 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -268,6 +268,7 @@ if { [is_elf_format] } then {
     run_dump_test "section24b"
     run_dump_test "section25"
     run_dump_test "section26"
+    run_dump_test "section27"
     run_dump_test "sh-link-zero"
     run_dump_test "dwarf2-1" $dump_opts
     run_dump_test "dwarf2-2" $dump_opts
diff --git a/gas/testsuite/gas/elf/section24b.d b/gas/testsuite/gas/elf/section24b.d
index 451ec21635..03dd2916ef 100644
--- a/gas/testsuite/gas/elf/section24b.d
+++ b/gas/testsuite/gas/elf/section24b.d
@@ -3,8 +3,12 @@
 #source: section24.s
 #readelf: -S --wide
 
-#failif
 #...
-  \[..\] .(text|data|bss|rodata)[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 [^R] .*
+  \[..\] .text[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +AX .*
+#...
+  \[..\] .data[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +WA .*
+#...
+  \[..\] .bss[ 	]+NOBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +WA .*
+#...
+  \[..\] .rodata[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +A .*
 #pass
-
diff --git a/gas/testsuite/gas/elf/section27.d b/gas/testsuite/gas/elf/section27.d
new file mode 100644
index 0000000000..5489d98d6e
--- /dev/null
+++ b/gas/testsuite/gas/elf/section27.d
@@ -0,0 +1,14 @@
+#readelf: -h -S --wide
+#name: SHF_GNU_RETAIN sections 27
+#notarget: ![supports_gnu_osabi]
+
+#...
+ +OS/ABI: +UNIX - (GNU|FreeBSD)
+#...
+  \[..\] .text[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  AX.*
+  \[..\] .data[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  WA.*
+  \[..\] .bss[ 	]+NOBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  WA.*
+  \[..\] .bss[ 	]+NOBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR.*
+  \[..\] .data[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR.*
+  \[..\] .text[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AXR.*
+#pass
diff --git a/gas/testsuite/gas/elf/section27.s b/gas/testsuite/gas/elf/section27.s
new file mode 100644
index 0000000000..78e410ff95
--- /dev/null
+++ b/gas/testsuite/gas/elf/section27.s
@@ -0,0 +1,34 @@
+	.section	.bss,"aw"
+	.global	discard0
+	.type	discard0, %object
+discard0:
+	.zero	2
+
+	.section	.data,"aw"
+	.global	discard1
+	.type	discard1, %object
+discard1:
+	.word	1
+
+	.text
+	.global	discard2
+	.type	discard2, %function
+discard2:
+	.word	0
+
+	.section	.bss,"awR",%nobits
+	.global	retain0
+	.type	retain0, %object
+retain0:
+	.zero	2
+
+	.section	.data,"awR",%progbits
+	.type	retain1, %object
+retain1:
+	.word	1
+
+	.section	.text,"axR",%progbits
+	.global	retain2
+	.type	retain2, %function
+retain2:
+	.word	0
-- 
2.28.0



More information about the Binutils mailing list