From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17682 invoked by alias); 11 Nov 2005 22:02:48 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 17671 invoked by uid 22791); 11 Nov 2005 22:02:44 -0000 Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Fri, 11 Nov 2005 22:02:43 +0000 Received: from drow by nevyn.them.org with local (Exim 4.54) id 1Eagyn-0007ti-Ei; Fri, 11 Nov 2005 17:02:41 -0500 Date: Sat, 12 Nov 2005 03:18:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sourceware.org, Richard Earnshaw Subject: [rfa] Use a different breakpoint instruction for EABI GNU/Linux Message-ID: <20051111220241.GA30323@nevyn.them.org> Mail-Followup-To: gdb-patches@sourceware.org, Richard Earnshaw Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.8i X-SW-Source: 2005-11/txt/msg00151.txt.bz2 Patches have been posted recently for the Linux kernel to use a different interface for system calls, in which r7 holds the syscall number instead of embedding it in the SWI. With old-ABI compatibility mode disabled, the kernel never looks in the SWI at all. Which means that using a SWI to set a breakpoint doesn't work very well. Since 2003 the kernel has supported these particular undefined instructions (in the reserved space) as breakpoints. So if we see an EABI binary, assume we have a recent vintage of kernel, and use them. Tested on arm-none-linux-gnueabi. OK for HEAD and 6.4? -- Daniel Jacobowitz CodeSourcery, LLC 2005-11-11 Daniel Jacobowitz * arm-linux-tdep.c (eabi_linux_arm_le_breakpoint) (eabi_linux_arm_be_breakpoint): New variables. (arm_linux_init_abi): Use them. 2005-11-11 Daniel Jacobowitz * linux-arm-low.c (arm_eabi_breakpoint): New variable. (arm_breakpoint_at): Recognize both breakpoints. (the_low_target): Use the correct breakpoint instruction. Index: src/gdb/arm-linux-tdep.c =================================================================== --- src.orig/gdb/arm-linux-tdep.c 2005-09-01 08:51:23.000000000 -0400 +++ src/gdb/arm-linux-tdep.c 2005-11-08 17:54:18.000000000 -0500 @@ -45,6 +45,19 @@ static const char arm_linux_arm_le_break static const char arm_linux_arm_be_breakpoint[] = { 0xef, 0x9f, 0x00, 0x01 }; +/* However, the EABI syscall interface (new in Nov. 2005) does not look at + the operand of the swi if old-ABI compatibility is disabled. Therefore, + use an undefined instruction instead. This is supported as of kernel + version 2.5.70 (May 2003), so should be a safe assumption for EABI + binaries. */ + +static const char eabi_linux_arm_le_breakpoint[] = { 0xf0, 0x01, 0xf0, 0xe7 }; + +static const char eabi_linux_arm_be_breakpoint[] = { 0xe7, 0xf0, 0x01, 0xf0 }; + +/* All the kernels which support Thumb support using a specific undefined + instruction for the Thumb breakpoint. */ + static const char arm_linux_thumb_be_breakpoint[] = {0xde, 0x01}; static const char arm_linux_thumb_le_breakpoint[] = {0x01, 0xde}; @@ -329,12 +342,18 @@ arm_linux_init_abi (struct gdbarch_info tdep->lowest_pc = 0x8000; if (info.byte_order == BFD_ENDIAN_BIG) { - tdep->arm_breakpoint = arm_linux_arm_be_breakpoint; + if (tdep->arm_abi == ARM_ABI_AAPCS) + tdep->arm_breakpoint = eabi_linux_arm_be_breakpoint; + else + tdep->arm_breakpoint = arm_linux_arm_be_breakpoint; tdep->thumb_breakpoint = arm_linux_thumb_be_breakpoint; } else { - tdep->arm_breakpoint = arm_linux_arm_le_breakpoint; + if (tdep->arm_abi == ARM_ABI_AAPCS) + tdep->arm_breakpoint = eabi_linux_arm_le_breakpoint; + else + tdep->arm_breakpoint = arm_linux_arm_le_breakpoint; tdep->thumb_breakpoint = arm_linux_thumb_le_breakpoint; } tdep->arm_breakpoint_size = sizeof (arm_linux_arm_le_breakpoint); Index: src/gdb/gdbserver/linux-arm-low.c =================================================================== --- src.orig/gdb/gdbserver/linux-arm-low.c 2005-06-12 21:59:22.000000000 -0400 +++ src/gdb/gdbserver/linux-arm-low.c 2005-11-08 17:54:24.000000000 -0500 @@ -70,6 +70,12 @@ arm_set_pc (CORE_ADDR pc) static const unsigned long arm_breakpoint = 0xef9f0001; #define arm_breakpoint_len 4 +/* For new EABI binaries. We recognize it regardless of which ABI + is used for gdbserver, so single threaded debugging should work + OK, but for multi-threaded debugging we only insert the current + ABI's breakpoint instruction. For now at least. */ +static const unsigned long arm_eabi_breakpoint = 0xe7f001f0; + static int arm_breakpoint_at (CORE_ADDR where) { @@ -79,8 +85,12 @@ arm_breakpoint_at (CORE_ADDR where) if (insn == arm_breakpoint) return 1; + if (insn == arm_eabi_breakpoint) + return 1; + /* If necessary, recognize more trap instructions here. GDB only uses the - one. */ + two. */ + return 0; } @@ -102,7 +112,11 @@ struct linux_target_ops the_low_target = arm_cannot_store_register, arm_get_pc, arm_set_pc, +#ifndef __ARM_EABI__ (const unsigned char *) &arm_breakpoint, +#else + (const unsigned char *) &arm_eabi_breakpoint, +#endif arm_breakpoint_len, arm_reinsert_addr, 0,