Don't emit symbols seen only in dynamic object, don't read duplicate
[deliverable/binutils-gdb.git] / gdb / solib.c
index 1368227c638740dfd81949939b480a83e5198fec..215d82bcbc9b3d82e600e2cf49922aa835336f76 100644 (file)
@@ -1,7 +1,7 @@
 /* Handle shared libraries for GDB, the GNU Debugger.
 
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2005
+   1999, 2000, 2001, 2002, 2003, 2005, 2006
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -146,34 +146,32 @@ solib_open (char *in_pathname, char **found_pathname)
   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 | O_BINARY, 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.)
@@ -208,14 +206,14 @@ solib_open (char *in_pathname, char **found_pathname)
                                           &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 | 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 | O_BINARY, 0,
                        &temp_pathname);
@@ -418,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,
@@ -606,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
 
@@ -652,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;
        }
 
This page took 0.025593 seconds and 4 git commands to generate.