// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Facebook */
#define _GNU_SOURCE
#include <string.h>
#include <byteswap.h>
#include <test_progs.h>
#include <bpf/btf.h>

void test_btf_endian() {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
	enum btf_endianness endian = BTF_LITTLE_ENDIAN;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
	enum btf_endianness endian = BTF_BIG_ENDIAN;
#else
#error "Unrecognized __BYTE_ORDER__"
#endif
	enum btf_endianness swap_endian = 1 - endian;
	struct btf *btf = NULL, *swap_btf = NULL;
	const void *raw_data, *swap_raw_data;
	const struct btf_type *t;
	const struct btf_header *hdr;
	__u32 raw_sz, swap_raw_sz;
	int var_id;

	/* Load BTF in native endianness */
	btf = btf__parse_elf("btf_dump_test_case_syntax.bpf.o", NULL);
	if (!ASSERT_OK_PTR(btf, "parse_native_btf"))
		goto err_out;

	ASSERT_EQ(btf__endianness(btf), endian, "endian");
	btf__set_endianness(btf, swap_endian);
	ASSERT_EQ(btf__endianness(btf), swap_endian, "endian");

	/* Get raw BTF data in non-native endianness... */
	raw_data = btf__raw_data(btf, &raw_sz);
	if (!ASSERT_OK_PTR(raw_data, "raw_data_inverted"))
		goto err_out;

	/* ...and open it as a new BTF instance */
	swap_btf = btf__new(raw_data, raw_sz);
	if (!ASSERT_OK_PTR(swap_btf, "parse_swap_btf"))
		goto err_out;

	ASSERT_EQ(btf__endianness(swap_btf), swap_endian, "endian");
	ASSERT_EQ(btf__type_cnt(swap_btf), btf__type_cnt(btf), "nr_types");

	swap_raw_data = btf__raw_data(swap_btf, &swap_raw_sz);
	if (!ASSERT_OK_PTR(swap_raw_data, "swap_raw_data"))
		goto err_out;

	/* both raw data should be identical (with non-native endianness) */
	ASSERT_OK(memcmp(raw_data, swap_raw_data, raw_sz), "mem_identical");

	/* make sure that at least BTF header data is really swapped */
	hdr = swap_raw_data;
	ASSERT_EQ(bswap_16(hdr->magic), BTF_MAGIC, "btf_magic_swapped");
	ASSERT_EQ(raw_sz, swap_raw_sz, "raw_sizes");

	/* swap it back to native endianness */
	btf__set_endianness(swap_btf, endian);
	swap_raw_data = btf__raw_data(swap_btf, &swap_raw_sz);
	if (!ASSERT_OK_PTR(swap_raw_data, "swap_raw_data"))
		goto err_out;

	/* now header should have native BTF_MAGIC */
	hdr = swap_raw_data;
	ASSERT_EQ(hdr->magic, BTF_MAGIC, "btf_magic_native");
	ASSERT_EQ(raw_sz, swap_raw_sz, "raw_sizes");

	/* now modify original BTF */
	var_id = btf__add_var(btf, "some_var", BTF_VAR_GLOBAL_ALLOCATED, 1);
	ASSERT_GT(var_id, 0, "var_id");

	btf__free(swap_btf);
	swap_btf = NULL;

	btf__set_endianness(btf, swap_endian);
	raw_data = btf__raw_data(btf, &raw_sz);
	if (!ASSERT_OK_PTR(raw_data, "raw_data_inverted"))
		goto err_out;

	/* and re-open swapped raw data again */
	swap_btf = btf__new(raw_data, raw_sz);
	if (!ASSERT_OK_PTR(swap_btf, "parse_swap_btf"))
		goto err_out;

	ASSERT_EQ(btf__endianness(swap_btf), swap_endian, "endian");
	ASSERT_EQ(btf__type_cnt(swap_btf), btf__type_cnt(btf), "nr_types");

	/* the type should appear as if it was stored in native endianness */
	t = btf__type_by_id(swap_btf, var_id);
	ASSERT_STREQ(btf__str_by_offset(swap_btf, t->name_off), "some_var", "var_name");
	ASSERT_EQ(btf_var(t)->linkage, BTF_VAR_GLOBAL_ALLOCATED, "var_linkage");
	ASSERT_EQ(t->type, 1, "var_type");

err_out:
	btf__free(btf);
	btf__free(swap_btf);
}
