bfd_set_input_error

Message ID Z3iUh2MVRxbRq-4O@squeak.grove.modra.org
State New
Headers
Series bfd_set_input_error |

Checks

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

Commit Message

Alan Modra Jan. 4, 2025, 1:53 a.m. UTC
  My recent change to closing archives showed some problems with the way
we stash errors for archive elements.  The most obvious thing found
by oss-fuzz, is that if output archive elements are closed during
bfd_close of an archive, then we can't access the element filename
when printing the element.  So change bfd_set_input_error to stash the
entire error message instead of input bfd and input error.

	* bfd.c (input_bfd, input_error): Delete.
	(bfd_error, _bfd_error_buf): Move.
	(_bfd_clear_error_data): Move.  Make static.  Clear bfd_error too.
	(bfd_set_input_error): Print the error use bfd_asprintf here..
	(bfd_errmsg): ..not here.
	(bfd_init): Update.
	* opncls.c (bfd_close_all_done): Don't call _bfd_clear_error_data.
	* libbfd.h: Regenerate.
  

Patch

diff --git a/bfd/bfd.c b/bfd/bfd.c
index 0e567ddeaea..194f24179fd 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -768,11 +768,6 @@  CODE_FRAGMENT
 .
 */
 
-static TLS bfd_error_type bfd_error;
-static TLS bfd_error_type input_error;
-static TLS bfd *input_bfd;
-static TLS char *_bfd_error_buf;
-
 const char *const bfd_errmsgs[] =
 {
   N_("no error"),
@@ -800,6 +795,19 @@  const char *const bfd_errmsgs[] =
   N_("#<invalid error code>")
 };
 
+static TLS bfd_error_type bfd_error;
+static TLS char *_bfd_error_buf;
+
+/* Free any data associated with the BFD error.  */
+
+static void
+_bfd_clear_error_data (void)
+{
+  bfd_error = bfd_error_no_error;
+  free (_bfd_error_buf);
+  _bfd_error_buf = NULL;
+}
+
 /*
 FUNCTION
 	bfd_get_error
@@ -858,12 +866,12 @@  bfd_set_input_error (bfd *input, bfd_error_type error_tag)
 {
   /* This is an error that occurred during bfd_close when writing an
      archive, but on one of the input files.  */
-  bfd_error = bfd_error_on_input;
   _bfd_clear_error_data ();
-  input_bfd = input;
-  input_error = error_tag;
-  if (input_error >= bfd_error_on_input)
+  if (error_tag >= bfd_error_on_input)
     abort ();
+  if (bfd_asprintf (_(bfd_errmsgs[bfd_error_on_input]),
+		    bfd_get_filename (input), bfd_errmsg (error_tag)))
+    bfd_error = bfd_error_on_input;
 }
 
 /*
@@ -885,16 +893,7 @@  bfd_errmsg (bfd_error_type error_tag)
   extern int errno;
 #endif
   if (error_tag == bfd_error_on_input)
-    {
-      const char *msg = bfd_errmsg (input_error);
-      char *ret = bfd_asprintf (_(bfd_errmsgs[error_tag]),
-				bfd_get_filename (input_bfd), msg);
-      if (ret)
-	return ret;
-
-      /* Ick, what to do on out of memory?  */
-      return msg;
-    }
+    return _bfd_error_buf;
 
   if (error_tag == bfd_error_system_call)
     return xstrerror (errno);
@@ -931,24 +930,6 @@  bfd_perror (const char *message)
   fflush (stderr);
 }
 
-/*
-INTERNAL_FUNCTION
-	_bfd_clear_error_data
-
-SYNOPSIS
-	void _bfd_clear_error_data (void);
-
-DESCRIPTION
-	Free any data associated with the BFD error.
-*/
-
-void
-_bfd_clear_error_data (void)
-{
-  free (_bfd_error_buf);
-  _bfd_error_buf = NULL;
-}
-
 /*
 INTERNAL_FUNCTION
 	bfd_asprintf
@@ -1961,10 +1942,7 @@  DESCRIPTION
 unsigned int
 bfd_init (void)
 {
-  bfd_error = bfd_error_no_error;
-  input_bfd = NULL;
   _bfd_clear_error_data ();
-  input_error = bfd_error_no_error;
   _bfd_error_internal = error_handler_fprintf;
   _bfd_assert_handler = _bfd_default_assert_handler;
 
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 3925fba00e4..f86cc23db45 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -963,8 +963,6 @@  bool bfd_write_bigendian_4byte_int (bfd *, unsigned int) ATTRIBUTE_HIDDEN;
 unsigned int bfd_log2 (bfd_vma x) ATTRIBUTE_HIDDEN;
 
 /* Extracted from bfd.c.  */
-void _bfd_clear_error_data (void) ATTRIBUTE_HIDDEN;
-
 char *bfd_asprintf (const char *fmt, ...) ATTRIBUTE_HIDDEN;
 
 /* Cached _bfd_check_format messages are put in this.  */
diff --git a/bfd/opncls.c b/bfd/opncls.c
index a0b30f568d7..93adbf117f0 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -943,7 +943,6 @@  bfd_close_all_done (bfd *abfd)
     _maybe_make_executable (abfd);
 
   _bfd_delete_bfd (abfd);
-  _bfd_clear_error_data ();
 
   return ret;
 }