Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom Tromey <tromey@adacore.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tromey@adacore.com>
Subject: [PATCH RFC 4/6] Allow missing objfile handler to return a file
Date: Thu, 22 Oct 2026 12:28:14 -0600	[thread overview]
Message-ID: <20261022-android-apk-file-v1-4-8444bb5f832a@adacore.com> (raw)
In-Reply-To: <20261022-android-apk-file-v1-0-8444bb5f832a@adacore.com>

This patch changes the missing objfile handler code so that a handler
can return a "file".

To be pedantic, this returned object isn't a Python file-like object
but instead a small shim; see missing_objfile.BFDFile.
---
 gdb/build-id.c                        |  4 +++-
 gdb/extension.c                       |  2 +-
 gdb/extension.h                       | 21 +++++++++++++++++++++
 gdb/python/lib/gdb/__init__.py        |  2 ++
 gdb/python/lib/gdb/missing_objfile.py | 24 ++++++++++++++++++++++++
 gdb/python/python.c                   | 28 ++++++++++++++++++----------
 gdb/symfile-debug.c                   | 20 +++++++++++---------
 7 files changed, 80 insertions(+), 21 deletions(-)

diff --git a/gdb/build-id.c b/gdb/build-id.c
index 123d87e519c..550880d0d9c 100644
--- a/gdb/build-id.c
+++ b/gdb/build-id.c
@@ -403,7 +403,9 @@ find_objfile_by_build_id (program_space *pspace,
       ext_lang_missing_file_result ext_result
 	= ext_lang_find_objfile_from_buildid (pspace, build_id,
 					      expected_filename);
-      if (!ext_result.filename ().empty ())
+      if (ext_result.bfd () != nullptr)
+	return ext_result.bfd ();
+      else if (!ext_result.filename ().empty ())
 	{
 	  /* The extension identified the file for us.  */
 	  abfd = gdb_bfd_open (ext_result.filename ().c_str (), gnutarget);
diff --git a/gdb/extension.c b/gdb/extension.c
index de3b3eb69a5..a531d87fd0d 100644
--- a/gdb/extension.c
+++ b/gdb/extension.c
@@ -1103,7 +1103,7 @@ ext_lang_find_objfile_from_buildid (program_space *pspace,
       ext_lang_missing_file_result result
 	= extlang->ops->find_objfile_from_buildid (extlang, pspace, build_id,
 						   filename);
-      if (!result.filename ().empty () || result.try_again ())
+      if (result.valid ())
 	return result;
     }
 
diff --git a/gdb/extension.h b/gdb/extension.h
index 360c788a41e..4437169215b 100644
--- a/gdb/extension.h
+++ b/gdb/extension.h
@@ -24,6 +24,7 @@
 #include "gdbsupport/array-view.h"
 #include <optional>
 #include "gdbtypes.h"
+#include "gdb_bfd.h"
 
 struct breakpoint;
 struct command_line;
@@ -385,6 +386,11 @@ struct ext_lang_missing_file_result
     : m_filename (std::move (filename))
   { /* Nothing.  */ }
 
+  /* Use BFD for the missing debug info.  */
+  ext_lang_missing_file_result (gdb_bfd_ref_ptr &&abfd)
+    : m_bfd (std::move (abfd))
+  { /* Nothing.  */ }
+
   /* The filename where GDB can find the missing debuginfo.  This is empty
      if the extension didn't suggest a file that can be used.  */
   const std::string &
@@ -393,6 +399,13 @@ struct ext_lang_missing_file_result
     return m_filename;
   }
 
+  /* The BFD where GDB can find the missing debuginfo.  This is empty
+     if the extension didn't open a file that can be used.  */
+  const gdb_bfd_ref_ptr &bfd () const
+  {
+    return m_bfd;
+  }
+
   /* Returns true if GDB should look again for the debug information.  */
   const bool
   try_again () const
@@ -400,10 +413,18 @@ struct ext_lang_missing_file_result
     return m_try_again;
   }
 
+  bool valid () const
+  {
+    return m_try_again || !m_filename.empty () || m_bfd != nullptr;
+  }
+
 private:
   /* The filename where the missing debuginfo can now be found.  */
   std::string m_filename;
 
+  /* The BFD where the missing debuginfo can now be found.  */
+  gdb_bfd_ref_ptr m_bfd;
+
   /* When true GDB will search again for the debuginfo using its standard
      techniques.  When false GDB will not search again.  */
   bool m_try_again = false;
diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
index f16e0a66c5b..bc47585378c 100644
--- a/gdb/python/lib/gdb/__init__.py
+++ b/gdb/python/lib/gdb/__init__.py
@@ -402,6 +402,8 @@ def _handle_missing_objfile(pspace, buildid, filename):
               installed there then GDB will not find it.
         A string: This is the filename of a file containing the
                   missing objfile.
+        A BFD: A wrapper for a file implementing the BFD protocol.
+               See gdb.missing_objfile.BFDFile.
     """
 
     # Delay this as long as possible.
diff --git a/gdb/python/lib/gdb/missing_objfile.py b/gdb/python/lib/gdb/missing_objfile.py
index fe45a418c6d..f19f6395d4d 100644
--- a/gdb/python/lib/gdb/missing_objfile.py
+++ b/gdb/python/lib/gdb/missing_objfile.py
@@ -17,6 +17,8 @@
 MissingObjfileHandler base class, and register_handler function.
 """
 
+import os
+
 import gdb
 from gdb.missing_files import MissingFileHandler
 
@@ -66,6 +68,28 @@ class MissingObjfileHandler(MissingFileHandler):
         raise NotImplementedError("MissingObjfileHandler.__call__()")
 
 
+class BFDFile:
+    def __init__(self, fd, filename):
+        assert fd.seekable()
+        self._fd = fd
+        self._filename = filename
+        fd.seek(0, os.SEEK_END)
+        self._size = fd.tell()
+
+    def filename(self):
+        return self._filename
+
+    def size(self):
+        return self._size
+
+    def read(self, offset, size):
+        self._fd.seek(offset)
+        return self._fd.read(size)
+
+    def close(self):
+        self._fd.close()
+
+
 def register_handler(locus, handler, replace=False):
     """See gdb.missing_files.register_handler."""
     gdb.missing_files.register_handler("objfile", locus, handler, replace)
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 06ad0876527..3f7fdc6b186 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -2022,24 +2022,32 @@ gdbpy_find_objfile_from_buildid (const struct extension_language_defn *extlang,
       return ext_lang_missing_file_result (try_again);
     }
 
-  if (!gdbpy_is_string (pyo_execute_ret.get ()))
+  if (gdbpy_is_string (pyo_execute_ret.get ()))
     {
-      PyErr_SetString (PyExc_ValueError,
-		       "return value from _find_objfile_by_buildid should "
-		       "be None, a bool, or a str");
-      gdbpy_print_stack ();
-      return {};
+      gdb::unique_xmalloc_ptr<char> filename
+	= python_string_to_host_string (pyo_execute_ret.get ());
+      if (filename == nullptr)
+	{
+	  gdbpy_print_stack ();
+	  return {};
+	}
+
+      return ext_lang_missing_file_result (std::string (filename.get ()));
     }
 
-  gdb::unique_xmalloc_ptr<char> filename
-    = python_string_to_host_string (pyo_execute_ret.get ());
-  if (filename == nullptr)
+  gdb_bfd_ref_ptr the_bfd = open_bfd_from_python (std::move (pyo_execute_ret));
+  if (the_bfd == nullptr)
     {
+      if (!PyErr_Occurred ())
+	PyErr_SetString (PyExc_ValueError,
+			 "return value from _find_objfile_by_buildid should "
+			 "be None, a bool, a str, or a "
+			 "gdb.missing_objfile.BFDFile-like object");
       gdbpy_print_stack ();
       return {};
     }
 
-  return ext_lang_missing_file_result (std::string (filename.get ()));
+  return ext_lang_missing_file_result (std::move (the_bfd));
 }
 
 /* Compute the list of active python type printers and store them in
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 2432a709ddf..61914c09a94 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -659,25 +659,27 @@ objfile::find_and_add_separate_symbol_file (symfile_add_flags symfile_flags)
 
 	  ext_lang_missing_file_result ext_result
 	    = ext_lang_handle_missing_debuginfo (this);
-	  if (!ext_result.filename ().empty ())
+	  if (ext_result.bfd () != nullptr)
+	    debug_bfd = ext_result.bfd ();
+	  else if (!ext_result.filename ().empty ())
 	    {
 	      /* Extension found a suitable debug file for us.  */
 	      debug_bfd
 		= symfile_bfd_open_no_error (ext_result.filename ().c_str ());
-
-	      if (debug_bfd != nullptr)
-		{
-		  symbol_file_add_separate (debug_bfd,
-					    ext_result.filename ().c_str (),
-					    symfile_flags, this);
-		  has_dwarf2 = true;
-		}
 	    }
 	  else if (ext_result.try_again ())
 	    {
 	      max_attempts = 2;
 	      continue;
 	    }
+
+	  if (debug_bfd != nullptr)
+	    {
+	      symbol_file_add_separate (debug_bfd,
+					bfd_get_filename (debug_bfd.get ()),
+					symfile_flags, this);
+	      has_dwarf2 = true;
+	    }
 	}
 
       /* If we still have not got a separate debug symbol file, then

-- 
2.56.0


  parent reply	other threads:[~2026-10-22 18:29 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-22 18:28 [PATCH RFC 0/6] Handle Android APK files Tom Tromey
2026-10-22 18:28 ` [PATCH RFC 1/6] Add py-file.c Tom Tromey
2026-10-22 18:28 ` [PATCH RFC 2/6] Add py-iovec.c Tom Tromey
2026-10-22 18:28 ` [PATCH RFC 3/6] Allow missing build-id when finding an objfile Tom Tromey
2026-10-22 18:28 ` Tom Tromey [this message]
2026-10-22 18:28 ` [PATCH RFC 5/6] Call ext_lang_find_objfile_from_buildid from solib_bfd_fopen Tom Tromey
2026-10-22 18:28 ` [PATCH RFC 6/6] Add gdb.handler.android module Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261022-android-apk-file-v1-4-8444bb5f832a@adacore.com \
    --to=tromey@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox