예제 #1
0
파일: sol2-tdep.c 프로젝트: ChrisG0x20/gdb
CORE_ADDR
sol2_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  struct bound_minimal_symbol msym;

  msym = lookup_minimal_symbol("elf_bndr", NULL, NULL);
  if (msym.minsym && BMSYMBOL_VALUE_ADDRESS (msym) == pc)
    return frame_unwind_caller_pc (get_current_frame ());

  return 0;
}
예제 #2
0
CORE_ADDR
obsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  struct bound_minimal_symbol msym;

  msym = lookup_minimal_symbol("_dl_bind", NULL, NULL);
  if (msym.minsym && BMSYMBOL_VALUE_ADDRESS (msym) == pc)
    return frame_unwind_caller_pc (get_current_frame ());
  else
    return find_solib_trampoline_target (get_current_frame (), pc);
}
예제 #3
0
static CORE_ADDR
tic6x_linux_syscall_next_pc (struct frame_info *frame)
{
  ULONGEST syscall_number = get_frame_register_unsigned (frame,
							 TIC6X_B0_REGNUM);
  CORE_ADDR pc = get_frame_pc (frame);

  if (syscall_number == 139 /* rt_sigreturn */)
    return frame_unwind_caller_pc (frame);

  return pc + 4;
}
static CORE_ADDR
mips_linux_skip_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  struct minimal_symbol *resolver;

  resolver = lookup_minimal_symbol ("__dl_runtime_resolve", NULL, NULL);

  if (resolver && SYMBOL_VALUE_ADDRESS (resolver) == pc)
    return frame_unwind_caller_pc (get_current_frame ());

  return glibc_skip_solib_resolver (gdbarch, pc);
}
예제 #5
0
static CORE_ADDR
nios2_linux_syscall_next_pc (struct frame_info *frame)
{
  CORE_ADDR pc = get_frame_pc (frame);
  ULONGEST syscall_nr = get_frame_register_unsigned (frame, NIOS2_R2_REGNUM);

  /* If we are about to make a sigreturn syscall, use the unwinder to
     decode the signal frame.  */
  if (syscall_nr == 139 /* rt_sigreturn */)
    return frame_unwind_caller_pc (frame);

  return pc + NIOS2_OPCODE_SIZE;
}
static CORE_ADDR
mips_linux_syscall_next_pc (struct frame_info *frame)
{
  CORE_ADDR pc = get_frame_pc (frame);
  ULONGEST v0 = get_frame_register_unsigned (frame, MIPS_V0_REGNUM);

  /* If we are about to make a sigreturn syscall, use the unwinder to
     decode the signal frame.  */
  if (v0 == MIPS_NR_sigreturn
      || v0 == MIPS_NR_rt_sigreturn
      || v0 == MIPS_NR_N64_rt_sigreturn
      || v0 == MIPS_NR_N32_rt_sigreturn)
    return frame_unwind_caller_pc (get_current_frame ());

  return pc + 4;
}
예제 #7
0
/* Copy the value of next pc of sigreturn and rt_sigrturn into PC,
   return 1.  In addition, set IS_THUMB depending on whether we
   will return to ARM or Thumb code.  Return 0 if it is not a
   rt_sigreturn/sigreturn syscall.  */
static int
arm_linux_sigreturn_return_addr (struct frame_info *frame,
				 unsigned long svc_number,
				 CORE_ADDR *pc, int *is_thumb)
{
  /* Is this a sigreturn or rt_sigreturn syscall?  */
  if (svc_number == 119 || svc_number == 173)
    {
      if (get_frame_type (frame) == SIGTRAMP_FRAME)
	{
	  ULONGEST t_bit = arm_psr_thumb_bit (frame_unwind_arch (frame));
	  CORE_ADDR cpsr
	    = frame_unwind_register_unsigned (frame, ARM_PS_REGNUM);

	  *is_thumb = (cpsr & t_bit) != 0;
	  *pc = frame_unwind_caller_pc (frame);
	  return 1;
	}
    }
  return 0;
}
예제 #8
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;
}