diff --git a/asm/instruction.go b/asm/instruction.go index ae96d622f..67cd39d6f 100644 --- a/asm/instruction.go +++ b/asm/instruction.go @@ -159,8 +159,13 @@ func (ins Instruction) Marshal(w io.Writer, bo binary.ByteOrder) (uint64, error) ins.Offset = newOffset } + op, err := ins.OpCode.bpfOpCode() + if err != nil { + return 0, err + } + data := make([]byte, InstructionSize) - data[0] = byte(ins.OpCode) + data[0] = op data[1] = byte(regs) bo.PutUint16(data[2:4], uint16(ins.Offset)) bo.PutUint32(data[4:8], uint32(cons)) diff --git a/asm/opcode.go b/asm/opcode.go index bbda2107f..1dfd0b171 100644 --- a/asm/opcode.go +++ b/asm/opcode.go @@ -93,6 +93,17 @@ type OpCode uint16 // InvalidOpCode is returned by setters on OpCode const InvalidOpCode OpCode = 0xffff +// bpfOpCode returns the actual BPF opcode. +func (op OpCode) bpfOpCode() (byte, error) { + const opCodeMask = 0xff + + if !valid(op, opCodeMask) { + return 0, fmt.Errorf("invalid opcode %x", op) + } + + return byte(op & opCodeMask), nil +} + // rawInstructions returns the number of BPF instructions required // to encode this opcode. func (op OpCode) rawInstructions() int {