On 12/09/2023 18.50, Peter Maydell wrote:
On Tue, 5 Sept 2023 at 12:50, Thomas Huth <[email protected]> wrote:
With these changes, it is now possible to compile the "risu" binary
for s390x hosts.
Acked-by: Ilya Leoshkevich <[email protected]>
Signed-off-by: Thomas Huth <[email protected]>
+/* reginfo_init: initialize with a ucontext */
+void reginfo_init(struct reginfo *ri, ucontext_t *uc)
+{
+ int i;
+
+ memset(ri, 0, sizeof(*ri));
+
+ ri->faulting_insn = *((uint32_t *) uc->uc_mcontext.psw.addr);
Here we extract the faulting instruction, assuming it to
be a 32-bit insn starting at uc_mcontext.psw.addr...
+ ri->psw_mask = uc->uc_mcontext.psw.mask;
+ ri->psw_addr = uc->uc_mcontext.psw.addr - image_start_address;
+
+ for (i = 0; i < 16; i++) {
+ ri->gregs[i] = uc->uc_mcontext.gregs[i];
+ }
+
+ memcpy(&ri->fpregs, &uc->uc_mcontext.fpregs, sizeof(fpregset_t));
+}
+void advance_pc(void *vuc)
+{
+ /*
+ * Note: The PSW address already points to the next instruction
+ * after we get a SIGILL, so we must not advance it here!
+ */
+ // ucontext_t *uc = (ucontext_t *) vuc;
+ // uc->uc_mcontext.psw.addr += 4;
...but here we say that psw.addr points to the instruction
*after* the faulting one.
These don't seem like they can both be correct?
Drat, you're right, thanks for the hint! The code in reginfo_init() is
wrong, it takes the instruction after the illegal one. It was just working
(wrongly, but without crashing) by accident here since the OP_TESTEND
instruction was preceeded by an OP_COMPARE instruction :-/
To get the address (and thus opcode) of the faulting instruction, I have to
use siginfo_t->si_addr instead of using the ucontext_t structure. I will fix
it in the next version.
Thomas