Home | History | Annotate | Line # | Download | only in net
bpfjit.c revision 1.46.14.1
      1  1.46.14.1  pgoyette /*	$NetBSD: bpfjit.c,v 1.46.14.1 2019/01/26 22:00:36 pgoyette Exp $	*/
      2        1.3     rmind 
      3        1.1     alnsn /*-
      4       1.43     alnsn  * Copyright (c) 2011-2015 Alexander Nasonov.
      5        1.1     alnsn  * All rights reserved.
      6        1.1     alnsn  *
      7        1.1     alnsn  * Redistribution and use in source and binary forms, with or without
      8        1.1     alnsn  * modification, are permitted provided that the following conditions
      9        1.1     alnsn  * are met:
     10        1.1     alnsn  *
     11        1.1     alnsn  * 1. Redistributions of source code must retain the above copyright
     12        1.1     alnsn  *    notice, this list of conditions and the following disclaimer.
     13        1.1     alnsn  * 2. Redistributions in binary form must reproduce the above copyright
     14        1.1     alnsn  *    notice, this list of conditions and the following disclaimer in
     15        1.1     alnsn  *    the documentation and/or other materials provided with the
     16        1.1     alnsn  *    distribution.
     17        1.1     alnsn  *
     18        1.1     alnsn  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19        1.1     alnsn  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20        1.1     alnsn  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     21        1.1     alnsn  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
     22        1.1     alnsn  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     23        1.1     alnsn  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
     24        1.1     alnsn  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25        1.1     alnsn  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     26        1.1     alnsn  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     27        1.1     alnsn  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     28        1.1     alnsn  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29        1.1     alnsn  * SUCH DAMAGE.
     30        1.1     alnsn  */
     31        1.1     alnsn 
     32        1.2     alnsn #include <sys/cdefs.h>
     33        1.2     alnsn #ifdef _KERNEL
     34  1.46.14.1  pgoyette __KERNEL_RCSID(0, "$NetBSD: bpfjit.c,v 1.46.14.1 2019/01/26 22:00:36 pgoyette Exp $");
     35        1.2     alnsn #else
     36  1.46.14.1  pgoyette __RCSID("$NetBSD: bpfjit.c,v 1.46.14.1 2019/01/26 22:00:36 pgoyette Exp $");
     37        1.2     alnsn #endif
     38        1.2     alnsn 
     39        1.3     rmind #include <sys/types.h>
     40        1.3     rmind #include <sys/queue.h>
     41        1.1     alnsn 
     42        1.1     alnsn #ifndef _KERNEL
     43        1.7     alnsn #include <assert.h>
     44        1.7     alnsn #define BJ_ASSERT(c) assert(c)
     45        1.7     alnsn #else
     46        1.7     alnsn #define BJ_ASSERT(c) KASSERT(c)
     47        1.7     alnsn #endif
     48        1.7     alnsn 
     49        1.7     alnsn #ifndef _KERNEL
     50        1.3     rmind #include <stdlib.h>
     51        1.7     alnsn #define BJ_ALLOC(sz) malloc(sz)
     52        1.7     alnsn #define BJ_FREE(p, sz) free(p)
     53        1.1     alnsn #else
     54        1.3     rmind #include <sys/kmem.h>
     55        1.7     alnsn #define BJ_ALLOC(sz) kmem_alloc(sz, KM_SLEEP)
     56        1.7     alnsn #define BJ_FREE(p, sz) kmem_free(p, sz)
     57        1.1     alnsn #endif
     58        1.1     alnsn 
     59        1.1     alnsn #ifndef _KERNEL
     60        1.1     alnsn #include <limits.h>
     61        1.1     alnsn #include <stdbool.h>
     62        1.1     alnsn #include <stddef.h>
     63        1.1     alnsn #include <stdint.h>
     64  1.46.14.1  pgoyette #include <string.h>
     65        1.1     alnsn #else
     66        1.1     alnsn #include <sys/atomic.h>
     67        1.1     alnsn #include <sys/module.h>
     68        1.1     alnsn #endif
     69        1.1     alnsn 
     70        1.5     rmind #define	__BPF_PRIVATE
     71        1.5     rmind #include <net/bpf.h>
     72        1.3     rmind #include <net/bpfjit.h>
     73        1.1     alnsn #include <sljitLir.h>
     74        1.1     alnsn 
     75        1.7     alnsn #if !defined(_KERNEL) && defined(SLJIT_VERBOSE) && SLJIT_VERBOSE
     76        1.7     alnsn #include <stdio.h> /* for stderr */
     77        1.7     alnsn #endif
     78        1.7     alnsn 
     79        1.7     alnsn /*
     80       1.44     alnsn  * Number of saved registers to pass to sljit_emit_enter() function.
     81       1.44     alnsn  */
     82       1.44     alnsn #define NSAVEDS		3
     83       1.44     alnsn 
     84       1.44     alnsn /*
     85       1.13     alnsn  * Arguments of generated bpfjit_func_t.
     86       1.13     alnsn  * The first argument is reassigned upon entry
     87       1.13     alnsn  * to a more frequently used buf argument.
     88       1.13     alnsn  */
     89       1.45     alnsn #define BJ_CTX_ARG	SLJIT_S0
     90       1.45     alnsn #define BJ_ARGS		SLJIT_S1
     91       1.13     alnsn 
     92       1.13     alnsn /*
     93        1.7     alnsn  * Permanent register assignments.
     94        1.7     alnsn  */
     95       1.45     alnsn #define BJ_BUF		SLJIT_S0
     96       1.45     alnsn //#define BJ_ARGS	SLJIT_S1
     97       1.45     alnsn #define BJ_BUFLEN	SLJIT_S2
     98       1.45     alnsn #define BJ_AREG		SLJIT_R0
     99       1.45     alnsn #define BJ_TMP1REG	SLJIT_R1
    100       1.45     alnsn #define BJ_TMP2REG	SLJIT_R2
    101       1.45     alnsn #define BJ_XREG		SLJIT_R3
    102       1.45     alnsn #define BJ_TMP3REG	SLJIT_R4
    103        1.7     alnsn 
    104       1.13     alnsn #ifdef _KERNEL
    105       1.13     alnsn #define MAX_MEMWORDS BPF_MAX_MEMWORDS
    106       1.13     alnsn #else
    107       1.13     alnsn #define MAX_MEMWORDS BPF_MEMWORDS
    108       1.13     alnsn #endif
    109       1.13     alnsn 
    110       1.13     alnsn #define BJ_INIT_NOBITS  ((bpf_memword_init_t)0)
    111       1.13     alnsn #define BJ_INIT_MBIT(k) BPF_MEMWORD_INIT(k)
    112       1.13     alnsn #define BJ_INIT_ABIT    BJ_INIT_MBIT(MAX_MEMWORDS)
    113       1.13     alnsn #define BJ_INIT_XBIT    BJ_INIT_MBIT(MAX_MEMWORDS + 1)
    114        1.1     alnsn 
    115        1.9     alnsn /*
    116       1.19     alnsn  * Get a number of memwords and external memwords from a bpf_ctx object.
    117       1.19     alnsn  */
    118       1.19     alnsn #define GET_EXTWORDS(bc) ((bc) ? (bc)->extwords : 0)
    119       1.19     alnsn #define GET_MEMWORDS(bc) (GET_EXTWORDS(bc) ? GET_EXTWORDS(bc) : BPF_MEMWORDS)
    120       1.19     alnsn 
    121       1.19     alnsn /*
    122       1.20     alnsn  * Optimization hints.
    123       1.20     alnsn  */
    124       1.20     alnsn typedef unsigned int bpfjit_hint_t;
    125       1.28     alnsn #define BJ_HINT_ABS  0x01 /* packet read at absolute offset   */
    126       1.28     alnsn #define BJ_HINT_IND  0x02 /* packet read at variable offset   */
    127       1.29     alnsn #define BJ_HINT_MSH  0x04 /* BPF_MSH instruction              */
    128       1.29     alnsn #define BJ_HINT_COP  0x08 /* BPF_COP or BPF_COPX instruction  */
    129       1.29     alnsn #define BJ_HINT_COPX 0x10 /* BPF_COPX instruction             */
    130       1.29     alnsn #define BJ_HINT_XREG 0x20 /* BJ_XREG is needed                */
    131       1.29     alnsn #define BJ_HINT_LDX  0x40 /* BPF_LDX instruction              */
    132       1.29     alnsn #define BJ_HINT_PKT  (BJ_HINT_ABS|BJ_HINT_IND|BJ_HINT_MSH)
    133       1.20     alnsn 
    134       1.20     alnsn /*
    135        1.9     alnsn  * Datatype for Array Bounds Check Elimination (ABC) pass.
    136        1.9     alnsn  */
    137        1.9     alnsn typedef uint64_t bpfjit_abc_length_t;
    138        1.9     alnsn #define MAX_ABC_LENGTH (UINT32_MAX + UINT64_C(4)) /* max. width is 4 */
    139        1.8     alnsn 
    140        1.7     alnsn struct bpfjit_stack
    141        1.7     alnsn {
    142       1.13     alnsn 	bpf_ctx_t *ctx;
    143       1.13     alnsn 	uint32_t *extmem; /* pointer to external memory store */
    144       1.32     alnsn 	uint32_t reg; /* saved A or X register */
    145        1.7     alnsn #ifdef _KERNEL
    146       1.21     alnsn 	int err; /* 3rd argument for m_xword/m_xhalf/m_xbyte function call */
    147        1.7     alnsn #endif
    148       1.13     alnsn 	uint32_t mem[BPF_MEMWORDS]; /* internal memory store */
    149        1.7     alnsn };
    150        1.7     alnsn 
    151        1.7     alnsn /*
    152        1.7     alnsn  * Data for BPF_JMP instruction.
    153        1.7     alnsn  * Forward declaration for struct bpfjit_jump.
    154        1.1     alnsn  */
    155        1.7     alnsn struct bpfjit_jump_data;
    156        1.1     alnsn 
    157        1.1     alnsn /*
    158        1.7     alnsn  * Node of bjumps list.
    159        1.1     alnsn  */
    160        1.3     rmind struct bpfjit_jump {
    161        1.7     alnsn 	struct sljit_jump *sjump;
    162        1.7     alnsn 	SLIST_ENTRY(bpfjit_jump) entries;
    163        1.7     alnsn 	struct bpfjit_jump_data *jdata;
    164        1.1     alnsn };
    165        1.1     alnsn 
    166        1.1     alnsn /*
    167        1.1     alnsn  * Data for BPF_JMP instruction.
    168        1.1     alnsn  */
    169        1.3     rmind struct bpfjit_jump_data {
    170        1.1     alnsn 	/*
    171        1.7     alnsn 	 * These entries make up bjumps list:
    172        1.7     alnsn 	 * jtf[0] - when coming from jt path,
    173        1.7     alnsn 	 * jtf[1] - when coming from jf path.
    174        1.1     alnsn 	 */
    175        1.7     alnsn 	struct bpfjit_jump jtf[2];
    176        1.7     alnsn 	/*
    177        1.7     alnsn 	 * Length calculated by Array Bounds Check Elimination (ABC) pass.
    178        1.7     alnsn 	 */
    179        1.8     alnsn 	bpfjit_abc_length_t abc_length;
    180        1.7     alnsn 	/*
    181        1.7     alnsn 	 * Length checked by the last out-of-bounds check.
    182        1.7     alnsn 	 */
    183        1.8     alnsn 	bpfjit_abc_length_t checked_length;
    184        1.1     alnsn };
    185        1.1     alnsn 
    186        1.1     alnsn /*
    187        1.1     alnsn  * Data for "read from packet" instructions.
    188        1.1     alnsn  * See also read_pkt_insn() function below.
    189        1.1     alnsn  */
    190        1.3     rmind struct bpfjit_read_pkt_data {
    191        1.1     alnsn 	/*
    192        1.7     alnsn 	 * Length calculated by Array Bounds Check Elimination (ABC) pass.
    193        1.7     alnsn 	 */
    194        1.8     alnsn 	bpfjit_abc_length_t abc_length;
    195        1.7     alnsn 	/*
    196        1.7     alnsn 	 * If positive, emit "if (buflen < check_length) return 0"
    197        1.7     alnsn 	 * out-of-bounds check.
    198        1.9     alnsn 	 * Values greater than UINT32_MAX generate unconditional "return 0".
    199        1.1     alnsn 	 */
    200        1.8     alnsn 	bpfjit_abc_length_t check_length;
    201        1.1     alnsn };
    202        1.1     alnsn 
    203        1.1     alnsn /*
    204        1.1     alnsn  * Additional (optimization-related) data for bpf_insn.
    205        1.1     alnsn  */
    206        1.3     rmind struct bpfjit_insn_data {
    207        1.1     alnsn 	/* List of jumps to this insn. */
    208        1.7     alnsn 	SLIST_HEAD(, bpfjit_jump) bjumps;
    209        1.1     alnsn 
    210        1.1     alnsn 	union {
    211        1.7     alnsn 		struct bpfjit_jump_data     jdata;
    212        1.7     alnsn 		struct bpfjit_read_pkt_data rdata;
    213        1.7     alnsn 	} u;
    214        1.1     alnsn 
    215       1.13     alnsn 	bpf_memword_init_t invalid;
    216        1.7     alnsn 	bool unreachable;
    217        1.1     alnsn };
    218        1.1     alnsn 
    219        1.1     alnsn #ifdef _KERNEL
    220        1.1     alnsn 
    221        1.1     alnsn uint32_t m_xword(const struct mbuf *, uint32_t, int *);
    222        1.1     alnsn uint32_t m_xhalf(const struct mbuf *, uint32_t, int *);
    223        1.1     alnsn uint32_t m_xbyte(const struct mbuf *, uint32_t, int *);
    224        1.1     alnsn 
    225        1.1     alnsn MODULE(MODULE_CLASS_MISC, bpfjit, "sljit")
    226        1.1     alnsn 
    227        1.1     alnsn static int
    228        1.1     alnsn bpfjit_modcmd(modcmd_t cmd, void *arg)
    229        1.1     alnsn {
    230        1.1     alnsn 
    231        1.1     alnsn 	switch (cmd) {
    232        1.1     alnsn 	case MODULE_CMD_INIT:
    233        1.1     alnsn 		bpfjit_module_ops.bj_free_code = &bpfjit_free_code;
    234        1.1     alnsn 		membar_producer();
    235        1.1     alnsn 		bpfjit_module_ops.bj_generate_code = &bpfjit_generate_code;
    236        1.1     alnsn 		membar_producer();
    237        1.1     alnsn 		return 0;
    238        1.1     alnsn 
    239        1.1     alnsn 	case MODULE_CMD_FINI:
    240        1.1     alnsn 		return EOPNOTSUPP;
    241        1.1     alnsn 
    242        1.1     alnsn 	default:
    243        1.1     alnsn 		return ENOTTY;
    244        1.1     alnsn 	}
    245        1.1     alnsn }
    246        1.1     alnsn #endif
    247        1.1     alnsn 
    248       1.20     alnsn /*
    249       1.21     alnsn  * Return a number of scratch registers to pass
    250       1.20     alnsn  * to sljit_emit_enter() function.
    251       1.20     alnsn  */
    252       1.45     alnsn static sljit_s32
    253       1.20     alnsn nscratches(bpfjit_hint_t hints)
    254       1.20     alnsn {
    255       1.45     alnsn 	sljit_s32 rv = 2;
    256       1.20     alnsn 
    257       1.22     alnsn #ifdef _KERNEL
    258       1.24     alnsn 	if (hints & BJ_HINT_PKT)
    259       1.24     alnsn 		rv = 3; /* xcall with three arguments */
    260       1.22     alnsn #endif
    261       1.22     alnsn 
    262       1.27     alnsn 	if (hints & BJ_HINT_IND)
    263       1.20     alnsn 		rv = 3; /* uses BJ_TMP2REG */
    264       1.20     alnsn 
    265       1.20     alnsn 	if (hints & BJ_HINT_COP)
    266       1.20     alnsn 		rv = 3; /* calls copfunc with three arguments */
    267       1.20     alnsn 
    268       1.32     alnsn 	if (hints & BJ_HINT_XREG)
    269       1.32     alnsn 		rv = 4; /* uses BJ_XREG */
    270       1.32     alnsn 
    271       1.32     alnsn #ifdef _KERNEL
    272       1.32     alnsn 	if (hints & BJ_HINT_LDX)
    273       1.32     alnsn 		rv = 5; /* uses BJ_TMP3REG */
    274       1.32     alnsn #endif
    275       1.32     alnsn 
    276       1.29     alnsn 	if (hints & BJ_HINT_COPX)
    277       1.32     alnsn 		rv = 5; /* uses BJ_TMP3REG */
    278       1.29     alnsn 
    279       1.29     alnsn 	return rv;
    280       1.29     alnsn }
    281       1.29     alnsn 
    282        1.1     alnsn static uint32_t
    283        1.7     alnsn read_width(const struct bpf_insn *pc)
    284        1.1     alnsn {
    285        1.1     alnsn 
    286        1.1     alnsn 	switch (BPF_SIZE(pc->code)) {
    287       1.39     alnsn 	case BPF_W: return 4;
    288       1.39     alnsn 	case BPF_H: return 2;
    289       1.39     alnsn 	case BPF_B: return 1;
    290       1.39     alnsn 	default:    return 0;
    291        1.1     alnsn 	}
    292        1.1     alnsn }
    293        1.1     alnsn 
    294       1.13     alnsn /*
    295       1.13     alnsn  * Copy buf and buflen members of bpf_args from BJ_ARGS
    296       1.13     alnsn  * pointer to BJ_BUF and BJ_BUFLEN registers.
    297       1.13     alnsn  */
    298       1.13     alnsn static int
    299       1.13     alnsn load_buf_buflen(struct sljit_compiler *compiler)
    300       1.13     alnsn {
    301       1.13     alnsn 	int status;
    302       1.13     alnsn 
    303       1.13     alnsn 	status = sljit_emit_op1(compiler,
    304       1.13     alnsn 	    SLJIT_MOV_P,
    305       1.13     alnsn 	    BJ_BUF, 0,
    306       1.13     alnsn 	    SLJIT_MEM1(BJ_ARGS),
    307       1.13     alnsn 	    offsetof(struct bpf_args, pkt));
    308       1.13     alnsn 	if (status != SLJIT_SUCCESS)
    309       1.13     alnsn 		return status;
    310       1.13     alnsn 
    311       1.13     alnsn 	status = sljit_emit_op1(compiler,
    312       1.21     alnsn 	    SLJIT_MOV, /* size_t source */
    313       1.13     alnsn 	    BJ_BUFLEN, 0,
    314       1.13     alnsn 	    SLJIT_MEM1(BJ_ARGS),
    315       1.13     alnsn 	    offsetof(struct bpf_args, buflen));
    316       1.13     alnsn 
    317       1.13     alnsn 	return status;
    318       1.13     alnsn }
    319       1.13     alnsn 
    320        1.7     alnsn static bool
    321        1.7     alnsn grow_jumps(struct sljit_jump ***jumps, size_t *size)
    322        1.7     alnsn {
    323        1.7     alnsn 	struct sljit_jump **newptr;
    324        1.7     alnsn 	const size_t elemsz = sizeof(struct sljit_jump *);
    325        1.7     alnsn 	size_t old_size = *size;
    326        1.7     alnsn 	size_t new_size = 2 * old_size;
    327        1.7     alnsn 
    328        1.7     alnsn 	if (new_size < old_size || new_size > SIZE_MAX / elemsz)
    329        1.7     alnsn 		return false;
    330        1.7     alnsn 
    331        1.7     alnsn 	newptr = BJ_ALLOC(new_size * elemsz);
    332        1.7     alnsn 	if (newptr == NULL)
    333        1.7     alnsn 		return false;
    334        1.7     alnsn 
    335        1.7     alnsn 	memcpy(newptr, *jumps, old_size * elemsz);
    336        1.7     alnsn 	BJ_FREE(*jumps, old_size * elemsz);
    337        1.7     alnsn 
    338        1.7     alnsn 	*jumps = newptr;
    339        1.7     alnsn 	*size = new_size;
    340        1.7     alnsn 	return true;
    341        1.7     alnsn }
    342        1.7     alnsn 
    343        1.7     alnsn static bool
    344        1.7     alnsn append_jump(struct sljit_jump *jump, struct sljit_jump ***jumps,
    345        1.7     alnsn     size_t *size, size_t *max_size)
    346        1.1     alnsn {
    347        1.7     alnsn 	if (*size == *max_size && !grow_jumps(jumps, max_size))
    348        1.7     alnsn 		return false;
    349        1.1     alnsn 
    350        1.7     alnsn 	(*jumps)[(*size)++] = jump;
    351        1.7     alnsn 	return true;
    352        1.1     alnsn }
    353        1.1     alnsn 
    354        1.1     alnsn /*
    355       1.24     alnsn  * Emit code for BPF_LD+BPF_B+BPF_ABS    A <- P[k:1].
    356        1.1     alnsn  */
    357        1.1     alnsn static int
    358       1.45     alnsn emit_read8(struct sljit_compiler *compiler, sljit_s32 src, uint32_t k)
    359        1.1     alnsn {
    360        1.1     alnsn 
    361        1.1     alnsn 	return sljit_emit_op1(compiler,
    362       1.45     alnsn 	    SLJIT_MOV_U8,
    363        1.7     alnsn 	    BJ_AREG, 0,
    364       1.27     alnsn 	    SLJIT_MEM1(src), k);
    365        1.1     alnsn }
    366        1.1     alnsn 
    367        1.1     alnsn /*
    368       1.24     alnsn  * Emit code for BPF_LD+BPF_H+BPF_ABS    A <- P[k:2].
    369        1.1     alnsn  */
    370        1.1     alnsn static int
    371       1.45     alnsn emit_read16(struct sljit_compiler *compiler, sljit_s32 src, uint32_t k)
    372        1.1     alnsn {
    373        1.1     alnsn 	int status;
    374        1.1     alnsn 
    375       1.27     alnsn 	BJ_ASSERT(k <= UINT32_MAX - 1);
    376       1.27     alnsn 
    377       1.27     alnsn 	/* A = buf[k]; */
    378        1.1     alnsn 	status = sljit_emit_op1(compiler,
    379       1.45     alnsn 	    SLJIT_MOV_U8,
    380       1.27     alnsn 	    BJ_AREG, 0,
    381       1.27     alnsn 	    SLJIT_MEM1(src), k);
    382        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    383        1.1     alnsn 		return status;
    384        1.1     alnsn 
    385       1.27     alnsn 	/* tmp1 = buf[k+1]; */
    386        1.1     alnsn 	status = sljit_emit_op1(compiler,
    387       1.45     alnsn 	    SLJIT_MOV_U8,
    388       1.27     alnsn 	    BJ_TMP1REG, 0,
    389       1.27     alnsn 	    SLJIT_MEM1(src), k+1);
    390        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    391        1.1     alnsn 		return status;
    392        1.1     alnsn 
    393       1.27     alnsn 	/* A = A << 8; */
    394        1.1     alnsn 	status = sljit_emit_op2(compiler,
    395        1.1     alnsn 	    SLJIT_SHL,
    396       1.27     alnsn 	    BJ_AREG, 0,
    397       1.27     alnsn 	    BJ_AREG, 0,
    398        1.1     alnsn 	    SLJIT_IMM, 8);
    399        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    400        1.1     alnsn 		return status;
    401        1.1     alnsn 
    402        1.1     alnsn 	/* A = A + tmp1; */
    403        1.1     alnsn 	status = sljit_emit_op2(compiler,
    404        1.1     alnsn 	    SLJIT_ADD,
    405        1.7     alnsn 	    BJ_AREG, 0,
    406        1.7     alnsn 	    BJ_AREG, 0,
    407        1.7     alnsn 	    BJ_TMP1REG, 0);
    408        1.1     alnsn 	return status;
    409        1.1     alnsn }
    410        1.1     alnsn 
    411        1.1     alnsn /*
    412       1.24     alnsn  * Emit code for BPF_LD+BPF_W+BPF_ABS    A <- P[k:4].
    413        1.1     alnsn  */
    414        1.1     alnsn static int
    415       1.45     alnsn emit_read32(struct sljit_compiler *compiler, sljit_s32 src, uint32_t k)
    416        1.1     alnsn {
    417        1.1     alnsn 	int status;
    418        1.1     alnsn 
    419       1.27     alnsn 	BJ_ASSERT(k <= UINT32_MAX - 3);
    420        1.1     alnsn 
    421       1.27     alnsn 	/* A = buf[k]; */
    422        1.1     alnsn 	status = sljit_emit_op1(compiler,
    423       1.45     alnsn 	    SLJIT_MOV_U8,
    424       1.27     alnsn 	    BJ_AREG, 0,
    425       1.27     alnsn 	    SLJIT_MEM1(src), k);
    426        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    427        1.1     alnsn 		return status;
    428        1.1     alnsn 
    429       1.27     alnsn 	/* tmp1 = buf[k+1]; */
    430        1.1     alnsn 	status = sljit_emit_op1(compiler,
    431       1.45     alnsn 	    SLJIT_MOV_U8,
    432       1.27     alnsn 	    BJ_TMP1REG, 0,
    433       1.27     alnsn 	    SLJIT_MEM1(src), k+1);
    434        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    435        1.1     alnsn 		return status;
    436        1.1     alnsn 
    437       1.27     alnsn 	/* A = A << 8; */
    438        1.1     alnsn 	status = sljit_emit_op2(compiler,
    439        1.1     alnsn 	    SLJIT_SHL,
    440       1.27     alnsn 	    BJ_AREG, 0,
    441       1.27     alnsn 	    BJ_AREG, 0,
    442       1.27     alnsn 	    SLJIT_IMM, 8);
    443        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    444        1.1     alnsn 		return status;
    445        1.1     alnsn 
    446        1.1     alnsn 	/* A = A + tmp1; */
    447        1.1     alnsn 	status = sljit_emit_op2(compiler,
    448        1.1     alnsn 	    SLJIT_ADD,
    449        1.7     alnsn 	    BJ_AREG, 0,
    450        1.7     alnsn 	    BJ_AREG, 0,
    451        1.7     alnsn 	    BJ_TMP1REG, 0);
    452        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    453        1.1     alnsn 		return status;
    454        1.1     alnsn 
    455        1.1     alnsn 	/* tmp1 = buf[k+2]; */
    456        1.1     alnsn 	status = sljit_emit_op1(compiler,
    457       1.45     alnsn 	    SLJIT_MOV_U8,
    458        1.7     alnsn 	    BJ_TMP1REG, 0,
    459       1.27     alnsn 	    SLJIT_MEM1(src), k+2);
    460        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    461        1.1     alnsn 		return status;
    462        1.1     alnsn 
    463       1.27     alnsn 	/* A = A << 8; */
    464        1.1     alnsn 	status = sljit_emit_op2(compiler,
    465        1.1     alnsn 	    SLJIT_SHL,
    466       1.27     alnsn 	    BJ_AREG, 0,
    467       1.27     alnsn 	    BJ_AREG, 0,
    468       1.27     alnsn 	    SLJIT_IMM, 8);
    469        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    470        1.1     alnsn 		return status;
    471        1.1     alnsn 
    472       1.27     alnsn 	/* A = A + tmp1; */
    473        1.1     alnsn 	status = sljit_emit_op2(compiler,
    474        1.1     alnsn 	    SLJIT_ADD,
    475        1.7     alnsn 	    BJ_AREG, 0,
    476        1.7     alnsn 	    BJ_AREG, 0,
    477       1.27     alnsn 	    BJ_TMP1REG, 0);
    478       1.27     alnsn 	if (status != SLJIT_SUCCESS)
    479       1.27     alnsn 		return status;
    480       1.27     alnsn 
    481       1.27     alnsn 	/* tmp1 = buf[k+3]; */
    482       1.27     alnsn 	status = sljit_emit_op1(compiler,
    483       1.45     alnsn 	    SLJIT_MOV_U8,
    484       1.27     alnsn 	    BJ_TMP1REG, 0,
    485       1.27     alnsn 	    SLJIT_MEM1(src), k+3);
    486        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    487        1.1     alnsn 		return status;
    488        1.1     alnsn 
    489       1.27     alnsn 	/* A = A << 8; */
    490        1.1     alnsn 	status = sljit_emit_op2(compiler,
    491        1.1     alnsn 	    SLJIT_SHL,
    492       1.27     alnsn 	    BJ_AREG, 0,
    493       1.27     alnsn 	    BJ_AREG, 0,
    494        1.1     alnsn 	    SLJIT_IMM, 8);
    495        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    496        1.1     alnsn 		return status;
    497        1.1     alnsn 
    498        1.1     alnsn 	/* A = A + tmp1; */
    499        1.1     alnsn 	status = sljit_emit_op2(compiler,
    500        1.1     alnsn 	    SLJIT_ADD,
    501        1.7     alnsn 	    BJ_AREG, 0,
    502        1.7     alnsn 	    BJ_AREG, 0,
    503        1.7     alnsn 	    BJ_TMP1REG, 0);
    504        1.1     alnsn 	return status;
    505        1.1     alnsn }
    506        1.1     alnsn 
    507        1.1     alnsn #ifdef _KERNEL
    508        1.1     alnsn /*
    509       1.24     alnsn  * Emit code for m_xword/m_xhalf/m_xbyte call.
    510        1.1     alnsn  *
    511       1.24     alnsn  * @pc BPF_LD+BPF_W+BPF_ABS    A <- P[k:4]
    512       1.24     alnsn  *     BPF_LD+BPF_H+BPF_ABS    A <- P[k:2]
    513       1.24     alnsn  *     BPF_LD+BPF_B+BPF_ABS    A <- P[k:1]
    514       1.24     alnsn  *     BPF_LD+BPF_W+BPF_IND    A <- P[X+k:4]
    515       1.24     alnsn  *     BPF_LD+BPF_H+BPF_IND    A <- P[X+k:2]
    516       1.24     alnsn  *     BPF_LD+BPF_B+BPF_IND    A <- P[X+k:1]
    517       1.24     alnsn  *     BPF_LDX+BPF_B+BPF_MSH   X <- 4*(P[k:1]&0xf)
    518        1.1     alnsn  */
    519        1.1     alnsn static int
    520       1.32     alnsn emit_xcall(struct sljit_compiler *compiler, bpfjit_hint_t hints,
    521       1.32     alnsn     const struct bpf_insn *pc, int dst, struct sljit_jump ***ret0,
    522       1.32     alnsn     size_t *ret0_size, size_t *ret0_maxsize,
    523        1.1     alnsn     uint32_t (*fn)(const struct mbuf *, uint32_t, int *))
    524        1.1     alnsn {
    525       1.32     alnsn #if BJ_XREG == SLJIT_RETURN_REG   || \
    526       1.45     alnsn     BJ_XREG == SLJIT_R0 || \
    527       1.45     alnsn     BJ_XREG == SLJIT_R1 || \
    528       1.45     alnsn     BJ_XREG == SLJIT_R2
    529       1.32     alnsn #error "Not supported assignment of registers."
    530       1.32     alnsn #endif
    531       1.23     alnsn 	struct sljit_jump *jump;
    532       1.45     alnsn 	sljit_s32 save_reg;
    533        1.1     alnsn 	int status;
    534        1.1     alnsn 
    535       1.32     alnsn 	save_reg = (BPF_CLASS(pc->code) == BPF_LDX) ? BJ_AREG : BJ_XREG;
    536       1.23     alnsn 
    537       1.32     alnsn 	if (save_reg == BJ_AREG || (hints & BJ_HINT_XREG)) {
    538       1.32     alnsn 		/* save A or X */
    539        1.1     alnsn 		status = sljit_emit_op1(compiler,
    540       1.45     alnsn 		    SLJIT_MOV_U32,
    541       1.45     alnsn 		    SLJIT_MEM1(SLJIT_SP),
    542       1.32     alnsn 		    offsetof(struct bpfjit_stack, reg),
    543       1.32     alnsn 		    save_reg, 0);
    544        1.1     alnsn 		if (status != SLJIT_SUCCESS)
    545        1.1     alnsn 			return status;
    546        1.1     alnsn 	}
    547        1.1     alnsn 
    548        1.1     alnsn 	/*
    549       1.23     alnsn 	 * Prepare registers for fn(mbuf, k, &err) call.
    550        1.1     alnsn 	 */
    551        1.1     alnsn 	status = sljit_emit_op1(compiler,
    552        1.1     alnsn 	    SLJIT_MOV,
    553       1.45     alnsn 	    SLJIT_R0, 0,
    554        1.7     alnsn 	    BJ_BUF, 0);
    555        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    556        1.1     alnsn 		return status;
    557        1.1     alnsn 
    558        1.1     alnsn 	if (BPF_CLASS(pc->code) == BPF_LD && BPF_MODE(pc->code) == BPF_IND) {
    559       1.31     alnsn 		if (pc->k == 0) {
    560       1.31     alnsn 			/* k = X; */
    561       1.31     alnsn 			status = sljit_emit_op1(compiler,
    562       1.31     alnsn 			    SLJIT_MOV,
    563       1.45     alnsn 			    SLJIT_R1, 0,
    564       1.31     alnsn 			    BJ_XREG, 0);
    565       1.31     alnsn 			if (status != SLJIT_SUCCESS)
    566       1.31     alnsn 				return status;
    567       1.31     alnsn 		} else {
    568       1.31     alnsn 			/* if (X > UINT32_MAX - pc->k) return 0; */
    569       1.31     alnsn 			jump = sljit_emit_cmp(compiler,
    570       1.45     alnsn 			    SLJIT_GREATER,
    571       1.31     alnsn 			    BJ_XREG, 0,
    572       1.31     alnsn 			    SLJIT_IMM, UINT32_MAX - pc->k);
    573       1.31     alnsn 			if (jump == NULL)
    574       1.31     alnsn 				return SLJIT_ERR_ALLOC_FAILED;
    575       1.31     alnsn 			if (!append_jump(jump, ret0, ret0_size, ret0_maxsize))
    576       1.31     alnsn 				return SLJIT_ERR_ALLOC_FAILED;
    577       1.31     alnsn 
    578       1.31     alnsn 			/* k = X + pc->k; */
    579       1.31     alnsn 			status = sljit_emit_op2(compiler,
    580       1.31     alnsn 			    SLJIT_ADD,
    581       1.45     alnsn 			    SLJIT_R1, 0,
    582       1.31     alnsn 			    BJ_XREG, 0,
    583       1.31     alnsn 			    SLJIT_IMM, (uint32_t)pc->k);
    584       1.31     alnsn 			if (status != SLJIT_SUCCESS)
    585       1.31     alnsn 				return status;
    586       1.31     alnsn 		}
    587        1.1     alnsn 	} else {
    588       1.23     alnsn 		/* k = pc->k */
    589        1.1     alnsn 		status = sljit_emit_op1(compiler,
    590        1.1     alnsn 		    SLJIT_MOV,
    591       1.45     alnsn 		    SLJIT_R1, 0,
    592        1.1     alnsn 		    SLJIT_IMM, (uint32_t)pc->k);
    593       1.24     alnsn 		if (status != SLJIT_SUCCESS)
    594       1.24     alnsn 			return status;
    595        1.1     alnsn 	}
    596        1.1     alnsn 
    597       1.21     alnsn 	/*
    598       1.21     alnsn 	 * The third argument of fn is an address on stack.
    599       1.21     alnsn 	 */
    600        1.1     alnsn 	status = sljit_get_local_base(compiler,
    601       1.45     alnsn 	    SLJIT_R2, 0,
    602       1.21     alnsn 	    offsetof(struct bpfjit_stack, err));
    603        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    604        1.1     alnsn 		return status;
    605        1.1     alnsn 
    606        1.1     alnsn 	/* fn(buf, k, &err); */
    607        1.1     alnsn 	status = sljit_emit_ijump(compiler,
    608        1.1     alnsn 	    SLJIT_CALL3,
    609        1.1     alnsn 	    SLJIT_IMM, SLJIT_FUNC_OFFSET(fn));
    610       1.24     alnsn 	if (status != SLJIT_SUCCESS)
    611       1.24     alnsn 		return status;
    612        1.1     alnsn 
    613        1.7     alnsn 	if (dst != SLJIT_RETURN_REG) {
    614        1.1     alnsn 		/* move return value to dst */
    615        1.1     alnsn 		status = sljit_emit_op1(compiler,
    616        1.1     alnsn 		    SLJIT_MOV,
    617       1.23     alnsn 		    dst, 0,
    618        1.1     alnsn 		    SLJIT_RETURN_REG, 0);
    619        1.1     alnsn 		if (status != SLJIT_SUCCESS)
    620        1.1     alnsn 			return status;
    621        1.7     alnsn 	}
    622        1.1     alnsn 
    623       1.30     alnsn 	/* if (*err != 0) return 0; */
    624       1.30     alnsn 	jump = sljit_emit_cmp(compiler,
    625       1.45     alnsn 	    SLJIT_NOT_EQUAL|SLJIT_I32_OP,
    626       1.45     alnsn 	    SLJIT_MEM1(SLJIT_SP),
    627       1.30     alnsn 	    offsetof(struct bpfjit_stack, err),
    628        1.1     alnsn 	    SLJIT_IMM, 0);
    629       1.23     alnsn 	if (jump == NULL)
    630       1.23     alnsn 		return SLJIT_ERR_ALLOC_FAILED;
    631       1.23     alnsn 
    632       1.23     alnsn 	if (!append_jump(jump, ret0, ret0_size, ret0_maxsize))
    633        1.1     alnsn 		return SLJIT_ERR_ALLOC_FAILED;
    634        1.1     alnsn 
    635       1.32     alnsn 	if (save_reg == BJ_AREG || (hints & BJ_HINT_XREG)) {
    636       1.32     alnsn 		/* restore A or X */
    637       1.26     alnsn 		status = sljit_emit_op1(compiler,
    638       1.45     alnsn 		    SLJIT_MOV_U32,
    639       1.32     alnsn 		    save_reg, 0,
    640       1.45     alnsn 		    SLJIT_MEM1(SLJIT_SP),
    641       1.32     alnsn 		    offsetof(struct bpfjit_stack, reg));
    642       1.26     alnsn 		if (status != SLJIT_SUCCESS)
    643       1.26     alnsn 			return status;
    644       1.26     alnsn 	}
    645       1.26     alnsn 
    646       1.24     alnsn 	return SLJIT_SUCCESS;
    647        1.1     alnsn }
    648        1.1     alnsn #endif
    649        1.1     alnsn 
    650        1.1     alnsn /*
    651       1.13     alnsn  * Emit code for BPF_COP and BPF_COPX instructions.
    652       1.13     alnsn  */
    653       1.13     alnsn static int
    654       1.32     alnsn emit_cop(struct sljit_compiler *compiler, bpfjit_hint_t hints,
    655       1.28     alnsn     const bpf_ctx_t *bc, const struct bpf_insn *pc,
    656       1.28     alnsn     struct sljit_jump ***ret0, size_t *ret0_size, size_t *ret0_maxsize)
    657       1.13     alnsn {
    658       1.32     alnsn #if BJ_XREG    == SLJIT_RETURN_REG   || \
    659       1.45     alnsn     BJ_XREG    == SLJIT_R0 || \
    660       1.45     alnsn     BJ_XREG    == SLJIT_R1 || \
    661       1.45     alnsn     BJ_XREG    == SLJIT_R2 || \
    662       1.45     alnsn     BJ_TMP3REG == SLJIT_R0 || \
    663       1.45     alnsn     BJ_TMP3REG == SLJIT_R1 || \
    664       1.45     alnsn     BJ_TMP3REG == SLJIT_R2
    665       1.13     alnsn #error "Not supported assignment of registers."
    666       1.13     alnsn #endif
    667       1.13     alnsn 
    668       1.13     alnsn 	struct sljit_jump *jump;
    669       1.45     alnsn 	sljit_s32 call_reg;
    670       1.28     alnsn 	sljit_sw call_off;
    671       1.13     alnsn 	int status;
    672       1.13     alnsn 
    673       1.13     alnsn 	BJ_ASSERT(bc != NULL && bc->copfuncs != NULL);
    674       1.13     alnsn 
    675       1.32     alnsn 	if (hints & BJ_HINT_LDX) {
    676       1.32     alnsn 		/* save X */
    677       1.32     alnsn 		status = sljit_emit_op1(compiler,
    678       1.45     alnsn 		    SLJIT_MOV_U32,
    679       1.45     alnsn 		    SLJIT_MEM1(SLJIT_SP),
    680       1.32     alnsn 		    offsetof(struct bpfjit_stack, reg),
    681       1.32     alnsn 		    BJ_XREG, 0);
    682       1.32     alnsn 		if (status != SLJIT_SUCCESS)
    683       1.32     alnsn 			return status;
    684       1.32     alnsn 	}
    685       1.32     alnsn 
    686       1.28     alnsn 	if (BPF_MISCOP(pc->code) == BPF_COP) {
    687       1.28     alnsn 		call_reg = SLJIT_IMM;
    688       1.28     alnsn 		call_off = SLJIT_FUNC_OFFSET(bc->copfuncs[pc->k]);
    689       1.28     alnsn 	} else {
    690       1.13     alnsn 		/* if (X >= bc->nfuncs) return 0; */
    691       1.13     alnsn 		jump = sljit_emit_cmp(compiler,
    692       1.45     alnsn 		    SLJIT_GREATER_EQUAL,
    693       1.13     alnsn 		    BJ_XREG, 0,
    694       1.13     alnsn 		    SLJIT_IMM, bc->nfuncs);
    695       1.13     alnsn 		if (jump == NULL)
    696       1.13     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
    697       1.28     alnsn 		if (!append_jump(jump, ret0, ret0_size, ret0_maxsize))
    698       1.28     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
    699       1.28     alnsn 
    700       1.28     alnsn 		/* tmp1 = ctx; */
    701       1.28     alnsn 		status = sljit_emit_op1(compiler,
    702       1.28     alnsn 		    SLJIT_MOV_P,
    703       1.28     alnsn 		    BJ_TMP1REG, 0,
    704       1.45     alnsn 		    SLJIT_MEM1(SLJIT_SP),
    705       1.28     alnsn 		    offsetof(struct bpfjit_stack, ctx));
    706       1.28     alnsn 		if (status != SLJIT_SUCCESS)
    707       1.28     alnsn 			return status;
    708       1.28     alnsn 
    709       1.28     alnsn 		/* tmp1 = ctx->copfuncs; */
    710       1.28     alnsn 		status = sljit_emit_op1(compiler,
    711       1.28     alnsn 		    SLJIT_MOV_P,
    712       1.28     alnsn 		    BJ_TMP1REG, 0,
    713       1.28     alnsn 		    SLJIT_MEM1(BJ_TMP1REG),
    714       1.28     alnsn 		    offsetof(struct bpf_ctx, copfuncs));
    715       1.28     alnsn 		if (status != SLJIT_SUCCESS)
    716       1.28     alnsn 			return status;
    717       1.28     alnsn 
    718       1.28     alnsn 		/* tmp2 = X; */
    719       1.28     alnsn 		status = sljit_emit_op1(compiler,
    720       1.28     alnsn 		    SLJIT_MOV,
    721       1.28     alnsn 		    BJ_TMP2REG, 0,
    722       1.28     alnsn 		    BJ_XREG, 0);
    723       1.28     alnsn 		if (status != SLJIT_SUCCESS)
    724       1.28     alnsn 			return status;
    725       1.28     alnsn 
    726       1.28     alnsn 		/* tmp3 = ctx->copfuncs[tmp2]; */
    727       1.28     alnsn 		call_reg = BJ_TMP3REG;
    728       1.28     alnsn 		call_off = 0;
    729       1.28     alnsn 		status = sljit_emit_op1(compiler,
    730       1.28     alnsn 		    SLJIT_MOV_P,
    731       1.28     alnsn 		    call_reg, call_off,
    732       1.28     alnsn 		    SLJIT_MEM2(BJ_TMP1REG, BJ_TMP2REG),
    733       1.28     alnsn 		    SLJIT_WORD_SHIFT);
    734       1.28     alnsn 		if (status != SLJIT_SUCCESS)
    735       1.28     alnsn 			return status;
    736       1.13     alnsn 	}
    737       1.13     alnsn 
    738       1.13     alnsn 	/*
    739       1.13     alnsn 	 * Copy bpf_copfunc_t arguments to registers.
    740       1.13     alnsn 	 */
    741       1.45     alnsn #if BJ_AREG != SLJIT_R2
    742       1.13     alnsn 	status = sljit_emit_op1(compiler,
    743       1.45     alnsn 	    SLJIT_MOV_U32,
    744       1.45     alnsn 	    SLJIT_R2, 0,
    745       1.13     alnsn 	    BJ_AREG, 0);
    746       1.13     alnsn 	if (status != SLJIT_SUCCESS)
    747       1.13     alnsn 		return status;
    748       1.13     alnsn #endif
    749       1.13     alnsn 
    750       1.13     alnsn 	status = sljit_emit_op1(compiler,
    751       1.13     alnsn 	    SLJIT_MOV_P,
    752       1.45     alnsn 	    SLJIT_R0, 0,
    753       1.45     alnsn 	    SLJIT_MEM1(SLJIT_SP),
    754       1.13     alnsn 	    offsetof(struct bpfjit_stack, ctx));
    755       1.13     alnsn 	if (status != SLJIT_SUCCESS)
    756       1.13     alnsn 		return status;
    757       1.13     alnsn 
    758       1.13     alnsn 	status = sljit_emit_op1(compiler,
    759       1.13     alnsn 	    SLJIT_MOV_P,
    760       1.45     alnsn 	    SLJIT_R1, 0,
    761       1.13     alnsn 	    BJ_ARGS, 0);
    762       1.13     alnsn 	if (status != SLJIT_SUCCESS)
    763       1.13     alnsn 		return status;
    764       1.13     alnsn 
    765       1.28     alnsn 	status = sljit_emit_ijump(compiler,
    766       1.28     alnsn 	    SLJIT_CALL3, call_reg, call_off);
    767       1.28     alnsn 	if (status != SLJIT_SUCCESS)
    768       1.28     alnsn 		return status;
    769       1.13     alnsn 
    770       1.13     alnsn #if BJ_AREG != SLJIT_RETURN_REG
    771       1.13     alnsn 	status = sljit_emit_op1(compiler,
    772       1.13     alnsn 	    SLJIT_MOV,
    773       1.13     alnsn 	    BJ_AREG, 0,
    774       1.13     alnsn 	    SLJIT_RETURN_REG, 0);
    775       1.13     alnsn 	if (status != SLJIT_SUCCESS)
    776       1.13     alnsn 		return status;
    777       1.13     alnsn #endif
    778       1.13     alnsn 
    779       1.32     alnsn 	if (hints & BJ_HINT_LDX) {
    780       1.32     alnsn 		/* restore X */
    781       1.32     alnsn 		status = sljit_emit_op1(compiler,
    782       1.45     alnsn 		    SLJIT_MOV_U32,
    783       1.32     alnsn 		    BJ_XREG, 0,
    784       1.45     alnsn 		    SLJIT_MEM1(SLJIT_SP),
    785       1.32     alnsn 		    offsetof(struct bpfjit_stack, reg));
    786       1.32     alnsn 		if (status != SLJIT_SUCCESS)
    787       1.32     alnsn 			return status;
    788       1.32     alnsn 	}
    789       1.32     alnsn 
    790       1.24     alnsn 	return SLJIT_SUCCESS;
    791       1.13     alnsn }
    792       1.13     alnsn 
    793       1.13     alnsn /*
    794        1.1     alnsn  * Generate code for
    795        1.1     alnsn  * BPF_LD+BPF_W+BPF_ABS    A <- P[k:4]
    796        1.1     alnsn  * BPF_LD+BPF_H+BPF_ABS    A <- P[k:2]
    797        1.1     alnsn  * BPF_LD+BPF_B+BPF_ABS    A <- P[k:1]
    798        1.1     alnsn  * BPF_LD+BPF_W+BPF_IND    A <- P[X+k:4]
    799        1.1     alnsn  * BPF_LD+BPF_H+BPF_IND    A <- P[X+k:2]
    800        1.1     alnsn  * BPF_LD+BPF_B+BPF_IND    A <- P[X+k:1]
    801        1.1     alnsn  */
    802        1.1     alnsn static int
    803       1.32     alnsn emit_pkt_read(struct sljit_compiler *compiler, bpfjit_hint_t hints,
    804        1.7     alnsn     const struct bpf_insn *pc, struct sljit_jump *to_mchain_jump,
    805        1.7     alnsn     struct sljit_jump ***ret0, size_t *ret0_size, size_t *ret0_maxsize)
    806        1.1     alnsn {
    807       1.25     alnsn 	int status = SLJIT_ERR_ALLOC_FAILED;
    808        1.1     alnsn 	uint32_t width;
    809       1.45     alnsn 	sljit_s32 ld_reg;
    810        1.1     alnsn 	struct sljit_jump *jump;
    811        1.1     alnsn #ifdef _KERNEL
    812        1.1     alnsn 	struct sljit_label *label;
    813        1.1     alnsn 	struct sljit_jump *over_mchain_jump;
    814        1.1     alnsn 	const bool check_zero_buflen = (to_mchain_jump != NULL);
    815        1.1     alnsn #endif
    816        1.1     alnsn 	const uint32_t k = pc->k;
    817        1.1     alnsn 
    818        1.1     alnsn #ifdef _KERNEL
    819        1.1     alnsn 	if (to_mchain_jump == NULL) {
    820        1.1     alnsn 		to_mchain_jump = sljit_emit_cmp(compiler,
    821       1.45     alnsn 		    SLJIT_EQUAL,
    822        1.7     alnsn 		    BJ_BUFLEN, 0,
    823        1.1     alnsn 		    SLJIT_IMM, 0);
    824        1.1     alnsn 		if (to_mchain_jump == NULL)
    825        1.7     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
    826        1.1     alnsn 	}
    827        1.1     alnsn #endif
    828        1.1     alnsn 
    829       1.27     alnsn 	ld_reg = BJ_BUF;
    830        1.1     alnsn 	width = read_width(pc);
    831       1.39     alnsn 	if (width == 0)
    832       1.39     alnsn 		return SLJIT_ERR_ALLOC_FAILED;
    833        1.1     alnsn 
    834        1.1     alnsn 	if (BPF_MODE(pc->code) == BPF_IND) {
    835        1.1     alnsn 		/* tmp1 = buflen - (pc->k + width); */
    836        1.1     alnsn 		status = sljit_emit_op2(compiler,
    837        1.1     alnsn 		    SLJIT_SUB,
    838        1.7     alnsn 		    BJ_TMP1REG, 0,
    839        1.7     alnsn 		    BJ_BUFLEN, 0,
    840        1.1     alnsn 		    SLJIT_IMM, k + width);
    841        1.1     alnsn 		if (status != SLJIT_SUCCESS)
    842        1.1     alnsn 			return status;
    843        1.1     alnsn 
    844       1.27     alnsn 		/* ld_reg = buf + X; */
    845       1.27     alnsn 		ld_reg = BJ_TMP2REG;
    846        1.1     alnsn 		status = sljit_emit_op2(compiler,
    847        1.1     alnsn 		    SLJIT_ADD,
    848       1.27     alnsn 		    ld_reg, 0,
    849        1.7     alnsn 		    BJ_BUF, 0,
    850        1.7     alnsn 		    BJ_XREG, 0);
    851        1.1     alnsn 		if (status != SLJIT_SUCCESS)
    852        1.1     alnsn 			return status;
    853        1.1     alnsn 
    854        1.1     alnsn 		/* if (tmp1 < X) return 0; */
    855        1.1     alnsn 		jump = sljit_emit_cmp(compiler,
    856       1.45     alnsn 		    SLJIT_LESS,
    857        1.7     alnsn 		    BJ_TMP1REG, 0,
    858        1.7     alnsn 		    BJ_XREG, 0);
    859        1.1     alnsn 		if (jump == NULL)
    860        1.7     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
    861        1.7     alnsn 		if (!append_jump(jump, ret0, ret0_size, ret0_maxsize))
    862        1.7     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
    863        1.1     alnsn 	}
    864        1.1     alnsn 
    865       1.40     alnsn 	/*
    866       1.40     alnsn 	 * Don't emit wrapped-around reads. They're dead code but
    867       1.40     alnsn 	 * dead code elimination logic isn't smart enough to figure
    868       1.40     alnsn 	 * it out.
    869       1.40     alnsn 	 */
    870       1.40     alnsn 	if (k <= UINT32_MAX - width + 1) {
    871       1.40     alnsn 		switch (width) {
    872       1.40     alnsn 		case 4:
    873       1.40     alnsn 			status = emit_read32(compiler, ld_reg, k);
    874       1.40     alnsn 			break;
    875       1.40     alnsn 		case 2:
    876       1.40     alnsn 			status = emit_read16(compiler, ld_reg, k);
    877       1.40     alnsn 			break;
    878       1.40     alnsn 		case 1:
    879       1.40     alnsn 			status = emit_read8(compiler, ld_reg, k);
    880       1.40     alnsn 			break;
    881       1.40     alnsn 		}
    882       1.40     alnsn 
    883       1.40     alnsn 		if (status != SLJIT_SUCCESS)
    884       1.40     alnsn 			return status;
    885        1.1     alnsn 	}
    886        1.1     alnsn 
    887        1.1     alnsn #ifdef _KERNEL
    888        1.1     alnsn 	over_mchain_jump = sljit_emit_jump(compiler, SLJIT_JUMP);
    889        1.1     alnsn 	if (over_mchain_jump == NULL)
    890        1.7     alnsn 		return SLJIT_ERR_ALLOC_FAILED;
    891        1.1     alnsn 
    892        1.1     alnsn 	/* entry point to mchain handler */
    893        1.1     alnsn 	label = sljit_emit_label(compiler);
    894        1.1     alnsn 	if (label == NULL)
    895        1.7     alnsn 		return SLJIT_ERR_ALLOC_FAILED;
    896        1.1     alnsn 	sljit_set_label(to_mchain_jump, label);
    897        1.1     alnsn 
    898        1.1     alnsn 	if (check_zero_buflen) {
    899        1.1     alnsn 		/* if (buflen != 0) return 0; */
    900        1.1     alnsn 		jump = sljit_emit_cmp(compiler,
    901       1.45     alnsn 		    SLJIT_NOT_EQUAL,
    902        1.7     alnsn 		    BJ_BUFLEN, 0,
    903        1.1     alnsn 		    SLJIT_IMM, 0);
    904        1.1     alnsn 		if (jump == NULL)
    905        1.1     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
    906        1.7     alnsn 		if (!append_jump(jump, ret0, ret0_size, ret0_maxsize))
    907        1.7     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
    908        1.1     alnsn 	}
    909        1.1     alnsn 
    910        1.1     alnsn 	switch (width) {
    911        1.1     alnsn 	case 4:
    912       1.32     alnsn 		status = emit_xcall(compiler, hints, pc, BJ_AREG,
    913       1.23     alnsn 		    ret0, ret0_size, ret0_maxsize, &m_xword);
    914        1.1     alnsn 		break;
    915        1.1     alnsn 	case 2:
    916       1.32     alnsn 		status = emit_xcall(compiler, hints, pc, BJ_AREG,
    917       1.23     alnsn 		    ret0, ret0_size, ret0_maxsize, &m_xhalf);
    918        1.1     alnsn 		break;
    919        1.1     alnsn 	case 1:
    920       1.32     alnsn 		status = emit_xcall(compiler, hints, pc, BJ_AREG,
    921       1.23     alnsn 		    ret0, ret0_size, ret0_maxsize, &m_xbyte);
    922        1.1     alnsn 		break;
    923        1.1     alnsn 	}
    924        1.1     alnsn 
    925        1.1     alnsn 	if (status != SLJIT_SUCCESS)
    926        1.1     alnsn 		return status;
    927        1.1     alnsn 
    928        1.1     alnsn 	label = sljit_emit_label(compiler);
    929        1.1     alnsn 	if (label == NULL)
    930        1.1     alnsn 		return SLJIT_ERR_ALLOC_FAILED;
    931        1.1     alnsn 	sljit_set_label(over_mchain_jump, label);
    932        1.1     alnsn #endif
    933        1.1     alnsn 
    934       1.24     alnsn 	return SLJIT_SUCCESS;
    935        1.1     alnsn }
    936        1.1     alnsn 
    937       1.13     alnsn static int
    938       1.19     alnsn emit_memload(struct sljit_compiler *compiler,
    939       1.45     alnsn     sljit_s32 dst, uint32_t k, size_t extwords)
    940       1.13     alnsn {
    941       1.13     alnsn 	int status;
    942       1.45     alnsn 	sljit_s32 src;
    943       1.13     alnsn 	sljit_sw srcw;
    944       1.13     alnsn 
    945       1.13     alnsn 	srcw = k * sizeof(uint32_t);
    946       1.13     alnsn 
    947       1.13     alnsn 	if (extwords == 0) {
    948       1.45     alnsn 		src = SLJIT_MEM1(SLJIT_SP);
    949       1.13     alnsn 		srcw += offsetof(struct bpfjit_stack, mem);
    950       1.13     alnsn 	} else {
    951       1.13     alnsn 		/* copy extmem pointer to the tmp1 register */
    952       1.13     alnsn 		status = sljit_emit_op1(compiler,
    953       1.16     alnsn 		    SLJIT_MOV_P,
    954       1.13     alnsn 		    BJ_TMP1REG, 0,
    955       1.45     alnsn 		    SLJIT_MEM1(SLJIT_SP),
    956       1.13     alnsn 		    offsetof(struct bpfjit_stack, extmem));
    957       1.13     alnsn 		if (status != SLJIT_SUCCESS)
    958       1.13     alnsn 			return status;
    959       1.13     alnsn 		src = SLJIT_MEM1(BJ_TMP1REG);
    960       1.13     alnsn 	}
    961       1.13     alnsn 
    962       1.45     alnsn 	return sljit_emit_op1(compiler, SLJIT_MOV_U32, dst, 0, src, srcw);
    963       1.13     alnsn }
    964       1.13     alnsn 
    965       1.13     alnsn static int
    966       1.19     alnsn emit_memstore(struct sljit_compiler *compiler,
    967       1.45     alnsn     sljit_s32 src, uint32_t k, size_t extwords)
    968       1.13     alnsn {
    969       1.13     alnsn 	int status;
    970       1.45     alnsn 	sljit_s32 dst;
    971       1.13     alnsn 	sljit_sw dstw;
    972       1.13     alnsn 
    973       1.13     alnsn 	dstw = k * sizeof(uint32_t);
    974       1.13     alnsn 
    975       1.13     alnsn 	if (extwords == 0) {
    976       1.45     alnsn 		dst = SLJIT_MEM1(SLJIT_SP);
    977       1.13     alnsn 		dstw += offsetof(struct bpfjit_stack, mem);
    978       1.13     alnsn 	} else {
    979       1.13     alnsn 		/* copy extmem pointer to the tmp1 register */
    980       1.13     alnsn 		status = sljit_emit_op1(compiler,
    981       1.16     alnsn 		    SLJIT_MOV_P,
    982       1.13     alnsn 		    BJ_TMP1REG, 0,
    983       1.45     alnsn 		    SLJIT_MEM1(SLJIT_SP),
    984       1.13     alnsn 		    offsetof(struct bpfjit_stack, extmem));
    985       1.13     alnsn 		if (status != SLJIT_SUCCESS)
    986       1.13     alnsn 			return status;
    987       1.13     alnsn 		dst = SLJIT_MEM1(BJ_TMP1REG);
    988       1.13     alnsn 	}
    989       1.13     alnsn 
    990       1.45     alnsn 	return sljit_emit_op1(compiler, SLJIT_MOV_U32, dst, dstw, src, 0);
    991       1.13     alnsn }
    992       1.13     alnsn 
    993        1.1     alnsn /*
    994       1.24     alnsn  * Emit code for BPF_LDX+BPF_B+BPF_MSH    X <- 4*(P[k:1]&0xf).
    995        1.1     alnsn  */
    996        1.1     alnsn static int
    997       1.32     alnsn emit_msh(struct sljit_compiler *compiler, bpfjit_hint_t hints,
    998        1.7     alnsn     const struct bpf_insn *pc, struct sljit_jump *to_mchain_jump,
    999        1.7     alnsn     struct sljit_jump ***ret0, size_t *ret0_size, size_t *ret0_maxsize)
   1000        1.1     alnsn {
   1001        1.1     alnsn 	int status;
   1002        1.1     alnsn #ifdef _KERNEL
   1003        1.1     alnsn 	struct sljit_label *label;
   1004        1.1     alnsn 	struct sljit_jump *jump, *over_mchain_jump;
   1005        1.1     alnsn 	const bool check_zero_buflen = (to_mchain_jump != NULL);
   1006        1.1     alnsn #endif
   1007        1.1     alnsn 	const uint32_t k = pc->k;
   1008        1.1     alnsn 
   1009        1.1     alnsn #ifdef _KERNEL
   1010        1.1     alnsn 	if (to_mchain_jump == NULL) {
   1011        1.1     alnsn 		to_mchain_jump = sljit_emit_cmp(compiler,
   1012       1.45     alnsn 		    SLJIT_EQUAL,
   1013        1.7     alnsn 		    BJ_BUFLEN, 0,
   1014        1.1     alnsn 		    SLJIT_IMM, 0);
   1015        1.1     alnsn 		if (to_mchain_jump == NULL)
   1016        1.7     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
   1017        1.1     alnsn 	}
   1018        1.1     alnsn #endif
   1019        1.1     alnsn 
   1020        1.1     alnsn 	/* tmp1 = buf[k] */
   1021        1.1     alnsn 	status = sljit_emit_op1(compiler,
   1022       1.45     alnsn 	    SLJIT_MOV_U8,
   1023        1.7     alnsn 	    BJ_TMP1REG, 0,
   1024        1.7     alnsn 	    SLJIT_MEM1(BJ_BUF), k);
   1025        1.1     alnsn 	if (status != SLJIT_SUCCESS)
   1026        1.1     alnsn 		return status;
   1027        1.1     alnsn 
   1028        1.1     alnsn #ifdef _KERNEL
   1029        1.1     alnsn 	over_mchain_jump = sljit_emit_jump(compiler, SLJIT_JUMP);
   1030        1.1     alnsn 	if (over_mchain_jump == NULL)
   1031        1.1     alnsn 		return SLJIT_ERR_ALLOC_FAILED;
   1032        1.1     alnsn 
   1033        1.1     alnsn 	/* entry point to mchain handler */
   1034        1.1     alnsn 	label = sljit_emit_label(compiler);
   1035        1.1     alnsn 	if (label == NULL)
   1036        1.1     alnsn 		return SLJIT_ERR_ALLOC_FAILED;
   1037        1.1     alnsn 	sljit_set_label(to_mchain_jump, label);
   1038        1.1     alnsn 
   1039        1.1     alnsn 	if (check_zero_buflen) {
   1040        1.1     alnsn 		/* if (buflen != 0) return 0; */
   1041        1.1     alnsn 		jump = sljit_emit_cmp(compiler,
   1042       1.45     alnsn 		    SLJIT_NOT_EQUAL,
   1043        1.7     alnsn 		    BJ_BUFLEN, 0,
   1044        1.1     alnsn 		    SLJIT_IMM, 0);
   1045        1.1     alnsn 		if (jump == NULL)
   1046        1.7     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
   1047        1.7     alnsn 		if (!append_jump(jump, ret0, ret0_size, ret0_maxsize))
   1048        1.7     alnsn 			return SLJIT_ERR_ALLOC_FAILED;
   1049        1.1     alnsn 	}
   1050        1.1     alnsn 
   1051       1.32     alnsn 	status = emit_xcall(compiler, hints, pc, BJ_TMP1REG,
   1052       1.23     alnsn 	    ret0, ret0_size, ret0_maxsize, &m_xbyte);
   1053        1.1     alnsn 	if (status != SLJIT_SUCCESS)
   1054        1.1     alnsn 		return status;
   1055        1.7     alnsn 
   1056       1.30     alnsn 	label = sljit_emit_label(compiler);
   1057       1.30     alnsn 	if (label == NULL)
   1058       1.30     alnsn 		return SLJIT_ERR_ALLOC_FAILED;
   1059       1.30     alnsn 	sljit_set_label(over_mchain_jump, label);
   1060       1.30     alnsn #endif
   1061       1.30     alnsn 
   1062        1.1     alnsn 	/* tmp1 &= 0xf */
   1063        1.1     alnsn 	status = sljit_emit_op2(compiler,
   1064        1.1     alnsn 	    SLJIT_AND,
   1065        1.7     alnsn 	    BJ_TMP1REG, 0,
   1066        1.7     alnsn 	    BJ_TMP1REG, 0,
   1067        1.1     alnsn 	    SLJIT_IMM, 0xf);
   1068        1.1     alnsn 	if (status != SLJIT_SUCCESS)
   1069        1.1     alnsn 		return status;
   1070        1.1     alnsn 
   1071       1.30     alnsn 	/* X = tmp1 << 2 */
   1072        1.1     alnsn 	status = sljit_emit_op2(compiler,
   1073        1.1     alnsn 	    SLJIT_SHL,
   1074        1.7     alnsn 	    BJ_XREG, 0,
   1075        1.7     alnsn 	    BJ_TMP1REG, 0,
   1076        1.1     alnsn 	    SLJIT_IMM, 2);
   1077        1.1     alnsn 	if (status != SLJIT_SUCCESS)
   1078        1.1     alnsn 		return status;
   1079        1.1     alnsn 
   1080       1.24     alnsn 	return SLJIT_SUCCESS;
   1081        1.1     alnsn }
   1082        1.1     alnsn 
   1083       1.35     alnsn /*
   1084       1.35     alnsn  * Emit code for A = A / k or A = A % k when k is a power of 2.
   1085       1.35     alnsn  * @pc BPF_DIV or BPF_MOD instruction.
   1086       1.35     alnsn  */
   1087        1.1     alnsn static int
   1088       1.35     alnsn emit_pow2_moddiv(struct sljit_compiler *compiler, const struct bpf_insn *pc)
   1089        1.1     alnsn {
   1090       1.35     alnsn 	uint32_t k = pc->k;
   1091        1.1     alnsn 	int status = SLJIT_SUCCESS;
   1092        1.1     alnsn 
   1093       1.35     alnsn 	BJ_ASSERT(k != 0 && (k & (k - 1)) == 0);
   1094        1.1     alnsn 
   1095       1.35     alnsn 	if (BPF_OP(pc->code) == BPF_MOD) {
   1096        1.1     alnsn 		status = sljit_emit_op2(compiler,
   1097       1.35     alnsn 		    SLJIT_AND,
   1098        1.7     alnsn 		    BJ_AREG, 0,
   1099        1.7     alnsn 		    BJ_AREG, 0,
   1100       1.35     alnsn 		    SLJIT_IMM, k - 1);
   1101       1.35     alnsn 	} else {
   1102       1.35     alnsn 		int shift = 0;
   1103       1.35     alnsn 
   1104       1.35     alnsn 		/*
   1105       1.35     alnsn 		 * Do shift = __builtin_ctz(k).
   1106       1.35     alnsn 		 * The loop is slower, but that's ok.
   1107       1.35     alnsn 		 */
   1108       1.35     alnsn 		while (k > 1) {
   1109       1.35     alnsn 			k >>= 1;
   1110       1.35     alnsn 			shift++;
   1111       1.35     alnsn 		}
   1112       1.35     alnsn 
   1113       1.35     alnsn 		if (shift != 0) {
   1114       1.35     alnsn 			status = sljit_emit_op2(compiler,
   1115       1.45     alnsn 			    SLJIT_LSHR|SLJIT_I32_OP,
   1116       1.35     alnsn 			    BJ_AREG, 0,
   1117       1.35     alnsn 			    BJ_AREG, 0,
   1118       1.35     alnsn 			    SLJIT_IMM, shift);
   1119       1.35     alnsn 		}
   1120        1.1     alnsn 	}
   1121        1.1     alnsn 
   1122        1.1     alnsn 	return status;
   1123        1.1     alnsn }
   1124        1.1     alnsn 
   1125        1.1     alnsn #if !defined(BPFJIT_USE_UDIV)
   1126        1.1     alnsn static sljit_uw
   1127        1.1     alnsn divide(sljit_uw x, sljit_uw y)
   1128        1.1     alnsn {
   1129        1.1     alnsn 
   1130        1.1     alnsn 	return (uint32_t)x / (uint32_t)y;
   1131        1.1     alnsn }
   1132       1.33  christos 
   1133       1.33  christos static sljit_uw
   1134       1.33  christos modulus(sljit_uw x, sljit_uw y)
   1135       1.33  christos {
   1136       1.33  christos 
   1137       1.33  christos 	return (uint32_t)x % (uint32_t)y;
   1138       1.33  christos }
   1139        1.1     alnsn #endif
   1140        1.1     alnsn 
   1141        1.1     alnsn /*
   1142       1.35     alnsn  * Emit code for A = A / div or A = A % div.
   1143       1.35     alnsn  * @pc BPF_DIV or BPF_MOD instruction.
   1144        1.1     alnsn  */
   1145        1.1     alnsn static int
   1146       1.35     alnsn emit_moddiv(struct sljit_compiler *compiler, const struct bpf_insn *pc)
   1147        1.1     alnsn {
   1148        1.1     alnsn 	int status;
   1149       1.38  christos 	const bool xdiv = BPF_OP(pc->code) == BPF_DIV;
   1150       1.35     alnsn 	const bool xreg = BPF_SRC(pc->code) == BPF_X;
   1151        1.1     alnsn 
   1152       1.32     alnsn #if BJ_XREG == SLJIT_RETURN_REG   || \
   1153       1.45     alnsn     BJ_XREG == SLJIT_R0 || \
   1154       1.45     alnsn     BJ_XREG == SLJIT_R1 || \
   1155       1.45     alnsn     BJ_AREG == SLJIT_R1
   1156       1.32     alnsn #error "Not supported assignment of registers."
   1157       1.32     alnsn #endif
   1158       1.32     alnsn 
   1159       1.45     alnsn #if BJ_AREG != SLJIT_R0
   1160        1.1     alnsn 	status = sljit_emit_op1(compiler,
   1161        1.1     alnsn 	    SLJIT_MOV,
   1162       1.45     alnsn 	    SLJIT_R0, 0,
   1163        1.7     alnsn 	    BJ_AREG, 0);
   1164        1.1     alnsn 	if (status != SLJIT_SUCCESS)
   1165        1.1     alnsn 		return status;
   1166        1.1     alnsn #endif
   1167        1.1     alnsn 
   1168        1.1     alnsn 	status = sljit_emit_op1(compiler,
   1169        1.1     alnsn 	    SLJIT_MOV,
   1170       1.45     alnsn 	    SLJIT_R1, 0,
   1171       1.35     alnsn 	    xreg ? BJ_XREG : SLJIT_IMM,
   1172       1.35     alnsn 	    xreg ? 0 : (uint32_t)pc->k);
   1173        1.1     alnsn 	if (status != SLJIT_SUCCESS)
   1174        1.1     alnsn 		return status;
   1175        1.1     alnsn 
   1176        1.1     alnsn #if defined(BPFJIT_USE_UDIV)
   1177       1.45     alnsn 	status = sljit_emit_op0(compiler, SLJIT_UDIV|SLJIT_I32_OP);
   1178        1.1     alnsn 
   1179       1.36     alnsn 	if (BPF_OP(pc->code) == BPF_DIV) {
   1180       1.45     alnsn #if BJ_AREG != SLJIT_R0
   1181       1.36     alnsn 		status = sljit_emit_op1(compiler,
   1182       1.36     alnsn 		    SLJIT_MOV,
   1183       1.36     alnsn 		    BJ_AREG, 0,
   1184       1.45     alnsn 		    SLJIT_R0, 0);
   1185       1.36     alnsn #endif
   1186       1.36     alnsn 	} else {
   1187       1.45     alnsn #if BJ_AREG != SLJIT_R1
   1188       1.45     alnsn 		/* Remainder is in SLJIT_R1. */
   1189       1.36     alnsn 		status = sljit_emit_op1(compiler,
   1190       1.36     alnsn 		    SLJIT_MOV,
   1191       1.36     alnsn 		    BJ_AREG, 0,
   1192       1.45     alnsn 		    SLJIT_R1, 0);
   1193       1.36     alnsn #endif
   1194       1.36     alnsn 	}
   1195       1.36     alnsn 
   1196        1.1     alnsn 	if (status != SLJIT_SUCCESS)
   1197        1.1     alnsn 		return status;
   1198        1.1     alnsn #else
   1199        1.1     alnsn 	status = sljit_emit_ijump(compiler,
   1200        1.1     alnsn 	    SLJIT_CALL2,
   1201       1.38  christos 	    SLJIT_IMM, xdiv ? SLJIT_FUNC_OFFSET(divide) :
   1202       1.33  christos 		SLJIT_FUNC_OFFSET(modulus));
   1203        1.1     alnsn 
   1204        1.7     alnsn #if BJ_AREG != SLJIT_RETURN_REG
   1205        1.1     alnsn 	status = sljit_emit_op1(compiler,
   1206        1.1     alnsn 	    SLJIT_MOV,
   1207        1.7     alnsn 	    BJ_AREG, 0,
   1208        1.1     alnsn 	    SLJIT_RETURN_REG, 0);
   1209        1.1     alnsn 	if (status != SLJIT_SUCCESS)
   1210        1.1     alnsn 		return status;
   1211        1.1     alnsn #endif
   1212        1.1     alnsn #endif
   1213        1.1     alnsn 
   1214        1.1     alnsn 	return status;
   1215        1.1     alnsn }
   1216        1.1     alnsn 
   1217        1.1     alnsn /*
   1218        1.1     alnsn  * Return true if pc is a "read from packet" instruction.
   1219        1.1     alnsn  * If length is not NULL and return value is true, *length will
   1220        1.1     alnsn  * be set to a safe length required to read a packet.
   1221        1.1     alnsn  */
   1222        1.1     alnsn static bool
   1223        1.8     alnsn read_pkt_insn(const struct bpf_insn *pc, bpfjit_abc_length_t *length)
   1224        1.1     alnsn {
   1225        1.1     alnsn 	bool rv;
   1226       1.37    justin 	bpfjit_abc_length_t width = 0; /* XXXuninit */
   1227        1.1     alnsn 
   1228        1.1     alnsn 	switch (BPF_CLASS(pc->code)) {
   1229        1.1     alnsn 	default:
   1230        1.1     alnsn 		rv = false;
   1231        1.1     alnsn 		break;
   1232        1.1     alnsn 
   1233        1.1     alnsn 	case BPF_LD:
   1234        1.1     alnsn 		rv = BPF_MODE(pc->code) == BPF_ABS ||
   1235        1.1     alnsn 		     BPF_MODE(pc->code) == BPF_IND;
   1236       1.39     alnsn 		if (rv) {
   1237        1.1     alnsn 			width = read_width(pc);
   1238       1.39     alnsn 			rv = (width != 0);
   1239       1.39     alnsn 		}
   1240        1.1     alnsn 		break;
   1241        1.1     alnsn 
   1242        1.1     alnsn 	case BPF_LDX:
   1243       1.39     alnsn 		rv = BPF_MODE(pc->code) == BPF_MSH &&
   1244       1.39     alnsn 		     BPF_SIZE(pc->code) == BPF_B;
   1245        1.1     alnsn 		width = 1;
   1246        1.1     alnsn 		break;
   1247        1.1     alnsn 	}
   1248        1.1     alnsn 
   1249        1.1     alnsn 	if (rv && length != NULL) {
   1250        1.9     alnsn 		/*
   1251        1.9     alnsn 		 * Values greater than UINT32_MAX will generate
   1252        1.9     alnsn 		 * unconditional "return 0".
   1253        1.9     alnsn 		 */
   1254        1.9     alnsn 		*length = (uint32_t)pc->k + width;
   1255        1.1     alnsn 	}
   1256        1.1     alnsn 
   1257        1.1     alnsn 	return rv;
   1258        1.1     alnsn }
   1259        1.1     alnsn 
   1260        1.1     alnsn static void
   1261        1.7     alnsn optimize_init(struct bpfjit_insn_data *insn_dat, size_t insn_count)
   1262        1.1     alnsn {
   1263        1.7     alnsn 	size_t i;
   1264        1.1     alnsn 
   1265        1.7     alnsn 	for (i = 0; i < insn_count; i++) {
   1266        1.7     alnsn 		SLIST_INIT(&insn_dat[i].bjumps);
   1267        1.7     alnsn 		insn_dat[i].invalid = BJ_INIT_NOBITS;
   1268        1.1     alnsn 	}
   1269        1.1     alnsn }
   1270        1.1     alnsn 
   1271        1.1     alnsn /*
   1272        1.1     alnsn  * The function divides instructions into blocks. Destination of a jump
   1273        1.1     alnsn  * instruction starts a new block. BPF_RET and BPF_JMP instructions
   1274        1.1     alnsn  * terminate a block. Blocks are linear, that is, there are no jumps out
   1275        1.1     alnsn  * from the middle of a block and there are no jumps in to the middle of
   1276        1.1     alnsn  * a block.
   1277        1.7     alnsn  *
   1278        1.7     alnsn  * The function also sets bits in *initmask for memwords that
   1279        1.7     alnsn  * need to be initialized to zero. Note that this set should be empty
   1280        1.7     alnsn  * for any valid kernel filter program.
   1281        1.1     alnsn  */
   1282        1.7     alnsn static bool
   1283       1.19     alnsn optimize_pass1(const bpf_ctx_t *bc, const struct bpf_insn *insns,
   1284       1.19     alnsn     struct bpfjit_insn_data *insn_dat, size_t insn_count,
   1285       1.20     alnsn     bpf_memword_init_t *initmask, bpfjit_hint_t *hints)
   1286        1.1     alnsn {
   1287        1.7     alnsn 	struct bpfjit_jump *jtf;
   1288        1.1     alnsn 	size_t i;
   1289        1.7     alnsn 	uint32_t jt, jf;
   1290       1.10     alnsn 	bpfjit_abc_length_t length;
   1291       1.13     alnsn 	bpf_memword_init_t invalid; /* borrowed from bpf_filter() */
   1292        1.1     alnsn 	bool unreachable;
   1293        1.1     alnsn 
   1294       1.19     alnsn 	const size_t memwords = GET_MEMWORDS(bc);
   1295       1.13     alnsn 
   1296       1.20     alnsn 	*hints = 0;
   1297        1.7     alnsn 	*initmask = BJ_INIT_NOBITS;
   1298        1.1     alnsn 
   1299        1.1     alnsn 	unreachable = false;
   1300        1.7     alnsn 	invalid = ~BJ_INIT_NOBITS;
   1301        1.1     alnsn 
   1302        1.1     alnsn 	for (i = 0; i < insn_count; i++) {
   1303        1.7     alnsn 		if (!SLIST_EMPTY(&insn_dat[i].bjumps))
   1304        1.1     alnsn 			unreachable = false;
   1305        1.7     alnsn 		insn_dat[i].unreachable = unreachable;
   1306        1.1     alnsn 
   1307        1.1     alnsn 		if (unreachable)
   1308        1.1     alnsn 			continue;
   1309        1.1     alnsn 
   1310        1.7     alnsn 		invalid |= insn_dat[i].invalid;
   1311        1.1     alnsn 
   1312       1.10     alnsn 		if (read_pkt_insn(&insns[i], &length) && length > UINT32_MAX)
   1313       1.10     alnsn 			unreachable = true;
   1314       1.10     alnsn 
   1315        1.1     alnsn 		switch (BPF_CLASS(insns[i].code)) {
   1316        1.1     alnsn 		case BPF_RET:
   1317        1.7     alnsn 			if (BPF_RVAL(insns[i].code) == BPF_A)
   1318        1.7     alnsn 				*initmask |= invalid & BJ_INIT_ABIT;
   1319        1.7     alnsn 
   1320        1.1     alnsn 			unreachable = true;
   1321        1.1     alnsn 			continue;
   1322        1.1     alnsn 
   1323        1.7     alnsn 		case BPF_LD:
   1324       1.27     alnsn 			if (BPF_MODE(insns[i].code) == BPF_ABS)
   1325       1.27     alnsn 				*hints |= BJ_HINT_ABS;
   1326        1.7     alnsn 
   1327       1.20     alnsn 			if (BPF_MODE(insns[i].code) == BPF_IND) {
   1328       1.27     alnsn 				*hints |= BJ_HINT_IND | BJ_HINT_XREG;
   1329        1.7     alnsn 				*initmask |= invalid & BJ_INIT_XBIT;
   1330       1.20     alnsn 			}
   1331        1.7     alnsn 
   1332        1.7     alnsn 			if (BPF_MODE(insns[i].code) == BPF_MEM &&
   1333       1.13     alnsn 			    (uint32_t)insns[i].k < memwords) {
   1334        1.7     alnsn 				*initmask |= invalid & BJ_INIT_MBIT(insns[i].k);
   1335        1.7     alnsn 			}
   1336        1.7     alnsn 
   1337        1.7     alnsn 			invalid &= ~BJ_INIT_ABIT;
   1338        1.7     alnsn 			continue;
   1339        1.7     alnsn 
   1340        1.7     alnsn 		case BPF_LDX:
   1341       1.20     alnsn 			*hints |= BJ_HINT_XREG | BJ_HINT_LDX;
   1342        1.7     alnsn 
   1343        1.7     alnsn 			if (BPF_MODE(insns[i].code) == BPF_MEM &&
   1344       1.13     alnsn 			    (uint32_t)insns[i].k < memwords) {
   1345        1.7     alnsn 				*initmask |= invalid & BJ_INIT_MBIT(insns[i].k);
   1346        1.7     alnsn 			}
   1347        1.7     alnsn 
   1348       1.29     alnsn 			if (BPF_MODE(insns[i].code) == BPF_MSH &&
   1349       1.29     alnsn 			    BPF_SIZE(insns[i].code) == BPF_B) {
   1350       1.29     alnsn 				*hints |= BJ_HINT_MSH;
   1351       1.29     alnsn 			}
   1352       1.29     alnsn 
   1353        1.7     alnsn 			invalid &= ~BJ_INIT_XBIT;
   1354        1.7     alnsn 			continue;
   1355        1.7     alnsn 
   1356        1.7     alnsn 		case BPF_ST:
   1357        1.7     alnsn 			*initmask |= invalid & BJ_INIT_ABIT;
   1358        1.7     alnsn 
   1359       1.13     alnsn 			if ((uint32_t)insns[i].k < memwords)
   1360        1.7     alnsn 				invalid &= ~BJ_INIT_MBIT(insns[i].k);
   1361        1.7     alnsn 
   1362        1.7     alnsn 			continue;
   1363        1.7     alnsn 
   1364        1.7     alnsn 		case BPF_STX:
   1365       1.20     alnsn 			*hints |= BJ_HINT_XREG;
   1366        1.7     alnsn 			*initmask |= invalid & BJ_INIT_XBIT;
   1367        1.7     alnsn 
   1368       1.13     alnsn 			if ((uint32_t)insns[i].k < memwords)
   1369        1.7     alnsn 				invalid &= ~BJ_INIT_MBIT(insns[i].k);
   1370        1.7     alnsn 
   1371        1.7     alnsn 			continue;
   1372        1.7     alnsn 
   1373        1.7     alnsn 		case BPF_ALU:
   1374        1.7     alnsn 			*initmask |= invalid & BJ_INIT_ABIT;
   1375        1.7     alnsn 
   1376        1.7     alnsn 			if (insns[i].code != (BPF_ALU|BPF_NEG) &&
   1377        1.7     alnsn 			    BPF_SRC(insns[i].code) == BPF_X) {
   1378       1.20     alnsn 				*hints |= BJ_HINT_XREG;
   1379        1.7     alnsn 				*initmask |= invalid & BJ_INIT_XBIT;
   1380        1.7     alnsn 			}
   1381        1.7     alnsn 
   1382        1.7     alnsn 			invalid &= ~BJ_INIT_ABIT;
   1383        1.7     alnsn 			continue;
   1384        1.7     alnsn 
   1385        1.7     alnsn 		case BPF_MISC:
   1386        1.7     alnsn 			switch (BPF_MISCOP(insns[i].code)) {
   1387        1.7     alnsn 			case BPF_TAX: // X <- A
   1388       1.20     alnsn 				*hints |= BJ_HINT_XREG;
   1389        1.7     alnsn 				*initmask |= invalid & BJ_INIT_ABIT;
   1390        1.7     alnsn 				invalid &= ~BJ_INIT_XBIT;
   1391        1.7     alnsn 				continue;
   1392        1.7     alnsn 
   1393        1.7     alnsn 			case BPF_TXA: // A <- X
   1394       1.20     alnsn 				*hints |= BJ_HINT_XREG;
   1395        1.7     alnsn 				*initmask |= invalid & BJ_INIT_XBIT;
   1396        1.7     alnsn 				invalid &= ~BJ_INIT_ABIT;
   1397        1.7     alnsn 				continue;
   1398       1.13     alnsn 
   1399       1.13     alnsn 			case BPF_COPX:
   1400       1.28     alnsn 				*hints |= BJ_HINT_XREG | BJ_HINT_COPX;
   1401       1.13     alnsn 				/* FALLTHROUGH */
   1402       1.13     alnsn 
   1403       1.13     alnsn 			case BPF_COP:
   1404       1.20     alnsn 				*hints |= BJ_HINT_COP;
   1405       1.13     alnsn 				*initmask |= invalid & BJ_INIT_ABIT;
   1406       1.13     alnsn 				invalid &= ~BJ_INIT_ABIT;
   1407       1.13     alnsn 				continue;
   1408        1.7     alnsn 			}
   1409        1.7     alnsn 
   1410        1.7     alnsn 			continue;
   1411        1.7     alnsn 
   1412        1.1     alnsn 		case BPF_JMP:
   1413        1.7     alnsn 			/* Initialize abc_length for ABC pass. */
   1414        1.8     alnsn 			insn_dat[i].u.jdata.abc_length = MAX_ABC_LENGTH;
   1415        1.7     alnsn 
   1416       1.41     alnsn 			*initmask |= invalid & BJ_INIT_ABIT;
   1417       1.41     alnsn 
   1418       1.41     alnsn 			if (BPF_SRC(insns[i].code) == BPF_X) {
   1419       1.39     alnsn 				*hints |= BJ_HINT_XREG;
   1420       1.41     alnsn 				*initmask |= invalid & BJ_INIT_XBIT;
   1421       1.41     alnsn 			}
   1422       1.39     alnsn 
   1423        1.7     alnsn 			if (BPF_OP(insns[i].code) == BPF_JA) {
   1424        1.1     alnsn 				jt = jf = insns[i].k;
   1425        1.1     alnsn 			} else {
   1426        1.1     alnsn 				jt = insns[i].jt;
   1427        1.1     alnsn 				jf = insns[i].jf;
   1428        1.1     alnsn 			}
   1429        1.1     alnsn 
   1430        1.1     alnsn 			if (jt >= insn_count - (i + 1) ||
   1431        1.1     alnsn 			    jf >= insn_count - (i + 1)) {
   1432        1.7     alnsn 				return false;
   1433        1.1     alnsn 			}
   1434        1.1     alnsn 
   1435        1.1     alnsn 			if (jt > 0 && jf > 0)
   1436        1.1     alnsn 				unreachable = true;
   1437        1.1     alnsn 
   1438        1.7     alnsn 			jt += i + 1;
   1439        1.7     alnsn 			jf += i + 1;
   1440        1.7     alnsn 
   1441        1.7     alnsn 			jtf = insn_dat[i].u.jdata.jtf;
   1442        1.1     alnsn 
   1443        1.7     alnsn 			jtf[0].jdata = &insn_dat[i].u.jdata;
   1444        1.7     alnsn 			SLIST_INSERT_HEAD(&insn_dat[jt].bjumps,
   1445        1.7     alnsn 			    &jtf[0], entries);
   1446        1.1     alnsn 
   1447        1.1     alnsn 			if (jf != jt) {
   1448        1.7     alnsn 				jtf[1].jdata = &insn_dat[i].u.jdata;
   1449        1.7     alnsn 				SLIST_INSERT_HEAD(&insn_dat[jf].bjumps,
   1450        1.7     alnsn 				    &jtf[1], entries);
   1451        1.1     alnsn 			}
   1452        1.1     alnsn 
   1453        1.7     alnsn 			insn_dat[jf].invalid |= invalid;
   1454        1.7     alnsn 			insn_dat[jt].invalid |= invalid;
   1455        1.7     alnsn 			invalid = 0;
   1456        1.7     alnsn 
   1457        1.1     alnsn 			continue;
   1458        1.1     alnsn 		}
   1459        1.1     alnsn 	}
   1460        1.1     alnsn 
   1461        1.7     alnsn 	return true;
   1462        1.1     alnsn }
   1463        1.1     alnsn 
   1464        1.1     alnsn /*
   1465        1.7     alnsn  * Array Bounds Check Elimination (ABC) pass.
   1466        1.1     alnsn  */
   1467        1.7     alnsn static void
   1468       1.19     alnsn optimize_pass2(const bpf_ctx_t *bc, const struct bpf_insn *insns,
   1469       1.19     alnsn     struct bpfjit_insn_data *insn_dat, size_t insn_count)
   1470        1.7     alnsn {
   1471        1.7     alnsn 	struct bpfjit_jump *jmp;
   1472        1.7     alnsn 	const struct bpf_insn *pc;
   1473        1.7     alnsn 	struct bpfjit_insn_data *pd;
   1474        1.7     alnsn 	size_t i;
   1475        1.8     alnsn 	bpfjit_abc_length_t length, abc_length = 0;
   1476        1.7     alnsn 
   1477       1.19     alnsn 	const size_t extwords = GET_EXTWORDS(bc);
   1478       1.19     alnsn 
   1479        1.7     alnsn 	for (i = insn_count; i != 0; i--) {
   1480        1.7     alnsn 		pc = &insns[i-1];
   1481        1.7     alnsn 		pd = &insn_dat[i-1];
   1482        1.7     alnsn 
   1483        1.7     alnsn 		if (pd->unreachable)
   1484        1.7     alnsn 			continue;
   1485        1.7     alnsn 
   1486        1.7     alnsn 		switch (BPF_CLASS(pc->code)) {
   1487        1.7     alnsn 		case BPF_RET:
   1488       1.11     alnsn 			/*
   1489       1.11     alnsn 			 * It's quite common for bpf programs to
   1490       1.11     alnsn 			 * check packet bytes in increasing order
   1491       1.11     alnsn 			 * and return zero if bytes don't match
   1492       1.11     alnsn 			 * specified critetion. Such programs disable
   1493       1.11     alnsn 			 * ABC optimization completely because for
   1494       1.11     alnsn 			 * every jump there is a branch with no read
   1495       1.11     alnsn 			 * instruction.
   1496       1.13     alnsn 			 * With no side effects, BPF_STMT(BPF_RET+BPF_K, 0)
   1497       1.13     alnsn 			 * is indistinguishable from out-of-bound load.
   1498       1.11     alnsn 			 * Therefore, abc_length can be set to
   1499       1.11     alnsn 			 * MAX_ABC_LENGTH and enable ABC for many
   1500       1.11     alnsn 			 * bpf programs.
   1501       1.13     alnsn 			 * If this optimization encounters any
   1502       1.11     alnsn 			 * instruction with a side effect, it will
   1503       1.11     alnsn 			 * reset abc_length.
   1504       1.11     alnsn 			 */
   1505       1.11     alnsn 			if (BPF_RVAL(pc->code) == BPF_K && pc->k == 0)
   1506       1.11     alnsn 				abc_length = MAX_ABC_LENGTH;
   1507       1.11     alnsn 			else
   1508       1.11     alnsn 				abc_length = 0;
   1509        1.7     alnsn 			break;
   1510        1.7     alnsn 
   1511       1.13     alnsn 		case BPF_MISC:
   1512       1.13     alnsn 			if (BPF_MISCOP(pc->code) == BPF_COP ||
   1513       1.13     alnsn 			    BPF_MISCOP(pc->code) == BPF_COPX) {
   1514       1.13     alnsn 				/* COP instructions can have side effects. */
   1515       1.13     alnsn 				abc_length = 0;
   1516       1.13     alnsn 			}
   1517       1.13     alnsn 			break;
   1518       1.13     alnsn 
   1519       1.13     alnsn 		case BPF_ST:
   1520       1.13     alnsn 		case BPF_STX:
   1521       1.13     alnsn 			if (extwords != 0) {
   1522       1.13     alnsn 				/* Write to memory is visible after a call. */
   1523       1.13     alnsn 				abc_length = 0;
   1524       1.13     alnsn 			}
   1525       1.13     alnsn 			break;
   1526       1.13     alnsn 
   1527        1.7     alnsn 		case BPF_JMP:
   1528        1.7     alnsn 			abc_length = pd->u.jdata.abc_length;
   1529        1.7     alnsn 			break;
   1530        1.7     alnsn 
   1531        1.7     alnsn 		default:
   1532        1.7     alnsn 			if (read_pkt_insn(pc, &length)) {
   1533        1.7     alnsn 				if (abc_length < length)
   1534        1.7     alnsn 					abc_length = length;
   1535        1.7     alnsn 				pd->u.rdata.abc_length = abc_length;
   1536        1.7     alnsn 			}
   1537        1.7     alnsn 			break;
   1538        1.7     alnsn 		}
   1539        1.7     alnsn 
   1540        1.7     alnsn 		SLIST_FOREACH(jmp, &pd->bjumps, entries) {
   1541        1.7     alnsn 			if (jmp->jdata->abc_length > abc_length)
   1542        1.7     alnsn 				jmp->jdata->abc_length = abc_length;
   1543        1.7     alnsn 		}
   1544        1.7     alnsn 	}
   1545        1.7     alnsn }
   1546        1.7     alnsn 
   1547        1.7     alnsn static void
   1548        1.7     alnsn optimize_pass3(const struct bpf_insn *insns,
   1549        1.7     alnsn     struct bpfjit_insn_data *insn_dat, size_t insn_count)
   1550        1.1     alnsn {
   1551        1.7     alnsn 	struct bpfjit_jump *jmp;
   1552        1.1     alnsn 	size_t i;
   1553        1.8     alnsn 	bpfjit_abc_length_t checked_length = 0;
   1554        1.1     alnsn 
   1555        1.1     alnsn 	for (i = 0; i < insn_count; i++) {
   1556        1.7     alnsn 		if (insn_dat[i].unreachable)
   1557        1.7     alnsn 			continue;
   1558        1.1     alnsn 
   1559        1.7     alnsn 		SLIST_FOREACH(jmp, &insn_dat[i].bjumps, entries) {
   1560        1.7     alnsn 			if (jmp->jdata->checked_length < checked_length)
   1561        1.7     alnsn 				checked_length = jmp->jdata->checked_length;
   1562        1.1     alnsn 		}
   1563        1.1     alnsn 
   1564        1.7     alnsn 		if (BPF_CLASS(insns[i].code) == BPF_JMP) {
   1565        1.7     alnsn 			insn_dat[i].u.jdata.checked_length = checked_length;
   1566        1.8     alnsn 		} else if (read_pkt_insn(&insns[i], NULL)) {
   1567        1.7     alnsn 			struct bpfjit_read_pkt_data *rdata =
   1568        1.7     alnsn 			    &insn_dat[i].u.rdata;
   1569        1.7     alnsn 			rdata->check_length = 0;
   1570        1.7     alnsn 			if (checked_length < rdata->abc_length) {
   1571        1.7     alnsn 				checked_length = rdata->abc_length;
   1572        1.7     alnsn 				rdata->check_length = checked_length;
   1573        1.7     alnsn 			}
   1574        1.1     alnsn 		}
   1575        1.7     alnsn 	}
   1576        1.7     alnsn }
   1577        1.1     alnsn 
   1578        1.7     alnsn static bool
   1579       1.19     alnsn optimize(const bpf_ctx_t *bc, const struct bpf_insn *insns,
   1580        1.7     alnsn     struct bpfjit_insn_data *insn_dat, size_t insn_count,
   1581       1.20     alnsn     bpf_memword_init_t *initmask, bpfjit_hint_t *hints)
   1582        1.7     alnsn {
   1583        1.1     alnsn 
   1584        1.7     alnsn 	optimize_init(insn_dat, insn_count);
   1585        1.7     alnsn 
   1586       1.20     alnsn 	if (!optimize_pass1(bc, insns, insn_dat, insn_count, initmask, hints))
   1587        1.7     alnsn 		return false;
   1588        1.1     alnsn 
   1589       1.19     alnsn 	optimize_pass2(bc, insns, insn_dat, insn_count);
   1590        1.7     alnsn 	optimize_pass3(insns, insn_dat, insn_count);
   1591        1.7     alnsn 
   1592        1.7     alnsn 	return true;
   1593        1.1     alnsn }
   1594        1.1     alnsn 
   1595        1.1     alnsn /*
   1596        1.1     alnsn  * Convert BPF_ALU operations except BPF_NEG and BPF_DIV to sljit operation.
   1597        1.1     alnsn  */
   1598       1.46     alnsn static bool
   1599       1.46     alnsn alu_to_op(const struct bpf_insn *pc, int *res)
   1600        1.1     alnsn {
   1601       1.42     alnsn 	const uint32_t k = pc->k;
   1602        1.1     alnsn 
   1603        1.1     alnsn 	/*
   1604        1.1     alnsn 	 * Note: all supported 64bit arches have 32bit multiply
   1605       1.45     alnsn 	 * instruction so SLJIT_I32_OP doesn't have any overhead.
   1606        1.1     alnsn 	 */
   1607        1.1     alnsn 	switch (BPF_OP(pc->code)) {
   1608       1.46     alnsn 	case BPF_ADD:
   1609       1.46     alnsn 		*res = SLJIT_ADD;
   1610       1.46     alnsn 		return true;
   1611       1.46     alnsn 	case BPF_SUB:
   1612       1.46     alnsn 		*res = SLJIT_SUB;
   1613       1.46     alnsn 		return true;
   1614       1.46     alnsn 	case BPF_MUL:
   1615       1.46     alnsn 		*res = SLJIT_MUL|SLJIT_I32_OP;
   1616       1.46     alnsn 		return true;
   1617       1.46     alnsn 	case BPF_OR:
   1618       1.46     alnsn 		*res = SLJIT_OR;
   1619       1.46     alnsn 		return true;
   1620       1.46     alnsn 	case BPF_XOR:
   1621       1.46     alnsn 		*res = SLJIT_XOR;
   1622       1.46     alnsn 		return true;
   1623       1.46     alnsn 	case BPF_AND:
   1624       1.46     alnsn 		*res = SLJIT_AND;
   1625       1.46     alnsn 		return true;
   1626       1.46     alnsn 	case BPF_LSH:
   1627       1.46     alnsn 		*res = SLJIT_SHL;
   1628       1.46     alnsn 		return k < 32;
   1629       1.46     alnsn 	case BPF_RSH:
   1630       1.46     alnsn 		*res = SLJIT_LSHR|SLJIT_I32_OP;
   1631       1.46     alnsn 		return k < 32;
   1632        1.1     alnsn 	default:
   1633       1.46     alnsn 		return false;
   1634        1.1     alnsn 	}
   1635        1.1     alnsn }
   1636        1.1     alnsn 
   1637        1.1     alnsn /*
   1638        1.1     alnsn  * Convert BPF_JMP operations except BPF_JA to sljit condition.
   1639        1.1     alnsn  */
   1640       1.46     alnsn static bool
   1641       1.46     alnsn jmp_to_cond(const struct bpf_insn *pc, bool negate, int *res)
   1642        1.1     alnsn {
   1643       1.46     alnsn 
   1644        1.1     alnsn 	/*
   1645        1.1     alnsn 	 * Note: all supported 64bit arches have 32bit comparison
   1646       1.45     alnsn 	 * instructions so SLJIT_I32_OP doesn't have any overhead.
   1647        1.1     alnsn 	 */
   1648       1.46     alnsn 	*res = SLJIT_I32_OP;
   1649        1.1     alnsn 
   1650        1.1     alnsn 	switch (BPF_OP(pc->code)) {
   1651        1.1     alnsn 	case BPF_JGT:
   1652       1.46     alnsn 		*res |= negate ? SLJIT_LESS_EQUAL : SLJIT_GREATER;
   1653       1.46     alnsn 		return true;
   1654        1.1     alnsn 	case BPF_JGE:
   1655       1.46     alnsn 		*res |= negate ? SLJIT_LESS : SLJIT_GREATER_EQUAL;
   1656       1.46     alnsn 		return true;
   1657        1.1     alnsn 	case BPF_JEQ:
   1658       1.46     alnsn 		*res |= negate ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
   1659       1.46     alnsn 		return true;
   1660        1.1     alnsn 	case BPF_JSET:
   1661       1.46     alnsn 		*res |= negate ? SLJIT_EQUAL : SLJIT_NOT_EQUAL;
   1662       1.46     alnsn 		return true;
   1663        1.1     alnsn 	default:
   1664       1.46     alnsn 		return false;
   1665        1.1     alnsn 	}
   1666        1.1     alnsn }
   1667        1.1     alnsn 
   1668        1.1     alnsn /*
   1669        1.1     alnsn  * Convert BPF_K and BPF_X to sljit register.
   1670        1.1     alnsn  */
   1671        1.1     alnsn static int
   1672        1.7     alnsn kx_to_reg(const struct bpf_insn *pc)
   1673        1.1     alnsn {
   1674        1.1     alnsn 
   1675        1.1     alnsn 	switch (BPF_SRC(pc->code)) {
   1676        1.1     alnsn 	case BPF_K: return SLJIT_IMM;
   1677        1.7     alnsn 	case BPF_X: return BJ_XREG;
   1678        1.1     alnsn 	default:
   1679        1.7     alnsn 		BJ_ASSERT(false);
   1680        1.1     alnsn 		return 0;
   1681        1.1     alnsn 	}
   1682        1.1     alnsn }
   1683        1.1     alnsn 
   1684       1.12     alnsn static sljit_sw
   1685        1.7     alnsn kx_to_reg_arg(const struct bpf_insn *pc)
   1686        1.1     alnsn {
   1687        1.1     alnsn 
   1688        1.1     alnsn 	switch (BPF_SRC(pc->code)) {
   1689        1.1     alnsn 	case BPF_K: return (uint32_t)pc->k; /* SLJIT_IMM, pc->k, */
   1690        1.7     alnsn 	case BPF_X: return 0;               /* BJ_XREG, 0,      */
   1691        1.1     alnsn 	default:
   1692        1.7     alnsn 		BJ_ASSERT(false);
   1693        1.1     alnsn 		return 0;
   1694        1.1     alnsn 	}
   1695        1.1     alnsn }
   1696        1.1     alnsn 
   1697       1.19     alnsn static bool
   1698       1.32     alnsn generate_insn_code(struct sljit_compiler *compiler, bpfjit_hint_t hints,
   1699       1.32     alnsn     const bpf_ctx_t *bc, const struct bpf_insn *insns,
   1700       1.32     alnsn     struct bpfjit_insn_data *insn_dat, size_t insn_count)
   1701        1.1     alnsn {
   1702        1.1     alnsn 	/* a list of jumps to out-of-bound return from a generated function */
   1703        1.1     alnsn 	struct sljit_jump **ret0;
   1704        1.7     alnsn 	size_t ret0_size, ret0_maxsize;
   1705        1.1     alnsn 
   1706       1.19     alnsn 	struct sljit_jump *jump;
   1707       1.19     alnsn 	struct sljit_label *label;
   1708        1.7     alnsn 	const struct bpf_insn *pc;
   1709        1.1     alnsn 	struct bpfjit_jump *bjump, *jtf;
   1710        1.1     alnsn 	struct sljit_jump *to_mchain_jump;
   1711        1.1     alnsn 
   1712       1.19     alnsn 	size_t i;
   1713       1.46     alnsn 	unsigned int rval, mode, src, op;
   1714       1.19     alnsn 	int branching, negate;
   1715       1.46     alnsn 	int status, cond, op2;
   1716        1.1     alnsn 	uint32_t jt, jf;
   1717        1.1     alnsn 
   1718       1.19     alnsn 	bool unconditional_ret;
   1719       1.19     alnsn 	bool rv;
   1720       1.19     alnsn 
   1721       1.19     alnsn 	const size_t extwords = GET_EXTWORDS(bc);
   1722       1.19     alnsn 	const size_t memwords = GET_MEMWORDS(bc);
   1723       1.13     alnsn 
   1724       1.13     alnsn 	ret0 = NULL;
   1725       1.19     alnsn 	rv = false;
   1726        1.7     alnsn 
   1727        1.1     alnsn 	ret0_size = 0;
   1728        1.7     alnsn 	ret0_maxsize = 64;
   1729        1.7     alnsn 	ret0 = BJ_ALLOC(ret0_maxsize * sizeof(ret0[0]));
   1730        1.7     alnsn 	if (ret0 == NULL)
   1731        1.1     alnsn 		goto fail;
   1732        1.1     alnsn 
   1733       1.24     alnsn 	/* reset sjump members of jdata */
   1734       1.24     alnsn 	for (i = 0; i < insn_count; i++) {
   1735       1.24     alnsn 		if (insn_dat[i].unreachable ||
   1736       1.24     alnsn 		    BPF_CLASS(insns[i].code) != BPF_JMP) {
   1737       1.24     alnsn 			continue;
   1738       1.24     alnsn 		}
   1739       1.24     alnsn 
   1740       1.24     alnsn 		jtf = insn_dat[i].u.jdata.jtf;
   1741       1.24     alnsn 		jtf[0].sjump = jtf[1].sjump = NULL;
   1742       1.24     alnsn 	}
   1743       1.24     alnsn 
   1744       1.24     alnsn 	/* main loop */
   1745        1.1     alnsn 	for (i = 0; i < insn_count; i++) {
   1746        1.7     alnsn 		if (insn_dat[i].unreachable)
   1747        1.1     alnsn 			continue;
   1748        1.1     alnsn 
   1749        1.1     alnsn 		/*
   1750        1.1     alnsn 		 * Resolve jumps to the current insn.
   1751        1.1     alnsn 		 */
   1752        1.1     alnsn 		label = NULL;
   1753        1.7     alnsn 		SLIST_FOREACH(bjump, &insn_dat[i].bjumps, entries) {
   1754        1.7     alnsn 			if (bjump->sjump != NULL) {
   1755        1.1     alnsn 				if (label == NULL)
   1756        1.1     alnsn 					label = sljit_emit_label(compiler);
   1757        1.1     alnsn 				if (label == NULL)
   1758        1.1     alnsn 					goto fail;
   1759        1.7     alnsn 				sljit_set_label(bjump->sjump, label);
   1760        1.1     alnsn 			}
   1761        1.1     alnsn 		}
   1762        1.1     alnsn 
   1763        1.9     alnsn 		to_mchain_jump = NULL;
   1764        1.9     alnsn 		unconditional_ret = false;
   1765        1.9     alnsn 
   1766        1.9     alnsn 		if (read_pkt_insn(&insns[i], NULL)) {
   1767        1.9     alnsn 			if (insn_dat[i].u.rdata.check_length > UINT32_MAX) {
   1768        1.9     alnsn 				/* Jump to "return 0" unconditionally. */
   1769        1.9     alnsn 				unconditional_ret = true;
   1770        1.9     alnsn 				jump = sljit_emit_jump(compiler, SLJIT_JUMP);
   1771        1.9     alnsn 				if (jump == NULL)
   1772        1.9     alnsn 					goto fail;
   1773        1.9     alnsn 				if (!append_jump(jump, &ret0,
   1774        1.9     alnsn 				    &ret0_size, &ret0_maxsize))
   1775        1.9     alnsn 					goto fail;
   1776        1.9     alnsn 			} else if (insn_dat[i].u.rdata.check_length > 0) {
   1777        1.9     alnsn 				/* if (buflen < check_length) return 0; */
   1778        1.9     alnsn 				jump = sljit_emit_cmp(compiler,
   1779       1.45     alnsn 				    SLJIT_LESS,
   1780        1.9     alnsn 				    BJ_BUFLEN, 0,
   1781        1.9     alnsn 				    SLJIT_IMM,
   1782        1.9     alnsn 				    insn_dat[i].u.rdata.check_length);
   1783        1.9     alnsn 				if (jump == NULL)
   1784        1.9     alnsn 					goto fail;
   1785        1.1     alnsn #ifdef _KERNEL
   1786        1.9     alnsn 				to_mchain_jump = jump;
   1787        1.1     alnsn #else
   1788        1.9     alnsn 				if (!append_jump(jump, &ret0,
   1789        1.9     alnsn 				    &ret0_size, &ret0_maxsize))
   1790        1.9     alnsn 					goto fail;
   1791        1.1     alnsn #endif
   1792        1.9     alnsn 			}
   1793        1.1     alnsn 		}
   1794        1.1     alnsn 
   1795        1.1     alnsn 		pc = &insns[i];
   1796        1.1     alnsn 		switch (BPF_CLASS(pc->code)) {
   1797        1.1     alnsn 
   1798        1.1     alnsn 		default:
   1799        1.1     alnsn 			goto fail;
   1800        1.1     alnsn 
   1801        1.1     alnsn 		case BPF_LD:
   1802        1.1     alnsn 			/* BPF_LD+BPF_IMM          A <- k */
   1803        1.1     alnsn 			if (pc->code == (BPF_LD|BPF_IMM)) {
   1804        1.1     alnsn 				status = sljit_emit_op1(compiler,
   1805        1.1     alnsn 				    SLJIT_MOV,
   1806        1.7     alnsn 				    BJ_AREG, 0,
   1807        1.1     alnsn 				    SLJIT_IMM, (uint32_t)pc->k);
   1808        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   1809        1.1     alnsn 					goto fail;
   1810        1.1     alnsn 
   1811        1.1     alnsn 				continue;
   1812        1.1     alnsn 			}
   1813        1.1     alnsn 
   1814        1.1     alnsn 			/* BPF_LD+BPF_MEM          A <- M[k] */
   1815        1.1     alnsn 			if (pc->code == (BPF_LD|BPF_MEM)) {
   1816       1.13     alnsn 				if ((uint32_t)pc->k >= memwords)
   1817        1.1     alnsn 					goto fail;
   1818       1.13     alnsn 				status = emit_memload(compiler,
   1819       1.13     alnsn 				    BJ_AREG, pc->k, extwords);
   1820        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   1821        1.1     alnsn 					goto fail;
   1822        1.1     alnsn 
   1823        1.1     alnsn 				continue;
   1824        1.1     alnsn 			}
   1825        1.1     alnsn 
   1826        1.1     alnsn 			/* BPF_LD+BPF_W+BPF_LEN    A <- len */
   1827        1.1     alnsn 			if (pc->code == (BPF_LD|BPF_W|BPF_LEN)) {
   1828        1.1     alnsn 				status = sljit_emit_op1(compiler,
   1829       1.21     alnsn 				    SLJIT_MOV, /* size_t source */
   1830        1.7     alnsn 				    BJ_AREG, 0,
   1831       1.13     alnsn 				    SLJIT_MEM1(BJ_ARGS),
   1832       1.13     alnsn 				    offsetof(struct bpf_args, wirelen));
   1833        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   1834        1.1     alnsn 					goto fail;
   1835        1.1     alnsn 
   1836        1.1     alnsn 				continue;
   1837        1.1     alnsn 			}
   1838        1.1     alnsn 
   1839        1.1     alnsn 			mode = BPF_MODE(pc->code);
   1840        1.1     alnsn 			if (mode != BPF_ABS && mode != BPF_IND)
   1841        1.1     alnsn 				goto fail;
   1842        1.1     alnsn 
   1843        1.9     alnsn 			if (unconditional_ret)
   1844        1.9     alnsn 				continue;
   1845        1.9     alnsn 
   1846       1.32     alnsn 			status = emit_pkt_read(compiler, hints, pc,
   1847        1.7     alnsn 			    to_mchain_jump, &ret0, &ret0_size, &ret0_maxsize);
   1848        1.1     alnsn 			if (status != SLJIT_SUCCESS)
   1849        1.1     alnsn 				goto fail;
   1850        1.1     alnsn 
   1851        1.1     alnsn 			continue;
   1852        1.1     alnsn 
   1853        1.1     alnsn 		case BPF_LDX:
   1854        1.1     alnsn 			mode = BPF_MODE(pc->code);
   1855        1.1     alnsn 
   1856        1.1     alnsn 			/* BPF_LDX+BPF_W+BPF_IMM    X <- k */
   1857        1.1     alnsn 			if (mode == BPF_IMM) {
   1858        1.1     alnsn 				if (BPF_SIZE(pc->code) != BPF_W)
   1859        1.1     alnsn 					goto fail;
   1860        1.1     alnsn 				status = sljit_emit_op1(compiler,
   1861        1.1     alnsn 				    SLJIT_MOV,
   1862        1.7     alnsn 				    BJ_XREG, 0,
   1863        1.1     alnsn 				    SLJIT_IMM, (uint32_t)pc->k);
   1864        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   1865        1.1     alnsn 					goto fail;
   1866        1.1     alnsn 
   1867        1.1     alnsn 				continue;
   1868        1.1     alnsn 			}
   1869        1.1     alnsn 
   1870        1.1     alnsn 			/* BPF_LDX+BPF_W+BPF_LEN    X <- len */
   1871        1.1     alnsn 			if (mode == BPF_LEN) {
   1872        1.1     alnsn 				if (BPF_SIZE(pc->code) != BPF_W)
   1873        1.1     alnsn 					goto fail;
   1874        1.1     alnsn 				status = sljit_emit_op1(compiler,
   1875       1.21     alnsn 				    SLJIT_MOV, /* size_t source */
   1876        1.7     alnsn 				    BJ_XREG, 0,
   1877       1.13     alnsn 				    SLJIT_MEM1(BJ_ARGS),
   1878       1.13     alnsn 				    offsetof(struct bpf_args, wirelen));
   1879        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   1880        1.1     alnsn 					goto fail;
   1881        1.1     alnsn 
   1882        1.1     alnsn 				continue;
   1883        1.1     alnsn 			}
   1884        1.1     alnsn 
   1885        1.1     alnsn 			/* BPF_LDX+BPF_W+BPF_MEM    X <- M[k] */
   1886        1.1     alnsn 			if (mode == BPF_MEM) {
   1887        1.1     alnsn 				if (BPF_SIZE(pc->code) != BPF_W)
   1888        1.1     alnsn 					goto fail;
   1889       1.13     alnsn 				if ((uint32_t)pc->k >= memwords)
   1890        1.1     alnsn 					goto fail;
   1891       1.13     alnsn 				status = emit_memload(compiler,
   1892       1.13     alnsn 				    BJ_XREG, pc->k, extwords);
   1893        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   1894        1.1     alnsn 					goto fail;
   1895        1.1     alnsn 
   1896        1.1     alnsn 				continue;
   1897        1.1     alnsn 			}
   1898        1.1     alnsn 
   1899        1.1     alnsn 			/* BPF_LDX+BPF_B+BPF_MSH    X <- 4*(P[k:1]&0xf) */
   1900        1.1     alnsn 			if (mode != BPF_MSH || BPF_SIZE(pc->code) != BPF_B)
   1901        1.1     alnsn 				goto fail;
   1902        1.1     alnsn 
   1903        1.9     alnsn 			if (unconditional_ret)
   1904        1.9     alnsn 				continue;
   1905        1.9     alnsn 
   1906       1.32     alnsn 			status = emit_msh(compiler, hints, pc,
   1907        1.7     alnsn 			    to_mchain_jump, &ret0, &ret0_size, &ret0_maxsize);
   1908        1.1     alnsn 			if (status != SLJIT_SUCCESS)
   1909        1.1     alnsn 				goto fail;
   1910        1.1     alnsn 
   1911        1.1     alnsn 			continue;
   1912        1.1     alnsn 
   1913        1.1     alnsn 		case BPF_ST:
   1914        1.8     alnsn 			if (pc->code != BPF_ST ||
   1915       1.13     alnsn 			    (uint32_t)pc->k >= memwords) {
   1916        1.1     alnsn 				goto fail;
   1917        1.8     alnsn 			}
   1918        1.1     alnsn 
   1919       1.13     alnsn 			status = emit_memstore(compiler,
   1920       1.13     alnsn 			    BJ_AREG, pc->k, extwords);
   1921        1.1     alnsn 			if (status != SLJIT_SUCCESS)
   1922        1.1     alnsn 				goto fail;
   1923        1.1     alnsn 
   1924        1.1     alnsn 			continue;
   1925        1.1     alnsn 
   1926        1.1     alnsn 		case BPF_STX:
   1927        1.8     alnsn 			if (pc->code != BPF_STX ||
   1928       1.13     alnsn 			    (uint32_t)pc->k >= memwords) {
   1929        1.1     alnsn 				goto fail;
   1930        1.8     alnsn 			}
   1931        1.1     alnsn 
   1932       1.13     alnsn 			status = emit_memstore(compiler,
   1933       1.13     alnsn 			    BJ_XREG, pc->k, extwords);
   1934        1.1     alnsn 			if (status != SLJIT_SUCCESS)
   1935        1.1     alnsn 				goto fail;
   1936        1.1     alnsn 
   1937        1.1     alnsn 			continue;
   1938        1.1     alnsn 
   1939        1.1     alnsn 		case BPF_ALU:
   1940        1.1     alnsn 			if (pc->code == (BPF_ALU|BPF_NEG)) {
   1941        1.1     alnsn 				status = sljit_emit_op1(compiler,
   1942        1.1     alnsn 				    SLJIT_NEG,
   1943        1.7     alnsn 				    BJ_AREG, 0,
   1944        1.7     alnsn 				    BJ_AREG, 0);
   1945        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   1946        1.1     alnsn 					goto fail;
   1947        1.1     alnsn 
   1948        1.1     alnsn 				continue;
   1949        1.1     alnsn 			}
   1950        1.1     alnsn 
   1951       1.33  christos 			op = BPF_OP(pc->code);
   1952       1.33  christos 			if (op != BPF_DIV && op != BPF_MOD) {
   1953       1.46     alnsn 				if (!alu_to_op(pc, &op2))
   1954       1.46     alnsn 					goto fail;
   1955       1.39     alnsn 
   1956        1.1     alnsn 				status = sljit_emit_op2(compiler,
   1957       1.39     alnsn 				    op2, BJ_AREG, 0, BJ_AREG, 0,
   1958        1.1     alnsn 				    kx_to_reg(pc), kx_to_reg_arg(pc));
   1959        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   1960        1.1     alnsn 					goto fail;
   1961        1.1     alnsn 
   1962        1.1     alnsn 				continue;
   1963        1.1     alnsn 			}
   1964        1.1     alnsn 
   1965       1.33  christos 			/* BPF_DIV/BPF_MOD */
   1966        1.1     alnsn 
   1967        1.1     alnsn 			src = BPF_SRC(pc->code);
   1968        1.1     alnsn 			if (src != BPF_X && src != BPF_K)
   1969        1.1     alnsn 				goto fail;
   1970        1.1     alnsn 
   1971        1.1     alnsn 			/* division by zero? */
   1972        1.1     alnsn 			if (src == BPF_X) {
   1973        1.1     alnsn 				jump = sljit_emit_cmp(compiler,
   1974       1.45     alnsn 				    SLJIT_EQUAL|SLJIT_I32_OP,
   1975        1.8     alnsn 				    BJ_XREG, 0,
   1976        1.1     alnsn 				    SLJIT_IMM, 0);
   1977        1.1     alnsn 				if (jump == NULL)
   1978        1.1     alnsn 					goto fail;
   1979        1.7     alnsn 				if (!append_jump(jump, &ret0,
   1980        1.7     alnsn 				    &ret0_size, &ret0_maxsize))
   1981        1.7     alnsn 					goto fail;
   1982        1.1     alnsn 			} else if (pc->k == 0) {
   1983        1.1     alnsn 				jump = sljit_emit_jump(compiler, SLJIT_JUMP);
   1984        1.1     alnsn 				if (jump == NULL)
   1985        1.1     alnsn 					goto fail;
   1986        1.7     alnsn 				if (!append_jump(jump, &ret0,
   1987        1.7     alnsn 				    &ret0_size, &ret0_maxsize))
   1988        1.7     alnsn 					goto fail;
   1989        1.1     alnsn 			}
   1990        1.1     alnsn 
   1991        1.1     alnsn 			if (src == BPF_X) {
   1992       1.35     alnsn 				status = emit_moddiv(compiler, pc);
   1993        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   1994        1.1     alnsn 					goto fail;
   1995        1.1     alnsn 			} else if (pc->k != 0) {
   1996       1.35     alnsn 				if (pc->k & (pc->k - 1)) {
   1997       1.35     alnsn 					status = emit_moddiv(compiler, pc);
   1998        1.1     alnsn 				} else {
   1999       1.35     alnsn 					status = emit_pow2_moddiv(compiler, pc);
   2000        1.1     alnsn 				}
   2001        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   2002        1.1     alnsn 					goto fail;
   2003        1.1     alnsn 			}
   2004        1.1     alnsn 
   2005        1.1     alnsn 			continue;
   2006        1.1     alnsn 
   2007        1.1     alnsn 		case BPF_JMP:
   2008       1.33  christos 			op = BPF_OP(pc->code);
   2009       1.33  christos 			if (op == BPF_JA) {
   2010        1.1     alnsn 				jt = jf = pc->k;
   2011        1.1     alnsn 			} else {
   2012        1.1     alnsn 				jt = pc->jt;
   2013        1.1     alnsn 				jf = pc->jf;
   2014        1.1     alnsn 			}
   2015        1.1     alnsn 
   2016        1.1     alnsn 			negate = (jt == 0) ? 1 : 0;
   2017        1.1     alnsn 			branching = (jt == jf) ? 0 : 1;
   2018        1.7     alnsn 			jtf = insn_dat[i].u.jdata.jtf;
   2019        1.1     alnsn 
   2020        1.1     alnsn 			if (branching) {
   2021       1.33  christos 				if (op != BPF_JSET) {
   2022       1.46     alnsn 					if (!jmp_to_cond(pc, negate, &cond))
   2023       1.46     alnsn 						goto fail;
   2024        1.1     alnsn 					jump = sljit_emit_cmp(compiler,
   2025       1.46     alnsn 					    cond, BJ_AREG, 0,
   2026        1.1     alnsn 					    kx_to_reg(pc), kx_to_reg_arg(pc));
   2027        1.1     alnsn 				} else {
   2028        1.1     alnsn 					status = sljit_emit_op2(compiler,
   2029        1.1     alnsn 					    SLJIT_AND,
   2030        1.7     alnsn 					    BJ_TMP1REG, 0,
   2031        1.7     alnsn 					    BJ_AREG, 0,
   2032        1.1     alnsn 					    kx_to_reg(pc), kx_to_reg_arg(pc));
   2033        1.1     alnsn 					if (status != SLJIT_SUCCESS)
   2034        1.1     alnsn 						goto fail;
   2035        1.1     alnsn 
   2036       1.46     alnsn 					if (!jmp_to_cond(pc, negate, &cond))
   2037       1.46     alnsn 						goto fail;
   2038        1.1     alnsn 					jump = sljit_emit_cmp(compiler,
   2039       1.46     alnsn 					    cond, BJ_TMP1REG, 0, SLJIT_IMM, 0);
   2040        1.1     alnsn 				}
   2041        1.1     alnsn 
   2042        1.1     alnsn 				if (jump == NULL)
   2043        1.1     alnsn 					goto fail;
   2044        1.1     alnsn 
   2045        1.7     alnsn 				BJ_ASSERT(jtf[negate].sjump == NULL);
   2046        1.7     alnsn 				jtf[negate].sjump = jump;
   2047        1.1     alnsn 			}
   2048        1.1     alnsn 
   2049        1.1     alnsn 			if (!branching || (jt != 0 && jf != 0)) {
   2050        1.1     alnsn 				jump = sljit_emit_jump(compiler, SLJIT_JUMP);
   2051        1.1     alnsn 				if (jump == NULL)
   2052        1.1     alnsn 					goto fail;
   2053        1.1     alnsn 
   2054        1.7     alnsn 				BJ_ASSERT(jtf[branching].sjump == NULL);
   2055        1.7     alnsn 				jtf[branching].sjump = jump;
   2056        1.1     alnsn 			}
   2057        1.1     alnsn 
   2058        1.1     alnsn 			continue;
   2059        1.1     alnsn 
   2060        1.1     alnsn 		case BPF_RET:
   2061        1.1     alnsn 			rval = BPF_RVAL(pc->code);
   2062        1.1     alnsn 			if (rval == BPF_X)
   2063        1.1     alnsn 				goto fail;
   2064        1.1     alnsn 
   2065        1.1     alnsn 			/* BPF_RET+BPF_K    accept k bytes */
   2066        1.1     alnsn 			if (rval == BPF_K) {
   2067        1.7     alnsn 				status = sljit_emit_return(compiler,
   2068       1.45     alnsn 				    SLJIT_MOV_U32,
   2069        1.1     alnsn 				    SLJIT_IMM, (uint32_t)pc->k);
   2070        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   2071        1.1     alnsn 					goto fail;
   2072        1.1     alnsn 			}
   2073        1.1     alnsn 
   2074        1.1     alnsn 			/* BPF_RET+BPF_A    accept A bytes */
   2075        1.1     alnsn 			if (rval == BPF_A) {
   2076        1.7     alnsn 				status = sljit_emit_return(compiler,
   2077       1.45     alnsn 				    SLJIT_MOV_U32,
   2078        1.7     alnsn 				    BJ_AREG, 0);
   2079        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   2080        1.1     alnsn 					goto fail;
   2081        1.1     alnsn 			}
   2082        1.1     alnsn 
   2083        1.1     alnsn 			continue;
   2084        1.1     alnsn 
   2085        1.1     alnsn 		case BPF_MISC:
   2086        1.7     alnsn 			switch (BPF_MISCOP(pc->code)) {
   2087        1.7     alnsn 			case BPF_TAX:
   2088        1.1     alnsn 				status = sljit_emit_op1(compiler,
   2089       1.45     alnsn 				    SLJIT_MOV_U32,
   2090        1.7     alnsn 				    BJ_XREG, 0,
   2091        1.7     alnsn 				    BJ_AREG, 0);
   2092        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   2093        1.1     alnsn 					goto fail;
   2094        1.1     alnsn 
   2095        1.1     alnsn 				continue;
   2096        1.1     alnsn 
   2097        1.7     alnsn 			case BPF_TXA:
   2098        1.1     alnsn 				status = sljit_emit_op1(compiler,
   2099        1.1     alnsn 				    SLJIT_MOV,
   2100        1.7     alnsn 				    BJ_AREG, 0,
   2101        1.7     alnsn 				    BJ_XREG, 0);
   2102        1.1     alnsn 				if (status != SLJIT_SUCCESS)
   2103        1.1     alnsn 					goto fail;
   2104        1.1     alnsn 
   2105        1.1     alnsn 				continue;
   2106       1.13     alnsn 
   2107       1.13     alnsn 			case BPF_COP:
   2108       1.13     alnsn 			case BPF_COPX:
   2109       1.13     alnsn 				if (bc == NULL || bc->copfuncs == NULL)
   2110       1.13     alnsn 					goto fail;
   2111       1.13     alnsn 				if (BPF_MISCOP(pc->code) == BPF_COP &&
   2112       1.13     alnsn 				    (uint32_t)pc->k >= bc->nfuncs) {
   2113       1.13     alnsn 					goto fail;
   2114       1.13     alnsn 				}
   2115       1.13     alnsn 
   2116       1.32     alnsn 				status = emit_cop(compiler, hints, bc, pc,
   2117       1.28     alnsn 				    &ret0, &ret0_size, &ret0_maxsize);
   2118       1.13     alnsn 				if (status != SLJIT_SUCCESS)
   2119       1.13     alnsn 					goto fail;
   2120       1.13     alnsn 
   2121       1.13     alnsn 				continue;
   2122        1.1     alnsn 			}
   2123        1.1     alnsn 
   2124        1.1     alnsn 			goto fail;
   2125        1.1     alnsn 		} /* switch */
   2126        1.1     alnsn 	} /* main loop */
   2127        1.1     alnsn 
   2128        1.7     alnsn 	BJ_ASSERT(ret0_size <= ret0_maxsize);
   2129        1.1     alnsn 
   2130        1.7     alnsn 	if (ret0_size > 0) {
   2131        1.1     alnsn 		label = sljit_emit_label(compiler);
   2132        1.1     alnsn 		if (label == NULL)
   2133        1.1     alnsn 			goto fail;
   2134        1.7     alnsn 		for (i = 0; i < ret0_size; i++)
   2135        1.7     alnsn 			sljit_set_label(ret0[i], label);
   2136        1.1     alnsn 	}
   2137        1.1     alnsn 
   2138       1.23     alnsn 	status = sljit_emit_return(compiler,
   2139       1.45     alnsn 	    SLJIT_MOV_U32,
   2140       1.23     alnsn 	    SLJIT_IMM, 0);
   2141       1.23     alnsn 	if (status != SLJIT_SUCCESS)
   2142       1.23     alnsn 		goto fail;
   2143       1.23     alnsn 
   2144       1.19     alnsn 	rv = true;
   2145       1.19     alnsn 
   2146       1.19     alnsn fail:
   2147       1.19     alnsn 	if (ret0 != NULL)
   2148       1.19     alnsn 		BJ_FREE(ret0, ret0_maxsize * sizeof(ret0[0]));
   2149       1.19     alnsn 
   2150       1.19     alnsn 	return rv;
   2151       1.19     alnsn }
   2152       1.19     alnsn 
   2153       1.19     alnsn bpfjit_func_t
   2154       1.19     alnsn bpfjit_generate_code(const bpf_ctx_t *bc,
   2155       1.19     alnsn     const struct bpf_insn *insns, size_t insn_count)
   2156       1.19     alnsn {
   2157       1.19     alnsn 	void *rv;
   2158       1.19     alnsn 	struct sljit_compiler *compiler;
   2159       1.19     alnsn 
   2160       1.19     alnsn 	size_t i;
   2161       1.19     alnsn 	int status;
   2162       1.19     alnsn 
   2163       1.19     alnsn 	/* optimization related */
   2164       1.19     alnsn 	bpf_memword_init_t initmask;
   2165       1.20     alnsn 	bpfjit_hint_t hints;
   2166       1.19     alnsn 
   2167       1.19     alnsn 	/* memory store location for initial zero initialization */
   2168       1.45     alnsn 	sljit_s32 mem_reg;
   2169       1.19     alnsn 	sljit_sw mem_off;
   2170       1.19     alnsn 
   2171       1.19     alnsn 	struct bpfjit_insn_data *insn_dat;
   2172       1.19     alnsn 
   2173       1.19     alnsn 	const size_t extwords = GET_EXTWORDS(bc);
   2174       1.19     alnsn 	const size_t memwords = GET_MEMWORDS(bc);
   2175       1.19     alnsn 	const bpf_memword_init_t preinited = extwords ? bc->preinited : 0;
   2176       1.19     alnsn 
   2177       1.19     alnsn 	rv = NULL;
   2178       1.19     alnsn 	compiler = NULL;
   2179       1.19     alnsn 	insn_dat = NULL;
   2180       1.19     alnsn 
   2181       1.19     alnsn 	if (memwords > MAX_MEMWORDS)
   2182       1.19     alnsn 		goto fail;
   2183       1.19     alnsn 
   2184       1.19     alnsn 	if (insn_count == 0 || insn_count > SIZE_MAX / sizeof(insn_dat[0]))
   2185       1.19     alnsn 		goto fail;
   2186       1.19     alnsn 
   2187       1.19     alnsn 	insn_dat = BJ_ALLOC(insn_count * sizeof(insn_dat[0]));
   2188       1.19     alnsn 	if (insn_dat == NULL)
   2189       1.19     alnsn 		goto fail;
   2190       1.19     alnsn 
   2191       1.20     alnsn 	if (!optimize(bc, insns, insn_dat, insn_count, &initmask, &hints))
   2192       1.19     alnsn 		goto fail;
   2193       1.19     alnsn 
   2194       1.45     alnsn 	compiler = sljit_create_compiler(NULL);
   2195       1.19     alnsn 	if (compiler == NULL)
   2196       1.19     alnsn 		goto fail;
   2197       1.19     alnsn 
   2198       1.19     alnsn #if !defined(_KERNEL) && defined(SLJIT_VERBOSE) && SLJIT_VERBOSE
   2199       1.19     alnsn 	sljit_compiler_verbose(compiler, stderr);
   2200       1.19     alnsn #endif
   2201       1.19     alnsn 
   2202       1.45     alnsn 	status = sljit_emit_enter(compiler, 0, 2, nscratches(hints),
   2203       1.45     alnsn 	    NSAVEDS, 0, 0, sizeof(struct bpfjit_stack));
   2204       1.19     alnsn 	if (status != SLJIT_SUCCESS)
   2205       1.19     alnsn 		goto fail;
   2206       1.19     alnsn 
   2207       1.20     alnsn 	if (hints & BJ_HINT_COP) {
   2208       1.19     alnsn 		/* save ctx argument */
   2209       1.19     alnsn 		status = sljit_emit_op1(compiler,
   2210       1.19     alnsn 		    SLJIT_MOV_P,
   2211       1.45     alnsn 		    SLJIT_MEM1(SLJIT_SP),
   2212       1.19     alnsn 		    offsetof(struct bpfjit_stack, ctx),
   2213       1.19     alnsn 		    BJ_CTX_ARG, 0);
   2214       1.19     alnsn 		if (status != SLJIT_SUCCESS)
   2215       1.19     alnsn 			goto fail;
   2216       1.19     alnsn 	}
   2217       1.19     alnsn 
   2218       1.19     alnsn 	if (extwords == 0) {
   2219       1.45     alnsn 		mem_reg = SLJIT_MEM1(SLJIT_SP);
   2220       1.19     alnsn 		mem_off = offsetof(struct bpfjit_stack, mem);
   2221       1.19     alnsn 	} else {
   2222       1.19     alnsn 		/* copy "mem" argument from bpf_args to bpfjit_stack */
   2223       1.19     alnsn 		status = sljit_emit_op1(compiler,
   2224       1.19     alnsn 		    SLJIT_MOV_P,
   2225       1.19     alnsn 		    BJ_TMP1REG, 0,
   2226       1.19     alnsn 		    SLJIT_MEM1(BJ_ARGS), offsetof(struct bpf_args, mem));
   2227       1.19     alnsn 		if (status != SLJIT_SUCCESS)
   2228       1.19     alnsn 			goto fail;
   2229       1.19     alnsn 
   2230       1.19     alnsn 		status = sljit_emit_op1(compiler,
   2231       1.19     alnsn 		    SLJIT_MOV_P,
   2232       1.45     alnsn 		    SLJIT_MEM1(SLJIT_SP),
   2233       1.19     alnsn 		    offsetof(struct bpfjit_stack, extmem),
   2234       1.19     alnsn 		    BJ_TMP1REG, 0);
   2235       1.19     alnsn 		if (status != SLJIT_SUCCESS)
   2236       1.19     alnsn 			goto fail;
   2237       1.19     alnsn 
   2238       1.19     alnsn 		mem_reg = SLJIT_MEM1(BJ_TMP1REG);
   2239       1.19     alnsn 		mem_off = 0;
   2240       1.19     alnsn 	}
   2241       1.19     alnsn 
   2242       1.19     alnsn 	/*
   2243       1.19     alnsn 	 * Exclude pre-initialised external memory words but keep
   2244       1.19     alnsn 	 * initialization statuses of A and X registers in case
   2245       1.19     alnsn 	 * bc->preinited wrongly sets those two bits.
   2246       1.19     alnsn 	 */
   2247       1.19     alnsn 	initmask &= ~preinited | BJ_INIT_ABIT | BJ_INIT_XBIT;
   2248       1.19     alnsn 
   2249       1.19     alnsn #if defined(_KERNEL)
   2250       1.19     alnsn 	/* bpf_filter() checks initialization of memwords. */
   2251       1.19     alnsn 	BJ_ASSERT((initmask & (BJ_INIT_MBIT(memwords) - 1)) == 0);
   2252       1.19     alnsn #endif
   2253       1.19     alnsn 	for (i = 0; i < memwords; i++) {
   2254       1.19     alnsn 		if (initmask & BJ_INIT_MBIT(i)) {
   2255       1.19     alnsn 			/* M[i] = 0; */
   2256       1.19     alnsn 			status = sljit_emit_op1(compiler,
   2257       1.45     alnsn 			    SLJIT_MOV_U32,
   2258       1.19     alnsn 			    mem_reg, mem_off + i * sizeof(uint32_t),
   2259       1.19     alnsn 			    SLJIT_IMM, 0);
   2260       1.19     alnsn 			if (status != SLJIT_SUCCESS)
   2261       1.19     alnsn 				goto fail;
   2262       1.19     alnsn 		}
   2263       1.19     alnsn 	}
   2264       1.19     alnsn 
   2265       1.19     alnsn 	if (initmask & BJ_INIT_ABIT) {
   2266       1.19     alnsn 		/* A = 0; */
   2267       1.19     alnsn 		status = sljit_emit_op1(compiler,
   2268       1.19     alnsn 		    SLJIT_MOV,
   2269       1.19     alnsn 		    BJ_AREG, 0,
   2270       1.19     alnsn 		    SLJIT_IMM, 0);
   2271       1.19     alnsn 		if (status != SLJIT_SUCCESS)
   2272       1.19     alnsn 			goto fail;
   2273       1.19     alnsn 	}
   2274       1.19     alnsn 
   2275       1.19     alnsn 	if (initmask & BJ_INIT_XBIT) {
   2276       1.19     alnsn 		/* X = 0; */
   2277       1.19     alnsn 		status = sljit_emit_op1(compiler,
   2278       1.19     alnsn 		    SLJIT_MOV,
   2279       1.19     alnsn 		    BJ_XREG, 0,
   2280       1.19     alnsn 		    SLJIT_IMM, 0);
   2281       1.19     alnsn 		if (status != SLJIT_SUCCESS)
   2282       1.19     alnsn 			goto fail;
   2283       1.19     alnsn 	}
   2284       1.19     alnsn 
   2285       1.19     alnsn 	status = load_buf_buflen(compiler);
   2286       1.19     alnsn 	if (status != SLJIT_SUCCESS)
   2287       1.19     alnsn 		goto fail;
   2288       1.19     alnsn 
   2289       1.32     alnsn 	if (!generate_insn_code(compiler, hints,
   2290       1.32     alnsn 	    bc, insns, insn_dat, insn_count)) {
   2291       1.19     alnsn 		goto fail;
   2292       1.32     alnsn 	}
   2293       1.19     alnsn 
   2294        1.1     alnsn 	rv = sljit_generate_code(compiler);
   2295        1.1     alnsn 
   2296        1.1     alnsn fail:
   2297        1.1     alnsn 	if (compiler != NULL)
   2298        1.1     alnsn 		sljit_free_compiler(compiler);
   2299        1.1     alnsn 
   2300        1.1     alnsn 	if (insn_dat != NULL)
   2301        1.7     alnsn 		BJ_FREE(insn_dat, insn_count * sizeof(insn_dat[0]));
   2302        1.1     alnsn 
   2303        1.4     rmind 	return (bpfjit_func_t)rv;
   2304        1.1     alnsn }
   2305        1.1     alnsn 
   2306        1.1     alnsn void
   2307        1.4     rmind bpfjit_free_code(bpfjit_func_t code)
   2308        1.1     alnsn {
   2309        1.7     alnsn 
   2310        1.1     alnsn 	sljit_free_code((void *)code);
   2311        1.1     alnsn }
   2312