Repository: pwndbg/pwndbg

Issue:
`context` gives wrong jump target for `jalr ra, ra, -0x16` in RISC-V
The jump target shown as annotation in the disassembly window is wrong:

```c++
pwndbg> si
pwndbg> set emulate on
pwndbg> context
 ► 0x1008e <_start+4>    jalr   ra, ra, -0x16               <main+8>
pwndbg> si
pwndbg> context
 ► 0x10074 <main>    addi   a7, zero, 0x40
```

Interestingly, `nearpc` shows the correct jump target:
```c++
 ► 0x1008e <_start+4>    jalr   ra, ra, -0x16               <main>
 ```
A workaround is `set emulate off`.


### test binary
[Download test binary](https://github.com/pwndbg/pwndbg/files/15366965/riscv-emu-bug.bin.txt). I created it from:

```asm
# riscv32-unknown-linux-gnu-as -march=rv32imac2p0 -o riscv-emu-bug.o riscv-emu-bug.s
# riscv32-unknown-linux-gnu-ld --no-relax -o riscv-emu-bug riscv-emu-bug.o

.section .rodata

greeting: .asciz "Hello world\n"
.equ greetlen, . - greeting

.section .text
main:
        li  a7, 64         # write
        li  a0, 1
        la  a1, greeting
        li  a2, greetlen
        ecall
        ret

.global _start
_start:
        call main
        li  a7, 93         # exit
        li  a0, 0
        ecall
```


### version information

pwndbg version: a1ddb3c0cd5e480710aa48f04ac560d659731bd8 (my fork)
```
Platform: Linux-6.9.1-arch1-1-x86_64-with-glibc2.39
OS: Arch Linux
OS ABI: #1 SMP PREEMPT_DYNAMIC Fri, 17 May 2024 16:56:38 +0000
Architecture: x86_64
Endian: little
Charset: utf-8
Width: 119
Height: 58
Gdb:      14.2
Python:   3.12.3 (main, Apr 23 2024, 09:16:07) [GCC 13.2.1 20240417]
Pwndbg:   2024.02.14 build: a1ddb3c0
Capstone: 5.0.1280
Unicorn:  2.0.1
This GDB was configured as follows:
   configure --host=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu
	    --with-auto-load-dir=$debugdir:$datadir/auto-load
	    --with-auto-load-safe-path=$debugdir:$datadir/auto-load
	    --with-expat
	    --with-gdb-datadir=/build/share/gdb (relocatable)
	    --with-jit-reader-dir=/build/lib/gdb (relocatable)
	    --without-libunwind-ia64
	    --with-lzma
	    --without-babeltrace
	    --without-intel-pt
	    --with-xxhash
	    --with-python=/usr
	    --with-python-libdir=/usr/lib
	    --with-debuginfod
	    --with-curses
	    --with-guile
	    --without-amd-dbgapi
	    --enable-source-highlight
	    --enable-threading
	    --enable-tui
	    --with-system-readline
	    --with-separate-debug-dir=/build/lib/debug (relocatable)
	    --with-system-gdbinit=/etc/gdb/gdbinit
```



Discussion:

Resolving patch:
diff --git a/pwndbg/disasm/riscv.py b/pwndbg/disasm/riscv.py
--- a/pwndbg/disasm/riscv.py
+++ b/pwndbg/disasm/riscv.py
@@ -20,10 +20,10 @@ def _is_condition_taken(
         self, instruction: PwndbgInstruction, emu: Emulator | None
     ) -> InstructionCondition:
         # B-type instructions have two source registers that are compared
-        src1_unsigned = self.parse_register(instruction, instruction.op_find(CS_OP_REG, 1), emu)
+        src1_unsigned = instruction.op_find(CS_OP_REG, 1).before_value
         # compressed instructions c.beqz and c.bnez only use one register operand.
         if instruction.op_count(CS_OP_REG) > 1:
-            src2_unsigned = self.parse_register(instruction, instruction.op_find(CS_OP_REG, 2), emu)
+            src2_unsigned = instruction.op_find(CS_OP_REG, 2).before_value
         else:
             src2_unsigned = 0
 
@@ -96,7 +96,7 @@ def resolve_target(self, instruction: PwndbgInstruction, emu: Emulator | None, c
         # Determine the target address of the indirect jump
         if instruction.id in [RISCV_INS_JALR, RISCV_INS_C_JALR]:
             target = (
-                self.parse_register(instruction, instruction.op_find(CS_OP_REG, 1), emu)
+                instruction.op_find(CS_OP_REG, 1).before_value
                 + instruction.op_find(CS_OP_IMM, 1).imm
             ) & ptrmask
             # Clear the lowest bit without knowing the register width


Test patch: