aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/core.c18
-rw-r--r--gdb/solib.c98
-rw-r--r--gdb/tm-sunos.h5
4 files changed, 127 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 595a653..37789a0 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/core.c b/gdb/core.c
index 4f3c617..04192df 100644
--- a/gdb/core.c
+++ b/gdb/core.c
@@ -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;
}
/* Get the registers out of a core file. This is the machine-
diff --git a/gdb/solib.c b/gdb/solib.c
index 1730b65..def9fd6 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -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;
diff --git a/gdb/tm-sunos.h b/gdb/tm-sunos.h
index f33e352..1de9b99 100644
--- a/gdb/tm-sunos.h
+++ b/gdb/tm-sunos.h
@@ -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 ();