the disasm doesn't show labels on invalid opcode, but
that's convenient when debugging.
one can argue it's not really efficient here, because two cycles are wastet.
imho that's not true, since modern x86 cpu's eliminate such instructions
sequences.
we could benchmark/test that, but well, it's just on the first hit, so suck it.
newNamedLabel (toString l) >>= defineLabel
-- causes SIGILL. in the signal handler we patch it to the acutal call.
-- place a nop at the end, therefore the disasm doesn't screw up
newNamedLabel (toString l) >>= defineLabel
-- causes SIGILL. in the signal handler we patch it to the acutal call.
-- place a nop at the end, therefore the disasm doesn't screw up
- emit32 (0xffffffff :: Word32) >> emit8 (0x90 :: Word8)
+ emit32 (0xffff9090 :: Word32) >> emit8 (0x90 :: Word8)
-- discard arguments on stack
let argcnt = (methodGetArgsCount cls cpidx) * 4
when (argcnt > 0) (add esp argcnt)
-- discard arguments on stack
let argcnt = (methodGetArgsCount cls cpidx) * 4
when (argcnt > 0) (add esp argcnt)
void callertrap(int nSignal, siginfo_t *info, void *ctx)
{
struct ucontext *uctx = (struct ucontext *) ctx;
void callertrap(int nSignal, siginfo_t *info, void *ctx)
{
struct ucontext *uctx = (struct ucontext *) ctx;
- unsigned int from = (unsigned int) uctx->uc_mcontext.eip;
+ unsigned int from = (unsigned int) uctx->uc_mcontext.eip - 2;
unsigned int patchme = getMethodEntry(from, method_map, caller_map);
printf("callertrap(mctx) by 0x%08x\n", from);
unsigned int patchme = getMethodEntry(from, method_map, caller_map);
printf("callertrap(mctx) by 0x%08x\n", from);
*insn = 0xe8; // call opcode
printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
printf("*to_patch: 0x%08x\n", *to_patch);
*insn = 0xe8; // call opcode
printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
printf("*to_patch: 0x%08x\n", *to_patch);
- if (*to_patch != 0x90ffffff) {
+ if (*to_patch != 0x90ffff90) {
printf("something is wrong here. abort\n");
exit(0);
}
printf("something is wrong here. abort\n");
exit(0);
}