[PATCH v2 12/47] gdb, solib, ze: solib_bfd_open_from_target_memory

Tankut Baris Aktemur
2024-12-13T16:16:46Z

From: Markus Metzger <markus.t.metzger@intel.com>

Add solib_bfd_open_from_target_memory to mimic the solib_bfd_open
behavior on top of gdb_bfd_open for in-memory files.
---
gdb/solib-target.c | 2 +-
gdb/solib.c | 52 ++++++++++++++++++++++++++++++++++++++++------------
gdb/solist.h | 5 +++++
3 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/gdb/solib-target.c b/gdb/solib-target.c
index bf74d79ecdb2309b7645aaf04ce9fed1bff51cff..78c8b1c58b8c9b5bdff704c059aeea18fe9955dd 100644
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -544,6 +544,6 @@ const solib_ops solib_target_so_ops =
nullptr,
nullptr,
default_find_solib_addr,
- gdb_bfd_open_from_target_memory,
+ solib_bfd_open_from_target_memory,
solib_target_ack_library,
};
diff --git a/gdb/solib.c b/gdb/solib.c
index 92fc5137a3d469f55043235a65dcadcc1f25fe96..a2d986dcd89841ee6ad7dbeff67b4f45042cc8d5 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -428,13 +428,34 @@ solib_bfd_fopen (const char *pathname, int fd)
return abfd;
}

+/* Initialize an opened BFD. */
+
+static void
+solib_bfd_init (bfd *abfd)
+{
+
+ /* Check bfd format. */
+ if (!bfd_check_format (abfd, bfd_object))
+ error (_("`%s': not in executable format: %s"),
+ bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+
+ /* Check bfd arch. */
+ const struct bfd_arch_info *b
+ = gdbarch_bfd_arch_info (current_inferior ()->arch ());
+ if (!b->compatible (b, bfd_get_arch_info (abfd)))
+ error (_("`%s': Shared library architecture %s is not compatible "
+ "with target architecture %s."),
+ bfd_get_filename (abfd),
+ bfd_get_arch_info (abfd)->printable_name,
+ b->printable_name);
+}
+
/* Find shared library PATHNAME and open a BFD for it. */

gdb_bfd_ref_ptr
solib_bfd_open (const char *pathname)
{
int found_file;
- const struct bfd_arch_info *b;

/* Search for shared library file. */
gdb::unique_xmalloc_ptr<char> found_pathname
@@ -452,18 +473,25 @@ solib_bfd_open (const char *pathname)
/* Open bfd for shared library. */
gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname.get (), found_file));

- /* Check bfd format. */
- if (!bfd_check_format (abfd.get (), bfd_object))
- error (_ ("`%s': not in executable format: %s"),
- bfd_get_filename (abfd.get ()), bfd_errmsg (bfd_get_error ()));
+ solib_bfd_init (abfd.get ());

- /* Check bfd arch. */
- b = gdbarch_bfd_arch_info (current_inferior ()->arch ());
- if (!b->compatible (b, bfd_get_arch_info (abfd.get ())))
- error (_ ("`%s': Shared library architecture %s is not compatible "
- "with target architecture %s."),
- bfd_get_filename (abfd.get ()),
- bfd_get_arch_info (abfd.get ())->printable_name, b->printable_name);
+ return abfd;
+}
+
+/* See solist.h. */
+
+gdb_bfd_ref_ptr
+solib_bfd_open_from_target_memory (CORE_ADDR begin, CORE_ADDR size,
+ const char *target)
+{
+ /* Open bfd for shared library. */
+ gdb_bfd_ref_ptr abfd
+ = gdb_bfd_open_from_target_memory (begin, size, target);
+ if (abfd == nullptr)
+ error (_("Could not open file from target '%s' "
+ "at address %s with size %s."), target,
+ core_addr_to_string_nz (begin), core_addr_to_string_nz (size));
+ solib_bfd_init (abfd.get ());

return abfd;
}
diff --git a/gdb/solist.h b/gdb/solist.h
index f64e45d874f68c644d1c5b6b182c7667319b6fad..4c30f4aaf9a23fd150c488ad390028ed410982e5 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -214,6 +214,11 @@ extern gdb_bfd_ref_ptr solib_bfd_fopen (const char *pathname, int fd);
/* Find solib binary file and open it. */
extern gdb_bfd_ref_ptr solib_bfd_open (const char *in_pathname);

+/* Open an in-memory binary file. */
+extern gdb_bfd_ref_ptr solib_bfd_open_from_target_memory (CORE_ADDR begin,
+ CORE_ADDR size,
+ const char *target);
+
/* A default implementation of the solib_ops::find_solib_addr callback.
This just returns an empty std::optional<CORE_ADDR> indicating GDB is
unable to find an address within the library SO. */