* Shared libaray/corefile changes from Peter Schauer:
authorJim Kingdon <jkingdon@engr.sgi.com>
Tue, 23 Apr 1991 00:05:24 +0000 (00:05 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Tue, 23 Apr 1991 00:05:24 +0000 (00:05 +0000)
core.c (core_close): Call CLEAR_SOLIB.
(core_open): Remove comment about "should deal with shared lib".
(core_xfer_memory): If we can't xfer the usual way, try the
shared libraries.
solib.c (so_list): New fields so_bfd and so_sections{,_end}.
(find_solib): Use solib_map_sections to get ld_text.
(solib_map_sections, solib_xfer_memory): New functions.
(clear_solib): Free so_sections and close so_bfd.
tm-sunos.h: Add solib_xfer_memory, solib_add.

gdb/ChangeLog
gdb/core.c
gdb/solib.c
gdb/tm-sunos.h

index 595a6538617c59c9203b1610e652b1dfeb786f42..37789a07e88cac3b407b7639eb50907da45ec969 100644 (file)
@@ -1,5 +1,16 @@
 Mon Apr 22 00:02:43 1991  Jim Kingdon  (kingdon at cygint.cygnus.com)
 
+       * Shared libaray/corefile changes from Peter Schauer:
+       core.c (core_close): Call CLEAR_SOLIB.
+       (core_open): Remove comment about "should deal with shared lib".
+       (core_xfer_memory): If we can't xfer the usual way, try the
+       shared libraries.
+       solib.c (so_list): New fields so_bfd and so_sections{,_end}.
+       (find_solib): Use solib_map_sections to get ld_text.
+       (solib_map_sections, solib_xfer_memory): New functions.
+       (clear_solib): Free so_sections and close so_bfd.
+       tm-sunos.h: Add solib_xfer_memory, solib_add.
+
        * sparc-tdep.c (skip_prologue): Don't skip anything unless there
        is a "save" instruction in there somewhere.
 
index 4f3c61797db08007c22e861cb9f8dbef78c804ca..04192df2bd35986a5ff8d09317e4900321ca85e3 100644 (file)
@@ -64,6 +64,9 @@ core_close (quitting)
     free (bfd_get_filename (core_bfd));
     bfd_close (core_bfd);
     core_bfd = NULL;
+#ifdef CLEAR_SOLIB
+    CLEAR_SOLIB ();
+#endif
   }
 }
 
@@ -140,7 +143,12 @@ core_open (filename, from_tty)
     set_current_frame ( create_new_frame (read_register (FP_REGNUM),
                                          read_pc ()));
     select_frame (get_current_frame (), 0);
-    /* FIXME, handle shared library reading here.  */
+#if 0
+    /* Shouldn't be necessary to read in symbols.  */
+#ifdef SOLIB_ADD
+    SOLIB_ADD (NULL, from_tty);
+#endif
+#endif /* 0 */
     print_sel_frame (0);       /* Print the top frame and source line */
   } else {
     printf (
@@ -370,8 +378,14 @@ core_xfer_memory (memaddr, myaddr, len, write)
      int len;
      int write;
 {
-  return xfer_memory (memaddr, myaddr, len, write,
+  int res;
+  res = xfer_memory (memaddr, myaddr, len, write,
                      core_bfd, core_sections, core_sections_end);
+#ifdef SOLIB_XFER_MEMORY
+  if (res == 0)
+    res = SOLIB_XFER_MEMORY (memaddr, myaddr, len, write);
+#endif
+  return res;
 }
 \f
 /* Get the registers out of a core file.  This is the machine-
index 1730b65e1c9464fbc5484c8edb17b9a7a60081b4..def9fd6757e9cc3fbf0fa2734b0f65e5ed3291f3 100644 (file)
@@ -22,6 +22,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <sys/types.h>
 #include <string.h>
 #include <link.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <stdio.h>
 #include "defs.h"
 #include "param.h"
 #include "symtab.h"
@@ -40,10 +43,63 @@ struct so_list {
     char inferior_so_name[MAX_PATH_SIZE];      /* Shared Object Library Name */
     struct so_list *next;                      /* Next Structure */
     int        symbols_loaded;
+    bfd *so_bfd;
+    struct section_table *so_sections;
+    struct section_table *so_sections_end;
 };
 
 static struct so_list *so_list_head = 0;
 
+/*
+** Build a section map for a shared library, record its text size in
+** the so_list structure and set up the text section of the shared lib.
+*/
+static void
+solib_map_sections(so)
+struct so_list *so;
+{
+  char *filename;
+  char *scratch_pathname;
+  int scratch_chan;
+  struct section_table *p;
+  
+  filename = tilde_expand (so->inferior_so_name);
+  make_cleanup (free, filename);
+  
+  scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
+                           &scratch_pathname);
+  if (scratch_chan < 0)
+    scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename, O_RDONLY, 0,
+                           &scratch_pathname);
+  if (scratch_chan < 0)
+       perror_with_name (filename);
+
+  so->so_bfd = bfd_fdopenr (scratch_pathname, NULL, scratch_chan);
+  if (!so->so_bfd)
+    error ("Could not open `%s' as an executable file: %s",
+          scratch_pathname, bfd_errmsg (bfd_error));
+  if (!bfd_check_format (so->so_bfd, bfd_object))
+    error ("\"%s\": not in executable format: %s.",
+          scratch_pathname, bfd_errmsg (bfd_error));
+  if (build_section_table (so->so_bfd, &so->so_sections, &so->so_sections_end))
+    error ("Can't find the file sections in `%s': %s", 
+          exec_bfd->filename, bfd_errmsg (bfd_error));
+
+  for (p = so->so_sections; p < so->so_sections_end; p++)
+    {
+      if (strcmp (bfd_section_name (so->so_bfd, p->sec_ptr), ".text") == 0)
+       {
+         /* Determine length of text section and relocate it. */
+         so->ld_text = p->endaddr - p->addr;
+         p->addr += (CORE_ADDR)so->inferior_lm.lm_addr;
+         p->endaddr += (CORE_ADDR)so->inferior_lm.lm_addr;
+       }
+      else
+       /* All other sections are ignored for now. */
+       p->addr = p->endaddr = 0;
+    }
+}
+
 /*=======================================================================*/
 
 /*     find_solib
@@ -128,6 +184,9 @@ int i;
         /* Zero everything after the first terminating null */
         strncpy(new->inferior_so_name, new->inferior_so_name, MAX_PATH_SIZE);
 
+#if 0
+        /* This doesn't work for core files, so instead get ld_text
+           using solib_map_sections (below).  */
         read_memory((CORE_ADDR)new->inferior_lm.lm_ld,
                     &inferior_dynamic_cpy,
                     sizeof(struct link_dynamic));
@@ -135,26 +194,55 @@ int i;
                     &inferior_ld_2_cpy,
                     sizeof(struct link_dynamic_2));
         new->ld_text = inferior_ld_2_cpy.ld_text;
-    
+#endif
+
         new->next = 0;
         new->symbols_loaded = 0;
+        new->so_bfd = NULL;
+        new->so_sections = NULL;
         if (so_list_ptr)
             so_list_ptr->next = new;
         else
             so_list_head = new;
+
+        solib_map_sections (new);
+
         so_list_next = new;
      }
      return(so_list_next);
 }
+
+/*
+** Called by core_xfer_memory if the transfer form the core file failed.
+** We try to satisfy the request from the text sections of the shared libs.
+*/
+int
+solib_xfer_memory (memaddr, myaddr, len, write)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+     int write;
+{
+  int res;
+  register struct so_list *so = 0;
+
+  while (so = find_solib(so))
+    {
+      res = xfer_memory (memaddr, myaddr, len, write,
+                        so->so_bfd, so->so_sections, so->so_sections_end);
+      if (res)
+       return res;
+    }
+  return 0;
+}
 /*=======================================================================*/
 
-static void solib_add(arg_string, from_tty)
+void solib_add(arg_string, from_tty)
 char *arg_string;
 int from_tty;
 {      
     register struct so_list *so = 0;           /* link map state variable */
     char *val;
-    int sz;
 
     if (arg_string == 0)
        re_comp (".");
@@ -228,6 +316,10 @@ clear_solib()
 struct so_list *next;
 
   while (so_list_head) {
+    if (so_list_head->so_sections)
+      free (so_list_head->so_sections);
+    if (so_list_head->so_bfd)
+      bfd_close (so_list_head->so_bfd);
     next = so_list_head->next;
     free(so_list_head);
     so_list_head = next;
index f33e3520686c8acc94a8b414e57bd16f1d433199..1de9b99f11d12bd95676cb52a25fb35a7130a854 100644 (file)
@@ -19,8 +19,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* This is for SunOS version 4, not for earlier versions.  */
 
 #define CLEAR_SOLIB clear_solib
+#define SOLIB_ADD(filename, from_tty) solib_add (filename, from_tty)
+#define SOLIB_XFER_MEMORY(memaddr, myaddr, len, write) solib_xfer_memory (memaddr, myaddr, len, write)
 
 /* If we can't set a breakpoint, and it's in a shared library, just
    disable it.  */
 #define DISABLE_UNSETTABLE_BREAK(addr) solib_address(addr)
 extern int solib_address ();                   /* solib.c */
+extern int solib_xfer_memory ();
+extern void solib_add ();
+extern void clear_solib ();