[1/2] ld-pe: Refactor code dealing with -exclude-symbols

Message ID AS4PR02MB79027501F30490ABF58445F6838B2@AS4PR02MB7902.eurprd02.prod.outlook.com
State New
Headers
Series [1/2] ld-pe: Refactor code dealing with -exclude-symbols |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Luca Bacci Sept. 30, 2026, 9:33 a.m. UTC
  Make it more generic. We'll make use of that code
in the next commit.
---
 ld/deffile.h  |  12 +++---
 ld/deffilep.y | 115 +++++++++++++++++++++++++++++++-------------------
 ld/pe-dll.c   |  10 +----
 3 files changed, 79 insertions(+), 58 deletions(-)
  

Comments

Luca Bacci Oct. 1, 2026, 8:56 a.m. UTC | #1
Hello dear binutils maintainers,

I discussed this patch with mingw-w64 developers. We came to the conclusion that some things should be done differently; namely:

  *
We should avoid extending the set of DEF statements
  *
We should use --require-defined instead of --undefined

A new patch will be sent in a while.

Best Regards,
Luca
  

Patch

diff --git a/ld/deffile.h b/ld/deffile.h
index 83bc4b1c..9269d488 100644
--- a/ld/deffile.h
+++ b/ld/deffile.h
@@ -61,9 +61,11 @@  typedef struct def_file_aligncomm {
   unsigned int alignment;	/* log-2 alignment.        */
 } def_file_aligncomm;
 
-typedef struct def_file_exclude_symbol {
-  char *symbol_name;		/* Name of excluded symbol.  */
-} def_file_exclude_symbol;
+typedef struct def_file_symbol_list {
+  char **array;			/* Sorted array of symbols names.  */
+  unsigned int count;		/* Count of entries in the array. */
+  unsigned int allocated;	/* Count of allocated entries in the array. */
+} def_file_symbol_list;
 
 typedef struct def_file {
   /* From the NAME or LIBRARY command.  */
@@ -102,9 +104,7 @@  typedef struct def_file {
   def_file_aligncomm *aligncomms;
 
   /* From EXCLUDE_SYMBOLS or embedded directives. */
-  unsigned int num_exclude_symbols, max_exclude_symbols;
-  def_file_exclude_symbol *exclude_symbols;
-
+  def_file_symbol_list exclude_symbols;
 } def_file;
 
 extern def_file *def_file_empty (void);
diff --git a/ld/deffilep.y b/ld/deffilep.y
index e715c4d2..bac19249 100644
--- a/ld/deffilep.y
+++ b/ld/deffilep.y
@@ -377,6 +377,9 @@  struct directive
 
 static struct directive *directives = 0;
 
+static void
+symbol_list_clear (def_file_symbol_list *symbols);
+
 def_file *
 def_file_empty (void)
 {
@@ -441,7 +444,6 @@  void
 def_file_free (def_file *fdef)
 {
   int i;
-  unsigned int ui;
 
   if (!fdef)
     return;
@@ -493,11 +495,7 @@  def_file_free (def_file *fdef)
       free (c);
     }
 
-  for (ui = 0; ui < fdef->num_exclude_symbols; ui++)
-    {
-      free (fdef->exclude_symbols[ui].symbol_name);
-    }
-  free (fdef->exclude_symbols);
+  symbol_list_clear (&fdef->exclude_symbols);
 
   free (fdef);
 }
@@ -948,37 +946,44 @@  def_file_add_import_at (def_file *fdef,
    points at an element which is identical to the one searched for.  */
 
 static unsigned int
-find_exclude_in_list (def_file_exclude_symbol *b, unsigned int max,
-		      const char *name, bool *is_ident)
+symbol_list_find_entry (def_file_symbol_list *symbols,
+			const char *name,
+			bool *is_ident)
 {
   int e;
   unsigned int l, r, p;
 
   *is_ident = false;
-  if (!max)
+
+  if (symbols->count == 0)
     return 0;
-  if ((e = strcmp (b[0].symbol_name, name)) <= 0)
+
+  if ((e = strcmp (symbols->array[0], name)) <= 0)
     {
-      if (!e)
+      if (e == 0)
 	*is_ident = true;
       return 0;
     }
-  if (max == 1)
+
+  if (symbols->count == 1)
     return 1;
-  if ((e = strcmp (b[max - 1].symbol_name, name)) > 0)
-    return max;
-  else if (!e || max == 2)
+
+  if ((e = strcmp (symbols->array[symbols->count - 1], name)) > 0)
+    return symbols->count;
+  else if (e == 0 || symbols->count == 2)
     {
-      if (!e)
+      if (e == 0)
 	*is_ident = true;
-      return max - 1;
+      return symbols->count - 1;
     }
-  l = 0; r = max - 1;
+
+  l = 0;
+  r = symbols->count - 1;
   while (l < r)
     {
       p = (l + r) / 2;
-      e = strcmp (b[p].symbol_name, name);
-      if (!e)
+      e = strcmp (symbols->array[p], name);
+      if (e == 0)
 	{
 	  *is_ident = true;
 	  return p;
@@ -988,45 +993,67 @@  find_exclude_in_list (def_file_exclude_symbol *b, unsigned int max,
       else if (e > 0)
 	l = p + 1;
     }
-  if ((e = strcmp (b[l].symbol_name, name)) > 0)
+
+  if ((e = strcmp (symbols->array[l], name)) > 0)
     ++l;
-  else if (!e)
+  else if (e == 0)
     *is_ident = true;
+
   return l;
 }
 
-static def_file_exclude_symbol *
-def_file_add_exclude_symbol (def_file *fdef, const char *name)
+static void
+symbol_list_add (def_file_symbol_list *symbols,
+		 const char *name)
 {
-  def_file_exclude_symbol *e;
-  unsigned pos;
+  unsigned int pos;
   bool is_dup = false;
 
-  pos = find_exclude_in_list (fdef->exclude_symbols, fdef->num_exclude_symbols,
-			      name, &is_dup);
+  pos = symbol_list_find_entry (symbols, name, &is_dup);
 
   /* We need to avoid duplicates.  */
   if (is_dup)
-    return (fdef->exclude_symbols + pos);
+    return;
 
-  if (fdef->num_exclude_symbols >= fdef->max_exclude_symbols)
+  if (symbols->count == symbols->allocated)
     {
-      fdef->max_exclude_symbols += SYMBOL_LIST_ARRAY_GROW;
-      fdef->exclude_symbols
-	= xrealloc (fdef->exclude_symbols,
-		    fdef->max_exclude_symbols * sizeof (*fdef->exclude_symbols));
+      symbols->allocated += SYMBOL_LIST_ARRAY_GROW;
+      symbols->array = xrealloc (symbols->array,
+				 symbols->allocated * sizeof (symbols->array[0]));
     }
 
-  e = fdef->exclude_symbols + pos;
-  /* If we're inserting in the middle of the array, we need to move the
-     following elements forward.  */
-  if (pos != fdef->num_exclude_symbols)
-    memmove (e + 1, e, sizeof (*e) * (fdef->num_exclude_symbols - pos));
-  /* Wipe the element for use as a new entry.  */
-  memset (e, 0, sizeof (*e));
-  e->symbol_name = xstrdup (name);
-  fdef->num_exclude_symbols++;
-  return e;
+  /* If we're inserting in the middle of the array
+   * we need to move the following elements forward.
+   */
+  if (pos != symbols->count)
+    {
+      memmove (symbols->array + pos + 1,
+	       symbols->array + pos,
+	       (symbols->count - pos) * sizeof (symbols->array[0]));
+    }
+
+  symbols->array[pos] = xstrdup (name);
+  symbols->count++;
+}
+
+static void
+symbol_list_clear (def_file_symbol_list *symbols)
+{
+  unsigned int ui;
+
+  for (ui = 0; ui < symbols->count; ui++)
+    free (symbols->array[ui]);
+
+  free (symbols->array);
+
+  memset (symbols, 0, sizeof (*symbols));
+}
+
+static void
+def_file_add_exclude_symbol (def_file *fdef,
+			     const char *name)
+{
+  symbol_list_add (&fdef->exclude_symbols, name);
 }
 
 struct
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index f43bd148..6fb3dce2 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -781,14 +781,8 @@  process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
 	}
     }
 
-  if (pe_def_file->exclude_symbols)
-    {
-      for (ui = 0; ui < pe_def_file->num_exclude_symbols; ui++)
-	{
-	  pe_dll_add_excludes (pe_def_file->exclude_symbols[ui].symbol_name,
-			       EXCLUDESYMS);
-	}
-    }
+  for (ui = 0; ui < pe_def_file->exclude_symbols.count; ui++)
+    pe_dll_add_excludes (pe_def_file->exclude_symbols.array[ui], EXCLUDESYMS);
 
   /* If we are building an executable and there is nothing
      to export, we do not build an export table at all.  */