This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Fix rs6000 atomic sequence single step
- From: Alan Modra <amodra at gmail dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 17 Nov 2011 21:56:06 +1030
- Subject: Fix rs6000 atomic sequence single step
This fixes a bug in the powerpc branch destination calculation for
branches inside an atomic sequence, tidies a sign extension (*), and
extends the set of atomic sequences we handle a little. OK to apply?
*) E1 >> E2 invokes implementation defined behaviour when E1 has
signed type and negative value according to ISO/IEC 9899:1999 6.5.7
* rs6000-tdep.c (ppc_deal_with_atomic_sequence): Correct branch
destination calculation. Don't expect >> to sign extend. Don't
add a break if branch lands inside the sequence anywhere.
Index: gdb/rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.352
diff -u -p -r1.352 rs6000-tdep.c
--- gdb/rs6000-tdep.c 18 Mar 2011 18:52:31 -0000 1.352
+++ gdb/rs6000-tdep.c 17 Nov 2011 11:09:07 -0000
@@ -1116,8 +1116,8 @@ ppc_deal_with_atomic_sequence (struct fr
its destination address. */
if ((insn & BRANCH_MASK) == BC_INSN)
{
- int immediate = ((insn & ~3) << 16) >> 16;
- int absolute = ((insn >> 1) & 1);
+ int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000;
+ int absolute = insn & 2;
if (bc_insn_count >= 1)
return 0; /* More than one conditional branch found, fallback
@@ -1126,7 +1126,7 @@ ppc_deal_with_atomic_sequence (struct fr
if (absolute)
breaks[1] = immediate;
else
- breaks[1] = pc + immediate;
+ breaks[1] = loc + immediate;
bc_insn_count++;
last_breakpoint++;
@@ -1150,11 +1150,10 @@ ppc_deal_with_atomic_sequence (struct fr
breaks[0] = loc;
/* Check for duplicated breakpoints. Check also for a breakpoint
- placed (branch instruction's destination) at the stwcx/stdcx
- instruction, this resets the reservation and take us back to the
- lwarx/ldarx instruction at the beginning of the atomic sequence. */
- if (last_breakpoint && ((breaks[1] == breaks[0])
- || (breaks[1] == closing_insn)))
+ placed (branch instruction's destination) anywhere in sequence. */
+ if (last_breakpoint
+ && (breaks[1] == breaks[0]
+ || (breaks[1] >= pc && breaks[1] <= closing_insn)))
last_breakpoint = 0;
/* Effectively inserts the breakpoints. */
--
Alan Modra
Australia Development Lab, IBM