From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19194 invoked by alias); 2 Mar 2007 12:47:48 -0000 Received: (qmail 19178 invoked by uid 22791); 2 Mar 2007 12:47:46 -0000 X-Spam-Check-By: sourceware.org Received: from inet-tsb5.toshiba.co.jp (HELO inet-tsb5.toshiba.co.jp) (202.33.96.24) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 02 Mar 2007 12:47:39 +0000 Received: from tsb-wall.toshiba.co.jp ([133.199.160.134]) by inet-tsb5.toshiba.co.jp with ESMTP id l22ClZCS011468 for ; Fri, 2 Mar 2007 21:47:35 +0900 (JST) Received: (from root@localhost) by tsb-wall.toshiba.co.jp id l22ClZnH020267 for gdb-patches@sourceware.org; Fri, 2 Mar 2007 21:47:35 +0900 (JST) Received: from ovp1.toshiba.co.jp [133.199.192.124] by tsb-wall.toshiba.co.jp with ESMTP id XAA20266; Fri, 2 Mar 2007 21:47:35 +0900 Received: from mx12.toshiba.co.jp (localhost [127.0.0.1]) by ovp1.toshiba.co.jp with ESMTP id l22ClY8S018185 for ; Fri, 2 Mar 2007 21:47:34 +0900 (JST) Received: from mx.tjsys.co.jp by toshiba.co.jp id l22ClYGJ017561; Fri, 2 Mar 2007 21:47:34 +0900 (JST) Received: from is-com10 (IDENT:U2FsdGVkX18nLa9p7FapBTbVM8Cale0i5uZSk1dHF+k@filtering.tjsys.co.jp [157.79.3.71]) by mx.tjsys.co.jp (8.12.11/8.12.11) with SMTP id l22ClXkg020950 for ; Fri, 2 Mar 2007 21:47:33 +0900 (JST) Received: from localhost ([157.79.51.133]) by ims.tjsys.co.jp (iPlanet Messaging Server 5.2 HotFix 2.10 (built Dec 26 2005)) with ESMTP id <0JEA0005O0V5J9@ims.tjsys.co.jp> for gdb-patches@sourceware.org; Fri, 02 Mar 2007 21:47:29 +0900 (JST) Date: Fri, 02 Mar 2007 12:47:00 -0000 From: Emi SUZUKI Subject: Re: [patch] "single step" atomic instruction sequences as a whole. In-reply-to: <1172678940.20041.13.camel@localhost> To: gdb-patches@sourceware.org Message-id: <20070302.214729.183026252.emi-suzuki@tjsys.co.jp> MIME-version: 1.0 X-Mailer: Mew version 5.2 on Emacs 22.0.91 / Mule 5.0 (SAKAKI) Content-type: Multipart/Mixed; boundary="--Next_Part(Fri_Mar__2_21_47_29_2007_455)--" Content-transfer-encoding: 7bit References: <20070228.170713.193706115.emi-suzuki@tjsys.co.jp> <20070228114545.GB4620@caradoc.them.org> <1172678940.20041.13.camel@localhost> X-WAuditID: 0703022147290000022085 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-03/txt/msg00016.txt.bz2 ----Next_Part(Fri_Mar__2_21_47_29_2007_455)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-length: 2315 Hello Luis, From: Luis Machado Subject: Re: [patch] "single step" atomic instruction sequences as a whole. Date: Wed, 28 Feb 2007 13:09:00 -0300 > Also, i haven't been able to reproduce the issue related at this post: > (http://sourceware.org/ml/gdb-patches/2006-09/msg00060.html) I think one of the reasons why is that you didn't build the target as Emre did; 'atomic_dec' seemed to be inline expanded in that target. I could get it with -O3 option of gcc-4.1.0 on my machine running FC5. And I could reproduce the issue with your patch by setting a breakpoint at where 'printf' preceded by 'atomic_dec' is before running the target. But the fix is fairly easy: =================================================================== diff -u rs6000-tdep.c.old rs6000-tdep.c --- rs6000-tdep.c.old 2007-03-02 19:33:12.000000000 +0900 +++ rs6000-tdep.c 2007-03-02 19:34:07.000000000 +0900 @@ -764,7 +764,7 @@ if (last_break && breaks[1] == breaks[0]) last_break = 0; - for (i= 0; i < last_break; ++i) + 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"), diff -u ppc-linux-tdep.c.old ppc-linux-tdep.c --- ppc-linux-tdep.c.old 2007-03-02 19:33:33.000000000 +0900 +++ ppc-linux-tdep.c 2007-03-02 19:33:54.000000000 +0900 @@ -996,7 +996,7 @@ if (last_break && breaks[1] == breaks[0]) last_break = 0; - for (i= 0; i < last_break; ++i) + 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"), =================================================================== Another thing I want to notice you about Paul's patch is that the patch for ppc-linux-tdep.c is not needed at all: they do exactly the same and RS6000 is the superset of PowerPC. And I think that the load or store instructions which deal with doublewords can be appeared as a part of the atomic sequence; Paul's patch doesn't check it. But maybe not needed for now. BTW, I had another mistake on my patch send last time... Please replace the attached one. My best regards, -- Emi SUZUKI ----Next_Part(Fri_Mar__2_21_47_29_2007_455)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rs6000-atomic-sequence_070302.diff" Content-length: 7042 diff -uBbEw -ruN -x CVS src/gdb/config/rs6000/tm-rs6000.h gdb/gdb/config/rs6000/tm-rs6000.h --- src/gdb/config/rs6000/tm-rs6000.h 2007-03-02 21:42:44.000000000 +0900 +++ gdb/gdb/config/rs6000/tm-rs6000.h 2007-03-02 21:17:31.000000000 +0900 @@ -30,3 +30,9 @@ #define PROCESS_LINENUMBER_HOOK() aix_process_linenos () extern void aix_process_linenos (void); +extern int rs6000_software_single_step_p (void); + +#ifdef SOFTWARE_SINGLE_STEP_P +#undef SOFTWARE_SINGLE_STEP_P +#endif +#define SOFTWARE_SINGLE_STEP_P() rs6000_software_single_step_p() diff -uBbEw -ruN -x CVS src/gdb/infrun.c gdb/gdb/infrun.c --- src/gdb/infrun.c 2007-03-02 21:42:43.000000000 +0900 +++ gdb/gdb/infrun.c 2007-03-02 21:28:25.000000000 +0900 @@ -556,7 +556,9 @@ if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here) SKIP_PERMANENT_BREAKPOINT (); - if (SOFTWARE_SINGLE_STEP_P () && step) + if (step) + { + if (SOFTWARE_SINGLE_STEP_P ()) { /* Do it the hard way, w/temp breakpoints */ SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ ); @@ -565,6 +567,8 @@ /* and do not pull these breakpoints until after a `wait' in `wait_for_inferior' */ singlestep_breakpoints_inserted_p = 1; + } + singlestep_ptid = inferior_ptid; singlestep_pc = read_pc (); } @@ -1565,8 +1569,6 @@ if (stepping_past_singlestep_breakpoint) { - gdb_assert (SOFTWARE_SINGLE_STEP_P () - && singlestep_breakpoints_inserted_p); gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid)); gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid)); @@ -1579,9 +1581,13 @@ { if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n"); + + if (singlestep_breakpoints_inserted_p) + { /* Pull the single step breakpoints out of the target. */ SOFTWARE_SINGLE_STEP (0, 0); singlestep_breakpoints_inserted_p = 0; + } ecs->random_signal = 0; @@ -1615,7 +1621,7 @@ if (!breakpoint_thread_match (stop_pc, ecs->ptid)) thread_hop_needed = 1; } - else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + else if (singlestep_breakpoints_inserted_p) { /* We have not context switched yet, so this should be true no matter which thread hit the singlestep breakpoint. */ @@ -1686,7 +1692,7 @@ /* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */ - if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + if (singlestep_breakpoints_inserted_p) { /* Pull the single step breakpoints out of the target. */ SOFTWARE_SINGLE_STEP (0, 0); @@ -1735,7 +1741,7 @@ return; } } - else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + else if (singlestep_breakpoints_inserted_p) { sw_single_step_trap_p = 1; ecs->random_signal = 0; @@ -1757,7 +1763,7 @@ deprecated_context_hook (pid_to_thread_id (ecs->ptid)); } - if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + if (singlestep_breakpoints_inserted_p) { /* Pull the single step breakpoints out of the target. */ SOFTWARE_SINGLE_STEP (0, 0); diff -uBbEw -ruN -x CVS src/gdb/rs6000-tdep.c gdb/gdb/rs6000-tdep.c --- src/gdb/rs6000-tdep.c 2007-03-02 21:42:45.000000000 +0900 +++ gdb/gdb/rs6000-tdep.c 2007-03-02 21:15:39.000000000 +0900 @@ -696,6 +696,79 @@ return little_breakpoint; } +#define LWARX_MASK 0xfc0007fe +#define LWARX_INSTRUCTION 0x7C000028 +#define LDARX_INSTRUCTION 0x7C000108 +#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)) + +CORE_ADDR +rs6000_deal_with_atomic_sequence (CORE_ADDR pc, CORE_ADDR *branch) +{ + CORE_ADDR loc = pc; + CORE_ADDR bc = -1; + int insn = read_memory_integer (loc, PPC_INSN_SIZE); + int i; + + /* Assume all atomic sequences start with an lwarx instruction. */ + if ((insn & LWARX_MASK) != LWARX_INSTRUCTION + && (insn & LWARX_MASK) != LDARX_INSTRUCTION) + return -1; + + /* 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); + + /* At most one conditional branch instruction is between the lwarx + and stwcx. instructions. */ + if ((insn & BC_MASK) == BC_INSTRUCTION) + { + bc = IMMEDIATE_PART (insn); + if (!ABSOLUTE_P (insn)) + bc += 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) + error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence.")); + + loc += PPC_INSN_SIZE; + insn = read_memory_integer (loc, PPC_INSN_SIZE); + + if ((insn & BC_MASK) != BC_INSTRUCTION) + error (_("Tried to step over an atomic sequence of instructions but it did not end as expected.")); + + /* set the location of conditional branch instruction between the lwarx + and stwcx. instruction if any. */ + if (bc != loc) + *branch = bc; + else + *branch = -1; + + return loc; +} + +/* SOFTWARE_SINGLE_STEP_P */ +int +rs6000_software_single_step_p (void) +{ + CORE_ADDR branch; + return (rs6000_deal_with_atomic_sequence (read_pc (), &branch) != -1); +} /* AIX does not support PT_STEP. Simulate it. */ @@ -715,8 +788,20 @@ { loc = read_pc (); - insn = read_memory_integer (loc, 4); + /* check if running on an atomic sequence of instructions */ + breaks[0] = rs6000_deal_with_atomic_sequence (loc, &breaks[1]); + if (breaks[0] != -1) + { + printf_unfiltered (_("Stepping over an atomic sequence of instructions. \n\ +Beginning at %s, break at %s next time.\n"), + core_addr_to_string (loc), + core_addr_to_string (breaks[0])); + gdb_flush (gdb_stdout); + } + else + { + insn = read_memory_integer (loc, PPC_INSN_SIZE); breaks[0] = loc + breakp_sz; opcode = insn >> 26; breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); @@ -724,6 +809,7 @@ /* Don't put two breakpoints on the same address. */ if (breaks[1] == breaks[0]) breaks[1] = -1; + } for (ii = 0; ii < 2; ++ii) { @@ -3442,6 +3529,7 @@ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc); + set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step); /* Handle the 64-bit SVR4 minimal-symbol convention of using "FN" for the descriptor and ".FN" for the entry-point -- a user ----Next_Part(Fri_Mar__2_21_47_29_2007_455)----