public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: John Baldwin <jhb@FreeBSD.org>
To: Pedro Alves <pedro@palves.net>,
	James Becker <james.becker@crossfire-tech.com>,
	gdb@sourceware.org
Subject: Re: gdb for Riscv, single stepping issue
Date: Wed, 29 Jun 2022 10:54:06 -0700	[thread overview]
Message-ID: <d44ecd93-b266-375d-81eb-061427888f8b@FreeBSD.org> (raw)
In-Reply-To: <6068e741-8f0f-53b3-0664-548a4930d92c@palves.net>

On 6/29/22 2:34 AM, Pedro Alves wrote:
> On 2022-06-28 16:52, John Baldwin wrote:
>> On 6/27/22 1:40 PM, James Becker wrote:
>>> Hello,
>>>
>>> I have a RISCV-EL2 core running in a Nexys A7 FPGA board.
>>>
>>> I have openocd for riscv running over jtag with a connection by
>>> riscv-gdb to the openocd instance at port 3333.
>>>
>>> Everything works fine, stepping, break points, load, view memory.
>>>
>>> But I have one issue: Some of the memory in my design is 4 byte
>>> aligned.  Its designed for fast instruction fetch, its known as ICCM.
>>>
>>> When I have code running in that memory, gdb still works fine for
>>> breakpoints, but it will not single step.
>>>
>>> Looking at the openocd debug files, it appears that gdb is attempting to
>>> do a 2 byte read as a part of the single stepping procedure.
>>>
>>> Since my memory does not support 2 byte reads or writes, this fails.
>>>
>>> Is there some way that gdb can be configured to not do any 2-byte word
>>> reads or writes during single stepping?  I can't seem to find any.
>>
>> Hmm, setting breakpoints tries to read 1 byte at a time unless you have
>> disabled compressed breakpoints.  It looks like as a local hack you could
>> change use-compressed-breakpoints to just read 4 bytes rather than 2
>> initially?  Perhaps this is upstreamable if you make it read 4 bytes if
>> the target address is 4 byte aligned and only fall back to reading 2 bytes
>> if it isn't?
>>
> 
> Is that from riscv_breakpoint_kind_from_pc?  That uses target_read_code,
> so I'd think that since it goes via the code cache, it would read a whole
> cache line at once, meaning 64 bytes (show code-cache, show dcache line-size).
> 
> OTOH, riscv_insn::fetch_instruction uses target_read_memory to read 2 bytes,
> so I wonder whether this is the access in question:
> 
>    /* All insns are at least 16 bits.  */
>    status = target_read_memory (addr, buf, 2);
>    if (status)
>      memory_error (TARGET_XFER_E_IO, addr);
> 
> Why is this using target_read_memory instead of target_read_code, though?
> If it did that, then the code cache would be involved here too, papering over
> the issue, presumably.
> 
> Curious that the Riscv stub behaves this way, though.  I mean, failing the
> access instead of reading in aligned 4 bytes chunks, and doing read-modify-write,
> if necessary, hiding the issue from GDB.  Even inf-ptrace.c handles unaligned
> reads/writes and shorter-than-word-sized reads/writes itself, like:
> 
> static ULONGEST
> inf_ptrace_peek_poke (ptid_t ptid, gdb_byte *readbuf,
> 		      const gdb_byte *writebuf,
> 		      ULONGEST addr, ULONGEST len)
> {
> ...
>    /* We transfer aligned words.  Thus align ADDR down to a word
>       boundary and determine how many bytes to skip at the
>       beginning.  */
> ...
>        /* Read the word, also when doing a partial word write.  */
>        if (readbuf != NULL || chunk < sizeof (PTRACE_TYPE_RET))
> 	{
> 
> 
> I guess this also affects the "x" command at least (e.g., "x/2b $pc"), since that
> doesn't use the code cache either.

Yes, I had reworked my e-mail part way through and I really meant to talk about
this code, not the breakpoint code.  I agree that target_read_code is probably
more correct in fetch_instruction and would in this case hide the odd behavior
of the stub:

diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 69f2123dcdb..09b2599e958 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1661,7 +1661,7 @@ riscv_insn::fetch_instruction (struct gdbarch *gdbarch,
    int instlen, status;
  
    /* All insns are at least 16 bits.  */
-  status = target_read_memory (addr, buf, 2);
+  status = target_read_code (addr, buf, 2);
    if (status)
      memory_error (TARGET_XFER_E_IO, addr);
  
@@ -1672,7 +1672,7 @@ riscv_insn::fetch_instruction (struct gdbarch *gdbarch,
  
    if (instlen > 2)
      {
-      status = target_read_memory (addr + 2, buf + 2, instlen - 2);
+      status = target_read_code (addr + 2, buf + 2, instlen - 2);
        if (status)
  	memory_error (TARGET_XFER_E_IO, addr + 2);
      }


-- 
John Baldwin

  parent reply	other threads:[~2022-06-29 17:54 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-27 20:40 James Becker
2022-06-28 15:52 ` John Baldwin
2022-06-29  9:34   ` Pedro Alves
2022-06-29 16:27     ` James Becker
2022-06-29 17:54     ` John Baldwin [this message]
2022-06-30  9:40       ` Pedro Alves
2022-07-03  3:58         ` James Becker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d44ecd93-b266-375d-81eb-061427888f8b@FreeBSD.org \
    --to=jhb@freebsd.org \
    --cc=gdb@sourceware.org \
    --cc=james.becker@crossfire-tech.com \
    --cc=pedro@palves.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).