* emultempl/armelf.em (elf32_arm_add_stub_section): Use
[deliverable/binutils-gdb.git] / gdb / solib-svr4.c
index c71f26b75783ba0542b62c86ac504c60158953f7..70e880266600adacaa221350bc6a6a8442cd09d7 100644 (file)
@@ -61,6 +61,9 @@ struct lm_info
        address changes, we may need a different offset, we want to
        warn about the difference and compute it only once.  */
     CORE_ADDR l_addr;
+
+    /* The target location of lm.  */
+    CORE_ADDR lm_addr;
   };
 
 /* On SVR4 systems, a list of symbols in the dynamic linker where
@@ -103,6 +106,40 @@ static char *main_name_list[] =
   NULL
 };
 
+/* Return non-zero if GDB_SO_NAME and INFERIOR_SO_NAME represent
+   the same shared library.  */
+
+static int
+svr4_same_1 (const char *gdb_so_name, const char *inferior_so_name)
+{
+  if (strcmp (gdb_so_name, inferior_so_name) == 0)
+    return 1;
+
+  /* On Solaris, when starting inferior we think that dynamic linker is
+     /usr/lib/ld.so.1, but later on, the table of loaded shared libraries 
+     contains /lib/ld.so.1.  Sometimes one file is a link to another, but 
+     sometimes they have identical content, but are not linked to each
+     other.  We don't restrict this check for Solaris, but the chances
+     of running into this situation elsewhere are very low.  */
+  if (strcmp (gdb_so_name, "/usr/lib/ld.so.1") == 0
+      && strcmp (inferior_so_name, "/lib/ld.so.1") == 0)
+    return 1;
+
+  /* Similarly, we observed the same issue with sparc64, but with
+     different locations.  */
+  if (strcmp (gdb_so_name, "/usr/lib/sparcv9/ld.so.1") == 0
+      && strcmp (inferior_so_name, "/lib/sparcv9/ld.so.1") == 0)
+    return 1;
+
+  return 0;
+}
+
+static int
+svr4_same (struct so_list *gdb, struct so_list *inferior)
+{
+  return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name));
+}
+
 /* link map access functions */
 
 static CORE_ADDR
@@ -244,6 +281,9 @@ static CORE_ADDR debug_loader_offset;
 /* Name of the dynamic linker, valid if debug_loader_offset_p.  */
 static char *debug_loader_name;
 
+/* Load map address for the main executable.  */
+static CORE_ADDR main_lm_addr;
+
 /* Local function prototypes */
 
 static int match_main (char *);
@@ -674,6 +714,7 @@ svr4_default_sos (void)
       /* Nothing will ever check the cached copy of the link
         map if we set l_addr.  */
       new->lm_info->l_addr = debug_loader_offset;
+      new->lm_info->lm_addr = 0;
       new->lm_info->lm = NULL;
 
       strncpy (new->so_name, debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1);
@@ -737,6 +778,7 @@ svr4_current_sos (void)
       make_cleanup (xfree, new->lm_info);
 
       new->lm_info->l_addr = (CORE_ADDR)-1;
+      new->lm_info->lm_addr = lm;
       new->lm_info->lm = xzalloc (lmo->link_map_size);
       make_cleanup (xfree, new->lm_info->lm);
 
@@ -750,7 +792,10 @@ svr4_current_sos (void)
          does have a name, so we can no longer use a missing name to
          decide when to ignore it. */
       if (IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0)
-       free_so (new);
+       {
+         main_lm_addr = new->lm_info->lm_addr;
+         free_so (new);
+       }
       else
        {
          int errcode;
@@ -799,76 +844,28 @@ svr4_current_sos (void)
   return head;
 }
 
-/* Get the address of the link_map for a given OBJFILE.  Loop through
-   the link maps, and return the address of the one corresponding to
-   the given objfile.  Note that this function takes into account that
-   objfile can be the main executable, not just a shared library.  The
-   main executable has always an empty name field in the linkmap.  */
+/* Get the address of the link_map for a given OBJFILE.  */
 
 CORE_ADDR
 svr4_fetch_objfile_link_map (struct objfile *objfile)
 {
-  CORE_ADDR lm;
+  struct so_list *so;
 
-  if (locate_base () == 0)
-    return 0;   /* failed somehow... */
+  /* Cause svr4_current_sos() to be run if it hasn't been already.  */
+  if (main_lm_addr == 0)
+    solib_add (NULL, 0, &current_target, auto_solib_add);
 
-  /* Position ourselves on the first link map.  */
-  lm = solib_svr4_r_map ();  
-  while (lm)
-    {
-      /* Get info on the layout of the r_debug and link_map structures. */
-      struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-      int errcode;
-      char *buffer;
-      struct lm_info objfile_lm_info;
-      struct cleanup *old_chain;
-      CORE_ADDR name_address;
-      int l_name_size = TYPE_LENGTH (builtin_type_void_data_ptr);
-      gdb_byte *l_name_buf = xmalloc (l_name_size);
-      old_chain = make_cleanup (xfree, l_name_buf);
-
-      /* Set up the buffer to contain the portion of the link_map
-         structure that gdb cares about.  Note that this is not the
-         whole link_map structure.  */
-      objfile_lm_info.lm = xzalloc (lmo->link_map_size);
-      make_cleanup (xfree, objfile_lm_info.lm);
-
-      /* Read the link map into our internal structure.  */
-      read_memory (lm, objfile_lm_info.lm, lmo->link_map_size);
-
-      /* Read address of name from target memory to GDB.  */
-      read_memory (lm + lmo->l_name_offset, l_name_buf, l_name_size);
-
-      /* Extract this object's name.  */
-      name_address = extract_typed_address (l_name_buf,
-                                           builtin_type_void_data_ptr);
-      target_read_string (name_address, &buffer,
-                         SO_NAME_MAX_PATH_SIZE - 1, &errcode);
-      make_cleanup (xfree, buffer);
-      if (errcode != 0)
-       warning (_("Can't read pathname for load map: %s."),
-                safe_strerror (errcode));
-      else
-       {
-         /* Is this the linkmap for the file we want?  */
-         /* If the file is not a shared library and has no name,
-            we are sure it is the main executable, so we return that.  */
-
-         if (buffer 
-             && ((strcmp (buffer, objfile->name) == 0)
-                 || (!(objfile->flags & OBJF_SHARED) 
-                     && (strcmp (buffer, "") == 0))))
-           {
-             do_cleanups (old_chain);
-             return lm;
-           }
-       }
-      /* Not the file we wanted, continue checking.  */
-      lm = extract_typed_address (objfile_lm_info.lm + lmo->l_next_offset,
-                                 builtin_type_void_data_ptr);
-      do_cleanups (old_chain);
-    }
+  /* svr4_current_sos() will set main_lm_addr for the main executable.  */
+  if (objfile == symfile_objfile)
+    return main_lm_addr;
+
+  /* The other link map addresses may be found by examining the list
+     of shared libraries.  */
+  for (so = master_so_list (); so; so = so->next)
+    if (so->objfile == objfile)
+      return so->lm_info->lm_addr;
+
+  /* Not found!  */
   return 0;
 }
 
@@ -998,6 +995,11 @@ enable_break (void)
     {
       struct obj_section *os;
 
+      sym_addr = gdbarch_addr_bits_remove
+       (current_gdbarch, gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+                                                             sym_addr,
+                                                             &current_target));
+
       os = find_pc_section (sym_addr);
       if (os != NULL)
        {
@@ -1090,7 +1092,7 @@ enable_break (void)
       so = master_so_list ();
       while (so)
        {
-         if (strcmp (buf, so->so_original_name) == 0)
+         if (svr4_same_1 (buf, so->so_original_name))
            {
              load_addr_found = 1;
              loader_found_in_list = 1;
@@ -1437,6 +1439,7 @@ svr4_clear_solib (void)
   debug_loader_offset = 0;
   xfree (debug_loader_name);
   debug_loader_name = NULL;
+  main_lm_addr = 0;
 }
 
 static void
@@ -1619,33 +1622,14 @@ static struct symbol *
 elf_lookup_lib_symbol (const struct objfile *objfile,
                       const char *name,
                       const char *linkage_name,
-                      const domain_enum domain, struct symtab **symtab)
+                      const domain_enum domain)
 {
   if (objfile->obfd == NULL
      || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1)
     return NULL;
 
   return lookup_global_symbol_from_objfile
-               (objfile, name, linkage_name, domain, symtab);
-}
-
-static int
-svr4_same (struct so_list *gdb, struct so_list *inferior)
-{
-  if (! strcmp (gdb->so_original_name, inferior->so_original_name))
-    return 1;
-
-  /* On Solaris, when starting inferior we think that dynamic linker is
-     /usr/lib/ld.so.1, but later on, the table of loaded shared libraries 
-     contains /lib/ld.so.1.  Sometimes one file is a link to another, but 
-     sometimes they have identical content, but are not linked to each
-     other.  We don't restrict this check for Solaris, but the chances
-     of running into this situation elsewhere are very low.  */
-  if (strcmp (gdb->so_original_name, "/usr/lib/ld.so.1") == 0
-      && strcmp (inferior->so_original_name, "/lib/ld.so.1") == 0)
-    return 1;
-
-  return 0;
+               (objfile, name, linkage_name, domain);
 }
 
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
This page took 0.026937 seconds and 4 git commands to generate.