1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 func aluOpConstant(ins ALUOpConstant, regA uint32) uint32 {
13 return aluOpCommon(ins.Op, regA, ins.Val)
16 func aluOpX(ins ALUOpX, regA uint32, regX uint32) (uint32, bool) {
17 // Guard against division or modulus by zero by terminating
18 // the program, as the OS BPF VM does
21 case ALUOpDiv, ALUOpMod:
26 return aluOpCommon(ins.Op, regA, regX), true
29 func aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 {
38 // Division by zero not permitted by NewVM and aluOpX checks
49 // Modulus by zero not permitted by NewVM and aluOpX checks
58 func jumpIf(ins JumpIf, value uint32) int {
60 inV := uint32(ins.Val)
71 case JumpGreaterOrEqual:
76 ok = (value & inV) != 0
78 ok = (value & inV) == 0
82 return int(ins.SkipTrue)
85 return int(ins.SkipFalse)
88 func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) {
89 offset := int(ins.Off)
92 return loadCommon(in, offset, size)
95 func loadConstant(ins LoadConstant, regA uint32, regX uint32) (uint32, uint32) {
106 func loadExtension(ins LoadExtension, in []byte) uint32 {
109 return uint32(len(in))
111 panic(fmt.Sprintf("unimplemented extension: %d", ins.Num))
115 func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) {
116 offset := int(ins.Off) + int(regX)
117 size := int(ins.Size)
119 return loadCommon(in, offset, size)
122 func loadMemShift(ins LoadMemShift, in []byte) (uint32, bool) {
123 offset := int(ins.Off)
125 if !inBounds(len(in), offset, 0) {
129 // Mask off high 4 bits and multiply low 4 bits by 4
130 return uint32(in[offset]&0x0f) * 4, true
133 func inBounds(inLen int, offset int, size int) bool {
134 return offset+size <= inLen
137 func loadCommon(in []byte, offset int, size int) (uint32, bool) {
138 if !inBounds(len(in), offset, size) {
144 return uint32(in[offset]), true
146 return uint32(binary.BigEndian.Uint16(in[offset : offset+size])), true
148 return uint32(binary.BigEndian.Uint32(in[offset : offset+size])), true
150 panic(fmt.Sprintf("invalid load size: %d", size))
154 func loadScratch(ins LoadScratch, regScratch [16]uint32, regA uint32, regX uint32) (uint32, uint32) {
157 regA = regScratch[ins.N]
159 regX = regScratch[ins.N]
165 func storeScratch(ins StoreScratch, regScratch [16]uint32, regA uint32, regX uint32) [16]uint32 {
168 regScratch[ins.N] = regA
170 regScratch[ins.N] = regX