From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29907 invoked by alias); 2 May 2008 18:30:41 -0000 Received: (qmail 29897 invoked by uid 22791); 2 May 2008 18:30:40 -0000 X-Spam-Check-By: sourceware.org Received: from igw3.br.ibm.com (HELO igw3.br.ibm.com) (32.104.18.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 02 May 2008 18:30:18 +0000 Received: from mailhub3.br.ibm.com (unknown [9.18.232.110]) by igw3.br.ibm.com (Postfix) with ESMTP id 20C853900C4 for ; Fri, 2 May 2008 15:16:14 -0300 (BRST) Received: from d24av01.br.ibm.com (d24av01.br.ibm.com [9.18.232.46]) by mailhub3.br.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m42IUGIT3920066 for ; Fri, 2 May 2008 15:30:16 -0300 Received: from d24av01.br.ibm.com (loopback [127.0.0.1]) by d24av01.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m42IUFb0007162 for ; Fri, 2 May 2008 15:30:15 -0300 Received: from [9.8.5.197] ([9.8.5.197]) by d24av01.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id m42IUEJs007125 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 2 May 2008 15:30:15 -0300 Subject: [PATCH] PPC - Stepping off breakpoints in non-stop mode From: Luis Machado Reply-To: luisgpm@linux.vnet.ibm.com To: gdb-patches@sourceware.org Content-Type: multipart/mixed; boundary="=-zJk/Q/1JvLyNl0pi1UsM" Date: Fri, 02 May 2008 20:26:00 -0000 Message-Id: <1209753019.7131.29.camel@gargoyle> Mime-Version: 1.0 X-Mailer: Evolution 2.12.1 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-05/txt/msg00110.txt.bz2 --=-zJk/Q/1JvLyNl0pi1UsM Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 380 Hi folks, This is the ppc-specific code to step off breakpoints in non-stop mode. The main code is the fixup function, responsible for making sure we have the correct PC after a displaced stepping has been concluded. It applies on top of Pedro and Jim's more general displaced stepping patch. Tested without regressions on PPC 32/64. Is this OK? Comments? Best regards, Luis --=-zJk/Q/1JvLyNl0pi1UsM Content-Disposition: attachment; filename=ppc_displaced.diff Content-Type: text/x-patch; name=ppc_displaced.diff; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-length: 5783 2008-05-02 Luis Machado * ppc-tdep.h: Define PPC_MAX_INSN_LEN, BRANCH_MASK, B_INSN, BC_INSN, LWARX_MASK, LWARX_INSTRUCTION, LDARX_INSTRUCTION, STWCX_MASK, STWCX_INSTRUCTION, STDCX_INSTRUCTION, BXL_INSN, BP_MASK and BP_INSN. * rs6000-tdep.c (ppc_displaced_step_fixup): New function. (deal_with_atomic_sequence): Update BC masks. (rs6000_gdbarch_init): Init displaced stepping infra-structure. Remove LWARX_MASK, LWARX_INSTRUCTION, LDARX_INSTRUCTION, STWCX_MASK, STWCX_INSTRUCTION, STDCX_INSTRUCTION, BC_MASK and BC_INSTRUCTION. Index: HEAD/gdb/ppc-tdep.h =================================================================== --- HEAD.orig/gdb/ppc-tdep.h 2008-05-01 14:00:40.000000000 -0700 +++ HEAD/gdb/ppc-tdep.h 2008-05-02 10:52:53.000000000 -0700 @@ -261,10 +261,28 @@ PPC_NUM_REGS }; +/* The length of the longest ppc instruction. */ +#define PPC_MAX_INSN_LEN (4) /* Instruction size. */ #define PPC_INSN_SIZE 4 +/* Instruction masks used during single-stepping of atomic sequences. */ +#define LWARX_MASK 0xfc0007fe +#define LWARX_INSTRUCTION 0x7c000028 +#define LDARX_INSTRUCTION 0x7c0000A8 +#define STWCX_MASK 0xfc0007ff +#define STWCX_INSTRUCTION 0x7c00012d +#define STDCX_INSTRUCTION 0x7c0001ad + +/* Instruction masks for displaced stepping. */ +#define BRANCH_MASK 0xfc000000 +#define BP_MASK 0xFC0007FE +#define B_INSN 0x48000000 +#define BC_INSN 0x40000000 +#define BXL_INSN 0x4c000000 +#define BP_INSN 0x7C000008 + /* Estimate for the maximum number of instrctions in a function epilogue. */ #define PPC_MAX_EPILOGUE_INSTRUCTIONS 52 Index: HEAD/gdb/rs6000-tdep.c =================================================================== --- HEAD.orig/gdb/rs6000-tdep.c 2008-04-30 22:05:39.000000000 -0700 +++ HEAD/gdb/rs6000-tdep.c 2008-05-02 11:22:04.000000000 -0700 @@ -985,16 +985,66 @@ return little_breakpoint; } - -/* Instruction masks used during single-stepping of atomic sequences. */ -#define LWARX_MASK 0xfc0007fe -#define LWARX_INSTRUCTION 0x7c000028 -#define LDARX_INSTRUCTION 0x7c0000A8 -#define STWCX_MASK 0xfc0007ff -#define STWCX_INSTRUCTION 0x7c00012d -#define STDCX_INSTRUCTION 0x7c0001ad -#define BC_MASK 0xfc000000 -#define BC_INSTRUCTION 0x40000000 +/* Fix up the state of registers and memory after having single-stepped + a displaced instruction. */ +void +ppc_displaced_step_fixup (struct gdbarch *gdbarch, + struct displaced_step_closure *closure, + CORE_ADDR from, CORE_ADDR to, + struct regcache *regs) +{ + /* Since we use simple_displaced_step_copy_insn, our closure is a + copy of the instruction. */ + unsigned int *insn = (unsigned int *) closure; + unsigned int opcode = (*insn & BRANCH_MASK); + int offset = 4; /* Default offset for non PC-relative instructions. */ + + if (debug_displaced) + fprintf_unfiltered (gdb_stdlog, + "displaced: (ppc) fixup (0x%s, 0x%s)\n", + paddr_nz (from), paddr_nz (to)); + + + /* Handle PC-relative branch instructions. */ + if ((opcode == B_INSN) || (opcode == BC_INSN) || (opcode == BXL_INSN)) + { + /* LK bit Indicates whether we should set the link register to point + to the next instruction or not. */ + char link_register_bit = (char) (*insn & 0x1); + unsigned long current_pc; + + /* Read the current PC value after the instruction has been executed + in a displaced location. Calculate the offset to be applied to the + original PC value before the displaced stepping. */ + regcache_cooked_read_unsigned (regs, gdbarch_pc_regnum (gdbarch), ¤t_pc); + offset = current_pc - to; + + if (debug_displaced) + fprintf_unfiltered (gdb_stdlog, + "displaced: (ppc) branch instruction: 0x%x\n" + "displaced: (ppc) adjusted PC from %s to %s\n", + *insn, paddr_nz (current_pc), paddr_nz (from + offset)); + + if (opcode != BXL_INSN) + { + /* AA bit indicating whether this is an absolute addressing or + PC-relative. */ + char absolute_addr_bit = (char) (*insn & 0x2); + + if (!absolute_addr_bit) + regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), from + offset); + } + + if (link_register_bit) + regcache_cooked_write_unsigned (regs, 67, from + 4); + } + /* Check for breakpoints in the inferior. If we've found one, place the PC + right at the breakpoint instruction. */ + else if ((*insn & BP_MASK) == BP_INSN) + regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), from); + else + regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), from + offset); +} /* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX instruction and ending with a STWCX/STDCX instruction. If such a sequence @@ -1032,7 +1082,7 @@ /* Assume that there is at most one conditional branch in the atomic sequence. If a conditional branch is found, put a breakpoint in its destination address. */ - if ((insn & BC_MASK) == BC_INSTRUCTION) + if ((insn & BRANCH_MASK) == BC_INSN) { if (bc_insn_count >= 1) return 0; /* More than one conditional branch found, fallback @@ -3821,6 +3871,17 @@ /* Put the _Decimal128 pseudo-registers after the SPE registers. */ tdep->ppc_dl0_regnum += 32; + /* Setup displaced stepping. */ + set_gdbarch_displaced_step_copy_insn (gdbarch, + simple_displaced_step_copy_insn); + set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup); + set_gdbarch_displaced_step_free_closure (gdbarch, + simple_displaced_step_free_closure); + set_gdbarch_displaced_step_location (gdbarch, + displaced_step_at_entry_point); + + set_gdbarch_max_insn_length (gdbarch, PPC_MAX_INSN_LEN); + return gdbarch; } --=-zJk/Q/1JvLyNl0pi1UsM--