public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable link
@ 2020-12-21 21:54 H.J. Lu
  2020-12-21 23:24 ` Fangrui Song
  0 siblings, 1 reply; 7+ messages in thread
From: H.J. Lu @ 2020-12-21 21:54 UTC (permalink / raw)
  To: binutils

For non-relocatable link with SHF_LINK_ORDER inputs, allow mixed indirect
and data inputs with ordered and unordered inputs:

1. Add pattern to bfd_section for the matching section name pattern in
linker script and update BFD_FAKE_SECTION.
2. Sort the consecutive bfd_indirect_link_order sections with the same
pattern to allow linker script to overdide input section order.
3. Place unordered sections before ordered sections.
4. Change the offsets of the indirect input sections only.

bfd/

	PR ld/26256
	* elflink.c (compare_link_order): Place unordered sections before
	ordered sections.
	(elf_fixup_link_order): Add a link info argument.  Allow mixed
	ordered and unordered input sections for non-relocatable link.
	Sort the consecutive bfd_indirect_link_order sections with the
	same pattern.  Change the offsets of the bfd_indirect_link_order
	sections only.
	(bfd_elf_final_link): Pass info to elf_fixup_link_order.
	* section.c (bfd_section): Add pattern.
	(BFD_FAKE_SECTION): Initialize pattern to NULL.
	* bfd-in2.h: Regenerated.

gas/

	PR ld/26256
	* config/obj-elf.c (obj_elf_change_section): Also filter out
	SHF_LINK_ORDER.

ld/

	PR ld/26256
	* ldlang.c (gc_section_callback): Set pattern.
	* testsuite/ld-elf/pr26256-1.s: New file.
	* testsuite/ld-elf/pr26256-1.t: Likewise.
	* testsuite/ld-elf/pr26256-1a.d: Likewise.
	* testsuite/ld-elf/pr26256-1b.d: Likewise.
	* testsuite/ld-elf/pr26256-2.s: Likewise.
	* testsuite/ld-elf/pr26256-2.t: Likewise.
	* testsuite/ld-elf/pr26256-2a.d: Likewise.
	* testsuite/ld-elf/pr26256-2b.d: Likewise.
	* testsuite/ld-elf/pr26256-3.s: Likewise.
	* testsuite/ld-elf/pr26256-3a.d: Likewise.
	* testsuite/ld-elf/pr26256-3a.t: Likewise.
	* testsuite/ld-elf/pr26256-3b.d: Likewise.
	* testsuite/ld-elf/pr26256-3b.t: Likewise.
---
 bfd/bfd-in2.h                    |  7 ++-
 bfd/elflink.c                    | 83 ++++++++++++++++++++++++--------
 bfd/section.c                    |  7 ++-
 gas/config/obj-elf.c             |  4 +-
 ld/ldlang.c                      |  4 +-
 ld/testsuite/ld-elf/pr26256-1.s  | 20 ++++++++
 ld/testsuite/ld-elf/pr26256-1.t  |  9 ++++
 ld/testsuite/ld-elf/pr26256-1a.d |  7 +++
 ld/testsuite/ld-elf/pr26256-1b.d |  7 +++
 ld/testsuite/ld-elf/pr26256-2.s  | 32 ++++++++++++
 ld/testsuite/ld-elf/pr26256-2.t  |  5 ++
 ld/testsuite/ld-elf/pr26256-2a.d | 19 ++++++++
 ld/testsuite/ld-elf/pr26256-2b.d | 19 ++++++++
 ld/testsuite/ld-elf/pr26256-3.s  | 18 +++++++
 ld/testsuite/ld-elf/pr26256-3a.d |  9 ++++
 ld/testsuite/ld-elf/pr26256-3a.t | 13 +++++
 ld/testsuite/ld-elf/pr26256-3b.d |  9 ++++
 ld/testsuite/ld-elf/pr26256-3b.t | 12 +++++
 18 files changed, 259 insertions(+), 25 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr26256-1.s
 create mode 100644 ld/testsuite/ld-elf/pr26256-1.t
 create mode 100644 ld/testsuite/ld-elf/pr26256-1a.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-1b.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-2.s
 create mode 100644 ld/testsuite/ld-elf/pr26256-2.t
 create mode 100644 ld/testsuite/ld-elf/pr26256-2a.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-2b.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-3.s
 create mode 100644 ld/testsuite/ld-elf/pr26256-3a.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-3a.t
 create mode 100644 ld/testsuite/ld-elf/pr26256-3b.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-3b.t

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index f1bef5742a..cc5a3c9912 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1184,6 +1184,9 @@ typedef struct bfd_section
   struct bfd_symbol *symbol;
   struct bfd_symbol **symbol_ptr_ptr;
 
+  /* The matching section name pattern in linker script.  */
+  const char *pattern;
+
   /* Early in the link process, map_head and map_tail are used to build
      a list of input sections attached to an output section.  Later,
      output sections use these fields for a list of bfd_link_order
@@ -1377,8 +1380,8 @@ discarded_section (const asection *sec)
   /* target_index, used_by_bfd, constructor_chain, owner,           */ \
      0,            NULL,        NULL,              NULL,               \
                                                                        \
-  /* symbol,                    symbol_ptr_ptr,                     */ \
-     (struct bfd_symbol *) SYM, &SEC.symbol,                           \
+  /* symbol,                    symbol_ptr_ptr, pattern,            */ \
+     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,                  \
                                                                        \
   /* map_head, map_tail, already_assigned                           */ \
      { NULL }, { NULL }, NULL                                          \
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 1b3398126f..6930c7c741 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11867,8 +11867,21 @@ compare_link_order (const void *a, const void *b)
   const struct bfd_link_order *blo = *(const struct bfd_link_order **) b;
   asection *asec = elf_linked_to_section (alo->u.indirect.section);
   asection *bsec = elf_linked_to_section (blo->u.indirect.section);
-  bfd_vma apos = asec->output_section->lma + asec->output_offset;
-  bfd_vma bpos = bsec->output_section->lma + bsec->output_offset;
+  bfd_vma apos, bpos;
+
+  /* Check if any sections are unordered.  */
+  if (asec == NULL || bsec == NULL)
+    {
+      /* Place unordered sections before ordered sections.  */
+      if (bsec != NULL)
+	return -1;
+      else if (asec != NULL)
+	return 1;
+      return 0;
+    }
+
+  apos = asec->output_section->lma + asec->output_offset;
+  bpos = bsec->output_section->lma + bsec->output_offset;
 
   if (apos < bpos)
     return -1;
@@ -11903,14 +11916,14 @@ compare_link_order (const void *a, const void *b)
    sections.  Ideally we'd do this in the linker proper.  */
 
 static bfd_boolean
-elf_fixup_link_order (bfd *abfd, asection *o)
+elf_fixup_link_order (struct bfd_link_info *info, bfd *abfd, asection *o)
 {
   size_t seen_linkorder;
   size_t seen_other;
   size_t n;
   struct bfd_link_order *p;
   bfd *sub;
-  struct bfd_link_order **sections;
+  struct bfd_link_order **sections, **indirect_sections;
   asection *other_sec, *linkorder_sec;
   bfd_vma offset;  /* Octets.  */
 
@@ -11941,7 +11954,9 @@ elf_fixup_link_order (bfd *abfd, asection *o)
       else
 	seen_other++;
 
-      if (seen_other && seen_linkorder)
+      /* Allow mixed ordered and unordered input sections for
+         non-relocatable link.  */
+      if (bfd_link_relocatable (info) && seen_other && seen_linkorder)
 	{
 	  if (other_sec && linkorder_sec)
 	    _bfd_error_handler
@@ -11961,6 +11976,10 @@ elf_fixup_link_order (bfd *abfd, asection *o)
   if (!seen_linkorder)
     return TRUE;
 
+  /* Non-relocatable output can have both ordered and unordered input
+     sections.  */
+  seen_linkorder += seen_other;
+
   sections = bfd_malloc (seen_linkorder * sizeof (*sections));
   if (sections == NULL)
     return FALSE;
@@ -11969,22 +11988,48 @@ elf_fixup_link_order (bfd *abfd, asection *o)
   for (p = o->map_head.link_order; p != NULL; p = p->next)
     sections[seen_linkorder++] = p;
 
-  /* Sort the input sections in the order of their linked section.  */
-  qsort (sections, seen_linkorder, sizeof (*sections), compare_link_order);
+  for (indirect_sections = sections, n = 0;
+       n < seen_linkorder;
+       indirect_sections++, n++)
+    {
+      /* Find the first bfd_indirect_link_order section.  */
+      if (indirect_sections[0]->type == bfd_indirect_link_order)
+	{
+	  /* Count the consecutive bfd_indirect_link_order sections
+	     with the same pattern.  */
+	  size_t i, n_indirect;
+	  const char *pattern
+	    = indirect_sections[0]->u.indirect.section->pattern;
+	  for (i = n + 1; i < seen_linkorder; i++)
+	    if (sections[i]->type != bfd_indirect_link_order
+		|| sections[i]->u.indirect.section->pattern != pattern)
+	      break;
+	  n_indirect = i - n;
+	  /* Sort the bfd_indirect_link_order sections in the order of
+	     their linked section.  */
+	  qsort (indirect_sections, n_indirect, sizeof (*sections),
+		 compare_link_order);
+	  indirect_sections += n_indirect;
+	  n += n_indirect;
+	}
+    }
 
-  /* Change the offsets of the sections.  */
+  /* Change the offsets of the bfd_indirect_link_order sections.  */
   offset = 0;
   for (n = 0; n < seen_linkorder; n++)
-    {
-      bfd_vma mask;
-      asection *s = sections[n]->u.indirect.section;
-      unsigned int opb = bfd_octets_per_byte (abfd, s);
-
-      mask = ~(bfd_vma) 0 << s->alignment_power * opb;
-      offset = (offset + ~mask) & mask;
-      sections[n]->offset = s->output_offset = offset / opb;
-      offset += sections[n]->size;
-    }
+    if (sections[n]->type == bfd_indirect_link_order)
+      {
+	bfd_vma mask;
+	asection *s = sections[n]->u.indirect.section;
+	unsigned int opb = bfd_octets_per_byte (abfd, s);
+
+	mask = ~(bfd_vma) 0 << s->alignment_power * opb;
+	offset = (offset + ~mask) & mask;
+	sections[n]->offset = s->output_offset = offset / opb;
+	offset += sections[n]->size;
+      }
+    else
+      offset = sections[n]->offset + sections[n]->size;
 
   free (sections);
   return TRUE;
@@ -12627,7 +12672,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   /* Reorder SHF_LINK_ORDER sections.  */
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      if (!elf_fixup_link_order (abfd, o))
+      if (!elf_fixup_link_order (info, abfd, o))
 	return FALSE;
     }
 
diff --git a/bfd/section.c b/bfd/section.c
index 17f5b4c3d8..aa383626e2 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -541,6 +541,9 @@ CODE_FRAGMENT
 .  struct bfd_symbol *symbol;
 .  struct bfd_symbol **symbol_ptr_ptr;
 .
+.  {* The matching section name pattern in linker script.  *}
+.  const char *pattern;
+.
 .  {* Early in the link process, map_head and map_tail are used to build
 .     a list of input sections attached to an output section.  Later,
 .     output sections use these fields for a list of bfd_link_order
@@ -734,8 +737,8 @@ CODE_FRAGMENT
 .  {* target_index, used_by_bfd, constructor_chain, owner,           *}	\
 .     0,            NULL,        NULL,              NULL,		\
 .									\
-.  {* symbol,                    symbol_ptr_ptr,                     *}	\
-.     (struct bfd_symbol *) SYM, &SEC.symbol,				\
+.  {* symbol,                    symbol_ptr_ptr, pattern,            *}	\
+.     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,			\
 .									\
 .  {* map_head, map_tail, already_assigned                           *}	\
 .     { NULL }, { NULL }, NULL						\
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index d030b548fb..621c35c182 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -666,7 +666,9 @@ obj_elf_change_section (const char *name,
 	    }
 	}
 
-      if (old_sec == NULL && ((attr & ~(SHF_MASKOS | SHF_MASKPROC))
+      if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
+					| SHF_MASKOS
+					| SHF_MASKPROC))
 			      & ~ssect->attr) != 0)
 	{
 	  /* As a GNU extension, we permit a .note section to be
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 41000da1e1..935880cf94 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -7486,7 +7486,7 @@ lang_reset_memory_regions (void)
 
 static void
 gc_section_callback (lang_wild_statement_type *ptr,
-		     struct wildcard_list *sec ATTRIBUTE_UNUSED,
+		     struct wildcard_list *sec,
 		     asection *section,
 		     struct flag_info *sflag_info ATTRIBUTE_UNUSED,
 		     lang_input_statement_type *file ATTRIBUTE_UNUSED,
@@ -7496,6 +7496,8 @@ gc_section_callback (lang_wild_statement_type *ptr,
      should be as well.  */
   if (ptr->keep_sections)
     section->flags |= SEC_KEEP;
+  if (sec)
+    section->pattern = sec->spec.name;
 }
 
 /* Iterate over sections marking them against GC.  */
diff --git a/ld/testsuite/ld-elf/pr26256-1.s b/ld/testsuite/ld-elf/pr26256-1.s
new file mode 100644
index 0000000000..7351f76655
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1.s
@@ -0,0 +1,20 @@
+	.section	.text.bar,"ax",%progbits
+	.globl	bar
+	.type	bar, %function
+bar:
+	.section __patchable_function_entries,"awo",%progbits,bar
+	.dc.a	.LPFE1
+	.section	.text.bar,"ax",%progbits
+.LPFE1:
+	.byte 0
+	.section	.text._start,"ax",%progbits
+	.globl	_start
+	.type	_start, %function
+_start:
+	.section __patchable_function_entries,"awo",%progbits,_start
+	.dc.a	.LPFE2
+	.section	.text._start,"ax",%progbits
+.LPFE2:
+	.byte 0
+	.section .init.data,"aw",%progbits
+	.byte 0
diff --git a/ld/testsuite/ld-elf/pr26256-1.t b/ld/testsuite/ld-elf/pr26256-1.t
new file mode 100644
index 0000000000..bc5232b0ae
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1.t
@@ -0,0 +1,9 @@
+SECTIONS
+{
+  .text : { *(.text*) }
+  .init.data :
+  {
+    *(.init.data);
+    *(__patchable_function_entries);
+  }
+}
diff --git a/ld/testsuite/ld-elf/pr26256-1a.d b/ld/testsuite/ld-elf/pr26256-1a.d
new file mode 100644
index 0000000000..025ace0e87
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1a.d
@@ -0,0 +1,7 @@
+#source: pr26256-1.s
+#ld: -e _start -T pr26256-1.t
+#nm: -n
+
+#...
+[0-9a-f]+ T _start
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-1b.d b/ld/testsuite/ld-elf/pr26256-1b.d
new file mode 100644
index 0000000000..760c6d82e7
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1b.d
@@ -0,0 +1,7 @@
+#source: pr26256-1.s
+#ld: -e _start
+#nm: -n
+
+#...
+[0-9a-f]+ T _start
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-2.s b/ld/testsuite/ld-elf/pr26256-2.s
new file mode 100644
index 0000000000..70e3693f42
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2.s
@@ -0,0 +1,32 @@
+	.section .text,"ax",%progbits,unique,0
+	.globl text0
+text0:
+	.nop
+	.section .text,"ax",%progbits,unique,1
+	.globl text1
+text1:
+	.nop
+	.section .linkorder,"ao",%progbits,0,unique,0
+	.globl linkorder2
+linkorder2:
+	.byte 0
+	.section .linkorder,"ao",%progbits,text0
+	.globl linkorder0
+linkorder0:
+	.byte 1
+	.section .linkorder,"ao",%progbits,text1
+	.globl linkorder1
+linkorder1:
+	.byte 2
+	.section .linkorder,"a",%progbits
+	.globl linkorder3
+linkorder3:
+	.byte 3
+	.section .linkorder,"ao",%progbits,0,unique,3
+	.globl linkorder4
+linkorder4:
+	.byte 4
+	.text
+	.global _start
+_start:
+	.nop
diff --git a/ld/testsuite/ld-elf/pr26256-2.t b/ld/testsuite/ld-elf/pr26256-2.t
new file mode 100644
index 0000000000..a69c01682e
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2.t
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .linkorder : { *(.linkorder.*) }
+  .text : { *(.text) }
+}
diff --git a/ld/testsuite/ld-elf/pr26256-2a.d b/ld/testsuite/ld-elf/pr26256-2a.d
new file mode 100644
index 0000000000..24e8e67ec3
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2a.d
@@ -0,0 +1,19 @@
+#source: pr26256-2.s
+#ld: -e _start -T pr26256-2.t
+#nm: -n
+
+#...
+[0-9a-f]+ R linkorder2
+#...
+[0-9a-f]+ R linkorder3
+#...
+[0-9a-f]+ R linkorder4
+#...
+[0-9a-f]+ R linkorder0
+#...
+[0-9a-f]+ R linkorder1
+#...
+[0-9a-f]+ T text0
+#...
+[0-9a-f]+ T text1
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-2b.d b/ld/testsuite/ld-elf/pr26256-2b.d
new file mode 100644
index 0000000000..f9bc557777
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2b.d
@@ -0,0 +1,19 @@
+#source: pr26256-2.s
+#ld: -e _start
+#nm: -n
+
+#...
+[0-9a-f]+ T text0
+#...
+[0-9a-f]+ T text1
+#...
+[0-9a-f]+ R linkorder2
+#...
+[0-9a-f]+ R linkorder3
+#...
+[0-9a-f]+ R linkorder4
+#...
+[0-9a-f]+ R linkorder0
+#...
+[0-9a-f]+ R linkorder1
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-3.s b/ld/testsuite/ld-elf/pr26256-3.s
new file mode 100644
index 0000000000..276f9de055
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3.s
@@ -0,0 +1,18 @@
+	.text
+	.global _start
+_start:
+	.byte 3
+
+	.section .rosection,"a"
+	.byte 9
+
+	.section .text.bar,"a",%progbits
+	.byte 2
+	.section .text.foo,"a",%progbits
+	.byte 1
+	.section .rodata.foo,"ao",%progbits,.text.foo
+	.byte 1
+	.section .rodata.bar,"a",%progbits
+	.byte 2
+	.section .rodata.bar,"ao",%progbits,.text.bar
+	.byte 3
diff --git a/ld/testsuite/ld-elf/pr26256-3a.d b/ld/testsuite/ld-elf/pr26256-3a.d
new file mode 100644
index 0000000000..3cef3a94c0
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3a.d
@@ -0,0 +1,9 @@
+#source: pr26256-3.s
+#ld: -e _start -T pr26256-3a.t
+#readelf: -x .rodata -x .text
+
+Hex dump of section \'.rodata\':
+  0x[a-f0-9]+ +00010203 +040907 +.+
+
+Hex dump of section \'.text\':
+  0x[a-f0-9]+ +020103 +.+
diff --git a/ld/testsuite/ld-elf/pr26256-3a.t b/ld/testsuite/ld-elf/pr26256-3a.t
new file mode 100644
index 0000000000..7add651a71
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3a.t
@@ -0,0 +1,13 @@
+SECTIONS
+{
+  .rodata :
+    {
+      BYTE(0)
+      *(.rodata.foo)
+      *(.rodata.bar)
+      BYTE(4)
+      *(.rosection)
+      BYTE(7)
+    }
+  .text : {*(.text.bar) *(.text.foo)}
+}
diff --git a/ld/testsuite/ld-elf/pr26256-3b.d b/ld/testsuite/ld-elf/pr26256-3b.d
new file mode 100644
index 0000000000..031de2de6f
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3b.d
@@ -0,0 +1,9 @@
+#source: pr26256-3.s
+#ld: -e _start -T pr26256-3b.t
+#readelf: -x .rodata -x .text
+
+Hex dump of section \'.rodata\':
+  0x[a-f0-9]+ +00020301 +040907 +.+
+
+Hex dump of section \'.text\':
+  0x[a-f0-9]+ +020103 +.+
diff --git a/ld/testsuite/ld-elf/pr26256-3b.t b/ld/testsuite/ld-elf/pr26256-3b.t
new file mode 100644
index 0000000000..6f72e93bad
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3b.t
@@ -0,0 +1,12 @@
+SECTIONS
+{
+  .rodata :
+    {
+      BYTE(0)
+      *(.rodata*)
+      BYTE(4)
+      *(.rosection)
+      BYTE(7)
+    }
+  .text : {*(.text.bar) *(.text.foo)}
+}
-- 
2.29.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable link
  2020-12-21 21:54 [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable link H.J. Lu
@ 2020-12-21 23:24 ` Fangrui Song
  2020-12-22  4:21   ` V2 " H.J. Lu
  0 siblings, 1 reply; 7+ messages in thread
From: Fangrui Song @ 2020-12-21 23:24 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

Really appreciate this patch! For RISC-V -mrelax, .gcc_except_table
has relocations referencing .text . I don't know whether GNU ld does
ad-hoc garbage collection for .gcc_except_table, if it doesn't, in the
future GCC can set SHF_LINK_ORDER on .gcc_except_table to allow a
non-adhoc garbage collection. I have a write-up about this
https://maskray.me/blog/2020-12-12-c++-exception-handling-abi#monolithic-.gcc_except_table
In particular, I mentioned on https://reviews.llvm.org/D83655
that Clang cannot use SHF_LINK_ORDER.

On 2020-12-21, H.J. Lu via Binutils wrote:
>For non-relocatable link with SHF_LINK_ORDER inputs, allow mixed indirect
>and data inputs with ordered and unordered inputs:
>
>1. Add pattern to bfd_section for the matching section name pattern in
>linker script and update BFD_FAKE_SECTION.
>2. Sort the consecutive bfd_indirect_link_order sections with the same
>pattern to allow linker script to overdide input section order.
>3. Place unordered sections before ordered sections.
>4. Change the offsets of the indirect input sections only.
>
>bfd/
>
>	PR ld/26256
>	* elflink.c (compare_link_order): Place unordered sections before
>	ordered sections.
>	(elf_fixup_link_order): Add a link info argument.  Allow mixed
>	ordered and unordered input sections for non-relocatable link.
>	Sort the consecutive bfd_indirect_link_order sections with the
>	same pattern.  Change the offsets of the bfd_indirect_link_order
>	sections only.
>	(bfd_elf_final_link): Pass info to elf_fixup_link_order.
>	* section.c (bfd_section): Add pattern.
>	(BFD_FAKE_SECTION): Initialize pattern to NULL.
>	* bfd-in2.h: Regenerated.
>
>gas/
>
>	PR ld/26256
>	* config/obj-elf.c (obj_elf_change_section): Also filter out
>	SHF_LINK_ORDER.
>
>ld/
>
>	PR ld/26256
>	* ldlang.c (gc_section_callback): Set pattern.
>	* testsuite/ld-elf/pr26256-1.s: New file.
>	* testsuite/ld-elf/pr26256-1.t: Likewise.
>	* testsuite/ld-elf/pr26256-1a.d: Likewise.
>	* testsuite/ld-elf/pr26256-1b.d: Likewise.
>	* testsuite/ld-elf/pr26256-2.s: Likewise.
>	* testsuite/ld-elf/pr26256-2.t: Likewise.
>	* testsuite/ld-elf/pr26256-2a.d: Likewise.
>	* testsuite/ld-elf/pr26256-2b.d: Likewise.
>	* testsuite/ld-elf/pr26256-3.s: Likewise.
>	* testsuite/ld-elf/pr26256-3a.d: Likewise.
>	* testsuite/ld-elf/pr26256-3a.t: Likewise.
>	* testsuite/ld-elf/pr26256-3b.d: Likewise.
>	* testsuite/ld-elf/pr26256-3b.t: Likewise.
>---
> bfd/bfd-in2.h                    |  7 ++-
> bfd/elflink.c                    | 83 ++++++++++++++++++++++++--------
> bfd/section.c                    |  7 ++-
> gas/config/obj-elf.c             |  4 +-
> ld/ldlang.c                      |  4 +-
> ld/testsuite/ld-elf/pr26256-1.s  | 20 ++++++++
> ld/testsuite/ld-elf/pr26256-1.t  |  9 ++++
> ld/testsuite/ld-elf/pr26256-1a.d |  7 +++
> ld/testsuite/ld-elf/pr26256-1b.d |  7 +++
> ld/testsuite/ld-elf/pr26256-2.s  | 32 ++++++++++++
> ld/testsuite/ld-elf/pr26256-2.t  |  5 ++
> ld/testsuite/ld-elf/pr26256-2a.d | 19 ++++++++
> ld/testsuite/ld-elf/pr26256-2b.d | 19 ++++++++
> ld/testsuite/ld-elf/pr26256-3.s  | 18 +++++++
> ld/testsuite/ld-elf/pr26256-3a.d |  9 ++++
> ld/testsuite/ld-elf/pr26256-3a.t | 13 +++++
> ld/testsuite/ld-elf/pr26256-3b.d |  9 ++++
> ld/testsuite/ld-elf/pr26256-3b.t | 12 +++++
> 18 files changed, 259 insertions(+), 25 deletions(-)
> create mode 100644 ld/testsuite/ld-elf/pr26256-1.s
> create mode 100644 ld/testsuite/ld-elf/pr26256-1.t
> create mode 100644 ld/testsuite/ld-elf/pr26256-1a.d
> create mode 100644 ld/testsuite/ld-elf/pr26256-1b.d
> create mode 100644 ld/testsuite/ld-elf/pr26256-2.s
> create mode 100644 ld/testsuite/ld-elf/pr26256-2.t
> create mode 100644 ld/testsuite/ld-elf/pr26256-2a.d
> create mode 100644 ld/testsuite/ld-elf/pr26256-2b.d
> create mode 100644 ld/testsuite/ld-elf/pr26256-3.s
> create mode 100644 ld/testsuite/ld-elf/pr26256-3a.d
> create mode 100644 ld/testsuite/ld-elf/pr26256-3a.t
> create mode 100644 ld/testsuite/ld-elf/pr26256-3b.d
> create mode 100644 ld/testsuite/ld-elf/pr26256-3b.t
>
>diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
>index f1bef5742a..cc5a3c9912 100644
>--- a/bfd/bfd-in2.h
>+++ b/bfd/bfd-in2.h
>@@ -1184,6 +1184,9 @@ typedef struct bfd_section
>   struct bfd_symbol *symbol;
>   struct bfd_symbol **symbol_ptr_ptr;
>
>+  /* The matching section name pattern in linker script.  */
>+  const char *pattern;
>+
>   /* Early in the link process, map_head and map_tail are used to build
>      a list of input sections attached to an output section.  Later,
>      output sections use these fields for a list of bfd_link_order
>@@ -1377,8 +1380,8 @@ discarded_section (const asection *sec)
>   /* target_index, used_by_bfd, constructor_chain, owner,           */ \
>      0,            NULL,        NULL,              NULL,               \
>                                                                        \
>-  /* symbol,                    symbol_ptr_ptr,                     */ \
>-     (struct bfd_symbol *) SYM, &SEC.symbol,                           \
>+  /* symbol,                    symbol_ptr_ptr, pattern,            */ \
>+     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,                  \
>                                                                        \
>   /* map_head, map_tail, already_assigned                           */ \
>      { NULL }, { NULL }, NULL                                          \
>diff --git a/bfd/elflink.c b/bfd/elflink.c
>index 1b3398126f..6930c7c741 100644
>--- a/bfd/elflink.c
>+++ b/bfd/elflink.c
>@@ -11867,8 +11867,21 @@ compare_link_order (const void *a, const void *b)
>   const struct bfd_link_order *blo = *(const struct bfd_link_order **) b;
>   asection *asec = elf_linked_to_section (alo->u.indirect.section);
>   asection *bsec = elf_linked_to_section (blo->u.indirect.section);
>-  bfd_vma apos = asec->output_section->lma + asec->output_offset;
>-  bfd_vma bpos = bsec->output_section->lma + bsec->output_offset;
>+  bfd_vma apos, bpos;
>+
>+  /* Check if any sections are unordered.  */
>+  if (asec == NULL || bsec == NULL)
>+    {
>+      /* Place unordered sections before ordered sections.  */
>+      if (bsec != NULL)
>+	return -1;
>+      else if (asec != NULL)
>+	return 1;
>+      return 0;
>+    }
>+

I just commented that LLD places ordered sections before unordered sections.
https://sourceware.org/bugzilla/show_bug.cgi?id=26256#c10
Solaris folks appear to prefer this style.

>+  apos = asec->output_section->lma + asec->output_offset;
>+  bpos = bsec->output_section->lma + bsec->output_offset;
>
>   if (apos < bpos)
>     return -1;
>@@ -11903,14 +11916,14 @@ compare_link_order (const void *a, const void *b)
>    sections.  Ideally we'd do this in the linker proper.  */
>
> static bfd_boolean
>-elf_fixup_link_order (bfd *abfd, asection *o)
>+elf_fixup_link_order (struct bfd_link_info *info, bfd *abfd, asection *o)
> {
>   size_t seen_linkorder;
>   size_t seen_other;
>   size_t n;
>   struct bfd_link_order *p;
>   bfd *sub;
>-  struct bfd_link_order **sections;
>+  struct bfd_link_order **sections, **indirect_sections;
>   asection *other_sec, *linkorder_sec;
>   bfd_vma offset;  /* Octets.  */
>
>@@ -11941,7 +11954,9 @@ elf_fixup_link_order (bfd *abfd, asection *o)
>       else
> 	seen_other++;
>
>-      if (seen_other && seen_linkorder)
>+      /* Allow mixed ordered and unordered input sections for
>+         non-relocatable link.  */
>+      if (bfd_link_relocatable (info) && seen_other && seen_linkorder)
> 	{
> 	  if (other_sec && linkorder_sec)
> 	    _bfd_error_handler

I don't take time investigating the logic here. But about -r &
SHF_LINK_ORDER:
https://sourceware.org/bugzilla/show_bug.cgi?id=26256#c11

>@@ -11961,6 +11976,10 @@ elf_fixup_link_order (bfd *abfd, asection *o)
>   if (!seen_linkorder)
>     return TRUE;
>
>+  /* Non-relocatable output can have both ordered and unordered input
>+     sections.  */
>+  seen_linkorder += seen_other;
>+
>   sections = bfd_malloc (seen_linkorder * sizeof (*sections));
>   if (sections == NULL)
>     return FALSE;
>@@ -11969,22 +11988,48 @@ elf_fixup_link_order (bfd *abfd, asection *o)
>   for (p = o->map_head.link_order; p != NULL; p = p->next)
>     sections[seen_linkorder++] = p;
>
>-  /* Sort the input sections in the order of their linked section.  */
>-  qsort (sections, seen_linkorder, sizeof (*sections), compare_link_order);
>+  for (indirect_sections = sections, n = 0;
>+       n < seen_linkorder;
>+       indirect_sections++, n++)
>+    {
>+      /* Find the first bfd_indirect_link_order section.  */
>+      if (indirect_sections[0]->type == bfd_indirect_link_order)
>+	{
>+	  /* Count the consecutive bfd_indirect_link_order sections
>+	     with the same pattern.  */
>+	  size_t i, n_indirect;
>+	  const char *pattern
>+	    = indirect_sections[0]->u.indirect.section->pattern;
>+	  for (i = n + 1; i < seen_linkorder; i++)
>+	    if (sections[i]->type != bfd_indirect_link_order
>+		|| sections[i]->u.indirect.section->pattern != pattern)
>+	      break;
>+	  n_indirect = i - n;
>+	  /* Sort the bfd_indirect_link_order sections in the order of
>+	     their linked section.  */
>+	  qsort (indirect_sections, n_indirect, sizeof (*sections),
>+		 compare_link_order);
>+	  indirect_sections += n_indirect;
>+	  n += n_indirect;
>+	}
>+    }
>
>-  /* Change the offsets of the sections.  */
>+  /* Change the offsets of the bfd_indirect_link_order sections.  */
>   offset = 0;
>   for (n = 0; n < seen_linkorder; n++)
>-    {
>-      bfd_vma mask;
>-      asection *s = sections[n]->u.indirect.section;
>-      unsigned int opb = bfd_octets_per_byte (abfd, s);
>-
>-      mask = ~(bfd_vma) 0 << s->alignment_power * opb;
>-      offset = (offset + ~mask) & mask;
>-      sections[n]->offset = s->output_offset = offset / opb;
>-      offset += sections[n]->size;
>-    }
>+    if (sections[n]->type == bfd_indirect_link_order)
>+      {
>+	bfd_vma mask;
>+	asection *s = sections[n]->u.indirect.section;
>+	unsigned int opb = bfd_octets_per_byte (abfd, s);
>+
>+	mask = ~(bfd_vma) 0 << s->alignment_power * opb;
>+	offset = (offset + ~mask) & mask;
>+	sections[n]->offset = s->output_offset = offset / opb;
>+	offset += sections[n]->size;
>+      }
>+    else
>+      offset = sections[n]->offset + sections[n]->size;
>
>   free (sections);
>   return TRUE;
>@@ -12627,7 +12672,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
>   /* Reorder SHF_LINK_ORDER sections.  */
>   for (o = abfd->sections; o != NULL; o = o->next)
>     {
>-      if (!elf_fixup_link_order (abfd, o))
>+      if (!elf_fixup_link_order (info, abfd, o))
> 	return FALSE;
>     }
>
>diff --git a/bfd/section.c b/bfd/section.c
>index 17f5b4c3d8..aa383626e2 100644
>--- a/bfd/section.c
>+++ b/bfd/section.c
>@@ -541,6 +541,9 @@ CODE_FRAGMENT
> .  struct bfd_symbol *symbol;
> .  struct bfd_symbol **symbol_ptr_ptr;
> .
>+.  {* The matching section name pattern in linker script.  *}
>+.  const char *pattern;
>+.
> .  {* Early in the link process, map_head and map_tail are used to build
> .     a list of input sections attached to an output section.  Later,
> .     output sections use these fields for a list of bfd_link_order
>@@ -734,8 +737,8 @@ CODE_FRAGMENT
> .  {* target_index, used_by_bfd, constructor_chain, owner,           *}	\
> .     0,            NULL,        NULL,              NULL,		\
> .									\
>-.  {* symbol,                    symbol_ptr_ptr,                     *}	\
>-.     (struct bfd_symbol *) SYM, &SEC.symbol,				\
>+.  {* symbol,                    symbol_ptr_ptr, pattern,            *}	\
>+.     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,			\
> .									\
> .  {* map_head, map_tail, already_assigned                           *}	\
> .     { NULL }, { NULL }, NULL						\
>diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
>index d030b548fb..621c35c182 100644
>--- a/gas/config/obj-elf.c
>+++ b/gas/config/obj-elf.c
>@@ -666,7 +666,9 @@ obj_elf_change_section (const char *name,
> 	    }
> 	}
>
>-      if (old_sec == NULL && ((attr & ~(SHF_MASKOS | SHF_MASKPROC))
>+      if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
>+					| SHF_MASKOS
>+					| SHF_MASKPROC))
> 			      & ~ssect->attr) != 0)
> 	{
> 	  /* As a GNU extension, we permit a .note section to be
>diff --git a/ld/ldlang.c b/ld/ldlang.c
>index 41000da1e1..935880cf94 100644
>--- a/ld/ldlang.c
>+++ b/ld/ldlang.c
>@@ -7486,7 +7486,7 @@ lang_reset_memory_regions (void)
>
> static void
> gc_section_callback (lang_wild_statement_type *ptr,
>-		     struct wildcard_list *sec ATTRIBUTE_UNUSED,
>+		     struct wildcard_list *sec,
> 		     asection *section,
> 		     struct flag_info *sflag_info ATTRIBUTE_UNUSED,
> 		     lang_input_statement_type *file ATTRIBUTE_UNUSED,
>@@ -7496,6 +7496,8 @@ gc_section_callback (lang_wild_statement_type *ptr,
>      should be as well.  */
>   if (ptr->keep_sections)
>     section->flags |= SEC_KEEP;
>+  if (sec)
>+    section->pattern = sec->spec.name;
> }
>
> /* Iterate over sections marking them against GC.  */
>diff --git a/ld/testsuite/ld-elf/pr26256-1.s b/ld/testsuite/ld-elf/pr26256-1.s
>new file mode 100644
>index 0000000000..7351f76655
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-1.s
>@@ -0,0 +1,20 @@
>+	.section	.text.bar,"ax",%progbits
>+	.globl	bar
>+	.type	bar, %function
>+bar:
>+	.section __patchable_function_entries,"awo",%progbits,bar
>+	.dc.a	.LPFE1
>+	.section	.text.bar,"ax",%progbits
>+.LPFE1:
>+	.byte 0
>+	.section	.text._start,"ax",%progbits
>+	.globl	_start
>+	.type	_start, %function
>+_start:
>+	.section __patchable_function_entries,"awo",%progbits,_start
>+	.dc.a	.LPFE2
>+	.section	.text._start,"ax",%progbits
>+.LPFE2:
>+	.byte 0
>+	.section .init.data,"aw",%progbits
>+	.byte 0
>diff --git a/ld/testsuite/ld-elf/pr26256-1.t b/ld/testsuite/ld-elf/pr26256-1.t
>new file mode 100644
>index 0000000000..bc5232b0ae
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-1.t
>@@ -0,0 +1,9 @@
>+SECTIONS
>+{
>+  .text : { *(.text*) }
>+  .init.data :
>+  {
>+    *(.init.data);
>+    *(__patchable_function_entries);
>+  }
>+}
>diff --git a/ld/testsuite/ld-elf/pr26256-1a.d b/ld/testsuite/ld-elf/pr26256-1a.d
>new file mode 100644
>index 0000000000..025ace0e87
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-1a.d
>@@ -0,0 +1,7 @@
>+#source: pr26256-1.s
>+#ld: -e _start -T pr26256-1.t
>+#nm: -n
>+
>+#...
>+[0-9a-f]+ T _start
>+#pass
>diff --git a/ld/testsuite/ld-elf/pr26256-1b.d b/ld/testsuite/ld-elf/pr26256-1b.d
>new file mode 100644
>index 0000000000..760c6d82e7
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-1b.d
>@@ -0,0 +1,7 @@
>+#source: pr26256-1.s
>+#ld: -e _start
>+#nm: -n
>+
>+#...
>+[0-9a-f]+ T _start
>+#pass
>diff --git a/ld/testsuite/ld-elf/pr26256-2.s b/ld/testsuite/ld-elf/pr26256-2.s
>new file mode 100644
>index 0000000000..70e3693f42
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-2.s
>@@ -0,0 +1,32 @@
>+	.section .text,"ax",%progbits,unique,0
>+	.globl text0
>+text0:
>+	.nop
>+	.section .text,"ax",%progbits,unique,1
>+	.globl text1
>+text1:
>+	.nop
>+	.section .linkorder,"ao",%progbits,0,unique,0
>+	.globl linkorder2
>+linkorder2:
>+	.byte 0
>+	.section .linkorder,"ao",%progbits,text0
>+	.globl linkorder0
>+linkorder0:
>+	.byte 1
>+	.section .linkorder,"ao",%progbits,text1
>+	.globl linkorder1
>+linkorder1:
>+	.byte 2
>+	.section .linkorder,"a",%progbits
>+	.globl linkorder3
>+linkorder3:
>+	.byte 3
>+	.section .linkorder,"ao",%progbits,0,unique,3
>+	.globl linkorder4
>+linkorder4:
>+	.byte 4
>+	.text
>+	.global _start
>+_start:
>+	.nop
>diff --git a/ld/testsuite/ld-elf/pr26256-2.t b/ld/testsuite/ld-elf/pr26256-2.t
>new file mode 100644
>index 0000000000..a69c01682e
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-2.t
>@@ -0,0 +1,5 @@
>+SECTIONS
>+{
>+  .linkorder : { *(.linkorder.*) }
>+  .text : { *(.text) }
>+}
>diff --git a/ld/testsuite/ld-elf/pr26256-2a.d b/ld/testsuite/ld-elf/pr26256-2a.d
>new file mode 100644
>index 0000000000..24e8e67ec3
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-2a.d
>@@ -0,0 +1,19 @@
>+#source: pr26256-2.s
>+#ld: -e _start -T pr26256-2.t
>+#nm: -n
>+
>+#...
>+[0-9a-f]+ R linkorder2
>+#...
>+[0-9a-f]+ R linkorder3
>+#...
>+[0-9a-f]+ R linkorder4
>+#...
>+[0-9a-f]+ R linkorder0
>+#...
>+[0-9a-f]+ R linkorder1
>+#...
>+[0-9a-f]+ T text0
>+#...
>+[0-9a-f]+ T text1
>+#pass
>diff --git a/ld/testsuite/ld-elf/pr26256-2b.d b/ld/testsuite/ld-elf/pr26256-2b.d
>new file mode 100644
>index 0000000000..f9bc557777
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-2b.d
>@@ -0,0 +1,19 @@
>+#source: pr26256-2.s
>+#ld: -e _start
>+#nm: -n
>+
>+#...
>+[0-9a-f]+ T text0
>+#...
>+[0-9a-f]+ T text1
>+#...
>+[0-9a-f]+ R linkorder2
>+#...
>+[0-9a-f]+ R linkorder3
>+#...
>+[0-9a-f]+ R linkorder4
>+#...
>+[0-9a-f]+ R linkorder0
>+#...
>+[0-9a-f]+ R linkorder1
>+#pass
>diff --git a/ld/testsuite/ld-elf/pr26256-3.s b/ld/testsuite/ld-elf/pr26256-3.s
>new file mode 100644
>index 0000000000..276f9de055
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-3.s
>@@ -0,0 +1,18 @@
>+	.text
>+	.global _start
>+_start:
>+	.byte 3
>+
>+	.section .rosection,"a"
>+	.byte 9
>+
>+	.section .text.bar,"a",%progbits
>+	.byte 2
>+	.section .text.foo,"a",%progbits
>+	.byte 1
>+	.section .rodata.foo,"ao",%progbits,.text.foo
>+	.byte 1
>+	.section .rodata.bar,"a",%progbits
>+	.byte 2
>+	.section .rodata.bar,"ao",%progbits,.text.bar
>+	.byte 3
>diff --git a/ld/testsuite/ld-elf/pr26256-3a.d b/ld/testsuite/ld-elf/pr26256-3a.d
>new file mode 100644
>index 0000000000..3cef3a94c0
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-3a.d
>@@ -0,0 +1,9 @@
>+#source: pr26256-3.s
>+#ld: -e _start -T pr26256-3a.t
>+#readelf: -x .rodata -x .text
>+
>+Hex dump of section \'.rodata\':
>+  0x[a-f0-9]+ +00010203 +040907 +.+
>+
>+Hex dump of section \'.text\':
>+  0x[a-f0-9]+ +020103 +.+
>diff --git a/ld/testsuite/ld-elf/pr26256-3a.t b/ld/testsuite/ld-elf/pr26256-3a.t
>new file mode 100644
>index 0000000000..7add651a71
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-3a.t
>@@ -0,0 +1,13 @@
>+SECTIONS
>+{
>+  .rodata :
>+    {
>+      BYTE(0)
>+      *(.rodata.foo)
>+      *(.rodata.bar)
>+      BYTE(4)
>+      *(.rosection)
>+      BYTE(7)
>+    }
>+  .text : {*(.text.bar) *(.text.foo)}
>+}
>diff --git a/ld/testsuite/ld-elf/pr26256-3b.d b/ld/testsuite/ld-elf/pr26256-3b.d
>new file mode 100644
>index 0000000000..031de2de6f
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-3b.d
>@@ -0,0 +1,9 @@
>+#source: pr26256-3.s
>+#ld: -e _start -T pr26256-3b.t
>+#readelf: -x .rodata -x .text
>+
>+Hex dump of section \'.rodata\':
>+  0x[a-f0-9]+ +00020301 +040907 +.+
>+
>+Hex dump of section \'.text\':
>+  0x[a-f0-9]+ +020103 +.+
>diff --git a/ld/testsuite/ld-elf/pr26256-3b.t b/ld/testsuite/ld-elf/pr26256-3b.t
>new file mode 100644
>index 0000000000..6f72e93bad
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/pr26256-3b.t
>@@ -0,0 +1,12 @@
>+SECTIONS
>+{
>+  .rodata :
>+    {
>+      BYTE(0)
>+      *(.rodata*)
>+      BYTE(4)
>+      *(.rosection)
>+      BYTE(7)
>+    }
>+  .text : {*(.text.bar) *(.text.foo)}
>+}
>-- 
>2.29.2
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* V2 [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable link
  2020-12-21 23:24 ` Fangrui Song
@ 2020-12-22  4:21   ` H.J. Lu
  2020-12-22 13:24     ` V3 " H.J. Lu
  0 siblings, 1 reply; 7+ messages in thread
From: H.J. Lu @ 2020-12-22  4:21 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

[-- Attachment #1: Type: text/plain, Size: 8538 bytes --]

On Mon, Dec 21, 2020 at 3:24 PM Fangrui Song <i@maskray.me> wrote:
>
> Really appreciate this patch! For RISC-V -mrelax, .gcc_except_table
> has relocations referencing .text . I don't know whether GNU ld does
> ad-hoc garbage collection for .gcc_except_table, if it doesn't, in the
> future GCC can set SHF_LINK_ORDER on .gcc_except_table to allow a
> non-adhoc garbage collection. I have a write-up about this
> https://maskray.me/blog/2020-12-12-c++-exception-handling-abi#monolithic-.gcc_except_table
> In particular, I mentioned on https://reviews.llvm.org/D83655
> that Clang cannot use SHF_LINK_ORDER.
>
> On 2020-12-21, H.J. Lu via Binutils wrote:
> >For non-relocatable link with SHF_LINK_ORDER inputs, allow mixed indirect
> >and data inputs with ordered and unordered inputs:
> >
> >1. Add pattern to bfd_section for the matching section name pattern in
> >linker script and update BFD_FAKE_SECTION.
> >2. Sort the consecutive bfd_indirect_link_order sections with the same
> >pattern to allow linker script to overdide input section order.
> >3. Place unordered sections before ordered sections.
> >4. Change the offsets of the indirect input sections only.
> >
> >bfd/
> >
> >       PR ld/26256
> >       * elflink.c (compare_link_order): Place unordered sections before
> >       ordered sections.
> >       (elf_fixup_link_order): Add a link info argument.  Allow mixed
> >       ordered and unordered input sections for non-relocatable link.
> >       Sort the consecutive bfd_indirect_link_order sections with the
> >       same pattern.  Change the offsets of the bfd_indirect_link_order
> >       sections only.
> >       (bfd_elf_final_link): Pass info to elf_fixup_link_order.
> >       * section.c (bfd_section): Add pattern.
> >       (BFD_FAKE_SECTION): Initialize pattern to NULL.
> >       * bfd-in2.h: Regenerated.
> >
> >gas/
> >
> >       PR ld/26256
> >       * config/obj-elf.c (obj_elf_change_section): Also filter out
> >       SHF_LINK_ORDER.
> >
> >ld/
> >
> >       PR ld/26256
> >       * ldlang.c (gc_section_callback): Set pattern.
> >       * testsuite/ld-elf/pr26256-1.s: New file.
> >       * testsuite/ld-elf/pr26256-1.t: Likewise.
> >       * testsuite/ld-elf/pr26256-1a.d: Likewise.
> >       * testsuite/ld-elf/pr26256-1b.d: Likewise.
> >       * testsuite/ld-elf/pr26256-2.s: Likewise.
> >       * testsuite/ld-elf/pr26256-2.t: Likewise.
> >       * testsuite/ld-elf/pr26256-2a.d: Likewise.
> >       * testsuite/ld-elf/pr26256-2b.d: Likewise.
> >       * testsuite/ld-elf/pr26256-3.s: Likewise.
> >       * testsuite/ld-elf/pr26256-3a.d: Likewise.
> >       * testsuite/ld-elf/pr26256-3a.t: Likewise.
> >       * testsuite/ld-elf/pr26256-3b.d: Likewise.
> >       * testsuite/ld-elf/pr26256-3b.t: Likewise.
> >---
> > bfd/bfd-in2.h                    |  7 ++-
> > bfd/elflink.c                    | 83 ++++++++++++++++++++++++--------
> > bfd/section.c                    |  7 ++-
> > gas/config/obj-elf.c             |  4 +-
> > ld/ldlang.c                      |  4 +-
> > ld/testsuite/ld-elf/pr26256-1.s  | 20 ++++++++
> > ld/testsuite/ld-elf/pr26256-1.t  |  9 ++++
> > ld/testsuite/ld-elf/pr26256-1a.d |  7 +++
> > ld/testsuite/ld-elf/pr26256-1b.d |  7 +++
> > ld/testsuite/ld-elf/pr26256-2.s  | 32 ++++++++++++
> > ld/testsuite/ld-elf/pr26256-2.t  |  5 ++
> > ld/testsuite/ld-elf/pr26256-2a.d | 19 ++++++++
> > ld/testsuite/ld-elf/pr26256-2b.d | 19 ++++++++
> > ld/testsuite/ld-elf/pr26256-3.s  | 18 +++++++
> > ld/testsuite/ld-elf/pr26256-3a.d |  9 ++++
> > ld/testsuite/ld-elf/pr26256-3a.t | 13 +++++
> > ld/testsuite/ld-elf/pr26256-3b.d |  9 ++++
> > ld/testsuite/ld-elf/pr26256-3b.t | 12 +++++
> > 18 files changed, 259 insertions(+), 25 deletions(-)
> > create mode 100644 ld/testsuite/ld-elf/pr26256-1.s
> > create mode 100644 ld/testsuite/ld-elf/pr26256-1.t
> > create mode 100644 ld/testsuite/ld-elf/pr26256-1a.d
> > create mode 100644 ld/testsuite/ld-elf/pr26256-1b.d
> > create mode 100644 ld/testsuite/ld-elf/pr26256-2.s
> > create mode 100644 ld/testsuite/ld-elf/pr26256-2.t
> > create mode 100644 ld/testsuite/ld-elf/pr26256-2a.d
> > create mode 100644 ld/testsuite/ld-elf/pr26256-2b.d
> > create mode 100644 ld/testsuite/ld-elf/pr26256-3.s
> > create mode 100644 ld/testsuite/ld-elf/pr26256-3a.d
> > create mode 100644 ld/testsuite/ld-elf/pr26256-3a.t
> > create mode 100644 ld/testsuite/ld-elf/pr26256-3b.d
> > create mode 100644 ld/testsuite/ld-elf/pr26256-3b.t
> >
> >diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> >index f1bef5742a..cc5a3c9912 100644
> >--- a/bfd/bfd-in2.h
> >+++ b/bfd/bfd-in2.h
> >@@ -1184,6 +1184,9 @@ typedef struct bfd_section
> >   struct bfd_symbol *symbol;
> >   struct bfd_symbol **symbol_ptr_ptr;
> >
> >+  /* The matching section name pattern in linker script.  */
> >+  const char *pattern;
> >+
> >   /* Early in the link process, map_head and map_tail are used to build
> >      a list of input sections attached to an output section.  Later,
> >      output sections use these fields for a list of bfd_link_order
> >@@ -1377,8 +1380,8 @@ discarded_section (const asection *sec)
> >   /* target_index, used_by_bfd, constructor_chain, owner,           */ \
> >      0,            NULL,        NULL,              NULL,               \
> >                                                                        \
> >-  /* symbol,                    symbol_ptr_ptr,                     */ \
> >-     (struct bfd_symbol *) SYM, &SEC.symbol,                           \
> >+  /* symbol,                    symbol_ptr_ptr, pattern,            */ \
> >+     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,                  \
> >                                                                        \
> >   /* map_head, map_tail, already_assigned                           */ \
> >      { NULL }, { NULL }, NULL                                          \
> >diff --git a/bfd/elflink.c b/bfd/elflink.c
> >index 1b3398126f..6930c7c741 100644
> >--- a/bfd/elflink.c
> >+++ b/bfd/elflink.c
> >@@ -11867,8 +11867,21 @@ compare_link_order (const void *a, const void *b)
> >   const struct bfd_link_order *blo = *(const struct bfd_link_order **) b;
> >   asection *asec = elf_linked_to_section (alo->u.indirect.section);
> >   asection *bsec = elf_linked_to_section (blo->u.indirect.section);
> >-  bfd_vma apos = asec->output_section->lma + asec->output_offset;
> >-  bfd_vma bpos = bsec->output_section->lma + bsec->output_offset;
> >+  bfd_vma apos, bpos;
> >+
> >+  /* Check if any sections are unordered.  */
> >+  if (asec == NULL || bsec == NULL)
> >+    {
> >+      /* Place unordered sections before ordered sections.  */
> >+      if (bsec != NULL)
> >+      return -1;
> >+      else if (asec != NULL)
> >+      return 1;
> >+      return 0;
> >+    }
> >+
>
> I just commented that LLD places ordered sections before unordered sections.
> https://sourceware.org/bugzilla/show_bug.cgi?id=26256#c10
> Solaris folks appear to prefer this style.

Changed.

> >+  apos = asec->output_section->lma + asec->output_offset;
> >+  bpos = bsec->output_section->lma + bsec->output_offset;
> >
> >   if (apos < bpos)
> >     return -1;
> >@@ -11903,14 +11916,14 @@ compare_link_order (const void *a, const void *b)
> >    sections.  Ideally we'd do this in the linker proper.  */
> >
> > static bfd_boolean
> >-elf_fixup_link_order (bfd *abfd, asection *o)
> >+elf_fixup_link_order (struct bfd_link_info *info, bfd *abfd, asection *o)
> > {
> >   size_t seen_linkorder;
> >   size_t seen_other;
> >   size_t n;
> >   struct bfd_link_order *p;
> >   bfd *sub;
> >-  struct bfd_link_order **sections;
> >+  struct bfd_link_order **sections, **indirect_sections;
> >   asection *other_sec, *linkorder_sec;
> >   bfd_vma offset;  /* Octets.  */
> >
> >@@ -11941,7 +11954,9 @@ elf_fixup_link_order (bfd *abfd, asection *o)
> >       else
> >       seen_other++;
> >
> >-      if (seen_other && seen_linkorder)
> >+      /* Allow mixed ordered and unordered input sections for
> >+         non-relocatable link.  */
> >+      if (bfd_link_relocatable (info) && seen_other && seen_linkorder)
> >       {
> >         if (other_sec && linkorder_sec)
> >           _bfd_error_handler
>
> I don't take time investigating the logic here. But about -r &
> SHF_LINK_ORDER:
> https://sourceware.org/bugzilla/show_bug.cgi?id=26256#c11

"ld-r" also uses a linker script:

  .rodata       0 : { *(.rodata) }
  .rodata1      0 : { *(.rodata1) }

What happens if 2 .rodata sections have different HF_LINK_ORDER?
It is better for ld to reject it.

OK for master?

-- 
H.J.

[-- Attachment #2: 0001-elf-Allow-mixed-ordered-unordered-inputs-for-non-rel.patch --]
[-- Type: text/x-patch, Size: 17778 bytes --]

From 35009bb198853e1b397c6cbdf2f2d110802a220f Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sat, 19 Dec 2020 13:16:17 -0800
Subject: [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable
 link

For non-relocatable link with SHF_LINK_ORDER inputs, allow mixed indirect
and data inputs with ordered and unordered inputs:

1. Add pattern to bfd_section for the matching section name pattern in
linker script and update BFD_FAKE_SECTION.
2. Sort the consecutive bfd_indirect_link_order sections with the same
pattern to allow linker script to overdide input section order.
3. Place unordered sections before ordered sections.
4. Change the offsets of the indirect input sections only.

bfd/

	PR ld/26256
	* elflink.c (compare_link_order): Place unordered sections before
	ordered sections.
	(elf_fixup_link_order): Add a link info argument.  Allow mixed
	ordered and unordered input sections for non-relocatable link.
	Sort the consecutive bfd_indirect_link_order sections with the
	same pattern.  Change the offsets of the bfd_indirect_link_order
	sections only.
	(bfd_elf_final_link): Pass info to elf_fixup_link_order.
	* section.c (bfd_section): Add pattern.
	(BFD_FAKE_SECTION): Initialize pattern to NULL.
	* bfd-in2.h: Regenerated.

gas/

	PR ld/26256
	* config/obj-elf.c (obj_elf_change_section): Also filter out
	SHF_LINK_ORDER.

ld/

	PR ld/26256
	* ldlang.c (gc_section_callback): Set pattern.
	* testsuite/ld-elf/pr26256-1.s: New file.
	* testsuite/ld-elf/pr26256-1.t: Likewise.
	* testsuite/ld-elf/pr26256-1a.d: Likewise.
	* testsuite/ld-elf/pr26256-1b.d: Likewise.
	* testsuite/ld-elf/pr26256-2.s: Likewise.
	* testsuite/ld-elf/pr26256-2.t: Likewise.
	* testsuite/ld-elf/pr26256-2a.d: Likewise.
	* testsuite/ld-elf/pr26256-2b.d: Likewise.
	* testsuite/ld-elf/pr26256-3.s: Likewise.
	* testsuite/ld-elf/pr26256-3a.d: Likewise.
	* testsuite/ld-elf/pr26256-3a.t: Likewise.
	* testsuite/ld-elf/pr26256-3b.d: Likewise.
	* testsuite/ld-elf/pr26256-3b.t: Likewise.
---
 bfd/bfd-in2.h                    |  7 ++-
 bfd/elflink.c                    | 83 ++++++++++++++++++++++++--------
 bfd/section.c                    |  7 ++-
 gas/config/obj-elf.c             |  4 +-
 ld/ldlang.c                      |  4 +-
 ld/testsuite/ld-elf/pr26256-1.s  | 20 ++++++++
 ld/testsuite/ld-elf/pr26256-1.t  |  9 ++++
 ld/testsuite/ld-elf/pr26256-1a.d |  7 +++
 ld/testsuite/ld-elf/pr26256-1b.d |  7 +++
 ld/testsuite/ld-elf/pr26256-2.s  | 32 ++++++++++++
 ld/testsuite/ld-elf/pr26256-2.t  |  5 ++
 ld/testsuite/ld-elf/pr26256-2a.d | 19 ++++++++
 ld/testsuite/ld-elf/pr26256-2b.d | 19 ++++++++
 ld/testsuite/ld-elf/pr26256-3.s  | 18 +++++++
 ld/testsuite/ld-elf/pr26256-3a.d |  9 ++++
 ld/testsuite/ld-elf/pr26256-3a.t | 13 +++++
 ld/testsuite/ld-elf/pr26256-3b.d |  9 ++++
 ld/testsuite/ld-elf/pr26256-3b.t | 12 +++++
 18 files changed, 259 insertions(+), 25 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr26256-1.s
 create mode 100644 ld/testsuite/ld-elf/pr26256-1.t
 create mode 100644 ld/testsuite/ld-elf/pr26256-1a.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-1b.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-2.s
 create mode 100644 ld/testsuite/ld-elf/pr26256-2.t
 create mode 100644 ld/testsuite/ld-elf/pr26256-2a.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-2b.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-3.s
 create mode 100644 ld/testsuite/ld-elf/pr26256-3a.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-3a.t
 create mode 100644 ld/testsuite/ld-elf/pr26256-3b.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-3b.t

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index f1bef5742a..cc5a3c9912 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1184,6 +1184,9 @@ typedef struct bfd_section
   struct bfd_symbol *symbol;
   struct bfd_symbol **symbol_ptr_ptr;
 
+  /* The matching section name pattern in linker script.  */
+  const char *pattern;
+
   /* Early in the link process, map_head and map_tail are used to build
      a list of input sections attached to an output section.  Later,
      output sections use these fields for a list of bfd_link_order
@@ -1377,8 +1380,8 @@ discarded_section (const asection *sec)
   /* target_index, used_by_bfd, constructor_chain, owner,           */ \
      0,            NULL,        NULL,              NULL,               \
                                                                        \
-  /* symbol,                    symbol_ptr_ptr,                     */ \
-     (struct bfd_symbol *) SYM, &SEC.symbol,                           \
+  /* symbol,                    symbol_ptr_ptr, pattern,            */ \
+     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,                  \
                                                                        \
   /* map_head, map_tail, already_assigned                           */ \
      { NULL }, { NULL }, NULL                                          \
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 1b3398126f..a1e4635e96 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11867,8 +11867,21 @@ compare_link_order (const void *a, const void *b)
   const struct bfd_link_order *blo = *(const struct bfd_link_order **) b;
   asection *asec = elf_linked_to_section (alo->u.indirect.section);
   asection *bsec = elf_linked_to_section (blo->u.indirect.section);
-  bfd_vma apos = asec->output_section->lma + asec->output_offset;
-  bfd_vma bpos = bsec->output_section->lma + bsec->output_offset;
+  bfd_vma apos, bpos;
+
+  /* Check if any sections are unordered.  */
+  if (asec == NULL || bsec == NULL)
+    {
+      /* Place ordered sections before unordered sections.  */
+      if (bsec != NULL)
+	return 1;
+      else if (asec != NULL)
+	return -1;
+      return 0;
+    }
+
+  apos = asec->output_section->lma + asec->output_offset;
+  bpos = bsec->output_section->lma + bsec->output_offset;
 
   if (apos < bpos)
     return -1;
@@ -11903,14 +11916,14 @@ compare_link_order (const void *a, const void *b)
    sections.  Ideally we'd do this in the linker proper.  */
 
 static bfd_boolean
-elf_fixup_link_order (bfd *abfd, asection *o)
+elf_fixup_link_order (struct bfd_link_info *info, bfd *abfd, asection *o)
 {
   size_t seen_linkorder;
   size_t seen_other;
   size_t n;
   struct bfd_link_order *p;
   bfd *sub;
-  struct bfd_link_order **sections;
+  struct bfd_link_order **sections, **indirect_sections;
   asection *other_sec, *linkorder_sec;
   bfd_vma offset;  /* Octets.  */
 
@@ -11941,7 +11954,9 @@ elf_fixup_link_order (bfd *abfd, asection *o)
       else
 	seen_other++;
 
-      if (seen_other && seen_linkorder)
+      /* Allow mixed ordered and unordered input sections for
+         non-relocatable link.  */
+      if (bfd_link_relocatable (info) && seen_other && seen_linkorder)
 	{
 	  if (other_sec && linkorder_sec)
 	    _bfd_error_handler
@@ -11961,6 +11976,10 @@ elf_fixup_link_order (bfd *abfd, asection *o)
   if (!seen_linkorder)
     return TRUE;
 
+  /* Non-relocatable output can have both ordered and unordered input
+     sections.  */
+  seen_linkorder += seen_other;
+
   sections = bfd_malloc (seen_linkorder * sizeof (*sections));
   if (sections == NULL)
     return FALSE;
@@ -11969,22 +11988,48 @@ elf_fixup_link_order (bfd *abfd, asection *o)
   for (p = o->map_head.link_order; p != NULL; p = p->next)
     sections[seen_linkorder++] = p;
 
-  /* Sort the input sections in the order of their linked section.  */
-  qsort (sections, seen_linkorder, sizeof (*sections), compare_link_order);
+  for (indirect_sections = sections, n = 0;
+       n < seen_linkorder;
+       indirect_sections++, n++)
+    {
+      /* Find the first bfd_indirect_link_order section.  */
+      if (indirect_sections[0]->type == bfd_indirect_link_order)
+	{
+	  /* Count the consecutive bfd_indirect_link_order sections
+	     with the same pattern.  */
+	  size_t i, n_indirect;
+	  const char *pattern
+	    = indirect_sections[0]->u.indirect.section->pattern;
+	  for (i = n + 1; i < seen_linkorder; i++)
+	    if (sections[i]->type != bfd_indirect_link_order
+		|| sections[i]->u.indirect.section->pattern != pattern)
+	      break;
+	  n_indirect = i - n;
+	  /* Sort the bfd_indirect_link_order sections in the order of
+	     their linked section.  */
+	  qsort (indirect_sections, n_indirect, sizeof (*sections),
+		 compare_link_order);
+	  indirect_sections += n_indirect;
+	  n += n_indirect;
+	}
+    }
 
-  /* Change the offsets of the sections.  */
+  /* Change the offsets of the bfd_indirect_link_order sections.  */
   offset = 0;
   for (n = 0; n < seen_linkorder; n++)
-    {
-      bfd_vma mask;
-      asection *s = sections[n]->u.indirect.section;
-      unsigned int opb = bfd_octets_per_byte (abfd, s);
-
-      mask = ~(bfd_vma) 0 << s->alignment_power * opb;
-      offset = (offset + ~mask) & mask;
-      sections[n]->offset = s->output_offset = offset / opb;
-      offset += sections[n]->size;
-    }
+    if (sections[n]->type == bfd_indirect_link_order)
+      {
+	bfd_vma mask;
+	asection *s = sections[n]->u.indirect.section;
+	unsigned int opb = bfd_octets_per_byte (abfd, s);
+
+	mask = ~(bfd_vma) 0 << s->alignment_power * opb;
+	offset = (offset + ~mask) & mask;
+	sections[n]->offset = s->output_offset = offset / opb;
+	offset += sections[n]->size;
+      }
+    else
+      offset = sections[n]->offset + sections[n]->size;
 
   free (sections);
   return TRUE;
@@ -12627,7 +12672,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   /* Reorder SHF_LINK_ORDER sections.  */
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      if (!elf_fixup_link_order (abfd, o))
+      if (!elf_fixup_link_order (info, abfd, o))
 	return FALSE;
     }
 
diff --git a/bfd/section.c b/bfd/section.c
index 17f5b4c3d8..aa383626e2 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -541,6 +541,9 @@ CODE_FRAGMENT
 .  struct bfd_symbol *symbol;
 .  struct bfd_symbol **symbol_ptr_ptr;
 .
+.  {* The matching section name pattern in linker script.  *}
+.  const char *pattern;
+.
 .  {* Early in the link process, map_head and map_tail are used to build
 .     a list of input sections attached to an output section.  Later,
 .     output sections use these fields for a list of bfd_link_order
@@ -734,8 +737,8 @@ CODE_FRAGMENT
 .  {* target_index, used_by_bfd, constructor_chain, owner,           *}	\
 .     0,            NULL,        NULL,              NULL,		\
 .									\
-.  {* symbol,                    symbol_ptr_ptr,                     *}	\
-.     (struct bfd_symbol *) SYM, &SEC.symbol,				\
+.  {* symbol,                    symbol_ptr_ptr, pattern,            *}	\
+.     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,			\
 .									\
 .  {* map_head, map_tail, already_assigned                           *}	\
 .     { NULL }, { NULL }, NULL						\
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index d030b548fb..621c35c182 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -666,7 +666,9 @@ obj_elf_change_section (const char *name,
 	    }
 	}
 
-      if (old_sec == NULL && ((attr & ~(SHF_MASKOS | SHF_MASKPROC))
+      if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
+					| SHF_MASKOS
+					| SHF_MASKPROC))
 			      & ~ssect->attr) != 0)
 	{
 	  /* As a GNU extension, we permit a .note section to be
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 41000da1e1..935880cf94 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -7486,7 +7486,7 @@ lang_reset_memory_regions (void)
 
 static void
 gc_section_callback (lang_wild_statement_type *ptr,
-		     struct wildcard_list *sec ATTRIBUTE_UNUSED,
+		     struct wildcard_list *sec,
 		     asection *section,
 		     struct flag_info *sflag_info ATTRIBUTE_UNUSED,
 		     lang_input_statement_type *file ATTRIBUTE_UNUSED,
@@ -7496,6 +7496,8 @@ gc_section_callback (lang_wild_statement_type *ptr,
      should be as well.  */
   if (ptr->keep_sections)
     section->flags |= SEC_KEEP;
+  if (sec)
+    section->pattern = sec->spec.name;
 }
 
 /* Iterate over sections marking them against GC.  */
diff --git a/ld/testsuite/ld-elf/pr26256-1.s b/ld/testsuite/ld-elf/pr26256-1.s
new file mode 100644
index 0000000000..7351f76655
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1.s
@@ -0,0 +1,20 @@
+	.section	.text.bar,"ax",%progbits
+	.globl	bar
+	.type	bar, %function
+bar:
+	.section __patchable_function_entries,"awo",%progbits,bar
+	.dc.a	.LPFE1
+	.section	.text.bar,"ax",%progbits
+.LPFE1:
+	.byte 0
+	.section	.text._start,"ax",%progbits
+	.globl	_start
+	.type	_start, %function
+_start:
+	.section __patchable_function_entries,"awo",%progbits,_start
+	.dc.a	.LPFE2
+	.section	.text._start,"ax",%progbits
+.LPFE2:
+	.byte 0
+	.section .init.data,"aw",%progbits
+	.byte 0
diff --git a/ld/testsuite/ld-elf/pr26256-1.t b/ld/testsuite/ld-elf/pr26256-1.t
new file mode 100644
index 0000000000..bc5232b0ae
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1.t
@@ -0,0 +1,9 @@
+SECTIONS
+{
+  .text : { *(.text*) }
+  .init.data :
+  {
+    *(.init.data);
+    *(__patchable_function_entries);
+  }
+}
diff --git a/ld/testsuite/ld-elf/pr26256-1a.d b/ld/testsuite/ld-elf/pr26256-1a.d
new file mode 100644
index 0000000000..025ace0e87
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1a.d
@@ -0,0 +1,7 @@
+#source: pr26256-1.s
+#ld: -e _start -T pr26256-1.t
+#nm: -n
+
+#...
+[0-9a-f]+ T _start
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-1b.d b/ld/testsuite/ld-elf/pr26256-1b.d
new file mode 100644
index 0000000000..760c6d82e7
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1b.d
@@ -0,0 +1,7 @@
+#source: pr26256-1.s
+#ld: -e _start
+#nm: -n
+
+#...
+[0-9a-f]+ T _start
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-2.s b/ld/testsuite/ld-elf/pr26256-2.s
new file mode 100644
index 0000000000..70e3693f42
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2.s
@@ -0,0 +1,32 @@
+	.section .text,"ax",%progbits,unique,0
+	.globl text0
+text0:
+	.nop
+	.section .text,"ax",%progbits,unique,1
+	.globl text1
+text1:
+	.nop
+	.section .linkorder,"ao",%progbits,0,unique,0
+	.globl linkorder2
+linkorder2:
+	.byte 0
+	.section .linkorder,"ao",%progbits,text0
+	.globl linkorder0
+linkorder0:
+	.byte 1
+	.section .linkorder,"ao",%progbits,text1
+	.globl linkorder1
+linkorder1:
+	.byte 2
+	.section .linkorder,"a",%progbits
+	.globl linkorder3
+linkorder3:
+	.byte 3
+	.section .linkorder,"ao",%progbits,0,unique,3
+	.globl linkorder4
+linkorder4:
+	.byte 4
+	.text
+	.global _start
+_start:
+	.nop
diff --git a/ld/testsuite/ld-elf/pr26256-2.t b/ld/testsuite/ld-elf/pr26256-2.t
new file mode 100644
index 0000000000..a69c01682e
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2.t
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .linkorder : { *(.linkorder.*) }
+  .text : { *(.text) }
+}
diff --git a/ld/testsuite/ld-elf/pr26256-2a.d b/ld/testsuite/ld-elf/pr26256-2a.d
new file mode 100644
index 0000000000..e2250c7e40
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2a.d
@@ -0,0 +1,19 @@
+#source: pr26256-2.s
+#ld: -e _start -T pr26256-2.t
+#nm: -n
+
+#...
+[0-9a-f]+ R linkorder0
+#...
+[0-9a-f]+ R linkorder1
+#...
+[0-9a-f]+ R linkorder2
+#...
+[0-9a-f]+ R linkorder3
+#...
+[0-9a-f]+ R linkorder4
+#...
+[0-9a-f]+ T text0
+#...
+[0-9a-f]+ T text1
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-2b.d b/ld/testsuite/ld-elf/pr26256-2b.d
new file mode 100644
index 0000000000..12b215552c
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2b.d
@@ -0,0 +1,19 @@
+#source: pr26256-2.s
+#ld: -e _start
+#nm: -n
+
+#...
+[0-9a-f]+ T text0
+#...
+[0-9a-f]+ T text1
+#...
+[0-9a-f]+ R linkorder0
+#...
+[0-9a-f]+ R linkorder1
+#...
+[0-9a-f]+ R linkorder2
+#...
+[0-9a-f]+ R linkorder3
+#...
+[0-9a-f]+ R linkorder4
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-3.s b/ld/testsuite/ld-elf/pr26256-3.s
new file mode 100644
index 0000000000..276f9de055
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3.s
@@ -0,0 +1,18 @@
+	.text
+	.global _start
+_start:
+	.byte 3
+
+	.section .rosection,"a"
+	.byte 9
+
+	.section .text.bar,"a",%progbits
+	.byte 2
+	.section .text.foo,"a",%progbits
+	.byte 1
+	.section .rodata.foo,"ao",%progbits,.text.foo
+	.byte 1
+	.section .rodata.bar,"a",%progbits
+	.byte 2
+	.section .rodata.bar,"ao",%progbits,.text.bar
+	.byte 3
diff --git a/ld/testsuite/ld-elf/pr26256-3a.d b/ld/testsuite/ld-elf/pr26256-3a.d
new file mode 100644
index 0000000000..3cef3a94c0
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3a.d
@@ -0,0 +1,9 @@
+#source: pr26256-3.s
+#ld: -e _start -T pr26256-3a.t
+#readelf: -x .rodata -x .text
+
+Hex dump of section \'.rodata\':
+  0x[a-f0-9]+ +00010203 +040907 +.+
+
+Hex dump of section \'.text\':
+  0x[a-f0-9]+ +020103 +.+
diff --git a/ld/testsuite/ld-elf/pr26256-3a.t b/ld/testsuite/ld-elf/pr26256-3a.t
new file mode 100644
index 0000000000..7add651a71
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3a.t
@@ -0,0 +1,13 @@
+SECTIONS
+{
+  .rodata :
+    {
+      BYTE(0)
+      *(.rodata.foo)
+      *(.rodata.bar)
+      BYTE(4)
+      *(.rosection)
+      BYTE(7)
+    }
+  .text : {*(.text.bar) *(.text.foo)}
+}
diff --git a/ld/testsuite/ld-elf/pr26256-3b.d b/ld/testsuite/ld-elf/pr26256-3b.d
new file mode 100644
index 0000000000..b879d4df59
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3b.d
@@ -0,0 +1,9 @@
+#source: pr26256-3.s
+#ld: -e _start -T pr26256-3b.t
+#readelf: -x .rodata -x .text
+
+Hex dump of section \'.rodata\':
+  0x[a-f0-9]+ +00030102 +040907 +.+
+
+Hex dump of section \'.text\':
+  0x[a-f0-9]+ +020103 +.+
diff --git a/ld/testsuite/ld-elf/pr26256-3b.t b/ld/testsuite/ld-elf/pr26256-3b.t
new file mode 100644
index 0000000000..6f72e93bad
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3b.t
@@ -0,0 +1,12 @@
+SECTIONS
+{
+  .rodata :
+    {
+      BYTE(0)
+      *(.rodata*)
+      BYTE(4)
+      *(.rosection)
+      BYTE(7)
+    }
+  .text : {*(.text.bar) *(.text.foo)}
+}
-- 
2.29.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* V3 [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable link
  2020-12-22  4:21   ` V2 " H.J. Lu
@ 2020-12-22 13:24     ` H.J. Lu
  2021-01-04 13:32       ` Nick Clifton
  0 siblings, 1 reply; 7+ messages in thread
From: H.J. Lu @ 2020-12-22 13:24 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

[-- Attachment #1: Type: text/plain, Size: 9069 bytes --]

On Mon, Dec 21, 2020 at 8:21 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Mon, Dec 21, 2020 at 3:24 PM Fangrui Song <i@maskray.me> wrote:
> >
> > Really appreciate this patch! For RISC-V -mrelax, .gcc_except_table
> > has relocations referencing .text . I don't know whether GNU ld does
> > ad-hoc garbage collection for .gcc_except_table, if it doesn't, in the
> > future GCC can set SHF_LINK_ORDER on .gcc_except_table to allow a
> > non-adhoc garbage collection. I have a write-up about this
> > https://maskray.me/blog/2020-12-12-c++-exception-handling-abi#monolithic-.gcc_except_table
> > In particular, I mentioned on https://reviews.llvm.org/D83655
> > that Clang cannot use SHF_LINK_ORDER.
> >
> > On 2020-12-21, H.J. Lu via Binutils wrote:
> > >For non-relocatable link with SHF_LINK_ORDER inputs, allow mixed indirect
> > >and data inputs with ordered and unordered inputs:
> > >
> > >1. Add pattern to bfd_section for the matching section name pattern in
> > >linker script and update BFD_FAKE_SECTION.
> > >2. Sort the consecutive bfd_indirect_link_order sections with the same
> > >pattern to allow linker script to overdide input section order.
> > >3. Place unordered sections before ordered sections.
> > >4. Change the offsets of the indirect input sections only.
> > >
> > >bfd/
> > >
> > >       PR ld/26256
> > >       * elflink.c (compare_link_order): Place unordered sections before
> > >       ordered sections.
> > >       (elf_fixup_link_order): Add a link info argument.  Allow mixed
> > >       ordered and unordered input sections for non-relocatable link.
> > >       Sort the consecutive bfd_indirect_link_order sections with the
> > >       same pattern.  Change the offsets of the bfd_indirect_link_order
> > >       sections only.
> > >       (bfd_elf_final_link): Pass info to elf_fixup_link_order.
> > >       * section.c (bfd_section): Add pattern.
> > >       (BFD_FAKE_SECTION): Initialize pattern to NULL.
> > >       * bfd-in2.h: Regenerated.
> > >
> > >gas/
> > >
> > >       PR ld/26256
> > >       * config/obj-elf.c (obj_elf_change_section): Also filter out
> > >       SHF_LINK_ORDER.
> > >
> > >ld/
> > >
> > >       PR ld/26256
> > >       * ldlang.c (gc_section_callback): Set pattern.
> > >       * testsuite/ld-elf/pr26256-1.s: New file.
> > >       * testsuite/ld-elf/pr26256-1.t: Likewise.
> > >       * testsuite/ld-elf/pr26256-1a.d: Likewise.
> > >       * testsuite/ld-elf/pr26256-1b.d: Likewise.
> > >       * testsuite/ld-elf/pr26256-2.s: Likewise.
> > >       * testsuite/ld-elf/pr26256-2.t: Likewise.
> > >       * testsuite/ld-elf/pr26256-2a.d: Likewise.
> > >       * testsuite/ld-elf/pr26256-2b.d: Likewise.
> > >       * testsuite/ld-elf/pr26256-3.s: Likewise.
> > >       * testsuite/ld-elf/pr26256-3a.d: Likewise.
> > >       * testsuite/ld-elf/pr26256-3a.t: Likewise.
> > >       * testsuite/ld-elf/pr26256-3b.d: Likewise.
> > >       * testsuite/ld-elf/pr26256-3b.t: Likewise.
> > >---
> > > bfd/bfd-in2.h                    |  7 ++-
> > > bfd/elflink.c                    | 83 ++++++++++++++++++++++++--------
> > > bfd/section.c                    |  7 ++-
> > > gas/config/obj-elf.c             |  4 +-
> > > ld/ldlang.c                      |  4 +-
> > > ld/testsuite/ld-elf/pr26256-1.s  | 20 ++++++++
> > > ld/testsuite/ld-elf/pr26256-1.t  |  9 ++++
> > > ld/testsuite/ld-elf/pr26256-1a.d |  7 +++
> > > ld/testsuite/ld-elf/pr26256-1b.d |  7 +++
> > > ld/testsuite/ld-elf/pr26256-2.s  | 32 ++++++++++++
> > > ld/testsuite/ld-elf/pr26256-2.t  |  5 ++
> > > ld/testsuite/ld-elf/pr26256-2a.d | 19 ++++++++
> > > ld/testsuite/ld-elf/pr26256-2b.d | 19 ++++++++
> > > ld/testsuite/ld-elf/pr26256-3.s  | 18 +++++++
> > > ld/testsuite/ld-elf/pr26256-3a.d |  9 ++++
> > > ld/testsuite/ld-elf/pr26256-3a.t | 13 +++++
> > > ld/testsuite/ld-elf/pr26256-3b.d |  9 ++++
> > > ld/testsuite/ld-elf/pr26256-3b.t | 12 +++++
> > > 18 files changed, 259 insertions(+), 25 deletions(-)
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-1.s
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-1.t
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-1a.d
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-1b.d
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-2.s
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-2.t
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-2a.d
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-2b.d
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-3.s
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-3a.d
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-3a.t
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-3b.d
> > > create mode 100644 ld/testsuite/ld-elf/pr26256-3b.t
> > >
> > >diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> > >index f1bef5742a..cc5a3c9912 100644
> > >--- a/bfd/bfd-in2.h
> > >+++ b/bfd/bfd-in2.h
> > >@@ -1184,6 +1184,9 @@ typedef struct bfd_section
> > >   struct bfd_symbol *symbol;
> > >   struct bfd_symbol **symbol_ptr_ptr;
> > >
> > >+  /* The matching section name pattern in linker script.  */
> > >+  const char *pattern;
> > >+
> > >   /* Early in the link process, map_head and map_tail are used to build
> > >      a list of input sections attached to an output section.  Later,
> > >      output sections use these fields for a list of bfd_link_order
> > >@@ -1377,8 +1380,8 @@ discarded_section (const asection *sec)
> > >   /* target_index, used_by_bfd, constructor_chain, owner,           */ \
> > >      0,            NULL,        NULL,              NULL,               \
> > >                                                                        \
> > >-  /* symbol,                    symbol_ptr_ptr,                     */ \
> > >-     (struct bfd_symbol *) SYM, &SEC.symbol,                           \
> > >+  /* symbol,                    symbol_ptr_ptr, pattern,            */ \
> > >+     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,                  \
> > >                                                                        \
> > >   /* map_head, map_tail, already_assigned                           */ \
> > >      { NULL }, { NULL }, NULL                                          \
> > >diff --git a/bfd/elflink.c b/bfd/elflink.c
> > >index 1b3398126f..6930c7c741 100644
> > >--- a/bfd/elflink.c
> > >+++ b/bfd/elflink.c
> > >@@ -11867,8 +11867,21 @@ compare_link_order (const void *a, const void *b)
> > >   const struct bfd_link_order *blo = *(const struct bfd_link_order **) b;
> > >   asection *asec = elf_linked_to_section (alo->u.indirect.section);
> > >   asection *bsec = elf_linked_to_section (blo->u.indirect.section);
> > >-  bfd_vma apos = asec->output_section->lma + asec->output_offset;
> > >-  bfd_vma bpos = bsec->output_section->lma + bsec->output_offset;
> > >+  bfd_vma apos, bpos;
> > >+
> > >+  /* Check if any sections are unordered.  */
> > >+  if (asec == NULL || bsec == NULL)
> > >+    {
> > >+      /* Place unordered sections before ordered sections.  */
> > >+      if (bsec != NULL)
> > >+      return -1;
> > >+      else if (asec != NULL)
> > >+      return 1;
> > >+      return 0;
> > >+    }
> > >+
> >
> > I just commented that LLD places ordered sections before unordered sections.
> > https://sourceware.org/bugzilla/show_bug.cgi?id=26256#c10
> > Solaris folks appear to prefer this style.
>
> Changed.
>
> > >+  apos = asec->output_section->lma + asec->output_offset;
> > >+  bpos = bsec->output_section->lma + bsec->output_offset;
> > >
> > >   if (apos < bpos)
> > >     return -1;
> > >@@ -11903,14 +11916,14 @@ compare_link_order (const void *a, const void *b)
> > >    sections.  Ideally we'd do this in the linker proper.  */
> > >
> > > static bfd_boolean
> > >-elf_fixup_link_order (bfd *abfd, asection *o)
> > >+elf_fixup_link_order (struct bfd_link_info *info, bfd *abfd, asection *o)
> > > {
> > >   size_t seen_linkorder;
> > >   size_t seen_other;
> > >   size_t n;
> > >   struct bfd_link_order *p;
> > >   bfd *sub;
> > >-  struct bfd_link_order **sections;
> > >+  struct bfd_link_order **sections, **indirect_sections;
> > >   asection *other_sec, *linkorder_sec;
> > >   bfd_vma offset;  /* Octets.  */
> > >
> > >@@ -11941,7 +11954,9 @@ elf_fixup_link_order (bfd *abfd, asection *o)
> > >       else
> > >       seen_other++;
> > >
> > >-      if (seen_other && seen_linkorder)
> > >+      /* Allow mixed ordered and unordered input sections for
> > >+         non-relocatable link.  */
> > >+      if (bfd_link_relocatable (info) && seen_other && seen_linkorder)
> > >       {
> > >         if (other_sec && linkorder_sec)
> > >           _bfd_error_handler
> >
> > I don't take time investigating the logic here. But about -r &
> > SHF_LINK_ORDER:
> > https://sourceware.org/bugzilla/show_bug.cgi?id=26256#c11
>
> "ld-r" also uses a linker script:
>
>   .rodata       0 : { *(.rodata) }
>   .rodata1      0 : { *(.rodata1) }
>
> What happens if 2 .rodata sections have different HF_LINK_ORDER?
> It is better for ld to reject it.
>
> OK for master?
>

Here is the updated patch to fix the sorting.  OK for master?

Thanks.

-- 
H.J.

[-- Attachment #2: 0001-elf-Allow-mixed-ordered-unordered-inputs-for-non-rel.patch --]
[-- Type: text/x-patch, Size: 17789 bytes --]

From 60030692b1dd8dd63e034ca9abca9028b6e3f7bf Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sat, 19 Dec 2020 13:16:17 -0800
Subject: [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable
 link

For non-relocatable link with SHF_LINK_ORDER inputs, allow mixed indirect
and data inputs with ordered and unordered inputs:

1. Add pattern to bfd_section for the matching section name pattern in
linker script and update BFD_FAKE_SECTION.
2. Sort the consecutive bfd_indirect_link_order sections with the same
pattern to allow linker script to overdide input section order.
3. Place unordered sections before ordered sections.
4. Change the offsets of the indirect input sections only.

bfd/

	PR ld/26256
	* elflink.c (compare_link_order): Place unordered sections before
	ordered sections.
	(elf_fixup_link_order): Add a link info argument.  Allow mixed
	ordered and unordered input sections for non-relocatable link.
	Sort the consecutive bfd_indirect_link_order sections with the
	same pattern.  Change the offsets of the bfd_indirect_link_order
	sections only.
	(bfd_elf_final_link): Pass info to elf_fixup_link_order.
	* section.c (bfd_section): Add pattern.
	(BFD_FAKE_SECTION): Initialize pattern to NULL.
	* bfd-in2.h: Regenerated.

gas/

	PR ld/26256
	* config/obj-elf.c (obj_elf_change_section): Also filter out
	SHF_LINK_ORDER.

ld/

	PR ld/26256
	* ldlang.c (gc_section_callback): Set pattern.
	* testsuite/ld-elf/pr26256-1.s: New file.
	* testsuite/ld-elf/pr26256-1.t: Likewise.
	* testsuite/ld-elf/pr26256-1a.d: Likewise.
	* testsuite/ld-elf/pr26256-1b.d: Likewise.
	* testsuite/ld-elf/pr26256-2.s: Likewise.
	* testsuite/ld-elf/pr26256-2.t: Likewise.
	* testsuite/ld-elf/pr26256-2a.d: Likewise.
	* testsuite/ld-elf/pr26256-2b.d: Likewise.
	* testsuite/ld-elf/pr26256-3.s: Likewise.
	* testsuite/ld-elf/pr26256-3a.d: Likewise.
	* testsuite/ld-elf/pr26256-3a.t: Likewise.
	* testsuite/ld-elf/pr26256-3b.d: Likewise.
	* testsuite/ld-elf/pr26256-3b.t: Likewise.
---
 bfd/bfd-in2.h                    |  7 ++-
 bfd/elflink.c                    | 86 +++++++++++++++++++++++++-------
 bfd/section.c                    |  7 ++-
 gas/config/obj-elf.c             |  4 +-
 ld/ldlang.c                      |  4 +-
 ld/testsuite/ld-elf/pr26256-1.s  | 20 ++++++++
 ld/testsuite/ld-elf/pr26256-1.t  |  9 ++++
 ld/testsuite/ld-elf/pr26256-1a.d |  7 +++
 ld/testsuite/ld-elf/pr26256-1b.d |  7 +++
 ld/testsuite/ld-elf/pr26256-2.s  | 32 ++++++++++++
 ld/testsuite/ld-elf/pr26256-2.t  |  5 ++
 ld/testsuite/ld-elf/pr26256-2a.d | 19 +++++++
 ld/testsuite/ld-elf/pr26256-2b.d | 19 +++++++
 ld/testsuite/ld-elf/pr26256-3.s  | 18 +++++++
 ld/testsuite/ld-elf/pr26256-3a.d |  9 ++++
 ld/testsuite/ld-elf/pr26256-3a.t | 13 +++++
 ld/testsuite/ld-elf/pr26256-3b.d |  9 ++++
 ld/testsuite/ld-elf/pr26256-3b.t | 12 +++++
 18 files changed, 262 insertions(+), 25 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr26256-1.s
 create mode 100644 ld/testsuite/ld-elf/pr26256-1.t
 create mode 100644 ld/testsuite/ld-elf/pr26256-1a.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-1b.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-2.s
 create mode 100644 ld/testsuite/ld-elf/pr26256-2.t
 create mode 100644 ld/testsuite/ld-elf/pr26256-2a.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-2b.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-3.s
 create mode 100644 ld/testsuite/ld-elf/pr26256-3a.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-3a.t
 create mode 100644 ld/testsuite/ld-elf/pr26256-3b.d
 create mode 100644 ld/testsuite/ld-elf/pr26256-3b.t

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index f1bef5742a..cc5a3c9912 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1184,6 +1184,9 @@ typedef struct bfd_section
   struct bfd_symbol *symbol;
   struct bfd_symbol **symbol_ptr_ptr;
 
+  /* The matching section name pattern in linker script.  */
+  const char *pattern;
+
   /* Early in the link process, map_head and map_tail are used to build
      a list of input sections attached to an output section.  Later,
      output sections use these fields for a list of bfd_link_order
@@ -1377,8 +1380,8 @@ discarded_section (const asection *sec)
   /* target_index, used_by_bfd, constructor_chain, owner,           */ \
      0,            NULL,        NULL,              NULL,               \
                                                                        \
-  /* symbol,                    symbol_ptr_ptr,                     */ \
-     (struct bfd_symbol *) SYM, &SEC.symbol,                           \
+  /* symbol,                    symbol_ptr_ptr, pattern,            */ \
+     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,                  \
                                                                        \
   /* map_head, map_tail, already_assigned                           */ \
      { NULL }, { NULL }, NULL                                          \
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 1b3398126f..ddff3bfe7b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11867,8 +11867,21 @@ compare_link_order (const void *a, const void *b)
   const struct bfd_link_order *blo = *(const struct bfd_link_order **) b;
   asection *asec = elf_linked_to_section (alo->u.indirect.section);
   asection *bsec = elf_linked_to_section (blo->u.indirect.section);
-  bfd_vma apos = asec->output_section->lma + asec->output_offset;
-  bfd_vma bpos = bsec->output_section->lma + bsec->output_offset;
+  bfd_vma apos, bpos;
+
+  /* Check if any sections are unordered.  */
+  if (asec == NULL || bsec == NULL)
+    {
+      /* Place ordered sections before unordered sections.  */
+      if (bsec != NULL)
+	return 1;
+      else if (asec != NULL)
+	return -1;
+      return 0;
+    }
+
+  apos = asec->output_section->lma + asec->output_offset;
+  bpos = bsec->output_section->lma + bsec->output_offset;
 
   if (apos < bpos)
     return -1;
@@ -11903,14 +11916,14 @@ compare_link_order (const void *a, const void *b)
    sections.  Ideally we'd do this in the linker proper.  */
 
 static bfd_boolean
-elf_fixup_link_order (bfd *abfd, asection *o)
+elf_fixup_link_order (struct bfd_link_info *info, bfd *abfd, asection *o)
 {
   size_t seen_linkorder;
   size_t seen_other;
   size_t n;
   struct bfd_link_order *p;
   bfd *sub;
-  struct bfd_link_order **sections;
+  struct bfd_link_order **sections, **indirect_sections;
   asection *other_sec, *linkorder_sec;
   bfd_vma offset;  /* Octets.  */
 
@@ -11941,7 +11954,9 @@ elf_fixup_link_order (bfd *abfd, asection *o)
       else
 	seen_other++;
 
-      if (seen_other && seen_linkorder)
+      /* Allow mixed ordered and unordered input sections for
+         non-relocatable link.  */
+      if (bfd_link_relocatable (info) && seen_other && seen_linkorder)
 	{
 	  if (other_sec && linkorder_sec)
 	    _bfd_error_handler
@@ -11961,6 +11976,10 @@ elf_fixup_link_order (bfd *abfd, asection *o)
   if (!seen_linkorder)
     return TRUE;
 
+  /* Non-relocatable output can have both ordered and unordered input
+     sections.  */
+  seen_linkorder += seen_other;
+
   sections = bfd_malloc (seen_linkorder * sizeof (*sections));
   if (sections == NULL)
     return FALSE;
@@ -11969,22 +11988,51 @@ elf_fixup_link_order (bfd *abfd, asection *o)
   for (p = o->map_head.link_order; p != NULL; p = p->next)
     sections[seen_linkorder++] = p;
 
-  /* Sort the input sections in the order of their linked section.  */
-  qsort (sections, seen_linkorder, sizeof (*sections), compare_link_order);
+  for (indirect_sections = sections, n = 0; n < seen_linkorder;)
+    {
+      /* Find the first bfd_indirect_link_order section.  */
+      if (indirect_sections[0]->type == bfd_indirect_link_order)
+	{
+	  /* Count the consecutive bfd_indirect_link_order sections
+	     with the same pattern.  */
+	  size_t i, n_indirect;
+	  const char *pattern
+	    = indirect_sections[0]->u.indirect.section->pattern;
+	  for (i = n + 1; i < seen_linkorder; i++)
+	    if (sections[i]->type != bfd_indirect_link_order
+		|| sections[i]->u.indirect.section->pattern != pattern)
+	      break;
+	  n_indirect = i - n;
+	  /* Sort the bfd_indirect_link_order sections in the order of
+	     their linked section.  */
+	  qsort (indirect_sections, n_indirect, sizeof (*sections),
+		 compare_link_order);
+	  indirect_sections += n_indirect;
+	  n += n_indirect;
+	}
+      else
+	{
+	  indirect_sections++;
+	  n++;
+	}
+    }
 
-  /* Change the offsets of the sections.  */
+  /* Change the offsets of the bfd_indirect_link_order sections.  */
   offset = 0;
   for (n = 0; n < seen_linkorder; n++)
-    {
-      bfd_vma mask;
-      asection *s = sections[n]->u.indirect.section;
-      unsigned int opb = bfd_octets_per_byte (abfd, s);
-
-      mask = ~(bfd_vma) 0 << s->alignment_power * opb;
-      offset = (offset + ~mask) & mask;
-      sections[n]->offset = s->output_offset = offset / opb;
-      offset += sections[n]->size;
-    }
+    if (sections[n]->type == bfd_indirect_link_order)
+      {
+	bfd_vma mask;
+	asection *s = sections[n]->u.indirect.section;
+	unsigned int opb = bfd_octets_per_byte (abfd, s);
+
+	mask = ~(bfd_vma) 0 << s->alignment_power * opb;
+	offset = (offset + ~mask) & mask;
+	sections[n]->offset = s->output_offset = offset / opb;
+	offset += sections[n]->size;
+      }
+    else
+      offset = sections[n]->offset + sections[n]->size;
 
   free (sections);
   return TRUE;
@@ -12627,7 +12675,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   /* Reorder SHF_LINK_ORDER sections.  */
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      if (!elf_fixup_link_order (abfd, o))
+      if (!elf_fixup_link_order (info, abfd, o))
 	return FALSE;
     }
 
diff --git a/bfd/section.c b/bfd/section.c
index 17f5b4c3d8..aa383626e2 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -541,6 +541,9 @@ CODE_FRAGMENT
 .  struct bfd_symbol *symbol;
 .  struct bfd_symbol **symbol_ptr_ptr;
 .
+.  {* The matching section name pattern in linker script.  *}
+.  const char *pattern;
+.
 .  {* Early in the link process, map_head and map_tail are used to build
 .     a list of input sections attached to an output section.  Later,
 .     output sections use these fields for a list of bfd_link_order
@@ -734,8 +737,8 @@ CODE_FRAGMENT
 .  {* target_index, used_by_bfd, constructor_chain, owner,           *}	\
 .     0,            NULL,        NULL,              NULL,		\
 .									\
-.  {* symbol,                    symbol_ptr_ptr,                     *}	\
-.     (struct bfd_symbol *) SYM, &SEC.symbol,				\
+.  {* symbol,                    symbol_ptr_ptr, pattern,            *}	\
+.     (struct bfd_symbol *) SYM, &SEC.symbol,    NULL,			\
 .									\
 .  {* map_head, map_tail, already_assigned                           *}	\
 .     { NULL }, { NULL }, NULL						\
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index d030b548fb..621c35c182 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -666,7 +666,9 @@ obj_elf_change_section (const char *name,
 	    }
 	}
 
-      if (old_sec == NULL && ((attr & ~(SHF_MASKOS | SHF_MASKPROC))
+      if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
+					| SHF_MASKOS
+					| SHF_MASKPROC))
 			      & ~ssect->attr) != 0)
 	{
 	  /* As a GNU extension, we permit a .note section to be
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 41000da1e1..935880cf94 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -7486,7 +7486,7 @@ lang_reset_memory_regions (void)
 
 static void
 gc_section_callback (lang_wild_statement_type *ptr,
-		     struct wildcard_list *sec ATTRIBUTE_UNUSED,
+		     struct wildcard_list *sec,
 		     asection *section,
 		     struct flag_info *sflag_info ATTRIBUTE_UNUSED,
 		     lang_input_statement_type *file ATTRIBUTE_UNUSED,
@@ -7496,6 +7496,8 @@ gc_section_callback (lang_wild_statement_type *ptr,
      should be as well.  */
   if (ptr->keep_sections)
     section->flags |= SEC_KEEP;
+  if (sec)
+    section->pattern = sec->spec.name;
 }
 
 /* Iterate over sections marking them against GC.  */
diff --git a/ld/testsuite/ld-elf/pr26256-1.s b/ld/testsuite/ld-elf/pr26256-1.s
new file mode 100644
index 0000000000..7351f76655
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1.s
@@ -0,0 +1,20 @@
+	.section	.text.bar,"ax",%progbits
+	.globl	bar
+	.type	bar, %function
+bar:
+	.section __patchable_function_entries,"awo",%progbits,bar
+	.dc.a	.LPFE1
+	.section	.text.bar,"ax",%progbits
+.LPFE1:
+	.byte 0
+	.section	.text._start,"ax",%progbits
+	.globl	_start
+	.type	_start, %function
+_start:
+	.section __patchable_function_entries,"awo",%progbits,_start
+	.dc.a	.LPFE2
+	.section	.text._start,"ax",%progbits
+.LPFE2:
+	.byte 0
+	.section .init.data,"aw",%progbits
+	.byte 0
diff --git a/ld/testsuite/ld-elf/pr26256-1.t b/ld/testsuite/ld-elf/pr26256-1.t
new file mode 100644
index 0000000000..bc5232b0ae
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1.t
@@ -0,0 +1,9 @@
+SECTIONS
+{
+  .text : { *(.text*) }
+  .init.data :
+  {
+    *(.init.data);
+    *(__patchable_function_entries);
+  }
+}
diff --git a/ld/testsuite/ld-elf/pr26256-1a.d b/ld/testsuite/ld-elf/pr26256-1a.d
new file mode 100644
index 0000000000..025ace0e87
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1a.d
@@ -0,0 +1,7 @@
+#source: pr26256-1.s
+#ld: -e _start -T pr26256-1.t
+#nm: -n
+
+#...
+[0-9a-f]+ T _start
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-1b.d b/ld/testsuite/ld-elf/pr26256-1b.d
new file mode 100644
index 0000000000..760c6d82e7
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-1b.d
@@ -0,0 +1,7 @@
+#source: pr26256-1.s
+#ld: -e _start
+#nm: -n
+
+#...
+[0-9a-f]+ T _start
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-2.s b/ld/testsuite/ld-elf/pr26256-2.s
new file mode 100644
index 0000000000..70e3693f42
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2.s
@@ -0,0 +1,32 @@
+	.section .text,"ax",%progbits,unique,0
+	.globl text0
+text0:
+	.nop
+	.section .text,"ax",%progbits,unique,1
+	.globl text1
+text1:
+	.nop
+	.section .linkorder,"ao",%progbits,0,unique,0
+	.globl linkorder2
+linkorder2:
+	.byte 0
+	.section .linkorder,"ao",%progbits,text0
+	.globl linkorder0
+linkorder0:
+	.byte 1
+	.section .linkorder,"ao",%progbits,text1
+	.globl linkorder1
+linkorder1:
+	.byte 2
+	.section .linkorder,"a",%progbits
+	.globl linkorder3
+linkorder3:
+	.byte 3
+	.section .linkorder,"ao",%progbits,0,unique,3
+	.globl linkorder4
+linkorder4:
+	.byte 4
+	.text
+	.global _start
+_start:
+	.nop
diff --git a/ld/testsuite/ld-elf/pr26256-2.t b/ld/testsuite/ld-elf/pr26256-2.t
new file mode 100644
index 0000000000..a69c01682e
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2.t
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .linkorder : { *(.linkorder.*) }
+  .text : { *(.text) }
+}
diff --git a/ld/testsuite/ld-elf/pr26256-2a.d b/ld/testsuite/ld-elf/pr26256-2a.d
new file mode 100644
index 0000000000..e2250c7e40
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2a.d
@@ -0,0 +1,19 @@
+#source: pr26256-2.s
+#ld: -e _start -T pr26256-2.t
+#nm: -n
+
+#...
+[0-9a-f]+ R linkorder0
+#...
+[0-9a-f]+ R linkorder1
+#...
+[0-9a-f]+ R linkorder2
+#...
+[0-9a-f]+ R linkorder3
+#...
+[0-9a-f]+ R linkorder4
+#...
+[0-9a-f]+ T text0
+#...
+[0-9a-f]+ T text1
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-2b.d b/ld/testsuite/ld-elf/pr26256-2b.d
new file mode 100644
index 0000000000..12b215552c
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-2b.d
@@ -0,0 +1,19 @@
+#source: pr26256-2.s
+#ld: -e _start
+#nm: -n
+
+#...
+[0-9a-f]+ T text0
+#...
+[0-9a-f]+ T text1
+#...
+[0-9a-f]+ R linkorder0
+#...
+[0-9a-f]+ R linkorder1
+#...
+[0-9a-f]+ R linkorder2
+#...
+[0-9a-f]+ R linkorder3
+#...
+[0-9a-f]+ R linkorder4
+#pass
diff --git a/ld/testsuite/ld-elf/pr26256-3.s b/ld/testsuite/ld-elf/pr26256-3.s
new file mode 100644
index 0000000000..276f9de055
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3.s
@@ -0,0 +1,18 @@
+	.text
+	.global _start
+_start:
+	.byte 3
+
+	.section .rosection,"a"
+	.byte 9
+
+	.section .text.bar,"a",%progbits
+	.byte 2
+	.section .text.foo,"a",%progbits
+	.byte 1
+	.section .rodata.foo,"ao",%progbits,.text.foo
+	.byte 1
+	.section .rodata.bar,"a",%progbits
+	.byte 2
+	.section .rodata.bar,"ao",%progbits,.text.bar
+	.byte 3
diff --git a/ld/testsuite/ld-elf/pr26256-3a.d b/ld/testsuite/ld-elf/pr26256-3a.d
new file mode 100644
index 0000000000..7b0a2bad7e
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3a.d
@@ -0,0 +1,9 @@
+#source: pr26256-3.s
+#ld: -e _start -T pr26256-3a.t
+#readelf: -x .rodata -x .text
+
+Hex dump of section \'.rodata\':
+  0x[a-f0-9]+ +00010302 +040907 +.+
+
+Hex dump of section \'.text\':
+  0x[a-f0-9]+ +020103 +.+
diff --git a/ld/testsuite/ld-elf/pr26256-3a.t b/ld/testsuite/ld-elf/pr26256-3a.t
new file mode 100644
index 0000000000..7add651a71
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3a.t
@@ -0,0 +1,13 @@
+SECTIONS
+{
+  .rodata :
+    {
+      BYTE(0)
+      *(.rodata.foo)
+      *(.rodata.bar)
+      BYTE(4)
+      *(.rosection)
+      BYTE(7)
+    }
+  .text : {*(.text.bar) *(.text.foo)}
+}
diff --git a/ld/testsuite/ld-elf/pr26256-3b.d b/ld/testsuite/ld-elf/pr26256-3b.d
new file mode 100644
index 0000000000..b879d4df59
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3b.d
@@ -0,0 +1,9 @@
+#source: pr26256-3.s
+#ld: -e _start -T pr26256-3b.t
+#readelf: -x .rodata -x .text
+
+Hex dump of section \'.rodata\':
+  0x[a-f0-9]+ +00030102 +040907 +.+
+
+Hex dump of section \'.text\':
+  0x[a-f0-9]+ +020103 +.+
diff --git a/ld/testsuite/ld-elf/pr26256-3b.t b/ld/testsuite/ld-elf/pr26256-3b.t
new file mode 100644
index 0000000000..6f72e93bad
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26256-3b.t
@@ -0,0 +1,12 @@
+SECTIONS
+{
+  .rodata :
+    {
+      BYTE(0)
+      *(.rodata*)
+      BYTE(4)
+      *(.rosection)
+      BYTE(7)
+    }
+  .text : {*(.text.bar) *(.text.foo)}
+}
-- 
2.29.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: V3 [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable link
  2020-12-22 13:24     ` V3 " H.J. Lu
@ 2021-01-04 13:32       ` Nick Clifton
  2021-01-04 16:40         ` V4 " H.J. Lu
  0 siblings, 1 reply; 7+ messages in thread
From: Nick Clifton @ 2021-01-04 13:32 UTC (permalink / raw)
  To: H.J. Lu, Fangrui Song; +Cc: Binutils

Hi H.J.

>>>> 1. Add pattern to bfd_section for the matching section name pattern in
>>>> linker script and update BFD_FAKE_SECTION.
>>>> 2. Sort the consecutive bfd_indirect_link_order sections with the same
>>>> pattern to allow linker script to overdide input section order.
>>>> 3. Place unordered sections before ordered sections.
>>>> 4. Change the offsets of the indirect input sections only.

The patch looks good to me, but the new tests do cause problems for
a variety of targets.  For example:

  fido-elf ...         LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b
  fr30-elf ...         LD REGRESSION: ld-elf/pr26256-2b
  mipsel-linux-gnu ... LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b
  riscv32-elf ...      LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b
  s390-linux ...       LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b
  score-elf ...        LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b

(This is just a selection).

The cause appears to be an incorrect assumption about the start address of
the text section:

   regexp_diff match failure
   regexp "^  0x[a-f0-9]+ +020103 +.+$"
   line   "  0x00000020 02010000 03000000                   ........"
   FAIL: ld-elf/pr26256-3a

   regexp_diff match failure
   regexp "^  0x[a-f0-9]+ +020103 +.+$"
   aline   "  0x00000020 02010000 03000000                   ........"
   FAIL: ld-elf/pr26256-3b

Could you fix these please ?

Cheers
   Nick


^ permalink raw reply	[flat|nested] 7+ messages in thread

* V4 [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable link
  2021-01-04 13:32       ` Nick Clifton
@ 2021-01-04 16:40         ` H.J. Lu
  2021-01-04 20:18           ` Nick Clifton
  0 siblings, 1 reply; 7+ messages in thread
From: H.J. Lu @ 2021-01-04 16:40 UTC (permalink / raw)
  To: Nick Clifton; +Cc: Fangrui Song, Binutils

[-- Attachment #1: Type: text/plain, Size: 1646 bytes --]

On Mon, Jan 4, 2021 at 5:32 AM Nick Clifton <nickc@redhat.com> wrote:
>
> Hi H.J.
>
> >>>> 1. Add pattern to bfd_section for the matching section name pattern in
> >>>> linker script and update BFD_FAKE_SECTION.
> >>>> 2. Sort the consecutive bfd_indirect_link_order sections with the same
> >>>> pattern to allow linker script to overdide input section order.
> >>>> 3. Place unordered sections before ordered sections.
> >>>> 4. Change the offsets of the indirect input sections only.
>
> The patch looks good to me, but the new tests do cause problems for
> a variety of targets.  For example:
>
>   fido-elf ...         LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b
>   fr30-elf ...         LD REGRESSION: ld-elf/pr26256-2b
>   mipsel-linux-gnu ... LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b
>   riscv32-elf ...      LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b
>   s390-linux ...       LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b
>   score-elf ...        LD REGRESSION: ld-elf/pr26256-3a  ld-elf/pr26256-3b
>
> (This is just a selection).
>
> The cause appears to be an incorrect assumption about the start address of
> the text section:
>
>    regexp_diff match failure
>    regexp "^  0x[a-f0-9]+ +020103 +.+$"
>    line   "  0x00000020 02010000 03000000                   ........"
>    FAIL: ld-elf/pr26256-3a
>
>    regexp_diff match failure
>    regexp "^  0x[a-f0-9]+ +020103 +.+$"
>    aline   "  0x00000020 02010000 03000000                   ........"
>    FAIL: ld-elf/pr26256-3b
>
> Could you fix these please ?
>

Here is the updated patch with testcases fixed.   OK for master?

Thanks.

-- 
H.J.

[-- Attachment #2: 0001-elf-Allow-mixed-ordered-unordered-inputs-for-non-rel.patch --]
[-- Type: application/x-patch, Size: 19631 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: V4 [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable link
  2021-01-04 16:40         ` V4 " H.J. Lu
@ 2021-01-04 20:18           ` Nick Clifton
  0 siblings, 0 replies; 7+ messages in thread
From: Nick Clifton @ 2021-01-04 20:18 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Fangrui Song, Binutils

Hi H.J.

> Here is the updated patch with testcases fixed.   OK for master?

Approved - please apply.  (And thanks for fixing the tests).

Cheers
   Nick



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-01-04 20:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-21 21:54 [PATCH] elf: Allow mixed ordered/unordered inputs for non-relocatable link H.J. Lu
2020-12-21 23:24 ` Fangrui Song
2020-12-22  4:21   ` V2 " H.J. Lu
2020-12-22 13:24     ` V3 " H.J. Lu
2021-01-04 13:32       ` Nick Clifton
2021-01-04 16:40         ` V4 " H.J. Lu
2021-01-04 20:18           ` Nick Clifton

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).