From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23174 invoked by alias); 28 Apr 2007 23:31:35 -0000 Received: (qmail 23161 invoked by uid 22791); 28 Apr 2007 23:31:34 -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; Sun, 29 Apr 2007 00:31:30 +0100 Received: from mailhub1.br.ibm.com (mailhub1 [9.18.232.109]) by igw2.br.ibm.com (Postfix) with ESMTP id 9D0FF5BDE8 for ; Sat, 28 Apr 2007 20:24:19 -0300 (BRT) Received: from d24av02.br.ibm.com (d24av02.br.ibm.com [9.18.232.47]) by mailhub1.br.ibm.com (8.13.8/8.13.8/NCO v8.3) with ESMTP id l3SNVRj41261716 for ; Sat, 28 Apr 2007 20:31:27 -0300 Received: from d24av02.br.ibm.com (loopback [127.0.0.1]) by d24av02.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id l3SNULu8011224 for ; Sat, 28 Apr 2007 20:30:21 -0300 Received: from [9.18.198.122] ([9.18.198.122]) by d24av02.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id l3SNUJAi011208; Sat, 28 Apr 2007 20:30:20 -0300 Subject: [RFC] "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@sourceware.org In-Reply-To: <1176482181.20644.8.camel@localhost> 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> <1176482181.20644.8.camel@localhost> Content-Type: multipart/mixed; boundary="=-4xpih7/fqGlTqbxNEIDh" Date: Sat, 28 Apr 2007 23:34:00 -0000 Message-Id: <1177803081.6280.48.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/msg00387.txt.bz2 --=-4xpih7/fqGlTqbxNEIDh Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 291 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 thoughts and comments on that. I'm re-submitting this one as it didn't make its way to the list. Thanks, Luis --=-4xpih7/fqGlTqbxNEIDh 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: 4509 2007-04-13 Paul Gilliam 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-28 16:22:11.000000000 -0700 +++ gdb/rs6000-tdep.c 2007-04-28 16:25:17.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. */ @@ -737,7 +824,10 @@ insn = read_memory_integer (loc, 4); - breaks[0] = loc + breakp_sz; + 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]); @@ -3461,6 +3551,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 --=-4xpih7/fqGlTqbxNEIDh--