This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFC] solib for darwin
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gingold at adacore dot com (Tristan Gingold)
- Cc: gdb-patches at sourceware dot org
- Date: Sun, 14 Dec 2008 18:37:56 +0100 (CET)
- Subject: Re: [RFC] solib for darwin
Tristan Gingold wrote:
> > Maybe you can have a look at my patch:
> > http://sourceware.org/ml/gdb-patches/2008-09/msg00136.html
> > and see whether this would solve your problem as well (or if we can
> > come up with a joint approach to solve both problems).
>
> Ulrich,
>
> do you have any plan to commit this patch ? As I could base my patch
> on it, that would be useful to continue the Darwin port integration.
Sorry for the late reply. Thinking about it some more, I'd prefer to
use something along your OBJF_KEEPBFD flag; I agree it doesn't really
make sense to open a second BFD.
The following patch combines the ops->bfd_open callback I need for
the Cell debugger with the OBJF_KEEPBFD, and also extracts the bulk
of the solib_bfd_open functionality into subroutines that might be
re-used by target-specific implementations.
Can you verify that this would also allow a Darwin implementation?
Bye,
Ulrich
ChangeLog:
* solist.h (struct target_so_ops): New member bfd_open.
(solib_find): Add prototype.
(solib_bfd_fopen): Add prototype.
* solib.c (solib_find, solib_bfd_fopen): New functions, extracted
from solib_bfd_open.
(solib_bfd_open): Use ops->bfd_open override if present. Call
solib_find and solib_bfd_open otherwise.
* objfiles.h (OBJF_KEEPBFD): New define.
* objfiles.c (free_objfile): Do not close BFD if OBJF_KEEPBFD
objfile flag is set.
* solib.c (symbol_add_stub): Do not allocate second BFD for
shared library; use OBJF_KEEPBFD flag on solib objfile.
diff -urNp gdb-orig/gdb/objfiles.c gdb-head/gdb/objfiles.c
--- gdb-orig/gdb/objfiles.c 2008-12-06 20:28:59.000000000 +0100
+++ gdb-head/gdb/objfiles.c 2008-12-14 17:52:16.000000000 +0100
@@ -424,7 +424,7 @@ free_objfile (struct objfile *objfile)
/* We always close the bfd. */
- if (objfile->obfd != NULL)
+ if (objfile->obfd != NULL && !(objfile->flags & OBJF_KEEPBFD))
{
char *name = bfd_get_filename (objfile->obfd);
if (!bfd_close (objfile->obfd))
diff -urNp gdb-orig/gdb/objfiles.h gdb-head/gdb/objfiles.h
--- gdb-orig/gdb/objfiles.h 2008-12-06 20:28:59.000000000 +0100
+++ gdb-head/gdb/objfiles.h 2008-12-14 17:52:16.000000000 +0100
@@ -414,6 +414,12 @@ struct objfile
#define OBJF_USERLOADED (1 << 3) /* User loaded */
+/* The bfd of this objfile is used outside of the objfile (eg by solib).
+ Do not try to free it. */
+
+#define OBJF_KEEPBFD (1 << 4) /* Do not delete bfd */
+
+
/* The object file that the main symbol table was loaded from (e.g. the
argument to the "symbol-file" or "file" command). */
diff -urNp gdb-orig/gdb/solib.c gdb-head/gdb/solib.c
--- gdb-orig/gdb/solib.c 2008-12-06 20:28:59.000000000 +0100
+++ gdb-head/gdb/solib.c 2008-12-14 18:23:14.000000000 +0100
@@ -107,11 +107,11 @@ The search path for loading non-absolute
GLOBAL FUNCTION
- solib_bfd_open -- Find a shared library file and open BFD for it.
+ solib_find -- Find a shared library file.
SYNOPSIS
- struct bfd *solib_open (char *in_pathname);
+ char *solib_find (char *in_pathname, int *fd);
DESCRIPTION
@@ -138,17 +138,17 @@ The search path for loading non-absolute
RETURNS
- BFD file handle for opened solib; throws error on failure. */
+ Full pathname of the shared library file, or NULL if not found.
+ (The pathname is malloc'ed; it needs to be freed by the caller.)
+ *FD is set to either -1 or an open file handle for the library. */
-bfd *
-solib_bfd_open (char *in_pathname)
+char *
+solib_find (char *in_pathname, int *fd)
{
struct target_so_ops *ops = solib_ops (target_gdbarch);
int found_file = -1;
char *temp_pathname = NULL;
- char *p = in_pathname;
int gdb_sysroot_is_empty;
- bfd *abfd;
gdb_sysroot_is_empty = (gdb_sysroot == NULL || *gdb_sysroot == 0);
@@ -173,24 +173,8 @@ solib_bfd_open (char *in_pathname)
/* Handle remote files. */
if (remote_filename_p (temp_pathname))
{
- temp_pathname = xstrdup (temp_pathname);
- abfd = remote_bfd_open (temp_pathname, gnutarget);
- if (!abfd)
- {
- make_cleanup (xfree, temp_pathname);
- error (_("Could not open `%s' as an executable file: %s"),
- temp_pathname, bfd_errmsg (bfd_get_error ()));
- }
-
- if (!bfd_check_format (abfd, bfd_object))
- {
- bfd_close (abfd);
- make_cleanup (xfree, temp_pathname);
- error (_("`%s': not in executable format: %s"),
- temp_pathname, bfd_errmsg (bfd_get_error ()));
- }
-
- return abfd;
+ *fd = -1;
+ return xstrdup (temp_pathname);
}
/* Now see if we can open it. */
@@ -253,29 +237,79 @@ solib_bfd_open (char *in_pathname)
OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0,
&temp_pathname);
- /* Done. If still not found, error. */
- if (found_file < 0)
- perror_with_name (in_pathname);
+ *fd = found_file;
+ return temp_pathname;
+}
+
+/* Open and return a BFD for the shared library PATHNAME. If FD is not -1,
+ it is used as file handle to open the file. Throws an error if the file
+ could not be opened. Handles both local and remote file access.
+
+ PATHNAME must be malloc'ed by the caller. If successful, the new BFD's
+ name will point to it. If unsuccessful, PATHNAME will be freed and the
+ FD will be closed (unless FD was -1). */
+
+bfd *
+solib_bfd_fopen (char *pathname, int fd)
+{
+ bfd *abfd;
+
+ if (remote_filename_p (pathname))
+ {
+ gdb_assert (fd == -1);
+ abfd = remote_bfd_open (pathname, gnutarget);
+ }
+ else
+ {
+ abfd = bfd_fopen (pathname, gnutarget, FOPEN_RB, fd);
+
+ if (abfd)
+ bfd_set_cacheable (abfd, 1);
+ else if (fd != -1)
+ close (fd);
+ }
- /* Leave temp_pathname allocated. abfd->name will point to it. */
- abfd = bfd_fopen (temp_pathname, gnutarget, FOPEN_RB, found_file);
if (!abfd)
{
- close (found_file);
- make_cleanup (xfree, temp_pathname);
+ make_cleanup (xfree, pathname);
error (_("Could not open `%s' as an executable file: %s"),
- temp_pathname, bfd_errmsg (bfd_get_error ()));
+ pathname, bfd_errmsg (bfd_get_error ()));
}
+ return abfd;
+}
+
+/* Find shared library PATHNAME and open a BFD for it. */
+
+bfd *
+solib_bfd_open (char *pathname)
+{
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
+ char *found_pathname;
+ int found_file;
+ bfd *abfd;
+
+ /* Use target-specific override if present. */
+ if (ops->bfd_open)
+ return ops->bfd_open (pathname);
+
+ /* Search for shared library file. */
+ found_pathname = solib_find (pathname, &found_file);
+ if (found_pathname == NULL)
+ perror_with_name (pathname);
+
+ /* Open bfd for shared library. */
+ abfd = solib_bfd_fopen (found_pathname, found_file);
+
+ /* Check bfd format. */
if (!bfd_check_format (abfd, bfd_object))
{
bfd_close (abfd);
- make_cleanup (xfree, temp_pathname);
+ make_cleanup (xfree, found_pathname);
error (_("`%s': not in executable format: %s"),
- temp_pathname, bfd_errmsg (bfd_get_error ()));
+ found_pathname, bfd_errmsg (bfd_get_error ()));
}
- bfd_set_cacheable (abfd, 1);
return abfd;
}
@@ -432,8 +466,8 @@ symbol_add_stub (void *arg)
sap = build_section_addr_info_from_section_table (so->sections,
so->sections_end);
- so->objfile = symbol_file_add (so->so_name, so->from_tty,
- sap, 0, OBJF_SHARED);
+ so->objfile = symbol_file_add_from_bfd (so->abfd, so->from_tty,
+ sap, 0, OBJF_SHARED | OBJF_KEEPBFD);
free_section_addr_info (sap);
return (1);
diff -urNp gdb-orig/gdb/solist.h gdb-head/gdb/solist.h
--- gdb-orig/gdb/solist.h 2008-12-06 20:28:59.000000000 +0100
+++ gdb-head/gdb/solist.h 2008-12-14 17:52:16.000000000 +0100
@@ -103,6 +103,9 @@ struct target_so_ops
the run time loader */
int (*in_dynsym_resolve_code) (CORE_ADDR pc);
+ /* Find and open shared library binary file. */
+ bfd *(*bfd_open) (char *pathname);
+
/* Extra hook for finding and opening a solib.
Convenience function for remote debuggers finding host libs. */
int (*find_and_open_solib) (char *soname,
@@ -126,6 +129,12 @@ void free_so (struct so_list *so);
/* Return address of first so_list entry in master shared object list. */
struct so_list *master_so_list (void);
+/* Find shared library binary file. */
+extern char *solib_find (char *in_pathname, int *fd);
+
+/* Open BFD for shared library file. */
+extern bfd *solib_bfd_fopen (char *pathname, int fd);
+
/* Find solib binary file and open it. */
extern bfd *solib_bfd_open (char *in_pathname);
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com