// SPDX-License-Identifier: GPL-2.0
/*
* The back-end-agnostic part of Just-In-Time compiler for eBPF bytecode.
*
* Copyright (c) 2024 Synopsys Inc.
* Author: Shahab Vahedi <shahab@synopsys.com>
*/
#include <linux/bug.h>
#include "bpf_jit.h"
/*
* Check for the return value. A pattern used often in this file.
* There must be a "ret" variable of type "int" in the scope.
*/
#define CHECK_RET(cmd) \
do { \
ret = (cmd); \
if (ret < 0) \
return ret; \
} while (0)
#ifdef ARC_BPF_JIT_DEBUG
/* Dumps bytes in /var/log/messages at KERN_INFO level (4). */
static void dump_bytes(const u8 *buf, u32 len, const char *header)
{
u8 line[64];
size_t i, j;
pr_info("-----------------[ %s ]-----------------\n", header);
for (i = 0, j = 0; i < len; i++) {
/* Last input byte? */
if (i == len - 1) {
j += scnprintf(line + j, 64 - j, "0x%02x", buf[i]);
pr_info("%s\n", line);
break;
}
/* End of line? */
else if (i % 8 == 7) {
j += scnprintf(line + j, 64 - j, "0x%02x", buf[i]);
pr_info("%s\n", line);
j = 0;
} else {
j += scnprintf(line + j, 64 - j, "0x%02x, ", buf[i]);
}
}
}
#endif /* ARC_BPF_JIT_DEBUG */
/********************* JIT context ***********************/
/*
* buf: Translated instructions end up here.
* len: The length of whole block in bytes.
* index: The offset at which the _next_ instruction may be put.
*/
struct jit_buffer {
u8 *buf;
u32 len;
u32 index;
};
/*
* This is a subset of "struct jit_context" that its information is deemed
* necessary for the next extra pass to come.
*
* bpf_header: Needed to finally lock the region.
* bpf2insn: Used to find the translation for instructions of interest.
*
* Things like "jit.buf" and "jit.len" can be retrieved respectively from
* "prog->bpf_func" and "prog->jited_len".
*/
struct arc_jit_data {
struct bpf_binary_header *bpf_header;
u32 *bpf2insn;