def _store_subscr_map(i, **kwargs): v, m, k = i.src_vars if not isinstance(m, _mem.ConstVar): raise TranslationError(i.starts_line, 'Cannot subscript dynamically selected map') return ([bi.Mov(bi.MapFdImm(m.val.fd), bi.Reg.R1)] + _lea(i, k, bi.Reg.R2, **kwargs) + _lea(i, v, bi.Reg.R3, **kwargs) + [ bi.Mov(bi.Imm(0), bi.Reg.R4), bi.Call(bi.Imm(funcs.map_update_elem.num)) ])
def _delete_subscr(i, **kwargs): if issubclass(i.src_vars[1].var_type, ctypes.Array): raise TranslationError(i.starts_line, 'Cannot delete from array') m, k = i.src_vars if not isinstance(m, _mem.ConstVar): raise TranslationError(i.starts_line, 'Cannot delete from dynamically selected map') return ([bi.Mov(bi.MapFdImm(m.val.fd), bi.Reg.R1)] + _lea(i, k, bi.Reg.R2, **kwargs) + [bi.Call(bi.Imm(funcs.map_delete_elem.num))])
def _call_function(i, **kwargs): fn_var = i.src_vars[0] if not isinstance(fn_var, _mem.ConstVar): raise TranslationError(i.starts_line, 'Function may not be determined dynamically') fn = fn_var.val if isinstance(fn, funcs.PseudoFunc): return _call_pseudo_function(i, **kwargs) if not isinstance(fn, funcs.Func): raise TranslationError( i.starts_line, 'Function must be bpf function from py2bpf.funcs') if fn.num_args != -1 and len(i.src_vars) != fn.num_args + 1: raise TranslationError( i.starts_line, 'Function "{}" expected {} arguments, got {}'.format( fn.name, fn.num_args, len(i.src_vars) - 1)) arg_regs = [bi.Reg.R1, bi.Reg.R2, bi.Reg.R3, bi.Reg.R4, bi.Reg.R5] ret = [] # See explanation for this nonsense in funcs.py arg_vars = [] for idx, var in enumerate(i.src_vars[1:]): arg_vars.append(var) if idx in fn.fill_array_size_args: if issubclass(var.var_type, _types.Ptr): length = ctypes.sizeof(var.var_type.var_type) else: length = ctypes.sizeof(var.var_type) arg_vars.append(_mem.ConstVar(ctypes.c_uint64(length))) # Put the arguments into appropriate registers for arg, reg in zip(arg_vars, arg_regs): if issubclass(arg.var_type, _ctypes._SimpleCData): ret.extend(_mov(arg, reg)) else: ret.extend(_lea(i, arg, reg, **kwargs)) # Call the function ret.append(bi.Call(bi.Imm(fn.num))) # Move the result, if we haven't ignored it if len(i.dst_vars) > 0: ret.extend(_mov(bi.Reg.R0, i.dst_vars[0])) return ret
def _binary_subscr_map(i, **kwargs): m, k, dv = i.src_vars[0], i.src_vars[1], i.dst_vars[0] if not isinstance(m, _mem.ConstVar): raise TranslationError(i.starts_line, 'Cannot subscript dynamically select map') found, done = _make_tmp_label(), _make_tmp_label() ret = [] ret.extend(_mov(bi.MapFdImm(m.val.fd), bi.Reg.R1)) ret.extend(_lea(i, k, bi.Reg.R2, **kwargs)) ret.extend([ bi.Call(bi.Imm(funcs.map_lookup_elem.num)), ]) if _is_ptr(dv.var_type): sz = _get_cdata_size(dv.var_type) ret.extend(_mov(bi.Reg.R0, dv)) else: ret.extend([ bi.JumpIfNotEqual(bi.Imm(0), bi.Reg.R0, found), ]) # Move default value dr = _get_var_reg(dv) ret.extend(_mov_const(dv.var_type, m.val.DEFAULT_VALUE, dr, dv.offset)) ret.extend([ bi.Jump(done), bi.Label(found), ]) # Primitives by value, others by reference if issubclass(dv.var_type, _ctypes._SimpleCData): sz = _get_cdata_size(dv.var_type) ret.extend(_mov(bi.Mem(bi.Reg.R0, 0, sz), dv)) else: ret.extend(_mov(bi.Reg.R0, dv)) ret.append(bi.Label(done)) return ret