/* Target-struct-independent code to start (run) and stop an inferior process.
- Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996
- Free Software Foundation, Inc.
+ Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998 Free Software Foundation, Inc.
This file is part of GDB.
#include "target.h"
#include "gdbthread.h"
#include "annotate.h"
+#include "symfile.h" /* for overlay functions */
#include <signal.h>
#define DYNAMIC_TRAMPOLINE_NEXTPC(pc) 0
#endif
+/* On SVR4 based systems, determining the callee's address is exceedingly
+ difficult and depends on the implementation of the run time loader.
+ If we are stepping at the source level, we single step until we exit
+ the run time loader code and reach the callee's address. */
+
+#ifndef IN_SOLIB_DYNSYM_RESOLVE_CODE
+#define IN_SOLIB_DYNSYM_RESOLVE_CODE(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. */
while (1)
{
+ extern int overlay_cache_invalid; /* declared in symfile.h */
+
+ overlay_cache_invalid = 1;
+
/* We have to invalidate the registers BEFORE calling target_wait because
they can be loaded from the target while in target_wait. This makes
remote debugging a bit more efficient for those targets that provide
/* If it's a new process, add it to the thread database */
- if (pid != inferior_pid
+ if (w.kind != TARGET_WAITKIND_EXITED
+ && pid != inferior_pid
&& !in_thread_list (pid))
{
- fprintf_unfiltered (gdb_stderr, "[New %s]\n", target_pid_to_str (pid));
add_thread (pid);
+ printf_filtered ("[New %s]\n", target_pid_to_str (pid));
/* We may want to consider not doing a resume here in order to give
the user a chance to play with the new thread. It might be good
switch (w.kind)
{
case TARGET_WAITKIND_LOADED:
- /* Ignore it gracefully. */
- if (breakpoints_inserted)
+ /* Ignore gracefully during startup of the inferior, as it
+ might be the shell which has just loaded some objects,
+ otherwise add the symbols for the newly loaded objects. */
+#ifdef SOLIB_ADD
+ if (!stop_soon_quietly)
{
- mark_breakpoints_out ();
- insert_breakpoints ();
+ extern int auto_solib_add;
+
+ /* Remove breakpoints, SOLIB_ADD might adjust
+ breakpoint addresses via breakpoint_re_set. */
+ if (breakpoints_inserted)
+ remove_breakpoints ();
+
+ /* Check for any newly added shared libraries if we're
+ supposed to be adding them automatically. */
+ if (auto_solib_add)
+ {
+ /* Switch terminal for any messages produced by
+ breakpoint_re_set. */
+ target_terminal_ours_for_output ();
+ SOLIB_ADD (NULL, 0, NULL);
+ target_terminal_inferior ();
+ }
+
+ /* Reinsert breakpoints and continue. */
+ if (breakpoints_inserted)
+ insert_breakpoints ();
}
+#endif
resume (0, TARGET_SIGNAL_0);
continue;
&step_frame_address, &handling_longjmp,
&another_trap);
printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid));
-
flush_cached_frames ();
}
write_pc (stop_pc - DECR_PC_AFTER_BREAK);
remove_breakpoints ();
+ registers_changed();
target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
if (target_wait_hook)
/* We stepped out of the stepping range. */
+ /* If we are stepping at the source level and entered the runtime
+ loader dynamic symbol resolution code, we keep on single stepping
+ until we exit the run time loader code and reach the callee's
+ address. */
+ if (step_over_calls < 0 && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc))
+ goto keep_going;
+
/* We can't update step_sp every time through the loop, because
reading the stack pointer would slow down stepping too much.
But we can update it every time we leave the step range. */
struct symtab_and_line sr_sal;
INIT_SAL (&sr_sal); /* initialize to zeroes */
- sr_sal.pc = prev_pc;
+ sr_sal.pc = prev_pc;
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
/* We could probably be setting the frame to
step_frame_address; I don't think anyone thought to try it. */
step_resume_breakpoint =
/* Why isn't this s_a_l called "sr_sal", like all of the
other s_a_l's where this code is duplicated? */
INIT_SAL (&xxx); /* initialize to zeroes */
- xxx.pc = tmp;
+ xxx.pc = tmp;
+ xxx.section = find_pc_overlay (xxx.pc);
step_resume_breakpoint =
set_momentary_breakpoint (xxx, NULL, bp_step_resume);
insert_breakpoints ();
INIT_SAL (&sr_sal); /* initialize to zeroes */
sr_sal.pc =
- ADDR_BITS_REMOVE
- (SAVED_PC_AFTER_CALL (get_current_frame ()));
+ ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ()));
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
step_resume_breakpoint =
set_momentary_breakpoint (sr_sal, get_current_frame (),
bp_step_resume);
- step_resume_breakpoint->frame = step_frame_address;
+ if (!IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
+ step_resume_breakpoint->frame = step_frame_address;
if (breakpoints_inserted)
insert_breakpoints ();
}
struct symtab_and_line sr_sal;
INIT_SAL (&sr_sal); /* initialize to zeroes */
- sr_sal.pc = stop_func_start;
+ sr_sal.pc = stop_func_start;
+ sr_sal.section = find_pc_overlay (stop_func_start);
/* Do not specify what the fp should be when we stop
since on some machines the prologue
is where the new fp value is established. */
struct symtab_and_line sr_sal;
INIT_SAL (&sr_sal); /* initialize to zeroes */
- sr_sal.pc = tmp;
+ sr_sal.pc = tmp;
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
/* Do not specify what the fp should be when we stop
since on some machines the prologue
is where the new fp value is established. */
struct symtab_and_line sr_sal;
INIT_SAL (&sr_sal); /* initialize to zeroes */
- sr_sal.pc = prev_pc;
+ sr_sal.pc = prev_pc;
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
/* We perhaps could set the frame if we kept track of what
the frame corresponding to prev_pc was. But we don't,
so don't. */
enum target_signal oursig;
{
char *name = target_signal_to_name (oursig);
+ int name_padding = 13 - strlen (name);
+ if (name_padding <= 0)
+ name_padding = 0;
+
printf_filtered ("%s", name);
- printf_filtered ("%*.*s ", 13 - strlen (name), 13 - strlen (name),
- " ");
+ printf_filtered ("%*.*s ", name_padding, name_padding, " ");
printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No");
printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No");
printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No");