summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/bfd-in2.h9
-rw-r--r--bfd/bfd.c92
-rw-r--r--bfd/libbfd-in.h1
-rw-r--r--bfd/libbfd.h1
5 files changed, 112 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b46eb9c4e3..115cd7c0eb 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2012-04-26 Hans-Peter Nilsson <hp@axis.com>
+
+ Provide a way for programs to recognize BFD_ASSERT calls.
+ * bfd.c (bfd_assert_handler_type): New API type.
+ (bfd_set_assert_handler, bfd_get_assert_handler): New API functions.
+ (_bfd_assert_handler): New variable.
+ (_bfd_default_assert_handler): New function.
+ (bfd_assert): Call _bfd_assert_handler, not _bfd_error_handler.
+ * libbfd-in.h (_bfd_assert_handler): Declare.
+ * libbfd.h, bfd-in2.h: Regenerate.
+
2012-04-24 Hans-Peter Nilsson <hp@axis.com>
PR ld/13990
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index c5d19dce6e..17dbbe1353 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5637,6 +5637,15 @@ void bfd_set_error_program_name (const char *);
bfd_error_handler_type bfd_get_error_handler (void);
+typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg,
+ const char *bfd_version,
+ const char *bfd_file,
+ int bfd_line);
+
+bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type);
+
+bfd_assert_handler_type bfd_get_assert_handler (void);
+
long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect);
long bfd_canonicalize_reloc
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 7c14c7a00a..227e26bb5e 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -797,6 +797,88 @@ bfd_get_error_handler (void)
{
return _bfd_error_handler;
}
+
+/*
+SUBSECTION
+ BFD assert handler
+
+ If BFD finds an internal inconsistency, the bfd assert
+ handler is called with information on the BFD version, BFD
+ source file and line. If this happens, most programs linked
+ against BFD are expected to want to exit with an error, or mark
+ the current BFD operation as failed, so it is recommended to
+ override the default handler, which just calls
+ _bfd_error_handler and continues.
+
+CODE_FRAGMENT
+.
+.typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg,
+. const char *bfd_version,
+. const char *bfd_file,
+. int bfd_line);
+.
+*/
+
+/* Note the use of bfd_ prefix on the parameter names above: we want to
+ show which one is the message and which is the version by naming the
+ parameters, but avoid polluting the program-using-bfd namespace as
+ the typedef is visible in the exported headers that the program
+ includes. Below, it's just for consistency. */
+
+static void
+_bfd_default_assert_handler (const char *bfd_formatmsg,
+ const char *bfd_version,
+ const char *bfd_file,
+ int bfd_line)
+
+{
+ (*_bfd_error_handler) (bfd_formatmsg, bfd_version, bfd_file, bfd_line);
+}
+
+/* Similar to _bfd_error_handler, a program can decide to exit on an
+ internal BFD error. We use a non-variadic type to simplify passing
+ on parameters to other functions, e.g. _bfd_error_handler. */
+
+bfd_assert_handler_type _bfd_assert_handler = _bfd_default_assert_handler;
+
+/*
+FUNCTION
+ bfd_set_assert_handler
+
+SYNOPSIS
+ bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type);
+
+DESCRIPTION
+ Set the BFD assert handler function. Returns the previous
+ function.
+*/
+
+bfd_assert_handler_type
+bfd_set_assert_handler (bfd_assert_handler_type pnew)
+{
+ bfd_assert_handler_type pold;
+
+ pold = _bfd_assert_handler;
+ _bfd_assert_handler = pnew;
+ return pold;
+}
+
+/*
+FUNCTION
+ bfd_get_assert_handler
+
+SYNOPSIS
+ bfd_assert_handler_type bfd_get_assert_handler (void);
+
+DESCRIPTION
+ Return the BFD assert handler function.
+*/
+
+bfd_assert_handler_type
+bfd_get_assert_handler (void)
+{
+ return _bfd_assert_handler;
+}
/*
SECTION
@@ -942,8 +1024,14 @@ bfd_set_file_flags (bfd *abfd, flagword flags)
void
bfd_assert (const char *file, int line)
{
- (*_bfd_error_handler) (_("BFD %s assertion fail %s:%d"),
- BFD_VERSION_STRING, file, line);
+ (*_bfd_assert_handler) (_("BFD %s assertion fail %s:%d"),
+ BFD_VERSION_STRING, file, line);
+
+ /* We used to just return from bfd_assert, but that caused more
+ grief than relief. The different code paths for bfd_assert and
+ _bfd_abort could be united but keeping them separate can
+ simplify debugging. */
+ _exit (EXIT_FAILURE);
}
/* A more or less friendly abort message. In libbfd.h abort is
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 640768ee88..45f0b0cf0d 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -117,6 +117,7 @@ extern void *bfd_zmalloc2
extern void _bfd_default_error_handler (const char *s, ...);
extern bfd_error_handler_type _bfd_error_handler;
+extern bfd_assert_handler_type _bfd_assert_handler;
/* These routines allocate and free things on the BFD's objalloc. */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index cc293bca19..ab3c897de0 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -122,6 +122,7 @@ extern void *bfd_zmalloc2
extern void _bfd_default_error_handler (const char *s, ...);
extern bfd_error_handler_type _bfd_error_handler;
+extern bfd_assert_handler_type _bfd_assert_handler;
/* These routines allocate and free things on the BFD's objalloc. */