Blob Blame History Raw
diff -rup binutils.orig/ld/emultempl/elf.em binutils-2.41/ld/emultempl/elf.em
--- binutils.orig/ld/emultempl/elf.em	2024-01-25 12:15:12.113299123 +0000
+++ binutils-2.41/ld/emultempl/elf.em	2024-01-25 12:15:21.754311058 +0000
@@ -893,7 +893,7 @@ fi
 
 fragment <<EOF
       else
-	einfo (_("%P: warning: -z %s ignored\n"), optarg);
+	queue_unknown_cmdline_warning ("-z %s", optarg);
       break;
 EOF
 
Only in binutils-2.41/ld/emultempl: elf.em.orig
diff -rup binutils.orig/ld/ldelf.c binutils-2.41/ld/ldelf.c
--- binutils.orig/ld/ldelf.c	2024-01-25 12:15:12.114299125 +0000
+++ binutils-2.41/ld/ldelf.c	2024-01-25 12:15:21.754311058 +0000
@@ -74,7 +74,7 @@ ldelf_after_parse (void)
       && link_info.nointerp)
     {
       if (link_info.dynamic_undefined_weak > 0)
-	einfo (_("%P: warning: -z dynamic-undefined-weak ignored\n"));
+	queue_unknown_cmdline_warning ("-z dynamic-undefined-weak");
       link_info.dynamic_undefined_weak = 0;
     }
 
diff -rup binutils.orig/ld/ldmain.c binutils-2.41/ld/ldmain.c
--- binutils.orig/ld/ldmain.c	2024-01-25 12:15:12.114299125 +0000
+++ binutils-2.41/ld/ldmain.c	2024-01-25 12:15:21.754311058 +0000
@@ -479,6 +479,8 @@ main (int argc, char **argv)
 
   ldemul_after_parse ();
 
+  output_unknown_cmdline_warnings ();
+
   if (config.map_filename)
     {
       if (strcmp (config.map_filename, "-") == 0)
diff -rup binutils.orig/ld/ldmisc.c binutils-2.41/ld/ldmisc.c
--- binutils.orig/ld/ldmisc.c	2024-01-25 12:15:12.114299125 +0000
+++ binutils-2.41/ld/ldmisc.c	2024-01-25 12:15:21.754311058 +0000
@@ -620,6 +620,81 @@ einfo (const char *fmt, ...)
   fflush (stderr);
 }
 
+/* The buffer size for each command-line option warning.  */
+#define CMDLINE_WARNING_SIZE	256
+
+/* A linked list of command-line option warnings.  */
+
+struct cmdline_warning_list
+{
+  struct cmdline_warning_list *next;
+  char *warning;
+};
+
+/* The head of the linked list of command-line option warnings.  */
+static struct cmdline_warning_list *cmdline_warning_head = NULL;
+
+/* The tail of the linked list of command-line option warnings.  */
+static struct cmdline_warning_list **cmdline_warning_tail
+  = &cmdline_warning_head;
+
+/* Queue an unknown command-line option warning.  */
+
+void
+queue_unknown_cmdline_warning (const char *fmt, ...)
+{
+  va_list arg;
+  struct cmdline_warning_list *warning_ptr
+    = xmalloc (sizeof (*warning_ptr));
+  warning_ptr->warning = xmalloc (CMDLINE_WARNING_SIZE);
+  warning_ptr->next = NULL;
+  int written;
+
+  va_start (arg, fmt);
+  written = vsnprintf (warning_ptr->warning, CMDLINE_WARNING_SIZE, fmt,
+		       arg);
+  if (written < 0 || written >= CMDLINE_WARNING_SIZE)
+    {
+      /* If vsnprintf fails or truncates, output the warning directly.  */
+      fflush (stdout);
+      va_start (arg, fmt);
+      vfinfo (stderr, fmt, arg, true);
+      fflush (stderr);
+    }
+  else
+    {
+      *cmdline_warning_tail = warning_ptr;
+      cmdline_warning_tail = &warning_ptr->next;
+    }
+  va_end (arg);
+}
+
+/* Output queued unknown command-line option warnings.  */
+
+void
+output_unknown_cmdline_warnings (void)
+{
+  struct cmdline_warning_list *list = cmdline_warning_head;
+  struct cmdline_warning_list *next;
+  if (list == NULL)
+    return;
+
+  fflush (stdout);
+
+  for (; list != NULL; list = next)
+    {
+      next = list->next;
+      if (config.fatal_warnings)
+	einfo (_("%P: error: unsupported option: %s\n"), list->warning);
+      else
+	einfo (_("%P: warning: %s ignored\n"), list->warning);
+      free (list->warning);
+      free (list);
+    }
+
+  fflush (stderr);
+}
+
 void
 info_assert (const char *file, unsigned int line)
 {
diff -rup binutils.orig/ld/ldmisc.h binutils-2.41/ld/ldmisc.h
--- binutils.orig/ld/ldmisc.h	2024-01-25 12:15:12.114299125 +0000
+++ binutils-2.41/ld/ldmisc.h	2024-01-25 12:15:59.559357849 +0000
@@ -31,6 +31,8 @@ extern void yyerror (const char *);
 extern void info_msg (const char *, ...);
 extern void lfinfo (FILE *, const char *, ...);
 extern void info_assert (const char *, unsigned int);
+extern void queue_unknown_cmdline_warning (const char *, ...);
+extern void output_unknown_cmdline_warnings (void);
 
 #define ASSERT(x) \
 do { if (!(x)) info_assert(__FILE__,__LINE__); } while (0)