]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
bfd_set_input_error
authorAlan Modra <amodra@gmail.com>
Fri, 3 Jan 2025 23:10:21 +0000 (09:40 +1030)
committerAlan Modra <amodra@gmail.com>
Sat, 4 Jan 2025 01:01:35 +0000 (11:31 +1030)
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.

bfd/bfd.c
bfd/libbfd.h
bfd/opncls.c

index 0e567ddeaea84c43dc7eeb2521ef5ee4ddb0fe1d..194f24179fd12501fdf797fdefd6e939091773c3 100644 (file)
--- 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;
 
index 3925fba00e4bcc3910d389ddd99c324a1deadf50..f86cc23db4521eb8248255754e2ad626134f3a01 100644 (file)
@@ -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.  */
index a0b30f568d7102f85e553f8578bf49efcd125252..93adbf117f05fd33191eabbfc1aaf0347e8cde0b 100644 (file)
@@ -943,7 +943,6 @@ bfd_close_all_done (bfd *abfd)
     _maybe_make_executable (abfd);
 
   _bfd_delete_bfd (abfd);
-  _bfd_clear_error_data ();
 
   return ret;
 }