From patchwork Fri Mar 4 16:42:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 348 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:41:52 -0000 Delivered-To: patches@linaro.org Received: by 10.224.60.68 with SMTP id o4cs20924qah; Fri, 4 Mar 2011 08:42:06 -0800 (PST) Received: by 10.213.15.16 with SMTP id i16mr581345eba.4.1299256925503; Fri, 04 Mar 2011 08:42:05 -0800 (PST) Received: from mtagate5.uk.ibm.com (mtagate5.uk.ibm.com [194.196.100.165]) by mx.google.com with ESMTPS id w16si5364800eei.65.2011.03.04.08.42.05 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 04 Mar 2011 08:42:05 -0800 (PST) Received-SPF: softfail (google.com: domain of transitioning uweigand@de.ibm.com does not designate 194.196.100.165 as permitted sender) client-ip=194.196.100.165; Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning uweigand@de.ibm.com does not designate 194.196.100.165 as permitted sender) smtp.mail=uweigand@de.ibm.com Received: from d06nrmr1507.portsmouth.uk.ibm.com (d06nrmr1507.portsmouth.uk.ibm.com [9.149.38.233]) by mtagate5.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p24Gg4Zn026999 for ; Fri, 4 Mar 2011 16:42:04 GMT Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by d06nrmr1507.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p24GgHZ11515704 for ; Fri, 4 Mar 2011 16:42:17 GMT Received: from d06av02.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p24Gg4hO010822 for ; Fri, 4 Mar 2011 09:42:04 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id p24Gg3Ti010819 for ; Fri, 4 Mar 2011 09:42:03 -0700 Message-Id: <201103041642.p24Gg3Ti010819@d06av02.portsmouth.uk.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Fri, 04 Mar 2011 17:42:03 +0100 Subject: [rfc v2, arm] Backtrace out of restart handler in vector page To: patches@linaro.org Date: Fri, 4 Mar 2011 17:42:03 +0100 (CET) From: "Ulrich Weigand" X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 http://sourceware.org/ml/gdb-patches/2011-02/msg00735.html ChangeLog: * arm-linux-tdep.c (ARM_LDR_PC_SP_4): Add define. (arm_linux_restart_syscall_init): Handle both on-stack and in-kernel versions of the trampoline. Handle Thumb vs. ARM addresses. (arm_kernel_linux_restart_syscall_tramp_frame): New global. (arm_linux_init_abi): Install it. * arm-tdep.c (arm_psr_thumb_bit): Make global. * arm-tdep.c (arm_psr_thumb_bit): Add prototype. diff -urNp gdb-orig/gdb/arm-linux-tdep.c gdb-head/gdb/arm-linux-tdep.c --- gdb-orig/gdb/arm-linux-tdep.c 2011-02-02 16:28:10.000000000 +0100 +++ gdb-head/gdb/arm-linux-tdep.c 2011-02-24 16:11:58.000000000 +0100 @@ -239,6 +239,7 @@ static const char arm_linux_thumb2_le_br whenever OABI support has been enabled in the kernel. */ #define ARM_OABI_SYSCALL_RESTART_SYSCALL 0xef900000 #define ARM_LDR_PC_SP_12 0xe49df00c +#define ARM_LDR_PC_SP_4 0xe49df004 static void arm_linux_sigtramp_cache (struct frame_info *this_frame, @@ -355,10 +356,36 @@ arm_linux_restart_syscall_init (const st struct trad_frame_cache *this_cache, CORE_ADDR func) { + struct gdbarch *gdbarch = get_frame_arch (this_frame); CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM); + CORE_ADDR pc = get_frame_memory_unsigned (this_frame, sp, 4); + CORE_ADDR cpsr = get_frame_register_unsigned (this_frame, ARM_PS_REGNUM); + ULONGEST t_bit = arm_psr_thumb_bit (gdbarch); + int sp_offset; + + /* There are two variants of this trampoline; with older kernels, the + stub is placed on the stack, while newer kernels use the stub from + the vector page. They are identical except that the older version + increments SP by 12 (to skip stored PC and the stub itself), while + the newer version increments SP only by 4 (just the stored PC). */ + if (self->insn[1].bytes == ARM_LDR_PC_SP_4) + sp_offset = 4; + else + sp_offset = 12; + + /* Update Thumb bit in CPSR. */ + if (pc & 1) + cpsr |= t_bit; + else + cpsr &= ~t_bit; - trad_frame_set_reg_addr (this_cache, ARM_PC_REGNUM, sp); - trad_frame_set_reg_value (this_cache, ARM_SP_REGNUM, sp + 12); + /* Remove Thumb bit from PC. */ + pc = gdbarch_addr_bits_remove (gdbarch, pc); + + /* Save previous register values. */ + trad_frame_set_reg_value (this_cache, ARM_SP_REGNUM, sp + sp_offset); + trad_frame_set_reg_value (this_cache, ARM_PC_REGNUM, pc); + trad_frame_set_reg_value (this_cache, ARM_PS_REGNUM, cpsr); /* Save a frame ID. */ trad_frame_set_id (this_cache, frame_id_build (sp, func)); @@ -417,6 +444,17 @@ static struct tramp_frame arm_linux_rest arm_linux_restart_syscall_init }; +static struct tramp_frame arm_kernel_linux_restart_syscall_tramp_frame = { + NORMAL_FRAME, + 4, + { + { ARM_OABI_SYSCALL_RESTART_SYSCALL, -1 }, + { ARM_LDR_PC_SP_4, -1 }, + { TRAMP_SENTINEL_INSN } + }, + arm_linux_restart_syscall_init +}; + /* Core file and register set support. */ #define ARM_LINUX_SIZEOF_GREGSET (18 * INT_REGISTER_SIZE) @@ -1008,6 +1046,8 @@ arm_linux_init_abi (struct gdbarch_info &arm_eabi_linux_rt_sigreturn_tramp_frame); tramp_frame_prepend_unwinder (gdbarch, &arm_linux_restart_syscall_tramp_frame); + tramp_frame_prepend_unwinder (gdbarch, + &arm_kernel_linux_restart_syscall_tramp_frame); /* Core file support. */ set_gdbarch_regset_from_core_section (gdbarch, diff -urNp gdb-orig/gdb/arm-tdep.c gdb-head/gdb/arm-tdep.c --- gdb-orig/gdb/arm-tdep.c 2011-02-17 14:00:14.000000000 +0100 +++ gdb-head/gdb/arm-tdep.c 2011-02-24 15:49:28.000000000 +0100 @@ -262,7 +262,7 @@ int arm_apcs_32 = 1; /* Return the bit mask in ARM_PS_REGNUM that indicates Thumb mode. */ -static int +int arm_psr_thumb_bit (struct gdbarch *gdbarch) { if (gdbarch_tdep (gdbarch)->is_m) diff -urNp gdb-orig/gdb/arm-tdep.h gdb-head/gdb/arm-tdep.h --- gdb-orig/gdb/arm-tdep.h 2011-02-09 15:28:26.000000000 +0100 +++ gdb-head/gdb/arm-tdep.h 2011-02-24 15:49:28.000000000 +0100 @@ -310,6 +310,9 @@ extern void arm_displaced_step_fixup (st struct displaced_step_closure *, CORE_ADDR, CORE_ADDR, struct regcache *); +/* Return the bit mask in ARM_PS_REGNUM that indicates Thumb mode. */ +extern int arm_psr_thumb_bit (struct gdbarch *); + /* Is the instruction at the given memory address a Thumb or ARM instruction? */ extern int arm_pc_is_thumb (struct gdbarch *, CORE_ADDR);