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 2/6] Add py-iovec.c
Date: Thu, 22 Oct 2026 12:28:12 -0600	[thread overview]
Message-ID: <20261022-android-apk-file-v1-2-8444bb5f832a@adacore.com> (raw)
In-Reply-To: <20261022-android-apk-file-v1-0-8444bb5f832a@adacore.com>

This patch adds py-iovec.c, which provides a way to construct a new
BFD that can access Python objects to get the underlying data.  Due to
how subsequent patches are written, Python file-like objects aren't
used directly, but instead a wrapper will be provided.
---
 gdb/Makefile.in              |   1 +
 gdb/python/py-iovec.c        | 130 +++++++++++++++++++++++++++++++++++++++++++
 gdb/python/python-internal.h |   2 +
 3 files changed, 133 insertions(+)

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 4260c90d425..e6c99924451 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -413,6 +413,7 @@ SUBDIR_PYTHON_SRCS = \
 	python/py-infevents.c \
 	python/py-infthread.c \
 	python/py-instruction.c \
+	python/py-iovec.c \
 	python/py-lazy-string.c \
 	python/py-linetable.c \
 	python/py-membuf.c \
diff --git a/gdb/python/py-iovec.c b/gdb/python/py-iovec.c
new file mode 100644
index 00000000000..4bcea6d8a3b
--- /dev/null
+++ b/gdb/python/py-iovec.c
@@ -0,0 +1,130 @@
+/* Python interface to BFD iovec
+
+   Copyright (C) 2026 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "gdb_bfd.h"
+#include "gdbcore.h"
+#include "python-internal.h"
+
+struct py_iovec : public gdb_bfd_iovec_base
+{
+  py_iovec (gdbpy_ref<> &&file_obj, ULONGEST file_size)
+    : m_file (std::move (file_obj)),
+      m_size (file_size)
+  {
+  }
+
+  ~py_iovec ();
+
+  file_ptr read (bfd *abfd, void *buffer, file_ptr nbytes,
+		 file_ptr offset) override;
+
+  int stat (struct bfd *abfd, struct stat *sb) override
+  {
+    /* We only support the size here.  */
+    memset (sb, 0, sizeof (*sb));
+    sb->st_size = m_size;
+    return 0;
+  }
+
+  gdbpy_ref<> m_file;
+  ULONGEST m_size;
+};
+
+py_iovec::~py_iovec ()
+{
+  /* Make sure the GIL is held before destruction.  */
+  gdbpy_enter enter_py;
+
+  gdbpy_ref<> result = gdbpy_call_method (m_file.get (), "close");
+  if (result == nullptr)
+    gdbpy_print_stack ();
+
+  m_file.reset (nullptr);
+}
+
+file_ptr
+py_iovec::read (bfd *abfd, void *buffer, file_ptr nbytes, file_ptr offset)
+{
+  /* If this read will read all of the file, limit it to just the rest.  */
+  if (offset + nbytes > m_size)
+    nbytes = m_size - offset;
+
+  /* If there are no more bytes left, we've reached EOF.  */
+  if (nbytes == 0)
+    return 0;
+
+  gdbpy_enter enter_py;
+
+  char *data;
+  Py_ssize_t len;
+  gdbpy_ref<> bytes = gdbpy_call_method (m_file.get (), "read",
+					 (gdb_py_ulongest) offset,
+					 (gdb_py_ulongest) nbytes);
+  if (bytes == nullptr
+      || PyBytes_AsStringAndSize (bytes.get (), &data, &len) == -1)
+    {
+      gdbpy_print_stack ();
+      bfd_set_error (bfd_error_bad_value);
+      return -1;
+    }
+
+  memcpy (buffer, data, len);
+  return len;
+}
+
+gdb_bfd_ref_ptr
+open_bfd_from_python (gdbpy_ref<> &&file_obj)
+{
+  int has_attr = PyObject_HasAttrString (file_obj.get (), "read");
+  if (has_attr != 1)
+    {
+      /* This may return without the error set, but this scenario is
+	 handled by the caller.  */
+      return nullptr;
+    }
+
+  gdbpy_ref<> size_obj = gdbpy_call_method (file_obj.get (), "size");
+  if (size_obj == nullptr)
+    return nullptr;
+  gdb_py_ulongest size = gdb_py_long_as_ulongest (size_obj.get ());
+  if (PyErr_Occurred ())
+    return nullptr;
+
+  gdbpy_ref<> name_obj = gdbpy_call_method (file_obj.get (), "filename");
+  if (name_obj == nullptr)
+    return nullptr;
+  gdb::unique_xmalloc_ptr<char> filename
+    = python_string_to_host_string (name_obj.get ());
+  if (filename == nullptr)
+    return nullptr;
+
+  auto iovec = std::make_unique<py_iovec> (std::move (file_obj), size);
+
+  auto open = [&] (bfd *nbfd) -> py_iovec *
+  {
+    return iovec.release ();
+  };
+
+  gdb_bfd_ref_ptr result = gdb_bfd_openr_iovec (filename.get (),
+						gnutarget, open);
+  if (result == nullptr)
+    PyErr_Format (PyExc_OSError, "could not open %s: %s",
+		  filename.get (), bfd_errmsg (bfd_get_error ()));
+  return result;
+}
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 2e064107cbc..bf7eb795061 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -1416,6 +1416,8 @@ class gdbpy_memoizing_registry_storage
 extern gdbpy_ref<> eval_python_command
   (const char *command, int start_symbol, const char *filename = nullptr);
 
+extern gdb_bfd_ref_ptr open_bfd_from_python (gdbpy_ref<> &&file_obj);
+
 /* The following four functions are refcount-safe wrappers around
    Py_RETURN_{NONE,TRUE,FALSE,NOTIMPLEMENTED}.  */
 

-- 
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 ` Tom Tromey [this message]
2026-10-22 18:28 ` [PATCH RFC 3/6] Allow missing build-id when finding an objfile Tom Tromey
2026-10-22 18:28 ` [PATCH RFC 4/6] Allow missing objfile handler to return a file Tom Tromey
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-2-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