Provide a way for programs to recognize BFD_ASSERT calls.
authorHans-Peter Nilsson <hp@axis.com>
Thu, 26 Apr 2012 13:49:52 +0000 (13:49 +0000)
committerHans-Peter Nilsson <hp@axis.com>
Thu, 26 Apr 2012 13:49:52 +0000 (13:49 +0000)
* 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.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/bfd.c
bfd/libbfd-in.h
bfd/libbfd.h

index b46eb9c4e3abfdf3b4918b1e96b9ce3bb49675df..115cd7c0ebac59cf53adc39ebbf74210c4be8773 100644 (file)
@@ -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
index c5d19dce6efb0a4aff223ffd745ff5ad1c2befe8..17dbbe135351c17e122fe419c6868eaa13c8b417 100644 (file)
@@ -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
index 7c14c7a00a6e885aa98443113456b240bd04c8b5..227e26bb5ebe5905a0fb90eed969f91c5d733364 100644 (file)
--- 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;
+}
 \f
 /*
 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
index 640768ee88c7287bef08bdb9c485c80a4961e780..45f0b0cf0d479bbabb03be153abc0aa2a41d2962 100644 (file)
@@ -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.  */
 
index cc293bca19dacdbcc62f22ed827e8407254a4891..ab3c897de0f74f7867db6b69005ece4aa68e7c37 100644 (file)
@@ -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.  */