Example #1
0
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))
            ])
Example #2
0
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))])
Example #3
0
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
Example #4
0
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