// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2024, Oracle and/or its affiliates. */

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#ifdef __KERNEL__
#include <linux/bpf.h>
#include <linux/bsearch.h>
#include <linux/btf.h>
#include <linux/sort.h>
#include <linux/string.h>
#include <linux/bpf_verifier.h>

#define btf_type_by_id				(struct btf_type *)btf_type_by_id
#define btf__type_cnt				btf_nr_types
#define btf__base_btf				btf_base_btf
#define btf__name_by_offset			btf_name_by_offset
#define btf__str_by_offset			btf_str_by_offset
#define btf_kflag				btf_type_kflag

#define calloc(nmemb, sz)			kvcalloc(nmemb, sz, GFP_KERNEL | __GFP_NOWARN)
#define free(ptr)				kvfree(ptr)
#define qsort(base, num, sz, cmp)		sort(base, num, sz, cmp, NULL)

#else

#include "btf.h"
#include "bpf.h"
#include "libbpf.h"
#include "libbpf_internal.h"

#endif /* __KERNEL__ */

struct btf;

struct btf_relocate {
	struct btf *btf;
	const struct btf *base_btf;
	const struct btf *dist_base_btf;
	unsigned int nr_base_types;
	unsigned int nr_split_types;
	unsigned int nr_dist_base_types;
	int dist_str_len;
	int base_str_len;
	__u32 *id_map;
	__u32 *str_map;
};

/* Set temporarily in relocation id_map if distilled base struct/union is
 * embedded in a split BTF struct/union; in such a case, size information must
 * match between distilled base BTF and base BTF representation of type.
 */
#define BTF_IS_EMBEDDED ((__u32)-1)

/* <name, size, id> triple used in sorting/searching distilled base BTF. */
struct btf_name_info {
	const char *name;
	/* set when search requires a size match */
	bool needs_size: 1;
	unsigned int size: 31;
	__u32 id;
};

static int btf_relocate_rewrite_type_id(struct btf_relocate *r, __u32 i)
{
	struct btf_type *t = btf_type_by_id(r->btf, i);
	struct btf_field_iter it;
	__u32 *id;
	int err;

	err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS);
	if (err)
		return err;

	while ((id = btf_field_iter_next(&it)))
		*id = r->id_map[*id];
	return 0;
}

/* Simple string comparison used for sorting within BTF, since all distilled
 * types are named.  If strings match, and size is non-zero for both elements
 * fall back to using size for ordering.
 */
static int cmp_btf_name_size(const void *n1, const void *n2)
{
	const struct btf_name_info *ni1 = n1;
	const struct btf_name_info *ni2 = n2;
	int name_diff = strcmp(ni1->name, ni2->name);

	if (!name_diff && ni1->needs_size && ni2->needs_size)
		return ni2->size - ni1->size;
	return name_diff;
}

/* Binary search with a small twist; find leftmost element that matches
 * so that we can then iterate through all exact matches.  So for example
 * searching { "a", "bb", "bb", "c" }  we would always match on the
 * leftmost "bb".
 */
static struct btf_name_info *search_btf_name_size(struct btf_name_info *key,
						  struct btf_name_info *vals,
						  int nelems)
{
	struct btf_name_info *ret = NULL;
	int high = nelems - 1;
	int low = 0;

	while (low <= high) {
		int mid = (low + high)/2;
		struct btf_name_info *val = &vals[mid];
		int diff = cmp_btf_name_size(key, val);

		if (diff == 0)
			ret = val;
		/* even if found, keep searching for leftmost match */
		if (diff <= 0)
			high = mid - 1;
		else
			low = mid + 1;
	}
	return ret;
}

/* If a member of a split BTF struct/union refers to a base BTF
 * struct/union, mark that struct/union id temporarily in the id_map
 * with BTF_IS_EMBEDDED.  Members can be const/restrict/volatile/typedef
 * reference types, but if a pointer is encountered, the type is no longer
 * considered embedded.
 */
static int btf_mark_embedded_composite_type_ids(struct btf_relocate *r, __u32 i)
{
	struct btf_type *t = btf_type_by_id(r->btf, i);
	struct btf_field_iter it;
	__u32 *id;
	int err;

	if (!btf_is_composite(t))
		return 0;

	err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS);
	if (err)
		return err;

	while ((id = btf_field_iter_next(&it))) {
		__u32 next_id = *id;

		while (next_id) {
			t = btf_type_by_id(r->btf, next_id);
			switch (btf_kind(t)) {
			case BTF_KIND_CONST:
			case BTF_KIND_RESTRICT:
			case BTF_KIND_VOLATILE:
			case BTF_KIND_TYPEDEF:
			case BTF_KIND_TYPE_TAG:
				next_id = t->type;
				break;
			case BTF_KIND_ARRAY: {
				struct btf_array *a = btf_array(t);

				next_id = a->type;
				break;
			}
			case BTF_KIND_STRUCT:
			case BTF_KIND_UNION:
				if (next_id < r->nr_dist_base_types)
					r->id_map[next_id] = BTF_IS_EMBEDDED;
				next_id = 0;
				break;
			default:
				next_id = 0;
				break;
			}
		}
	}

	return 0;
}

/* Build a map from distilled base BTF ids to base BTF ids. To do so, iterate
 * through base BTF looking up distilled type (using binary search) equivalents.
 */
static int btf_relocate_map_distilled_base(struct btf_relocate *r)
{
	struct btf_name_info *info, *info_end;
	struct btf_type *base_t, *dist_t;
	__u8 *base_name_cnt = NULL;
	int err = 0;
	__u32 id;

	/* generate a sort index array of name/type ids sorted by name for
	 * distilled base BTF to speed name-based lookups.
	 */
	info = calloc(r->nr_dist_base_types, sizeof(*info));
	if (!info) {
		err = -ENOMEM;
		goto done;
	}
	info_end = info + r->nr_dist_base_types;
	for (id = 0; id < r->nr_dist_base_types; id++) {
		dist_t = btf_type_by_id(r->dist_base_btf, id);
		info[id].name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off);
		info[id].id = id;
		info[id].size = dist_t->size;
		info[id].needs_size = true;
	}
	qsort(info, r->nr_dist_base_types, sizeof(*info), cmp_btf_name_size);

	/* Mark distilled base struct/union members of split BTF structs/unions
	 * in id_map with BTF_IS_EMBEDDED; this signals that these types
	 * need to match both name and size, otherwise embedding the base
	 * struct/union in the split type is invalid.
	 */
	for (id = r->nr_dist_base_types; id < r->nr_split_types; id++) {
		err = btf_mark_embedded_composite_type_ids(r, id);
		if (err)
			goto done;
	}

	/* Collect name counts for composite types in base BTF.  If multiple
	 * instances of a struct/union of the same name exist, we need to use
	 * size to determine which to map to since name alone is ambiguous.
	 */
	base_name_cnt = calloc(r->base_str_len, sizeof(*base_name_cnt));
	if (!base_name_cnt) {
		err = -ENOMEM;
		goto done;
	}
	for (id = 1; id < r->nr_base_types; id++) {
		base_t = btf_type_by_id(r->base_btf, id);
		if (!btf_is_composite(base_t) || !base_t->name_off)
			continue;
		if (base_name_cnt[base_t->name_off] < 255)
			base_name_cnt[base_t->name_off]++;
	}

	/* Now search base BTF for matching distilled base BTF types. */
	for (id = 1; id < r->nr_base_types; id++) {
		struct btf_name_info *dist_info, base_info = {};
		int dist_kind, base_kind;

		base_t = btf_type_by_id(r->base_btf, id);
		/* distilled base consists of named types only. */
		if (!base_t->name_off)
			continue;
		base_kind = btf_kind(base_t);
		base_info.id = id;
		base_info.name = btf__name_by_offset(r->base_btf, base_t->name_off);
		switch (base_kind) {
		case BTF_KIND_INT:
		case BTF_KIND_FLOAT:
		case BTF_KIND_ENUM:
		case BTF_KIND_ENUM64:
			/* These types should match both name and size */
			base_info.needs_size = true;
			base_info.size = base_t->size;
			break;
		case BTF_KIND_FWD:
			/* No size considerations for fwds. */
			break;
		case BTF_KIND_STRUCT:
		case BTF_KIND_UNION:
			/* Size only needs to be used for struct/union if there
			 * are multiple types in base BTF with the same name.
			 * If there are multiple _distilled_ types with the same
			 * name (a very unlikely scenario), that doesn't matter
			 * unless corresponding _base_ types to match them are
			 * missing.
			 */
			base_info.needs_size = base_name_cnt[base_t->name_off] > 1;
			base_info.size = base_t->size;
			break;
		default:
			continue;
		}
		/* iterate over all matching distilled base types */
		for (dist_info = search_btf_name_size(&base_info, info, r->nr_dist_base_types);
		     dist_info != NULL && dist_info < info_end &&
		     cmp_btf_name_size(&base_info, dist_info) == 0;
		     dist_info++) {
			if (!dist_info->id || dist_info->id >= r->nr_dist_base_types) {
				pr_warn("base BTF id [%d] maps to invalid distilled base BTF id [%d]\n",
					id, dist_info->id);
				err = -EINVAL;
				goto done;
			}
			dist_t = btf_type_by_id(r->dist_base_btf, dist_info->id);
			dist_kind = btf_kind(dist_t);

			/* Validate that the found distilled type is compatible.
			 * Do not error out on mismatch as another match may
			 * occur for an identically-named type.
			 */
			switch (dist_kind) {
			case BTF_KIND_FWD:
				switch (base_kind) {
				case BTF_KIND_FWD:
					if (btf_kflag(dist_t) != btf_kflag(base_t))
						continue;
					break;
				case BTF_KIND_STRUCT:
					if (btf_kflag(base_t))
						continue;
					break;
				case BTF_KIND_UNION:
					if (!btf_kflag(base_t))
						continue;
					break;
				default:
					continue;
				}
				break;
			case BTF_KIND_INT:
				if (dist_kind != base_kind ||
				    btf_int_encoding(base_t) != btf_int_encoding(dist_t))
					continue;
				break;
			case BTF_KIND_FLOAT:
				if (dist_kind != base_kind)
					continue;
				break;
			case BTF_KIND_ENUM:
				/* ENUM and ENUM64 are encoded as sized ENUM in
				 * distilled base BTF.
				 */
				if (base_kind != dist_kind && base_kind != BTF_KIND_ENUM64)
					continue;
				break;
			case BTF_KIND_STRUCT:
			case BTF_KIND_UNION:
				/* size verification is required for embedded
				 * struct/unions.
				 */
				if (r->id_map[dist_info->id] == BTF_IS_EMBEDDED &&
				    base_t->size != dist_t->size)
					continue;
				break;
			default:
				continue;
			}
			if (r->id_map[dist_info->id] &&
			    r->id_map[dist_info->id] != BTF_IS_EMBEDDED) {
				/* we already have a match; this tells us that
				 * multiple base types of the same name
				 * have the same size, since for cases where
				 * multiple types have the same name we match
				 * on name and size.  In this case, we have
				 * no way of determining which to relocate
				 * to in base BTF, so error out.
				 */
				pr_warn("distilled base BTF type '%s' [%u], size %u has multiple candidates of the same size (ids [%u, %u]) in base BTF\n",
					base_info.name, dist_info->id,
					base_t->size, id, r->id_map[dist_info->id]);
				err = -EINVAL;
				goto done;
			}
			/* map id and name */
			r->id_map[dist_info->id] = id;
			r->str_map[dist_t->name_off] = base_t->name_off;
		}
	}
	/* ensure all distilled BTF ids now have a mapping... */
	for (id = 1; id < r->nr_dist_base_types; id++) {
		const char *name;

		if (r->id_map[id] && r->id_map[id] != BTF_IS_EMBEDDED)
			continue;
		dist_t = btf_type_by_id(r->dist_base_btf, id);
		name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off);
		pr_warn("distilled base BTF type '%s' [%d] is not mapped to base BTF id\n",
			name, id);
		err = -EINVAL;
		break;
	}
done:
	free(base_name_cnt);
	free(info);
	return err;
}

/* distilled base should only have named int/float/enum/fwd/struct/union types. */
static int btf_relocate_validate_distilled_base(struct btf_relocate *r)
{
	unsigned int i;

	for (i = 1; i < r->nr_dist_base_types; i++) {
		struct btf_type *t = btf_type_by_id(r->dist_base_btf, i);
		int kind = btf_kind(t);

		switch (kind) {
		case BTF_KIND_INT:
		case BTF_KIND_FLOAT:
		case BTF_KIND_ENUM:
		case BTF_KIND_STRUCT:
		case BTF_KIND_UNION:
		case BTF_KIND_FWD:
			if (t->name_off)
				break;
			pr_warn("type [%d], kind [%d] is invalid for distilled base BTF; it is anonymous\n",
				i, kind);
			return -EINVAL;
		default:
			pr_warn("type [%d] in distilled based BTF has unexpected kind [%d]\n",
				i, kind);
			return -EINVAL;
		}
	}
	return 0;
}

static int btf_relocate_rewrite_strs(struct btf_relocate *r, __u32 i)
{
	struct btf_type *t = btf_type_by_id(r->btf, i);
	struct btf_field_iter it;
	__u32 *str_off;
	int off, err;

	err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS);
	if (err)
		return err;

	while ((str_off = btf_field_iter_next(&it))) {
		if (!*str_off)
			continue;
		if (*str_off >= r->dist_str_len) {
			*str_off += r->base_str_len - r->dist_str_len;
		} else {
			off = r->str_map[*str_off];
			if (!off) {
				pr_warn("string '%s' [offset %u] is not mapped to base BTF",
					btf__str_by_offset(r->btf, off), *str_off);
				return -ENOENT;
			}
			*str_off = off;
		}
	}
	return 0;
}

/* If successful, output of relocation is updated BTF with base BTF pointing
 * at base_btf, and type ids, strings adjusted accordingly.
 */
int btf_relocate(struct btf *btf, const struct btf *base_btf, __u32 **id_map)
{
	unsigned int nr_types = btf__type_cnt(btf);
	const struct btf_header *dist_base_hdr;
	const struct btf_header *base_hdr;
	struct btf_relocate r = {};
	int err = 0;
	__u32 id, i;

	r.dist_base_btf = btf__base_btf(btf);
	if (!base_btf || r.dist_base_btf == base_btf)
		return -EINVAL;

	r.nr_dist_base_types = btf__type_cnt(r.dist_base_btf);
	r.nr_base_types = btf__type_cnt(base_btf);
	r.nr_split_types = nr_types - r.nr_dist_base_types;
	r.btf = btf;
	r.base_btf = base_btf;

	r.id_map = calloc(nr_types, sizeof(*r.id_map));
	r.str_map = calloc(btf_header(r.dist_base_btf)->str_len, sizeof(*r.str_map));
	dist_base_hdr = btf_header(r.dist_base_btf);
	base_hdr = btf_header(r.base_btf);
	r.dist_str_len = dist_base_hdr->str_len;
	r.base_str_len = base_hdr->str_len;
	if (!r.id_map || !r.str_map) {
		err = -ENOMEM;
		goto err_out;
	}

	err = btf_relocate_validate_distilled_base(&r);
	if (err)
		goto err_out;

	/* Split BTF ids need to be adjusted as base and distilled base
	 * have different numbers of types, changing the start id of split
	 * BTF.
	 */
	for (id = r.nr_dist_base_types; id < nr_types; id++)
		r.id_map[id] = id + r.nr_base_types - r.nr_dist_base_types;

	/* Build a map from distilled base ids to actual base BTF ids; it is used
	 * to update split BTF id references.  Also build a str_map mapping from
	 * distilled base BTF names to base BTF names.
	 */
	err = btf_relocate_map_distilled_base(&r);
	if (err)
		goto err_out;

	/* Next, rewrite type ids in split BTF, replacing split ids with updated
	 * ids based on number of types in base BTF, and base ids with
	 * relocated ids from base_btf.
	 */
	for (i = 0, id = r.nr_dist_base_types; i < r.nr_split_types; i++, id++) {
		err = btf_relocate_rewrite_type_id(&r, id);
		if (err)
			goto err_out;
	}
	/* String offsets now need to be updated using the str_map. */
	for (i = 0; i < r.nr_split_types; i++) {
		err = btf_relocate_rewrite_strs(&r, i + r.nr_dist_base_types);
		if (err)
			goto err_out;
	}
	/* Finally reset base BTF to be base_btf */
	btf_set_base_btf(btf, base_btf);

	if (id_map) {
		*id_map = r.id_map;
		r.id_map = NULL;
	}
err_out:
	free(r.id_map);
	free(r.str_map);
	return err;
}
