Merge pull request #8388 from avagin:arm64-regs

PiperOrigin-RevId: 502688823
This commit is contained in:
gVisor bot
2023-01-17 14:30:03 -08:00
3 changed files with 62 additions and 0 deletions
+31
View File
@@ -17,6 +17,37 @@
package linux
const (
//PSR bits
PSR_MODE_EL0t = 0x00000000
PSR_MODE_EL1t = 0x00000004
PSR_MODE_EL1h = 0x00000005
PSR_MODE_EL2t = 0x00000008
PSR_MODE_EL2h = 0x00000009
PSR_MODE_EL3t = 0x0000000c
PSR_MODE_EL3h = 0x0000000d
PSR_MODE_MASK = 0x0000000f
// AArch32 CPSR bits
PSR_MODE32_BIT = 0x00000010
// AArch64 SPSR bits
PSR_F_BIT = 0x00000040
PSR_I_BIT = 0x00000080
PSR_A_BIT = 0x00000100
PSR_D_BIT = 0x00000200
PSR_BTYPE_MASK = 0x00000c00
PSR_SSBS_BIT = 0x00001000
PSR_PAN_BIT = 0x00400000
PSR_UAO_BIT = 0x00800000
PSR_DIT_BIT = 0x01000000
PSR_TCO_BIT = 0x02000000
PSR_V_BIT = 0x10000000
PSR_C_BIT = 0x20000000
PSR_Z_BIT = 0x40000000
PSR_N_BIT = 0x80000000
)
// PtraceRegs is the set of CPU registers exposed by ptrace. Source:
// syscall.PtraceRegs.
//
+3
View File
@@ -196,6 +196,9 @@ func (s *State) PtraceSetRegs(src io.Reader) (int, error) {
return 0, err
}
regs.UnmarshalUnsafe(buf)
if !regs.validRegs() {
return 0, linuxerr.EINVAL
}
s.Regs = regs
return ptraceRegistersSize, nil
}
+28
View File
@@ -138,6 +138,29 @@ func (c *Context64) SignalSetup(st *Stack, act *linux.SigAction, info *linux.Sig
return nil
}
// SPSR_ELx bits which are always architecturally RES0 per ARM DDI 0487D.a.
const _SPSR_EL1_AARCH64_RES0_BITS = uint64(0xffffffff0cdfe020)
func (regs *Registers) userMode() bool {
return (regs.Pstate & linux.PSR_MODE_MASK) == linux.PSR_MODE_EL0t
}
func (regs *Registers) validRegs() bool {
regs.Pstate &= ^_SPSR_EL1_AARCH64_RES0_BITS
if regs.userMode() && (regs.Pstate&linux.PSR_MODE32_BIT) == 0 &&
(regs.Pstate&linux.PSR_D_BIT) == 0 &&
(regs.Pstate&linux.PSR_A_BIT) == 0 &&
(regs.Pstate&linux.PSR_I_BIT) == 0 &&
(regs.Pstate&linux.PSR_F_BIT) == 0 {
return true
}
// Force PSR to a valid 64-bit EL0t
regs.Pstate &= linux.PSR_N_BIT | linux.PSR_Z_BIT | linux.PSR_C_BIT | linux.PSR_V_BIT
return false
}
// SignalRestore implements Context.SignalRestore.
func (c *Context64) SignalRestore(st *Stack, rt bool, featureSet cpuid.FeatureSet) (linux.SignalSet, linux.SignalStack, error) {
// Copy out the stack frame.
@@ -156,6 +179,10 @@ func (c *Context64) SignalRestore(st *Stack, rt bool, featureSet cpuid.FeatureSe
c.Regs.Sp = uc.MContext.Sp
c.Regs.Pstate = uc.MContext.Pstate
if !c.Regs.validRegs() {
return 0, linux.SignalStack{}, unix.EFAULT
}
// Restore floating point state.
l := len(c.sigFPState)
if l > 0 {
@@ -170,6 +197,7 @@ func (c *Context64) SignalRestore(st *Stack, rt bool, featureSet cpuid.FeatureSe
// don't bother to do anything fancy with the floating point
// state.
log.Warningf("sigreturn unable to restore application fpstate")
return 0, linux.SignalStack{}, unix.EFAULT
}
return uc.Sigset, uc.Stack, nil