Well, I first tried that. But then realized it won't work. In order to
find where the true context is, I memcmp the 32 GPRGs from the os
context starting at a given address offset (I do this max 8 times). If
I change the value of a register in one of the contexts, they won't match anymore.
So I had to make changes in both. And since arch_os_get_context is
called on several occasions, I decided that it would be more beneficial
to first find it, store its address, then work with the false context
as usual, and then at the end transfer all registers.
- in a signal handler, when you make changes to the context (e.g.
arch_skip_next_instruction) nothing happens. It turns out that the context
you get passed is a read-only copy, and the real thing that gets copied back
to the caller before sigreturn is further down the stack. Moreover, due to
cache lineup, it is not on a fixed offset from SP, so I have to first find
it. Thus, a wrapper around the signal handlers (e.g. SIGTRAP, SIGSEGV, etc.)
first finds the offset of the real context (I named it Amber after Zelazny's
novels), and then before returning copies the contents of the context to
Amber. The sigreturn then copies the modifed Amber context to the caller.
Suddenly, the runtime started to execute cold-sbcl.core and all was ok,
until the first garbage collection when all hell broke (lose);
This reminds me of the problem with SPARC/Linux, way back when: again,
the context was somewhere on the stack (at a constant offset, in my
case), and what was in the third argument to the signal handler was not
documented and not useful. That's why there's the slightly weird
arch_os_get_context() call, where you could hook in your search for the