github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/platform/kvm/testutil/testutil_amd64.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build amd64 16 17 package testutil 18 19 import ( 20 "reflect" 21 22 "github.com/SagerNet/gvisor/pkg/sentry/arch" 23 ) 24 25 // TwiddleSegments reads segments into known registers. 26 func TwiddleSegments() 27 28 // SetTestTarget sets the rip appropriately. 29 func SetTestTarget(regs *arch.Registers, fn func()) { 30 regs.Rip = uint64(reflect.ValueOf(fn).Pointer()) 31 } 32 33 // SetTouchTarget sets rax appropriately. 34 func SetTouchTarget(regs *arch.Registers, target *uintptr) { 35 if target != nil { 36 regs.Rax = uint64(reflect.ValueOf(target).Pointer()) 37 } else { 38 regs.Rax = 0 39 } 40 } 41 42 // RewindSyscall rewinds a syscall RIP. 43 func RewindSyscall(regs *arch.Registers) { 44 regs.Rip -= 2 45 } 46 47 // SetTestRegs initializes registers to known values. 48 func SetTestRegs(regs *arch.Registers) { 49 regs.R15 = 0x15 50 regs.R14 = 0x14 51 regs.R13 = 0x13 52 regs.R12 = 0x12 53 regs.Rbp = 0xb9 54 regs.Rbx = 0xb4 55 regs.R11 = 0x11 56 regs.R10 = 0x10 57 regs.R9 = 0x09 58 regs.R8 = 0x08 59 regs.Rax = 0x44 60 regs.Rcx = 0xc4 61 regs.Rdx = 0xd4 62 regs.Rsi = 0x51 63 regs.Rdi = 0xd1 64 regs.Rsp = 0x59 65 } 66 67 // CheckTestRegs checks that registers were twiddled per TwiddleRegs. 68 func CheckTestRegs(regs *arch.Registers, full bool) (err error) { 69 if need := ^uint64(0x15); regs.R15 != need { 70 err = addRegisterMismatch(err, "R15", regs.R15, need) 71 } 72 if need := ^uint64(0x14); regs.R14 != need { 73 err = addRegisterMismatch(err, "R14", regs.R14, need) 74 } 75 if need := ^uint64(0x13); regs.R13 != need { 76 err = addRegisterMismatch(err, "R13", regs.R13, need) 77 } 78 if need := ^uint64(0x12); regs.R12 != need { 79 err = addRegisterMismatch(err, "R12", regs.R12, need) 80 } 81 if need := ^uint64(0xb9); regs.Rbp != need { 82 err = addRegisterMismatch(err, "Rbp", regs.Rbp, need) 83 } 84 if need := ^uint64(0xb4); regs.Rbx != need { 85 err = addRegisterMismatch(err, "Rbx", regs.Rbx, need) 86 } 87 if need := ^uint64(0x10); regs.R10 != need { 88 err = addRegisterMismatch(err, "R10", regs.R10, need) 89 } 90 if need := ^uint64(0x09); regs.R9 != need { 91 err = addRegisterMismatch(err, "R9", regs.R9, need) 92 } 93 if need := ^uint64(0x08); regs.R8 != need { 94 err = addRegisterMismatch(err, "R8", regs.R8, need) 95 } 96 if need := ^uint64(0x44); regs.Rax != need { 97 err = addRegisterMismatch(err, "Rax", regs.Rax, need) 98 } 99 if need := ^uint64(0xd4); regs.Rdx != need { 100 err = addRegisterMismatch(err, "Rdx", regs.Rdx, need) 101 } 102 if need := ^uint64(0x51); regs.Rsi != need { 103 err = addRegisterMismatch(err, "Rsi", regs.Rsi, need) 104 } 105 if need := ^uint64(0xd1); regs.Rdi != need { 106 err = addRegisterMismatch(err, "Rdi", regs.Rdi, need) 107 } 108 if need := ^uint64(0x59); regs.Rsp != need { 109 err = addRegisterMismatch(err, "Rsp", regs.Rsp, need) 110 } 111 // Rcx & R11 are ignored if !full is set. 112 if need := ^uint64(0x11); full && regs.R11 != need { 113 err = addRegisterMismatch(err, "R11", regs.R11, need) 114 } 115 if need := ^uint64(0xc4); full && regs.Rcx != need { 116 err = addRegisterMismatch(err, "Rcx", regs.Rcx, need) 117 } 118 return 119 } 120 121 var fsData uint64 = 0x55 122 var gsData uint64 = 0x85 123 124 // SetTestSegments initializes segments to known values. 125 func SetTestSegments(regs *arch.Registers) { 126 regs.Fs_base = uint64(reflect.ValueOf(&fsData).Pointer()) 127 regs.Gs_base = uint64(reflect.ValueOf(&gsData).Pointer()) 128 } 129 130 // CheckTestSegments checks that registers were twiddled per TwiddleSegments. 131 func CheckTestSegments(regs *arch.Registers) (err error) { 132 if regs.Rax != fsData { 133 err = addRegisterMismatch(err, "Rax", regs.Rax, fsData) 134 } 135 if regs.Rbx != gsData { 136 err = addRegisterMismatch(err, "Rbx", regs.Rcx, gsData) 137 } 138 return 139 }