public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] aarch64: detect atomic sequences like other ll/sc architectures
@ 2014-03-24 16:11 Kyle McMartin
  2014-03-24 16:25 ` Pedro Alves
  2014-03-24 16:57 ` Joel Brobecker
  0 siblings, 2 replies; 6+ messages in thread
From: Kyle McMartin @ 2014-03-24 16:11 UTC (permalink / raw)
  To: gdb-patches

Add similar single-stepping over atomic sequences support like other
load-locked/store-conditional architectures (alpha, powerpc, arm, etc.)
do. Verified the decode_masked_match, and decode_bcond works against the
atomic sequences used in the Linux kernel atomic.h, and also gcc
libatomic. Thanks to Richard Henderson for feedback on my initial
attempt at this patch!

2014-03-23  Kyle McMartin  <kyle@redhat.com>

	* aarch64-tdep.c (aarch64_deal_with_atomic_sequence): New function.
	(aarch64_gdbarch_init): Handle single stepping of atomic sequences
	with aarch64_deal_with_atomic_sequence.

--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -2509,6 +2509,82 @@ value_of_aarch64_user_reg (struct frame_info *frame, const void *baton)
 }
 \f
 
+static int
+aarch64_deal_with_atomic_sequence (struct frame_info *frame)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct address_space *aspace = get_frame_address_space (frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  const int insn_size = 4;
+  const int atomic_sequence_length = 16; /* Instruction sequence length.  */
+  CORE_ADDR pc = get_frame_pc (frame);
+  CORE_ADDR breaks[2] = { -1, -1 };
+  CORE_ADDR loc = pc;
+  CORE_ADDR closing_insn = 0;
+  uint32_t insn = read_memory_unsigned_integer (loc, insn_size, byte_order);
+  int index;
+  int insn_count;
+  int bc_insn_count = 0; /* Conditional branch instruction count.  */
+  int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */
+
+  /* look for a load-exclusive to begin the sequence... */
+  if (!decode_masked_match(insn, 0x3fc00000, 0x08400000))
+    return 0;
+
+  for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
+    {
+      int32_t offset;
+      unsigned cond;
+
+      loc += insn_size;
+      insn = read_memory_unsigned_integer (loc, insn_size, byte_order);
+
+      /* look for a conditional branch to set a breakpoint on the destination. */
+      if (decode_bcond(loc, insn, &cond, &offset))
+	{
+
+	  if (bc_insn_count >= 1)
+	    return 0;
+
+	  breaks[1] = loc + offset;
+
+	  bc_insn_count++;
+	  last_breakpoint++;
+	}
+
+      /* and the matching store-exclusive to close it. */
+      if (decode_masked_match(insn, 0x3fc00000, 0x08000000))
+	{
+          closing_insn = loc;
+	  break;
+	}
+    }
+
+  /* didn't find a stxr to end the sequence... */
+  if (!closing_insn)
+    return 0;
+
+  loc += insn_size;
+  insn = read_memory_unsigned_integer (loc, insn_size, byte_order);
+
+  /* insert breakpoint at the end of the atomic sequence */
+  breaks[0] = loc;
+
+  /* check for duplicated breakpoints. also check for a breakpoint placed on
+   * the conditional branch destination isn't within the sequence. */
+  if (last_breakpoint &&
+      (breaks[1] == breaks[0] ||
+       (breaks[1] >= pc && breaks[1] <= closing_insn)))
+    last_breakpoint = 0;
+
+  /* insert the breakpoint at the end of the sequence, also possibly at the
+     conditional branch destination */
+  for (index = 0; index <= last_breakpoint; index++)
+    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+
+  return 1;
+}
+
 /* Initialize the current architecture based on INFO.  If possible,
    re-use an architecture from ARCHES, which is a list of
    architectures already created during this debugging session.
@@ -2624,6 +2700,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_breakpoint_from_pc (gdbarch, aarch64_breakpoint_from_pc);
   set_gdbarch_cannot_step_breakpoint (gdbarch, 1);
   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
+  /* Handles single stepping of atomic sequences.  */
+  set_gdbarch_software_single_step (gdbarch, aarch64_deal_with_atomic_sequence);
 
   /* Information about registers, etc.  */
   set_gdbarch_sp_regnum (gdbarch, AARCH64_SP_REGNUM);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aarch64: detect atomic sequences like other ll/sc architectures
  2014-03-24 16:11 [PATCH] aarch64: detect atomic sequences like other ll/sc architectures Kyle McMartin
@ 2014-03-24 16:25 ` Pedro Alves
  2014-03-24 16:28   ` Kyle McMartin
  2014-03-24 16:57 ` Joel Brobecker
  1 sibling, 1 reply; 6+ messages in thread
From: Pedro Alves @ 2014-03-24 16:25 UTC (permalink / raw)
  To: Kyle McMartin; +Cc: gdb-patches

Hi!

On 03/24/2014 04:10 PM, Kyle McMartin wrote:
> Add similar single-stepping over atomic sequences support like other
> load-locked/store-conditional architectures (alpha, powerpc, arm, etc.)
> do. Verified the decode_masked_match, and decode_bcond works against the
> atomic sequences used in the Linux kernel atomic.h, and also gcc
> libatomic. Thanks to Richard Henderson for feedback on my initial
> attempt at this patch!

Thanks!  It'd be nice to have a test in the test suite.  Could you
add one?

PPC64's equivalent seems to be gdb.arch/ppc64-atomic-inst.c|exp.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aarch64: detect atomic sequences like other ll/sc architectures
  2014-03-24 16:25 ` Pedro Alves
@ 2014-03-24 16:28   ` Kyle McMartin
  0 siblings, 0 replies; 6+ messages in thread
From: Kyle McMartin @ 2014-03-24 16:28 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Mon, Mar 24, 2014 at 04:24:58PM +0000, Pedro Alves wrote:
> Hi!
> 
> On 03/24/2014 04:10 PM, Kyle McMartin wrote:
> > Add similar single-stepping over atomic sequences support like other
> > load-locked/store-conditional architectures (alpha, powerpc, arm, etc.)
> > do. Verified the decode_masked_match, and decode_bcond works against the
> > atomic sequences used in the Linux kernel atomic.h, and also gcc
> > libatomic. Thanks to Richard Henderson for feedback on my initial
> > attempt at this patch!
> 
> Thanks!  It'd be nice to have a test in the test suite.  Could you
> add one?
> 
> PPC64's equivalent seems to be gdb.arch/ppc64-atomic-inst.c|exp.
> 

Absolutely, I'll work on a set of tests for this today.

--Kyle

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aarch64: detect atomic sequences like other ll/sc architectures
  2014-03-24 16:11 [PATCH] aarch64: detect atomic sequences like other ll/sc architectures Kyle McMartin
  2014-03-24 16:25 ` Pedro Alves
@ 2014-03-24 16:57 ` Joel Brobecker
  2014-03-24 18:00   ` Richard Earnshaw
  1 sibling, 1 reply; 6+ messages in thread
From: Joel Brobecker @ 2014-03-24 16:57 UTC (permalink / raw)
  To: Kyle McMartin; +Cc: gdb-patches

Hello Kyle,

> 2014-03-23  Kyle McMartin  <kyle@redhat.com>
> 
> 	* aarch64-tdep.c (aarch64_deal_with_atomic_sequence): New function.
> 	(aarch64_gdbarch_init): Handle single stepping of atomic sequences
> 	with aarch64_deal_with_atomic_sequence.

Some small commments...

The convention for functions implementing gdbarch hooks has been
to name the callback (nearly) the same as the gdbarch hook. In your
case, the function should be called aarch64_software_single_step.

The rest of my comments are mostly Coding Style. GDB follows the GNU
Coding Style with some additional requirements.
https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards

> +static int
> +aarch64_deal_with_atomic_sequence (struct frame_info *frame)

An introductory comment is required for all functions, now.
In this case, since it implements a gdbarch hook which is expected
to be already documented (in gdbarch.sh, gdbarch.h), you only need
to say:

/* Implements the "software_single_step" gdbarch method.  */

I would probably add a comment explaining that you only deal with
atomic sequences in this implementation.  That way, we know why
you had to implement that hook for AArch64, and what its scope is;
and you then won't need to add the comment next to the
set_gdbarch_software_single_step call.

> +{
> +  struct gdbarch *gdbarch = get_frame_arch (frame);
> +  struct address_space *aspace = get_frame_address_space (frame);
> +  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> +  const int insn_size = 4;
> +  const int atomic_sequence_length = 16; /* Instruction sequence length.  */
> +  CORE_ADDR pc = get_frame_pc (frame);
> +  CORE_ADDR breaks[2] = { -1, -1 };
> +  CORE_ADDR loc = pc;
> +  CORE_ADDR closing_insn = 0;
> +  uint32_t insn = read_memory_unsigned_integer (loc, insn_size, byte_order);
> +  int index;
> +  int insn_count;
> +  int bc_insn_count = 0; /* Conditional branch instruction count.  */
> +  int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */
> +
> +  /* look for a load-exclusive to begin the sequence... */
> +  if (!decode_masked_match(insn, 0x3fc00000, 0x08400000))

Missing space before the '('.

> +    return 0;
> +
> +  for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
> +    {
> +      int32_t offset;
> +      unsigned cond;
> +
> +      loc += insn_size;
> +      insn = read_memory_unsigned_integer (loc, insn_size, byte_order);
> +
> +      /* look for a conditional branch to set a breakpoint on the destination. */

This line looks too long?

> +      if (decode_bcond(loc, insn, &cond, &offset))

Missing space before '('.

> +	{
> +
> +	  if (bc_insn_count >= 1)
> +	    return 0;
> +
> +	  breaks[1] = loc + offset;
> +
> +	  bc_insn_count++;
> +	  last_breakpoint++;
> +	}
> +
> +      /* and the matching store-exclusive to close it. */
> +      if (decode_masked_match(insn, 0x3fc00000, 0x08000000))

Same here...

> +	{
> +          closing_insn = loc;
> +	  break;
> +	}
> +    }
> +
> +  /* didn't find a stxr to end the sequence... */
> +  if (!closing_insn)
> +    return 0;
> +
> +  loc += insn_size;
> +  insn = read_memory_unsigned_integer (loc, insn_size, byte_order);
> +
> +  /* insert breakpoint at the end of the atomic sequence */
> +  breaks[0] = loc;
> +
> +  /* check for duplicated breakpoints. also check for a breakpoint placed on
> +   * the conditional branch destination isn't within the sequence. */

No '*' on the second line...

> +  if (last_breakpoint &&
> +      (breaks[1] == breaks[0] ||
> +       (breaks[1] >= pc && breaks[1] <= closing_insn)))

Binary operators should be at the start of the next line.

> +    last_breakpoint = 0;
> +
> +  /* insert the breakpoint at the end of the sequence, also possibly at the
> +     conditional branch destination */
> +  for (index = 0; index <= last_breakpoint; index++)
> +    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
> +
> +  return 1;
> +}
> +
>  /* Initialize the current architecture based on INFO.  If possible,
>     re-use an architecture from ARCHES, which is a list of
>     architectures already created during this debugging session.
> @@ -2624,6 +2700,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>    set_gdbarch_breakpoint_from_pc (gdbarch, aarch64_breakpoint_from_pc);
>    set_gdbarch_cannot_step_breakpoint (gdbarch, 1);
>    set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
> +  /* Handles single stepping of atomic sequences.  */
> +  set_gdbarch_software_single_step (gdbarch, aarch64_deal_with_atomic_sequence);
>  
>    /* Information about registers, etc.  */
>    set_gdbarch_sp_regnum (gdbarch, AARCH64_SP_REGNUM);

Thanks!
-- 
Joel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aarch64: detect atomic sequences like other ll/sc architectures
  2014-03-24 16:57 ` Joel Brobecker
@ 2014-03-24 18:00   ` Richard Earnshaw
  2014-03-27  1:52     ` Kyle McMartin
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Earnshaw @ 2014-03-24 18:00 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: Kyle McMartin, gdb-patches

On 24/03/14 16:57, Joel Brobecker wrote:
> Hello Kyle,
>> +      /* look for a conditional branch to set a breakpoint on the destination. */
> 
> This line looks too long?

Also, comments are full sentences, so begin with a capital letter and
end with a full stop and two spaces.

>> +      /* and the matching store-exclusive to close it. */
>> +      if (decode_masked_match(insn, 0x3fc00000, 0x08000000))
> 
> Same here...

If you really need a continuation comment like this, then end the
previous one with "..." and start the current one with "... and".
Otherwise, this should be re-written as a stand-alone sentence.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aarch64: detect atomic sequences like other ll/sc architectures
  2014-03-24 18:00   ` Richard Earnshaw
@ 2014-03-27  1:52     ` Kyle McMartin
  0 siblings, 0 replies; 6+ messages in thread
From: Kyle McMartin @ 2014-03-27  1:52 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: Joel Brobecker, gdb-patches

On Mon, Mar 24, 2014 at 06:00:47PM +0000, Richard Earnshaw wrote:
> On 24/03/14 16:57, Joel Brobecker wrote:
> > Hello Kyle,
> >> +      /* look for a conditional branch to set a breakpoint on the destination. */
> > 
> > This line looks too long?
> 
> Also, comments are full sentences, so begin with a capital letter and
> end with a full stop and two spaces.
> 
> >> +      /* and the matching store-exclusive to close it. */
> >> +      if (decode_masked_match(insn, 0x3fc00000, 0x08000000))
> > 
> > Same here...
> 
> If you really need a continuation comment like this, then end the
> previous one with "..." and start the current one with "... and".
> Otherwise, this should be re-written as a stand-alone sentence.
> 

Thanks very much, I've just posted a v2 which I hope addresses your
issues with my patch (and adds a testcase.)

regards, Kyle

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-03-27  1:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-24 16:11 [PATCH] aarch64: detect atomic sequences like other ll/sc architectures Kyle McMartin
2014-03-24 16:25 ` Pedro Alves
2014-03-24 16:28   ` Kyle McMartin
2014-03-24 16:57 ` Joel Brobecker
2014-03-24 18:00   ` Richard Earnshaw
2014-03-27  1:52     ` Kyle McMartin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).