Subject: Re: COMPAT_LINUX: more hints
To: None <port-mips@netbsd.org>
From: Toru Nishimura <locore32@gaea.ocn.ne.jp>
List: port-mips
Date: 11/20/2001 00:16:23
Emmanuel Dreyfus <manu@netbsd.org> asked;

> Quick summary about where we are: signals reach the Linux process, the
> signal handler is run, but the Linux process crashes when the signal
> handler exits.
>   ...
> (gdb) x/20i $pc-32
> 0x7fffefcc:     nop
> 0x7fffefd0:     nop
> 0x7fffefd4:     nop
> 0x7fffefd8:     nop
> 0x7fffefdc:     nop
> 0x7fffefe0:     addiu   $a0,$sp,16   <-- this is the signal trampoline
> 0x7fffefe4:     li      $v0,119
> 0x7fffefe8:     syscall
> 0x7fffefec:     break
>   ...
> It seems I've gone through the signal trampoline. My first question is
> about the break instruction: what is it supposed to do in MIPS assembly
> exactly? I would have expected it to terminate my program immediatly...

The way how OS responds to BREAK instrunction is "open" to
implementors.  In this specific case, the process should be forced to
terminate.

BREAK can take a 20bit worth of "BREAK value" inside.  When OS
detects process made BREAK exception, the value is fetched by
trap() logic which decides what to do.  MIPS compiler produces
BREAK instructions around DIV arithmetic to trap DIV by ZERO
condition.  Another common BREAK usage is "instruction single
stepping" under OS'es control.

> Even more intersting: I used gdb to discover if yes or no I was
> executing the signal trampoline. In fact, the answer can be found in a
> simple kernel trace:
>
>   206 signal   PSIG  SIGHUP caught handler=0x400384 mask=() code=0x0
>   206 signal   CALL  write(0x1,0x30000000,0x30)
>   206 signal   GIO   fd 1 wrote 48 bytes
>       "Signal Handler: sig=1  code=0x0  scp=0x7ff9f8a8
>       "
>   206 signal   RET   write 48/0x30
>   206 signal   CALL  [-3881]
>   206 signal   RET   [-3881] -1 unknown errno 78
>
> Hence yes, I go through the signal trampoline, but it does not work
> because the system call which is called here is wrong: -3881 instead of
> 119.
>
> Second question: how could 119 be transformed into -3881? I think I need
> some input from someone which is confortable with the way system calls
> work on the MIPS...

Would the following code in syscall.c make any trouble?
        ov0 = code = frame->f_regs[V0] - SYSCALL_SHIFT;

Toru Nishimura