Commit 7c71ca70 authored by Matt Layher's avatar Matt Layher Committed by Mikio Hara

bpf: implement LoadExtension and ExtLen for VM

Change-Id: I29487b0c1fdea97b5c35d22b4f7c23e11e7ceeed
Reviewed-on: https://go-review.googlesource.com/24272Reviewed-by: 's avatarDavid Anderson <danderson@google.com>
Reviewed-by: 's avatarMikio Hara <mikioh.mikioh@gmail.com>
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
parent 8bf2b398
......@@ -45,6 +45,13 @@ func NewVM(filter []Instruction) (*VM, error) {
case ALUOpDiv, ALUOpMod:
return nil, errors.New("cannot divide by zero using ALUOpConstant")
}
// Check for unknown extensions
case LoadExtension:
switch ins.Num {
case ExtLen:
default:
return nil, fmt.Errorf("extension %d not implemented", ins.Num)
}
}
}
......@@ -84,9 +91,6 @@ func (v *VM) Run(in []byte) (int, error) {
// - NegateA:
// - would require a change from uint32 registers to int32
// registers
// - Extension:
// - implement extensions that do not depend on kernel-specific
// functionality, such as 'rand'
// TODO(mdlayher): add interop tests that check signedness of ALU
// operations against kernel implementation, and make sure Go
......@@ -109,6 +113,8 @@ func (v *VM) Run(in []byte) (int, error) {
regA, ok = loadAbsolute(ins, in)
case LoadConstant:
regA, regX = loadConstant(ins, regA, regX)
case LoadExtension:
regA = loadExtension(ins, in)
case LoadIndirect:
regA, ok = loadIndirect(ins, in, regX)
case LoadMemShift:
......
// 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 TestVMLoadExtensionNotImplemented(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.LoadExtension{
Num: 100,
},
bpf.RetA{},
})
if errStr(err) != "extension 100 not implemented" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMLoadExtensionExtLen(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadExtension{
Num: bpf.ExtLen,
},
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,
0, 1, 2, 3,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 4, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
......@@ -103,6 +103,15 @@ func loadConstant(ins LoadConstant, regA uint32, regX uint32) (uint32, uint32) {
return regA, regX
}
func loadExtension(ins LoadExtension, in []byte) uint32 {
switch ins.Num {
case ExtLen:
return uint32(len(in))
default:
panic(fmt.Sprintf("unimplemented extension: %d", ins.Num))
}
}
func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) {
offset := int(ins.Off) + int(regX)
size := int(ins.Size)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment