зеркало из https://github.com/golang/net.git
248 строки
4.7 KiB
Go
248 строки
4.7 KiB
Go
// Copyright 2016 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package bpf_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"golang.org/x/net/bpf"
|
|
)
|
|
|
|
func TestVMStoreScratchInvalidScratchRegisterTooSmall(t *testing.T) {
|
|
_, _, err := testVM(t, []bpf.Instruction{
|
|
bpf.StoreScratch{
|
|
Src: bpf.RegA,
|
|
N: -1,
|
|
},
|
|
bpf.RetA{},
|
|
})
|
|
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestVMStoreScratchInvalidScratchRegisterTooLarge(t *testing.T) {
|
|
_, _, err := testVM(t, []bpf.Instruction{
|
|
bpf.StoreScratch{
|
|
Src: bpf.RegA,
|
|
N: 16,
|
|
},
|
|
bpf.RetA{},
|
|
})
|
|
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestVMStoreScratchUnknownSourceRegister(t *testing.T) {
|
|
_, _, err := testVM(t, []bpf.Instruction{
|
|
bpf.StoreScratch{
|
|
Src: 100,
|
|
N: 0,
|
|
},
|
|
bpf.RetA{},
|
|
})
|
|
if errStr(err) != "assembling instruction 1: invalid source register 100" {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestVMLoadScratchInvalidScratchRegisterTooSmall(t *testing.T) {
|
|
_, _, err := testVM(t, []bpf.Instruction{
|
|
bpf.LoadScratch{
|
|
Dst: bpf.RegX,
|
|
N: -1,
|
|
},
|
|
bpf.RetA{},
|
|
})
|
|
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestVMLoadScratchInvalidScratchRegisterTooLarge(t *testing.T) {
|
|
_, _, err := testVM(t, []bpf.Instruction{
|
|
bpf.LoadScratch{
|
|
Dst: bpf.RegX,
|
|
N: 16,
|
|
},
|
|
bpf.RetA{},
|
|
})
|
|
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestVMLoadScratchUnknownDestinationRegister(t *testing.T) {
|
|
_, _, err := testVM(t, []bpf.Instruction{
|
|
bpf.LoadScratch{
|
|
Dst: 100,
|
|
N: 0,
|
|
},
|
|
bpf.RetA{},
|
|
})
|
|
if errStr(err) != "assembling instruction 1: invalid target register 100" {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestVMStoreScratchLoadScratchOneValue(t *testing.T) {
|
|
vm, done, err := testVM(t, []bpf.Instruction{
|
|
// Load byte 255
|
|
bpf.LoadAbsolute{
|
|
Off: 8,
|
|
Size: 1,
|
|
},
|
|
// Copy to X and store in scratch[0]
|
|
bpf.TAX{},
|
|
bpf.StoreScratch{
|
|
Src: bpf.RegX,
|
|
N: 0,
|
|
},
|
|
// Load byte 1
|
|
bpf.LoadAbsolute{
|
|
Off: 9,
|
|
Size: 1,
|
|
},
|
|
// Overwrite 1 with 255 from scratch[0]
|
|
bpf.LoadScratch{
|
|
Dst: bpf.RegA,
|
|
N: 0,
|
|
},
|
|
// Return 255
|
|
bpf.RetA{},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("failed to load BPF program: %v", err)
|
|
}
|
|
defer done()
|
|
|
|
out, err := vm.Run([]byte{
|
|
0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
255, 1, 2,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error while running program: %v", err)
|
|
}
|
|
if want, got := 3, out; want != got {
|
|
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
want, got)
|
|
}
|
|
}
|
|
|
|
func TestVMStoreScratchLoadScratchMultipleValues(t *testing.T) {
|
|
vm, done, err := testVM(t, []bpf.Instruction{
|
|
// Load byte 10
|
|
bpf.LoadAbsolute{
|
|
Off: 8,
|
|
Size: 1,
|
|
},
|
|
// Store in scratch[0]
|
|
bpf.StoreScratch{
|
|
Src: bpf.RegA,
|
|
N: 0,
|
|
},
|
|
// Load byte 20
|
|
bpf.LoadAbsolute{
|
|
Off: 9,
|
|
Size: 1,
|
|
},
|
|
// Store in scratch[1]
|
|
bpf.StoreScratch{
|
|
Src: bpf.RegA,
|
|
N: 1,
|
|
},
|
|
// Load byte 30
|
|
bpf.LoadAbsolute{
|
|
Off: 10,
|
|
Size: 1,
|
|
},
|
|
// Store in scratch[2]
|
|
bpf.StoreScratch{
|
|
Src: bpf.RegA,
|
|
N: 2,
|
|
},
|
|
// Load byte 1
|
|
bpf.LoadAbsolute{
|
|
Off: 11,
|
|
Size: 1,
|
|
},
|
|
// Store in scratch[3]
|
|
bpf.StoreScratch{
|
|
Src: bpf.RegA,
|
|
N: 3,
|
|
},
|
|
// Load in byte 10 to X
|
|
bpf.LoadScratch{
|
|
Dst: bpf.RegX,
|
|
N: 0,
|
|
},
|
|
// Copy X -> A
|
|
bpf.TXA{},
|
|
// Verify value is 10
|
|
bpf.JumpIf{
|
|
Cond: bpf.JumpEqual,
|
|
Val: 10,
|
|
SkipTrue: 1,
|
|
},
|
|
// Fail test if incorrect
|
|
bpf.RetConstant{
|
|
Val: 0,
|
|
},
|
|
// Load in byte 20 to A
|
|
bpf.LoadScratch{
|
|
Dst: bpf.RegA,
|
|
N: 1,
|
|
},
|
|
// Verify value is 20
|
|
bpf.JumpIf{
|
|
Cond: bpf.JumpEqual,
|
|
Val: 20,
|
|
SkipTrue: 1,
|
|
},
|
|
// Fail test if incorrect
|
|
bpf.RetConstant{
|
|
Val: 0,
|
|
},
|
|
// Load in byte 30 to A
|
|
bpf.LoadScratch{
|
|
Dst: bpf.RegA,
|
|
N: 2,
|
|
},
|
|
// Verify value is 30
|
|
bpf.JumpIf{
|
|
Cond: bpf.JumpEqual,
|
|
Val: 30,
|
|
SkipTrue: 1,
|
|
},
|
|
// Fail test if incorrect
|
|
bpf.RetConstant{
|
|
Val: 0,
|
|
},
|
|
// Return first two bytes on success
|
|
bpf.RetConstant{
|
|
Val: 10,
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("failed to load BPF program: %v", err)
|
|
}
|
|
defer done()
|
|
|
|
out, err := vm.Run([]byte{
|
|
0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
10, 20, 30, 1,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error while running program: %v", err)
|
|
}
|
|
if want, got := 2, out; want != got {
|
|
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
want, got)
|
|
}
|
|
}
|