Don't emit symbols seen only in dynamic object, don't read duplicate
[deliverable/binutils-gdb.git] / gdb / solib.c
index dd5af4d7bf9421faae637c3275f4b741a9beec03..215d82bcbc9b3d82e600e2cf49922aa835336f76 100644 (file)
@@ -1,7 +1,7 @@
 /* Handle shared libraries for GDB, the GNU Debugger.
 
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2005
+   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002, 2003, 2005, 2006
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -18,8 +18,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 
 #include "observer.h"
 #include "readline/readline.h"
 
+/* Architecture-specific operations.  */
+
+/* Per-architecture data key.  */
+static struct gdbarch_data *solib_data;
+
+static void *
+solib_init (struct obstack *obstack)
+{
+  struct target_so_ops **ops;
+
+  ops = OBSTACK_ZALLOC (obstack, struct target_so_ops *);
+  *ops = current_target_so_ops;
+  return ops;
+}
+
+static struct target_so_ops *
+solib_ops (struct gdbarch *gdbarch)
+{
+  struct target_so_ops **ops = gdbarch_data (gdbarch, solib_data);
+  return *ops;
+}
+\f
+
 /* external data declarations */
 
 /* FIXME: gdbarch needs to control this variable */
@@ -119,37 +142,36 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
 int
 solib_open (char *in_pathname, char **found_pathname)
 {
+  struct target_so_ops *ops = solib_ops (current_gdbarch);
   int found_file = -1;
   char *temp_pathname = NULL;
   char *p = in_pathname;
+  int solib_absolute_prefix_is_empty;
 
-  while (*p && !IS_DIR_SEPARATOR (*p))
-    p++;
+  solib_absolute_prefix_is_empty = (solib_absolute_prefix == NULL
+                                    || *solib_absolute_prefix == 0);
 
-  if (*p)
+  if (! IS_ABSOLUTE_PATH (in_pathname) || solib_absolute_prefix_is_empty)
+    temp_pathname = in_pathname;
+  else
     {
-      if (! IS_ABSOLUTE_PATH (in_pathname) || solib_absolute_prefix == NULL)
-        temp_pathname = in_pathname;
-      else
-       {
-         int prefix_len = strlen (solib_absolute_prefix);
-
-         /* Remove trailing slashes from absolute prefix.  */
-         while (prefix_len > 0
-                && IS_DIR_SEPARATOR (solib_absolute_prefix[prefix_len - 1]))
-           prefix_len--;
-
-         /* Cat the prefixed pathname together.  */
-         temp_pathname = alloca (prefix_len + strlen (in_pathname) + 1);
-         strncpy (temp_pathname, solib_absolute_prefix, prefix_len);
-         temp_pathname[prefix_len] = '\0';
-         strcat (temp_pathname, in_pathname);
-       }
-
-      /* Now see if we can open it.  */
-      found_file = open (temp_pathname, O_RDONLY, 0);
+      int prefix_len = strlen (solib_absolute_prefix);
+
+      /* Remove trailing slashes from absolute prefix.  */
+      while (prefix_len > 0
+            && IS_DIR_SEPARATOR (solib_absolute_prefix[prefix_len - 1]))
+       prefix_len--;
+
+      /* Cat the prefixed pathname together.  */
+      temp_pathname = alloca (prefix_len + strlen (in_pathname) + 1);
+      strncpy (temp_pathname, solib_absolute_prefix, prefix_len);
+      temp_pathname[prefix_len] = '\0';
+      strcat (temp_pathname, in_pathname);
     }
 
+  /* Now see if we can open it.  */
+  found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
+
   /* If the search in solib_absolute_prefix failed, and the path name is
      absolute at this point, make it relative.  (openp will try and open the
      file according to its absolute path otherwise, which is not what we want.)
@@ -168,32 +190,32 @@ solib_open (char *in_pathname, char **found_pathname)
   /* If not found, search the solib_search_path (if any).  */
   if (found_file < 0 && solib_search_path != NULL)
     found_file = openp (solib_search_path, OPF_TRY_CWD_FIRST,
-                       in_pathname, O_RDONLY, 0, &temp_pathname);
+                       in_pathname, O_RDONLY | O_BINARY, 0, &temp_pathname);
   
   /* If not found, next search the solib_search_path (if any) for the basename
      only (ignoring the path).  This is to allow reading solibs from a path
      that differs from the opened path.  */
   if (found_file < 0 && solib_search_path != NULL)
     found_file = openp (solib_search_path, OPF_TRY_CWD_FIRST,
-                        lbasename (in_pathname), O_RDONLY, 0,
+                        lbasename (in_pathname), O_RDONLY | O_BINARY, 0,
                         &temp_pathname);
 
   /* If not found, try to use target supplied solib search method */
-  if (found_file < 0 && TARGET_SO_FIND_AND_OPEN_SOLIB != NULL)
-    found_file = TARGET_SO_FIND_AND_OPEN_SOLIB
-                 (in_pathname, O_RDONLY, &temp_pathname);
+  if (found_file < 0 && ops->find_and_open_solib)
+    found_file = ops->find_and_open_solib (in_pathname, O_RDONLY | O_BINARY,
+                                          &temp_pathname);
 
   /* If not found, next search the inferior's $PATH environment variable. */
-  if (found_file < 0 && solib_absolute_prefix == NULL)
+  if (found_file < 0 && solib_absolute_prefix_is_empty)
     found_file = openp (get_in_environ (inferior_environ, "PATH"),
-                       OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY, 0,
+                       OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0,
                        &temp_pathname);
 
   /* If not found, next search the inferior's $LD_LIBRARY_PATH 
      environment variable. */
-  if (found_file < 0 && solib_absolute_prefix == NULL)
+  if (found_file < 0 && solib_absolute_prefix_is_empty)
     found_file = openp (get_in_environ (inferior_environ, "LD_LIBRARY_PATH"),
-                       OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY, 0,
+                       OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0,
                        &temp_pathname);
 
   /* Done.  If not found, tough luck.  Return found_file and 
@@ -253,7 +275,7 @@ solib_map_sections (void *arg)
     }
 
   /* Leave scratch_pathname allocated.  abfd->name will point to it.  */
-  abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
+  abfd = bfd_fopen (scratch_pathname, gnutarget, FOPEN_RB, scratch_chan);
   if (!abfd)
     {
       close (scratch_chan);
@@ -284,10 +306,12 @@ solib_map_sections (void *arg)
 
   for (p = so->sections; p < so->sections_end; p++)
     {
+      struct target_so_ops *ops = solib_ops (current_gdbarch);
+
       /* Relocate the section binding addresses as recorded in the shared
          object's file by the base address to which the object was actually
          mapped. */
-      TARGET_SO_RELOCATE_SECTION_ADDRESSES (so, p);
+      ops->relocate_section_addresses (so, p);
       if (strcmp (p->the_bfd_section->name, ".text") == 0)
        {
          so->textsection = p;
@@ -324,6 +348,7 @@ solib_map_sections (void *arg)
 void
 free_so (struct so_list *so)
 {
+  struct target_so_ops *ops = solib_ops (current_gdbarch);
   char *bfd_filename = 0;
 
   if (so->sections)
@@ -340,7 +365,7 @@ free_so (struct so_list *so)
   if (bfd_filename)
     xfree (bfd_filename);
 
-  TARGET_SO_FREE_SO (so);
+  ops->free_so (so);
 
   xfree (so);
 }
@@ -391,6 +416,11 @@ solib_read_symbols (struct so_list *so, int from_tty)
       if (from_tty)
        printf_unfiltered (_("Symbols already loaded for %s\n"), so->so_name);
     }
+  else if (so->abfd == NULL)
+    {
+      if (from_tty)
+       printf_unfiltered (_("Symbol file not found for %s\n"), so->so_name);
+    }
   else
     {
       if (catch_errors (symbol_add_stub, so,
@@ -439,7 +469,8 @@ solib_read_symbols (struct so_list *so, int from_tty)
 static void
 update_solib_list (int from_tty, struct target_ops *target)
 {
-  struct so_list *inferior = TARGET_SO_CURRENT_SOS ();
+  struct target_so_ops *ops = solib_ops (current_gdbarch);
+  struct so_list *inferior = ops->current_sos();
   struct so_list *gdb, **gdb_link;
 
   /* If we are attaching to a running process for which we 
@@ -447,7 +478,7 @@ update_solib_list (int from_tty, struct target_ops *target)
      symbols now!  */
   if (attach_flag &&
       symfile_objfile == NULL)
-    catch_errors (TARGET_SO_OPEN_SYMBOL_FILE_OBJECT, &from_tty, 
+    catch_errors (ops->open_symbol_file_object, &from_tty, 
                  "Error reading attached process's symbol file.\n",
                  RETURN_MASK_ALL);
 
@@ -578,6 +609,17 @@ update_solib_list (int from_tty, struct target_ops *target)
     }
 }
 
+/* Return non-zero if SO is the libpthread shared library.
+
+   Uses a fairly simplistic heuristic approach where we check
+   the file name against "/libpthread".  This can lead to false
+   positives, but this should be good enough in practice.  */
+
+static int
+libpthread_solib_p (struct so_list *so)
+{
+  return (strstr (so->so_name, "/libpthread") != NULL);
+}
 
 /* GLOBAL FUNCTION
 
@@ -624,8 +666,16 @@ solib_add (char *pattern, int from_tty, struct target_ops *target, int readsyms)
     for (gdb = so_list_head; gdb; gdb = gdb->next)
       if (! pattern || re_exec (gdb->so_name))
        {
+          /* Normally, we would read the symbols from that library
+             only if READSYMS is set.  However, we're making a small
+             exception for the pthread library, because we sometimes
+             need the library symbols to be loaded in order to provide
+             thread support (x86-linux for instance).  */
+          const int add_this_solib =
+            (readsyms || libpthread_solib_p (gdb));
+
          any_matches = 1;
-         if (readsyms && solib_read_symbols (gdb, from_tty))
+         if (add_this_solib && solib_read_symbols (gdb, from_tty))
            loaded_any_symbols = 1;
        }
 
@@ -635,11 +685,13 @@ solib_add (char *pattern, int from_tty, struct target_ops *target, int readsyms)
 
     if (loaded_any_symbols)
       {
+       struct target_so_ops *ops = solib_ops (current_gdbarch);
+
        /* Getting new symbols may change our opinion about what is
           frameless.  */
        reinit_frame_cache ();
 
-       TARGET_SO_SPECIAL_SYMBOL_HANDLING ();
+       ops->special_symbol_handling ();
       }
   }
 }
@@ -668,16 +720,8 @@ info_sharedlibrary_command (char *ignore, int from_tty)
   int header_done = 0;
   int addr_width;
 
-  if (TARGET_PTR_BIT == 32)
-    addr_width = 8 + 4;
-  else if (TARGET_PTR_BIT == 64)
-    addr_width = 16 + 4;
-  else
-    {
-      internal_error (__FILE__, __LINE__,
-                     _("TARGET_PTR_BIT returned unknown size %d"),
-                     TARGET_PTR_BIT);
-    }
+  /* "0x", a little whitespace, and two hex digits per byte of pointers.  */
+  addr_width = 4 + (TARGET_PTR_BIT / 4);
 
   update_solib_list (from_tty, 0);
 
@@ -760,6 +804,8 @@ solib_address (CORE_ADDR address)
 void
 clear_solib (void)
 {
+  struct target_so_ops *ops = solib_ops (current_gdbarch);
+
   /* This function is expected to handle ELF shared libraries.  It is
      also used on Solaris, which can run either ELF or a.out binaries
      (for compatibility with SunOS 4), both of which can use shared
@@ -793,7 +839,7 @@ clear_solib (void)
       free_so (so);
     }
 
-  TARGET_SO_CLEAR_SOLIB ();
+  ops->clear_solib ();
 }
 
 static void
@@ -821,7 +867,8 @@ do_clear_solib (void *dummy)
 void
 solib_create_inferior_hook (void)
 {
-  TARGET_SO_SOLIB_CREATE_INFERIOR_HOOK ();
+  struct target_so_ops *ops = solib_ops (current_gdbarch);
+  ops->solib_create_inferior_hook();
 }
 
 /* GLOBAL FUNCTION
@@ -843,7 +890,8 @@ solib_create_inferior_hook (void)
 int
 in_solib_dynsym_resolve_code (CORE_ADDR pc)
 {
-  return TARGET_SO_IN_DYNSYM_RESOLVE_CODE (pc);
+  struct target_so_ops *ops = solib_ops (current_gdbarch);
+  return ops->in_dynsym_resolve_code (pc);
 }
 
 /*
@@ -910,6 +958,8 @@ _initialize_solib (void)
 {
   struct cmd_list_element *c;
 
+  solib_data = gdbarch_data_register_pre_init (solib_init);
+
   add_com ("sharedlibrary", class_files, sharedlibrary_command,
           _("Load shared object library symbols for files matching REGEXP."));
   add_info ("sharedlibrary", info_sharedlibrary_command,
This page took 0.048864 seconds and 4 git commands to generate.