#include "event-top.h"
#include "record.h"
#include "inline-frame.h"
+#include "jit.h"
/* Prototypes for local functions */
solib_create_inferior_hook ();
#endif
+ jit_inferior_created_hook ();
+
/* Reinsert all breakpoints. (Those which were symbolic have
been reset to the proper address in the new a.out, thanks
to symbol_file_command...) */
read_memory (copy, displaced_step_saved_copy, len);
if (debug_displaced)
{
- fprintf_unfiltered (gdb_stdlog, "displaced: saved 0x%s: ",
- paddr_nz (copy));
+ fprintf_unfiltered (gdb_stdlog, "displaced: saved %s: ",
+ paddress (gdbarch, copy));
displaced_step_dump_bytes (gdb_stdlog, displaced_step_saved_copy, len);
};
do_cleanups (old_cleanups);
if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: displaced pc to 0x%s\n",
- paddr_nz (copy));
+ fprintf_unfiltered (gdb_stdlog, "displaced: displaced pc to %s\n",
+ paddress (gdbarch, copy));
return 1;
}
write_memory_ptid (displaced_step_ptid, displaced_step_copy,
displaced_step_saved_copy, len);
if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: restored 0x%s\n",
- paddr_nz (displaced_step_copy));
+ fprintf_unfiltered (gdb_stdlog, "displaced: restored %s\n",
+ paddress (displaced_step_gdbarch,
+ displaced_step_copy));
}
/* Did the instruction complete successfully? */
{
struct displaced_step_request *head;
ptid_t ptid;
+ struct regcache *regcache;
+ struct gdbarch *gdbarch;
CORE_ADDR actual_pc;
head = displaced_step_request_queue;
context_switch (ptid);
- actual_pc = regcache_read_pc (get_thread_regcache (ptid));
+ regcache = get_thread_regcache (ptid);
+ actual_pc = regcache_read_pc (regcache);
if (breakpoint_here_p (actual_pc))
{
displaced_step_prepare (ptid);
+ gdbarch = get_regcache_arch (regcache);
+
if (debug_displaced)
{
+ CORE_ADDR actual_pc = regcache_read_pc (regcache);
gdb_byte buf[4];
- fprintf_unfiltered (gdb_stdlog, "displaced: run 0x%s: ",
- paddr_nz (actual_pc));
+ fprintf_unfiltered (gdb_stdlog, "displaced: run %s: ",
+ paddress (gdbarch, actual_pc));
read_memory (actual_pc, buf, sizeof (buf));
displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
}
- target_resume (ptid, 1, TARGET_SIGNAL_0);
+ if (gdbarch_software_single_step_p (gdbarch))
+ target_resume (ptid, 0, TARGET_SIGNAL_0);
+ else
+ target_resume (ptid, 1, TARGET_SIGNAL_0);
/* Done, we're stepping a thread. */
break;
{
int hw_step = 1;
- if (gdbarch_software_single_step_p (gdbarch)
- && gdbarch_software_single_step (gdbarch, get_current_frame ()))
+ if (gdbarch_software_single_step_p (gdbarch))
{
- hw_step = 0;
- /* Do not pull these breakpoints until after a `wait' in
- `wait_for_inferior' */
- singlestep_breakpoints_inserted_p = 1;
- singlestep_ptid = inferior_ptid;
- singlestep_pc = pc;
+ if (use_displaced_stepping (gdbarch))
+ hw_step = 0;
+ else if (gdbarch_software_single_step (gdbarch, get_current_frame ()))
+ {
+ hw_step = 0;
+ /* Do not pull these breakpoints until after a `wait' in
+ `wait_for_inferior' */
+ singlestep_breakpoints_inserted_p = 1;
+ singlestep_ptid = inferior_ptid;
+ singlestep_pc = pc;
+ }
}
return hw_step;
}
comments in the handle_inferior event for dealing with 'random
signals' explain what we do instead. */
if (use_displaced_stepping (gdbarch)
- && tp->trap_expected
+ && (tp->trap_expected
+ || (step && gdbarch_software_single_step_p (gdbarch)))
&& sig == TARGET_SIGNAL_0)
{
if (!displaced_step_prepare (inferior_ptid))
&& tp->trap_expected)
{
struct regcache *resume_regcache = get_thread_regcache (resume_ptid);
+ struct gdbarch *resume_gdbarch = get_regcache_arch (resume_regcache);
CORE_ADDR actual_pc = regcache_read_pc (resume_regcache);
gdb_byte buf[4];
- fprintf_unfiltered (gdb_stdlog, "displaced: run 0x%s: ",
- paddr_nz (actual_pc));
+ fprintf_unfiltered (gdb_stdlog, "displaced: run %s: ",
+ paddress (resume_gdbarch, actual_pc));
read_memory (actual_pc, buf, sizeof (buf));
displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
}
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
- "infrun: proceed (addr=0x%s, signal=%d, step=%d)\n",
- paddr_nz (addr), siggnal, step);
+ "infrun: proceed (addr=%s, signal=%d, step=%d)\n",
+ paddress (gdbarch, addr), siggnal, step);
if (non_stop)
/* In non-stop, each thread is handled individually. The context
static void init_execution_control_state (struct execution_control_state *ecs);
-void handle_inferior_event (struct execution_control_state *ecs);
+static void handle_inferior_event (struct execution_control_state *ecs);
static void handle_step_into_function (struct gdbarch *gdbarch,
struct execution_control_state *ecs);
char *status_string = target_waitstatus_to_string (ws);
struct ui_file *tmp_stream = mem_fileopen ();
char *text;
- long len;
/* The text is split over several lines because it was getting too long.
Call fprintf_unfiltered (gdb_stdlog) once so that the text is still
"infrun: %s\n",
status_string);
- text = ui_file_xstrdup (tmp_stream, &len);
+ text = ui_file_xstrdup (tmp_stream, NULL);
/* This uses %s in part to handle %'s in the text, but also to avoid
a gcc error: the format attribute requires a string literal. */
ecs = &ecss;
memset (ecs, 0, sizeof (*ecs));
- overlay_cache_invalid = 1;
-
/* We'll update this if & when we switch to a new thread. */
previous_inferior_ptid = inferior_ptid;
- /* 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 critical registers as part of their normal
- status mechanism. */
-
- registers_changed ();
-
while (1)
{
struct cleanup *old_chain;
+ /* 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 critical registers as part of their normal
+ status mechanism. */
+
+ overlay_cache_invalid = 1;
+ registers_changed ();
+
if (deprecated_target_wait_hook)
ecs->ptid = deprecated_target_wait_hook (waiton_ptid, &ecs->ws, 0);
else
memset (ecs, 0, sizeof (*ecs));
- overlay_cache_invalid = 1;
-
- /* We can only rely on wait_for_more being correct before handling
- the event in all-stop, but previous_inferior_ptid isn't used in
- non-stop. */
- if (!ecs->wait_some_more)
- /* We'll update this if & when we switch to a new thread. */
- previous_inferior_ptid = inferior_ptid;
+ /* We'll update this if & when we switch to a new thread. */
+ previous_inferior_ptid = inferior_ptid;
if (non_stop)
/* In non-stop mode, the user/frontend should not notice a thread
targets that provide critical registers as part of their normal
status mechanism. */
+ overlay_cache_invalid = 1;
registers_changed ();
if (deprecated_target_wait_hook)
by an event from the inferior, figure out what it means and take
appropriate action. */
-void
+static void
handle_inferior_event (struct execution_control_state *ecs)
{
struct frame_info *frame;
case infwait_thread_hop_state:
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: infwait_thread_hop_state\n");
- /* Cancel the waiton_ptid. */
- waiton_ptid = pid_to_ptid (-1);
break;
case infwait_normal_state:
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
}
+
infwait_state = infwait_normal_state;
+ waiton_ptid = pid_to_ptid (-1);
switch (ecs->ws.kind)
{
if (debug_infrun)
{
- fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = 0x%s\n",
- paddr_nz (stop_pc));
+ struct regcache *regcache = get_thread_regcache (ecs->ptid);
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = %s\n",
+ paddress (gdbarch, stop_pc));
if (target_stopped_by_watchpoint ())
{
CORE_ADDR addr;
if (target_stopped_data_address (¤t_target, &addr))
fprintf_unfiltered (gdb_stdlog,
- "infrun: stopped data address = 0x%s\n",
- paddr_nz (addr));
+ "infrun: stopped data address = %s\n",
+ paddress (gdbarch, addr));
else
fprintf_unfiltered (gdb_stdlog,
"infrun: (no data address available)\n");
singlestep_breakpoints_inserted_p = 0;
ecs->random_signal = 0;
+ ecs->event_thread->trap_expected = 0;
context_switch (saved_singlestep_ptid);
if (deprecated_context_hook)
ecs->event_thread->stepping_over_breakpoint = 1;
keep_going (ecs);
- registers_changed ();
return;
}
}
/* Single step */
hw_step = maybe_software_singlestep (gdbarch, stop_pc);
target_resume (ecs->ptid, hw_step, TARGET_SIGNAL_0);
- registers_changed ();
waiton_ptid = ecs->ptid;
if (target_have_steppable_watchpoint)
infwait_state = infwait_step_watch_state;
}
break;
+ case BPSTAT_WHAT_CHECK_JIT:
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_CHECK_JIT\n");
+
+ /* Switch terminal for any messages produced by breakpoint_re_set. */
+ target_terminal_ours_for_output ();
+
+ jit_event_handler (gdbarch);
+
+ target_terminal_inferior ();
+
+ /* We want to step over this breakpoint, then keep going. */
+ ecs->event_thread->stepping_over_breakpoint = 1;
+
+ break;
+
case BPSTAT_WHAT_LAST:
/* Not a real code, but listed here to shut up gcc -Wall. */
ecs->event_thread->step_frame_id)))
{
if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: stepping inside range [0x%s-0x%s]\n",
- paddr_nz (ecs->event_thread->step_range_start),
- paddr_nz (ecs->event_thread->step_range_end));
+ fprintf_unfiltered
+ (gdb_stdlog, "infrun: stepping inside range [%s-%s]\n",
+ paddress (gdbarch, ecs->event_thread->step_range_start),
+ paddress (gdbarch, ecs->event_thread->step_range_end));
/* When stepping backward, stop at beginning of line range
(unless it's the function entry point, in which case
previous frame must have valid frame IDs. */
if (!frame_id_eq (get_stack_frame_id (frame),
ecs->event_thread->step_stack_frame_id)
- && (frame_id_eq (frame_unwind_caller_id (frame),
- ecs->event_thread->step_stack_frame_id)
- || execution_direction == EXEC_REVERSE))
+ && frame_id_eq (frame_unwind_caller_id (frame),
+ ecs->event_thread->step_stack_frame_id))
{
CORE_ADDR real_stop_pc;
/* Reverse stepping through solib trampolines. */
if (execution_direction == EXEC_REVERSE
+ && ecs->event_thread->step_over_calls != STEP_OVER_NONE
&& (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
|| (ecs->stop_func_start == 0
&& in_solib_dynsym_resolve_code (stop_pc))))
return;
}
+ /* Reverse stepping through solib trampolines. */
+
+ if (execution_direction == EXEC_REVERSE
+ && ecs->event_thread->step_over_calls != STEP_OVER_NONE)
+ {
+ if (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
+ || (ecs->stop_func_start == 0
+ && in_solib_dynsym_resolve_code (stop_pc)))
+ {
+ /* Any solib trampoline code can be handled in reverse
+ by simply continuing to single-step. We have already
+ executed the solib function (backwards), and a few
+ steps will take us back through the trampoline to the
+ caller. */
+ keep_going (ecs);
+ return;
+ }
+ else if (in_solib_dynsym_resolve_code (stop_pc))
+ {
+ /* Stepped backward into the solib dynsym resolver.
+ Set a breakpoint at its start and continue, then
+ one more step will take us out. */
+ struct symtab_and_line sr_sal;
+ init_sal (&sr_sal);
+ sr_sal.pc = ecs->stop_func_start;
+ insert_step_resume_breakpoint_at_sal (gdbarch,
+ sr_sal, null_frame_id);
+ keep_going (ecs);
+ return;
+ }
+ }
+
/* If we're in the return path from a shared library trampoline,
we want to proceed through the trampoline when stepping. */
if (gdbarch_in_solib_return_trampoline (gdbarch,
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
- "infrun: inserting step-resume breakpoint at 0x%s\n",
- paddr_nz (sr_sal.pc));
+ "infrun: inserting step-resume breakpoint at %s\n",
+ paddress (gdbarch, sr_sal.pc));
inferior_thread ()->step_resume_breakpoint
= set_momentary_breakpoint (gdbarch, sr_sal, sr_id, bp_step_resume);
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
- "infrun: inserting longjmp-resume breakpoint at 0x%s\n",
- paddr_nz (pc));
+ "infrun: inserting longjmp-resume breakpoint at %s\n",
+ paddress (gdbarch, pc));
inferior_thread ()->step_resume_breakpoint =
set_momentary_breakpoint_at_pc (gdbarch, pc, bp_longjmp_resume);
{
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: prepare_to_wait\n");
- if (infwait_state == infwait_normal_state)
- {
- 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 critical registers
- as part of their normal status mechanism. */
- registers_changed ();
- waiton_ptid = pid_to_ptid (-1);
- }
/* This is the old end of the while loop. Let everybody know we
want to wait for the inferior some more and get called again
soon. */