Add a symbol's value to the computed frag offset, rather than overwriting it.
[deliverable/binutils-gdb.git] / gdb / solib.c
index 65b35e74fc09ee7cc4004cdb94b0e730472053bf..93eb06611c10d4910abc5a700d449f54ce481f6e 100644 (file)
@@ -31,7 +31,6 @@
 #include "gdb_string.h"
 #include <sys/param.h>
 #include <fcntl.h>
-#include <unistd.h>
 
 #ifndef SVR4_SHARED_LIBS
  /* SunOS shared libs need the nlist structure.  */
@@ -888,6 +887,70 @@ first_link_map_member ()
   return (lm);
 }
 
+#ifdef SVR4_SHARED_LIBS
+/*
+
+  LOCAL FUNCTION
+
+  open_exec_file_object
+
+  SYNOPSIS
+
+  void open_symbol_file_object (int from_tty)
+
+  DESCRIPTION
+
+  If no open symbol file, attempt to locate and open the main symbol
+  file.  On SVR4 systems, this is the first link map entry.  If its
+  name is here, we can open it.  Useful when attaching to a process
+  without first loading its symbol file.
+
+ */
+
+int
+open_symbol_file_object (arg)
+     PTR arg;
+{
+  int from_tty = (int) arg;    /* sneak past catch_errors */
+  struct link_map *lm, lmcopy;
+  char *filename;
+  int errcode;
+
+  if (symfile_objfile)
+    if (!query ("Attempt to reload symbols from process? "))
+      return 0;
+
+  if ((debug_base = locate_base ()) == 0)
+    return 0;  /* failed somehow... */
+
+  /* First link map member should be the executable.  */
+  if ((lm = first_link_map_member ()) == NULL)
+    return 0;  /* failed somehow... */
+
+  /* Read from target memory to GDB.  */
+  read_memory ((CORE_ADDR) lm, (void *) &lmcopy, sizeof (lmcopy));
+
+  if (lmcopy.l_name == 0)
+    return 0;  /* no filename.  */
+
+  /* Now fetch the filename from target memory.  */
+  target_read_string ((CORE_ADDR) lmcopy.l_name, &filename, 
+                     MAX_PATH_SIZE - 1, &errcode);
+  if (errcode)
+    {
+      warning ("failed to read exec filename from attached file: %s",
+              safe_strerror (errcode));
+      return 0;
+    }
+
+  make_cleanup ((make_cleanup_func) free, (void *) filename);
+  /* Have a pathname: read the symbol file.  */
+  symbol_file_command (filename, from_tty);
+
+  return 1;
+}
+#endif /* SVR4_SHARED_LIBS */
+
 /*
 
    LOCAL FUNCTION
@@ -1020,7 +1083,9 @@ symbol_add_stub (arg)
 {
   register struct so_list *so = (struct so_list *) arg;                /* catch_errs bogon */
   CORE_ADDR text_addr = 0;
+  struct section_addr_info section_addrs;
 
+  memset (&section_addrs, 0, sizeof (section_addrs));
   if (so->textsection)
     text_addr = so->textsection->addr;
   else if (so->abfd != NULL)
@@ -1033,7 +1098,7 @@ symbol_add_stub (arg)
       lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
       if (lowest_sect == NULL)
        bfd_map_over_sections (so->abfd, find_lowest_section,
-                              (PTR) & lowest_sect);
+                              (PTR) &lowest_sect);
       if (lowest_sect)
        text_addr = bfd_section_vma (so->abfd, lowest_sect)
          + (CORE_ADDR) LM_ADDR (so);
@@ -1044,10 +1109,10 @@ symbol_add_stub (arg)
     if (strcmp (so->objfile->name, so->so_name) == 0)
       return 1;
   }
+  section_addrs.text_addr = text_addr;
   so->objfile =
     symbol_file_add (so->so_name, so->from_tty,
-                    text_addr,
-                    0, 0, 0, 0, 1);
+                    &section_addrs, 0, OBJF_SHARED);
   return (1);
 }
 
@@ -1099,7 +1164,19 @@ solib_add (arg_string, from_tty, target)
   int count;
   int old;
 
-  if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
+#ifdef SVR4_SHARED_LIBS
+  /* If we are attaching to a running process for which we 
+     have not opened a symbol file, we may be able to get its 
+     symbols now!  */
+  if (attach_flag &&
+      symfile_objfile == NULL)
+    catch_errors (open_symbol_file_object, (PTR) from_tty, 
+                 "Error reading attached process's symbol file.\n",
+                 RETURN_MASK_ALL);
+
+#endif SVR4_SHARED_LIBS
+
+  if ((re_err = re_comp (arg_string? arg_string : ".")) != NULL)
     {
       error ("Invalid regexp: %s", re_err);
     }
@@ -1121,38 +1198,9 @@ solib_add (arg_string, from_tty, target)
 
       if (count)
        {
-         int update_coreops;
-
-         /* We must update the to_sections field in the core_ops structure
-            here, otherwise we dereference a potential dangling pointer
-            for each call to target_read/write_memory within this routine.  */
-         update_coreops = core_ops.to_sections == target->to_sections;
-
-         /* Reallocate the target's section table including the new size.  */
-         if (target->to_sections)
-           {
-             old = target->to_sections_end - target->to_sections;
-             target->to_sections = (struct section_table *)
-               xrealloc ((char *) target->to_sections,
-                         (sizeof (struct section_table)) * (count + old));
-           }
-         else
-           {
-             old = 0;
-             target->to_sections = (struct section_table *)
-               xmalloc ((sizeof (struct section_table)) * count);
-           }
-         target->to_sections_end = target->to_sections + (count + old);
-
-         /* Update the to_sections field in the core_ops structure
-            if needed.  */
-         if (update_coreops)
-           {
-             core_ops.to_sections = target->to_sections;
-             core_ops.to_sections_end = target->to_sections_end;
-           }
-
+         
          /* Add these section table entries to the target's table.  */
+         old = target_resize_to_sections (target, count);
          while ((so = find_solib (so)) != NULL)
            {
              if (so->so_name[0])
@@ -1229,7 +1277,7 @@ info_sharedlibrary_command (ignore, from_tty)
 
   if (exec_bfd == NULL)
     {
-      printf_unfiltered ("No exec file.\n");
+      printf_unfiltered ("No executable file.\n");
       return;
     }
 
This page took 0.02494 seconds and 4 git commands to generate.