133574905SAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0
233574905SAndrii Nakryiko // Copyright (c) 2020 Facebook
333574905SAndrii Nakryiko 
433574905SAndrii Nakryiko #include <linux/bpf.h>
533574905SAndrii Nakryiko #include <stdint.h>
633574905SAndrii Nakryiko #include <stdbool.h>
733574905SAndrii Nakryiko #include <bpf/bpf_helpers.h>
833574905SAndrii Nakryiko #include <bpf/bpf_core_read.h>
933574905SAndrii Nakryiko 
1033574905SAndrii Nakryiko char _license[] SEC("license") = "GPL";
1133574905SAndrii Nakryiko 
1233574905SAndrii Nakryiko struct {
1333574905SAndrii Nakryiko 	char in[256];
1433574905SAndrii Nakryiko 	char out[256];
1533574905SAndrii Nakryiko 	bool skip;
1633574905SAndrii Nakryiko } data = {};
1733574905SAndrii Nakryiko 
1833574905SAndrii Nakryiko enum named_enum {
1933574905SAndrii Nakryiko 	NAMED_ENUM_VAL1 = 1,
2033574905SAndrii Nakryiko 	NAMED_ENUM_VAL2 = 2,
2133574905SAndrii Nakryiko 	NAMED_ENUM_VAL3 = 3,
2233574905SAndrii Nakryiko };
2333574905SAndrii Nakryiko 
2433574905SAndrii Nakryiko typedef enum {
2533574905SAndrii Nakryiko 	ANON_ENUM_VAL1 = 0x10,
2633574905SAndrii Nakryiko 	ANON_ENUM_VAL2 = 0x20,
2733574905SAndrii Nakryiko 	ANON_ENUM_VAL3 = 0x30,
2833574905SAndrii Nakryiko } anon_enum;
2933574905SAndrii Nakryiko 
3033574905SAndrii Nakryiko struct core_reloc_enumval_output {
3133574905SAndrii Nakryiko 	bool named_val1_exists;
3233574905SAndrii Nakryiko 	bool named_val2_exists;
3333574905SAndrii Nakryiko 	bool named_val3_exists;
3433574905SAndrii Nakryiko 	bool anon_val1_exists;
3533574905SAndrii Nakryiko 	bool anon_val2_exists;
3633574905SAndrii Nakryiko 	bool anon_val3_exists;
3733574905SAndrii Nakryiko 
3833574905SAndrii Nakryiko 	int named_val1;
3933574905SAndrii Nakryiko 	int named_val2;
4033574905SAndrii Nakryiko 	int anon_val1;
4133574905SAndrii Nakryiko 	int anon_val2;
4233574905SAndrii Nakryiko };
4333574905SAndrii Nakryiko 
4433574905SAndrii Nakryiko SEC("raw_tracepoint/sys_enter")
test_core_enumval(void * ctx)4533574905SAndrii Nakryiko int test_core_enumval(void *ctx)
4633574905SAndrii Nakryiko {
4733574905SAndrii Nakryiko #if __has_builtin(__builtin_preserve_enum_value)
4833574905SAndrii Nakryiko 	struct core_reloc_enumval_output *out = (void *)&data.out;
4933574905SAndrii Nakryiko 	enum named_enum named = 0;
5033574905SAndrii Nakryiko 	anon_enum anon = 0;
5133574905SAndrii Nakryiko 
5233574905SAndrii Nakryiko 	out->named_val1_exists = bpf_core_enum_value_exists(named, NAMED_ENUM_VAL1);
5333574905SAndrii Nakryiko 	out->named_val2_exists = bpf_core_enum_value_exists(enum named_enum, NAMED_ENUM_VAL2);
5433574905SAndrii Nakryiko 	out->named_val3_exists = bpf_core_enum_value_exists(enum named_enum, NAMED_ENUM_VAL3);
5533574905SAndrii Nakryiko 
5633574905SAndrii Nakryiko 	out->anon_val1_exists = bpf_core_enum_value_exists(anon, ANON_ENUM_VAL1);
5733574905SAndrii Nakryiko 	out->anon_val2_exists = bpf_core_enum_value_exists(anon_enum, ANON_ENUM_VAL2);
5833574905SAndrii Nakryiko 	out->anon_val3_exists = bpf_core_enum_value_exists(anon_enum, ANON_ENUM_VAL3);
5933574905SAndrii Nakryiko 
6033574905SAndrii Nakryiko 	out->named_val1 = bpf_core_enum_value(named, NAMED_ENUM_VAL1);
6133574905SAndrii Nakryiko 	out->named_val2 = bpf_core_enum_value(named, NAMED_ENUM_VAL2);
6233574905SAndrii Nakryiko 	/* NAMED_ENUM_VAL3 value is optional */
6333574905SAndrii Nakryiko 
6433574905SAndrii Nakryiko 	out->anon_val1 = bpf_core_enum_value(anon, ANON_ENUM_VAL1);
6533574905SAndrii Nakryiko 	out->anon_val2 = bpf_core_enum_value(anon, ANON_ENUM_VAL2);
6633574905SAndrii Nakryiko 	/* ANON_ENUM_VAL3 value is optional */
6733574905SAndrii Nakryiko #else
6833574905SAndrii Nakryiko 	data.skip = true;
6933574905SAndrii Nakryiko #endif
7033574905SAndrii Nakryiko 
7133574905SAndrii Nakryiko 	return 0;
7233574905SAndrii Nakryiko }
73