aboutsummaryrefslogtreecommitdiff
path: root/gdb/solib.c
diff options
context:
space:
mode:
authorDavid Taylor <taylor@redhat.com>1998-01-30 20:33:43 +0000
committerDavid Taylor <taylor@redhat.com>1998-01-30 20:33:43 +0000
commit7d0a3fc844cdaea1e8c164cefc35f912c11e845a (patch)
tree2bc52d5db8fe9e58a72b2d3be06cf1568be7ca3a /gdb/solib.c
parentcd9a4eec4909803230a07b939087e64a24cb5fee (diff)
downloadgdb-7d0a3fc844cdaea1e8c164cefc35f912c11e845a.zip
gdb-7d0a3fc844cdaea1e8c164cefc35f912c11e845a.tar.gz
gdb-7d0a3fc844cdaea1e8c164cefc35f912c11e845a.tar.bz2
Changes by Peter.Schauer to fix gdb/13521 -- gdb step command fails to step
from a function in one dynamically linked library into a function in another dynamically linked library.
Diffstat (limited to 'gdb/solib.c')
-rw-r--r--gdb/solib.c102
1 files changed, 95 insertions, 7 deletions
diff --git a/gdb/solib.c b/gdb/solib.c
index b8fffd7..b09b140 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1,5 +1,5 @@
/* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -70,6 +70,7 @@ static char *solib_break_names[] = {
"r_debug_state",
"_r_debug_state",
"_dl_debug_state",
+ "rtld_db_dlactivity",
NULL
};
#endif
@@ -148,12 +149,20 @@ static struct so_list *so_list_head; /* List of known shared objects */
static CORE_ADDR debug_base; /* Base of dynamic linker structures */
static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
+static int solib_cleanup_queued = 0; /* make_run_cleanup called */
+
extern int
fdmatch PARAMS ((int, int)); /* In libiberty */
/* Local function prototypes */
static void
+do_clear_solib PARAMS ((PTR));
+
+static int
+match_main PARAMS ((char *));
+
+static void
special_symbol_handling PARAMS ((struct so_list *));
static void
@@ -936,6 +945,13 @@ find_solib (so_list_ptr)
else
{
so_list_head = new;
+
+ if (! solib_cleanup_queued)
+ {
+ make_run_cleanup (do_clear_solib);
+ solib_cleanup_queued = 1;
+ }
+
}
so_list_next = new;
read_memory ((CORE_ADDR) lm, (char *) &(new -> lm),
@@ -970,12 +986,34 @@ symbol_add_stub (arg)
char *arg;
{
register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
+ CORE_ADDR text_addr = 0;
+
+ if (so -> textsection)
+ text_addr = so -> textsection -> addr;
+ else
+ {
+ asection *lowest_sect;
+
+ /* If we didn't find a mapped non zero sized .text section, set up
+ text_addr so that the relocation in symbol_file_add does no harm. */
+
+ 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);
+ if (lowest_sect)
+ text_addr = bfd_section_vma (so -> abfd, lowest_sect)
+ + (CORE_ADDR) LM_ADDR (so);
+ }
+ ALL_OBJFILES (so -> objfile)
+ {
+ if (strcmp (so -> objfile -> name, so -> so_name) == 0)
+ return 1;
+ }
so -> objfile =
symbol_file_add (so -> so_name, so -> from_tty,
- (so->textsection == NULL
- ? 0
- : (unsigned int) so -> textsection -> addr),
+ text_addr,
0, 0, 0);
return (1);
}
@@ -1262,6 +1300,34 @@ clear_solib()
debug_base = 0;
}
+static void
+do_clear_solib (dummy)
+ PTR dummy;
+{
+ solib_cleanup_queued = 0;
+ clear_solib ();
+}
+
+#ifdef SVR4_SHARED_LIBS
+
+/* Return 1 if PC lies in the dynamic symbol resolution code of the
+ SVR4 run time loader. */
+
+static CORE_ADDR interp_text_sect_low;
+static CORE_ADDR interp_text_sect_high;
+static CORE_ADDR interp_plt_sect_low;
+static CORE_ADDR interp_plt_sect_high;
+
+int
+in_svr4_dynsym_resolve_code (pc)
+ CORE_ADDR pc;
+{
+ return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
+ || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
+ || in_plt_section (pc, NULL));
+}
+#endif
+
/*
LOCAL FUNCTION
@@ -1422,6 +1488,9 @@ enable_break ()
remove_solib_event_breakpoints ();
#ifdef SVR4_SHARED_LIBS
+ interp_text_sect_low = interp_text_sect_high = 0;
+ interp_plt_sect_low = interp_plt_sect_high = 0;
+
/* Find the .interp section; if not found, warn the user and drop
into the old breakpoint at symbol code. */
interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
@@ -1465,6 +1534,25 @@ enable_break ()
linker) and subtracting the offset of the entry point. */
load_addr = read_pc () - tmp_bfd->start_address;
+ /* Record the relocated start and end address of the dynamic linker
+ text and plt section for in_svr4_dynsym_resolve_code. */
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
+ if (interp_sect)
+ {
+ interp_text_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_text_sect_high =
+ interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
+ if (interp_sect)
+ {
+ interp_plt_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_plt_sect_high =
+ interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+
/* Now try to set a breakpoint in the dynamic linker. */
for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
{
@@ -1506,7 +1594,7 @@ bkpt_at_symbol:
}
/* Nothing good happened. */
- return 0;
+ success = 0;
#endif /* BKPT_AT_SYMBOL */
@@ -1747,14 +1835,14 @@ must be loaded manually, using `sharedlibrary'.",
add_show_from_set
(add_set_cmd ("solib-absolute-prefix", class_support, var_filename,
(char *) &solib_absolute_prefix,
- "Set prefix for loading absolute shared library symbol files.\n
+ "Set prefix for loading absolute shared library symbol files.\n\
For other (relative) files, you can add values using `set solib-search-path'.",
&setlist),
&showlist);
add_show_from_set
(add_set_cmd ("solib-search-path", class_support, var_string,
(char *) &solib_search_path,
- "Set the search path for loading non-absolute shared library symbol files.\n
+ "Set the search path for loading non-absolute shared library symbol files.\n\
This takes precedence over the environment variables PATH and LD_LIBRARY_PATH.",
&setlist),
&showlist);