This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] ELF: Properly group and place orphan note sections


On Sat, Oct 06, 2018 at 03:50:54PM +0930, Alan Modra wrote:
> On Fri, Oct 05, 2018 at 04:56:52PM -0700, H.J. Lu wrote:
> > I couldn't find a way to place a note section after the dummy
> > abs_output_section.
> 
> INSERT BEFORE manages to do it.  Please revert commit 1887ae7304
> if you really can't sort out the logic.  That commit causes needless
> reordering of sections, as shown by the spu-elf ovl testsuite
> failures.
> 

Here is the patch.  OK for master?


H.J.
---
Properly group orphan note sections.  When placing orphan note section
as the first note section, place it after the section before all note
sections.

	PR ld/23658
	* ldlang.c (lang_insert_orphan): Properly group and place orphan
	note sections.  Properly handle orphan note section before all
	note sections.
	* testsuite/ld-elf/pr23658-1.d: Renamed to ...
	* testsuite/ld-elf/pr23658-1a.d: This.  Updated.
	* testsuite/ld-elf/pr23658-1b.d: New test.
	* testsuite/ld-elf/pr23658-1c.d: Likewise.
---
 ld/ldlang.c                                   | 150 +++++++++++-------
 .../ld-elf/{pr23658-1.d => pr23658-1a.d}      |   6 +-
 ld/testsuite/ld-elf/pr23658-1b.d              |  16 ++
 ld/testsuite/ld-elf/pr23658-1c.d              |  13 ++
 4 files changed, 129 insertions(+), 56 deletions(-)
 rename ld/testsuite/ld-elf/{pr23658-1.d => pr23658-1a.d} (65%)
 create mode 100644 ld/testsuite/ld-elf/pr23658-1b.d
 create mode 100644 ld/testsuite/ld-elf/pr23658-1c.d

diff --git a/ld/ldlang.c b/ld/ldlang.c
index 1a27787193..4cb482719e 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1876,6 +1876,7 @@ lang_insert_orphan (asection *s,
     {
       asection *snew, *as;
       bfd_boolean place_after = place->stmt == NULL;
+      bfd_boolean insert_after = TRUE;
 
       snew = os->bfd_section;
 
@@ -1931,7 +1932,9 @@ lang_insert_orphan (asection *s,
 	  asection *after_sec;
 	  /* True if we need to insert the orphan section after a
 	     specific section to maintain output note section order.  */
-	  bfd_boolean after_sec_note;
+	  bfd_boolean after_sec_note = FALSE;
+
+	  static asection *first_orphan_note = NULL;
 
 	  /* Group and sort output note section by alignments in
 	     ascending order.  */
@@ -1939,11 +1942,12 @@ lang_insert_orphan (asection *s,
 	  if (elf_section_type (s) == SHT_NOTE
 	      && (s->flags & SEC_LOAD) != 0)
 	    {
-	      /* Search forward for the last output note section
-		 with equal or larger alignments.  */
-	      asection *first_note = NULL;
+	      /* Search from the beginning for the last output note
+		 section with equal or larger alignments.  NB: Don't
+		 place orphan note section after code sections.  */
 
-	      for (sec = as;
+	      first_orphan_note = NULL;
+	      for (sec = link_info.output_bfd->sections;
 		   (sec != NULL
 		    && !bfd_is_abs_section (sec));
 		   sec = sec->next)
@@ -1951,52 +1955,34 @@ lang_insert_orphan (asection *s,
 		    && elf_section_type (sec) == SHT_NOTE
 		    && (sec->flags & SEC_LOAD) != 0)
 		  {
-		    if (!first_note)
-		      first_note = sec;
+		    if (!first_orphan_note)
+		      first_orphan_note = sec;
 		    if (sec->alignment_power >= s->alignment_power)
 		      after_sec = sec;
 		  }
+		else if (first_orphan_note)
+		  {
+		    /* Stop if there is non-note section after the first
+		       orphan note section.  */
+		    break;
+		  }
 
-	      if (after_sec)
-		after_sec_note = TRUE;
-	      else
+	      /* If this will be the first orphan note section, it can
+		 be placed at the default location.  */
+	      after_sec_note = first_orphan_note != NULL;
+	      if (after_sec == NULL && after_sec_note)
 		{
-		  /* Search backward for the first output note section
-		     as well as the last output note section with equal
-		     or larger alignments.  */
-		  after_sec = NULL;
-		  for (sec = as;
-		       (sec != NULL
-			&& !bfd_is_abs_section (sec));
-		       sec = sec->prev)
-		    if (sec != snew
-			&& elf_section_type (sec) == SHT_NOTE
-			&& (sec->flags & SEC_LOAD) != 0)
-		      {
-			first_note = sec;
-			if (!after_sec
-			    && sec->alignment_power >= s->alignment_power)
-			  after_sec = sec;
-		      }
-
-		  /* If this will be the first note section, it can be
-		     placed at the default location.  */
-		  after_sec_note = first_note != NULL;
-		  if (after_sec == NULL && after_sec_note)
-		    {
-		      /* If all output note sections have smaller
-			 alignments, place the section before all
-			 output note sections.  AFTER_SEC will be
-			 NULL if FIRST_NOTE is the first output
-			 section.  */
-		      after_sec = first_note->prev;
-		    }
+		  /* If all output note sections have smaller
+		     alignments, place the section before all
+		     output orphan note sections.  */
+		  after_sec = first_orphan_note;
+		  insert_after = FALSE;
 		}
 	    }
-	  else
+	  else if (first_orphan_note)
 	    {
-	      /* Don't place non-note sections in the middle of note
-		 sections.  */
+	      /* Don't place non-note sections in the middle of orphan
+	         note sections.  */
 	      after_sec_note = TRUE;
 	      after_sec = as;
 	      for (sec = as->next;
@@ -2012,20 +1998,68 @@ lang_insert_orphan (asection *s,
 	    {
 	      if (after_sec)
 		{
-		  /* Insert OS after AFTER_SEC output statement.  */
-		  lang_output_section_statement_type *stmt;
-		  for (stmt = after;
-		       stmt != NULL;
-		       stmt = stmt->next)
-		    if (stmt->bfd_section == after_sec)
+		  /* Search forward to insert OS after AFTER_SEC output
+		     statement.  */
+		  lang_output_section_statement_type *stmt, *next;
+		  bfd_boolean found = FALSE;
+		  for (stmt = after; stmt != NULL; stmt = next)
+		    {
+		      next = stmt->next;
+		      if (insert_after)
+			{
+			  if (stmt->bfd_section == after_sec)
+			    {
+			      place_after = TRUE;
+			      found = TRUE;
+			      after = stmt;
+			      break;
+			    }
+			}
+		      else
+			{
+			  /* If INSERT_AFTER is FALSE, place OS before
+			     AFTER_SEC output statement.  */
+			  if (next && next->bfd_section == after_sec)
+			    {
+			      place_after = TRUE;
+			      found = TRUE;
+			      after = stmt;
+			      break;
+			    }
+			}
+		    }
+
+		  /* Search backward to insert OS after AFTER_SEC output
+		     statement.  */
+		  if (!found)
+		    for (stmt = after; stmt != NULL; stmt = stmt->prev)
 		      {
-			place_after = TRUE;
-			after = stmt;
-			break;
+			if (insert_after)
+			  {
+			    if (stmt->bfd_section == after_sec)
+			      {
+				place_after = TRUE;
+				after = stmt;
+				break;
+			      }
+			  }
+			else
+			  {
+			    /* If INSERT_AFTER is FALSE, place OS before
+			       AFTER_SEC output statement.  */
+			    if (stmt->next->bfd_section == after_sec)
+			      {
+				place_after = TRUE;
+				after = stmt;
+				break;
+			      }
+			  }
 		      }
 		}
 
-	      if (after_sec == NULL || after_sec->next != snew)
+	      if (after_sec == NULL
+		  || (insert_after && after_sec->next != snew)
+		  || (!insert_after && after_sec->prev != snew))
 		{
 		  /* Unlink the section.  */
 		  bfd_section_list_remove (link_info.output_bfd, snew);
@@ -2033,8 +2067,14 @@ lang_insert_orphan (asection *s,
 		  /* Place SNEW after AFTER_SEC.  If AFTER_SEC is NULL,
 		     prepend SNEW.  */
 		  if (after_sec)
-		    bfd_section_list_insert_after (link_info.output_bfd,
-						   after_sec, snew);
+		    {
+		      if (insert_after)
+			bfd_section_list_insert_after (link_info.output_bfd,
+						       after_sec, snew);
+		      else
+			bfd_section_list_insert_before (link_info.output_bfd,
+						       after_sec, snew);
+		    }
 		  else
 		    bfd_section_list_prepend (link_info.output_bfd, snew);
 		}
diff --git a/ld/testsuite/ld-elf/pr23658-1.d b/ld/testsuite/ld-elf/pr23658-1a.d
similarity index 65%
rename from ld/testsuite/ld-elf/pr23658-1.d
rename to ld/testsuite/ld-elf/pr23658-1a.d
index e21206b38a..5cfc7d2791 100644
--- a/ld/testsuite/ld-elf/pr23658-1.d
+++ b/ld/testsuite/ld-elf/pr23658-1a.d
@@ -7,8 +7,12 @@
 #readelf: -l --wide
 # Since generic linker targets don't place SHT_NOTE sections as orphan,
 # SHT_NOTE sections aren't grouped nor sorted.
-#xfail: cr16-* crx-* d30v-* dlx-* fr30-* frv-* ft32-* iq2000-*
+#xfail: d30v-* dlx-* fr30-* frv-*-elf ft32-* iq2000-*
 #xfail: m68hc12-* mn10200-* moxie-* mt-* msp430-* pj-* xgate-*
+# The following targets don't support --build-id.
+#xfail: cr16-* crx-* visium-* xc16x-*
+# The following targets place .note.gnu.build-id in unusual places.
+#xfail: pru-*
 
 #...
  +[0-9]+ +\.note\.4 \.note\.1 +
diff --git a/ld/testsuite/ld-elf/pr23658-1b.d b/ld/testsuite/ld-elf/pr23658-1b.d
new file mode 100644
index 0000000000..a8e7d16f49
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23658-1b.d
@@ -0,0 +1,16 @@
+#source: pr23658-1a.s
+#source: pr23658-1b.s
+#source: pr23658-1c.s
+#source: pr23658-1d.s
+#source: start.s
+#ld:
+#readelf: -l --wide
+# Since generic linker targets don't place SHT_NOTE sections as orphan,
+# SHT_NOTE sections aren't grouped nor sorted.
+#xfail: d30v-* dlx-* fr30-* frv-*-elf ft32-* iq2000-*
+#xfail: mn10200-* moxie-* mt-* msp430-* pj-* xgate-*
+
+#...
+ +[0-9]+ +\.note\.4 \.note\.1( .note.gnu.property|) +
+ +[0-9]+ +\.note\.2 .note\.3( .note.gnu.property|) +
+#pass
diff --git a/ld/testsuite/ld-elf/pr23658-1c.d b/ld/testsuite/ld-elf/pr23658-1c.d
new file mode 100644
index 0000000000..6d8fd7e537
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23658-1c.d
@@ -0,0 +1,13 @@
+#source: pr23658-1a.s
+#source: pr23658-1b.s
+#source: pr23658-1c.s
+#source: pr23658-1d.s
+#source: start.s
+#ld: --build-id -shared
+#readelf: -l --wide
+#target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi
+
+#...
+ +[0-9]+ +\.note\.4 \.note\.1 +
+ +[0-9]+ +\.note.gnu.build-id \.note\.2 .note\.3 +
+#pass
-- 
2.17.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]