[binutils-gdb] bfd_check_format_matches error paths

Alan Modra amodra@sourceware.org
Sun Apr 20 23:36:33 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7dc5df8e5d374fa6fec2f2a6b7d1bbc258095d47

commit 7dc5df8e5d374fa6fec2f2a6b7d1bbc258095d47
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Apr 19 14:42:23 2025 +0930

    bfd_check_format_matches error paths
    
    Tidy early out errors which didn't free matching_vector.  Don't
    bfd_preserve_restore if we get to err_ret from the first
    bfd_preserve_save, which might fail from a memory allocation leaving
    preserve.marker NULL.  Also take bfd_lock a little earlier before
    modifying abfd->format to simplify error return path from a lock
    failure.

Diff:
---
 bfd/format.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/bfd/format.c b/bfd/format.c
index 3db0792d412..a909b70fe81 100644
--- a/bfd/format.c
+++ b/bfd/format.c
@@ -470,7 +470,18 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
   /* Avoid clashes with bfd_cache_close_all running in another
      thread.  */
   if (!bfd_cache_set_uncloseable (abfd, true, &old_in_format_matches))
-    return false;
+    {
+      free (matching_vector);
+      return false;
+    }
+
+  /* Locking is required here in order to manage _bfd_section_id.  */
+  if (!bfd_lock ())
+    {
+      bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
+      free (matching_vector);
+      return false;
+    }
 
   /* Presume the answer is yes.  */
   abfd->format = format;
@@ -480,10 +491,6 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
      of an archive.  */
   orig_messages = _bfd_set_error_handler_caching (&messages);
 
-  /* Locking is required here in order to manage _bfd_section_id.  */
-  if (!bfd_lock ())
-    return false;
-
   preserve_match.marker = NULL;
   if (!bfd_preserve_save (abfd, &preserve, NULL))
     goto err_ret;
@@ -779,7 +786,8 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
  out:
   if (preserve_match.marker != NULL)
     bfd_preserve_finish (abfd, &preserve_match);
-  bfd_preserve_restore (abfd, &preserve);
+  if (preserve.marker != NULL)
+    bfd_preserve_restore (abfd, &preserve);
   _bfd_restore_error_handler_caching (orig_messages);
   print_and_clear_messages (&messages, PER_XVEC_NO_TARGET);
   bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);


More information about the Binutils-cvs mailing list