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
next prev 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).