EDIT: Nevermind, this is a known issue in the 4.15 kernel; 4.19 fixes it.
Been experimenting with riscv-native GDB. Here’s my test program:
char text[] = "Vafgehpgvba frgf jnag gb or serr!";
// Don't use the stack, because sp isn't set up.
volatile int mywait = 0;
int main() {
asm volatile("ebreak");
// Doesn't actually go on the stack, because there are lots of GPRs.
int i = 0;
while (text[i]) {
char lower = text[i] | 32;
if (lower >= 'a' && lower <= 'm')
text[i] += 13;
else if (lower > 'm' && lower <= 'z')
text[i] -= 13;
i++;
}
}
The important part here is the inlined EBREAK instruction - this is a variant on an earlier test I did where I noticed the program counter was off when I inserted a breakpoint in GDB. I wanted to make sure it didn’t have something to do with GDB’s breakpoint insertion somehow messing up the PC.
Anyways, this is the decompiled object code:
00000000000103da <main>:
103da: 1101 addi sp,sp,-32
103dc: ec22 sd s0,24(sp)
103de: 1000 addi s0,sp,32
103e0: 9002 ebreak
103e2: 0001 nop
103e4: 67c9 lui a5,0x12
As can be seen, the ebreak instruction is at address 103e0. However, this is the output of the signal log in GDB for this program:
(gdb) run
LNW: waitpid(-1, ...) returned 1403, ERRNO-OK
LLW: waitpid 1403 received Trace/breakpoint trap (stopped)
target_fetch_registers (pc) = e403010000000000 0x103e4 66532
CSBB: process 1403 stopped by software breakpoint
LNW: waitpid(-1, ...) returned 0, ERRNO-OK
RSRL: NOT resuming LWP process 1403, has pending status
LLW: trap ptid is process 1403.
LLW: exit
infrun: target_wait (-1.0.0, status) =
infrun: 1403.1403.0 [process 1403],
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x103e4
As can be seen, stop_pc is at 103e4, instead of 103e0. This is the exact same thing I’ve seen when the breakpoint is manually inserted instead of an inlined EBREAK instruction causing it. You can also see the four-byte shift skips over the two-byte compressed NOP, so this could cause some serious problems if trying to debug a program with compressed instructions.
I’m wondering if this could have to do with the riscv linux kernel’s trap handler not properly decrementing the PC. If it’s not that, does anyone have other ideas as to what could be causing this?