From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19319 invoked by alias); 3 May 2007 14:51:27 -0000 Received: (qmail 19306 invoked by uid 22791); 3 May 2007 14:51:25 -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; Thu, 03 May 2007 14:51:22 +0000 Received: from mailhub1.br.ibm.com (mailhub1 [9.18.232.109]) by igw2.br.ibm.com (Postfix) with ESMTP id C712F5BD6E for ; Thu, 3 May 2007 11:43:59 -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 l43EpGYs1089726 for ; Thu, 3 May 2007 11:51:18 -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 l43EoB6f019978 for ; Thu, 3 May 2007 11:50:11 -0300 Received: from dyn531804.br.ibm.com (dyn531804.br.ibm.com [9.18.238.71]) by d24av02.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id l43EoBrt019975; Thu, 3 May 2007 11:50:11 -0300 Subject: Re: [RFC] "single step" atomic instruction sequences as a whole on PPC From: Luis Machado Reply-To: luisgpm@linux.vnet.ibm.com To: uweigand@de.ibm.com Cc: gdb-patches@sourceware.org In-Reply-To: <200705021408.l42E8Qc0019267@dyn-9-152-216-62.boeblingen.de.ibm.com> References: <200705021408.l42E8Qc0019267@dyn-9-152-216-62.boeblingen.de.ibm.com> Content-Type: multipart/mixed; boundary="=-Px5yV+pgnHPlbuLLSsPF" Date: Thu, 03 May 2007 14:51:00 -0000 Message-Id: <1178203875.4375.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-05/txt/msg00042.txt.bz2 --=-Px5yV+pgnHPlbuLLSsPF Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 242 Ulrich, Thanks for the comments. I've modified the patch according to your suggestions. Any additional comments on it? Any suggestions for the duplicate breakpoint detection? Maybe it could be handled in a better way. Best Regards. Luis --=-Px5yV+pgnHPlbuLLSsPF 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: 4788 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-05-03 06:06:21.000000000 -0700 +++ gdb/rs6000-tdep.c 2007-05-03 07:45:09.000000000 -0700 @@ -719,8 +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 + +static int +deal_with_atomic_sequence(struct regcache *regcache) +{ + CORE_ADDR pc = read_pc (); + CORE_ADDR breaks[16] = {-1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1}; + CORE_ADDR branch_bp; /* Breakpoint at destination of a banch instruction */ + CORE_ADDR loc = pc; + int insn = read_memory_integer (loc, PPC_INSN_SIZE); + int insn_count; + int index; /* Index used for the "breaks" arrays */ + int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed) */ + const int atomic_sequence_length = 16; + const int opcode = BC_INSTRUCTION; /* Branch instruction's OPcode */ + + /* 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 "atomic_sequence_length + instructions. */ + for (insn_count = 0; insn_count < atomic_sequence_length ; ++insn_count) + { + loc += PPC_INSN_SIZE; + insn = read_memory_integer (loc, PPC_INSN_SIZE); + + /* Check for conditiconal branches in the middle of the sequence + and put breakpoints in their destinations */ + if ((insn & BC_MASK) == BC_INSTRUCTION) + { + branch_bp = branch_dest(opcode, insn, pc, breaks[0]); + + /* Make sure we don't have two breakpoints at the same address */ + for (index = 0; index <= last_breakpoint; index++) + breaks[last_breakpoint] = (breaks[last_breakpoint] == branch_bp)? + -1:branch_bp; + + if (breaks[last_breakpoint] != -1) + last_breakpoint++; + } -/* AIX does not support PT_STEP. Simulate it. */ + if ((insn & STWCX_MASK) == STWCX_INSTRUCTION + || (insn & STWCX_MASK) == STDCX_INSTRUCTION) + break; + } + + /* Assume that the atomic sequence ends with a stwcx/stdcx instruction */ + if ((insn & STWCX_MASK) != STWCX_INSTRUCTION + && (insn & STWCX_MASK) != STDCX_INSTRUCTION) + { + warning (_("\nTried 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)); + return 0; + } + + loc += PPC_INSN_SIZE; + insn = read_memory_integer (loc, PPC_INSN_SIZE); + + for (index = 0; index < last_breakpoint; index++) + if (loc == breaks[index]) + break; + + /* Insert a breakpoint right after the end of the atomic sequence */ + if (index == last_breakpoint) + breaks[last_breakpoint++] = loc; + + /* Effectively inserts all the breakpoints */ + for (index = 0; index < last_breakpoint; index++) + insert_single_step_breakpoint (breaks[index]); + + gdb_flush (gdb_stdout); + + return 1; +} + +/* AIX does not support PT_STEP. Simulate it. */ int rs6000_software_single_step (struct regcache *regcache) @@ -737,6 +822,9 @@ insn = read_memory_integer (loc, 4); + if (deal_with_atomic_sequence(regcache)) + return 1; + breaks[0] = loc + breakp_sz; opcode = insn >> 26; breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); @@ -3461,6 +3549,9 @@ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc); + /* Handles single stepping of atomic sequences */ + 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 --=-Px5yV+pgnHPlbuLLSsPF--