diff options
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/ppc-linux-tdep.c | 137 |
2 files changed, 9 insertions, 137 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d09eb4d..cc4a828 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2007-06-01 Ulrich Weigand <uweigand@de.ibm.com> + + * ppc-linux-tdep.c (INSTR_SC, INSTR_LI_R0_0x6666, INSTR_LI_R0_0x7777, + INSTR_LI_R0_NR_sigreturn, INSTR_LI_R0_NR_rt_sigreturn): Remove. + (PPC_LINUX_SIGNAL_FRAMESIZE, PPC_LINUX_REGS_PTR_OFFSET, + PPC_LINUX_HANDLER_PTR_OFFSET): Remove. + (ppc_linux_in_sigtramp, insn_is_sigreturn, + ppc_linux_at_sigtramp_return_path): Remove. + 2007-05-31 Markus Deuling <deuling@de.ibm.com> * xtensa-tdep.c (XTENSA_IS_ENTRY, extract_call_winsize) diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index cf09a17..9f2aceea 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -40,33 +40,6 @@ #include "frame-unwind.h" #include "tramp-frame.h" -/* The following instructions are used in the signal trampoline code - on GNU/Linux PPC. The kernel used to use magic syscalls 0x6666 and - 0x7777 but now uses the sigreturn syscalls. We check for both. */ -#define INSTR_LI_R0_0x6666 0x38006666 -#define INSTR_LI_R0_0x7777 0x38007777 -#define INSTR_LI_R0_NR_sigreturn 0x38000077 -#define INSTR_LI_R0_NR_rt_sigreturn 0x380000AC - -#define INSTR_SC 0x44000002 - -/* Since the *-tdep.c files are platform independent (i.e, they may be - used to build cross platform debuggers), we can't include system - headers. Therefore, details concerning the sigcontext structure - must be painstakingly rerecorded. What's worse, if these details - ever change in the header files, they'll have to be changed here - as well. */ - -/* __SIGNAL_FRAMESIZE from <asm/ptrace.h> */ -#define PPC_LINUX_SIGNAL_FRAMESIZE 64 - -/* From <asm/sigcontext.h>, offsetof(struct sigcontext_struct, regs) == 0x1c */ -#define PPC_LINUX_REGS_PTR_OFFSET (PPC_LINUX_SIGNAL_FRAMESIZE + 0x1c) - -/* From <asm/sigcontext.h>, - offsetof(struct sigcontext_struct, handler) == 0x14 */ -#define PPC_LINUX_HANDLER_PTR_OFFSET (PPC_LINUX_SIGNAL_FRAMESIZE + 0x14) - /* From <asm/ptrace.h>, values for PT_NIP, PT_R1, and PT_LNK */ #define PPC_LINUX_PT_R0 0 #define PPC_LINUX_PT_R1 1 @@ -111,116 +84,6 @@ #define PPC_LINUX_PT_FPR31 (PPC_LINUX_PT_FPR0 + 2*31) #define PPC_LINUX_PT_FPSCR (PPC_LINUX_PT_FPR0 + 2*32 + 1) -static int ppc_linux_at_sigtramp_return_path (CORE_ADDR pc); - -/* Determine if pc is in a signal trampoline... - - Ha! That's not what this does at all. wait_for_inferior in - infrun.c calls get_frame_type() in order to detect entry into a - signal trampoline just after delivery of a signal. But on - GNU/Linux, signal trampolines are used for the return path only. - The kernel sets things up so that the signal handler is called - directly. - - If we use in_sigtramp2() in place of in_sigtramp() (see below) - we'll (often) end up with stop_pc in the trampoline and prev_pc in - the (now exited) handler. The code there will cause a temporary - breakpoint to be set on prev_pc which is not very likely to get hit - again. - - If this is confusing, think of it this way... the code in - wait_for_inferior() needs to be able to detect entry into a signal - trampoline just after a signal is delivered, not after the handler - has been run. - - So, we define in_sigtramp() below to return 1 if the following is - true: - - 1) The previous frame is a real signal trampoline. - - - and - - - 2) pc is at the first or second instruction of the corresponding - handler. - - Why the second instruction? It seems that wait_for_inferior() - never sees the first instruction when single stepping. When a - signal is delivered while stepping, the next instruction that - would've been stepped over isn't, instead a signal is delivered and - the first instruction of the handler is stepped over instead. That - puts us on the second instruction. (I added the test for the first - instruction long after the fact, just in case the observed behavior - is ever fixed.) */ - -int -ppc_linux_in_sigtramp (CORE_ADDR pc, char *func_name) -{ - CORE_ADDR lr; - CORE_ADDR sp; - CORE_ADDR tramp_sp; - gdb_byte buf[4]; - CORE_ADDR handler; - - lr = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum); - if (!ppc_linux_at_sigtramp_return_path (lr)) - return 0; - - sp = read_register (SP_REGNUM); - - if (target_read_memory (sp, buf, sizeof (buf)) != 0) - return 0; - - tramp_sp = extract_unsigned_integer (buf, 4); - - if (target_read_memory (tramp_sp + PPC_LINUX_HANDLER_PTR_OFFSET, buf, - sizeof (buf)) != 0) - return 0; - - handler = extract_unsigned_integer (buf, 4); - - return (pc == handler || pc == handler + 4); -} - -static int -insn_is_sigreturn (unsigned long pcinsn) -{ - switch(pcinsn) - { - case INSTR_LI_R0_0x6666: - case INSTR_LI_R0_0x7777: - case INSTR_LI_R0_NR_sigreturn: - case INSTR_LI_R0_NR_rt_sigreturn: - return 1; - default: - return 0; - } -} - -/* - * The signal handler trampoline is on the stack and consists of exactly - * two instructions. The easiest and most accurate way of determining - * whether the pc is in one of these trampolines is by inspecting the - * instructions. It'd be faster though if we could find a way to do this - * via some simple address comparisons. - */ -static int -ppc_linux_at_sigtramp_return_path (CORE_ADDR pc) -{ - gdb_byte buf[12]; - unsigned long pcinsn; - if (target_read_memory (pc - 4, buf, sizeof (buf)) != 0) - return 0; - - /* extract the instruction at the pc */ - pcinsn = extract_unsigned_integer (buf + 4, 4); - - return ( - (insn_is_sigreturn (pcinsn) - && extract_unsigned_integer (buf + 8, 4) == INSTR_SC) - || - (pcinsn == INSTR_SC - && insn_is_sigreturn (extract_unsigned_integer (buf, 4)))); -} static CORE_ADDR ppc_linux_skip_trampoline_code (CORE_ADDR pc) |