static void gdbsim_create_inferior (struct target_ops *target, char *exec_file, char *args, char **env, int from_tty) { int len; char *arg_buf, **argv; if (exec_file == 0 || exec_bfd == 0) warning (_("No executable file specified.")); if (!program_loaded) warning (_("No program loaded.")); if (remote_debug) printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n", (exec_file ? exec_file : "(NULL)"), args); if (ptid_equal (inferior_ptid, remote_sim_ptid)) gdbsim_kill (target); remove_breakpoints (); init_wait_for_inferior (); if (exec_file != NULL) { len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10; arg_buf = (char *) alloca (len); arg_buf[0] = '\0'; strcat (arg_buf, exec_file); strcat (arg_buf, " "); strcat (arg_buf, args); argv = gdb_buildargv (arg_buf); make_cleanup_freeargv (argv); } else argv = NULL; sim_create_inferior (gdbsim_desc, exec_bfd, argv, env); inferior_ptid = remote_sim_ptid; add_inferior_silent (ptid_get_pid (inferior_ptid)); add_thread_silent (inferior_ptid); target_mark_running (&gdbsim_ops); insert_breakpoints (); /* Needed to get correct instruction in cache */ clear_proceed_status (); }
static void gdbsim_create_inferior (char *exec_file, char *args, char **env, int from_tty) { int len; char *arg_buf, **argv; if (exec_file == 0 || exec_bfd == 0) warning ("No executable file specified."); if (!program_loaded) warning ("No program loaded."); if (sr_get_debug ()) printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n", (exec_file ? exec_file : "(NULL)"), args); gdbsim_kill (); remove_breakpoints (); init_wait_for_inferior (); if (exec_file != NULL) { len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10; arg_buf = (char *) alloca (len); arg_buf[0] = '\0'; strcat (arg_buf, exec_file); strcat (arg_buf, " "); strcat (arg_buf, args); argv = buildargv (arg_buf); make_cleanup_freeargv (argv); } else argv = NULL; sim_create_inferior (gdbsim_desc, exec_bfd, argv, env); inferior_ptid = pid_to_ptid (42); insert_breakpoints (); /* Needed to get correct instruction in cache */ clear_proceed_status (); /* NB: Entry point already set by sim_create_inferior. */ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); }
static int arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs, struct displaced_step_closure *dsc) { CORE_ADDR return_to = 0; struct frame_info *frame; unsigned int svc_number = displaced_read_reg (regs, dsc, 7); int is_sigreturn = 0; int is_thumb; frame = get_current_frame (); is_sigreturn = arm_linux_sigreturn_return_addr(frame, svc_number, &return_to, &is_thumb); if (is_sigreturn) { struct symtab_and_line sal; if (debug_displaced) fprintf_unfiltered (gdb_stdlog, "displaced: found " "sigreturn/rt_sigreturn SVC call. PC in frame = %lx\n", (unsigned long) get_frame_pc (frame)); if (debug_displaced) fprintf_unfiltered (gdb_stdlog, "displaced: unwind pc = %lx. " "Setting momentary breakpoint.\n", (unsigned long) return_to); gdb_assert (inferior_thread ()->control.step_resume_breakpoint == NULL); sal = find_pc_line (return_to, 0); sal.pc = return_to; sal.section = find_pc_overlay (return_to); sal.explicit_pc = 1; frame = get_prev_frame (frame); if (frame) { inferior_thread ()->control.step_resume_breakpoint = set_momentary_breakpoint (gdbarch, sal, get_frame_id (frame), bp_step_resume); /* set_momentary_breakpoint invalidates FRAME. */ frame = NULL; /* We need to make sure we actually insert the momentary breakpoint set above. */ insert_breakpoints (); } else if (debug_displaced) fprintf_unfiltered (gdb_stderr, "displaced: couldn't find previous " "frame to set momentary breakpoint for " "sigreturn/rt_sigreturn\n"); } else if (debug_displaced) fprintf_unfiltered (gdb_stdlog, "displaced: sigreturn/rt_sigreturn " "SVC call not in signal trampoline frame\n"); /* Preparation: If we detect sigreturn, set momentary breakpoint at resume location, else nothing. Insn: unmodified svc. Cleanup: if pc lands in scratch space, pc <- insn_addr + 4 else leave pc alone. */ dsc->cleanup = &arm_linux_cleanup_svc; /* Pretend we wrote to the PC, so cleanup doesn't set PC to the next instruction. */ dsc->wrote_to_pc = 1; return 0; }
static int arm_linux_copy_svc (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to, struct regcache *regs, struct displaced_step_closure *dsc) { CORE_ADDR from = dsc->insn_addr; struct frame_info *frame; unsigned int svc_number = displaced_read_reg (regs, from, 7); if (debug_displaced) fprintf_unfiltered (gdb_stdlog, "displaced: copying Linux svc insn %.8lx\n", (unsigned long) insn); frame = get_current_frame (); /* Is this a sigreturn or rt_sigreturn syscall? Note: these are only useful for EABI. */ if (svc_number == 119 || svc_number == 173) { if (get_frame_type (frame) == SIGTRAMP_FRAME) { CORE_ADDR return_to; struct symtab_and_line sal; if (debug_displaced) fprintf_unfiltered (gdb_stdlog, "displaced: found " "sigreturn/rt_sigreturn SVC call. PC in frame = %lx\n", (unsigned long) get_frame_pc (frame)); return_to = frame_unwind_caller_pc (frame); if (debug_displaced) fprintf_unfiltered (gdb_stdlog, "displaced: unwind pc = %lx. " "Setting momentary breakpoint.\n", (unsigned long) return_to); gdb_assert (inferior_thread ()->step_resume_breakpoint == NULL); sal = find_pc_line (return_to, 0); sal.pc = return_to; sal.section = find_pc_overlay (return_to); sal.explicit_pc = 1; frame = get_prev_frame (frame); if (frame) { inferior_thread ()->step_resume_breakpoint = set_momentary_breakpoint (gdbarch, sal, get_frame_id (frame), bp_step_resume); /* We need to make sure we actually insert the momentary breakpoint set above. */ insert_breakpoints (); } else if (debug_displaced) fprintf_unfiltered (gdb_stderr, "displaced: couldn't find previous " "frame to set momentary breakpoint for " "sigreturn/rt_sigreturn\n"); } else if (debug_displaced) fprintf_unfiltered (gdb_stdlog, "displaced: sigreturn/rt_sigreturn " "SVC call not in signal trampoline frame\n"); } /* Preparation: If we detect sigreturn, set momentary breakpoint at resume location, else nothing. Insn: unmodified svc. Cleanup: if pc lands in scratch space, pc <- insn_addr + 4 else leave pc alone. */ dsc->modinsn[0] = insn; dsc->cleanup = &arm_linux_cleanup_svc; /* Pretend we wrote to the PC, so cleanup doesn't set PC to the next instruction. */ dsc->wrote_to_pc = 1; return 0; }