From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32286 invoked by alias); 13 Apr 2007 16:36:32 -0000 Received: (qmail 32270 invoked by uid 22791); 13 Apr 2007 16:36:31 -0000 X-Spam-Check-By: sourceware.org Received: from igw2.br.ibm.com (HELO igw2.br.ibm.com) (32.104.18.25) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 13 Apr 2007 17:36:28 +0100 Received: from mailhub3.br.ibm.com (mailhub3 [9.18.232.110]) by igw2.br.ibm.com (Postfix) with ESMTP id 3E95A5BF90 for ; Fri, 13 Apr 2007 13:29:50 -0300 (BRT) 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.3) with ESMTP id l3DGaM0u1736884 for ; Fri, 13 Apr 2007 13:36:22 -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 l3DGYMA5002911 for ; Fri, 13 Apr 2007 13:34:22 -0300 Received: from dyn531804.br.ibm.com (dyn531804.br.ibm.com [9.18.238.71]) by d24av01.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id l3DGYMmp002908; Fri, 13 Apr 2007 13:34:22 -0300 Subject: [patch] "single step" atomic instruction sequences as a whole on PPC From: Luis Machado Reply-To: luisgpm@linux.vnet.ibm.com To: Daniel Jacobowitz Cc: gdb-patches@gcc.gnu.org In-Reply-To: <20070413135710.GC12300@caradoc.them.org> References: <20070409021338.GA28612@caradoc.them.org> <200704092325.QAA13441@hpsje.cup.hp.com> <20070410120547.GB18255@caradoc.them.org> <20070410202213.GA778@caradoc.them.org> <20070413135710.GC12300@caradoc.them.org> Content-Type: multipart/mixed; boundary="=-M2Z7kqYbMDeE3Id+z+TN" Date: Fri, 13 Apr 2007 17:07:00 -0000 Message-Id: <1176482181.20644.8.camel@localhost> Mime-Version: 1.0 X-Mailer: Evolution 2.6.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: 2007-04/txt/msg00202.txt.bz2 --=-M2Z7kqYbMDeE3Id+z+TN Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 229 Daniel, Follows attached the ppc portion of the patch for single stepping of atomic instruction sequences. You did mention that it had some cosmetic issues, so i'd like to have your thoughts and comments on that. Thanks, Luis --=-M2Z7kqYbMDeE3Id+z+TN Content-Disposition: attachment; filename=ppc-atomic-single-stepping.diff Content-Type: text/x-patch; name=ppc-atomic-single-stepping.diff; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-length: 4466 2007-04-13 Luis Machado * rs6000-tdep.c: Defines masks for POWER instructions that set and use the reservation flag (LWARX,LDARX,STWCX,STDCX). * rs6000-tdep.c (deal_with_atomic_sequence): Handles single stepping through an atomic sequence of instructions. * rs6000-tdep.c (rs6000_software_single_step): Added a function call to check if we are stepping through an atomic sequence of instructions. * rs6000-tdep.c (rs6000_gdbarch_init): Initializes a function to check for atomic instruction sequences while single stepping. Index: gdb/rs6000-tdep.c =================================================================== --- gdb.orig/rs6000-tdep.c 2007-04-13 06:13:20.000000000 -0700 +++ gdb/rs6000-tdep.c 2007-04-13 08:52:43.000000000 -0700 @@ -719,6 +719,93 @@ return little_breakpoint; } +#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 +#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16) +#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1)) + +static int +deal_with_atomic_sequence (enum target_signal sig, int insert_breakpoints_p) +{ + CORE_ADDR pc = read_pc (); + CORE_ADDR breaks[2] = {-1, -1}; + CORE_ADDR loc = pc; + int insn = read_memory_integer (loc, PPC_INSN_SIZE); + int last_break = 0; + int i; + + if (insert_breakpoints_p) + { + + /* Assume all atomic sequences start with an lwarx or ldarx instruction. */ + if ((insn & LWARX_MASK) != LWARX_INSTRUCTION + && (insn & LWARX_MASK) != LDARX_INSTRUCTION) + return 0; + + /* Assume that no atomic sequence is longer than 6 instructions. */ + for (i = 1; i < 5; ++i) + { + loc += PPC_INSN_SIZE; + insn = read_memory_integer (loc, PPC_INSN_SIZE); + + /* Assume at most one conditional branch instruction between + the lwarx and stwcx instructions.*/ + if ((insn & BC_MASK) == BC_INSTRUCTION) + { + last_break = 1; + breaks[1] = IMMEDIATE_PART (insn); + if ( ! ABSOLUTE_P(insn)) + breaks[1] += loc; + continue; + } + + if ((insn & STWCX_MASK) == STWCX_INSTRUCTION + || (insn & STWCX_MASK) == STDCX_INSTRUCTION) + break; + } + + /* Assume that the atomic sequence ends with a stwcx instruction + followed by a conditional branch instruction. */ + if ((insn & STWCX_MASK) != STWCX_INSTRUCTION + && (insn & STWCX_MASK) != STDCX_INSTRUCTION) + warning (_("Tried to step over an atomic sequence of instructions at %s\n \ + but could not find the end of the sequence."), + core_addr_to_string(pc)); + + loc += PPC_INSN_SIZE; + insn = read_memory_integer (loc, PPC_INSN_SIZE); + + if ((insn & BC_MASK) != BC_INSTRUCTION) + warning (_("Tried to step over an atomic sequence of instructions at %s\n \ + but the instruction sequence ended in an unexpected way."), + core_addr_to_string(pc)); + + breaks[0] = loc; + + /* This should never happen, but make sure we don't put + two breakpoints on the same address. */ + if (last_break && breaks[1] == breaks[0]) + last_break = 0; + + for (i = 0; i <= last_break; ++i) + insert_single_step_breakpoint (breaks[i]); + + printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"), + core_addr_to_string (pc)); + + gdb_flush (gdb_stdout); + } + else + remove_single_step_breakpoints(); + + return 1; +} /* AIX does not support PT_STEP. Simulate it. */ @@ -740,6 +827,9 @@ insn = read_memory_integer (loc, 4); + if (deal_with_atomic_sequence (signal, insert_breakpoints_p)) + return 1; + breaks[0] = loc + breakp_sz; opcode = insn >> 26; breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); @@ -3467,6 +3557,9 @@ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc); + /* Watch for locking instruction sequences during single stepping */ + set_gdbarch_software_single_step(gdbarch, deal_with_atomic_sequence); + /* Handle the 64-bit SVR4 minimal-symbol convention of using "FN" for the descriptor and ".FN" for the entry-point -- a user specifying "break FN" will unexpectedly end up with a breakpoint --=-M2Z7kqYbMDeE3Id+z+TN--