GAS: Update the .section directive so that a numeric section index can be provided...
authorNick Clifton <nickc@redhat.com>
Mon, 5 Oct 2020 09:40:07 +0000 (10:40 +0100)
committerNick Clifton <nickc@redhat.com>
Mon, 5 Oct 2020 09:40:07 +0000 (10:40 +0100)
PR 26253
gas * config/obj-elf.c (obj_elf_section): Accept a numeric value for
the "o" section flag.  Interpret it as a section index.  Allow an
index of zero.
* doc/as.texi: Document the new behaviour.
* NEWS: Mention the new feature.  Tidy entries.
* testsuite/gas/elf/sh-link-zero.s: New test.
* testsuite/gas/elf/sh-link-zero.d: New test driver.
* testsuite/gas/elf/elf.exp: Run the new test.
* testsuite/gas/elf/section21.l: Updated expected assembler
output.

bfd * elf.c (_bfd_elf_setup_sections): Do not complain about an
sh_link value of zero when the SLF_LINK_ORDER flag is set.
(assign_section_numbers): Likewise.

bfd/ChangeLog
bfd/elf.c
gas/ChangeLog
gas/NEWS
gas/config/obj-elf.c
gas/config/obj-elf.h
gas/doc/as.texi
gas/testsuite/gas/elf/elf.exp
gas/testsuite/gas/elf/section21.l
gas/testsuite/gas/elf/sh-link-zero.d [new file with mode: 0644]
gas/testsuite/gas/elf/sh-link-zero.s [new file with mode: 0644]

index 623cb8a188b870bcc8fad503e27ef5d598094eca..659d8d4bd62deb330a311589dbdae33f2bd68b62 100644 (file)
@@ -1,3 +1,10 @@
+2020-10-05  Nick Clifton  <nickc@redhat.com>
+
+       PR 26253
+       * elf.c (_bfd_elf_setup_sections): Do not complain about an
+       sh_link value of zero when the SLF_LINK_ORDER flag is set.
+       (assign_section_numbers): Likewise.
+
 2020-10-02  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR 26681
index 00594020c93038e312d52e67f03f07c67e4e7dc6..9d7cbd52e024e312bdc10c700c47d05da85d4267 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -848,16 +848,14 @@ _bfd_elf_setup_sections (bfd *abfd)
       if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0)
        {
          unsigned int elfsec = this_hdr->sh_link;
-         /* FIXME: The old Intel compiler and old strip/objcopy may
-            not set the sh_link or sh_info fields.  Hence we could
-            get the situation where elfsec is 0.  */
+         /* An sh_link value of 0 is now allowed.  It indicates that linked
+            to section has already been discarded, but that the current
+            section has been retained for some other reason.  This linking
+            section is still a candidate for later garbage collection
+            however.  */
          if (elfsec == 0)
            {
-             const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-             bed->link_order_error_handler
-               /* xgettext:c-format */
-               (_("%pB: warning: sh_link not set for section `%pA'"),
-                abfd, s);
+             elf_linked_to_section (s) = NULL;
            }
          else
            {
@@ -3888,6 +3886,10 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
       if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0)
        {
          s = elf_linked_to_section (sec);
+         /* We can now have a NULL linked section pointer.
+            This happens when the sh_link field is 0, which is done
+            when a linked to section is discarded but the linking
+            section has been retained for some reason.  */
          if (s)
            {
              /* Check discarded linkonce section.  */
@@ -3923,20 +3925,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
              s = s->output_section;
              d->this_hdr.sh_link = elf_section_data (s)->this_idx;
            }
-         else
-           {
-             /* PR 290:
-                The Intel C compiler generates SHT_IA_64_UNWIND with
-                SHF_LINK_ORDER.  But it doesn't set the sh_link or
-                sh_info fields.  Hence we could get the situation
-                where s is NULL.  */
-             const struct elf_backend_data *bed
-               = get_elf_backend_data (abfd);
-             bed->link_order_error_handler
-               /* xgettext:c-format */
-               (_("%pB: warning: sh_link not set for section `%pA'"),
-                abfd, sec);
-           }
        }
 
       switch (d->this_hdr.sh_type)
index 866a8b46baffe9f83a0eeb5b590685a81fb0b2f6..56796ff9485abe1d9b25aa430e23bf0821c54862 100644 (file)
@@ -1,3 +1,17 @@
+2020-10-05  Nick Clifton  <nickc@redhat.com>
+
+       PR 26253
+       * config/obj-elf.c (obj_elf_section): Accept a numeric value for
+       the "o" section flag.  Interpret it as a section index.  Allow an
+       index of zero.
+       * doc/as.texi: Document the new behaviour.
+       * NEWS: Mention the new feature.  Tidy entries.
+       * testsuite/gas/elf/sh-link-zero.s: New test.
+       * testsuite/gas/elf/sh-link-zero.d: New test driver.
+       * testsuite/gas/elf/elf.exp: Run the new test.
+       * testsuite/gas/elf/section21.l: Updated expected assembler
+       output.
+
 2020-10-03  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR gas/26685
index 8394f7466ca25bcbd8c39d04604627f57bf73a5b..8f83beb15b2fa6675e38b9b472e81a3d7c7335ed 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,21 +1,12 @@
 -*- text -*-
-* Add support for Cortex-A78 and Cortex-A78AE for ARM.
+* When setting the link order attribute of ELF sections, it is now possible to
+  use a numeric section index instead of symbol name.
 
-* Add support for Cortex-A78 and Cortex-A78AE for AArch64.
+* Add support for Cortex-A78, Cortex-A78AE and Cortex-X1 for AArch64 and ARM.
+  Add support for Cortex-R82, Neoverse V1, and Neoverse N2 for ARM.
 
-* Add support for ETMv4 (Embedded Trace Macrocell) system registers for
-  AArch64.
-
-* Add support for ETE (Embedded Trace Extension) system registers for AArch64.
-
-* Add support for TRBE (Trace Buffer Extension) system registers for AArch64.
-
-* Add support for Cortex-X1 for AArch64.
-
-* Add support for Cortex-X1 for ARM.
-
-* Add support for Arm's Cortex-R82, Neoverse V1, and Neoverse N2
-  processors.
+* Add support for ETMv4 (Embedded Trace Macrocell), ETE (Embedded Trace
+  Extension) and TRBE (Trace Buffer Extension) system registers for AArch64.
 
 * Add support for Armv8-R AArch64.
 
index 45de821495e3d2dbddb7ba2d30a19586bf45153a..f061ea61f3e0e554d7c554c5c8a55b43c4df535b 100644 (file)
@@ -519,8 +519,10 @@ struct section_stack
 
 static struct section_stack *section_stack;
 
+/* Return TRUE iff SEC matches the section info INF.  */
+
 static bfd_boolean
-get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
+get_section_by_match (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
 {
   struct elf_section_match *match = (struct elf_section_match *) inf;
   const char *gname = match->group_name;
@@ -602,7 +604,7 @@ obj_elf_change_section (const char *name,
   previous_section = now_seg;
   previous_subsection = now_subseg;
 
-  old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
+  old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section_by_match,
                                        (void *) match_p);
   if (old_sec)
     {
@@ -1076,6 +1078,7 @@ obj_elf_section (int push)
   int linkonce;
   subsegT new_subsection = -1;
   struct elf_section_match match;
+  unsigned long linked_to_section_index = -1UL;
 
   if (flag_mri)
     {
@@ -1215,15 +1218,24 @@ obj_elf_section (int push)
 
          if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',')
            {
-             char c;
-             unsigned int length;
              ++input_line_pointer;
              SKIP_WHITESPACE ();
-             c = get_symbol_name (& beg);
-             (void) restore_line_pointer (c);
-             length = input_line_pointer - beg;
-             if (length)
-               match.linked_to_symbol_name = xmemdup0 (beg, length);
+             /* Check for a numeric section index, rather than a symbol name.  */
+             if (ISDIGIT (* input_line_pointer))
+               {
+                 linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
+               }
+             else
+               {
+                 char c;
+                 unsigned int length;
+
+                 c = get_symbol_name (& beg);
+                 (void) restore_line_pointer (c);
+                 length = input_line_pointer - beg;
+                 if (length)
+                   match.linked_to_symbol_name = xmemdup0 (beg, length);
+               }
            }
 
          if ((attr & SHF_GROUP) != 0 && is_clone)
@@ -1231,6 +1243,7 @@ obj_elf_section (int push)
              as_warn (_("? section flag ignored with G present"));
              is_clone = FALSE;
            }
+
          if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
            {
              ++input_line_pointer;
@@ -1289,6 +1302,7 @@ obj_elf_section (int push)
          if (*input_line_pointer == ',')
            {
              char *save = input_line_pointer;
+
              ++input_line_pointer;
              SKIP_WHITESPACE ();
              if (strncmp (input_line_pointer, "unique", 6) == 0)
@@ -1394,6 +1408,13 @@ obj_elf_section (int push)
     }
   elf_section_flags (now_seg) |= gnu_attr;
 
+  if (linked_to_section_index != -1UL)
+    {
+      elf_section_flags (now_seg) |= SHF_LINK_ORDER;
+      elf_section_data (now_seg)->this_hdr.sh_link = linked_to_section_index;
+      /* FIXME: Should we perform some sanity checking on the section index ?  */
+    }
+
   if (push && new_subsection != -1)
     subseg_set (now_seg, new_subsection);
 }
index b39a1a1ab63e5d7093bb846b7f94b6902527d59e..4f29572eef70f8b6219d59b80ec8a1c673ad5da7 100644 (file)
@@ -104,11 +104,11 @@ struct elf_obj_sy
    field.  */
 struct elf_section_match
 {
-  const char *group_name;
-  const char *linked_to_symbol_name;
-  unsigned int info;
-  unsigned int section_id;
-  flagword flags;
+  const char *   group_name;
+  const char *   linked_to_symbol_name;
+  unsigned int   info;
+  unsigned int   section_id;
+  flagword       flags;
 };
 
 #define OBJ_SYMFIELD_TYPE struct elf_obj_sy
index c0baa945360b99b8f2211cb430da2c0c559340bb..2ba101ce8d6558839a03e1ebaa3cf48a9bc37900 100644 (file)
@@ -6728,11 +6728,14 @@ If @var{flags} contains the @code{o} flag, then the @var{type} argument
 must be present along with an additional field like this:
 
 @smallexample
-.section @var{name},"@var{flags}"o,@@@var{type},@var{SymbolName}
+.section @var{name},"@var{flags}"o,@@@var{type},@var{SymbolName}|@var{SectionIndex}
 @end smallexample
 
 The @var{SymbolName} field specifies the symbol name which the section
-references.
+references.  Alternatively a numeric @var{SectionIndex} can be provided.  This
+is not generally a good idea as section indicies are rarely known at assembly
+time, but the facility is provided for testing purposes.  An index of zero is
+allowed.  It indicates that the linked-to section has already been discarded.
 
 Note: If both the @var{M} and @var{o} flags are present, then the fields
 for the Merge flag should come first, like this:
index 5ce9691b389c7d3e8b8502c0cade696d6ad66e7a..9d751544830b0f9f473cb37f786902fe4a315599 100644 (file)
@@ -142,7 +142,7 @@ if { [is_elf_format] } then {
 
     run_dump_test "attach-1"
     run_dump_test "attach-err"
-    
+
     switch -glob $target_triplet {
        hppa64*-*-hpux* { }
        riscv*-*-* { }
@@ -261,6 +261,8 @@ if { [is_elf_format] } then {
     run_dump_test "section19"
     run_dump_test "section20"
     run_dump_test "section21"
+    run_dump_test "sh-link-zero"
+
     run_dump_test "dwarf2-1" $dump_opts
     run_dump_test "dwarf2-2" $dump_opts
     run_dump_test "dwarf2-3" $dump_opts
index 50342ec659aa249845c90fbab7b5f9447081835e..53f04151d33e2735765527edecefbf8010784f7c 100644 (file)
@@ -1,5 +1,5 @@
 [^:]*: Assembler messages:
-[^:]*:11: Error: junk at end of line, first unrecognized character is `1'
+[^:]*:11: Error: junk at end of line, first unrecognized character is `f'
 #...
 [^:]*: Error: undefined linked-to symbol `bar' on section `__patchable_function_entries'
 [^:]*: Error: undefined linked-to symbol `foo' on section `__patchable_function_entries'
diff --git a/gas/testsuite/gas/elf/sh-link-zero.d b/gas/testsuite/gas/elf/sh-link-zero.d
new file mode 100644 (file)
index 0000000..243d50c
--- /dev/null
@@ -0,0 +1,9 @@
+#readelf: --wide --sections
+#name: Setting the sh_link field to 0
+#source: sh-link-zero.s
+
+#...
+.*\.meta1.*WAL[        ]+0.*
+#...
+.*\.meta2.*WAL[        ]+[1-9].*
+#pass
diff --git a/gas/testsuite/gas/elf/sh-link-zero.s b/gas/testsuite/gas/elf/sh-link-zero.s
new file mode 100644 (file)
index 0000000..9e90792
--- /dev/null
@@ -0,0 +1,13 @@
+.section .meta1,"awo",%progbits,0
+1:
+       .dc.b 0
+
+.section .meta2,"awo",%progbits,foo
+2:
+       .dc.b 1
+
+.section foo, "aw"
+       .dc.b 2
+
+.section .gc_root,"a",%progbits
+       .dc.a 1b