aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2025-01-04 09:40:21 +1030
committerAlan Modra <amodra@gmail.com>2025-01-04 11:31:35 +1030
commitd8d3ed295efb75a7421340484e3fe8115402b1f2 (patch)
tree8e76d0b387c9cd1c830e9f82ff6f6953fce0f044
parent879bde78c2568b251526a9c874cce60091b0d0e5 (diff)
downloadgdb-d8d3ed295efb75a7421340484e3fe8115402b1f2.zip
gdb-d8d3ed295efb75a7421340484e3fe8115402b1f2.tar.gz
gdb-d8d3ed295efb75a7421340484e3fe8115402b1f2.tar.bz2
bfd_set_input_error
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.
-rw-r--r--bfd/bfd.c58
-rw-r--r--bfd/libbfd.h2
-rw-r--r--bfd/opncls.c1
3 files changed, 18 insertions, 43 deletions
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 0e567dd..194f241 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);
@@ -933,24 +932,6 @@ bfd_perror (const char *message)
/*
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
SYNOPSIS
@@ -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 3925fba..f86cc23 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 a0b30f5..93adbf1 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;
}