This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]