Re: gdb for Riscv, single stepping issue
Pedro Alves <[email protected]>
| Newsgroups | gmane.comp.gdb.devel |
|---|---|
| Message-ID | <[email protected]> |
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.