* solist.h (struct target_so_ops): New member bfd_open.
authorUlrich Weigand <uweigand@de.ibm.com>
Thu, 15 Jan 2009 16:35:22 +0000 (16:35 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Thu, 15 Jan 2009 16:35:22 +0000 (16:35 +0000)
(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.

gdb/ChangeLog
gdb/objfiles.c
gdb/objfiles.h
gdb/solib.c
gdb/solist.h

index 5a8f5d3d83fabb3b13093f57a98f8c1f4a5ecfa1..25da5e20882431d731da3e90e21bb9aef7118490 100644 (file)
@@ -1,3 +1,20 @@
+2009-01-15  Ulrich Weigand  <uweigand@de.ibm.com>
+           Tristan Gingold  <gingold@adacore.com>
+
+       * 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.
+
 2009-01-15  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * frame.c (get_frame_arch): Abort if called with NULL this_frame.
index c7a85645e9c6d0d8f3dfa706147cd9c8807d4961..bc77de8635f7899665e6402541b93862d9fe76c0 100644 (file)
@@ -422,9 +422,9 @@ free_objfile (struct objfile *objfile)
       (*objfile->sf->sym_finish) (objfile);
     }
 
-  /* We always close the bfd. */
+  /* We always close the bfd, unless the OBJF_KEEPBFD flag is set.  */
 
-  if (objfile->obfd != NULL)
+  if (objfile->obfd != NULL && !(objfile->flags & OBJF_KEEPBFD))
     {
       char *name = bfd_get_filename (objfile->obfd);
       if (!bfd_close (objfile->obfd))
index c90511224c822cd9935ee9f5b5009d5502f31c7b..60d3143eb978a670997079d8f7e984fbcdeda46c 100644 (file)
@@ -414,6 +414,12 @@ struct objfile
 
 #define OBJF_USERLOADED        (1 << 3)        /* User loaded */
 
+/* The bfd of this objfile is used outside of the objfile (e.g. 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).  */
 
index 1a2e70240999abb530878b30658084a75bc11c66..cce4f7f13b634215a289aaa161e92a59e1f45560 100644 (file)
@@ -107,11 +107,11 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
 
    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 shared library symbol files is %s.\n"),
 
    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);
index 9c5b36bf69777783fb4101c62f4c6a74b9251748..64754f34e973f3ce61847b55ea1344dc9d9acdd1 100644 (file)
@@ -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);