aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog27
-rw-r--r--gdb/NEWS13
-rw-r--r--gdb/hppa-tdep.c4
-rw-r--r--gdb/infrun.c86
-rw-r--r--gdb/irix5-nat.c11
-rw-r--r--gdb/minsyms.c52
-rw-r--r--gdb/osfsolib.c11
-rw-r--r--gdb/somsolib.c124
8 files changed, 300 insertions, 28 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 861c03d..a0c947f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,30 @@
+Tue Jan 23 13:08:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * symfile.c (auto_solib_add): Renamed from auto_solib_add_at_startup.
+ All references changed.
+ * breakpoint.c (bpstat_what): Add shlib_event to the class types.
+ Update state table. Reformat so that it's still readable.
+ When we hit the shlib_event breakpoint, set the calss of shlib_event.
+ (breakpoint_1): Add "shlib events" as a breakpoint type.
+ Print the shlib_event breakpoint like other breakpoints.
+ (create_solib_event_breakpoint): New function.
+ (breakpoint_re_set_one): Handle solib_event breakpoints.
+ * breakpoint.h (enum bytype): Add bp_shlib_event breakpoint type.
+ (enum bpstat_what_main_action): Add BPSTAT_WHAT_CHECK_SHLIBS
+ action.
+ (create_solib_event_breakpoint): Declare.
+ * infrun.c (wait_for_inferior): Handle CHECK_SHLIBS bpstat.
+ (normal_stop): Inform the user when the inferior stoped due
+ to a shared library event.
+ (_initialize_infrun): Add new set/show variable "stop_on-solib-events"
+ to control whether or not gdb continues the inferior or stops it when
+ a shared library event occurs.
+ * minsyms.c (lookup_minimal_symbol_solib_trampoline): New function.
+ * somsolib.c (TODO list): Update.
+ (som_solib_create_inferior_hook): Arrange for gdb to be notified
+ when significant shared library events occur.
+ * hppa-tdep.c (find_unwind_entry): No longer static.
+
Tue Jan 23 09:00:48 1996 Doug Evans <dje@charmed.cygnus.com>
* gdbtk.c (gdb_disassemble): Rework disassemble_info initialization.
diff --git a/gdb/NEWS b/gdb/NEWS
index 1d754cd..0867bde 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -19,6 +19,19 @@ The standard remote protocol now includes an option to send a break
rather than a ^C to the target in order to interrupt it. By default,
GDB will send ^C; to send a break, set the variable `remotebreak' to 1.
+* Automatic tracking of dynamic object loading (HPUX only at the moment).
+
+By default GDB will automatically keep track of objects as they are
+loaded and unloaded by the dynamic linker. By using the command
+"set stop-on-solib-events 1" you can arrange for GDB to stop the
+inferior when shared library events occur, thus allowing you to
+set breakpoints in shared libraries which are explicitly loaded by
+the inferior.
+
+Note this feature does not work on hpux8. On hpux9 you must link
+/usr/lib/end.o into your program. This feature should work automatically
+on hpux10.
+
*** Changes in GDB-4.15:
* Psymtabs for XCOFF
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 4fee8b0..544d726 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -1,5 +1,5 @@
/* Target-dependent code for the HP PA architecture, for GDB.
- Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
Free Software Foundation, Inc.
Contributed by the Center for Software Science at the
@@ -487,7 +487,7 @@ read_unwind_info (objfile)
contains a sorted list of struct unwind_table_entry. Since we do a binary
search of the unwind tables, we depend upon them to be sorted. */
-static struct unwind_table_entry *
+struct unwind_table_entry *
find_unwind_entry(pc)
CORE_ADDR pc;
{
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 73647aa..19ff2d3 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1,5 +1,5 @@
/* Target-struct-independent code to start (run) and stop an inferior process.
- Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994
+ Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996
Free Software Foundation, Inc.
This file is part of GDB.
@@ -72,6 +72,21 @@ static int hook_stop_stub PARAMS ((char *));
#define SKIP_TRAMPOLINE_CODE(pc) 0
#endif
+/* Dynamic function trampolines are similar to solib trampolines in that they
+ are between the caller and the callee. The difference is that when you
+ enter a dynamic trampoline, you can't determine the callee's address. Some
+ (usually complex) code needs to run in the dynamic trampoline to figure out
+ the callee's address. This macro is usually called twice. First, when we
+ enter the trampoline (looks like a normal function call at that point). It
+ should return the PC of a point within the trampoline where the callee's
+ address is known. Second, when we hit the breakpoint, this routine returns
+ the callee's address. At that point, things proceed as per a step resume
+ breakpoint. */
+
+#ifndef DYNAMIC_TRAMPOLINE_NEXTPC
+#define DYNAMIC_TRAMPOLINE_NEXTPC(pc) 0
+#endif
+
/* For SVR4 shared libraries, each call goes through a small piece of
trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates
to nonzero if we are current stopped in one of these. */
@@ -136,6 +151,10 @@ static struct symbol *step_start_function;
static int trap_expected;
+/* Nonzero if we want to give control to the user when we're notified
+ of shared library events by the dynamic linker. */
+static int stop_on_solib_events;
+
#ifdef HP_OS_BUG
/* Nonzero if the next time we try to continue the inferior, it will
step one instruction and generate a spurious trace trap.
@@ -1015,6 +1034,35 @@ wait_for_inferior ()
another_trap = 1;
break;
+#ifdef SOLIB_ADD
+ case BPSTAT_WHAT_CHECK_SHLIBS:
+ {
+ extern int auto_solib_add;
+
+ /* Check for any newly added shared libraries if we're
+ supposed to be adding them automatically. */
+ if (auto_solib_add)
+ SOLIB_ADD (NULL, 0, NULL);
+
+ /* If requested, stop when the dynamic linker notifies
+ gdb of events. This allows the user to get control
+ and place breakpoints in initializer routines for
+ dynamically loaded objects (among other things). */
+ if (stop_on_solib_events)
+ {
+ stop_print_frame = 0;
+ goto stop_stepping;
+ }
+ else
+ {
+ /* We want to step over this breakpoint, then keep going. */
+ another_trap = 1;
+ remove_breakpoints_on_following_step = 1;
+ break;
+ }
+ }
+#endif
+
case BPSTAT_WHAT_LAST:
/* Not a real code, but listed here to shut up gcc -Wall. */
@@ -1208,8 +1256,9 @@ wait_for_inferior ()
handling_longjmp stuff is working. */
))
#else
-/* This is experimental code which greatly simplifies the subroutine call
- test. I've actually tested on the Alpha, and it works great. -Stu */
+ /* This test is a much more streamlined, (but hopefully correct)
+ replacement for the code above. It's been tested on the Sparc,
+ Mips, PA, and Power architectures with good results. */
if (stop_pc == stop_func_start /* Quick test */
|| in_prologue (stop_pc, stop_func_start)
@@ -1241,6 +1290,22 @@ wait_for_inferior ()
tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
if (tmp != 0)
stop_func_start = tmp;
+ else
+ {
+ tmp = DYNAMIC_TRAMPOLINE_NEXTPC (stop_pc);
+ if (tmp)
+ {
+ struct symtab_and_line xxx;
+
+ xxx.pc = tmp;
+ xxx.symtab = NULL;
+ xxx.line = 0;
+ step_resume_breakpoint =
+ set_momentary_breakpoint (xxx, NULL, bp_step_resume);
+ insert_breakpoints ();
+ goto keep_going;
+ }
+ }
/* If we have line number information for the function we
are thinking of stepping into, step into it.
@@ -1593,6 +1658,9 @@ Further execution is probably impossible.\n");
target_terminal_ours ();
+ if (stop_bpstat && stop_bpstat->breakpoint_at->type == bp_shlib_event)
+ printf_filtered ("Stopped due to shared library event\n");
+
/* Look up the hook_stop and run it if it exists. */
if (stop_command->hook)
@@ -2121,4 +2189,16 @@ of the program stops.", &cmdlist);
signal_print[TARGET_SIGNAL_POLL] = 0;
signal_stop[TARGET_SIGNAL_URG] = 0;
signal_print[TARGET_SIGNAL_URG] = 0;
+
+#ifdef SOLIB_ADD
+ add_show_from_set
+ (add_set_cmd ("stop-on-solib-events", class_support, var_zinteger,
+ (char *) &stop_on_solib_events,
+ "Set stopping for shared library events.\n\
+If nonzero, gdb will give control to the user when the dynamic linker\n\
+notifies gdb of shared library events. The most common event of interest\n\
+to the user would be loading/unloading of a new library.\n",
+ &setlist),
+ &showlist);
+#endif
}
diff --git a/gdb/irix5-nat.c b/gdb/irix5-nat.c
index 1be5d4d..fc4c8cb 100644
--- a/gdb/irix5-nat.c
+++ b/gdb/irix5-nat.c
@@ -1,5 +1,5 @@
/* Native support for the SGI Iris running IRIX version 5, for GDB.
- Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
Free Software Foundation, Inc.
Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
@@ -1001,7 +1001,7 @@ solib_create_inferior_hook()
and will put out an annoying warning.
Delaying the resetting of stop_soon_quietly until after symbol loading
suppresses the warning. */
- if (auto_solib_add_at_startup)
+ if (auto_solib_add)
solib_add ((char *) 0, 0, (struct target_ops *) 0);
stop_soon_quietly = 0;
}
@@ -1039,10 +1039,11 @@ _initialize_solib()
add_show_from_set
(add_set_cmd ("auto-solib-add", class_support, var_zinteger,
- (char *) &auto_solib_add_at_startup,
- "Set autoloading of shared library symbols at startup.\n\
+ (char *) &auto_solib_add,
+ "Set autoloading of shared library symbols.\n\
If nonzero, symbols from all shared object libraries will be loaded\n\
-automatically when the inferior begins execution. Otherwise, symbols\n\
+automatically when the inferior begins execution or when the dynamic linker\n\
+informs gdb that a new library has been loaded. Otherwise, symbols\n\
must be loaded manually, using `sharedlibrary'.",
&setlist),
&showlist);
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index e36302e..6ef709a 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -1,5 +1,5 @@
/* GDB routines for manipulating the minimal symbol tables.
- Copyright 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1994, 1996, 1996 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
This file is part of GDB.
@@ -253,6 +253,56 @@ lookup_minimal_symbol_text (name, sfile, objf)
return NULL;
}
+/* Look through all the current minimal symbol tables and find the
+ first minimal symbol that matches NAME and of solib trampoline type.
+ If OBJF is non-NULL, limit
+ the search to that objfile. If SFILE is non-NULL, limit the search
+ to that source file. Returns a pointer to the minimal symbol that
+ matches, or NULL if no match is found.
+*/
+
+struct minimal_symbol *
+lookup_minimal_symbol_solib_trampoline (name, sfile, objf)
+ register const char *name;
+ const char *sfile;
+ struct objfile *objf;
+{
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *found_symbol = NULL;
+ struct minimal_symbol *found_file_symbol = NULL;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ if (sfile != NULL)
+ {
+ char *p = strrchr (sfile, '/');
+ if (p != NULL)
+ sfile = p + 1;
+ }
+#endif
+
+ for (objfile = object_files;
+ objfile != NULL && found_symbol == NULL;
+ objfile = objfile -> next)
+ {
+ if (objf == NULL || objf == objfile)
+ {
+ for (msymbol = objfile -> msymbols;
+ msymbol != NULL && SYMBOL_NAME (msymbol) != NULL &&
+ found_symbol == NULL;
+ msymbol++)
+ {
+ if (SYMBOL_MATCHES_NAME (msymbol, name) &&
+ MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+ return msymbol;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
/* Search through the minimal symbol table for each objfile and find the
symbol whose address is the largest address that is still less than or
equal to PC. Returns a pointer to the minimal symbol if such a symbol
diff --git a/gdb/osfsolib.c b/gdb/osfsolib.c
index b97e683..85afa24 100644
--- a/gdb/osfsolib.c
+++ b/gdb/osfsolib.c
@@ -1,5 +1,5 @@
/* Handle OSF/1 shared libraries for GDB, the GNU Debugger.
- Copyright 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
@@ -905,7 +905,7 @@ solib_create_inferior_hook()
and will put out an annoying warning.
Delaying the resetting of stop_soon_quietly until after symbol loading
suppresses the warning. */
- if (auto_solib_add_at_startup)
+ if (auto_solib_add)
solib_add ((char *) 0, 0, (struct target_ops *) 0);
stop_soon_quietly = 0;
}
@@ -944,10 +944,11 @@ _initialize_solib()
add_show_from_set
(add_set_cmd ("auto-solib-add", class_support, var_zinteger,
- (char *) &auto_solib_add_at_startup,
- "Set autoloading of shared library symbols at startup.\n\
+ (char *) &auto_solib_add,
+ "Set autoloading of shared library symbols.\n\
If nonzero, symbols from all shared object libraries will be loaded\n\
-automatically when the inferior begins execution. Otherwise, symbols\n\
+automatically when the inferior begins execution or when the dynamic linker\n\
+informs gdb that a new library has been loaded. Otherwise, symbols\n\
must be loaded manually, using `sharedlibrary'.",
&setlist),
&showlist);
diff --git a/gdb/somsolib.c b/gdb/somsolib.c
index 595752c..2d232b3 100644
--- a/gdb/somsolib.c
+++ b/gdb/somsolib.c
@@ -1,5 +1,5 @@
/* Handle HP SOM shared libraries for GDB, the GNU Debugger.
- Copyright 1993 Free Software Foundation, Inc.
+ Copyright 1993, 1996 Free Software Foundation, Inc.
This file is part of GDB.
@@ -41,11 +41,7 @@ and by Cygnus Support. */
* Most of this code should work for hp300 shared libraries. Does
anyone care enough to weed out any SOM-isms.
- * Do we need/want a command to load a shared library?
-
- * Support for hpux8 dynamic linker.
-
- * Support for tracking user calls to dld_load, dld_unload. */
+ * Support for hpux8 dynamic linker. */
/* The basic structure which describes a dynamically loaded object. This
data structure is private to the dynamic linker and isn't found in
@@ -499,9 +495,10 @@ void
som_solib_create_inferior_hook()
{
struct minimal_symbol *msymbol;
- unsigned int dld_flags, status;
+ unsigned int dld_flags, status, have_endo;
asection *shlib_info;
char shadow_contents[BREAKPOINT_MAX], buf[4];
+ struct objfile *objfile;
CORE_ADDR anaddr;
if (symfile_objfile == NULL)
@@ -516,12 +513,106 @@ som_solib_create_inferior_hook()
if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
return;
+ have_endo = 0;
+ /* Slam the pid of the process into __d_pid; failing is only a warning! */
+ msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ {
+ warning ("Unable to find __d_pid symbol in object file.\n");
+ warning ("Suggest linking with /usr/lib/end.o.\n");
+ warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+ goto keep_going;
+ }
+
+ anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+ store_unsigned_integer (buf, 4, inferior_pid);
+ status = target_write_memory (anaddr, buf, 4);
+ if (status != 0)
+ {
+ warning ("Unable to write __d_pid\n");
+ warning ("Suggest linking with /usr/lib/end.o.\n");
+ warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+ goto keep_going;
+ }
+
+ /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
+ This will force the dynamic linker to call __d_trap when significant
+ events occur. */
+ msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ {
+ warning ("Unable to find _DLD_HOOK symbol in object file.\n");
+ warning ("Suggest linking with /usr/lib/end.o.\n");
+ warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+ goto keep_going;
+ }
+ anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ /* Grrr, this might not be an export symbol! We have to find the
+ export stub. */
+ ALL_OBJFILES (objfile)
+ {
+ struct unwind_table_entry *u;
+
+ /* What a crock. */
+ msymbol = lookup_minimal_symbol_solib_trampoline (SYMBOL_NAME (msymbol),
+ NULL, objfile);
+ /* Found a symbol with the right name. */
+ if (msymbol)
+ {
+ struct unwind_table_entry *u;
+ /* It must be a shared library trampoline. */
+ if (SYMBOL_TYPE (msymbol) != mst_solib_trampoline)
+ continue;
+
+ /* It must also be an export stub. */
+ u = find_unwind_entry (SYMBOL_VALUE (msymbol));
+ if (!u || u->stub_type != EXPORT)
+ continue;
+
+ /* OK. Looks like the correct import stub. */
+ anaddr = SYMBOL_VALUE (msymbol);
+ break;
+ }
+ }
+ store_unsigned_integer (buf, 4, anaddr);
+
+ msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ {
+ warning ("Unable to find __dld_hook symbol in object file.\n");
+ warning ("Suggest linking with /usr/lib/end.o.\n");
+ warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+ goto keep_going;
+ }
+ anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+ status = target_write_memory (anaddr, buf, 4);
+
+ /* Now set a shlib_event breakpoint at __d_trap so we can track
+ significant shared library events. */
+ msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ {
+ warning ("Unable to find __dld_d_trap symbol in object file.\n");
+ warning ("Suggest linking with /usr/lib/end.o.\n");
+ warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+ goto keep_going;
+ }
+ create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
+
+ /* We have all the support usually found in end.o, so we can track
+ shl_load and shl_unload calls. */
+ have_endo = 1;
+
+keep_going:
+
/* Get the address of __dld_flags, if no such symbol exists, then we can
not debug the shared code. */
msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
if (msymbol == NULL)
{
error ("Unable to find __dld_flags symbol in object file.\n");
+ goto keep_going;
return;
}
@@ -536,7 +627,7 @@ som_solib_create_inferior_hook()
dld_flags = extract_unsigned_integer (buf, 4);
/* Turn on the flags we care about. */
- dld_flags |= 0x5;
+ dld_flags |= (0x5 | (have_endo << 1));
store_unsigned_integer (buf, 4, dld_flags);
status = target_write_memory (anaddr, buf, 4);
if (status != 0)
@@ -545,7 +636,15 @@ som_solib_create_inferior_hook()
return;
}
- /* Now find the address of _start and set a breakpoint there. */
+ /* Now find the address of _start and set a breakpoint there.
+ We still need this code for two reasons:
+
+ * Not all sites have /usr/lib/end.o, so it's not always
+ possible to track the dynamic linker's events.
+
+ * At this time no events are triggered for shared libraries
+ loaded at startup time (what a crock). */
+
msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
if (msymbol == NULL)
{
@@ -592,7 +691,7 @@ som_solib_create_inferior_hook()
return;
}
- if (auto_solib_add_at_startup)
+ if (auto_solib_add)
som_solib_add ((char *) 0, 0, (struct target_ops *) 0);
}
@@ -728,10 +827,11 @@ _initialize_som_solib ()
"Status of loaded shared object libraries.");
add_show_from_set
(add_set_cmd ("auto-solib-add", class_support, var_zinteger,
- (char *) &auto_solib_add_at_startup,
+ (char *) &auto_solib_add,
"Set autoloading of shared library symbols at startup.\n\
If nonzero, symbols from all shared object libraries will be loaded\n\
-automatically when the inferior begins execution. Otherwise, symbols\n\
+automatically when the inferior begins execution or when the dynamic linker\n\
+informs gdb that a new library has been loaded. Otherwise, symbols\n\
must be loaded manually, using `sharedlibrary'.",
&setlist),
&showlist);