[v2,2/2] ld: Update gld${EMULATION_NAME}_place_orphan for PE/PEP

Message ID 20250115110347.1718501-3-hjl.tools@gmail.com
State New
Headers
Series Fix orphan_init_done for the object-only output |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_check--master-arm fail Patch failed to apply

Commit Message

H.J. Lu Jan. 15, 2025, 11:03 a.m. UTC
  Similar to ldelf_place_orphan, initialize hold from orig_hold at run-time
in PE and PEP gld${EMULATION_NAME}_place_orphan.

	* emultempl/pe.em (orphan_init_done): Make it file scope.
	(gld${EMULATION_NAME}_finish): Set orphan_init_done to false for
	the object-only output.
	(gld${EMULATION_NAME}_place_orphan): Rename hold to orig_hold.
	Initialize hold from orig_hold at run-time.
	* emultempl/pep.em (orphan_init_done): Make it file scope.
	(gld${EMULATION_NAME}_finish): Set orphan_init_done to false for
	the object-only output.
	(gld${EMULATION_NAME}_place_orphan): Rename hold to orig_hold.
	Initialize hold from orig_hold at run-time.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 ld/emultempl/pe.em  | 32 +++++++++++++++++++++-----------
 ld/emultempl/pep.em | 32 +++++++++++++++++++++-----------
 2 files changed, 42 insertions(+), 22 deletions(-)
  

Patch

diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 1a458aa774d..5fb14c9a4a6 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -160,6 +160,7 @@  static char * thumb_entry_symbol = NULL;
 static lang_assignment_statement_type *image_base_statement = 0;
 static unsigned short pe_dll_characteristics = DEFAULT_DLL_CHARACTERISTICS;
 static bool insert_timestamp = true;
+static bool orphan_init_done;
 static const char *emit_build_id;
 #ifdef PDB_H
 static int pdb;
@@ -2032,6 +2033,10 @@  gld${EMULATION_NAME}_recognized_file (lang_input_statement_type *entry ATTRIBUTE
 static void
 gld${EMULATION_NAME}_finish (void)
 {
+  /* Support the object-only output.  */
+  if (config.emit_gnu_object_only)
+    orphan_init_done = false;
+
 #if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_wince_pe)
   struct bfd_link_hash_entry * h;
 
@@ -2191,7 +2196,7 @@  gld${EMULATION_NAME}_place_orphan (asection *s,
 
   if (os == NULL)
     {
-      static struct orphan_save hold[] =
+      static struct orphan_save orig_hold[] =
 	{
 	  { ".text",
 	    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
@@ -2209,6 +2214,7 @@  gld${EMULATION_NAME}_place_orphan (asection *s,
 	    SEC_ALLOC,
 	    0, 0, 0, 0 }
 	};
+      static struct orphan_save hold[ARRAY_SIZE (orig_hold)];
       enum orphan_save_index
 	{
 	  orphan_text = 0,
@@ -2217,7 +2223,6 @@  gld${EMULATION_NAME}_place_orphan (asection *s,
 	  orphan_data,
 	  orphan_bss
 	};
-      static int orphan_init_done = 0;
       struct orphan_save *place;
       lang_output_section_statement_type *after;
       etree_type *address;
@@ -2226,15 +2231,20 @@  gld${EMULATION_NAME}_place_orphan (asection *s,
 
       if (!orphan_init_done)
 	{
-	  struct orphan_save *ho;
-	  for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
-	    if (ho->name != NULL)
-	      {
-		ho->os = lang_output_section_find (ho->name);
-		if (ho->os != NULL && ho->os->flags == 0)
-		  ho->os->flags = ho->flags;
-	      }
-	  orphan_init_done = 1;
+	  struct orphan_save *ho, *horig;
+	  for (ho = hold, horig = orig_hold;
+	       ho < hold + ARRAY_SIZE (hold);
+	       ++ho, ++horig)
+	    {
+	      *ho = *horig;
+	      if (ho->name != NULL)
+		{
+		  ho->os = lang_output_section_find (ho->name);
+		  if (ho->os != NULL && ho->os->flags == 0)
+		    ho->os->flags = ho->flags;
+	        }
+	    }
+	  orphan_init_done = true;
 	}
 
       flags = s->flags;
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 356b0e9f5da..df74352e4df 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -181,6 +181,7 @@  static int support_old_code = 0;
 static lang_assignment_statement_type *image_base_statement = 0;
 static unsigned short pe_dll_characteristics = DEFAULT_DLL_CHARACTERISTICS;
 static bool insert_timestamp = true;
+static bool orphan_init_done;
 static const char *emit_build_id;
 #ifdef PDB_H
 static int pdb;
@@ -1915,6 +1916,10 @@  gld${EMULATION_NAME}_recognized_file (lang_input_statement_type *entry ATTRIBUTE
 static void
 gld${EMULATION_NAME}_finish (void)
 {
+  /* Support the object-only output.  */
+  if (config.emit_gnu_object_only)
+    orphan_init_done = false;
+
   is_underscoring ();
   finish_default ();
 
@@ -2027,7 +2032,7 @@  gld${EMULATION_NAME}_place_orphan (asection *s,
 
   if (os == NULL)
     {
-      static struct orphan_save hold[] =
+      static struct orphan_save orig_hold[] =
 	{
 	  { ".text",
 	    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
@@ -2045,6 +2050,7 @@  gld${EMULATION_NAME}_place_orphan (asection *s,
 	    SEC_ALLOC,
 	    0, 0, 0, 0 }
 	};
+      static struct orphan_save hold[ARRAY_SIZE (orig_hold)];
       enum orphan_save_index
 	{
 	  orphan_text = 0,
@@ -2053,7 +2059,6 @@  gld${EMULATION_NAME}_place_orphan (asection *s,
 	  orphan_data,
 	  orphan_bss
 	};
-      static int orphan_init_done = 0;
       struct orphan_save *place;
       lang_output_section_statement_type *after;
       etree_type *address;
@@ -2062,15 +2067,20 @@  gld${EMULATION_NAME}_place_orphan (asection *s,
 
       if (!orphan_init_done)
 	{
-	  struct orphan_save *ho;
-	  for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
-	    if (ho->name != NULL)
-	      {
-		ho->os = lang_output_section_find (ho->name);
-		if (ho->os != NULL && ho->os->flags == 0)
-		  ho->os->flags = ho->flags;
-	      }
-	  orphan_init_done = 1;
+	  struct orphan_save *ho, *horig;
+	  for (ho = hold, horig = orig_hold;
+	       ho < hold + ARRAY_SIZE (hold);
+	       ++ho, ++horig)
+	    {
+	      *ho = *horig;
+	      if (ho->name != NULL)
+		{
+		  ho->os = lang_output_section_find (ho->name);
+		  if (ho->os != NULL && ho->os->flags == 0)
+		    ho->os->flags = ho->flags;
+	        }
+	    }
+	  orphan_init_done = true;
 	}
 
       flags = s->flags;