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; }
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); }
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); }
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; }
/* 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; }
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; }