Exemple #1
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;
}
Exemple #2
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;
}