// SPDX-License-Identifier: GPL-2.0

#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <regex.h>
#include <test_progs.h>

#include "bpf/btf.h"
#include "bpf_util.h"
#include "linux/filter.h"
#include "disasm.h"

#define MAX_PROG_TEXT_SZ (32 * 1024)

/* The code in this file serves the sole purpose of executing test cases
 * specified in the test_cases array. Each test case specifies a program
 * type, context field offset, and disassembly patterns that correspond
 * to read and write instructions generated by
 * verifier.c:convert_ctx_access() for accessing that field.
 *
 * For each test case, up to three programs are created:
 * - One that uses BPF_LDX_MEM to read the context field.
 * - One that uses BPF_STX_MEM to write to the context field.
 * - One that uses BPF_ST_MEM to write to the context field.
 *
 * The disassembly of each program is then compared with the pattern
 * specified in the test case.
 */
struct test_case {
	char *name;
	enum bpf_prog_type prog_type;
	enum bpf_attach_type expected_attach_type;
	int field_offset;
	int field_sz;
	/* Program generated for BPF_ST_MEM uses value 42 by default,
	 * this field allows to specify custom value.
	 */
	struct {
		bool use;
		int value;
	} st_value;
	/* Pattern for BPF_LDX_MEM(field_sz, dst, ctx, field_offset) */
	char *read;
	/* Pattern for BPF_STX_MEM(field_sz, ctx, src, field_offset) and
	 *             BPF_ST_MEM (field_sz, ctx, src, field_offset)
	 */
	char *write;
	/* Pattern for BPF_ST_MEM(field_sz, ctx, src, field_offset),
	 * takes priority over `write`.
	 */
	char *write_st;
	/* Pattern for BPF_STX_MEM (field_sz, ctx, src, field_offset),
	 * takes priority over `write`.
	 */
	char *write_stx;
};

#define N(_prog_type, type, field, name_extra...)	\
	.name = #_prog_type "." #field name_extra,	\
	.prog_type = BPF_PROG_TYPE_##_prog_type,	\
	.field_offset = offsetof(type, field),		\
	.field_sz = sizeof(typeof(((type *)NULL)->field))

static struct test_case test_cases[] = {
/* Sign extension on s390 changes the pattern */
#if defined(__x86_64__) || defined(__aarch64__)
	{
		N(SCHED_CLS, struct __sk_buff, tstamp),
		.read  = "r11 = *(u8 *)($ctx + sk_buff::__mono_tc_offset);"
			 "w11 &= 3;"
			 "if w11 != 0x3 goto pc+2;"
			 "$dst = 0;"
			 "goto pc+1;"
			 "$dst = *(u64 *)($ctx + sk_buff::tstamp);",
		.write = "r11 = *(u8 *)($ctx + sk_buff::__mono_tc_offset);"
			 "if w11 & 0x2 goto pc+1;"
			 "goto pc+2;"
			 "w11 &= -2;"
			 "*(u8 *)($ctx + sk_buff::__mono_tc_offset) = r11;"
			 "*(u64 *)($ctx + sk_buff::tstamp) = $src;",
	},
#endif
	{
		N(SCHED_CLS, struct __sk_buff, priority),
		.read  = "$dst = *(u32 *)($ctx + sk_buff::priority);",
		.write = "*(u32 *)($ctx + sk_buff::priority) = $src;",
	},
	{
		N(SCHED_CLS, struct __sk_buff, mark),
		.read  = "$dst = *(u32 *)($ctx + sk_buff::mark);",
		.write = "*(u32 *)($ctx + sk_buff::mark) = $src;",
	},
	{
		N(SCHED_CLS, struct __sk_buff, cb[0]),
		.read  = "$dst = *(u32 *)($ctx + $(sk_buff::cb + qdisc_skb_cb::data));",
		.write = "*(u32 *)($ctx + $(sk_buff::cb + qdisc_skb_cb::data)) = $src;",
	},
	{
		N(SCHED_CLS, struct __sk_buff, tc_classid),
		.read  = "$dst = *(u16 *)($ctx + $(sk_buff::cb + qdisc_skb_cb::tc_classid));",
		.write = "*(u16 *)($ctx + $(sk_buff::cb + qdisc_skb_cb::tc_classid)) = $src;",
	},
	{
		N(SCHED_CLS, struct __sk_buff, tc_index),
		.read  = "$dst = *(u16 *)($ctx + sk_buff::tc_index);",
		.write = "*(u16 *)($ctx + sk_buff::tc_index) = $src;",
	},
	{
		N(SCHED_CLS, struct __sk_buff, queue_mapping),
		.read      = "$dst = *(u16 *)($ctx + sk_buff::queue_mapping);",
		.write_stx = "if $src >= 0xffff goto pc+1;"
			     "*(u16 *)($ctx + sk_buff::queue_mapping) = $src;",
		.write_st  = "*(u16 *)($ctx + sk_buff::queue_mapping) = $src;",
	},
	{
		/* This is a corner case in filter.c:bpf_convert_ctx_access() */
		N(SCHED_CLS, struct __sk_buff, queue_mapping, ".ushrt_max"),
		.st_value = { true, USHRT_MAX },
		.write_st = "goto pc+0;",
	},
	{
		N(CGROUP_SOCK, struct bpf_sock, bound_dev_if),
		.read  = "$dst = *(u32 *)($ctx + sock_common::skc_bound_dev_if);",
		.write = "*(u32 *)($ctx + sock_common::skc_bound_dev_if) = $src;",
	},
	{
		N(CGROUP_SOCK, struct bpf_sock, mark),
		.read  = "$dst = *(u32 *)($ctx + sock::sk_mark);",
		.write = "*(u32 *)($ctx + sock::sk_mark) = $src;",
	},
	{
		N(CGROUP_SOCK, struct bpf_sock, priority),
		.read  = "$dst = *(u32 *)($ctx + sock::sk_priority);",
		.write = "*(u32 *)($ctx + sock::sk_priority) = $src;",
	},
	{
		N(SOCK_OPS, struct bpf_sock_ops, replylong[0]),
		.read  = "$dst = *(u32 *)($ctx + bpf_sock_ops_kern::replylong);",
		.write = "*(u32 *)($ctx + bpf_sock_ops_kern::replylong) = $src;",
	},
	{
		N(CGROUP_SYSCTL, struct bpf_sysctl, file_pos),
#if __BYTE_ORDER == __LITTLE_ENDIAN
		.read  = "$dst = *(u64 *)($ctx + bpf_sysctl_kern::ppos);"
			 "$dst = *(u32 *)($dst +0);",
		.write = "*(u64 *)($ctx + bpf_sysctl_kern::tmp_reg) = r9;"
			 "r9 = *(u64 *)($ctx + bpf_sysctl_kern::ppos);"
			 "*(u32 *)(r9 +0) = $src;"
			 "r9 = *(u64 *)($ctx + bpf_sysctl_kern::tmp_reg);",
#else
		.read  = "$dst = *(u64 *)($ctx + bpf_sysctl_kern::ppos);"
			 "$dst = *(u32 *)($dst +4);",
		.write = "*(u64 *)($ctx + bpf_sysctl_kern::tmp_reg) = r9;"
			 "r9 = *(u64 *)($ctx + bpf_sysctl_kern::ppos);"
			 "*(u32 *)(r9 +4) = $src;"
			 "r9 = *(u64 *)($ctx + bpf_sysctl_kern::tmp_reg);",
#endif
	},
	{
		N(CGROUP_SOCKOPT, struct bpf_sockopt, sk),
		.read  = "$dst = *(u64 *)($ctx + bpf_sockopt_kern::sk);",
		.expected_attach_type = BPF_CGROUP_GETSOCKOPT,
	},
	{
		N(CGROUP_SOCKOPT, struct bpf_sockopt, level),
		.read  = "$dst = *(u32 *)($ctx + bpf_sockopt_kern::level);",
		.write = "*(u32 *)($ctx + bpf_sockopt_kern::level) = $src;",
		.expected_attach_type = BPF_CGROUP_SETSOCKOPT,
	},
	{
		N(CGROUP_SOCKOPT, struct bpf_sockopt, optname),
		.read  = "$dst = *(u32 *)($ctx + bpf_sockopt_kern::optname);",
		.write = "*(u32 *)($ctx + bpf_sockopt_kern::optname) = $src;",
		.expected_attach_type = BPF_CGROUP_SETSOCKOPT,
	},
	{
		N(CGROUP_SOCKOPT, struct bpf_sockopt, optlen),
		.read  = "$dst = *(u32 *)($ctx + bpf_sockopt_kern::optlen);",
		.write = "*(u32 *)($ctx + bpf_sockopt_kern::optlen) = $src;",
		.expected_attach_type = BPF_CGROUP_SETSOCKOPT,
	},
	{
		N(CGROUP_SOCKOPT, struct bpf_sockopt, retval),
		.read  = "$dst = *(u64 *)($ctx + bpf_sockopt_kern::current_task);"
			 "$dst = *(u64 *)($dst + task_struct::bpf_ctx);"
			 "$dst = *(u32 *)($dst + bpf_cg_run_ctx::retval);",
		.write = "*(u64 *)($ctx + bpf_sockopt_kern::tmp_reg) = r9;"
			 "r9 = *(u64 *)($ctx + bpf_sockopt_kern::current_task);"
			 "r9 = *(u64 *)(r9 + task_struct::bpf_ctx);"
			 "*(u32 *)(r9 + bpf_cg_run_ctx::retval) = $src;"
			 "r9 = *(u64 *)($ctx + bpf_sockopt_kern::tmp_reg);",
		.expected_attach_type = BPF_CGROUP_GETSOCKOPT,
	},
	{
		N(CGROUP_SOCKOPT, struct bpf_sockopt, optval),
		.read  = "$dst = *(u64 *)($ctx + bpf_sockopt_kern::optval);",
		.expected_attach_type = BPF_CGROUP_GETSOCKOPT,
	},
	{
		N(CGROUP_SOCKOPT, struct bpf_sockopt, optval_end),
		.read  = "$dst = *(u64 *)($ctx + bpf_sockopt_kern::optval_end);",
		.expected_attach_type = BPF_CGROUP_GETSOCKOPT,
	},
};

#undef N

static regex_t *ident_regex;
static regex_t *field_regex;

static char *skip_space(char *str)
{
	while (*str && isspace(*str))
		++str;
	return str;
}

static char *skip_space_and_semi(char *str)
{
	while (*str && (isspace(*str) || *str == ';'))
		++str;
	return str;
}

static char *match_str(char *str, char *prefix)
{
	while (*str && *prefix && *str == *prefix) {
		++str;
		++prefix;
	}
	if (*prefix)
		return NULL;
	return str;
}

static char *match_number(char *str, int num)
{
	char *next;
	int snum = strtol(str, &next, 10);

	if (next - str == 0 || num != snum)
		return NULL;

	return next;
}

static int find_field_offset_aux(struct btf *btf, int btf_id, char *field_name, int off)
{
	const struct btf_type *type = btf__type_by_id(btf, btf_id);
	const struct btf_member *m;
	__u16 mnum;
	int i;

	if (!type) {
		PRINT_FAIL("Can't find btf_type for id %d\n", btf_id);
		return -1;
	}

	if (!btf_is_struct(type) && !btf_is_union(type)) {
		PRINT_FAIL("BTF id %d is not struct or union\n", btf_id);
		return -1;
	}

	m = btf_members(type);
	mnum = btf_vlen(type);

	for (i = 0; i < mnum; ++i, ++m) {
		const char *mname = btf__name_by_offset(btf, m->name_off);

		if (strcmp(mname, "") == 0) {
			int msize = find_field_offset_aux(btf, m->type, field_name,
							  off + m->offset);
			if (msize >= 0)
				return msize;
		}

		if (strcmp(mname, field_name))
			continue;

		return (off + m->offset) / 8;
	}

	return -1;
}

static int find_field_offset(struct btf *btf, char *pattern, regmatch_t *matches)
{
	int type_sz  = matches[1].rm_eo - matches[1].rm_so;
	int field_sz = matches[2].rm_eo - matches[2].rm_so;
	char *type   = pattern + matches[1].rm_so;
	char *field  = pattern + matches[2].rm_so;
	char field_str[128] = {};
	char type_str[128] = {};
	int btf_id, field_offset;

	if (type_sz >= sizeof(type_str)) {
		PRINT_FAIL("Malformed pattern: type ident is too long: %d\n", type_sz);
		return -1;
	}

	if (field_sz >= sizeof(field_str)) {
		PRINT_FAIL("Malformed pattern: field ident is too long: %d\n", field_sz);
		return -1;
	}

	strncpy(type_str, type, type_sz);
	strncpy(field_str, field, field_sz);
	btf_id = btf__find_by_name(btf, type_str);
	if (btf_id < 0) {
		PRINT_FAIL("No BTF info for type %s\n", type_str);
		return -1;
	}

	field_offset = find_field_offset_aux(btf, btf_id, field_str, 0);
	if (field_offset < 0) {
		PRINT_FAIL("No BTF info for field %s::%s\n", type_str, field_str);
		return -1;
	}

	return field_offset;
}

static regex_t *compile_regex(char *pat)
{
	regex_t *re;
	int err;

	re = malloc(sizeof(regex_t));
	if (!re) {
		PRINT_FAIL("Can't alloc regex\n");
		return NULL;
	}

	err = regcomp(re, pat, REG_EXTENDED);
	if (err) {
		char errbuf[512];

		regerror(err, re, errbuf, sizeof(errbuf));
		PRINT_FAIL("Can't compile regex: %s\n", errbuf);
		free(re);
		return NULL;
	}

	return re;
}

static void free_regex(regex_t *re)
{
	if (!re)
		return;

	regfree(re);
	free(re);
}

static u32 max_line_len(char *str)
{
	u32 max_line = 0;
	char *next = str;

	while (next) {
		next = strchr(str, '\n');
		if (next) {
			max_line = max_t(u32, max_line, (next - str));
			str = next + 1;
		} else {
			max_line = max_t(u32, max_line, strlen(str));
		}
	}

	return min(max_line, 60u);
}

/* Print strings `pattern_origin` and `text_origin` side by side,
 * assume `pattern_pos` and `text_pos` designate location within
 * corresponding origin string where match diverges.
 * The output should look like:
 *
 *   Can't match disassembly(left) with pattern(right):
 *   r2 = *(u64 *)(r1 +0)  ;  $dst = *(u64 *)($ctx + bpf_sockopt_kern::sk1)
 *                     ^                             ^
 *   r0 = 0                ;
 *   exit                  ;
 */
static void print_match_error(FILE *out,
			      char *pattern_origin, char *text_origin,
			      char *pattern_pos, char *text_pos)
{
	char *pattern = pattern_origin;
	char *text = text_origin;
	int middle = max_line_len(text) + 2;

	fprintf(out, "Can't match disassembly(left) with pattern(right):\n");
	while (*pattern || *text) {
		int column = 0;
		int mark1 = -1;
		int mark2 = -1;

		/* Print one line from text */
		while (*text && *text != '\n') {
			if (text == text_pos)
				mark1 = column;
			fputc(*text, out);
			++text;
			++column;
		}
		if (text == text_pos)
			mark1 = column;

		/* Pad to the middle */
		while (column < middle) {
			fputc(' ', out);
			++column;
		}
		fputs(";  ", out);
		column += 3;

		/* Print one line from pattern, pattern lines are terminated by ';' */
		while (*pattern && *pattern != ';') {
			if (pattern == pattern_pos)
				mark2 = column;
			fputc(*pattern, out);
			++pattern;
			++column;
		}
		if (pattern == pattern_pos)
			mark2 = column;

		fputc('\n', out);
		if (*pattern)
			++pattern;
		if (*text)
			++text;

		/* If pattern and text diverge at this line, print an
		 * additional line with '^' marks, highlighting
		 * positions where match fails.
		 */
		if (mark1 > 0 || mark2 > 0) {
			for (column = 0; column <= max(mark1, mark2); ++column) {
				if (column == mark1 || column == mark2)
					fputc('^', out);
				else
					fputc(' ', out);
			}
			fputc('\n', out);
		}
	}
}

/* Test if `text` matches `pattern`. Pattern consists of the following elements:
 *
 * - Field offset references:
 *
 *     <type>::<field>
 *
 *   When such reference is encountered BTF is used to compute numerical
 *   value for the offset of <field> in <type>. The `text` is expected to
 *   contain matching numerical value.
 *
 * - Field groups:
 *
 *     $(<type>::<field> [+ <type>::<field>]*)
 *
 *   Allows to specify an offset that is a sum of multiple field offsets.
 *   The `text` is expected to contain matching numerical value.
 *
 * - Variable references, e.g. `$src`, `$dst`, `$ctx`.
 *   These are substitutions specified in `reg_map` array.
 *   If a substring of pattern is equal to `reg_map[i][0]` the `text` is
 *   expected to contain `reg_map[i][1]` in the matching position.
 *
 * - Whitespace is ignored, ';' counts as whitespace for `pattern`.
 *
 * - Any other characters, `pattern` and `text` should match one-to-one.
 *
 * Example of a pattern:
 *
 *                    __________ fields group ________________
 *                   '                                        '
 *   *(u16 *)($ctx + $(sk_buff::cb + qdisc_skb_cb::tc_classid)) = $src;
 *            ^^^^                   '______________________'
 *     variable reference             field offset reference
 */
static bool match_pattern(struct btf *btf, char *pattern, char *text, char *reg_map[][2])
{
	char *pattern_origin = pattern;
	char *text_origin = text;
	regmatch_t matches[3];

_continue:
	while (*pattern) {
		if (!*text)
			goto err;

		/* Skip whitespace */
		if (isspace(*pattern) || *pattern == ';') {
			if (!isspace(*text) && text != text_origin && isalnum(text[-1]))
				goto err;
			pattern = skip_space_and_semi(pattern);
			text = skip_space(text);
			continue;
		}

		/* Check for variable references */
		for (int i = 0; reg_map[i][0]; ++i) {
			char *pattern_next, *text_next;

			pattern_next = match_str(pattern, reg_map[i][0]);
			if (!pattern_next)
				continue;

			text_next = match_str(text, reg_map[i][1]);
			if (!text_next)
				goto err;

			pattern = pattern_next;
			text = text_next;
			goto _continue;
		}

		/* Match field group:
		 *   $(sk_buff::cb + qdisc_skb_cb::tc_classid)
		 */
		if (strncmp(pattern, "$(", 2) == 0) {
			char *group_start = pattern, *text_next;
			int acc_offset = 0;

			pattern += 2;

			for (;;) {
				int field_offset;

				pattern = skip_space(pattern);
				if (!*pattern) {
					PRINT_FAIL("Unexpected end of pattern\n");
					goto err;
				}

				if (*pattern == ')') {
					++pattern;
					break;
				}

				if (*pattern == '+') {
					++pattern;
					continue;
				}

				printf("pattern: %s\n", pattern);
				if (regexec(field_regex, pattern, 3, matches, 0) != 0) {
					PRINT_FAIL("Field reference expected\n");
					goto err;
				}

				field_offset = find_field_offset(btf, pattern, matches);
				if (field_offset < 0)
					goto err;

				pattern += matches[0].rm_eo;
				acc_offset += field_offset;
			}

			text_next = match_number(text, acc_offset);
			if (!text_next) {
				PRINT_FAIL("No match for group offset %.*s (%d)\n",
					   (int)(pattern - group_start),
					   group_start,
					   acc_offset);
				goto err;
			}
			text = text_next;
		}

		/* Match field reference:
		 *   sk_buff::cb
		 */
		if (regexec(field_regex, pattern, 3, matches, 0) == 0) {
			int field_offset;
			char *text_next;

			field_offset = find_field_offset(btf, pattern, matches);
			if (field_offset < 0)
				goto err;

			text_next = match_number(text, field_offset);
			if (!text_next) {
				PRINT_FAIL("No match for field offset %.*s (%d)\n",
					   (int)matches[0].rm_eo, pattern, field_offset);
				goto err;
			}

			pattern += matches[0].rm_eo;
			text = text_next;
			continue;
		}

		/* If pattern points to identifier not followed by '::'
		 * skip the identifier to avoid n^2 application of the
		 * field reference rule.
		 */
		if (regexec(ident_regex, pattern, 1, matches, 0) == 0) {
			if (strncmp(pattern, text, matches[0].rm_eo) != 0)
				goto err;

			pattern += matches[0].rm_eo;
			text += matches[0].rm_eo;
			continue;
		}

		/* Match literally */
		if (*pattern != *text)
			goto err;

		++pattern;
		++text;
	}

	return true;

err:
	test__fail();
	print_match_error(stdout, pattern_origin, text_origin, pattern, text);
	return false;
}

static void print_insn(void *private_data, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	vfprintf((FILE *)private_data, fmt, args);
	va_end(args);
}

/* Disassemble instructions to a stream */
static void print_xlated(FILE *out, struct bpf_insn *insn, __u32 len)
{
	const struct bpf_insn_cbs cbs = {
		.cb_print	= print_insn,
		.cb_call	= NULL,
		.cb_imm		= NULL,
		.private_data	= out,
	};
	bool double_insn = false;
	int i;

	for (i = 0; i < len; i++) {
		if (double_insn) {
			double_insn = false;
			continue;
		}

		double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW);
		print_bpf_insn(&cbs, insn + i, true);
	}
}

/* We share code with kernel BPF disassembler, it adds '(FF) ' prefix
 * for each instruction (FF stands for instruction `code` byte).
 * This function removes the prefix inplace for each line in `str`.
 */
static void remove_insn_prefix(char *str, int size)
{
	const int prefix_size = 5;

	int write_pos = 0, read_pos = prefix_size;
	int len = strlen(str);
	char c;

	size = min(size, len);

	while (read_pos < size) {
		c = str[read_pos++];
		if (c == 0)
			break;
		str[write_pos++] = c;
		if (c == '\n')
			read_pos += prefix_size;
	}
	str[write_pos] = 0;
}

struct prog_info {
	char *prog_kind;
	enum bpf_prog_type prog_type;
	enum bpf_attach_type expected_attach_type;
	struct bpf_insn *prog;
	u32 prog_len;
};

static void match_program(struct btf *btf,
			  struct prog_info *pinfo,
			  char *pattern,
			  char *reg_map[][2],
			  bool skip_first_insn)
{
	struct bpf_insn *buf = NULL;
	int err = 0, prog_fd = 0;
	FILE *prog_out = NULL;
	char *text = NULL;
	__u32 cnt = 0;

	text = calloc(MAX_PROG_TEXT_SZ, 1);
	if (!text) {
		PRINT_FAIL("Can't allocate %d bytes\n", MAX_PROG_TEXT_SZ);
		goto out;
	}

	// TODO: log level
	LIBBPF_OPTS(bpf_prog_load_opts, opts);
	opts.log_buf = text;
	opts.log_size = MAX_PROG_TEXT_SZ;
	opts.log_level = 1 | 2 | 4;
	opts.expected_attach_type = pinfo->expected_attach_type;

	prog_fd = bpf_prog_load(pinfo->prog_type, NULL, "GPL",
				pinfo->prog, pinfo->prog_len, &opts);
	if (prog_fd < 0) {
		PRINT_FAIL("Can't load program, errno %d (%s), verifier log:\n%s\n",
			   errno, strerror(errno), text);
		goto out;
	}

	memset(text, 0, MAX_PROG_TEXT_SZ);

	err = get_xlated_program(prog_fd, &buf, &cnt);
	if (err) {
		PRINT_FAIL("Can't load back BPF program\n");
		goto out;
	}

	prog_out = fmemopen(text, MAX_PROG_TEXT_SZ - 1, "w");
	if (!prog_out) {
		PRINT_FAIL("Can't open memory stream\n");
		goto out;
	}
	if (skip_first_insn)
		print_xlated(prog_out, buf + 1, cnt - 1);
	else
		print_xlated(prog_out, buf, cnt);
	fclose(prog_out);
	remove_insn_prefix(text, MAX_PROG_TEXT_SZ);

	ASSERT_TRUE(match_pattern(btf, pattern, text, reg_map),
		    pinfo->prog_kind);

out:
	if (prog_fd)
		close(prog_fd);
	free(buf);
	free(text);
}

static void run_one_testcase(struct btf *btf, struct test_case *test)
{
	struct prog_info pinfo = {};
	int bpf_sz;

	if (!test__start_subtest(test->name))
		return;

	switch (test->field_sz) {
	case 8:
		bpf_sz = BPF_DW;
		break;
	case 4:
		bpf_sz = BPF_W;
		break;
	case 2:
		bpf_sz = BPF_H;
		break;
	case 1:
		bpf_sz = BPF_B;
		break;
	default:
		PRINT_FAIL("Unexpected field size: %d, want 8,4,2 or 1\n", test->field_sz);
		return;
	}

	pinfo.prog_type = test->prog_type;
	pinfo.expected_attach_type = test->expected_attach_type;

	if (test->read) {
		struct bpf_insn ldx_prog[] = {
			BPF_LDX_MEM(bpf_sz, BPF_REG_2, BPF_REG_1, test->field_offset),
			BPF_MOV64_IMM(BPF_REG_0, 0),
			BPF_EXIT_INSN(),
		};
		char *reg_map[][2] = {
			{ "$ctx", "r1" },
			{ "$dst", "r2" },
			{}
		};

		pinfo.prog_kind = "LDX";
		pinfo.prog = ldx_prog;
		pinfo.prog_len = ARRAY_SIZE(ldx_prog);
		match_program(btf, &pinfo, test->read, reg_map, false);
	}

	if (test->write || test->write_st || test->write_stx) {
		struct bpf_insn stx_prog[] = {
			BPF_MOV64_IMM(BPF_REG_2, 0),
			BPF_STX_MEM(bpf_sz, BPF_REG_1, BPF_REG_2, test->field_offset),
			BPF_MOV64_IMM(BPF_REG_0, 0),
			BPF_EXIT_INSN(),
		};
		char *stx_reg_map[][2] = {
			{ "$ctx", "r1" },
			{ "$src", "r2" },
			{}
		};
		struct bpf_insn st_prog[] = {
			BPF_ST_MEM(bpf_sz, BPF_REG_1, test->field_offset,
				   test->st_value.use ? test->st_value.value : 42),
			BPF_MOV64_IMM(BPF_REG_0, 0),
			BPF_EXIT_INSN(),
		};
		char *st_reg_map[][2] = {
			{ "$ctx", "r1" },
			{ "$src", "42" },
			{}
		};

		if (test->write || test->write_stx) {
			char *pattern = test->write_stx ? test->write_stx : test->write;

			pinfo.prog_kind = "STX";
			pinfo.prog = stx_prog;
			pinfo.prog_len = ARRAY_SIZE(stx_prog);
			match_program(btf, &pinfo, pattern, stx_reg_map, true);
		}

		if (test->write || test->write_st) {
			char *pattern = test->write_st ? test->write_st : test->write;

			pinfo.prog_kind = "ST";
			pinfo.prog = st_prog;
			pinfo.prog_len = ARRAY_SIZE(st_prog);
			match_program(btf, &pinfo, pattern, st_reg_map, false);
		}
	}

	test__end_subtest();
}

void test_ctx_rewrite(void)
{
	struct btf *btf;
	int i;

	field_regex = compile_regex("^([[:alpha:]_][[:alnum:]_]+)::([[:alpha:]_][[:alnum:]_]+)");
	ident_regex = compile_regex("^[[:alpha:]_][[:alnum:]_]+");
	if (!field_regex || !ident_regex)
		return;

	btf = btf__load_vmlinux_btf();
	if (!btf) {
		PRINT_FAIL("Can't load vmlinux BTF, errno %d (%s)\n", errno, strerror(errno));
		goto out;
	}

	for (i = 0; i < ARRAY_SIZE(test_cases); ++i)
		run_one_testcase(btf, &test_cases[i]);

out:
	btf__free(btf);
	free_regex(field_regex);
	free_regex(ident_regex);
}
