Skip to content

Commit

Permalink
Update to bpfjit@8a51c60 and sljit@0afe96a
Browse files Browse the repository at this point in the history
Includes a backport of the fix in zherczeg/sljit#105, and an update to bpfjit.c to fix calls to `sljit_create_compiler` and `sljit_free_code`.
  • Loading branch information
alexforster committed Aug 9, 2024
1 parent 6be5300 commit 7c39cf2
Show file tree
Hide file tree
Showing 29 changed files with 10,903 additions and 16,866 deletions.
1 change: 0 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ fn main() {
cc.define("SLJIT_ARGUMENT_CHECKS", "1");
cc.define("SLJIT_DEBUG", "0");
cc.define("SLJIT_VERBOSE", "0");
cc.define("__BPF_PRIVATE", "1");

cc.include(&src.join("sljit"));
cc.include(&src.join("bpfjit"));
Expand Down
26 changes: 13 additions & 13 deletions src/bpfjit/bpf-compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,19 @@ typedef uint32_t bpf_memword_init_t;
#define BPF_MEMWORD_INIT(k) (UINT32_C(1) << (k))

typedef struct bpf_args {
const uint8_t * pkt;
size_t wirelen;
size_t buflen;
/*
* The following arguments are used only by some kernel
* subsystems.
* They aren't required for classical bpf filter programs.
* For such programs, bpfjit generated code doesn't read
* those arguments at all. Note however that bpf interpreter
* always needs a pointer to memstore.
*/
uint32_t * mem; /* pointer to external memory store */
void * arg; /* auxiliary argument for a copfunc */
const uint8_t * pkt;
size_t wirelen;
size_t buflen;
/*
* The following arguments are used only by some kernel
* subsystems.
* They aren't required for classical bpf filter programs.
* For such programs, bpfjit generated code doesn't read
* those arguments at all. Note however that bpf interpreter
* always needs a pointer to memstore.
*/
uint32_t * mem; /* pointer to external memory store */
void * arg; /* auxiliary argument for a copfunc */
} bpf_args_t;

#if defined(_KERNEL) || defined(__BPF_PRIVATE)
Expand Down
60 changes: 42 additions & 18 deletions src/bpfjit/bpfjit.c
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: bpfjit.c,v 1.47 2019/01/20 23:36:57 alnsn Exp $ */
/* $NetBSD: bpfjit.c,v 1.43 2015/02/14 21:32:46 alnsn Exp $ */

/*-
* Copyright (c) 2011-2015 Alexander Nasonov.
Expand Down Expand Up @@ -30,6 +30,9 @@
*/

#include <sys/cdefs.h>
#ifdef _KERNEL
__KERNEL_RCSID(0, "$NetBSD: bpfjit.c,v 1.43 2015/02/14 21:32:46 alnsn Exp $");
#endif

#include <sys/types.h>
#include <sys/queue.h>
Expand Down Expand Up @@ -62,8 +65,15 @@
#include <sys/module.h>
#endif

#define __BPF_PRIVATE
#ifdef __linux
#include <pcap-bpf.h>
#else
#include <net/bpf.h>
#endif

#include "bpfjit.h"
#include "sljitLir.h"
#include <sljitLir.h>

#if !defined(_KERNEL) && defined(SLJIT_VERBOSE) && SLJIT_VERBOSE
#include <stdio.h> /* for stderr */
Expand Down Expand Up @@ -597,8 +607,12 @@ emit_xcall(struct sljit_compiler *compiler, bpfjit_hint_t hints,
return status;

/* fn(buf, k, &err); */
status = sljit_emit_ijump(compiler,
SLJIT_CALL3,
status = sljit_emit_icall(compiler,
SLJIT_CALL_CDECL,
SLJIT_DEF_RET(SLJIT_ARG_TYPE_U32) |
SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_UW) |
SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_U32) |
SLJIT_DEF_ARG3(SLJIT_ARG_TYPE_UW),
SLJIT_IMM, SLJIT_FUNC_OFFSET(fn));
if (status != SLJIT_SUCCESS)
return status;
Expand Down Expand Up @@ -755,8 +769,13 @@ emit_cop(struct sljit_compiler *compiler, bpfjit_hint_t hints,
if (status != SLJIT_SUCCESS)
return status;

status = sljit_emit_ijump(compiler,
SLJIT_CALL3, call_reg, call_off);
status = sljit_emit_icall(compiler,
SLJIT_CALL_CDECL,
SLJIT_DEF_RET(SLJIT_ARG_TYPE_U32) |
SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_UW) |
SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_UW) |
SLJIT_DEF_ARG3(SLJIT_ARG_TYPE_U32),
call_reg, call_off);
if (status != SLJIT_SUCCESS)
return status;

Expand Down Expand Up @@ -1116,14 +1135,14 @@ emit_pow2_moddiv(struct sljit_compiler *compiler, const struct bpf_insn *pc)
}

#if !defined(BPFJIT_USE_UDIV)
static sljit_uw
static sljit_uw SLJIT_FUNC
divide(sljit_uw x, sljit_uw y)
{

return (uint32_t)x / (uint32_t)y;
}

static sljit_uw
static sljit_uw SLJIT_FUNC
modulus(sljit_uw x, sljit_uw y)
{

Expand All @@ -1139,7 +1158,6 @@ static int
emit_moddiv(struct sljit_compiler *compiler, const struct bpf_insn *pc)
{
int status;
const bool xdiv = BPF_OP(pc->code) == BPF_DIV;
const bool xreg = BPF_SRC(pc->code) == BPF_X;

#if BJ_XREG == SLJIT_RETURN_REG || \
Expand Down Expand Up @@ -1167,7 +1185,7 @@ emit_moddiv(struct sljit_compiler *compiler, const struct bpf_insn *pc)
return status;

#if defined(BPFJIT_USE_UDIV)
status = sljit_emit_op0(compiler, SLJIT_UDIV|SLJIT_I32_OP);
status = sljit_emit_op0(compiler, SLJIT_DIV_U32);

if (BPF_OP(pc->code) == BPF_DIV) {
#if BJ_AREG != SLJIT_R0
Expand All @@ -1189,10 +1207,14 @@ emit_moddiv(struct sljit_compiler *compiler, const struct bpf_insn *pc)
if (status != SLJIT_SUCCESS)
return status;
#else
status = sljit_emit_ijump(compiler,
SLJIT_CALL2,
SLJIT_IMM, xdiv ? SLJIT_FUNC_OFFSET(divide) :
SLJIT_FUNC_OFFSET(modulus));
status = sljit_emit_icall(compiler,
SLJIT_CALL,
SLJIT_DEF_RET(SLJIT_ARG_TYPE_UW) |
SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_UW) |
SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_UW),
SLJIT_IMM,
BPF_OP(pc->code) == BPF_DIV ?
SLJIT_FUNC_OFFSET(divide) : SLJIT_FUNC_OFFSET(modulus));

#if BJ_AREG != SLJIT_RETURN_REG
status = sljit_emit_op1(compiler,
Expand Down Expand Up @@ -2184,16 +2206,18 @@ bpfjit_generate_code(const bpf_ctx_t *bc,
if (!optimize(bc, insns, insn_dat, insn_count, &initmask, &hints))
goto fail;

compiler = sljit_create_compiler(NULL);
compiler = sljit_create_compiler(NULL, NULL);
if (compiler == NULL)
goto fail;

#if !defined(_KERNEL) && defined(SLJIT_VERBOSE) && SLJIT_VERBOSE
sljit_compiler_verbose(compiler, stderr);
#endif

status = sljit_emit_enter(compiler, 0, 2, nscratches(hints),
NSAVEDS, 0, 0, sizeof(struct bpfjit_stack));
status = sljit_emit_enter(compiler, 0,
SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_UW) |
SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_UW),
nscratches(hints), NSAVEDS, 0, 0, sizeof(struct bpfjit_stack));
if (status != SLJIT_SUCCESS)
goto fail;

Expand Down Expand Up @@ -2300,5 +2324,5 @@ void
bpfjit_free_code(bpfjit_func_t code)
{

sljit_free_code((void *)code);
sljit_free_code((void *)code, NULL);
}
11 changes: 1 addition & 10 deletions src/bpfjit/bpfjit.h
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/* $NetBSD: bpfjit.h,v 1.4 2014/06/25 19:32:37 alnsn Exp $ */

/*-
* Copyright (c) 2011-2014 Alexander Nasonov.
* Copyright (c) 2011-2013 Alexander Nasonov.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -52,13 +50,6 @@ typedef struct bpf_ctx bpf_ctx_t;
#include "bpf-compat.h"
#endif

/*
* Return value of a function generated by sljit have sljit_uw type
* which can have a greater width. In such cases, we rely on the fact
* that calling conventions use same registers for smaller types.
* SLJIT_MOV_UI is passed to sljit_emit_return() to make sure that the
* return value is truncated to unsigned int.
*/
typedef unsigned int (*bpfjit_func_t)(const bpf_ctx_t *, bpf_args_t *);

bpfjit_func_t bpfjit_generate_code(const bpf_ctx_t *,
Expand Down
65 changes: 46 additions & 19 deletions src/sljit/sljitConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef _SLJIT_CONFIG_H_
#define _SLJIT_CONFIG_H_
#ifndef SLJIT_CONFIG_H_
#define SLJIT_CONFIG_H_

/* --------------------------------------------------------------------- */
/* Custom defines */
/* --------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif

/* Put your custom defines here. This empty section will never change
which helps maintaining patches (with diff / patch utilities). */
/*
This file contains the basic configuration options for the SLJIT compiler
and their default values. These options can be overridden in the
sljitConfigPre.h header file when SLJIT_HAVE_CONFIG_PRE is set to a
non-zero value.
*/

/* --------------------------------------------------------------------- */
/* Architecture */
Expand All @@ -50,7 +54,7 @@
/* #define SLJIT_CONFIG_MIPS_32 1 */
/* #define SLJIT_CONFIG_MIPS_64 1 */
/* #define SLJIT_CONFIG_SPARC_32 1 */
/* #define SLJIT_CONFIG_TILEGX 1 */
/* #define SLJIT_CONFIG_S390X 1 */

/* #define SLJIT_CONFIG_AUTO 1 */
/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
Expand All @@ -59,18 +63,19 @@
/* Utilities */
/* --------------------------------------------------------------------- */

/* Useful for thread-safe compiling of global functions. */
#ifndef SLJIT_UTIL_GLOBAL_LOCK
/* Enabled by default */
#define SLJIT_UTIL_GLOBAL_LOCK 1
#endif

/* Implements a stack like data structure (by using mmap / VirtualAlloc). */
/* Implements a stack like data structure (by using mmap / VirtualAlloc */
/* or a custom allocator). */
#ifndef SLJIT_UTIL_STACK
/* Enabled by default */
#define SLJIT_UTIL_STACK 1
#endif

/* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */
#ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION
/* Disabled by default */
#define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0
#endif

/* Single threaded application. Does not require any locks. */
#ifndef SLJIT_SINGLE_THREADED
/* Disabled by default. */
Expand All @@ -97,19 +102,37 @@

/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses
an allocator which does not set writable and executable
permission flags at the same time. The trade-of is increased
memory consumption and disabled dynamic code modifications. */
permission flags at the same time.
Instead, it creates a shared memory segment (usually backed by a file)
and maps it twice, with different permissions, depending on the use
case.
The trade-off is increased use of virtual memory, incompatibility with
fork(), and some possible additional security risks by the use of
publicly accessible files for the generated code. */
#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR
/* Disabled by default. */
#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0
#endif

/* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an
allocator which does not set writable and executable permission
flags at the same time.
Instead, it creates a new independent map on each invocation and
switches permissions at the underlying pages as needed.
The trade-off is increased memory use and degraded performance. */
#ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR
/* Disabled by default. */
#define SLJIT_WX_EXECUTABLE_ALLOCATOR 0
#endif

#endif /* !SLJIT_EXECUTABLE_ALLOCATOR */

/* Force cdecl calling convention even if a better calling
convention (e.g. fastcall) is supported by the C compiler.
If this option is enabled, C functions without
SLJIT_CALL can also be called from JIT code. */
If this option is disabled (this is the default), functions
called from JIT should be defined with SLJIT_FUNC attribute.
Standard C functions can still be called by using the
SLJIT_CALL_CDECL jump type. */
#ifndef SLJIT_USE_CDECL_CALLING_CONVENTION
/* Disabled by default */
#define SLJIT_USE_CDECL_CALLING_CONVENTION 0
Expand Down Expand Up @@ -142,4 +165,8 @@

/* For further configurations, see the beginning of sljitConfigInternal.h */

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* SLJIT_CONFIG_H_ */
Loading

0 comments on commit 7c39cf2

Please sign in to comment.