Arm64 signal#2: signal support in arch module

SA_RESTORER is always used on Intel platform.
But this flag is optional on other platforms.

The vdso is enabled, so we can use the sigreturn trampolines
the vdso provides instead on Arm platform.

Signed-off-by: Bin Lu <bin.lu@arm.com>
This commit is contained in:
Bin Lu 2020-02-11 02:55:51 -05:00
parent 0dd9ee0d1e
commit 5eb41c8fba
2 changed files with 37 additions and 6 deletions

View File

@ -83,9 +83,12 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt
if ucSize < 0 {
panic("can't get size of UContext64")
}
// st.Arch.Width() is for the restorer address. sizeof(siginfo) == 128.
frameSize := int(st.Arch.Width()) + ucSize + 128
frameBottom := (sp-usermem.Addr(frameSize)) & ^usermem.Addr(15) - 8
// frameSize = ucSize + sizeof(siginfo).
// sizeof(siginfo) == 128.
// R30 stores the restorer address.
frameSize := ucSize + 128
frameBottom := (sp - usermem.Addr(frameSize)) & ^usermem.Addr(15)
sp = frameBottom + usermem.Addr(frameSize)
st.Bottom = sp
@ -115,12 +118,27 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt
c.Regs.Regs[0] = uint64(info.Signo)
c.Regs.Regs[1] = uint64(infoAddr)
c.Regs.Regs[2] = uint64(ucAddr)
c.Regs.Regs[30] = uint64(act.Restorer)
return nil
}
// SignalRestore implements Context.SignalRestore.
// Only used on intel.
func (c *context64) SignalRestore(st *Stack, rt bool) (linux.SignalSet, SignalStack, error) {
return 0, SignalStack{}, nil
// Copy out the stack frame.
var uc UContext64
if _, err := st.Pop(&uc); err != nil {
return 0, SignalStack{}, err
}
var info SignalInfo
if _, err := st.Pop(&info); err != nil {
return 0, SignalStack{}, err
}
// Restore registers.
c.Regs.Regs = uc.MContext.Regs
c.Regs.Pc = uc.MContext.Pc
c.Regs.Sp = uc.MContext.Sp
c.Regs.Pstate = uc.MContext.Pstate
return uc.Sigset, uc.Stack, nil
}

View File

@ -263,6 +263,19 @@ func (t *Task) deliverSignalToHandler(info *arch.SignalInfo, act arch.SignalAct)
if t.haveSavedSignalMask {
mask = t.savedSignalMask
}
// Set up the restorer.
// x86-64 should always uses SA_RESTORER, but this flag is optional on other platforms.
// Please see the linux code as reference:
// linux/arch/x86/kernel/signal.c:__setup_rt_frame()
// If SA_RESTORER is not configured, we can use the sigreturn trampolines
// the vdso provides instead.
// Please see the linux code as reference:
// linux/arch/arm64/kernel/signal.c:setup_return()
if act.Flags&linux.SA_RESTORER == 0 {
act.Restorer = t.MemoryManager().VDSOSigReturn()
}
if err := t.Arch().SignalSetup(st, &act, info, &alt, mask); err != nil {
return err
}