Here's a snippet from emulate_load_store_insn. See the way the sdl and sdr
are wrapped in fixups? Well, the fixups can't trigger: we get to
emulate_load_store_insn a second time, and we hit the fact that sdl_op has a
"goto sigbus" before we hit the fixup_exception call.
It doesn't much matter, the bug I'm working on is whatever caused the first
call. But we get a SIGBUS when arguably we ought to get a SIGSEGV.
case sd_op:
#ifdef CONFIG_MIPS64
/*
* A 32-bit kernel might be running on a 64-bit processor. But
* if we're on a 32-bit processor and an i-cache incoherency
* or race makes us see a 64-bit instruction here the sdl/sdr
* would blow up, so for now we don't handle unaligned 64-bit
* instructions on 32-bit kernels.
*/
if (verify_area(VERIFY_WRITE, addr, 8))
goto sigbus;
value = regs->regs[insn.i_format.rt];
__asm__ __volatile__ (
#ifdef __BIG_ENDIAN
"1:\tsdl\t%1,(%2)\n"
"2:\tsdr\t%1, 7(%2)\n\t"
#endif
#ifdef __LITTLE_ENDIAN
"1:\tsdl\t%1, 7(%2)\n"
"2:\tsdr\t%1, (%2)\n\t"
#endif
"li\t%0, 0\n"
"3:\n\t"
".section\t.fixup,\"ax\"\n\t"
"4:\tli\t%0, %3\n\t"
"j\t3b\n\t"
".previous\n\t"
".section\t__ex_table,\"a\"\n\t"
STR(PTR)"\t1b, 4b\n\t"
STR(PTR)"\t2b, 4b\n\t"
".previous"
: "=r" (res)
: "r" (value), "r" (addr), "i" (-EFAULT));
if (res)
goto fault;
break;
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
|