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)
|
|
)
|