Extended Berkeley Packet Filter (eBPF) assembler and virtual machine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

233 lines
5.1 KiB

package ebpf
import (
"fmt"
)
type ALUOp uint16
func (op ALUOp) CString() string {
switch op {
case ALUOpAdd:
return "+"
case ALUOpSub:
return "-"
case ALUOpMul:
return "*"
case ALUOpDiv:
return "/"
case ALUOpOr:
return "|"
case ALUOpAnd:
return "&"
case ALUOpShiftLeft:
return "<<"
case ALUOpShiftRight:
return ">>"
case aluOpNegate:
return "!"
case ALUOpMod:
return "%"
case ALUOpXor:
return "^"
default:
return ""
}
}
func (op ALUOp) Mnemoic() string {
switch op {
case ALUOpAdd:
return "add"
case ALUOpSub:
return "sub"
case ALUOpMul:
return "mul"
case ALUOpDiv:
return "div"
case ALUOpOr:
return "or"
case ALUOpAnd:
return "and"
case ALUOpShiftLeft:
return "lsh"
case ALUOpShiftRight:
return "rsh"
case aluOpNegate:
return "neg"
case ALUOpMod:
return "mod"
case ALUOpXor:
return "xor"
case ALUOpMove:
return "mov"
case ALUOpArithmicShiftRight:
return "arsh"
default:
return fmt.Sprintf("# invalid operand %#02x", uint8(op))
}
}
const (
ALUOpAdd ALUOp = iota << 4 // 0x00
ALUOpSub // 0x10
ALUOpMul // 0x20
ALUOpDiv // 0x30
ALUOpOr // 0x40
ALUOpAnd // 0x50
ALUOpShiftLeft // 0x60
ALUOpShiftRight // 0x70
aluOpNegate // 0x80
ALUOpMod // 0x90
ALUOpXor // 0xa0
ALUOpMove // 0xb0
ALUOpArithmicShiftRight // 0xc0
aluOpByteSwap // 0xd0
)
// ALUOpConstant executes Dst = Dst <Op> Value.
type ALUOpConstant struct {
Op ALUOp
Dst Register
Value uint32
}
// Assemble implements the Instruction Assemble method.
func (a ALUOpConstant) Assemble() (RawInstruction, error) {
return RawInstruction{
Op: opClassALU | aluSourceImmediate | Opcode(a.Op),
Dst: a.Dst,
Immediate: uint64(a.Value),
}, nil
}
func (a ALUOpConstant) String() string {
return fmt.Sprintf("%s32 %s, %#x", a.Op.Mnemoic(), a.Dst, a.Value)
}
func (a ALUOpConstant) CString() string {
return fmt.Sprintf("%s %s= (uint32_t)(%x);", a.Dst, a.Op.CString(), a.Value)
}
// ALUOpRegister executes Dst = Dst <Op> Src.
type ALUOpRegister struct {
Op ALUOp
Dst Register
Src Register
}
// Assemble implements the Instruction Assemble method.
func (a ALUOpRegister) Assemble() (RawInstruction, error) {
return RawInstruction{
Op: opClassALU | aluSourceX | Opcode(a.Op),
Dst: a.Dst,
Src: a.Src,
}, nil
}
func (a ALUOpRegister) String() string {
return fmt.Sprintf("%s32 %s, %s", a.Op.Mnemoic(), a.Dst, a.Src)
}
func (a ALUOpRegister) CString() string {
return fmt.Sprintf("%s %s= %x;", a.Dst, a.Op.CString(), a.Src)
}
// Negate executes Dst = !Dst.
type Negate struct {
Dst Register
}
// Assemble implements the Instruction Assemble method.
func (a Negate) Assemble() (RawInstruction, error) {
return RawInstruction{
Op: opClassALU | aluSourceImmediate | Opcode(aluOpNegate),
Dst: a.Dst,
}, nil
}
func (a Negate) String() string {
return fmt.Sprintf("neg32 %s", a.Dst)
}
func (a Negate) CString() string {
return fmt.Sprintf("%s = (uint32_t)(!%s);", a.Dst, a.Dst)
}
// ALU64OpConstant executes Dst = Dst <Op> Value.
type ALU64OpConstant struct {
Op ALUOp
Dst Register
Value uint32
}
// Assemble implements the Instruction Assemble method.
func (a ALU64OpConstant) Assemble() (RawInstruction, error) {
return RawInstruction{
Op: opClassALU64 | aluSourceImmediate | Opcode(a.Op),
Dst: a.Dst,
Immediate: uint64(a.Value),
}, nil
}
func (a ALU64OpConstant) String() string {
return fmt.Sprintf("%s %s, %#x", a.Op.Mnemoic(), a.Dst, a.Value)
}
func (a ALU64OpConstant) CString() string {
return fmt.Sprintf("%s %s= %#x;", a.Dst, a.Op.CString(), a.Value)
}
// ALU64OpRegister executes Dst = Dst <Op> Src.
type ALU64OpRegister struct {
Op ALUOp
Dst Register
Src Register
}
// Assemble implements the Instruction Assemble method.
func (a ALU64OpRegister) Assemble() (RawInstruction, error) {
return RawInstruction{
Op: opClassALU64 | aluSourceX | Opcode(a.Op),
Dst: a.Dst,
Src: a.Src,
}, nil
}
func (a ALU64OpRegister) String() string {
return fmt.Sprintf("%s %s, %s", a.Op.Mnemoic(), a.Dst, a.Src)
}
func (a ALU64OpRegister) CString() string {
return fmt.Sprintf("%s %s= %s", a.Dst, a.Op.CString(), a.Src)
}
// Negate64 executes Dst = !Dst.
type Negate64 struct {
Dst Register
}
// Assemble implements the Instruction Assemble method.
func (a Negate64) Assemble() (RawInstruction, error) {
return RawInstruction{
Op: opClassALU64 | aluSourceImmediate | Opcode(aluOpNegate),
Dst: a.Dst,
}, nil
}
func (a Negate64) String() string {
return fmt.Sprintf("neg %s", a.Dst)
}
func (a Negate64) CString() string {
return fmt.Sprintf("%s = !%s", a.Dst, a.Dst)
}
var (
_ Instruction = (*ALUOpConstant)(nil)
_ Instruction = (*ALUOpRegister)(nil)
_ Instruction = (*Negate)(nil)
_ Instruction = (*ALU64OpConstant)(nil)
_ Instruction = (*ALU64OpRegister)(nil)
_ Instruction = (*Negate64)(nil)
)