Improved Windows ABI support
This commit is contained in:
parent
91a3ec9d52
commit
b3fec98baf
22 changed files with 124 additions and 32 deletions
|
@ -1,6 +0,0 @@
|
|||
package x86
|
||||
|
||||
// AlignStack aligns RSP on a 16-byte boundary.
|
||||
func AlignStack(code []byte) []byte {
|
||||
return append(code, 0x48, 0x83, 0xE4, 0xF0)
|
||||
}
|
|
@ -1,6 +1,31 @@
|
|||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/sizeof"
|
||||
)
|
||||
|
||||
// PushNumber pushes a number onto the stack.
|
||||
func PushNumber(code []byte, number int) []byte {
|
||||
length := sizeof.Signed(number)
|
||||
|
||||
if length >= 8 {
|
||||
panic("x86 does not support pushing 64-bit numbers")
|
||||
}
|
||||
|
||||
if length >= 2 {
|
||||
return append(
|
||||
code,
|
||||
0x68,
|
||||
byte(number),
|
||||
byte(number>>8),
|
||||
byte(number>>16),
|
||||
byte(number>>24),
|
||||
)
|
||||
}
|
||||
|
||||
return append(code, 0x6A, byte(number))
|
||||
}
|
||||
|
||||
// PushRegister pushes the value inside the register onto the stack.
|
||||
func PushRegister(code []byte, register cpu.Register) []byte {
|
||||
|
|
|
@ -8,6 +8,28 @@ import (
|
|||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestPushNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{0, []byte{0x6A, 0x00}},
|
||||
{1, []byte{0x6A, 0x01}},
|
||||
{-1, []byte{0x6A, 0xFF}},
|
||||
{127, []byte{0x6A, 0x7F}},
|
||||
{128, []byte{0x68, 0x80, 0x00, 0x00, 0x00}},
|
||||
{0xFF, []byte{0x68, 0xFF, 0x00, 0x00, 0x00}},
|
||||
{0xFFFF, []byte{0x68, 0xFF, 0xFF, 0x00, 0x00}},
|
||||
{0x7FFFFFFF, []byte{0x68, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("push %d", pattern.Number)
|
||||
code := x86.PushNumber(nil, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPushRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
|
|
|
@ -25,7 +25,7 @@ var (
|
|||
AllRegisters = []cpu.Register{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15}
|
||||
SyscallInputRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9}
|
||||
SyscallOutputRegisters = []cpu.Register{RAX, RCX, R11}
|
||||
GeneralRegisters = []cpu.Register{RBX, R12, R13, R14, R15, RCX, R11, RBP}
|
||||
GeneralRegisters = []cpu.Register{RBX, R12, R13, R14, R15, RCX, R11}
|
||||
InputRegisters = SyscallInputRegisters
|
||||
OutputRegisters = SyscallInputRegisters
|
||||
WindowsInputRegisters = []cpu.Register{RCX, RDX, R8, R9}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
)
|
||||
|
||||
func TestX86(t *testing.T) {
|
||||
assert.DeepEqual(t, x86.AlignStack(nil), []byte{0x48, 0x83, 0xE4, 0xF0})
|
||||
assert.DeepEqual(t, x86.Call(nil, 1), []byte{0xE8, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x86.CallAtAddress(nil, 1), []byte{0xFF, 0x15, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x86.ExtendRAXToRDX(nil), []byte{0x48, 0x99})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue