brintos

brintos / linux-shallow public Read only

0
0
Text · 375.6 KiB · 219facd Raw
14037 lines · c
1// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)2 3/*4 * Common eBPF ELF object loading operations.5 *6 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>7 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>8 * Copyright (C) 2015 Huawei Inc.9 * Copyright (C) 2017 Nicira, Inc.10 * Copyright (C) 2019 Isovalent, Inc.11 */12 13#ifndef _GNU_SOURCE14#define _GNU_SOURCE15#endif16#include <stdlib.h>17#include <stdio.h>18#include <stdarg.h>19#include <libgen.h>20#include <inttypes.h>21#include <limits.h>22#include <string.h>23#include <unistd.h>24#include <endian.h>25#include <fcntl.h>26#include <errno.h>27#include <ctype.h>28#include <asm/unistd.h>29#include <linux/err.h>30#include <linux/kernel.h>31#include <linux/bpf.h>32#include <linux/btf.h>33#include <linux/filter.h>34#include <linux/limits.h>35#include <linux/perf_event.h>36#include <linux/bpf_perf_event.h>37#include <linux/ring_buffer.h>38#include <sys/epoll.h>39#include <sys/ioctl.h>40#include <sys/mman.h>41#include <sys/stat.h>42#include <sys/types.h>43#include <sys/vfs.h>44#include <sys/utsname.h>45#include <sys/resource.h>46#include <libelf.h>47#include <gelf.h>48#include <zlib.h>49 50#include "libbpf.h"51#include "bpf.h"52#include "btf.h"53#include "str_error.h"54#include "libbpf_internal.h"55#include "hashmap.h"56#include "bpf_gen_internal.h"57#include "zip.h"58 59#ifndef BPF_FS_MAGIC60#define BPF_FS_MAGIC		0xcafe4a1161#endif62 63#define BPF_FS_DEFAULT_PATH "/sys/fs/bpf"64 65#define BPF_INSN_SZ (sizeof(struct bpf_insn))66 67/* vsprintf() in __base_pr() uses nonliteral format string. It may break68 * compilation if user enables corresponding warning. Disable it explicitly.69 */70#pragma GCC diagnostic ignored "-Wformat-nonliteral"71 72#define __printf(a, b)	__attribute__((format(printf, a, b)))73 74static struct bpf_map *bpf_object__add_map(struct bpf_object *obj);75static bool prog_is_subprog(const struct bpf_object *obj, const struct bpf_program *prog);76static int map_set_def_max_entries(struct bpf_map *map);77 78static const char * const attach_type_name[] = {79	[BPF_CGROUP_INET_INGRESS]	= "cgroup_inet_ingress",80	[BPF_CGROUP_INET_EGRESS]	= "cgroup_inet_egress",81	[BPF_CGROUP_INET_SOCK_CREATE]	= "cgroup_inet_sock_create",82	[BPF_CGROUP_INET_SOCK_RELEASE]	= "cgroup_inet_sock_release",83	[BPF_CGROUP_SOCK_OPS]		= "cgroup_sock_ops",84	[BPF_CGROUP_DEVICE]		= "cgroup_device",85	[BPF_CGROUP_INET4_BIND]		= "cgroup_inet4_bind",86	[BPF_CGROUP_INET6_BIND]		= "cgroup_inet6_bind",87	[BPF_CGROUP_INET4_CONNECT]	= "cgroup_inet4_connect",88	[BPF_CGROUP_INET6_CONNECT]	= "cgroup_inet6_connect",89	[BPF_CGROUP_UNIX_CONNECT]       = "cgroup_unix_connect",90	[BPF_CGROUP_INET4_POST_BIND]	= "cgroup_inet4_post_bind",91	[BPF_CGROUP_INET6_POST_BIND]	= "cgroup_inet6_post_bind",92	[BPF_CGROUP_INET4_GETPEERNAME]	= "cgroup_inet4_getpeername",93	[BPF_CGROUP_INET6_GETPEERNAME]	= "cgroup_inet6_getpeername",94	[BPF_CGROUP_UNIX_GETPEERNAME]	= "cgroup_unix_getpeername",95	[BPF_CGROUP_INET4_GETSOCKNAME]	= "cgroup_inet4_getsockname",96	[BPF_CGROUP_INET6_GETSOCKNAME]	= "cgroup_inet6_getsockname",97	[BPF_CGROUP_UNIX_GETSOCKNAME]	= "cgroup_unix_getsockname",98	[BPF_CGROUP_UDP4_SENDMSG]	= "cgroup_udp4_sendmsg",99	[BPF_CGROUP_UDP6_SENDMSG]	= "cgroup_udp6_sendmsg",100	[BPF_CGROUP_UNIX_SENDMSG]	= "cgroup_unix_sendmsg",101	[BPF_CGROUP_SYSCTL]		= "cgroup_sysctl",102	[BPF_CGROUP_UDP4_RECVMSG]	= "cgroup_udp4_recvmsg",103	[BPF_CGROUP_UDP6_RECVMSG]	= "cgroup_udp6_recvmsg",104	[BPF_CGROUP_UNIX_RECVMSG]	= "cgroup_unix_recvmsg",105	[BPF_CGROUP_GETSOCKOPT]		= "cgroup_getsockopt",106	[BPF_CGROUP_SETSOCKOPT]		= "cgroup_setsockopt",107	[BPF_SK_SKB_STREAM_PARSER]	= "sk_skb_stream_parser",108	[BPF_SK_SKB_STREAM_VERDICT]	= "sk_skb_stream_verdict",109	[BPF_SK_SKB_VERDICT]		= "sk_skb_verdict",110	[BPF_SK_MSG_VERDICT]		= "sk_msg_verdict",111	[BPF_LIRC_MODE2]		= "lirc_mode2",112	[BPF_FLOW_DISSECTOR]		= "flow_dissector",113	[BPF_TRACE_RAW_TP]		= "trace_raw_tp",114	[BPF_TRACE_FENTRY]		= "trace_fentry",115	[BPF_TRACE_FEXIT]		= "trace_fexit",116	[BPF_MODIFY_RETURN]		= "modify_return",117	[BPF_LSM_MAC]			= "lsm_mac",118	[BPF_LSM_CGROUP]		= "lsm_cgroup",119	[BPF_SK_LOOKUP]			= "sk_lookup",120	[BPF_TRACE_ITER]		= "trace_iter",121	[BPF_XDP_DEVMAP]		= "xdp_devmap",122	[BPF_XDP_CPUMAP]		= "xdp_cpumap",123	[BPF_XDP]			= "xdp",124	[BPF_SK_REUSEPORT_SELECT]	= "sk_reuseport_select",125	[BPF_SK_REUSEPORT_SELECT_OR_MIGRATE]	= "sk_reuseport_select_or_migrate",126	[BPF_PERF_EVENT]		= "perf_event",127	[BPF_TRACE_KPROBE_MULTI]	= "trace_kprobe_multi",128	[BPF_STRUCT_OPS]		= "struct_ops",129	[BPF_NETFILTER]			= "netfilter",130	[BPF_TCX_INGRESS]		= "tcx_ingress",131	[BPF_TCX_EGRESS]		= "tcx_egress",132	[BPF_TRACE_UPROBE_MULTI]	= "trace_uprobe_multi",133	[BPF_NETKIT_PRIMARY]		= "netkit_primary",134	[BPF_NETKIT_PEER]		= "netkit_peer",135	[BPF_TRACE_KPROBE_SESSION]	= "trace_kprobe_session",136};137 138static const char * const link_type_name[] = {139	[BPF_LINK_TYPE_UNSPEC]			= "unspec",140	[BPF_LINK_TYPE_RAW_TRACEPOINT]		= "raw_tracepoint",141	[BPF_LINK_TYPE_TRACING]			= "tracing",142	[BPF_LINK_TYPE_CGROUP]			= "cgroup",143	[BPF_LINK_TYPE_ITER]			= "iter",144	[BPF_LINK_TYPE_NETNS]			= "netns",145	[BPF_LINK_TYPE_XDP]			= "xdp",146	[BPF_LINK_TYPE_PERF_EVENT]		= "perf_event",147	[BPF_LINK_TYPE_KPROBE_MULTI]		= "kprobe_multi",148	[BPF_LINK_TYPE_STRUCT_OPS]		= "struct_ops",149	[BPF_LINK_TYPE_NETFILTER]		= "netfilter",150	[BPF_LINK_TYPE_TCX]			= "tcx",151	[BPF_LINK_TYPE_UPROBE_MULTI]		= "uprobe_multi",152	[BPF_LINK_TYPE_NETKIT]			= "netkit",153	[BPF_LINK_TYPE_SOCKMAP]			= "sockmap",154};155 156static const char * const map_type_name[] = {157	[BPF_MAP_TYPE_UNSPEC]			= "unspec",158	[BPF_MAP_TYPE_HASH]			= "hash",159	[BPF_MAP_TYPE_ARRAY]			= "array",160	[BPF_MAP_TYPE_PROG_ARRAY]		= "prog_array",161	[BPF_MAP_TYPE_PERF_EVENT_ARRAY]		= "perf_event_array",162	[BPF_MAP_TYPE_PERCPU_HASH]		= "percpu_hash",163	[BPF_MAP_TYPE_PERCPU_ARRAY]		= "percpu_array",164	[BPF_MAP_TYPE_STACK_TRACE]		= "stack_trace",165	[BPF_MAP_TYPE_CGROUP_ARRAY]		= "cgroup_array",166	[BPF_MAP_TYPE_LRU_HASH]			= "lru_hash",167	[BPF_MAP_TYPE_LRU_PERCPU_HASH]		= "lru_percpu_hash",168	[BPF_MAP_TYPE_LPM_TRIE]			= "lpm_trie",169	[BPF_MAP_TYPE_ARRAY_OF_MAPS]		= "array_of_maps",170	[BPF_MAP_TYPE_HASH_OF_MAPS]		= "hash_of_maps",171	[BPF_MAP_TYPE_DEVMAP]			= "devmap",172	[BPF_MAP_TYPE_DEVMAP_HASH]		= "devmap_hash",173	[BPF_MAP_TYPE_SOCKMAP]			= "sockmap",174	[BPF_MAP_TYPE_CPUMAP]			= "cpumap",175	[BPF_MAP_TYPE_XSKMAP]			= "xskmap",176	[BPF_MAP_TYPE_SOCKHASH]			= "sockhash",177	[BPF_MAP_TYPE_CGROUP_STORAGE]		= "cgroup_storage",178	[BPF_MAP_TYPE_REUSEPORT_SOCKARRAY]	= "reuseport_sockarray",179	[BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE]	= "percpu_cgroup_storage",180	[BPF_MAP_TYPE_QUEUE]			= "queue",181	[BPF_MAP_TYPE_STACK]			= "stack",182	[BPF_MAP_TYPE_SK_STORAGE]		= "sk_storage",183	[BPF_MAP_TYPE_STRUCT_OPS]		= "struct_ops",184	[BPF_MAP_TYPE_RINGBUF]			= "ringbuf",185	[BPF_MAP_TYPE_INODE_STORAGE]		= "inode_storage",186	[BPF_MAP_TYPE_TASK_STORAGE]		= "task_storage",187	[BPF_MAP_TYPE_BLOOM_FILTER]		= "bloom_filter",188	[BPF_MAP_TYPE_USER_RINGBUF]             = "user_ringbuf",189	[BPF_MAP_TYPE_CGRP_STORAGE]		= "cgrp_storage",190	[BPF_MAP_TYPE_ARENA]			= "arena",191};192 193static const char * const prog_type_name[] = {194	[BPF_PROG_TYPE_UNSPEC]			= "unspec",195	[BPF_PROG_TYPE_SOCKET_FILTER]		= "socket_filter",196	[BPF_PROG_TYPE_KPROBE]			= "kprobe",197	[BPF_PROG_TYPE_SCHED_CLS]		= "sched_cls",198	[BPF_PROG_TYPE_SCHED_ACT]		= "sched_act",199	[BPF_PROG_TYPE_TRACEPOINT]		= "tracepoint",200	[BPF_PROG_TYPE_XDP]			= "xdp",201	[BPF_PROG_TYPE_PERF_EVENT]		= "perf_event",202	[BPF_PROG_TYPE_CGROUP_SKB]		= "cgroup_skb",203	[BPF_PROG_TYPE_CGROUP_SOCK]		= "cgroup_sock",204	[BPF_PROG_TYPE_LWT_IN]			= "lwt_in",205	[BPF_PROG_TYPE_LWT_OUT]			= "lwt_out",206	[BPF_PROG_TYPE_LWT_XMIT]		= "lwt_xmit",207	[BPF_PROG_TYPE_SOCK_OPS]		= "sock_ops",208	[BPF_PROG_TYPE_SK_SKB]			= "sk_skb",209	[BPF_PROG_TYPE_CGROUP_DEVICE]		= "cgroup_device",210	[BPF_PROG_TYPE_SK_MSG]			= "sk_msg",211	[BPF_PROG_TYPE_RAW_TRACEPOINT]		= "raw_tracepoint",212	[BPF_PROG_TYPE_CGROUP_SOCK_ADDR]	= "cgroup_sock_addr",213	[BPF_PROG_TYPE_LWT_SEG6LOCAL]		= "lwt_seg6local",214	[BPF_PROG_TYPE_LIRC_MODE2]		= "lirc_mode2",215	[BPF_PROG_TYPE_SK_REUSEPORT]		= "sk_reuseport",216	[BPF_PROG_TYPE_FLOW_DISSECTOR]		= "flow_dissector",217	[BPF_PROG_TYPE_CGROUP_SYSCTL]		= "cgroup_sysctl",218	[BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE]	= "raw_tracepoint_writable",219	[BPF_PROG_TYPE_CGROUP_SOCKOPT]		= "cgroup_sockopt",220	[BPF_PROG_TYPE_TRACING]			= "tracing",221	[BPF_PROG_TYPE_STRUCT_OPS]		= "struct_ops",222	[BPF_PROG_TYPE_EXT]			= "ext",223	[BPF_PROG_TYPE_LSM]			= "lsm",224	[BPF_PROG_TYPE_SK_LOOKUP]		= "sk_lookup",225	[BPF_PROG_TYPE_SYSCALL]			= "syscall",226	[BPF_PROG_TYPE_NETFILTER]		= "netfilter",227};228 229static int __base_pr(enum libbpf_print_level level, const char *format,230		     va_list args)231{232	const char *env_var = "LIBBPF_LOG_LEVEL";233	static enum libbpf_print_level min_level = LIBBPF_INFO;234	static bool initialized;235 236	if (!initialized) {237		char *verbosity;238 239		initialized = true;240		verbosity = getenv(env_var);241		if (verbosity) {242			if (strcasecmp(verbosity, "warn") == 0)243				min_level = LIBBPF_WARN;244			else if (strcasecmp(verbosity, "debug") == 0)245				min_level = LIBBPF_DEBUG;246			else if (strcasecmp(verbosity, "info") == 0)247				min_level = LIBBPF_INFO;248			else249				fprintf(stderr, "libbpf: unrecognized '%s' envvar value: '%s', should be one of 'warn', 'debug', or 'info'.\n",250					env_var, verbosity);251		}252	}253 254	/* if too verbose, skip logging  */255	if (level > min_level)256		return 0;257 258	return vfprintf(stderr, format, args);259}260 261static libbpf_print_fn_t __libbpf_pr = __base_pr;262 263libbpf_print_fn_t libbpf_set_print(libbpf_print_fn_t fn)264{265	libbpf_print_fn_t old_print_fn;266 267	old_print_fn = __atomic_exchange_n(&__libbpf_pr, fn, __ATOMIC_RELAXED);268 269	return old_print_fn;270}271 272__printf(2, 3)273void libbpf_print(enum libbpf_print_level level, const char *format, ...)274{275	va_list args;276	int old_errno;277	libbpf_print_fn_t print_fn;278 279	print_fn = __atomic_load_n(&__libbpf_pr, __ATOMIC_RELAXED);280	if (!print_fn)281		return;282 283	old_errno = errno;284 285	va_start(args, format);286	__libbpf_pr(level, format, args);287	va_end(args);288 289	errno = old_errno;290}291 292static void pr_perm_msg(int err)293{294	struct rlimit limit;295	char buf[100];296 297	if (err != -EPERM || geteuid() != 0)298		return;299 300	err = getrlimit(RLIMIT_MEMLOCK, &limit);301	if (err)302		return;303 304	if (limit.rlim_cur == RLIM_INFINITY)305		return;306 307	if (limit.rlim_cur < 1024)308		snprintf(buf, sizeof(buf), "%zu bytes", (size_t)limit.rlim_cur);309	else if (limit.rlim_cur < 1024*1024)310		snprintf(buf, sizeof(buf), "%.1f KiB", (double)limit.rlim_cur / 1024);311	else312		snprintf(buf, sizeof(buf), "%.1f MiB", (double)limit.rlim_cur / (1024*1024));313 314	pr_warn("permission error while running as root; try raising 'ulimit -l'? current value: %s\n",315		buf);316}317 318#define STRERR_BUFSIZE  128319 320/* Copied from tools/perf/util/util.h */321#ifndef zfree322# define zfree(ptr) ({ free(*ptr); *ptr = NULL; })323#endif324 325#ifndef zclose326# define zclose(fd) ({			\327	int ___err = 0;			\328	if ((fd) >= 0)			\329		___err = close((fd));	\330	fd = -1;			\331	___err; })332#endif333 334static inline __u64 ptr_to_u64(const void *ptr)335{336	return (__u64) (unsigned long) ptr;337}338 339int libbpf_set_strict_mode(enum libbpf_strict_mode mode)340{341	/* as of v1.0 libbpf_set_strict_mode() is a no-op */342	return 0;343}344 345__u32 libbpf_major_version(void)346{347	return LIBBPF_MAJOR_VERSION;348}349 350__u32 libbpf_minor_version(void)351{352	return LIBBPF_MINOR_VERSION;353}354 355const char *libbpf_version_string(void)356{357#define __S(X) #X358#define _S(X) __S(X)359	return  "v" _S(LIBBPF_MAJOR_VERSION) "." _S(LIBBPF_MINOR_VERSION);360#undef _S361#undef __S362}363 364enum reloc_type {365	RELO_LD64,366	RELO_CALL,367	RELO_DATA,368	RELO_EXTERN_LD64,369	RELO_EXTERN_CALL,370	RELO_SUBPROG_ADDR,371	RELO_CORE,372};373 374struct reloc_desc {375	enum reloc_type type;376	int insn_idx;377	union {378		const struct bpf_core_relo *core_relo; /* used when type == RELO_CORE */379		struct {380			int map_idx;381			int sym_off;382			int ext_idx;383		};384	};385};386 387/* stored as sec_def->cookie for all libbpf-supported SEC()s */388enum sec_def_flags {389	SEC_NONE = 0,390	/* expected_attach_type is optional, if kernel doesn't support that */391	SEC_EXP_ATTACH_OPT = 1,392	/* legacy, only used by libbpf_get_type_names() and393	 * libbpf_attach_type_by_name(), not used by libbpf itself at all.394	 * This used to be associated with cgroup (and few other) BPF programs395	 * that were attachable through BPF_PROG_ATTACH command. Pretty396	 * meaningless nowadays, though.397	 */398	SEC_ATTACHABLE = 2,399	SEC_ATTACHABLE_OPT = SEC_ATTACHABLE | SEC_EXP_ATTACH_OPT,400	/* attachment target is specified through BTF ID in either kernel or401	 * other BPF program's BTF object402	 */403	SEC_ATTACH_BTF = 4,404	/* BPF program type allows sleeping/blocking in kernel */405	SEC_SLEEPABLE = 8,406	/* BPF program support non-linear XDP buffer */407	SEC_XDP_FRAGS = 16,408	/* Setup proper attach type for usdt probes. */409	SEC_USDT = 32,410};411 412struct bpf_sec_def {413	char *sec;414	enum bpf_prog_type prog_type;415	enum bpf_attach_type expected_attach_type;416	long cookie;417	int handler_id;418 419	libbpf_prog_setup_fn_t prog_setup_fn;420	libbpf_prog_prepare_load_fn_t prog_prepare_load_fn;421	libbpf_prog_attach_fn_t prog_attach_fn;422};423 424/*425 * bpf_prog should be a better name but it has been used in426 * linux/filter.h.427 */428struct bpf_program {429	char *name;430	char *sec_name;431	size_t sec_idx;432	const struct bpf_sec_def *sec_def;433	/* this program's instruction offset (in number of instructions)434	 * within its containing ELF section435	 */436	size_t sec_insn_off;437	/* number of original instructions in ELF section belonging to this438	 * program, not taking into account subprogram instructions possible439	 * appended later during relocation440	 */441	size_t sec_insn_cnt;442	/* Offset (in number of instructions) of the start of instruction443	 * belonging to this BPF program  within its containing main BPF444	 * program. For the entry-point (main) BPF program, this is always445	 * zero. For a sub-program, this gets reset before each of main BPF446	 * programs are processed and relocated and is used to determined447	 * whether sub-program was already appended to the main program, and448	 * if yes, at which instruction offset.449	 */450	size_t sub_insn_off;451 452	/* instructions that belong to BPF program; insns[0] is located at453	 * sec_insn_off instruction within its ELF section in ELF file, so454	 * when mapping ELF file instruction index to the local instruction,455	 * one needs to subtract sec_insn_off; and vice versa.456	 */457	struct bpf_insn *insns;458	/* actual number of instruction in this BPF program's image; for459	 * entry-point BPF programs this includes the size of main program460	 * itself plus all the used sub-programs, appended at the end461	 */462	size_t insns_cnt;463 464	struct reloc_desc *reloc_desc;465	int nr_reloc;466 467	/* BPF verifier log settings */468	char *log_buf;469	size_t log_size;470	__u32 log_level;471 472	struct bpf_object *obj;473 474	int fd;475	bool autoload;476	bool autoattach;477	bool sym_global;478	bool mark_btf_static;479	enum bpf_prog_type type;480	enum bpf_attach_type expected_attach_type;481	int exception_cb_idx;482 483	int prog_ifindex;484	__u32 attach_btf_obj_fd;485	__u32 attach_btf_id;486	__u32 attach_prog_fd;487 488	void *func_info;489	__u32 func_info_rec_size;490	__u32 func_info_cnt;491 492	void *line_info;493	__u32 line_info_rec_size;494	__u32 line_info_cnt;495	__u32 prog_flags;496};497 498struct bpf_struct_ops {499	struct bpf_program **progs;500	__u32 *kern_func_off;501	/* e.g. struct tcp_congestion_ops in bpf_prog's btf format */502	void *data;503	/* e.g. struct bpf_struct_ops_tcp_congestion_ops in504	 *      btf_vmlinux's format.505	 * struct bpf_struct_ops_tcp_congestion_ops {506	 *	[... some other kernel fields ...]507	 *	struct tcp_congestion_ops data;508	 * }509	 * kern_vdata-size == sizeof(struct bpf_struct_ops_tcp_congestion_ops)510	 * bpf_map__init_kern_struct_ops() will populate the "kern_vdata"511	 * from "data".512	 */513	void *kern_vdata;514	__u32 type_id;515};516 517#define DATA_SEC ".data"518#define BSS_SEC ".bss"519#define RODATA_SEC ".rodata"520#define KCONFIG_SEC ".kconfig"521#define KSYMS_SEC ".ksyms"522#define STRUCT_OPS_SEC ".struct_ops"523#define STRUCT_OPS_LINK_SEC ".struct_ops.link"524#define ARENA_SEC ".addr_space.1"525 526enum libbpf_map_type {527	LIBBPF_MAP_UNSPEC,528	LIBBPF_MAP_DATA,529	LIBBPF_MAP_BSS,530	LIBBPF_MAP_RODATA,531	LIBBPF_MAP_KCONFIG,532};533 534struct bpf_map_def {535	unsigned int type;536	unsigned int key_size;537	unsigned int value_size;538	unsigned int max_entries;539	unsigned int map_flags;540};541 542struct bpf_map {543	struct bpf_object *obj;544	char *name;545	/* real_name is defined for special internal maps (.rodata*,546	 * .data*, .bss, .kconfig) and preserves their original ELF section547	 * name. This is important to be able to find corresponding BTF548	 * DATASEC information.549	 */550	char *real_name;551	int fd;552	int sec_idx;553	size_t sec_offset;554	int map_ifindex;555	int inner_map_fd;556	struct bpf_map_def def;557	__u32 numa_node;558	__u32 btf_var_idx;559	int mod_btf_fd;560	__u32 btf_key_type_id;561	__u32 btf_value_type_id;562	__u32 btf_vmlinux_value_type_id;563	enum libbpf_map_type libbpf_type;564	void *mmaped;565	struct bpf_struct_ops *st_ops;566	struct bpf_map *inner_map;567	void **init_slots;568	int init_slots_sz;569	char *pin_path;570	bool pinned;571	bool reused;572	bool autocreate;573	bool autoattach;574	__u64 map_extra;575};576 577enum extern_type {578	EXT_UNKNOWN,579	EXT_KCFG,580	EXT_KSYM,581};582 583enum kcfg_type {584	KCFG_UNKNOWN,585	KCFG_CHAR,586	KCFG_BOOL,587	KCFG_INT,588	KCFG_TRISTATE,589	KCFG_CHAR_ARR,590};591 592struct extern_desc {593	enum extern_type type;594	int sym_idx;595	int btf_id;596	int sec_btf_id;597	const char *name;598	char *essent_name;599	bool is_set;600	bool is_weak;601	union {602		struct {603			enum kcfg_type type;604			int sz;605			int align;606			int data_off;607			bool is_signed;608		} kcfg;609		struct {610			unsigned long long addr;611 612			/* target btf_id of the corresponding kernel var. */613			int kernel_btf_obj_fd;614			int kernel_btf_id;615 616			/* local btf_id of the ksym extern's type. */617			__u32 type_id;618			/* BTF fd index to be patched in for insn->off, this is619			 * 0 for vmlinux BTF, index in obj->fd_array for module620			 * BTF621			 */622			__s16 btf_fd_idx;623		} ksym;624	};625};626 627struct module_btf {628	struct btf *btf;629	char *name;630	__u32 id;631	int fd;632	int fd_array_idx;633};634 635enum sec_type {636	SEC_UNUSED = 0,637	SEC_RELO,638	SEC_BSS,639	SEC_DATA,640	SEC_RODATA,641	SEC_ST_OPS,642};643 644struct elf_sec_desc {645	enum sec_type sec_type;646	Elf64_Shdr *shdr;647	Elf_Data *data;648};649 650struct elf_state {651	int fd;652	const void *obj_buf;653	size_t obj_buf_sz;654	Elf *elf;655	Elf64_Ehdr *ehdr;656	Elf_Data *symbols;657	Elf_Data *arena_data;658	size_t shstrndx; /* section index for section name strings */659	size_t strtabidx;660	struct elf_sec_desc *secs;661	size_t sec_cnt;662	int btf_maps_shndx;663	__u32 btf_maps_sec_btf_id;664	int text_shndx;665	int symbols_shndx;666	bool has_st_ops;667	int arena_data_shndx;668};669 670struct usdt_manager;671 672struct bpf_object {673	char name[BPF_OBJ_NAME_LEN];674	char license[64];675	__u32 kern_version;676 677	struct bpf_program *programs;678	size_t nr_programs;679	struct bpf_map *maps;680	size_t nr_maps;681	size_t maps_cap;682 683	char *kconfig;684	struct extern_desc *externs;685	int nr_extern;686	int kconfig_map_idx;687 688	bool loaded;689	bool has_subcalls;690	bool has_rodata;691 692	struct bpf_gen *gen_loader;693 694	/* Information when doing ELF related work. Only valid if efile.elf is not NULL */695	struct elf_state efile;696 697	struct btf *btf;698	struct btf_ext *btf_ext;699 700	/* Parse and load BTF vmlinux if any of the programs in the object need701	 * it at load time.702	 */703	struct btf *btf_vmlinux;704	/* Path to the custom BTF to be used for BPF CO-RE relocations as an705	 * override for vmlinux BTF.706	 */707	char *btf_custom_path;708	/* vmlinux BTF override for CO-RE relocations */709	struct btf *btf_vmlinux_override;710	/* Lazily initialized kernel module BTFs */711	struct module_btf *btf_modules;712	bool btf_modules_loaded;713	size_t btf_module_cnt;714	size_t btf_module_cap;715 716	/* optional log settings passed to BPF_BTF_LOAD and BPF_PROG_LOAD commands */717	char *log_buf;718	size_t log_size;719	__u32 log_level;720 721	int *fd_array;722	size_t fd_array_cap;723	size_t fd_array_cnt;724 725	struct usdt_manager *usdt_man;726 727	struct bpf_map *arena_map;728	void *arena_data;729	size_t arena_data_sz;730 731	struct kern_feature_cache *feat_cache;732	char *token_path;733	int token_fd;734 735	char path[];736};737 738static const char *elf_sym_str(const struct bpf_object *obj, size_t off);739static const char *elf_sec_str(const struct bpf_object *obj, size_t off);740static Elf_Scn *elf_sec_by_idx(const struct bpf_object *obj, size_t idx);741static Elf_Scn *elf_sec_by_name(const struct bpf_object *obj, const char *name);742static Elf64_Shdr *elf_sec_hdr(const struct bpf_object *obj, Elf_Scn *scn);743static const char *elf_sec_name(const struct bpf_object *obj, Elf_Scn *scn);744static Elf_Data *elf_sec_data(const struct bpf_object *obj, Elf_Scn *scn);745static Elf64_Sym *elf_sym_by_idx(const struct bpf_object *obj, size_t idx);746static Elf64_Rel *elf_rel_by_idx(Elf_Data *data, size_t idx);747 748void bpf_program__unload(struct bpf_program *prog)749{750	if (!prog)751		return;752 753	zclose(prog->fd);754 755	zfree(&prog->func_info);756	zfree(&prog->line_info);757}758 759static void bpf_program__exit(struct bpf_program *prog)760{761	if (!prog)762		return;763 764	bpf_program__unload(prog);765	zfree(&prog->name);766	zfree(&prog->sec_name);767	zfree(&prog->insns);768	zfree(&prog->reloc_desc);769 770	prog->nr_reloc = 0;771	prog->insns_cnt = 0;772	prog->sec_idx = -1;773}774 775static bool insn_is_subprog_call(const struct bpf_insn *insn)776{777	return BPF_CLASS(insn->code) == BPF_JMP &&778	       BPF_OP(insn->code) == BPF_CALL &&779	       BPF_SRC(insn->code) == BPF_K &&780	       insn->src_reg == BPF_PSEUDO_CALL &&781	       insn->dst_reg == 0 &&782	       insn->off == 0;783}784 785static bool is_call_insn(const struct bpf_insn *insn)786{787	return insn->code == (BPF_JMP | BPF_CALL);788}789 790static bool insn_is_pseudo_func(struct bpf_insn *insn)791{792	return is_ldimm64_insn(insn) && insn->src_reg == BPF_PSEUDO_FUNC;793}794 795static int796bpf_object__init_prog(struct bpf_object *obj, struct bpf_program *prog,797		      const char *name, size_t sec_idx, const char *sec_name,798		      size_t sec_off, void *insn_data, size_t insn_data_sz)799{800	if (insn_data_sz == 0 || insn_data_sz % BPF_INSN_SZ || sec_off % BPF_INSN_SZ) {801		pr_warn("sec '%s': corrupted program '%s', offset %zu, size %zu\n",802			sec_name, name, sec_off, insn_data_sz);803		return -EINVAL;804	}805 806	memset(prog, 0, sizeof(*prog));807	prog->obj = obj;808 809	prog->sec_idx = sec_idx;810	prog->sec_insn_off = sec_off / BPF_INSN_SZ;811	prog->sec_insn_cnt = insn_data_sz / BPF_INSN_SZ;812	/* insns_cnt can later be increased by appending used subprograms */813	prog->insns_cnt = prog->sec_insn_cnt;814 815	prog->type = BPF_PROG_TYPE_UNSPEC;816	prog->fd = -1;817	prog->exception_cb_idx = -1;818 819	/* libbpf's convention for SEC("?abc...") is that it's just like820	 * SEC("abc...") but the corresponding bpf_program starts out with821	 * autoload set to false.822	 */823	if (sec_name[0] == '?') {824		prog->autoload = false;825		/* from now on forget there was ? in section name */826		sec_name++;827	} else {828		prog->autoload = true;829	}830 831	prog->autoattach = true;832 833	/* inherit object's log_level */834	prog->log_level = obj->log_level;835 836	prog->sec_name = strdup(sec_name);837	if (!prog->sec_name)838		goto errout;839 840	prog->name = strdup(name);841	if (!prog->name)842		goto errout;843 844	prog->insns = malloc(insn_data_sz);845	if (!prog->insns)846		goto errout;847	memcpy(prog->insns, insn_data, insn_data_sz);848 849	return 0;850errout:851	pr_warn("sec '%s': failed to allocate memory for prog '%s'\n", sec_name, name);852	bpf_program__exit(prog);853	return -ENOMEM;854}855 856static int857bpf_object__add_programs(struct bpf_object *obj, Elf_Data *sec_data,858			 const char *sec_name, int sec_idx)859{860	Elf_Data *symbols = obj->efile.symbols;861	struct bpf_program *prog, *progs;862	void *data = sec_data->d_buf;863	size_t sec_sz = sec_data->d_size, sec_off, prog_sz, nr_syms;864	int nr_progs, err, i;865	const char *name;866	Elf64_Sym *sym;867 868	progs = obj->programs;869	nr_progs = obj->nr_programs;870	nr_syms = symbols->d_size / sizeof(Elf64_Sym);871 872	for (i = 0; i < nr_syms; i++) {873		sym = elf_sym_by_idx(obj, i);874 875		if (sym->st_shndx != sec_idx)876			continue;877		if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)878			continue;879 880		prog_sz = sym->st_size;881		sec_off = sym->st_value;882 883		name = elf_sym_str(obj, sym->st_name);884		if (!name) {885			pr_warn("sec '%s': failed to get symbol name for offset %zu\n",886				sec_name, sec_off);887			return -LIBBPF_ERRNO__FORMAT;888		}889 890		if (sec_off + prog_sz > sec_sz) {891			pr_warn("sec '%s': program at offset %zu crosses section boundary\n",892				sec_name, sec_off);893			return -LIBBPF_ERRNO__FORMAT;894		}895 896		if (sec_idx != obj->efile.text_shndx && ELF64_ST_BIND(sym->st_info) == STB_LOCAL) {897			pr_warn("sec '%s': program '%s' is static and not supported\n", sec_name, name);898			return -ENOTSUP;899		}900 901		pr_debug("sec '%s': found program '%s' at insn offset %zu (%zu bytes), code size %zu insns (%zu bytes)\n",902			 sec_name, name, sec_off / BPF_INSN_SZ, sec_off, prog_sz / BPF_INSN_SZ, prog_sz);903 904		progs = libbpf_reallocarray(progs, nr_progs + 1, sizeof(*progs));905		if (!progs) {906			/*907			 * In this case the original obj->programs908			 * is still valid, so don't need special treat for909			 * bpf_close_object().910			 */911			pr_warn("sec '%s': failed to alloc memory for new program '%s'\n",912				sec_name, name);913			return -ENOMEM;914		}915		obj->programs = progs;916 917		prog = &progs[nr_progs];918 919		err = bpf_object__init_prog(obj, prog, name, sec_idx, sec_name,920					    sec_off, data + sec_off, prog_sz);921		if (err)922			return err;923 924		if (ELF64_ST_BIND(sym->st_info) != STB_LOCAL)925			prog->sym_global = true;926 927		/* if function is a global/weak symbol, but has restricted928		 * (STV_HIDDEN or STV_INTERNAL) visibility, mark its BTF FUNC929		 * as static to enable more permissive BPF verification mode930		 * with more outside context available to BPF verifier931		 */932		if (prog->sym_global && (ELF64_ST_VISIBILITY(sym->st_other) == STV_HIDDEN933		    || ELF64_ST_VISIBILITY(sym->st_other) == STV_INTERNAL))934			prog->mark_btf_static = true;935 936		nr_progs++;937		obj->nr_programs = nr_progs;938	}939 940	return 0;941}942 943static const struct btf_member *944find_member_by_offset(const struct btf_type *t, __u32 bit_offset)945{946	struct btf_member *m;947	int i;948 949	for (i = 0, m = btf_members(t); i < btf_vlen(t); i++, m++) {950		if (btf_member_bit_offset(t, i) == bit_offset)951			return m;952	}953 954	return NULL;955}956 957static const struct btf_member *958find_member_by_name(const struct btf *btf, const struct btf_type *t,959		    const char *name)960{961	struct btf_member *m;962	int i;963 964	for (i = 0, m = btf_members(t); i < btf_vlen(t); i++, m++) {965		if (!strcmp(btf__name_by_offset(btf, m->name_off), name))966			return m;967	}968 969	return NULL;970}971 972static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,973			    __u16 kind, struct btf **res_btf,974			    struct module_btf **res_mod_btf);975 976#define STRUCT_OPS_VALUE_PREFIX "bpf_struct_ops_"977static int find_btf_by_prefix_kind(const struct btf *btf, const char *prefix,978				   const char *name, __u32 kind);979 980static int981find_struct_ops_kern_types(struct bpf_object *obj, const char *tname_raw,982			   struct module_btf **mod_btf,983			   const struct btf_type **type, __u32 *type_id,984			   const struct btf_type **vtype, __u32 *vtype_id,985			   const struct btf_member **data_member)986{987	const struct btf_type *kern_type, *kern_vtype;988	const struct btf_member *kern_data_member;989	struct btf *btf = NULL;990	__s32 kern_vtype_id, kern_type_id;991	char tname[256];992	__u32 i;993 994	snprintf(tname, sizeof(tname), "%.*s",995		 (int)bpf_core_essential_name_len(tname_raw), tname_raw);996 997	kern_type_id = find_ksym_btf_id(obj, tname, BTF_KIND_STRUCT,998					&btf, mod_btf);999	if (kern_type_id < 0) {1000		pr_warn("struct_ops init_kern: struct %s is not found in kernel BTF\n",1001			tname);1002		return kern_type_id;1003	}1004	kern_type = btf__type_by_id(btf, kern_type_id);1005 1006	/* Find the corresponding "map_value" type that will be used1007	 * in map_update(BPF_MAP_TYPE_STRUCT_OPS).  For example,1008	 * find "struct bpf_struct_ops_tcp_congestion_ops" from the1009	 * btf_vmlinux.1010	 */1011	kern_vtype_id = find_btf_by_prefix_kind(btf, STRUCT_OPS_VALUE_PREFIX,1012						tname, BTF_KIND_STRUCT);1013	if (kern_vtype_id < 0) {1014		pr_warn("struct_ops init_kern: struct %s%s is not found in kernel BTF\n",1015			STRUCT_OPS_VALUE_PREFIX, tname);1016		return kern_vtype_id;1017	}1018	kern_vtype = btf__type_by_id(btf, kern_vtype_id);1019 1020	/* Find "struct tcp_congestion_ops" from1021	 * struct bpf_struct_ops_tcp_congestion_ops {1022	 *	[ ... ]1023	 *	struct tcp_congestion_ops data;1024	 * }1025	 */1026	kern_data_member = btf_members(kern_vtype);1027	for (i = 0; i < btf_vlen(kern_vtype); i++, kern_data_member++) {1028		if (kern_data_member->type == kern_type_id)1029			break;1030	}1031	if (i == btf_vlen(kern_vtype)) {1032		pr_warn("struct_ops init_kern: struct %s data is not found in struct %s%s\n",1033			tname, STRUCT_OPS_VALUE_PREFIX, tname);1034		return -EINVAL;1035	}1036 1037	*type = kern_type;1038	*type_id = kern_type_id;1039	*vtype = kern_vtype;1040	*vtype_id = kern_vtype_id;1041	*data_member = kern_data_member;1042 1043	return 0;1044}1045 1046static bool bpf_map__is_struct_ops(const struct bpf_map *map)1047{1048	return map->def.type == BPF_MAP_TYPE_STRUCT_OPS;1049}1050 1051static bool is_valid_st_ops_program(struct bpf_object *obj,1052				    const struct bpf_program *prog)1053{1054	int i;1055 1056	for (i = 0; i < obj->nr_programs; i++) {1057		if (&obj->programs[i] == prog)1058			return prog->type == BPF_PROG_TYPE_STRUCT_OPS;1059	}1060 1061	return false;1062}1063 1064/* For each struct_ops program P, referenced from some struct_ops map M,1065 * enable P.autoload if there are Ms for which M.autocreate is true,1066 * disable P.autoload if for all Ms M.autocreate is false.1067 * Don't change P.autoload for programs that are not referenced from any maps.1068 */1069static int bpf_object_adjust_struct_ops_autoload(struct bpf_object *obj)1070{1071	struct bpf_program *prog, *slot_prog;1072	struct bpf_map *map;1073	int i, j, k, vlen;1074 1075	for (i = 0; i < obj->nr_programs; ++i) {1076		int should_load = false;1077		int use_cnt = 0;1078 1079		prog = &obj->programs[i];1080		if (prog->type != BPF_PROG_TYPE_STRUCT_OPS)1081			continue;1082 1083		for (j = 0; j < obj->nr_maps; ++j) {1084			const struct btf_type *type;1085 1086			map = &obj->maps[j];1087			if (!bpf_map__is_struct_ops(map))1088				continue;1089 1090			type = btf__type_by_id(obj->btf, map->st_ops->type_id);1091			vlen = btf_vlen(type);1092			for (k = 0; k < vlen; ++k) {1093				slot_prog = map->st_ops->progs[k];1094				if (prog != slot_prog)1095					continue;1096 1097				use_cnt++;1098				if (map->autocreate)1099					should_load = true;1100			}1101		}1102		if (use_cnt)1103			prog->autoload = should_load;1104	}1105 1106	return 0;1107}1108 1109/* Init the map's fields that depend on kern_btf */1110static int bpf_map__init_kern_struct_ops(struct bpf_map *map)1111{1112	const struct btf_member *member, *kern_member, *kern_data_member;1113	const struct btf_type *type, *kern_type, *kern_vtype;1114	__u32 i, kern_type_id, kern_vtype_id, kern_data_off;1115	struct bpf_object *obj = map->obj;1116	const struct btf *btf = obj->btf;1117	struct bpf_struct_ops *st_ops;1118	const struct btf *kern_btf;1119	struct module_btf *mod_btf = NULL;1120	void *data, *kern_data;1121	const char *tname;1122	int err;1123 1124	st_ops = map->st_ops;1125	type = btf__type_by_id(btf, st_ops->type_id);1126	tname = btf__name_by_offset(btf, type->name_off);1127	err = find_struct_ops_kern_types(obj, tname, &mod_btf,1128					 &kern_type, &kern_type_id,1129					 &kern_vtype, &kern_vtype_id,1130					 &kern_data_member);1131	if (err)1132		return err;1133 1134	kern_btf = mod_btf ? mod_btf->btf : obj->btf_vmlinux;1135 1136	pr_debug("struct_ops init_kern %s: type_id:%u kern_type_id:%u kern_vtype_id:%u\n",1137		 map->name, st_ops->type_id, kern_type_id, kern_vtype_id);1138 1139	map->mod_btf_fd = mod_btf ? mod_btf->fd : -1;1140	map->def.value_size = kern_vtype->size;1141	map->btf_vmlinux_value_type_id = kern_vtype_id;1142 1143	st_ops->kern_vdata = calloc(1, kern_vtype->size);1144	if (!st_ops->kern_vdata)1145		return -ENOMEM;1146 1147	data = st_ops->data;1148	kern_data_off = kern_data_member->offset / 8;1149	kern_data = st_ops->kern_vdata + kern_data_off;1150 1151	member = btf_members(type);1152	for (i = 0; i < btf_vlen(type); i++, member++) {1153		const struct btf_type *mtype, *kern_mtype;1154		__u32 mtype_id, kern_mtype_id;1155		void *mdata, *kern_mdata;1156		struct bpf_program *prog;1157		__s64 msize, kern_msize;1158		__u32 moff, kern_moff;1159		__u32 kern_member_idx;1160		const char *mname;1161 1162		mname = btf__name_by_offset(btf, member->name_off);1163		moff = member->offset / 8;1164		mdata = data + moff;1165		msize = btf__resolve_size(btf, member->type);1166		if (msize < 0) {1167			pr_warn("struct_ops init_kern %s: failed to resolve the size of member %s\n",1168				map->name, mname);1169			return msize;1170		}1171 1172		kern_member = find_member_by_name(kern_btf, kern_type, mname);1173		if (!kern_member) {1174			if (!libbpf_is_mem_zeroed(mdata, msize)) {1175				pr_warn("struct_ops init_kern %s: Cannot find member %s in kernel BTF\n",1176					map->name, mname);1177				return -ENOTSUP;1178			}1179 1180			if (st_ops->progs[i]) {1181				/* If we had declaratively set struct_ops callback, we need to1182				 * force its autoload to false, because it doesn't have1183				 * a chance of succeeding from POV of the current struct_ops map.1184				 * If this program is still referenced somewhere else, though,1185				 * then bpf_object_adjust_struct_ops_autoload() will update its1186				 * autoload accordingly.1187				 */1188				st_ops->progs[i]->autoload = false;1189				st_ops->progs[i] = NULL;1190			}1191 1192			/* Skip all-zero/NULL fields if they are not present in the kernel BTF */1193			pr_info("struct_ops %s: member %s not found in kernel, skipping it as it's set to zero\n",1194				map->name, mname);1195			continue;1196		}1197 1198		kern_member_idx = kern_member - btf_members(kern_type);1199		if (btf_member_bitfield_size(type, i) ||1200		    btf_member_bitfield_size(kern_type, kern_member_idx)) {1201			pr_warn("struct_ops init_kern %s: bitfield %s is not supported\n",1202				map->name, mname);1203			return -ENOTSUP;1204		}1205 1206		kern_moff = kern_member->offset / 8;1207		kern_mdata = kern_data + kern_moff;1208 1209		mtype = skip_mods_and_typedefs(btf, member->type, &mtype_id);1210		kern_mtype = skip_mods_and_typedefs(kern_btf, kern_member->type,1211						    &kern_mtype_id);1212		if (BTF_INFO_KIND(mtype->info) !=1213		    BTF_INFO_KIND(kern_mtype->info)) {1214			pr_warn("struct_ops init_kern %s: Unmatched member type %s %u != %u(kernel)\n",1215				map->name, mname, BTF_INFO_KIND(mtype->info),1216				BTF_INFO_KIND(kern_mtype->info));1217			return -ENOTSUP;1218		}1219 1220		if (btf_is_ptr(mtype)) {1221			prog = *(void **)mdata;1222			/* just like for !kern_member case above, reset declaratively1223			 * set (at compile time) program's autload to false,1224			 * if user replaced it with another program or NULL1225			 */1226			if (st_ops->progs[i] && st_ops->progs[i] != prog)1227				st_ops->progs[i]->autoload = false;1228 1229			/* Update the value from the shadow type */1230			st_ops->progs[i] = prog;1231			if (!prog)1232				continue;1233 1234			if (!is_valid_st_ops_program(obj, prog)) {1235				pr_warn("struct_ops init_kern %s: member %s is not a struct_ops program\n",1236					map->name, mname);1237				return -ENOTSUP;1238			}1239 1240			kern_mtype = skip_mods_and_typedefs(kern_btf,1241							    kern_mtype->type,1242							    &kern_mtype_id);1243 1244			/* mtype->type must be a func_proto which was1245			 * guaranteed in bpf_object__collect_st_ops_relos(),1246			 * so only check kern_mtype for func_proto here.1247			 */1248			if (!btf_is_func_proto(kern_mtype)) {1249				pr_warn("struct_ops init_kern %s: kernel member %s is not a func ptr\n",1250					map->name, mname);1251				return -ENOTSUP;1252			}1253 1254			if (mod_btf)1255				prog->attach_btf_obj_fd = mod_btf->fd;1256 1257			/* if we haven't yet processed this BPF program, record proper1258			 * attach_btf_id and member_idx1259			 */1260			if (!prog->attach_btf_id) {1261				prog->attach_btf_id = kern_type_id;1262				prog->expected_attach_type = kern_member_idx;1263			}1264 1265			/* struct_ops BPF prog can be re-used between multiple1266			 * .struct_ops & .struct_ops.link as long as it's the1267			 * same struct_ops struct definition and the same1268			 * function pointer field1269			 */1270			if (prog->attach_btf_id != kern_type_id) {1271				pr_warn("struct_ops init_kern %s func ptr %s: invalid reuse of prog %s in sec %s with type %u: attach_btf_id %u != kern_type_id %u\n",1272					map->name, mname, prog->name, prog->sec_name, prog->type,1273					prog->attach_btf_id, kern_type_id);1274				return -EINVAL;1275			}1276			if (prog->expected_attach_type != kern_member_idx) {1277				pr_warn("struct_ops init_kern %s func ptr %s: invalid reuse of prog %s in sec %s with type %u: expected_attach_type %u != kern_member_idx %u\n",1278					map->name, mname, prog->name, prog->sec_name, prog->type,1279					prog->expected_attach_type, kern_member_idx);1280				return -EINVAL;1281			}1282 1283			st_ops->kern_func_off[i] = kern_data_off + kern_moff;1284 1285			pr_debug("struct_ops init_kern %s: func ptr %s is set to prog %s from data(+%u) to kern_data(+%u)\n",1286				 map->name, mname, prog->name, moff,1287				 kern_moff);1288 1289			continue;1290		}1291 1292		kern_msize = btf__resolve_size(kern_btf, kern_mtype_id);1293		if (kern_msize < 0 || msize != kern_msize) {1294			pr_warn("struct_ops init_kern %s: Error in size of member %s: %zd != %zd(kernel)\n",1295				map->name, mname, (ssize_t)msize,1296				(ssize_t)kern_msize);1297			return -ENOTSUP;1298		}1299 1300		pr_debug("struct_ops init_kern %s: copy %s %u bytes from data(+%u) to kern_data(+%u)\n",1301			 map->name, mname, (unsigned int)msize,1302			 moff, kern_moff);1303		memcpy(kern_mdata, mdata, msize);1304	}1305 1306	return 0;1307}1308 1309static int bpf_object__init_kern_struct_ops_maps(struct bpf_object *obj)1310{1311	struct bpf_map *map;1312	size_t i;1313	int err;1314 1315	for (i = 0; i < obj->nr_maps; i++) {1316		map = &obj->maps[i];1317 1318		if (!bpf_map__is_struct_ops(map))1319			continue;1320 1321		if (!map->autocreate)1322			continue;1323 1324		err = bpf_map__init_kern_struct_ops(map);1325		if (err)1326			return err;1327	}1328 1329	return 0;1330}1331 1332static int init_struct_ops_maps(struct bpf_object *obj, const char *sec_name,1333				int shndx, Elf_Data *data)1334{1335	const struct btf_type *type, *datasec;1336	const struct btf_var_secinfo *vsi;1337	struct bpf_struct_ops *st_ops;1338	const char *tname, *var_name;1339	__s32 type_id, datasec_id;1340	const struct btf *btf;1341	struct bpf_map *map;1342	__u32 i;1343 1344	if (shndx == -1)1345		return 0;1346 1347	btf = obj->btf;1348	datasec_id = btf__find_by_name_kind(btf, sec_name,1349					    BTF_KIND_DATASEC);1350	if (datasec_id < 0) {1351		pr_warn("struct_ops init: DATASEC %s not found\n",1352			sec_name);1353		return -EINVAL;1354	}1355 1356	datasec = btf__type_by_id(btf, datasec_id);1357	vsi = btf_var_secinfos(datasec);1358	for (i = 0; i < btf_vlen(datasec); i++, vsi++) {1359		type = btf__type_by_id(obj->btf, vsi->type);1360		var_name = btf__name_by_offset(obj->btf, type->name_off);1361 1362		type_id = btf__resolve_type(obj->btf, vsi->type);1363		if (type_id < 0) {1364			pr_warn("struct_ops init: Cannot resolve var type_id %u in DATASEC %s\n",1365				vsi->type, sec_name);1366			return -EINVAL;1367		}1368 1369		type = btf__type_by_id(obj->btf, type_id);1370		tname = btf__name_by_offset(obj->btf, type->name_off);1371		if (!tname[0]) {1372			pr_warn("struct_ops init: anonymous type is not supported\n");1373			return -ENOTSUP;1374		}1375		if (!btf_is_struct(type)) {1376			pr_warn("struct_ops init: %s is not a struct\n", tname);1377			return -EINVAL;1378		}1379 1380		map = bpf_object__add_map(obj);1381		if (IS_ERR(map))1382			return PTR_ERR(map);1383 1384		map->sec_idx = shndx;1385		map->sec_offset = vsi->offset;1386		map->name = strdup(var_name);1387		if (!map->name)1388			return -ENOMEM;1389		map->btf_value_type_id = type_id;1390 1391		/* Follow same convention as for programs autoload:1392		 * SEC("?.struct_ops") means map is not created by default.1393		 */1394		if (sec_name[0] == '?') {1395			map->autocreate = false;1396			/* from now on forget there was ? in section name */1397			sec_name++;1398		}1399 1400		map->def.type = BPF_MAP_TYPE_STRUCT_OPS;1401		map->def.key_size = sizeof(int);1402		map->def.value_size = type->size;1403		map->def.max_entries = 1;1404		map->def.map_flags = strcmp(sec_name, STRUCT_OPS_LINK_SEC) == 0 ? BPF_F_LINK : 0;1405		map->autoattach = true;1406 1407		map->st_ops = calloc(1, sizeof(*map->st_ops));1408		if (!map->st_ops)1409			return -ENOMEM;1410		st_ops = map->st_ops;1411		st_ops->data = malloc(type->size);1412		st_ops->progs = calloc(btf_vlen(type), sizeof(*st_ops->progs));1413		st_ops->kern_func_off = malloc(btf_vlen(type) *1414					       sizeof(*st_ops->kern_func_off));1415		if (!st_ops->data || !st_ops->progs || !st_ops->kern_func_off)1416			return -ENOMEM;1417 1418		if (vsi->offset + type->size > data->d_size) {1419			pr_warn("struct_ops init: var %s is beyond the end of DATASEC %s\n",1420				var_name, sec_name);1421			return -EINVAL;1422		}1423 1424		memcpy(st_ops->data,1425		       data->d_buf + vsi->offset,1426		       type->size);1427		st_ops->type_id = type_id;1428 1429		pr_debug("struct_ops init: struct %s(type_id=%u) %s found at offset %u\n",1430			 tname, type_id, var_name, vsi->offset);1431	}1432 1433	return 0;1434}1435 1436static int bpf_object_init_struct_ops(struct bpf_object *obj)1437{1438	const char *sec_name;1439	int sec_idx, err;1440 1441	for (sec_idx = 0; sec_idx < obj->efile.sec_cnt; ++sec_idx) {1442		struct elf_sec_desc *desc = &obj->efile.secs[sec_idx];1443 1444		if (desc->sec_type != SEC_ST_OPS)1445			continue;1446 1447		sec_name = elf_sec_name(obj, elf_sec_by_idx(obj, sec_idx));1448		if (!sec_name)1449			return -LIBBPF_ERRNO__FORMAT;1450 1451		err = init_struct_ops_maps(obj, sec_name, sec_idx, desc->data);1452		if (err)1453			return err;1454	}1455 1456	return 0;1457}1458 1459static struct bpf_object *bpf_object__new(const char *path,1460					  const void *obj_buf,1461					  size_t obj_buf_sz,1462					  const char *obj_name)1463{1464	struct bpf_object *obj;1465	char *end;1466 1467	obj = calloc(1, sizeof(struct bpf_object) + strlen(path) + 1);1468	if (!obj) {1469		pr_warn("alloc memory failed for %s\n", path);1470		return ERR_PTR(-ENOMEM);1471	}1472 1473	strcpy(obj->path, path);1474	if (obj_name) {1475		libbpf_strlcpy(obj->name, obj_name, sizeof(obj->name));1476	} else {1477		/* Using basename() GNU version which doesn't modify arg. */1478		libbpf_strlcpy(obj->name, basename((void *)path), sizeof(obj->name));1479		end = strchr(obj->name, '.');1480		if (end)1481			*end = 0;1482	}1483 1484	obj->efile.fd = -1;1485	/*1486	 * Caller of this function should also call1487	 * bpf_object__elf_finish() after data collection to return1488	 * obj_buf to user. If not, we should duplicate the buffer to1489	 * avoid user freeing them before elf finish.1490	 */1491	obj->efile.obj_buf = obj_buf;1492	obj->efile.obj_buf_sz = obj_buf_sz;1493	obj->efile.btf_maps_shndx = -1;1494	obj->kconfig_map_idx = -1;1495 1496	obj->kern_version = get_kernel_version();1497	obj->loaded = false;1498 1499	return obj;1500}1501 1502static void bpf_object__elf_finish(struct bpf_object *obj)1503{1504	if (!obj->efile.elf)1505		return;1506 1507	elf_end(obj->efile.elf);1508	obj->efile.elf = NULL;1509	obj->efile.symbols = NULL;1510	obj->efile.arena_data = NULL;1511 1512	zfree(&obj->efile.secs);1513	obj->efile.sec_cnt = 0;1514	zclose(obj->efile.fd);1515	obj->efile.obj_buf = NULL;1516	obj->efile.obj_buf_sz = 0;1517}1518 1519static int bpf_object__elf_init(struct bpf_object *obj)1520{1521	Elf64_Ehdr *ehdr;1522	int err = 0;1523	Elf *elf;1524 1525	if (obj->efile.elf) {1526		pr_warn("elf: init internal error\n");1527		return -LIBBPF_ERRNO__LIBELF;1528	}1529 1530	if (obj->efile.obj_buf_sz > 0) {1531		/* obj_buf should have been validated by bpf_object__open_mem(). */1532		elf = elf_memory((char *)obj->efile.obj_buf, obj->efile.obj_buf_sz);1533	} else {1534		obj->efile.fd = open(obj->path, O_RDONLY | O_CLOEXEC);1535		if (obj->efile.fd < 0) {1536			char errmsg[STRERR_BUFSIZE], *cp;1537 1538			err = -errno;1539			cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg));1540			pr_warn("elf: failed to open %s: %s\n", obj->path, cp);1541			return err;1542		}1543 1544		elf = elf_begin(obj->efile.fd, ELF_C_READ_MMAP, NULL);1545	}1546 1547	if (!elf) {1548		pr_warn("elf: failed to open %s as ELF file: %s\n", obj->path, elf_errmsg(-1));1549		err = -LIBBPF_ERRNO__LIBELF;1550		goto errout;1551	}1552 1553	obj->efile.elf = elf;1554 1555	if (elf_kind(elf) != ELF_K_ELF) {1556		err = -LIBBPF_ERRNO__FORMAT;1557		pr_warn("elf: '%s' is not a proper ELF object\n", obj->path);1558		goto errout;1559	}1560 1561	if (gelf_getclass(elf) != ELFCLASS64) {1562		err = -LIBBPF_ERRNO__FORMAT;1563		pr_warn("elf: '%s' is not a 64-bit ELF object\n", obj->path);1564		goto errout;1565	}1566 1567	obj->efile.ehdr = ehdr = elf64_getehdr(elf);1568	if (!obj->efile.ehdr) {1569		pr_warn("elf: failed to get ELF header from %s: %s\n", obj->path, elf_errmsg(-1));1570		err = -LIBBPF_ERRNO__FORMAT;1571		goto errout;1572	}1573 1574	if (elf_getshdrstrndx(elf, &obj->efile.shstrndx)) {1575		pr_warn("elf: failed to get section names section index for %s: %s\n",1576			obj->path, elf_errmsg(-1));1577		err = -LIBBPF_ERRNO__FORMAT;1578		goto errout;1579	}1580 1581	/* ELF is corrupted/truncated, avoid calling elf_strptr. */1582	if (!elf_rawdata(elf_getscn(elf, obj->efile.shstrndx), NULL)) {1583		pr_warn("elf: failed to get section names strings from %s: %s\n",1584			obj->path, elf_errmsg(-1));1585		err = -LIBBPF_ERRNO__FORMAT;1586		goto errout;1587	}1588 1589	/* Old LLVM set e_machine to EM_NONE */1590	if (ehdr->e_type != ET_REL || (ehdr->e_machine && ehdr->e_machine != EM_BPF)) {1591		pr_warn("elf: %s is not a valid eBPF object file\n", obj->path);1592		err = -LIBBPF_ERRNO__FORMAT;1593		goto errout;1594	}1595 1596	return 0;1597errout:1598	bpf_object__elf_finish(obj);1599	return err;1600}1601 1602static int bpf_object__check_endianness(struct bpf_object *obj)1603{1604#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__1605	if (obj->efile.ehdr->e_ident[EI_DATA] == ELFDATA2LSB)1606		return 0;1607#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__1608	if (obj->efile.ehdr->e_ident[EI_DATA] == ELFDATA2MSB)1609		return 0;1610#else1611# error "Unrecognized __BYTE_ORDER__"1612#endif1613	pr_warn("elf: endianness mismatch in %s.\n", obj->path);1614	return -LIBBPF_ERRNO__ENDIAN;1615}1616 1617static int1618bpf_object__init_license(struct bpf_object *obj, void *data, size_t size)1619{1620	if (!data) {1621		pr_warn("invalid license section in %s\n", obj->path);1622		return -LIBBPF_ERRNO__FORMAT;1623	}1624	/* libbpf_strlcpy() only copies first N - 1 bytes, so size + 1 won't1625	 * go over allowed ELF data section buffer1626	 */1627	libbpf_strlcpy(obj->license, data, min(size + 1, sizeof(obj->license)));1628	pr_debug("license of %s is %s\n", obj->path, obj->license);1629	return 0;1630}1631 1632static int1633bpf_object__init_kversion(struct bpf_object *obj, void *data, size_t size)1634{1635	__u32 kver;1636 1637	if (!data || size != sizeof(kver)) {1638		pr_warn("invalid kver section in %s\n", obj->path);1639		return -LIBBPF_ERRNO__FORMAT;1640	}1641	memcpy(&kver, data, sizeof(kver));1642	obj->kern_version = kver;1643	pr_debug("kernel version of %s is %x\n", obj->path, obj->kern_version);1644	return 0;1645}1646 1647static bool bpf_map_type__is_map_in_map(enum bpf_map_type type)1648{1649	if (type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||1650	    type == BPF_MAP_TYPE_HASH_OF_MAPS)1651		return true;1652	return false;1653}1654 1655static int find_elf_sec_sz(const struct bpf_object *obj, const char *name, __u32 *size)1656{1657	Elf_Data *data;1658	Elf_Scn *scn;1659 1660	if (!name)1661		return -EINVAL;1662 1663	scn = elf_sec_by_name(obj, name);1664	data = elf_sec_data(obj, scn);1665	if (data) {1666		*size = data->d_size;1667		return 0; /* found it */1668	}1669 1670	return -ENOENT;1671}1672 1673static Elf64_Sym *find_elf_var_sym(const struct bpf_object *obj, const char *name)1674{1675	Elf_Data *symbols = obj->efile.symbols;1676	const char *sname;1677	size_t si;1678 1679	for (si = 0; si < symbols->d_size / sizeof(Elf64_Sym); si++) {1680		Elf64_Sym *sym = elf_sym_by_idx(obj, si);1681 1682		if (ELF64_ST_TYPE(sym->st_info) != STT_OBJECT)1683			continue;1684 1685		if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&1686		    ELF64_ST_BIND(sym->st_info) != STB_WEAK)1687			continue;1688 1689		sname = elf_sym_str(obj, sym->st_name);1690		if (!sname) {1691			pr_warn("failed to get sym name string for var %s\n", name);1692			return ERR_PTR(-EIO);1693		}1694		if (strcmp(name, sname) == 0)1695			return sym;1696	}1697 1698	return ERR_PTR(-ENOENT);1699}1700 1701/* Some versions of Android don't provide memfd_create() in their libc1702 * implementation, so avoid complications and just go straight to Linux1703 * syscall.1704 */1705static int sys_memfd_create(const char *name, unsigned flags)1706{1707	return syscall(__NR_memfd_create, name, flags);1708}1709 1710#ifndef MFD_CLOEXEC1711#define MFD_CLOEXEC 0x0001U1712#endif1713 1714static int create_placeholder_fd(void)1715{1716	int fd;1717 1718	fd = ensure_good_fd(sys_memfd_create("libbpf-placeholder-fd", MFD_CLOEXEC));1719	if (fd < 0)1720		return -errno;1721	return fd;1722}1723 1724static struct bpf_map *bpf_object__add_map(struct bpf_object *obj)1725{1726	struct bpf_map *map;1727	int err;1728 1729	err = libbpf_ensure_mem((void **)&obj->maps, &obj->maps_cap,1730				sizeof(*obj->maps), obj->nr_maps + 1);1731	if (err)1732		return ERR_PTR(err);1733 1734	map = &obj->maps[obj->nr_maps++];1735	map->obj = obj;1736	/* Preallocate map FD without actually creating BPF map just yet.1737	 * These map FD "placeholders" will be reused later without changing1738	 * FD value when map is actually created in the kernel.1739	 *1740	 * This is useful to be able to perform BPF program relocations1741	 * without having to create BPF maps before that step. This allows us1742	 * to finalize and load BTF very late in BPF object's loading phase,1743	 * right before BPF maps have to be created and BPF programs have to1744	 * be loaded. By having these map FD placeholders we can perform all1745	 * the sanitizations, relocations, and any other adjustments before we1746	 * start creating actual BPF kernel objects (BTF, maps, progs).1747	 */1748	map->fd = create_placeholder_fd();1749	if (map->fd < 0)1750		return ERR_PTR(map->fd);1751	map->inner_map_fd = -1;1752	map->autocreate = true;1753 1754	return map;1755}1756 1757static size_t array_map_mmap_sz(unsigned int value_sz, unsigned int max_entries)1758{1759	const long page_sz = sysconf(_SC_PAGE_SIZE);1760	size_t map_sz;1761 1762	map_sz = (size_t)roundup(value_sz, 8) * max_entries;1763	map_sz = roundup(map_sz, page_sz);1764	return map_sz;1765}1766 1767static size_t bpf_map_mmap_sz(const struct bpf_map *map)1768{1769	const long page_sz = sysconf(_SC_PAGE_SIZE);1770 1771	switch (map->def.type) {1772	case BPF_MAP_TYPE_ARRAY:1773		return array_map_mmap_sz(map->def.value_size, map->def.max_entries);1774	case BPF_MAP_TYPE_ARENA:1775		return page_sz * map->def.max_entries;1776	default:1777		return 0; /* not supported */1778	}1779}1780 1781static int bpf_map_mmap_resize(struct bpf_map *map, size_t old_sz, size_t new_sz)1782{1783	void *mmaped;1784 1785	if (!map->mmaped)1786		return -EINVAL;1787 1788	if (old_sz == new_sz)1789		return 0;1790 1791	mmaped = mmap(NULL, new_sz, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);1792	if (mmaped == MAP_FAILED)1793		return -errno;1794 1795	memcpy(mmaped, map->mmaped, min(old_sz, new_sz));1796	munmap(map->mmaped, old_sz);1797	map->mmaped = mmaped;1798	return 0;1799}1800 1801static char *internal_map_name(struct bpf_object *obj, const char *real_name)1802{1803	char map_name[BPF_OBJ_NAME_LEN], *p;1804	int pfx_len, sfx_len = max((size_t)7, strlen(real_name));1805 1806	/* This is one of the more confusing parts of libbpf for various1807	 * reasons, some of which are historical. The original idea for naming1808	 * internal names was to include as much of BPF object name prefix as1809	 * possible, so that it can be distinguished from similar internal1810	 * maps of a different BPF object.1811	 * As an example, let's say we have bpf_object named 'my_object_name'1812	 * and internal map corresponding to '.rodata' ELF section. The final1813	 * map name advertised to user and to the kernel will be1814	 * 'my_objec.rodata', taking first 8 characters of object name and1815	 * entire 7 characters of '.rodata'.1816	 * Somewhat confusingly, if internal map ELF section name is shorter1817	 * than 7 characters, e.g., '.bss', we still reserve 7 characters1818	 * for the suffix, even though we only have 4 actual characters, and1819	 * resulting map will be called 'my_objec.bss', not even using all 151820	 * characters allowed by the kernel. Oh well, at least the truncated1821	 * object name is somewhat consistent in this case. But if the map1822	 * name is '.kconfig', we'll still have entirety of '.kconfig' added1823	 * (8 chars) and thus will be left with only first 7 characters of the1824	 * object name ('my_obje'). Happy guessing, user, that the final map1825	 * name will be "my_obje.kconfig".1826	 * Now, with libbpf starting to support arbitrarily named .rodata.*1827	 * and .data.* data sections, it's possible that ELF section name is1828	 * longer than allowed 15 chars, so we now need to be careful to take1829	 * only up to 15 first characters of ELF name, taking no BPF object1830	 * name characters at all. So '.rodata.abracadabra' will result in1831	 * '.rodata.abracad' kernel and user-visible name.1832	 * We need to keep this convoluted logic intact for .data, .bss and1833	 * .rodata maps, but for new custom .data.custom and .rodata.custom1834	 * maps we use their ELF names as is, not prepending bpf_object name1835	 * in front. We still need to truncate them to 15 characters for the1836	 * kernel. Full name can be recovered for such maps by using DATASEC1837	 * BTF type associated with such map's value type, though.1838	 */1839	if (sfx_len >= BPF_OBJ_NAME_LEN)1840		sfx_len = BPF_OBJ_NAME_LEN - 1;1841 1842	/* if there are two or more dots in map name, it's a custom dot map */1843	if (strchr(real_name + 1, '.') != NULL)1844		pfx_len = 0;1845	else1846		pfx_len = min((size_t)BPF_OBJ_NAME_LEN - sfx_len - 1, strlen(obj->name));1847 1848	snprintf(map_name, sizeof(map_name), "%.*s%.*s", pfx_len, obj->name,1849		 sfx_len, real_name);1850 1851	/* sanities map name to characters allowed by kernel */1852	for (p = map_name; *p && p < map_name + sizeof(map_name); p++)1853		if (!isalnum(*p) && *p != '_' && *p != '.')1854			*p = '_';1855 1856	return strdup(map_name);1857}1858 1859static int1860map_fill_btf_type_info(struct bpf_object *obj, struct bpf_map *map);1861 1862/* Internal BPF map is mmap()'able only if at least one of corresponding1863 * DATASEC's VARs are to be exposed through BPF skeleton. I.e., it's a GLOBAL1864 * variable and it's not marked as __hidden (which turns it into, effectively,1865 * a STATIC variable).1866 */1867static bool map_is_mmapable(struct bpf_object *obj, struct bpf_map *map)1868{1869	const struct btf_type *t, *vt;1870	struct btf_var_secinfo *vsi;1871	int i, n;1872 1873	if (!map->btf_value_type_id)1874		return false;1875 1876	t = btf__type_by_id(obj->btf, map->btf_value_type_id);1877	if (!btf_is_datasec(t))1878		return false;1879 1880	vsi = btf_var_secinfos(t);1881	for (i = 0, n = btf_vlen(t); i < n; i++, vsi++) {1882		vt = btf__type_by_id(obj->btf, vsi->type);1883		if (!btf_is_var(vt))1884			continue;1885 1886		if (btf_var(vt)->linkage != BTF_VAR_STATIC)1887			return true;1888	}1889 1890	return false;1891}1892 1893static int1894bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type,1895			      const char *real_name, int sec_idx, void *data, size_t data_sz)1896{1897	struct bpf_map_def *def;1898	struct bpf_map *map;1899	size_t mmap_sz;1900	int err;1901 1902	map = bpf_object__add_map(obj);1903	if (IS_ERR(map))1904		return PTR_ERR(map);1905 1906	map->libbpf_type = type;1907	map->sec_idx = sec_idx;1908	map->sec_offset = 0;1909	map->real_name = strdup(real_name);1910	map->name = internal_map_name(obj, real_name);1911	if (!map->real_name || !map->name) {1912		zfree(&map->real_name);1913		zfree(&map->name);1914		return -ENOMEM;1915	}1916 1917	def = &map->def;1918	def->type = BPF_MAP_TYPE_ARRAY;1919	def->key_size = sizeof(int);1920	def->value_size = data_sz;1921	def->max_entries = 1;1922	def->map_flags = type == LIBBPF_MAP_RODATA || type == LIBBPF_MAP_KCONFIG1923		? BPF_F_RDONLY_PROG : 0;1924 1925	/* failures are fine because of maps like .rodata.str1.1 */1926	(void) map_fill_btf_type_info(obj, map);1927 1928	if (map_is_mmapable(obj, map))1929		def->map_flags |= BPF_F_MMAPABLE;1930 1931	pr_debug("map '%s' (global data): at sec_idx %d, offset %zu, flags %x.\n",1932		 map->name, map->sec_idx, map->sec_offset, def->map_flags);1933 1934	mmap_sz = bpf_map_mmap_sz(map);1935	map->mmaped = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,1936			   MAP_SHARED | MAP_ANONYMOUS, -1, 0);1937	if (map->mmaped == MAP_FAILED) {1938		err = -errno;1939		map->mmaped = NULL;1940		pr_warn("failed to alloc map '%s' content buffer: %d\n",1941			map->name, err);1942		zfree(&map->real_name);1943		zfree(&map->name);1944		return err;1945	}1946 1947	if (data)1948		memcpy(map->mmaped, data, data_sz);1949 1950	pr_debug("map %td is \"%s\"\n", map - obj->maps, map->name);1951	return 0;1952}1953 1954static int bpf_object__init_global_data_maps(struct bpf_object *obj)1955{1956	struct elf_sec_desc *sec_desc;1957	const char *sec_name;1958	int err = 0, sec_idx;1959 1960	/*1961	 * Populate obj->maps with libbpf internal maps.1962	 */1963	for (sec_idx = 1; sec_idx < obj->efile.sec_cnt; sec_idx++) {1964		sec_desc = &obj->efile.secs[sec_idx];1965 1966		/* Skip recognized sections with size 0. */1967		if (!sec_desc->data || sec_desc->data->d_size == 0)1968			continue;1969 1970		switch (sec_desc->sec_type) {1971		case SEC_DATA:1972			sec_name = elf_sec_name(obj, elf_sec_by_idx(obj, sec_idx));1973			err = bpf_object__init_internal_map(obj, LIBBPF_MAP_DATA,1974							    sec_name, sec_idx,1975							    sec_desc->data->d_buf,1976							    sec_desc->data->d_size);1977			break;1978		case SEC_RODATA:1979			obj->has_rodata = true;1980			sec_name = elf_sec_name(obj, elf_sec_by_idx(obj, sec_idx));1981			err = bpf_object__init_internal_map(obj, LIBBPF_MAP_RODATA,1982							    sec_name, sec_idx,1983							    sec_desc->data->d_buf,1984							    sec_desc->data->d_size);1985			break;1986		case SEC_BSS:1987			sec_name = elf_sec_name(obj, elf_sec_by_idx(obj, sec_idx));1988			err = bpf_object__init_internal_map(obj, LIBBPF_MAP_BSS,1989							    sec_name, sec_idx,1990							    NULL,1991							    sec_desc->data->d_size);1992			break;1993		default:1994			/* skip */1995			break;1996		}1997		if (err)1998			return err;1999	}2000	return 0;2001}2002 2003 2004static struct extern_desc *find_extern_by_name(const struct bpf_object *obj,2005					       const void *name)2006{2007	int i;2008 2009	for (i = 0; i < obj->nr_extern; i++) {2010		if (strcmp(obj->externs[i].name, name) == 0)2011			return &obj->externs[i];2012	}2013	return NULL;2014}2015 2016static struct extern_desc *find_extern_by_name_with_len(const struct bpf_object *obj,2017							const void *name, int len)2018{2019	const char *ext_name;2020	int i;2021 2022	for (i = 0; i < obj->nr_extern; i++) {2023		ext_name = obj->externs[i].name;2024		if (strlen(ext_name) == len && strncmp(ext_name, name, len) == 0)2025			return &obj->externs[i];2026	}2027	return NULL;2028}2029 2030static int set_kcfg_value_tri(struct extern_desc *ext, void *ext_val,2031			      char value)2032{2033	switch (ext->kcfg.type) {2034	case KCFG_BOOL:2035		if (value == 'm') {2036			pr_warn("extern (kcfg) '%s': value '%c' implies tristate or char type\n",2037				ext->name, value);2038			return -EINVAL;2039		}2040		*(bool *)ext_val = value == 'y' ? true : false;2041		break;2042	case KCFG_TRISTATE:2043		if (value == 'y')2044			*(enum libbpf_tristate *)ext_val = TRI_YES;2045		else if (value == 'm')2046			*(enum libbpf_tristate *)ext_val = TRI_MODULE;2047		else /* value == 'n' */2048			*(enum libbpf_tristate *)ext_val = TRI_NO;2049		break;2050	case KCFG_CHAR:2051		*(char *)ext_val = value;2052		break;2053	case KCFG_UNKNOWN:2054	case KCFG_INT:2055	case KCFG_CHAR_ARR:2056	default:2057		pr_warn("extern (kcfg) '%s': value '%c' implies bool, tristate, or char type\n",2058			ext->name, value);2059		return -EINVAL;2060	}2061	ext->is_set = true;2062	return 0;2063}2064 2065static int set_kcfg_value_str(struct extern_desc *ext, char *ext_val,2066			      const char *value)2067{2068	size_t len;2069 2070	if (ext->kcfg.type != KCFG_CHAR_ARR) {2071		pr_warn("extern (kcfg) '%s': value '%s' implies char array type\n",2072			ext->name, value);2073		return -EINVAL;2074	}2075 2076	len = strlen(value);2077	if (value[len - 1] != '"') {2078		pr_warn("extern (kcfg) '%s': invalid string config '%s'\n",2079			ext->name, value);2080		return -EINVAL;2081	}2082 2083	/* strip quotes */2084	len -= 2;2085	if (len >= ext->kcfg.sz) {2086		pr_warn("extern (kcfg) '%s': long string '%s' of (%zu bytes) truncated to %d bytes\n",2087			ext->name, value, len, ext->kcfg.sz - 1);2088		len = ext->kcfg.sz - 1;2089	}2090	memcpy(ext_val, value + 1, len);2091	ext_val[len] = '\0';2092	ext->is_set = true;2093	return 0;2094}2095 2096static int parse_u64(const char *value, __u64 *res)2097{2098	char *value_end;2099	int err;2100 2101	errno = 0;2102	*res = strtoull(value, &value_end, 0);2103	if (errno) {2104		err = -errno;2105		pr_warn("failed to parse '%s' as integer: %d\n", value, err);2106		return err;2107	}2108	if (*value_end) {2109		pr_warn("failed to parse '%s' as integer completely\n", value);2110		return -EINVAL;2111	}2112	return 0;2113}2114 2115static bool is_kcfg_value_in_range(const struct extern_desc *ext, __u64 v)2116{2117	int bit_sz = ext->kcfg.sz * 8;2118 2119	if (ext->kcfg.sz == 8)2120		return true;2121 2122	/* Validate that value stored in u64 fits in integer of `ext->sz`2123	 * bytes size without any loss of information. If the target integer2124	 * is signed, we rely on the following limits of integer type of2125	 * Y bits and subsequent transformation:2126	 *2127	 *     -2^(Y-1) <= X           <= 2^(Y-1) - 12128	 *            0 <= X + 2^(Y-1) <= 2^Y - 12129	 *            0 <= X + 2^(Y-1) <  2^Y2130	 *2131	 *  For unsigned target integer, check that all the (64 - Y) bits are2132	 *  zero.2133	 */2134	if (ext->kcfg.is_signed)2135		return v + (1ULL << (bit_sz - 1)) < (1ULL << bit_sz);2136	else2137		return (v >> bit_sz) == 0;2138}2139 2140static int set_kcfg_value_num(struct extern_desc *ext, void *ext_val,2141			      __u64 value)2142{2143	if (ext->kcfg.type != KCFG_INT && ext->kcfg.type != KCFG_CHAR &&2144	    ext->kcfg.type != KCFG_BOOL) {2145		pr_warn("extern (kcfg) '%s': value '%llu' implies integer, char, or boolean type\n",2146			ext->name, (unsigned long long)value);2147		return -EINVAL;2148	}2149	if (ext->kcfg.type == KCFG_BOOL && value > 1) {2150		pr_warn("extern (kcfg) '%s': value '%llu' isn't boolean compatible\n",2151			ext->name, (unsigned long long)value);2152		return -EINVAL;2153 2154	}2155	if (!is_kcfg_value_in_range(ext, value)) {2156		pr_warn("extern (kcfg) '%s': value '%llu' doesn't fit in %d bytes\n",2157			ext->name, (unsigned long long)value, ext->kcfg.sz);2158		return -ERANGE;2159	}2160	switch (ext->kcfg.sz) {2161	case 1:2162		*(__u8 *)ext_val = value;2163		break;2164	case 2:2165		*(__u16 *)ext_val = value;2166		break;2167	case 4:2168		*(__u32 *)ext_val = value;2169		break;2170	case 8:2171		*(__u64 *)ext_val = value;2172		break;2173	default:2174		return -EINVAL;2175	}2176	ext->is_set = true;2177	return 0;2178}2179 2180static int bpf_object__process_kconfig_line(struct bpf_object *obj,2181					    char *buf, void *data)2182{2183	struct extern_desc *ext;2184	char *sep, *value;2185	int len, err = 0;2186	void *ext_val;2187	__u64 num;2188 2189	if (!str_has_pfx(buf, "CONFIG_"))2190		return 0;2191 2192	sep = strchr(buf, '=');2193	if (!sep) {2194		pr_warn("failed to parse '%s': no separator\n", buf);2195		return -EINVAL;2196	}2197 2198	/* Trim ending '\n' */2199	len = strlen(buf);2200	if (buf[len - 1] == '\n')2201		buf[len - 1] = '\0';2202	/* Split on '=' and ensure that a value is present. */2203	*sep = '\0';2204	if (!sep[1]) {2205		*sep = '=';2206		pr_warn("failed to parse '%s': no value\n", buf);2207		return -EINVAL;2208	}2209 2210	ext = find_extern_by_name(obj, buf);2211	if (!ext || ext->is_set)2212		return 0;2213 2214	ext_val = data + ext->kcfg.data_off;2215	value = sep + 1;2216 2217	switch (*value) {2218	case 'y': case 'n': case 'm':2219		err = set_kcfg_value_tri(ext, ext_val, *value);2220		break;2221	case '"':2222		err = set_kcfg_value_str(ext, ext_val, value);2223		break;2224	default:2225		/* assume integer */2226		err = parse_u64(value, &num);2227		if (err) {2228			pr_warn("extern (kcfg) '%s': value '%s' isn't a valid integer\n", ext->name, value);2229			return err;2230		}2231		if (ext->kcfg.type != KCFG_INT && ext->kcfg.type != KCFG_CHAR) {2232			pr_warn("extern (kcfg) '%s': value '%s' implies integer type\n", ext->name, value);2233			return -EINVAL;2234		}2235		err = set_kcfg_value_num(ext, ext_val, num);2236		break;2237	}2238	if (err)2239		return err;2240	pr_debug("extern (kcfg) '%s': set to %s\n", ext->name, value);2241	return 0;2242}2243 2244static int bpf_object__read_kconfig_file(struct bpf_object *obj, void *data)2245{2246	char buf[PATH_MAX];2247	struct utsname uts;2248	int len, err = 0;2249	gzFile file;2250 2251	uname(&uts);2252	len = snprintf(buf, PATH_MAX, "/boot/config-%s", uts.release);2253	if (len < 0)2254		return -EINVAL;2255	else if (len >= PATH_MAX)2256		return -ENAMETOOLONG;2257 2258	/* gzopen also accepts uncompressed files. */2259	file = gzopen(buf, "re");2260	if (!file)2261		file = gzopen("/proc/config.gz", "re");2262 2263	if (!file) {2264		pr_warn("failed to open system Kconfig\n");2265		return -ENOENT;2266	}2267 2268	while (gzgets(file, buf, sizeof(buf))) {2269		err = bpf_object__process_kconfig_line(obj, buf, data);2270		if (err) {2271			pr_warn("error parsing system Kconfig line '%s': %d\n",2272				buf, err);2273			goto out;2274		}2275	}2276 2277out:2278	gzclose(file);2279	return err;2280}2281 2282static int bpf_object__read_kconfig_mem(struct bpf_object *obj,2283					const char *config, void *data)2284{2285	char buf[PATH_MAX];2286	int err = 0;2287	FILE *file;2288 2289	file = fmemopen((void *)config, strlen(config), "r");2290	if (!file) {2291		err = -errno;2292		pr_warn("failed to open in-memory Kconfig: %d\n", err);2293		return err;2294	}2295 2296	while (fgets(buf, sizeof(buf), file)) {2297		err = bpf_object__process_kconfig_line(obj, buf, data);2298		if (err) {2299			pr_warn("error parsing in-memory Kconfig line '%s': %d\n",2300				buf, err);2301			break;2302		}2303	}2304 2305	fclose(file);2306	return err;2307}2308 2309static int bpf_object__init_kconfig_map(struct bpf_object *obj)2310{2311	struct extern_desc *last_ext = NULL, *ext;2312	size_t map_sz;2313	int i, err;2314 2315	for (i = 0; i < obj->nr_extern; i++) {2316		ext = &obj->externs[i];2317		if (ext->type == EXT_KCFG)2318			last_ext = ext;2319	}2320 2321	if (!last_ext)2322		return 0;2323 2324	map_sz = last_ext->kcfg.data_off + last_ext->kcfg.sz;2325	err = bpf_object__init_internal_map(obj, LIBBPF_MAP_KCONFIG,2326					    ".kconfig", obj->efile.symbols_shndx,2327					    NULL, map_sz);2328	if (err)2329		return err;2330 2331	obj->kconfig_map_idx = obj->nr_maps - 1;2332 2333	return 0;2334}2335 2336const struct btf_type *2337skip_mods_and_typedefs(const struct btf *btf, __u32 id, __u32 *res_id)2338{2339	const struct btf_type *t = btf__type_by_id(btf, id);2340 2341	if (res_id)2342		*res_id = id;2343 2344	while (btf_is_mod(t) || btf_is_typedef(t)) {2345		if (res_id)2346			*res_id = t->type;2347		t = btf__type_by_id(btf, t->type);2348	}2349 2350	return t;2351}2352 2353static const struct btf_type *2354resolve_func_ptr(const struct btf *btf, __u32 id, __u32 *res_id)2355{2356	const struct btf_type *t;2357 2358	t = skip_mods_and_typedefs(btf, id, NULL);2359	if (!btf_is_ptr(t))2360		return NULL;2361 2362	t = skip_mods_and_typedefs(btf, t->type, res_id);2363 2364	return btf_is_func_proto(t) ? t : NULL;2365}2366 2367static const char *__btf_kind_str(__u16 kind)2368{2369	switch (kind) {2370	case BTF_KIND_UNKN: return "void";2371	case BTF_KIND_INT: return "int";2372	case BTF_KIND_PTR: return "ptr";2373	case BTF_KIND_ARRAY: return "array";2374	case BTF_KIND_STRUCT: return "struct";2375	case BTF_KIND_UNION: return "union";2376	case BTF_KIND_ENUM: return "enum";2377	case BTF_KIND_FWD: return "fwd";2378	case BTF_KIND_TYPEDEF: return "typedef";2379	case BTF_KIND_VOLATILE: return "volatile";2380	case BTF_KIND_CONST: return "const";2381	case BTF_KIND_RESTRICT: return "restrict";2382	case BTF_KIND_FUNC: return "func";2383	case BTF_KIND_FUNC_PROTO: return "func_proto";2384	case BTF_KIND_VAR: return "var";2385	case BTF_KIND_DATASEC: return "datasec";2386	case BTF_KIND_FLOAT: return "float";2387	case BTF_KIND_DECL_TAG: return "decl_tag";2388	case BTF_KIND_TYPE_TAG: return "type_tag";2389	case BTF_KIND_ENUM64: return "enum64";2390	default: return "unknown";2391	}2392}2393 2394const char *btf_kind_str(const struct btf_type *t)2395{2396	return __btf_kind_str(btf_kind(t));2397}2398 2399/*2400 * Fetch integer attribute of BTF map definition. Such attributes are2401 * represented using a pointer to an array, in which dimensionality of array2402 * encodes specified integer value. E.g., int (*type)[BPF_MAP_TYPE_ARRAY];2403 * encodes `type => BPF_MAP_TYPE_ARRAY` key/value pair completely using BTF2404 * type definition, while using only sizeof(void *) space in ELF data section.2405 */2406static bool get_map_field_int(const char *map_name, const struct btf *btf,2407			      const struct btf_member *m, __u32 *res)2408{2409	const struct btf_type *t = skip_mods_and_typedefs(btf, m->type, NULL);2410	const char *name = btf__name_by_offset(btf, m->name_off);2411	const struct btf_array *arr_info;2412	const struct btf_type *arr_t;2413 2414	if (!btf_is_ptr(t)) {2415		pr_warn("map '%s': attr '%s': expected PTR, got %s.\n",2416			map_name, name, btf_kind_str(t));2417		return false;2418	}2419 2420	arr_t = btf__type_by_id(btf, t->type);2421	if (!arr_t) {2422		pr_warn("map '%s': attr '%s': type [%u] not found.\n",2423			map_name, name, t->type);2424		return false;2425	}2426	if (!btf_is_array(arr_t)) {2427		pr_warn("map '%s': attr '%s': expected ARRAY, got %s.\n",2428			map_name, name, btf_kind_str(arr_t));2429		return false;2430	}2431	arr_info = btf_array(arr_t);2432	*res = arr_info->nelems;2433	return true;2434}2435 2436static bool get_map_field_long(const char *map_name, const struct btf *btf,2437			       const struct btf_member *m, __u64 *res)2438{2439	const struct btf_type *t = skip_mods_and_typedefs(btf, m->type, NULL);2440	const char *name = btf__name_by_offset(btf, m->name_off);2441 2442	if (btf_is_ptr(t)) {2443		__u32 res32;2444		bool ret;2445 2446		ret = get_map_field_int(map_name, btf, m, &res32);2447		if (ret)2448			*res = (__u64)res32;2449		return ret;2450	}2451 2452	if (!btf_is_enum(t) && !btf_is_enum64(t)) {2453		pr_warn("map '%s': attr '%s': expected ENUM or ENUM64, got %s.\n",2454			map_name, name, btf_kind_str(t));2455		return false;2456	}2457 2458	if (btf_vlen(t) != 1) {2459		pr_warn("map '%s': attr '%s': invalid __ulong\n",2460			map_name, name);2461		return false;2462	}2463 2464	if (btf_is_enum(t)) {2465		const struct btf_enum *e = btf_enum(t);2466 2467		*res = e->val;2468	} else {2469		const struct btf_enum64 *e = btf_enum64(t);2470 2471		*res = btf_enum64_value(e);2472	}2473	return true;2474}2475 2476static int pathname_concat(char *buf, size_t buf_sz, const char *path, const char *name)2477{2478	int len;2479 2480	len = snprintf(buf, buf_sz, "%s/%s", path, name);2481	if (len < 0)2482		return -EINVAL;2483	if (len >= buf_sz)2484		return -ENAMETOOLONG;2485 2486	return 0;2487}2488 2489static int build_map_pin_path(struct bpf_map *map, const char *path)2490{2491	char buf[PATH_MAX];2492	int err;2493 2494	if (!path)2495		path = BPF_FS_DEFAULT_PATH;2496 2497	err = pathname_concat(buf, sizeof(buf), path, bpf_map__name(map));2498	if (err)2499		return err;2500 2501	return bpf_map__set_pin_path(map, buf);2502}2503 2504/* should match definition in bpf_helpers.h */2505enum libbpf_pin_type {2506	LIBBPF_PIN_NONE,2507	/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */2508	LIBBPF_PIN_BY_NAME,2509};2510 2511int parse_btf_map_def(const char *map_name, struct btf *btf,2512		      const struct btf_type *def_t, bool strict,2513		      struct btf_map_def *map_def, struct btf_map_def *inner_def)2514{2515	const struct btf_type *t;2516	const struct btf_member *m;2517	bool is_inner = inner_def == NULL;2518	int vlen, i;2519 2520	vlen = btf_vlen(def_t);2521	m = btf_members(def_t);2522	for (i = 0; i < vlen; i++, m++) {2523		const char *name = btf__name_by_offset(btf, m->name_off);2524 2525		if (!name) {2526			pr_warn("map '%s': invalid field #%d.\n", map_name, i);2527			return -EINVAL;2528		}2529		if (strcmp(name, "type") == 0) {2530			if (!get_map_field_int(map_name, btf, m, &map_def->map_type))2531				return -EINVAL;2532			map_def->parts |= MAP_DEF_MAP_TYPE;2533		} else if (strcmp(name, "max_entries") == 0) {2534			if (!get_map_field_int(map_name, btf, m, &map_def->max_entries))2535				return -EINVAL;2536			map_def->parts |= MAP_DEF_MAX_ENTRIES;2537		} else if (strcmp(name, "map_flags") == 0) {2538			if (!get_map_field_int(map_name, btf, m, &map_def->map_flags))2539				return -EINVAL;2540			map_def->parts |= MAP_DEF_MAP_FLAGS;2541		} else if (strcmp(name, "numa_node") == 0) {2542			if (!get_map_field_int(map_name, btf, m, &map_def->numa_node))2543				return -EINVAL;2544			map_def->parts |= MAP_DEF_NUMA_NODE;2545		} else if (strcmp(name, "key_size") == 0) {2546			__u32 sz;2547 2548			if (!get_map_field_int(map_name, btf, m, &sz))2549				return -EINVAL;2550			if (map_def->key_size && map_def->key_size != sz) {2551				pr_warn("map '%s': conflicting key size %u != %u.\n",2552					map_name, map_def->key_size, sz);2553				return -EINVAL;2554			}2555			map_def->key_size = sz;2556			map_def->parts |= MAP_DEF_KEY_SIZE;2557		} else if (strcmp(name, "key") == 0) {2558			__s64 sz;2559 2560			t = btf__type_by_id(btf, m->type);2561			if (!t) {2562				pr_warn("map '%s': key type [%d] not found.\n",2563					map_name, m->type);2564				return -EINVAL;2565			}2566			if (!btf_is_ptr(t)) {2567				pr_warn("map '%s': key spec is not PTR: %s.\n",2568					map_name, btf_kind_str(t));2569				return -EINVAL;2570			}2571			sz = btf__resolve_size(btf, t->type);2572			if (sz < 0) {2573				pr_warn("map '%s': can't determine key size for type [%u]: %zd.\n",2574					map_name, t->type, (ssize_t)sz);2575				return sz;2576			}2577			if (map_def->key_size && map_def->key_size != sz) {2578				pr_warn("map '%s': conflicting key size %u != %zd.\n",2579					map_name, map_def->key_size, (ssize_t)sz);2580				return -EINVAL;2581			}2582			map_def->key_size = sz;2583			map_def->key_type_id = t->type;2584			map_def->parts |= MAP_DEF_KEY_SIZE | MAP_DEF_KEY_TYPE;2585		} else if (strcmp(name, "value_size") == 0) {2586			__u32 sz;2587 2588			if (!get_map_field_int(map_name, btf, m, &sz))2589				return -EINVAL;2590			if (map_def->value_size && map_def->value_size != sz) {2591				pr_warn("map '%s': conflicting value size %u != %u.\n",2592					map_name, map_def->value_size, sz);2593				return -EINVAL;2594			}2595			map_def->value_size = sz;2596			map_def->parts |= MAP_DEF_VALUE_SIZE;2597		} else if (strcmp(name, "value") == 0) {2598			__s64 sz;2599 2600			t = btf__type_by_id(btf, m->type);2601			if (!t) {2602				pr_warn("map '%s': value type [%d] not found.\n",2603					map_name, m->type);2604				return -EINVAL;2605			}2606			if (!btf_is_ptr(t)) {2607				pr_warn("map '%s': value spec is not PTR: %s.\n",2608					map_name, btf_kind_str(t));2609				return -EINVAL;2610			}2611			sz = btf__resolve_size(btf, t->type);2612			if (sz < 0) {2613				pr_warn("map '%s': can't determine value size for type [%u]: %zd.\n",2614					map_name, t->type, (ssize_t)sz);2615				return sz;2616			}2617			if (map_def->value_size && map_def->value_size != sz) {2618				pr_warn("map '%s': conflicting value size %u != %zd.\n",2619					map_name, map_def->value_size, (ssize_t)sz);2620				return -EINVAL;2621			}2622			map_def->value_size = sz;2623			map_def->value_type_id = t->type;2624			map_def->parts |= MAP_DEF_VALUE_SIZE | MAP_DEF_VALUE_TYPE;2625		}2626		else if (strcmp(name, "values") == 0) {2627			bool is_map_in_map = bpf_map_type__is_map_in_map(map_def->map_type);2628			bool is_prog_array = map_def->map_type == BPF_MAP_TYPE_PROG_ARRAY;2629			const char *desc = is_map_in_map ? "map-in-map inner" : "prog-array value";2630			char inner_map_name[128];2631			int err;2632 2633			if (is_inner) {2634				pr_warn("map '%s': multi-level inner maps not supported.\n",2635					map_name);2636				return -ENOTSUP;2637			}2638			if (i != vlen - 1) {2639				pr_warn("map '%s': '%s' member should be last.\n",2640					map_name, name);2641				return -EINVAL;2642			}2643			if (!is_map_in_map && !is_prog_array) {2644				pr_warn("map '%s': should be map-in-map or prog-array.\n",2645					map_name);2646				return -ENOTSUP;2647			}2648			if (map_def->value_size && map_def->value_size != 4) {2649				pr_warn("map '%s': conflicting value size %u != 4.\n",2650					map_name, map_def->value_size);2651				return -EINVAL;2652			}2653			map_def->value_size = 4;2654			t = btf__type_by_id(btf, m->type);2655			if (!t) {2656				pr_warn("map '%s': %s type [%d] not found.\n",2657					map_name, desc, m->type);2658				return -EINVAL;2659			}2660			if (!btf_is_array(t) || btf_array(t)->nelems) {2661				pr_warn("map '%s': %s spec is not a zero-sized array.\n",2662					map_name, desc);2663				return -EINVAL;2664			}2665			t = skip_mods_and_typedefs(btf, btf_array(t)->type, NULL);2666			if (!btf_is_ptr(t)) {2667				pr_warn("map '%s': %s def is of unexpected kind %s.\n",2668					map_name, desc, btf_kind_str(t));2669				return -EINVAL;2670			}2671			t = skip_mods_and_typedefs(btf, t->type, NULL);2672			if (is_prog_array) {2673				if (!btf_is_func_proto(t)) {2674					pr_warn("map '%s': prog-array value def is of unexpected kind %s.\n",2675						map_name, btf_kind_str(t));2676					return -EINVAL;2677				}2678				continue;2679			}2680			if (!btf_is_struct(t)) {2681				pr_warn("map '%s': map-in-map inner def is of unexpected kind %s.\n",2682					map_name, btf_kind_str(t));2683				return -EINVAL;2684			}2685 2686			snprintf(inner_map_name, sizeof(inner_map_name), "%s.inner", map_name);2687			err = parse_btf_map_def(inner_map_name, btf, t, strict, inner_def, NULL);2688			if (err)2689				return err;2690 2691			map_def->parts |= MAP_DEF_INNER_MAP;2692		} else if (strcmp(name, "pinning") == 0) {2693			__u32 val;2694 2695			if (is_inner) {2696				pr_warn("map '%s': inner def can't be pinned.\n", map_name);2697				return -EINVAL;2698			}2699			if (!get_map_field_int(map_name, btf, m, &val))2700				return -EINVAL;2701			if (val != LIBBPF_PIN_NONE && val != LIBBPF_PIN_BY_NAME) {2702				pr_warn("map '%s': invalid pinning value %u.\n",2703					map_name, val);2704				return -EINVAL;2705			}2706			map_def->pinning = val;2707			map_def->parts |= MAP_DEF_PINNING;2708		} else if (strcmp(name, "map_extra") == 0) {2709			__u64 map_extra;2710 2711			if (!get_map_field_long(map_name, btf, m, &map_extra))2712				return -EINVAL;2713			map_def->map_extra = map_extra;2714			map_def->parts |= MAP_DEF_MAP_EXTRA;2715		} else {2716			if (strict) {2717				pr_warn("map '%s': unknown field '%s'.\n", map_name, name);2718				return -ENOTSUP;2719			}2720			pr_debug("map '%s': ignoring unknown field '%s'.\n", map_name, name);2721		}2722	}2723 2724	if (map_def->map_type == BPF_MAP_TYPE_UNSPEC) {2725		pr_warn("map '%s': map type isn't specified.\n", map_name);2726		return -EINVAL;2727	}2728 2729	return 0;2730}2731 2732static size_t adjust_ringbuf_sz(size_t sz)2733{2734	__u32 page_sz = sysconf(_SC_PAGE_SIZE);2735	__u32 mul;2736 2737	/* if user forgot to set any size, make sure they see error */2738	if (sz == 0)2739		return 0;2740	/* Kernel expects BPF_MAP_TYPE_RINGBUF's max_entries to be2741	 * a power-of-2 multiple of kernel's page size. If user diligently2742	 * satisified these conditions, pass the size through.2743	 */2744	if ((sz % page_sz) == 0 && is_pow_of_2(sz / page_sz))2745		return sz;2746 2747	/* Otherwise find closest (page_sz * power_of_2) product bigger than2748	 * user-set size to satisfy both user size request and kernel2749	 * requirements and substitute correct max_entries for map creation.2750	 */2751	for (mul = 1; mul <= UINT_MAX / page_sz; mul <<= 1) {2752		if (mul * page_sz > sz)2753			return mul * page_sz;2754	}2755 2756	/* if it's impossible to satisfy the conditions (i.e., user size is2757	 * very close to UINT_MAX but is not a power-of-2 multiple of2758	 * page_size) then just return original size and let kernel reject it2759	 */2760	return sz;2761}2762 2763static bool map_is_ringbuf(const struct bpf_map *map)2764{2765	return map->def.type == BPF_MAP_TYPE_RINGBUF ||2766	       map->def.type == BPF_MAP_TYPE_USER_RINGBUF;2767}2768 2769static void fill_map_from_def(struct bpf_map *map, const struct btf_map_def *def)2770{2771	map->def.type = def->map_type;2772	map->def.key_size = def->key_size;2773	map->def.value_size = def->value_size;2774	map->def.max_entries = def->max_entries;2775	map->def.map_flags = def->map_flags;2776	map->map_extra = def->map_extra;2777 2778	map->numa_node = def->numa_node;2779	map->btf_key_type_id = def->key_type_id;2780	map->btf_value_type_id = def->value_type_id;2781 2782	/* auto-adjust BPF ringbuf map max_entries to be a multiple of page size */2783	if (map_is_ringbuf(map))2784		map->def.max_entries = adjust_ringbuf_sz(map->def.max_entries);2785 2786	if (def->parts & MAP_DEF_MAP_TYPE)2787		pr_debug("map '%s': found type = %u.\n", map->name, def->map_type);2788 2789	if (def->parts & MAP_DEF_KEY_TYPE)2790		pr_debug("map '%s': found key [%u], sz = %u.\n",2791			 map->name, def->key_type_id, def->key_size);2792	else if (def->parts & MAP_DEF_KEY_SIZE)2793		pr_debug("map '%s': found key_size = %u.\n", map->name, def->key_size);2794 2795	if (def->parts & MAP_DEF_VALUE_TYPE)2796		pr_debug("map '%s': found value [%u], sz = %u.\n",2797			 map->name, def->value_type_id, def->value_size);2798	else if (def->parts & MAP_DEF_VALUE_SIZE)2799		pr_debug("map '%s': found value_size = %u.\n", map->name, def->value_size);2800 2801	if (def->parts & MAP_DEF_MAX_ENTRIES)2802		pr_debug("map '%s': found max_entries = %u.\n", map->name, def->max_entries);2803	if (def->parts & MAP_DEF_MAP_FLAGS)2804		pr_debug("map '%s': found map_flags = 0x%x.\n", map->name, def->map_flags);2805	if (def->parts & MAP_DEF_MAP_EXTRA)2806		pr_debug("map '%s': found map_extra = 0x%llx.\n", map->name,2807			 (unsigned long long)def->map_extra);2808	if (def->parts & MAP_DEF_PINNING)2809		pr_debug("map '%s': found pinning = %u.\n", map->name, def->pinning);2810	if (def->parts & MAP_DEF_NUMA_NODE)2811		pr_debug("map '%s': found numa_node = %u.\n", map->name, def->numa_node);2812 2813	if (def->parts & MAP_DEF_INNER_MAP)2814		pr_debug("map '%s': found inner map definition.\n", map->name);2815}2816 2817static const char *btf_var_linkage_str(__u32 linkage)2818{2819	switch (linkage) {2820	case BTF_VAR_STATIC: return "static";2821	case BTF_VAR_GLOBAL_ALLOCATED: return "global";2822	case BTF_VAR_GLOBAL_EXTERN: return "extern";2823	default: return "unknown";2824	}2825}2826 2827static int bpf_object__init_user_btf_map(struct bpf_object *obj,2828					 const struct btf_type *sec,2829					 int var_idx, int sec_idx,2830					 const Elf_Data *data, bool strict,2831					 const char *pin_root_path)2832{2833	struct btf_map_def map_def = {}, inner_def = {};2834	const struct btf_type *var, *def;2835	const struct btf_var_secinfo *vi;2836	const struct btf_var *var_extra;2837	const char *map_name;2838	struct bpf_map *map;2839	int err;2840 2841	vi = btf_var_secinfos(sec) + var_idx;2842	var = btf__type_by_id(obj->btf, vi->type);2843	var_extra = btf_var(var);2844	map_name = btf__name_by_offset(obj->btf, var->name_off);2845 2846	if (map_name == NULL || map_name[0] == '\0') {2847		pr_warn("map #%d: empty name.\n", var_idx);2848		return -EINVAL;2849	}2850	if ((__u64)vi->offset + vi->size > data->d_size) {2851		pr_warn("map '%s' BTF data is corrupted.\n", map_name);2852		return -EINVAL;2853	}2854	if (!btf_is_var(var)) {2855		pr_warn("map '%s': unexpected var kind %s.\n",2856			map_name, btf_kind_str(var));2857		return -EINVAL;2858	}2859	if (var_extra->linkage != BTF_VAR_GLOBAL_ALLOCATED) {2860		pr_warn("map '%s': unsupported map linkage %s.\n",2861			map_name, btf_var_linkage_str(var_extra->linkage));2862		return -EOPNOTSUPP;2863	}2864 2865	def = skip_mods_and_typedefs(obj->btf, var->type, NULL);2866	if (!btf_is_struct(def)) {2867		pr_warn("map '%s': unexpected def kind %s.\n",2868			map_name, btf_kind_str(var));2869		return -EINVAL;2870	}2871	if (def->size > vi->size) {2872		pr_warn("map '%s': invalid def size.\n", map_name);2873		return -EINVAL;2874	}2875 2876	map = bpf_object__add_map(obj);2877	if (IS_ERR(map))2878		return PTR_ERR(map);2879	map->name = strdup(map_name);2880	if (!map->name) {2881		pr_warn("map '%s': failed to alloc map name.\n", map_name);2882		return -ENOMEM;2883	}2884	map->libbpf_type = LIBBPF_MAP_UNSPEC;2885	map->def.type = BPF_MAP_TYPE_UNSPEC;2886	map->sec_idx = sec_idx;2887	map->sec_offset = vi->offset;2888	map->btf_var_idx = var_idx;2889	pr_debug("map '%s': at sec_idx %d, offset %zu.\n",2890		 map_name, map->sec_idx, map->sec_offset);2891 2892	err = parse_btf_map_def(map->name, obj->btf, def, strict, &map_def, &inner_def);2893	if (err)2894		return err;2895 2896	fill_map_from_def(map, &map_def);2897 2898	if (map_def.pinning == LIBBPF_PIN_BY_NAME) {2899		err = build_map_pin_path(map, pin_root_path);2900		if (err) {2901			pr_warn("map '%s': couldn't build pin path.\n", map->name);2902			return err;2903		}2904	}2905 2906	if (map_def.parts & MAP_DEF_INNER_MAP) {2907		map->inner_map = calloc(1, sizeof(*map->inner_map));2908		if (!map->inner_map)2909			return -ENOMEM;2910		map->inner_map->fd = create_placeholder_fd();2911		if (map->inner_map->fd < 0)2912			return map->inner_map->fd;2913		map->inner_map->sec_idx = sec_idx;2914		map->inner_map->name = malloc(strlen(map_name) + sizeof(".inner") + 1);2915		if (!map->inner_map->name)2916			return -ENOMEM;2917		sprintf(map->inner_map->name, "%s.inner", map_name);2918 2919		fill_map_from_def(map->inner_map, &inner_def);2920	}2921 2922	err = map_fill_btf_type_info(obj, map);2923	if (err)2924		return err;2925 2926	return 0;2927}2928 2929static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map,2930			       const char *sec_name, int sec_idx,2931			       void *data, size_t data_sz)2932{2933	const long page_sz = sysconf(_SC_PAGE_SIZE);2934	size_t mmap_sz;2935 2936	mmap_sz = bpf_map_mmap_sz(obj->arena_map);2937	if (roundup(data_sz, page_sz) > mmap_sz) {2938		pr_warn("elf: sec '%s': declared ARENA map size (%zu) is too small to hold global __arena variables of size %zu\n",2939			sec_name, mmap_sz, data_sz);2940		return -E2BIG;2941	}2942 2943	obj->arena_data = malloc(data_sz);2944	if (!obj->arena_data)2945		return -ENOMEM;2946	memcpy(obj->arena_data, data, data_sz);2947	obj->arena_data_sz = data_sz;2948 2949	/* make bpf_map__init_value() work for ARENA maps */2950	map->mmaped = obj->arena_data;2951 2952	return 0;2953}2954 2955static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict,2956					  const char *pin_root_path)2957{2958	const struct btf_type *sec = NULL;2959	int nr_types, i, vlen, err;2960	const struct btf_type *t;2961	const char *name;2962	Elf_Data *data;2963	Elf_Scn *scn;2964 2965	if (obj->efile.btf_maps_shndx < 0)2966		return 0;2967 2968	scn = elf_sec_by_idx(obj, obj->efile.btf_maps_shndx);2969	data = elf_sec_data(obj, scn);2970	if (!scn || !data) {2971		pr_warn("elf: failed to get %s map definitions for %s\n",2972			MAPS_ELF_SEC, obj->path);2973		return -EINVAL;2974	}2975 2976	nr_types = btf__type_cnt(obj->btf);2977	for (i = 1; i < nr_types; i++) {2978		t = btf__type_by_id(obj->btf, i);2979		if (!btf_is_datasec(t))2980			continue;2981		name = btf__name_by_offset(obj->btf, t->name_off);2982		if (strcmp(name, MAPS_ELF_SEC) == 0) {2983			sec = t;2984			obj->efile.btf_maps_sec_btf_id = i;2985			break;2986		}2987	}2988 2989	if (!sec) {2990		pr_warn("DATASEC '%s' not found.\n", MAPS_ELF_SEC);2991		return -ENOENT;2992	}2993 2994	vlen = btf_vlen(sec);2995	for (i = 0; i < vlen; i++) {2996		err = bpf_object__init_user_btf_map(obj, sec, i,2997						    obj->efile.btf_maps_shndx,2998						    data, strict,2999						    pin_root_path);3000		if (err)3001			return err;3002	}3003 3004	for (i = 0; i < obj->nr_maps; i++) {3005		struct bpf_map *map = &obj->maps[i];3006 3007		if (map->def.type != BPF_MAP_TYPE_ARENA)3008			continue;3009 3010		if (obj->arena_map) {3011			pr_warn("map '%s': only single ARENA map is supported (map '%s' is also ARENA)\n",3012				map->name, obj->arena_map->name);3013			return -EINVAL;3014		}3015		obj->arena_map = map;3016 3017		if (obj->efile.arena_data) {3018			err = init_arena_map_data(obj, map, ARENA_SEC, obj->efile.arena_data_shndx,3019						  obj->efile.arena_data->d_buf,3020						  obj->efile.arena_data->d_size);3021			if (err)3022				return err;3023		}3024	}3025	if (obj->efile.arena_data && !obj->arena_map) {3026		pr_warn("elf: sec '%s': to use global __arena variables the ARENA map should be explicitly declared in SEC(\".maps\")\n",3027			ARENA_SEC);3028		return -ENOENT;3029	}3030 3031	return 0;3032}3033 3034static int bpf_object__init_maps(struct bpf_object *obj,3035				 const struct bpf_object_open_opts *opts)3036{3037	const char *pin_root_path;3038	bool strict;3039	int err = 0;3040 3041	strict = !OPTS_GET(opts, relaxed_maps, false);3042	pin_root_path = OPTS_GET(opts, pin_root_path, NULL);3043 3044	err = bpf_object__init_user_btf_maps(obj, strict, pin_root_path);3045	err = err ?: bpf_object__init_global_data_maps(obj);3046	err = err ?: bpf_object__init_kconfig_map(obj);3047	err = err ?: bpf_object_init_struct_ops(obj);3048 3049	return err;3050}3051 3052static bool section_have_execinstr(struct bpf_object *obj, int idx)3053{3054	Elf64_Shdr *sh;3055 3056	sh = elf_sec_hdr(obj, elf_sec_by_idx(obj, idx));3057	if (!sh)3058		return false;3059 3060	return sh->sh_flags & SHF_EXECINSTR;3061}3062 3063static bool starts_with_qmark(const char *s)3064{3065	return s && s[0] == '?';3066}3067 3068static bool btf_needs_sanitization(struct bpf_object *obj)3069{3070	bool has_func_global = kernel_supports(obj, FEAT_BTF_GLOBAL_FUNC);3071	bool has_datasec = kernel_supports(obj, FEAT_BTF_DATASEC);3072	bool has_float = kernel_supports(obj, FEAT_BTF_FLOAT);3073	bool has_func = kernel_supports(obj, FEAT_BTF_FUNC);3074	bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG);3075	bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG);3076	bool has_enum64 = kernel_supports(obj, FEAT_BTF_ENUM64);3077	bool has_qmark_datasec = kernel_supports(obj, FEAT_BTF_QMARK_DATASEC);3078 3079	return !has_func || !has_datasec || !has_func_global || !has_float ||3080	       !has_decl_tag || !has_type_tag || !has_enum64 || !has_qmark_datasec;3081}3082 3083static int bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)3084{3085	bool has_func_global = kernel_supports(obj, FEAT_BTF_GLOBAL_FUNC);3086	bool has_datasec = kernel_supports(obj, FEAT_BTF_DATASEC);3087	bool has_float = kernel_supports(obj, FEAT_BTF_FLOAT);3088	bool has_func = kernel_supports(obj, FEAT_BTF_FUNC);3089	bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG);3090	bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG);3091	bool has_enum64 = kernel_supports(obj, FEAT_BTF_ENUM64);3092	bool has_qmark_datasec = kernel_supports(obj, FEAT_BTF_QMARK_DATASEC);3093	int enum64_placeholder_id = 0;3094	struct btf_type *t;3095	int i, j, vlen;3096 3097	for (i = 1; i < btf__type_cnt(btf); i++) {3098		t = (struct btf_type *)btf__type_by_id(btf, i);3099 3100		if ((!has_datasec && btf_is_var(t)) || (!has_decl_tag && btf_is_decl_tag(t))) {3101			/* replace VAR/DECL_TAG with INT */3102			t->info = BTF_INFO_ENC(BTF_KIND_INT, 0, 0);3103			/*3104			 * using size = 1 is the safest choice, 4 will be too3105			 * big and cause kernel BTF validation failure if3106			 * original variable took less than 4 bytes3107			 */3108			t->size = 1;3109			*(int *)(t + 1) = BTF_INT_ENC(0, 0, 8);3110		} else if (!has_datasec && btf_is_datasec(t)) {3111			/* replace DATASEC with STRUCT */3112			const struct btf_var_secinfo *v = btf_var_secinfos(t);3113			struct btf_member *m = btf_members(t);3114			struct btf_type *vt;3115			char *name;3116 3117			name = (char *)btf__name_by_offset(btf, t->name_off);3118			while (*name) {3119				if (*name == '.' || *name == '?')3120					*name = '_';3121				name++;3122			}3123 3124			vlen = btf_vlen(t);3125			t->info = BTF_INFO_ENC(BTF_KIND_STRUCT, 0, vlen);3126			for (j = 0; j < vlen; j++, v++, m++) {3127				/* order of field assignments is important */3128				m->offset = v->offset * 8;3129				m->type = v->type;3130				/* preserve variable name as member name */3131				vt = (void *)btf__type_by_id(btf, v->type);3132				m->name_off = vt->name_off;3133			}3134		} else if (!has_qmark_datasec && btf_is_datasec(t) &&3135			   starts_with_qmark(btf__name_by_offset(btf, t->name_off))) {3136			/* replace '?' prefix with '_' for DATASEC names */3137			char *name;3138 3139			name = (char *)btf__name_by_offset(btf, t->name_off);3140			if (name[0] == '?')3141				name[0] = '_';3142		} else if (!has_func && btf_is_func_proto(t)) {3143			/* replace FUNC_PROTO with ENUM */3144			vlen = btf_vlen(t);3145			t->info = BTF_INFO_ENC(BTF_KIND_ENUM, 0, vlen);3146			t->size = sizeof(__u32); /* kernel enforced */3147		} else if (!has_func && btf_is_func(t)) {3148			/* replace FUNC with TYPEDEF */3149			t->info = BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0);3150		} else if (!has_func_global && btf_is_func(t)) {3151			/* replace BTF_FUNC_GLOBAL with BTF_FUNC_STATIC */3152			t->info = BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0);3153		} else if (!has_float && btf_is_float(t)) {3154			/* replace FLOAT with an equally-sized empty STRUCT;3155			 * since C compilers do not accept e.g. "float" as a3156			 * valid struct name, make it anonymous3157			 */3158			t->name_off = 0;3159			t->info = BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 0);3160		} else if (!has_type_tag && btf_is_type_tag(t)) {3161			/* replace TYPE_TAG with a CONST */3162			t->name_off = 0;3163			t->info = BTF_INFO_ENC(BTF_KIND_CONST, 0, 0);3164		} else if (!has_enum64 && btf_is_enum(t)) {3165			/* clear the kflag */3166			t->info = btf_type_info(btf_kind(t), btf_vlen(t), false);3167		} else if (!has_enum64 && btf_is_enum64(t)) {3168			/* replace ENUM64 with a union */3169			struct btf_member *m;3170 3171			if (enum64_placeholder_id == 0) {3172				enum64_placeholder_id = btf__add_int(btf, "enum64_placeholder", 1, 0);3173				if (enum64_placeholder_id < 0)3174					return enum64_placeholder_id;3175 3176				t = (struct btf_type *)btf__type_by_id(btf, i);3177			}3178 3179			m = btf_members(t);3180			vlen = btf_vlen(t);3181			t->info = BTF_INFO_ENC(BTF_KIND_UNION, 0, vlen);3182			for (j = 0; j < vlen; j++, m++) {3183				m->type = enum64_placeholder_id;3184				m->offset = 0;3185			}3186		}3187	}3188 3189	return 0;3190}3191 3192static bool libbpf_needs_btf(const struct bpf_object *obj)3193{3194	return obj->efile.btf_maps_shndx >= 0 ||3195	       obj->efile.has_st_ops ||3196	       obj->nr_extern > 0;3197}3198 3199static bool kernel_needs_btf(const struct bpf_object *obj)3200{3201	return obj->efile.has_st_ops;3202}3203 3204static int bpf_object__init_btf(struct bpf_object *obj,3205				Elf_Data *btf_data,3206				Elf_Data *btf_ext_data)3207{3208	int err = -ENOENT;3209 3210	if (btf_data) {3211		obj->btf = btf__new(btf_data->d_buf, btf_data->d_size);3212		err = libbpf_get_error(obj->btf);3213		if (err) {3214			obj->btf = NULL;3215			pr_warn("Error loading ELF section %s: %d.\n", BTF_ELF_SEC, err);3216			goto out;3217		}3218		/* enforce 8-byte pointers for BPF-targeted BTFs */3219		btf__set_pointer_size(obj->btf, 8);3220	}3221	if (btf_ext_data) {3222		struct btf_ext_info *ext_segs[3];3223		int seg_num, sec_num;3224 3225		if (!obj->btf) {3226			pr_debug("Ignore ELF section %s because its depending ELF section %s is not found.\n",3227				 BTF_EXT_ELF_SEC, BTF_ELF_SEC);3228			goto out;3229		}3230		obj->btf_ext = btf_ext__new(btf_ext_data->d_buf, btf_ext_data->d_size);3231		err = libbpf_get_error(obj->btf_ext);3232		if (err) {3233			pr_warn("Error loading ELF section %s: %d. Ignored and continue.\n",3234				BTF_EXT_ELF_SEC, err);3235			obj->btf_ext = NULL;3236			goto out;3237		}3238 3239		/* setup .BTF.ext to ELF section mapping */3240		ext_segs[0] = &obj->btf_ext->func_info;3241		ext_segs[1] = &obj->btf_ext->line_info;3242		ext_segs[2] = &obj->btf_ext->core_relo_info;3243		for (seg_num = 0; seg_num < ARRAY_SIZE(ext_segs); seg_num++) {3244			struct btf_ext_info *seg = ext_segs[seg_num];3245			const struct btf_ext_info_sec *sec;3246			const char *sec_name;3247			Elf_Scn *scn;3248 3249			if (seg->sec_cnt == 0)3250				continue;3251 3252			seg->sec_idxs = calloc(seg->sec_cnt, sizeof(*seg->sec_idxs));3253			if (!seg->sec_idxs) {3254				err = -ENOMEM;3255				goto out;3256			}3257 3258			sec_num = 0;3259			for_each_btf_ext_sec(seg, sec) {3260				/* preventively increment index to avoid doing3261				 * this before every continue below3262				 */3263				sec_num++;3264 3265				sec_name = btf__name_by_offset(obj->btf, sec->sec_name_off);3266				if (str_is_empty(sec_name))3267					continue;3268				scn = elf_sec_by_name(obj, sec_name);3269				if (!scn)3270					continue;3271 3272				seg->sec_idxs[sec_num - 1] = elf_ndxscn(scn);3273			}3274		}3275	}3276out:3277	if (err && libbpf_needs_btf(obj)) {3278		pr_warn("BTF is required, but is missing or corrupted.\n");3279		return err;3280	}3281	return 0;3282}3283 3284static int compare_vsi_off(const void *_a, const void *_b)3285{3286	const struct btf_var_secinfo *a = _a;3287	const struct btf_var_secinfo *b = _b;3288 3289	return a->offset - b->offset;3290}3291 3292static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf,3293			     struct btf_type *t)3294{3295	__u32 size = 0, i, vars = btf_vlen(t);3296	const char *sec_name = btf__name_by_offset(btf, t->name_off);3297	struct btf_var_secinfo *vsi;3298	bool fixup_offsets = false;3299	int err;3300 3301	if (!sec_name) {3302		pr_debug("No name found in string section for DATASEC kind.\n");3303		return -ENOENT;3304	}3305 3306	/* Extern-backing datasecs (.ksyms, .kconfig) have their size and3307	 * variable offsets set at the previous step. Further, not every3308	 * extern BTF VAR has corresponding ELF symbol preserved, so we skip3309	 * all fixups altogether for such sections and go straight to sorting3310	 * VARs within their DATASEC.3311	 */3312	if (strcmp(sec_name, KCONFIG_SEC) == 0 || strcmp(sec_name, KSYMS_SEC) == 0)3313		goto sort_vars;3314 3315	/* Clang leaves DATASEC size and VAR offsets as zeroes, so we need to3316	 * fix this up. But BPF static linker already fixes this up and fills3317	 * all the sizes and offsets during static linking. So this step has3318	 * to be optional. But the STV_HIDDEN handling is non-optional for any3319	 * non-extern DATASEC, so the variable fixup loop below handles both3320	 * functions at the same time, paying the cost of BTF VAR <-> ELF3321	 * symbol matching just once.3322	 */3323	if (t->size == 0) {3324		err = find_elf_sec_sz(obj, sec_name, &size);3325		if (err || !size) {3326			pr_debug("sec '%s': failed to determine size from ELF: size %u, err %d\n",3327				 sec_name, size, err);3328			return -ENOENT;3329		}3330 3331		t->size = size;3332		fixup_offsets = true;3333	}3334 3335	for (i = 0, vsi = btf_var_secinfos(t); i < vars; i++, vsi++) {3336		const struct btf_type *t_var;3337		struct btf_var *var;3338		const char *var_name;3339		Elf64_Sym *sym;3340 3341		t_var = btf__type_by_id(btf, vsi->type);3342		if (!t_var || !btf_is_var(t_var)) {3343			pr_debug("sec '%s': unexpected non-VAR type found\n", sec_name);3344			return -EINVAL;3345		}3346 3347		var = btf_var(t_var);3348		if (var->linkage == BTF_VAR_STATIC || var->linkage == BTF_VAR_GLOBAL_EXTERN)3349			continue;3350 3351		var_name = btf__name_by_offset(btf, t_var->name_off);3352		if (!var_name) {3353			pr_debug("sec '%s': failed to find name of DATASEC's member #%d\n",3354				 sec_name, i);3355			return -ENOENT;3356		}3357 3358		sym = find_elf_var_sym(obj, var_name);3359		if (IS_ERR(sym)) {3360			pr_debug("sec '%s': failed to find ELF symbol for VAR '%s'\n",3361				 sec_name, var_name);3362			return -ENOENT;3363		}3364 3365		if (fixup_offsets)3366			vsi->offset = sym->st_value;3367 3368		/* if variable is a global/weak symbol, but has restricted3369		 * (STV_HIDDEN or STV_INTERNAL) visibility, mark its BTF VAR3370		 * as static. This follows similar logic for functions (BPF3371		 * subprogs) and influences libbpf's further decisions about3372		 * whether to make global data BPF array maps as3373		 * BPF_F_MMAPABLE.3374		 */3375		if (ELF64_ST_VISIBILITY(sym->st_other) == STV_HIDDEN3376		    || ELF64_ST_VISIBILITY(sym->st_other) == STV_INTERNAL)3377			var->linkage = BTF_VAR_STATIC;3378	}3379 3380sort_vars:3381	qsort(btf_var_secinfos(t), vars, sizeof(*vsi), compare_vsi_off);3382	return 0;3383}3384 3385static int bpf_object_fixup_btf(struct bpf_object *obj)3386{3387	int i, n, err = 0;3388 3389	if (!obj->btf)3390		return 0;3391 3392	n = btf__type_cnt(obj->btf);3393	for (i = 1; i < n; i++) {3394		struct btf_type *t = btf_type_by_id(obj->btf, i);3395 3396		/* Loader needs to fix up some of the things compiler3397		 * couldn't get its hands on while emitting BTF. This3398		 * is section size and global variable offset. We use3399		 * the info from the ELF itself for this purpose.3400		 */3401		if (btf_is_datasec(t)) {3402			err = btf_fixup_datasec(obj, obj->btf, t);3403			if (err)3404				return err;3405		}3406	}3407 3408	return 0;3409}3410 3411static bool prog_needs_vmlinux_btf(struct bpf_program *prog)3412{3413	if (prog->type == BPF_PROG_TYPE_STRUCT_OPS ||3414	    prog->type == BPF_PROG_TYPE_LSM)3415		return true;3416 3417	/* BPF_PROG_TYPE_TRACING programs which do not attach to other programs3418	 * also need vmlinux BTF3419	 */3420	if (prog->type == BPF_PROG_TYPE_TRACING && !prog->attach_prog_fd)3421		return true;3422 3423	return false;3424}3425 3426static bool map_needs_vmlinux_btf(struct bpf_map *map)3427{3428	return bpf_map__is_struct_ops(map);3429}3430 3431static bool obj_needs_vmlinux_btf(const struct bpf_object *obj)3432{3433	struct bpf_program *prog;3434	struct bpf_map *map;3435	int i;3436 3437	/* CO-RE relocations need kernel BTF, only when btf_custom_path3438	 * is not specified3439	 */3440	if (obj->btf_ext && obj->btf_ext->core_relo_info.len && !obj->btf_custom_path)3441		return true;3442 3443	/* Support for typed ksyms needs kernel BTF */3444	for (i = 0; i < obj->nr_extern; i++) {3445		const struct extern_desc *ext;3446 3447		ext = &obj->externs[i];3448		if (ext->type == EXT_KSYM && ext->ksym.type_id)3449			return true;3450	}3451 3452	bpf_object__for_each_program(prog, obj) {3453		if (!prog->autoload)3454			continue;3455		if (prog_needs_vmlinux_btf(prog))3456			return true;3457	}3458 3459	bpf_object__for_each_map(map, obj) {3460		if (map_needs_vmlinux_btf(map))3461			return true;3462	}3463 3464	return false;3465}3466 3467static int bpf_object__load_vmlinux_btf(struct bpf_object *obj, bool force)3468{3469	int err;3470 3471	/* btf_vmlinux could be loaded earlier */3472	if (obj->btf_vmlinux || obj->gen_loader)3473		return 0;3474 3475	if (!force && !obj_needs_vmlinux_btf(obj))3476		return 0;3477 3478	obj->btf_vmlinux = btf__load_vmlinux_btf();3479	err = libbpf_get_error(obj->btf_vmlinux);3480	if (err) {3481		pr_warn("Error loading vmlinux BTF: %d\n", err);3482		obj->btf_vmlinux = NULL;3483		return err;3484	}3485	return 0;3486}3487 3488static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj)3489{3490	struct btf *kern_btf = obj->btf;3491	bool btf_mandatory, sanitize;3492	int i, err = 0;3493 3494	if (!obj->btf)3495		return 0;3496 3497	if (!kernel_supports(obj, FEAT_BTF)) {3498		if (kernel_needs_btf(obj)) {3499			err = -EOPNOTSUPP;3500			goto report;3501		}3502		pr_debug("Kernel doesn't support BTF, skipping uploading it.\n");3503		return 0;3504	}3505 3506	/* Even though some subprogs are global/weak, user might prefer more3507	 * permissive BPF verification process that BPF verifier performs for3508	 * static functions, taking into account more context from the caller3509	 * functions. In such case, they need to mark such subprogs with3510	 * __attribute__((visibility("hidden"))) and libbpf will adjust3511	 * corresponding FUNC BTF type to be marked as static and trigger more3512	 * involved BPF verification process.3513	 */3514	for (i = 0; i < obj->nr_programs; i++) {3515		struct bpf_program *prog = &obj->programs[i];3516		struct btf_type *t;3517		const char *name;3518		int j, n;3519 3520		if (!prog->mark_btf_static || !prog_is_subprog(obj, prog))3521			continue;3522 3523		n = btf__type_cnt(obj->btf);3524		for (j = 1; j < n; j++) {3525			t = btf_type_by_id(obj->btf, j);3526			if (!btf_is_func(t) || btf_func_linkage(t) != BTF_FUNC_GLOBAL)3527				continue;3528 3529			name = btf__str_by_offset(obj->btf, t->name_off);3530			if (strcmp(name, prog->name) != 0)3531				continue;3532 3533			t->info = btf_type_info(BTF_KIND_FUNC, BTF_FUNC_STATIC, 0);3534			break;3535		}3536	}3537 3538	sanitize = btf_needs_sanitization(obj);3539	if (sanitize) {3540		const void *raw_data;3541		__u32 sz;3542 3543		/* clone BTF to sanitize a copy and leave the original intact */3544		raw_data = btf__raw_data(obj->btf, &sz);3545		kern_btf = btf__new(raw_data, sz);3546		err = libbpf_get_error(kern_btf);3547		if (err)3548			return err;3549 3550		/* enforce 8-byte pointers for BPF-targeted BTFs */3551		btf__set_pointer_size(obj->btf, 8);3552		err = bpf_object__sanitize_btf(obj, kern_btf);3553		if (err)3554			return err;3555	}3556 3557	if (obj->gen_loader) {3558		__u32 raw_size = 0;3559		const void *raw_data = btf__raw_data(kern_btf, &raw_size);3560 3561		if (!raw_data)3562			return -ENOMEM;3563		bpf_gen__load_btf(obj->gen_loader, raw_data, raw_size);3564		/* Pretend to have valid FD to pass various fd >= 0 checks.3565		 * This fd == 0 will not be used with any syscall and will be reset to -1 eventually.3566		 */3567		btf__set_fd(kern_btf, 0);3568	} else {3569		/* currently BPF_BTF_LOAD only supports log_level 1 */3570		err = btf_load_into_kernel(kern_btf, obj->log_buf, obj->log_size,3571					   obj->log_level ? 1 : 0, obj->token_fd);3572	}3573	if (sanitize) {3574		if (!err) {3575			/* move fd to libbpf's BTF */3576			btf__set_fd(obj->btf, btf__fd(kern_btf));3577			btf__set_fd(kern_btf, -1);3578		}3579		btf__free(kern_btf);3580	}3581report:3582	if (err) {3583		btf_mandatory = kernel_needs_btf(obj);3584		pr_warn("Error loading .BTF into kernel: %d. %s\n", err,3585			btf_mandatory ? "BTF is mandatory, can't proceed."3586				      : "BTF is optional, ignoring.");3587		if (!btf_mandatory)3588			err = 0;3589	}3590	return err;3591}3592 3593static const char *elf_sym_str(const struct bpf_object *obj, size_t off)3594{3595	const char *name;3596 3597	name = elf_strptr(obj->efile.elf, obj->efile.strtabidx, off);3598	if (!name) {3599		pr_warn("elf: failed to get section name string at offset %zu from %s: %s\n",3600			off, obj->path, elf_errmsg(-1));3601		return NULL;3602	}3603 3604	return name;3605}3606 3607static const char *elf_sec_str(const struct bpf_object *obj, size_t off)3608{3609	const char *name;3610 3611	name = elf_strptr(obj->efile.elf, obj->efile.shstrndx, off);3612	if (!name) {3613		pr_warn("elf: failed to get section name string at offset %zu from %s: %s\n",3614			off, obj->path, elf_errmsg(-1));3615		return NULL;3616	}3617 3618	return name;3619}3620 3621static Elf_Scn *elf_sec_by_idx(const struct bpf_object *obj, size_t idx)3622{3623	Elf_Scn *scn;3624 3625	scn = elf_getscn(obj->efile.elf, idx);3626	if (!scn) {3627		pr_warn("elf: failed to get section(%zu) from %s: %s\n",3628			idx, obj->path, elf_errmsg(-1));3629		return NULL;3630	}3631	return scn;3632}3633 3634static Elf_Scn *elf_sec_by_name(const struct bpf_object *obj, const char *name)3635{3636	Elf_Scn *scn = NULL;3637	Elf *elf = obj->efile.elf;3638	const char *sec_name;3639 3640	while ((scn = elf_nextscn(elf, scn)) != NULL) {3641		sec_name = elf_sec_name(obj, scn);3642		if (!sec_name)3643			return NULL;3644 3645		if (strcmp(sec_name, name) != 0)3646			continue;3647 3648		return scn;3649	}3650	return NULL;3651}3652 3653static Elf64_Shdr *elf_sec_hdr(const struct bpf_object *obj, Elf_Scn *scn)3654{3655	Elf64_Shdr *shdr;3656 3657	if (!scn)3658		return NULL;3659 3660	shdr = elf64_getshdr(scn);3661	if (!shdr) {3662		pr_warn("elf: failed to get section(%zu) header from %s: %s\n",3663			elf_ndxscn(scn), obj->path, elf_errmsg(-1));3664		return NULL;3665	}3666 3667	return shdr;3668}3669 3670static const char *elf_sec_name(const struct bpf_object *obj, Elf_Scn *scn)3671{3672	const char *name;3673	Elf64_Shdr *sh;3674 3675	if (!scn)3676		return NULL;3677 3678	sh = elf_sec_hdr(obj, scn);3679	if (!sh)3680		return NULL;3681 3682	name = elf_sec_str(obj, sh->sh_name);3683	if (!name) {3684		pr_warn("elf: failed to get section(%zu) name from %s: %s\n",3685			elf_ndxscn(scn), obj->path, elf_errmsg(-1));3686		return NULL;3687	}3688 3689	return name;3690}3691 3692static Elf_Data *elf_sec_data(const struct bpf_object *obj, Elf_Scn *scn)3693{3694	Elf_Data *data;3695 3696	if (!scn)3697		return NULL;3698 3699	data = elf_getdata(scn, 0);3700	if (!data) {3701		pr_warn("elf: failed to get section(%zu) %s data from %s: %s\n",3702			elf_ndxscn(scn), elf_sec_name(obj, scn) ?: "<?>",3703			obj->path, elf_errmsg(-1));3704		return NULL;3705	}3706 3707	return data;3708}3709 3710static Elf64_Sym *elf_sym_by_idx(const struct bpf_object *obj, size_t idx)3711{3712	if (idx >= obj->efile.symbols->d_size / sizeof(Elf64_Sym))3713		return NULL;3714 3715	return (Elf64_Sym *)obj->efile.symbols->d_buf + idx;3716}3717 3718static Elf64_Rel *elf_rel_by_idx(Elf_Data *data, size_t idx)3719{3720	if (idx >= data->d_size / sizeof(Elf64_Rel))3721		return NULL;3722 3723	return (Elf64_Rel *)data->d_buf + idx;3724}3725 3726static bool is_sec_name_dwarf(const char *name)3727{3728	/* approximation, but the actual list is too long */3729	return str_has_pfx(name, ".debug_");3730}3731 3732static bool ignore_elf_section(Elf64_Shdr *hdr, const char *name)3733{3734	/* no special handling of .strtab */3735	if (hdr->sh_type == SHT_STRTAB)3736		return true;3737 3738	/* ignore .llvm_addrsig section as well */3739	if (hdr->sh_type == SHT_LLVM_ADDRSIG)3740		return true;3741 3742	/* no subprograms will lead to an empty .text section, ignore it */3743	if (hdr->sh_type == SHT_PROGBITS && hdr->sh_size == 0 &&3744	    strcmp(name, ".text") == 0)3745		return true;3746 3747	/* DWARF sections */3748	if (is_sec_name_dwarf(name))3749		return true;3750 3751	if (str_has_pfx(name, ".rel")) {3752		name += sizeof(".rel") - 1;3753		/* DWARF section relocations */3754		if (is_sec_name_dwarf(name))3755			return true;3756 3757		/* .BTF and .BTF.ext don't need relocations */3758		if (strcmp(name, BTF_ELF_SEC) == 0 ||3759		    strcmp(name, BTF_EXT_ELF_SEC) == 0)3760			return true;3761	}3762 3763	return false;3764}3765 3766static int cmp_progs(const void *_a, const void *_b)3767{3768	const struct bpf_program *a = _a;3769	const struct bpf_program *b = _b;3770 3771	if (a->sec_idx != b->sec_idx)3772		return a->sec_idx < b->sec_idx ? -1 : 1;3773 3774	/* sec_insn_off can't be the same within the section */3775	return a->sec_insn_off < b->sec_insn_off ? -1 : 1;3776}3777 3778static int bpf_object__elf_collect(struct bpf_object *obj)3779{3780	struct elf_sec_desc *sec_desc;3781	Elf *elf = obj->efile.elf;3782	Elf_Data *btf_ext_data = NULL;3783	Elf_Data *btf_data = NULL;3784	int idx = 0, err = 0;3785	const char *name;3786	Elf_Data *data;3787	Elf_Scn *scn;3788	Elf64_Shdr *sh;3789 3790	/* ELF section indices are 0-based, but sec #0 is special "invalid"3791	 * section. Since section count retrieved by elf_getshdrnum() does3792	 * include sec #0, it is already the necessary size of an array to keep3793	 * all the sections.3794	 */3795	if (elf_getshdrnum(obj->efile.elf, &obj->efile.sec_cnt)) {3796		pr_warn("elf: failed to get the number of sections for %s: %s\n",3797			obj->path, elf_errmsg(-1));3798		return -LIBBPF_ERRNO__FORMAT;3799	}3800	obj->efile.secs = calloc(obj->efile.sec_cnt, sizeof(*obj->efile.secs));3801	if (!obj->efile.secs)3802		return -ENOMEM;3803 3804	/* a bunch of ELF parsing functionality depends on processing symbols,3805	 * so do the first pass and find the symbol table3806	 */3807	scn = NULL;3808	while ((scn = elf_nextscn(elf, scn)) != NULL) {3809		sh = elf_sec_hdr(obj, scn);3810		if (!sh)3811			return -LIBBPF_ERRNO__FORMAT;3812 3813		if (sh->sh_type == SHT_SYMTAB) {3814			if (obj->efile.symbols) {3815				pr_warn("elf: multiple symbol tables in %s\n", obj->path);3816				return -LIBBPF_ERRNO__FORMAT;3817			}3818 3819			data = elf_sec_data(obj, scn);3820			if (!data)3821				return -LIBBPF_ERRNO__FORMAT;3822 3823			idx = elf_ndxscn(scn);3824 3825			obj->efile.symbols = data;3826			obj->efile.symbols_shndx = idx;3827			obj->efile.strtabidx = sh->sh_link;3828		}3829	}3830 3831	if (!obj->efile.symbols) {3832		pr_warn("elf: couldn't find symbol table in %s, stripped object file?\n",3833			obj->path);3834		return -ENOENT;3835	}3836 3837	scn = NULL;3838	while ((scn = elf_nextscn(elf, scn)) != NULL) {3839		idx = elf_ndxscn(scn);3840		sec_desc = &obj->efile.secs[idx];3841 3842		sh = elf_sec_hdr(obj, scn);3843		if (!sh)3844			return -LIBBPF_ERRNO__FORMAT;3845 3846		name = elf_sec_str(obj, sh->sh_name);3847		if (!name)3848			return -LIBBPF_ERRNO__FORMAT;3849 3850		if (ignore_elf_section(sh, name))3851			continue;3852 3853		data = elf_sec_data(obj, scn);3854		if (!data)3855			return -LIBBPF_ERRNO__FORMAT;3856 3857		pr_debug("elf: section(%d) %s, size %ld, link %d, flags %lx, type=%d\n",3858			 idx, name, (unsigned long)data->d_size,3859			 (int)sh->sh_link, (unsigned long)sh->sh_flags,3860			 (int)sh->sh_type);3861 3862		if (strcmp(name, "license") == 0) {3863			err = bpf_object__init_license(obj, data->d_buf, data->d_size);3864			if (err)3865				return err;3866		} else if (strcmp(name, "version") == 0) {3867			err = bpf_object__init_kversion(obj, data->d_buf, data->d_size);3868			if (err)3869				return err;3870		} else if (strcmp(name, "maps") == 0) {3871			pr_warn("elf: legacy map definitions in 'maps' section are not supported by libbpf v1.0+\n");3872			return -ENOTSUP;3873		} else if (strcmp(name, MAPS_ELF_SEC) == 0) {3874			obj->efile.btf_maps_shndx = idx;3875		} else if (strcmp(name, BTF_ELF_SEC) == 0) {3876			if (sh->sh_type != SHT_PROGBITS)3877				return -LIBBPF_ERRNO__FORMAT;3878			btf_data = data;3879		} else if (strcmp(name, BTF_EXT_ELF_SEC) == 0) {3880			if (sh->sh_type != SHT_PROGBITS)3881				return -LIBBPF_ERRNO__FORMAT;3882			btf_ext_data = data;3883		} else if (sh->sh_type == SHT_SYMTAB) {3884			/* already processed during the first pass above */3885		} else if (sh->sh_type == SHT_PROGBITS && data->d_size > 0) {3886			if (sh->sh_flags & SHF_EXECINSTR) {3887				if (strcmp(name, ".text") == 0)3888					obj->efile.text_shndx = idx;3889				err = bpf_object__add_programs(obj, data, name, idx);3890				if (err)3891					return err;3892			} else if (strcmp(name, DATA_SEC) == 0 ||3893				   str_has_pfx(name, DATA_SEC ".")) {3894				sec_desc->sec_type = SEC_DATA;3895				sec_desc->shdr = sh;3896				sec_desc->data = data;3897			} else if (strcmp(name, RODATA_SEC) == 0 ||3898				   str_has_pfx(name, RODATA_SEC ".")) {3899				sec_desc->sec_type = SEC_RODATA;3900				sec_desc->shdr = sh;3901				sec_desc->data = data;3902			} else if (strcmp(name, STRUCT_OPS_SEC) == 0 ||3903				   strcmp(name, STRUCT_OPS_LINK_SEC) == 0 ||3904				   strcmp(name, "?" STRUCT_OPS_SEC) == 0 ||3905				   strcmp(name, "?" STRUCT_OPS_LINK_SEC) == 0) {3906				sec_desc->sec_type = SEC_ST_OPS;3907				sec_desc->shdr = sh;3908				sec_desc->data = data;3909				obj->efile.has_st_ops = true;3910			} else if (strcmp(name, ARENA_SEC) == 0) {3911				obj->efile.arena_data = data;3912				obj->efile.arena_data_shndx = idx;3913			} else {3914				pr_info("elf: skipping unrecognized data section(%d) %s\n",3915					idx, name);3916			}3917		} else if (sh->sh_type == SHT_REL) {3918			int targ_sec_idx = sh->sh_info; /* points to other section */3919 3920			if (sh->sh_entsize != sizeof(Elf64_Rel) ||3921			    targ_sec_idx >= obj->efile.sec_cnt)3922				return -LIBBPF_ERRNO__FORMAT;3923 3924			/* Only do relo for section with exec instructions */3925			if (!section_have_execinstr(obj, targ_sec_idx) &&3926			    strcmp(name, ".rel" STRUCT_OPS_SEC) &&3927			    strcmp(name, ".rel" STRUCT_OPS_LINK_SEC) &&3928			    strcmp(name, ".rel?" STRUCT_OPS_SEC) &&3929			    strcmp(name, ".rel?" STRUCT_OPS_LINK_SEC) &&3930			    strcmp(name, ".rel" MAPS_ELF_SEC)) {3931				pr_info("elf: skipping relo section(%d) %s for section(%d) %s\n",3932					idx, name, targ_sec_idx,3933					elf_sec_name(obj, elf_sec_by_idx(obj, targ_sec_idx)) ?: "<?>");3934				continue;3935			}3936 3937			sec_desc->sec_type = SEC_RELO;3938			sec_desc->shdr = sh;3939			sec_desc->data = data;3940		} else if (sh->sh_type == SHT_NOBITS && (strcmp(name, BSS_SEC) == 0 ||3941							 str_has_pfx(name, BSS_SEC "."))) {3942			sec_desc->sec_type = SEC_BSS;3943			sec_desc->shdr = sh;3944			sec_desc->data = data;3945		} else {3946			pr_info("elf: skipping section(%d) %s (size %zu)\n", idx, name,3947				(size_t)sh->sh_size);3948		}3949	}3950 3951	if (!obj->efile.strtabidx || obj->efile.strtabidx > idx) {3952		pr_warn("elf: symbol strings section missing or invalid in %s\n", obj->path);3953		return -LIBBPF_ERRNO__FORMAT;3954	}3955 3956	/* sort BPF programs by section name and in-section instruction offset3957	 * for faster search3958	 */3959	if (obj->nr_programs)3960		qsort(obj->programs, obj->nr_programs, sizeof(*obj->programs), cmp_progs);3961 3962	return bpf_object__init_btf(obj, btf_data, btf_ext_data);3963}3964 3965static bool sym_is_extern(const Elf64_Sym *sym)3966{3967	int bind = ELF64_ST_BIND(sym->st_info);3968	/* externs are symbols w/ type=NOTYPE, bind=GLOBAL|WEAK, section=UND */3969	return sym->st_shndx == SHN_UNDEF &&3970	       (bind == STB_GLOBAL || bind == STB_WEAK) &&3971	       ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE;3972}3973 3974static bool sym_is_subprog(const Elf64_Sym *sym, int text_shndx)3975{3976	int bind = ELF64_ST_BIND(sym->st_info);3977	int type = ELF64_ST_TYPE(sym->st_info);3978 3979	/* in .text section */3980	if (sym->st_shndx != text_shndx)3981		return false;3982 3983	/* local function */3984	if (bind == STB_LOCAL && type == STT_SECTION)3985		return true;3986 3987	/* global function */3988	return bind == STB_GLOBAL && type == STT_FUNC;3989}3990 3991static int find_extern_btf_id(const struct btf *btf, const char *ext_name)3992{3993	const struct btf_type *t;3994	const char *tname;3995	int i, n;3996 3997	if (!btf)3998		return -ESRCH;3999 4000	n = btf__type_cnt(btf);4001	for (i = 1; i < n; i++) {4002		t = btf__type_by_id(btf, i);4003 4004		if (!btf_is_var(t) && !btf_is_func(t))4005			continue;4006 4007		tname = btf__name_by_offset(btf, t->name_off);4008		if (strcmp(tname, ext_name))4009			continue;4010 4011		if (btf_is_var(t) &&4012		    btf_var(t)->linkage != BTF_VAR_GLOBAL_EXTERN)4013			return -EINVAL;4014 4015		if (btf_is_func(t) && btf_func_linkage(t) != BTF_FUNC_EXTERN)4016			return -EINVAL;4017 4018		return i;4019	}4020 4021	return -ENOENT;4022}4023 4024static int find_extern_sec_btf_id(struct btf *btf, int ext_btf_id) {4025	const struct btf_var_secinfo *vs;4026	const struct btf_type *t;4027	int i, j, n;4028 4029	if (!btf)4030		return -ESRCH;4031 4032	n = btf__type_cnt(btf);4033	for (i = 1; i < n; i++) {4034		t = btf__type_by_id(btf, i);4035 4036		if (!btf_is_datasec(t))4037			continue;4038 4039		vs = btf_var_secinfos(t);4040		for (j = 0; j < btf_vlen(t); j++, vs++) {4041			if (vs->type == ext_btf_id)4042				return i;4043		}4044	}4045 4046	return -ENOENT;4047}4048 4049static enum kcfg_type find_kcfg_type(const struct btf *btf, int id,4050				     bool *is_signed)4051{4052	const struct btf_type *t;4053	const char *name;4054 4055	t = skip_mods_and_typedefs(btf, id, NULL);4056	name = btf__name_by_offset(btf, t->name_off);4057 4058	if (is_signed)4059		*is_signed = false;4060	switch (btf_kind(t)) {4061	case BTF_KIND_INT: {4062		int enc = btf_int_encoding(t);4063 4064		if (enc & BTF_INT_BOOL)4065			return t->size == 1 ? KCFG_BOOL : KCFG_UNKNOWN;4066		if (is_signed)4067			*is_signed = enc & BTF_INT_SIGNED;4068		if (t->size == 1)4069			return KCFG_CHAR;4070		if (t->size < 1 || t->size > 8 || (t->size & (t->size - 1)))4071			return KCFG_UNKNOWN;4072		return KCFG_INT;4073	}4074	case BTF_KIND_ENUM:4075		if (t->size != 4)4076			return KCFG_UNKNOWN;4077		if (strcmp(name, "libbpf_tristate"))4078			return KCFG_UNKNOWN;4079		return KCFG_TRISTATE;4080	case BTF_KIND_ENUM64:4081		if (strcmp(name, "libbpf_tristate"))4082			return KCFG_UNKNOWN;4083		return KCFG_TRISTATE;4084	case BTF_KIND_ARRAY:4085		if (btf_array(t)->nelems == 0)4086			return KCFG_UNKNOWN;4087		if (find_kcfg_type(btf, btf_array(t)->type, NULL) != KCFG_CHAR)4088			return KCFG_UNKNOWN;4089		return KCFG_CHAR_ARR;4090	default:4091		return KCFG_UNKNOWN;4092	}4093}4094 4095static int cmp_externs(const void *_a, const void *_b)4096{4097	const struct extern_desc *a = _a;4098	const struct extern_desc *b = _b;4099 4100	if (a->type != b->type)4101		return a->type < b->type ? -1 : 1;4102 4103	if (a->type == EXT_KCFG) {4104		/* descending order by alignment requirements */4105		if (a->kcfg.align != b->kcfg.align)4106			return a->kcfg.align > b->kcfg.align ? -1 : 1;4107		/* ascending order by size, within same alignment class */4108		if (a->kcfg.sz != b->kcfg.sz)4109			return a->kcfg.sz < b->kcfg.sz ? -1 : 1;4110	}4111 4112	/* resolve ties by name */4113	return strcmp(a->name, b->name);4114}4115 4116static int find_int_btf_id(const struct btf *btf)4117{4118	const struct btf_type *t;4119	int i, n;4120 4121	n = btf__type_cnt(btf);4122	for (i = 1; i < n; i++) {4123		t = btf__type_by_id(btf, i);4124 4125		if (btf_is_int(t) && btf_int_bits(t) == 32)4126			return i;4127	}4128 4129	return 0;4130}4131 4132static int add_dummy_ksym_var(struct btf *btf)4133{4134	int i, int_btf_id, sec_btf_id, dummy_var_btf_id;4135	const struct btf_var_secinfo *vs;4136	const struct btf_type *sec;4137 4138	if (!btf)4139		return 0;4140 4141	sec_btf_id = btf__find_by_name_kind(btf, KSYMS_SEC,4142					    BTF_KIND_DATASEC);4143	if (sec_btf_id < 0)4144		return 0;4145 4146	sec = btf__type_by_id(btf, sec_btf_id);4147	vs = btf_var_secinfos(sec);4148	for (i = 0; i < btf_vlen(sec); i++, vs++) {4149		const struct btf_type *vt;4150 4151		vt = btf__type_by_id(btf, vs->type);4152		if (btf_is_func(vt))4153			break;4154	}4155 4156	/* No func in ksyms sec.  No need to add dummy var. */4157	if (i == btf_vlen(sec))4158		return 0;4159 4160	int_btf_id = find_int_btf_id(btf);4161	dummy_var_btf_id = btf__add_var(btf,4162					"dummy_ksym",4163					BTF_VAR_GLOBAL_ALLOCATED,4164					int_btf_id);4165	if (dummy_var_btf_id < 0)4166		pr_warn("cannot create a dummy_ksym var\n");4167 4168	return dummy_var_btf_id;4169}4170 4171static int bpf_object__collect_externs(struct bpf_object *obj)4172{4173	struct btf_type *sec, *kcfg_sec = NULL, *ksym_sec = NULL;4174	const struct btf_type *t;4175	struct extern_desc *ext;4176	int i, n, off, dummy_var_btf_id;4177	const char *ext_name, *sec_name;4178	size_t ext_essent_len;4179	Elf_Scn *scn;4180	Elf64_Shdr *sh;4181 4182	if (!obj->efile.symbols)4183		return 0;4184 4185	scn = elf_sec_by_idx(obj, obj->efile.symbols_shndx);4186	sh = elf_sec_hdr(obj, scn);4187	if (!sh || sh->sh_entsize != sizeof(Elf64_Sym))4188		return -LIBBPF_ERRNO__FORMAT;4189 4190	dummy_var_btf_id = add_dummy_ksym_var(obj->btf);4191	if (dummy_var_btf_id < 0)4192		return dummy_var_btf_id;4193 4194	n = sh->sh_size / sh->sh_entsize;4195	pr_debug("looking for externs among %d symbols...\n", n);4196 4197	for (i = 0; i < n; i++) {4198		Elf64_Sym *sym = elf_sym_by_idx(obj, i);4199 4200		if (!sym)4201			return -LIBBPF_ERRNO__FORMAT;4202		if (!sym_is_extern(sym))4203			continue;4204		ext_name = elf_sym_str(obj, sym->st_name);4205		if (!ext_name || !ext_name[0])4206			continue;4207 4208		ext = obj->externs;4209		ext = libbpf_reallocarray(ext, obj->nr_extern + 1, sizeof(*ext));4210		if (!ext)4211			return -ENOMEM;4212		obj->externs = ext;4213		ext = &ext[obj->nr_extern];4214		memset(ext, 0, sizeof(*ext));4215		obj->nr_extern++;4216 4217		ext->btf_id = find_extern_btf_id(obj->btf, ext_name);4218		if (ext->btf_id <= 0) {4219			pr_warn("failed to find BTF for extern '%s': %d\n",4220				ext_name, ext->btf_id);4221			return ext->btf_id;4222		}4223		t = btf__type_by_id(obj->btf, ext->btf_id);4224		ext->name = btf__name_by_offset(obj->btf, t->name_off);4225		ext->sym_idx = i;4226		ext->is_weak = ELF64_ST_BIND(sym->st_info) == STB_WEAK;4227 4228		ext_essent_len = bpf_core_essential_name_len(ext->name);4229		ext->essent_name = NULL;4230		if (ext_essent_len != strlen(ext->name)) {4231			ext->essent_name = strndup(ext->name, ext_essent_len);4232			if (!ext->essent_name)4233				return -ENOMEM;4234		}4235 4236		ext->sec_btf_id = find_extern_sec_btf_id(obj->btf, ext->btf_id);4237		if (ext->sec_btf_id <= 0) {4238			pr_warn("failed to find BTF for extern '%s' [%d] section: %d\n",4239				ext_name, ext->btf_id, ext->sec_btf_id);4240			return ext->sec_btf_id;4241		}4242		sec = (void *)btf__type_by_id(obj->btf, ext->sec_btf_id);4243		sec_name = btf__name_by_offset(obj->btf, sec->name_off);4244 4245		if (strcmp(sec_name, KCONFIG_SEC) == 0) {4246			if (btf_is_func(t)) {4247				pr_warn("extern function %s is unsupported under %s section\n",4248					ext->name, KCONFIG_SEC);4249				return -ENOTSUP;4250			}4251			kcfg_sec = sec;4252			ext->type = EXT_KCFG;4253			ext->kcfg.sz = btf__resolve_size(obj->btf, t->type);4254			if (ext->kcfg.sz <= 0) {4255				pr_warn("failed to resolve size of extern (kcfg) '%s': %d\n",4256					ext_name, ext->kcfg.sz);4257				return ext->kcfg.sz;4258			}4259			ext->kcfg.align = btf__align_of(obj->btf, t->type);4260			if (ext->kcfg.align <= 0) {4261				pr_warn("failed to determine alignment of extern (kcfg) '%s': %d\n",4262					ext_name, ext->kcfg.align);4263				return -EINVAL;4264			}4265			ext->kcfg.type = find_kcfg_type(obj->btf, t->type,4266							&ext->kcfg.is_signed);4267			if (ext->kcfg.type == KCFG_UNKNOWN) {4268				pr_warn("extern (kcfg) '%s': type is unsupported\n", ext_name);4269				return -ENOTSUP;4270			}4271		} else if (strcmp(sec_name, KSYMS_SEC) == 0) {4272			ksym_sec = sec;4273			ext->type = EXT_KSYM;4274			skip_mods_and_typedefs(obj->btf, t->type,4275					       &ext->ksym.type_id);4276		} else {4277			pr_warn("unrecognized extern section '%s'\n", sec_name);4278			return -ENOTSUP;4279		}4280	}4281	pr_debug("collected %d externs total\n", obj->nr_extern);4282 4283	if (!obj->nr_extern)4284		return 0;4285 4286	/* sort externs by type, for kcfg ones also by (align, size, name) */4287	qsort(obj->externs, obj->nr_extern, sizeof(*ext), cmp_externs);4288 4289	/* for .ksyms section, we need to turn all externs into allocated4290	 * variables in BTF to pass kernel verification; we do this by4291	 * pretending that each extern is a 8-byte variable4292	 */4293	if (ksym_sec) {4294		/* find existing 4-byte integer type in BTF to use for fake4295		 * extern variables in DATASEC4296		 */4297		int int_btf_id = find_int_btf_id(obj->btf);4298		/* For extern function, a dummy_var added earlier4299		 * will be used to replace the vs->type and4300		 * its name string will be used to refill4301		 * the missing param's name.4302		 */4303		const struct btf_type *dummy_var;4304 4305		dummy_var = btf__type_by_id(obj->btf, dummy_var_btf_id);4306		for (i = 0; i < obj->nr_extern; i++) {4307			ext = &obj->externs[i];4308			if (ext->type != EXT_KSYM)4309				continue;4310			pr_debug("extern (ksym) #%d: symbol %d, name %s\n",4311				 i, ext->sym_idx, ext->name);4312		}4313 4314		sec = ksym_sec;4315		n = btf_vlen(sec);4316		for (i = 0, off = 0; i < n; i++, off += sizeof(int)) {4317			struct btf_var_secinfo *vs = btf_var_secinfos(sec) + i;4318			struct btf_type *vt;4319 4320			vt = (void *)btf__type_by_id(obj->btf, vs->type);4321			ext_name = btf__name_by_offset(obj->btf, vt->name_off);4322			ext = find_extern_by_name(obj, ext_name);4323			if (!ext) {4324				pr_warn("failed to find extern definition for BTF %s '%s'\n",4325					btf_kind_str(vt), ext_name);4326				return -ESRCH;4327			}4328			if (btf_is_func(vt)) {4329				const struct btf_type *func_proto;4330				struct btf_param *param;4331				int j;4332 4333				func_proto = btf__type_by_id(obj->btf,4334							     vt->type);4335				param = btf_params(func_proto);4336				/* Reuse the dummy_var string if the4337				 * func proto does not have param name.4338				 */4339				for (j = 0; j < btf_vlen(func_proto); j++)4340					if (param[j].type && !param[j].name_off)4341						param[j].name_off =4342							dummy_var->name_off;4343				vs->type = dummy_var_btf_id;4344				vt->info &= ~0xffff;4345				vt->info |= BTF_FUNC_GLOBAL;4346			} else {4347				btf_var(vt)->linkage = BTF_VAR_GLOBAL_ALLOCATED;4348				vt->type = int_btf_id;4349			}4350			vs->offset = off;4351			vs->size = sizeof(int);4352		}4353		sec->size = off;4354	}4355 4356	if (kcfg_sec) {4357		sec = kcfg_sec;4358		/* for kcfg externs calculate their offsets within a .kconfig map */4359		off = 0;4360		for (i = 0; i < obj->nr_extern; i++) {4361			ext = &obj->externs[i];4362			if (ext->type != EXT_KCFG)4363				continue;4364 4365			ext->kcfg.data_off = roundup(off, ext->kcfg.align);4366			off = ext->kcfg.data_off + ext->kcfg.sz;4367			pr_debug("extern (kcfg) #%d: symbol %d, off %u, name %s\n",4368				 i, ext->sym_idx, ext->kcfg.data_off, ext->name);4369		}4370		sec->size = off;4371		n = btf_vlen(sec);4372		for (i = 0; i < n; i++) {4373			struct btf_var_secinfo *vs = btf_var_secinfos(sec) + i;4374 4375			t = btf__type_by_id(obj->btf, vs->type);4376			ext_name = btf__name_by_offset(obj->btf, t->name_off);4377			ext = find_extern_by_name(obj, ext_name);4378			if (!ext) {4379				pr_warn("failed to find extern definition for BTF var '%s'\n",4380					ext_name);4381				return -ESRCH;4382			}4383			btf_var(t)->linkage = BTF_VAR_GLOBAL_ALLOCATED;4384			vs->offset = ext->kcfg.data_off;4385		}4386	}4387	return 0;4388}4389 4390static bool prog_is_subprog(const struct bpf_object *obj, const struct bpf_program *prog)4391{4392	return prog->sec_idx == obj->efile.text_shndx && obj->nr_programs > 1;4393}4394 4395struct bpf_program *4396bpf_object__find_program_by_name(const struct bpf_object *obj,4397				 const char *name)4398{4399	struct bpf_program *prog;4400 4401	bpf_object__for_each_program(prog, obj) {4402		if (prog_is_subprog(obj, prog))4403			continue;4404		if (!strcmp(prog->name, name))4405			return prog;4406	}4407	return errno = ENOENT, NULL;4408}4409 4410static bool bpf_object__shndx_is_data(const struct bpf_object *obj,4411				      int shndx)4412{4413	switch (obj->efile.secs[shndx].sec_type) {4414	case SEC_BSS:4415	case SEC_DATA:4416	case SEC_RODATA:4417		return true;4418	default:4419		return false;4420	}4421}4422 4423static bool bpf_object__shndx_is_maps(const struct bpf_object *obj,4424				      int shndx)4425{4426	return shndx == obj->efile.btf_maps_shndx;4427}4428 4429static enum libbpf_map_type4430bpf_object__section_to_libbpf_map_type(const struct bpf_object *obj, int shndx)4431{4432	if (shndx == obj->efile.symbols_shndx)4433		return LIBBPF_MAP_KCONFIG;4434 4435	switch (obj->efile.secs[shndx].sec_type) {4436	case SEC_BSS:4437		return LIBBPF_MAP_BSS;4438	case SEC_DATA:4439		return LIBBPF_MAP_DATA;4440	case SEC_RODATA:4441		return LIBBPF_MAP_RODATA;4442	default:4443		return LIBBPF_MAP_UNSPEC;4444	}4445}4446 4447static int bpf_program__record_reloc(struct bpf_program *prog,4448				     struct reloc_desc *reloc_desc,4449				     __u32 insn_idx, const char *sym_name,4450				     const Elf64_Sym *sym, const Elf64_Rel *rel)4451{4452	struct bpf_insn *insn = &prog->insns[insn_idx];4453	size_t map_idx, nr_maps = prog->obj->nr_maps;4454	struct bpf_object *obj = prog->obj;4455	__u32 shdr_idx = sym->st_shndx;4456	enum libbpf_map_type type;4457	const char *sym_sec_name;4458	struct bpf_map *map;4459 4460	if (!is_call_insn(insn) && !is_ldimm64_insn(insn)) {4461		pr_warn("prog '%s': invalid relo against '%s' for insns[%d].code 0x%x\n",4462			prog->name, sym_name, insn_idx, insn->code);4463		return -LIBBPF_ERRNO__RELOC;4464	}4465 4466	if (sym_is_extern(sym)) {4467		int sym_idx = ELF64_R_SYM(rel->r_info);4468		int i, n = obj->nr_extern;4469		struct extern_desc *ext;4470 4471		for (i = 0; i < n; i++) {4472			ext = &obj->externs[i];4473			if (ext->sym_idx == sym_idx)4474				break;4475		}4476		if (i >= n) {4477			pr_warn("prog '%s': extern relo failed to find extern for '%s' (%d)\n",4478				prog->name, sym_name, sym_idx);4479			return -LIBBPF_ERRNO__RELOC;4480		}4481		pr_debug("prog '%s': found extern #%d '%s' (sym %d) for insn #%u\n",4482			 prog->name, i, ext->name, ext->sym_idx, insn_idx);4483		if (insn->code == (BPF_JMP | BPF_CALL))4484			reloc_desc->type = RELO_EXTERN_CALL;4485		else4486			reloc_desc->type = RELO_EXTERN_LD64;4487		reloc_desc->insn_idx = insn_idx;4488		reloc_desc->ext_idx = i;4489		return 0;4490	}4491 4492	/* sub-program call relocation */4493	if (is_call_insn(insn)) {4494		if (insn->src_reg != BPF_PSEUDO_CALL) {4495			pr_warn("prog '%s': incorrect bpf_call opcode\n", prog->name);4496			return -LIBBPF_ERRNO__RELOC;4497		}4498		/* text_shndx can be 0, if no default "main" program exists */4499		if (!shdr_idx || shdr_idx != obj->efile.text_shndx) {4500			sym_sec_name = elf_sec_name(obj, elf_sec_by_idx(obj, shdr_idx));4501			pr_warn("prog '%s': bad call relo against '%s' in section '%s'\n",4502				prog->name, sym_name, sym_sec_name);4503			return -LIBBPF_ERRNO__RELOC;4504		}4505		if (sym->st_value % BPF_INSN_SZ) {4506			pr_warn("prog '%s': bad call relo against '%s' at offset %zu\n",4507				prog->name, sym_name, (size_t)sym->st_value);4508			return -LIBBPF_ERRNO__RELOC;4509		}4510		reloc_desc->type = RELO_CALL;4511		reloc_desc->insn_idx = insn_idx;4512		reloc_desc->sym_off = sym->st_value;4513		return 0;4514	}4515 4516	if (!shdr_idx || shdr_idx >= SHN_LORESERVE) {4517		pr_warn("prog '%s': invalid relo against '%s' in special section 0x%x; forgot to initialize global var?..\n",4518			prog->name, sym_name, shdr_idx);4519		return -LIBBPF_ERRNO__RELOC;4520	}4521 4522	/* loading subprog addresses */4523	if (sym_is_subprog(sym, obj->efile.text_shndx)) {4524		/* global_func: sym->st_value = offset in the section, insn->imm = 0.4525		 * local_func: sym->st_value = 0, insn->imm = offset in the section.4526		 */4527		if ((sym->st_value % BPF_INSN_SZ) || (insn->imm % BPF_INSN_SZ)) {4528			pr_warn("prog '%s': bad subprog addr relo against '%s' at offset %zu+%d\n",4529				prog->name, sym_name, (size_t)sym->st_value, insn->imm);4530			return -LIBBPF_ERRNO__RELOC;4531		}4532 4533		reloc_desc->type = RELO_SUBPROG_ADDR;4534		reloc_desc->insn_idx = insn_idx;4535		reloc_desc->sym_off = sym->st_value;4536		return 0;4537	}4538 4539	type = bpf_object__section_to_libbpf_map_type(obj, shdr_idx);4540	sym_sec_name = elf_sec_name(obj, elf_sec_by_idx(obj, shdr_idx));4541 4542	/* arena data relocation */4543	if (shdr_idx == obj->efile.arena_data_shndx) {4544		reloc_desc->type = RELO_DATA;4545		reloc_desc->insn_idx = insn_idx;4546		reloc_desc->map_idx = obj->arena_map - obj->maps;4547		reloc_desc->sym_off = sym->st_value;4548		return 0;4549	}4550 4551	/* generic map reference relocation */4552	if (type == LIBBPF_MAP_UNSPEC) {4553		if (!bpf_object__shndx_is_maps(obj, shdr_idx)) {4554			pr_warn("prog '%s': bad map relo against '%s' in section '%s'\n",4555				prog->name, sym_name, sym_sec_name);4556			return -LIBBPF_ERRNO__RELOC;4557		}4558		for (map_idx = 0; map_idx < nr_maps; map_idx++) {4559			map = &obj->maps[map_idx];4560			if (map->libbpf_type != type ||4561			    map->sec_idx != sym->st_shndx ||4562			    map->sec_offset != sym->st_value)4563				continue;4564			pr_debug("prog '%s': found map %zd (%s, sec %d, off %zu) for insn #%u\n",4565				 prog->name, map_idx, map->name, map->sec_idx,4566				 map->sec_offset, insn_idx);4567			break;4568		}4569		if (map_idx >= nr_maps) {4570			pr_warn("prog '%s': map relo failed to find map for section '%s', off %zu\n",4571				prog->name, sym_sec_name, (size_t)sym->st_value);4572			return -LIBBPF_ERRNO__RELOC;4573		}4574		reloc_desc->type = RELO_LD64;4575		reloc_desc->insn_idx = insn_idx;4576		reloc_desc->map_idx = map_idx;4577		reloc_desc->sym_off = 0; /* sym->st_value determines map_idx */4578		return 0;4579	}4580 4581	/* global data map relocation */4582	if (!bpf_object__shndx_is_data(obj, shdr_idx)) {4583		pr_warn("prog '%s': bad data relo against section '%s'\n",4584			prog->name, sym_sec_name);4585		return -LIBBPF_ERRNO__RELOC;4586	}4587	for (map_idx = 0; map_idx < nr_maps; map_idx++) {4588		map = &obj->maps[map_idx];4589		if (map->libbpf_type != type || map->sec_idx != sym->st_shndx)4590			continue;4591		pr_debug("prog '%s': found data map %zd (%s, sec %d, off %zu) for insn %u\n",4592			 prog->name, map_idx, map->name, map->sec_idx,4593			 map->sec_offset, insn_idx);4594		break;4595	}4596	if (map_idx >= nr_maps) {4597		pr_warn("prog '%s': data relo failed to find map for section '%s'\n",4598			prog->name, sym_sec_name);4599		return -LIBBPF_ERRNO__RELOC;4600	}4601 4602	reloc_desc->type = RELO_DATA;4603	reloc_desc->insn_idx = insn_idx;4604	reloc_desc->map_idx = map_idx;4605	reloc_desc->sym_off = sym->st_value;4606	return 0;4607}4608 4609static bool prog_contains_insn(const struct bpf_program *prog, size_t insn_idx)4610{4611	return insn_idx >= prog->sec_insn_off &&4612	       insn_idx < prog->sec_insn_off + prog->sec_insn_cnt;4613}4614 4615static struct bpf_program *find_prog_by_sec_insn(const struct bpf_object *obj,4616						 size_t sec_idx, size_t insn_idx)4617{4618	int l = 0, r = obj->nr_programs - 1, m;4619	struct bpf_program *prog;4620 4621	if (!obj->nr_programs)4622		return NULL;4623 4624	while (l < r) {4625		m = l + (r - l + 1) / 2;4626		prog = &obj->programs[m];4627 4628		if (prog->sec_idx < sec_idx ||4629		    (prog->sec_idx == sec_idx && prog->sec_insn_off <= insn_idx))4630			l = m;4631		else4632			r = m - 1;4633	}4634	/* matching program could be at index l, but it still might be the4635	 * wrong one, so we need to double check conditions for the last time4636	 */4637	prog = &obj->programs[l];4638	if (prog->sec_idx == sec_idx && prog_contains_insn(prog, insn_idx))4639		return prog;4640	return NULL;4641}4642 4643static int4644bpf_object__collect_prog_relos(struct bpf_object *obj, Elf64_Shdr *shdr, Elf_Data *data)4645{4646	const char *relo_sec_name, *sec_name;4647	size_t sec_idx = shdr->sh_info, sym_idx;4648	struct bpf_program *prog;4649	struct reloc_desc *relos;4650	int err, i, nrels;4651	const char *sym_name;4652	__u32 insn_idx;4653	Elf_Scn *scn;4654	Elf_Data *scn_data;4655	Elf64_Sym *sym;4656	Elf64_Rel *rel;4657 4658	if (sec_idx >= obj->efile.sec_cnt)4659		return -EINVAL;4660 4661	scn = elf_sec_by_idx(obj, sec_idx);4662	scn_data = elf_sec_data(obj, scn);4663	if (!scn_data)4664		return -LIBBPF_ERRNO__FORMAT;4665 4666	relo_sec_name = elf_sec_str(obj, shdr->sh_name);4667	sec_name = elf_sec_name(obj, scn);4668	if (!relo_sec_name || !sec_name)4669		return -EINVAL;4670 4671	pr_debug("sec '%s': collecting relocation for section(%zu) '%s'\n",4672		 relo_sec_name, sec_idx, sec_name);4673	nrels = shdr->sh_size / shdr->sh_entsize;4674 4675	for (i = 0; i < nrels; i++) {4676		rel = elf_rel_by_idx(data, i);4677		if (!rel) {4678			pr_warn("sec '%s': failed to get relo #%d\n", relo_sec_name, i);4679			return -LIBBPF_ERRNO__FORMAT;4680		}4681 4682		sym_idx = ELF64_R_SYM(rel->r_info);4683		sym = elf_sym_by_idx(obj, sym_idx);4684		if (!sym) {4685			pr_warn("sec '%s': symbol #%zu not found for relo #%d\n",4686				relo_sec_name, sym_idx, i);4687			return -LIBBPF_ERRNO__FORMAT;4688		}4689 4690		if (sym->st_shndx >= obj->efile.sec_cnt) {4691			pr_warn("sec '%s': corrupted symbol #%zu pointing to invalid section #%zu for relo #%d\n",4692				relo_sec_name, sym_idx, (size_t)sym->st_shndx, i);4693			return -LIBBPF_ERRNO__FORMAT;4694		}4695 4696		if (rel->r_offset % BPF_INSN_SZ || rel->r_offset >= scn_data->d_size) {4697			pr_warn("sec '%s': invalid offset 0x%zx for relo #%d\n",4698				relo_sec_name, (size_t)rel->r_offset, i);4699			return -LIBBPF_ERRNO__FORMAT;4700		}4701 4702		insn_idx = rel->r_offset / BPF_INSN_SZ;4703		/* relocations against static functions are recorded as4704		 * relocations against the section that contains a function;4705		 * in such case, symbol will be STT_SECTION and sym.st_name4706		 * will point to empty string (0), so fetch section name4707		 * instead4708		 */4709		if (ELF64_ST_TYPE(sym->st_info) == STT_SECTION && sym->st_name == 0)4710			sym_name = elf_sec_name(obj, elf_sec_by_idx(obj, sym->st_shndx));4711		else4712			sym_name = elf_sym_str(obj, sym->st_name);4713		sym_name = sym_name ?: "<?";4714 4715		pr_debug("sec '%s': relo #%d: insn #%u against '%s'\n",4716			 relo_sec_name, i, insn_idx, sym_name);4717 4718		prog = find_prog_by_sec_insn(obj, sec_idx, insn_idx);4719		if (!prog) {4720			pr_debug("sec '%s': relo #%d: couldn't find program in section '%s' for insn #%u, probably overridden weak function, skipping...\n",4721				relo_sec_name, i, sec_name, insn_idx);4722			continue;4723		}4724 4725		relos = libbpf_reallocarray(prog->reloc_desc,4726					    prog->nr_reloc + 1, sizeof(*relos));4727		if (!relos)4728			return -ENOMEM;4729		prog->reloc_desc = relos;4730 4731		/* adjust insn_idx to local BPF program frame of reference */4732		insn_idx -= prog->sec_insn_off;4733		err = bpf_program__record_reloc(prog, &relos[prog->nr_reloc],4734						insn_idx, sym_name, sym, rel);4735		if (err)4736			return err;4737 4738		prog->nr_reloc++;4739	}4740	return 0;4741}4742 4743static int map_fill_btf_type_info(struct bpf_object *obj, struct bpf_map *map)4744{4745	int id;4746 4747	if (!obj->btf)4748		return -ENOENT;4749 4750	/* if it's BTF-defined map, we don't need to search for type IDs.4751	 * For struct_ops map, it does not need btf_key_type_id and4752	 * btf_value_type_id.4753	 */4754	if (map->sec_idx == obj->efile.btf_maps_shndx || bpf_map__is_struct_ops(map))4755		return 0;4756 4757	/*4758	 * LLVM annotates global data differently in BTF, that is,4759	 * only as '.data', '.bss' or '.rodata'.4760	 */4761	if (!bpf_map__is_internal(map))4762		return -ENOENT;4763 4764	id = btf__find_by_name(obj->btf, map->real_name);4765	if (id < 0)4766		return id;4767 4768	map->btf_key_type_id = 0;4769	map->btf_value_type_id = id;4770	return 0;4771}4772 4773static int bpf_get_map_info_from_fdinfo(int fd, struct bpf_map_info *info)4774{4775	char file[PATH_MAX], buff[4096];4776	FILE *fp;4777	__u32 val;4778	int err;4779 4780	snprintf(file, sizeof(file), "/proc/%d/fdinfo/%d", getpid(), fd);4781	memset(info, 0, sizeof(*info));4782 4783	fp = fopen(file, "re");4784	if (!fp) {4785		err = -errno;4786		pr_warn("failed to open %s: %d. No procfs support?\n", file,4787			err);4788		return err;4789	}4790 4791	while (fgets(buff, sizeof(buff), fp)) {4792		if (sscanf(buff, "map_type:\t%u", &val) == 1)4793			info->type = val;4794		else if (sscanf(buff, "key_size:\t%u", &val) == 1)4795			info->key_size = val;4796		else if (sscanf(buff, "value_size:\t%u", &val) == 1)4797			info->value_size = val;4798		else if (sscanf(buff, "max_entries:\t%u", &val) == 1)4799			info->max_entries = val;4800		else if (sscanf(buff, "map_flags:\t%i", &val) == 1)4801			info->map_flags = val;4802	}4803 4804	fclose(fp);4805 4806	return 0;4807}4808 4809bool bpf_map__autocreate(const struct bpf_map *map)4810{4811	return map->autocreate;4812}4813 4814int bpf_map__set_autocreate(struct bpf_map *map, bool autocreate)4815{4816	if (map->obj->loaded)4817		return libbpf_err(-EBUSY);4818 4819	map->autocreate = autocreate;4820	return 0;4821}4822 4823int bpf_map__set_autoattach(struct bpf_map *map, bool autoattach)4824{4825	if (!bpf_map__is_struct_ops(map))4826		return libbpf_err(-EINVAL);4827 4828	map->autoattach = autoattach;4829	return 0;4830}4831 4832bool bpf_map__autoattach(const struct bpf_map *map)4833{4834	return map->autoattach;4835}4836 4837int bpf_map__reuse_fd(struct bpf_map *map, int fd)4838{4839	struct bpf_map_info info;4840	__u32 len = sizeof(info), name_len;4841	int new_fd, err;4842	char *new_name;4843 4844	memset(&info, 0, len);4845	err = bpf_map_get_info_by_fd(fd, &info, &len);4846	if (err && errno == EINVAL)4847		err = bpf_get_map_info_from_fdinfo(fd, &info);4848	if (err)4849		return libbpf_err(err);4850 4851	name_len = strlen(info.name);4852	if (name_len == BPF_OBJ_NAME_LEN - 1 && strncmp(map->name, info.name, name_len) == 0)4853		new_name = strdup(map->name);4854	else4855		new_name = strdup(info.name);4856 4857	if (!new_name)4858		return libbpf_err(-errno);4859 4860	/*4861	 * Like dup(), but make sure new FD is >= 3 and has O_CLOEXEC set.4862	 * This is similar to what we do in ensure_good_fd(), but without4863	 * closing original FD.4864	 */4865	new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);4866	if (new_fd < 0) {4867		err = -errno;4868		goto err_free_new_name;4869	}4870 4871	err = reuse_fd(map->fd, new_fd);4872	if (err)4873		goto err_free_new_name;4874 4875	free(map->name);4876 4877	map->name = new_name;4878	map->def.type = info.type;4879	map->def.key_size = info.key_size;4880	map->def.value_size = info.value_size;4881	map->def.max_entries = info.max_entries;4882	map->def.map_flags = info.map_flags;4883	map->btf_key_type_id = info.btf_key_type_id;4884	map->btf_value_type_id = info.btf_value_type_id;4885	map->reused = true;4886	map->map_extra = info.map_extra;4887 4888	return 0;4889 4890err_free_new_name:4891	free(new_name);4892	return libbpf_err(err);4893}4894 4895__u32 bpf_map__max_entries(const struct bpf_map *map)4896{4897	return map->def.max_entries;4898}4899 4900struct bpf_map *bpf_map__inner_map(struct bpf_map *map)4901{4902	if (!bpf_map_type__is_map_in_map(map->def.type))4903		return errno = EINVAL, NULL;4904 4905	return map->inner_map;4906}4907 4908int bpf_map__set_max_entries(struct bpf_map *map, __u32 max_entries)4909{4910	if (map->obj->loaded)4911		return libbpf_err(-EBUSY);4912 4913	map->def.max_entries = max_entries;4914 4915	/* auto-adjust BPF ringbuf map max_entries to be a multiple of page size */4916	if (map_is_ringbuf(map))4917		map->def.max_entries = adjust_ringbuf_sz(map->def.max_entries);4918 4919	return 0;4920}4921 4922static int bpf_object_prepare_token(struct bpf_object *obj)4923{4924	const char *bpffs_path;4925	int bpffs_fd = -1, token_fd, err;4926	bool mandatory;4927	enum libbpf_print_level level;4928 4929	/* token is explicitly prevented */4930	if (obj->token_path && obj->token_path[0] == '\0') {4931		pr_debug("object '%s': token is prevented, skipping...\n", obj->name);4932		return 0;4933	}4934 4935	mandatory = obj->token_path != NULL;4936	level = mandatory ? LIBBPF_WARN : LIBBPF_DEBUG;4937 4938	bpffs_path = obj->token_path ?: BPF_FS_DEFAULT_PATH;4939	bpffs_fd = open(bpffs_path, O_DIRECTORY, O_RDWR);4940	if (bpffs_fd < 0) {4941		err = -errno;4942		__pr(level, "object '%s': failed (%d) to open BPF FS mount at '%s'%s\n",4943		     obj->name, err, bpffs_path,4944		     mandatory ? "" : ", skipping optional step...");4945		return mandatory ? err : 0;4946	}4947 4948	token_fd = bpf_token_create(bpffs_fd, 0);4949	close(bpffs_fd);4950	if (token_fd < 0) {4951		if (!mandatory && token_fd == -ENOENT) {4952			pr_debug("object '%s': BPF FS at '%s' doesn't have BPF token delegation set up, skipping...\n",4953				 obj->name, bpffs_path);4954			return 0;4955		}4956		__pr(level, "object '%s': failed (%d) to create BPF token from '%s'%s\n",4957		     obj->name, token_fd, bpffs_path,4958		     mandatory ? "" : ", skipping optional step...");4959		return mandatory ? token_fd : 0;4960	}4961 4962	obj->feat_cache = calloc(1, sizeof(*obj->feat_cache));4963	if (!obj->feat_cache) {4964		close(token_fd);4965		return -ENOMEM;4966	}4967 4968	obj->token_fd = token_fd;4969	obj->feat_cache->token_fd = token_fd;4970 4971	return 0;4972}4973 4974static int4975bpf_object__probe_loading(struct bpf_object *obj)4976{4977	char *cp, errmsg[STRERR_BUFSIZE];4978	struct bpf_insn insns[] = {4979		BPF_MOV64_IMM(BPF_REG_0, 0),4980		BPF_EXIT_INSN(),4981	};4982	int ret, insn_cnt = ARRAY_SIZE(insns);4983	LIBBPF_OPTS(bpf_prog_load_opts, opts,4984		.token_fd = obj->token_fd,4985		.prog_flags = obj->token_fd ? BPF_F_TOKEN_FD : 0,4986	);4987 4988	if (obj->gen_loader)4989		return 0;4990 4991	ret = bump_rlimit_memlock();4992	if (ret)4993		pr_warn("Failed to bump RLIMIT_MEMLOCK (err = %d), you might need to do it explicitly!\n", ret);4994 4995	/* make sure basic loading works */4996	ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, &opts);4997	if (ret < 0)4998		ret = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", insns, insn_cnt, &opts);4999	if (ret < 0) {5000		ret = errno;5001		cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg));5002		pr_warn("Error in %s():%s(%d). Couldn't load trivial BPF "5003			"program. Make sure your kernel supports BPF "5004			"(CONFIG_BPF_SYSCALL=y) and/or that RLIMIT_MEMLOCK is "5005			"set to big enough value.\n", __func__, cp, ret);5006		return -ret;5007	}5008	close(ret);5009 5010	return 0;5011}5012 5013bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id)5014{5015	if (obj->gen_loader)5016		/* To generate loader program assume the latest kernel5017		 * to avoid doing extra prog_load, map_create syscalls.5018		 */5019		return true;5020 5021	if (obj->token_fd)5022		return feat_supported(obj->feat_cache, feat_id);5023 5024	return feat_supported(NULL, feat_id);5025}5026 5027static bool map_is_reuse_compat(const struct bpf_map *map, int map_fd)5028{5029	struct bpf_map_info map_info;5030	char msg[STRERR_BUFSIZE];5031	__u32 map_info_len = sizeof(map_info);5032	int err;5033 5034	memset(&map_info, 0, map_info_len);5035	err = bpf_map_get_info_by_fd(map_fd, &map_info, &map_info_len);5036	if (err && errno == EINVAL)5037		err = bpf_get_map_info_from_fdinfo(map_fd, &map_info);5038	if (err) {5039		pr_warn("failed to get map info for map FD %d: %s\n", map_fd,5040			libbpf_strerror_r(errno, msg, sizeof(msg)));5041		return false;5042	}5043 5044	return (map_info.type == map->def.type &&5045		map_info.key_size == map->def.key_size &&5046		map_info.value_size == map->def.value_size &&5047		map_info.max_entries == map->def.max_entries &&5048		map_info.map_flags == map->def.map_flags &&5049		map_info.map_extra == map->map_extra);5050}5051 5052static int5053bpf_object__reuse_map(struct bpf_map *map)5054{5055	char *cp, errmsg[STRERR_BUFSIZE];5056	int err, pin_fd;5057 5058	pin_fd = bpf_obj_get(map->pin_path);5059	if (pin_fd < 0) {5060		err = -errno;5061		if (err == -ENOENT) {5062			pr_debug("found no pinned map to reuse at '%s'\n",5063				 map->pin_path);5064			return 0;5065		}5066 5067		cp = libbpf_strerror_r(-err, errmsg, sizeof(errmsg));5068		pr_warn("couldn't retrieve pinned map '%s': %s\n",5069			map->pin_path, cp);5070		return err;5071	}5072 5073	if (!map_is_reuse_compat(map, pin_fd)) {5074		pr_warn("couldn't reuse pinned map at '%s': parameter mismatch\n",5075			map->pin_path);5076		close(pin_fd);5077		return -EINVAL;5078	}5079 5080	err = bpf_map__reuse_fd(map, pin_fd);5081	close(pin_fd);5082	if (err)5083		return err;5084 5085	map->pinned = true;5086	pr_debug("reused pinned map at '%s'\n", map->pin_path);5087 5088	return 0;5089}5090 5091static int5092bpf_object__populate_internal_map(struct bpf_object *obj, struct bpf_map *map)5093{5094	enum libbpf_map_type map_type = map->libbpf_type;5095	char *cp, errmsg[STRERR_BUFSIZE];5096	int err, zero = 0;5097 5098	if (obj->gen_loader) {5099		bpf_gen__map_update_elem(obj->gen_loader, map - obj->maps,5100					 map->mmaped, map->def.value_size);5101		if (map_type == LIBBPF_MAP_RODATA || map_type == LIBBPF_MAP_KCONFIG)5102			bpf_gen__map_freeze(obj->gen_loader, map - obj->maps);5103		return 0;5104	}5105 5106	err = bpf_map_update_elem(map->fd, &zero, map->mmaped, 0);5107	if (err) {5108		err = -errno;5109		cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg));5110		pr_warn("Error setting initial map(%s) contents: %s\n",5111			map->name, cp);5112		return err;5113	}5114 5115	/* Freeze .rodata and .kconfig map as read-only from syscall side. */5116	if (map_type == LIBBPF_MAP_RODATA || map_type == LIBBPF_MAP_KCONFIG) {5117		err = bpf_map_freeze(map->fd);5118		if (err) {5119			err = -errno;5120			cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg));5121			pr_warn("Error freezing map(%s) as read-only: %s\n",5122				map->name, cp);5123			return err;5124		}5125	}5126	return 0;5127}5128 5129static void bpf_map__destroy(struct bpf_map *map);5130 5131static bool map_is_created(const struct bpf_map *map)5132{5133	return map->obj->loaded || map->reused;5134}5135 5136static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, bool is_inner)5137{5138	LIBBPF_OPTS(bpf_map_create_opts, create_attr);5139	struct bpf_map_def *def = &map->def;5140	const char *map_name = NULL;5141	int err = 0, map_fd;5142 5143	if (kernel_supports(obj, FEAT_PROG_NAME))5144		map_name = map->name;5145	create_attr.map_ifindex = map->map_ifindex;5146	create_attr.map_flags = def->map_flags;5147	create_attr.numa_node = map->numa_node;5148	create_attr.map_extra = map->map_extra;5149	create_attr.token_fd = obj->token_fd;5150	if (obj->token_fd)5151		create_attr.map_flags |= BPF_F_TOKEN_FD;5152 5153	if (bpf_map__is_struct_ops(map)) {5154		create_attr.btf_vmlinux_value_type_id = map->btf_vmlinux_value_type_id;5155		if (map->mod_btf_fd >= 0) {5156			create_attr.value_type_btf_obj_fd = map->mod_btf_fd;5157			create_attr.map_flags |= BPF_F_VTYPE_BTF_OBJ_FD;5158		}5159	}5160 5161	if (obj->btf && btf__fd(obj->btf) >= 0) {5162		create_attr.btf_fd = btf__fd(obj->btf);5163		create_attr.btf_key_type_id = map->btf_key_type_id;5164		create_attr.btf_value_type_id = map->btf_value_type_id;5165	}5166 5167	if (bpf_map_type__is_map_in_map(def->type)) {5168		if (map->inner_map) {5169			err = map_set_def_max_entries(map->inner_map);5170			if (err)5171				return err;5172			err = bpf_object__create_map(obj, map->inner_map, true);5173			if (err) {5174				pr_warn("map '%s': failed to create inner map: %d\n",5175					map->name, err);5176				return err;5177			}5178			map->inner_map_fd = map->inner_map->fd;5179		}5180		if (map->inner_map_fd >= 0)5181			create_attr.inner_map_fd = map->inner_map_fd;5182	}5183 5184	switch (def->type) {5185	case BPF_MAP_TYPE_PERF_EVENT_ARRAY:5186	case BPF_MAP_TYPE_CGROUP_ARRAY:5187	case BPF_MAP_TYPE_STACK_TRACE:5188	case BPF_MAP_TYPE_ARRAY_OF_MAPS:5189	case BPF_MAP_TYPE_HASH_OF_MAPS:5190	case BPF_MAP_TYPE_DEVMAP:5191	case BPF_MAP_TYPE_DEVMAP_HASH:5192	case BPF_MAP_TYPE_CPUMAP:5193	case BPF_MAP_TYPE_XSKMAP:5194	case BPF_MAP_TYPE_SOCKMAP:5195	case BPF_MAP_TYPE_SOCKHASH:5196	case BPF_MAP_TYPE_QUEUE:5197	case BPF_MAP_TYPE_STACK:5198	case BPF_MAP_TYPE_ARENA:5199		create_attr.btf_fd = 0;5200		create_attr.btf_key_type_id = 0;5201		create_attr.btf_value_type_id = 0;5202		map->btf_key_type_id = 0;5203		map->btf_value_type_id = 0;5204		break;5205	case BPF_MAP_TYPE_STRUCT_OPS:5206		create_attr.btf_value_type_id = 0;5207		break;5208	default:5209		break;5210	}5211 5212	if (obj->gen_loader) {5213		bpf_gen__map_create(obj->gen_loader, def->type, map_name,5214				    def->key_size, def->value_size, def->max_entries,5215				    &create_attr, is_inner ? -1 : map - obj->maps);5216		/* We keep pretenting we have valid FD to pass various fd >= 05217		 * checks by just keeping original placeholder FDs in place.5218		 * See bpf_object__add_map() comment.5219		 * This placeholder fd will not be used with any syscall and5220		 * will be reset to -1 eventually.5221		 */5222		map_fd = map->fd;5223	} else {5224		map_fd = bpf_map_create(def->type, map_name,5225					def->key_size, def->value_size,5226					def->max_entries, &create_attr);5227	}5228	if (map_fd < 0 && (create_attr.btf_key_type_id || create_attr.btf_value_type_id)) {5229		char *cp, errmsg[STRERR_BUFSIZE];5230 5231		err = -errno;5232		cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg));5233		pr_warn("Error in bpf_create_map_xattr(%s):%s(%d). Retrying without BTF.\n",5234			map->name, cp, err);5235		create_attr.btf_fd = 0;5236		create_attr.btf_key_type_id = 0;5237		create_attr.btf_value_type_id = 0;5238		map->btf_key_type_id = 0;5239		map->btf_value_type_id = 0;5240		map_fd = bpf_map_create(def->type, map_name,5241					def->key_size, def->value_size,5242					def->max_entries, &create_attr);5243	}5244 5245	if (bpf_map_type__is_map_in_map(def->type) && map->inner_map) {5246		if (obj->gen_loader)5247			map->inner_map->fd = -1;5248		bpf_map__destroy(map->inner_map);5249		zfree(&map->inner_map);5250	}5251 5252	if (map_fd < 0)5253		return map_fd;5254 5255	/* obj->gen_loader case, prevent reuse_fd() from closing map_fd */5256	if (map->fd == map_fd)5257		return 0;5258 5259	/* Keep placeholder FD value but now point it to the BPF map object.5260	 * This way everything that relied on this map's FD (e.g., relocated5261	 * ldimm64 instructions) will stay valid and won't need adjustments.5262	 * map->fd stays valid but now point to what map_fd points to.5263	 */5264	return reuse_fd(map->fd, map_fd);5265}5266 5267static int init_map_in_map_slots(struct bpf_object *obj, struct bpf_map *map)5268{5269	const struct bpf_map *targ_map;5270	unsigned int i;5271	int fd, err = 0;5272 5273	for (i = 0; i < map->init_slots_sz; i++) {5274		if (!map->init_slots[i])5275			continue;5276 5277		targ_map = map->init_slots[i];5278		fd = targ_map->fd;5279 5280		if (obj->gen_loader) {5281			bpf_gen__populate_outer_map(obj->gen_loader,5282						    map - obj->maps, i,5283						    targ_map - obj->maps);5284		} else {5285			err = bpf_map_update_elem(map->fd, &i, &fd, 0);5286		}5287		if (err) {5288			err = -errno;5289			pr_warn("map '%s': failed to initialize slot [%d] to map '%s' fd=%d: %d\n",5290				map->name, i, targ_map->name, fd, err);5291			return err;5292		}5293		pr_debug("map '%s': slot [%d] set to map '%s' fd=%d\n",5294			 map->name, i, targ_map->name, fd);5295	}5296 5297	zfree(&map->init_slots);5298	map->init_slots_sz = 0;5299 5300	return 0;5301}5302 5303static int init_prog_array_slots(struct bpf_object *obj, struct bpf_map *map)5304{5305	const struct bpf_program *targ_prog;5306	unsigned int i;5307	int fd, err;5308 5309	if (obj->gen_loader)5310		return -ENOTSUP;5311 5312	for (i = 0; i < map->init_slots_sz; i++) {5313		if (!map->init_slots[i])5314			continue;5315 5316		targ_prog = map->init_slots[i];5317		fd = bpf_program__fd(targ_prog);5318 5319		err = bpf_map_update_elem(map->fd, &i, &fd, 0);5320		if (err) {5321			err = -errno;5322			pr_warn("map '%s': failed to initialize slot [%d] to prog '%s' fd=%d: %d\n",5323				map->name, i, targ_prog->name, fd, err);5324			return err;5325		}5326		pr_debug("map '%s': slot [%d] set to prog '%s' fd=%d\n",5327			 map->name, i, targ_prog->name, fd);5328	}5329 5330	zfree(&map->init_slots);5331	map->init_slots_sz = 0;5332 5333	return 0;5334}5335 5336static int bpf_object_init_prog_arrays(struct bpf_object *obj)5337{5338	struct bpf_map *map;5339	int i, err;5340 5341	for (i = 0; i < obj->nr_maps; i++) {5342		map = &obj->maps[i];5343 5344		if (!map->init_slots_sz || map->def.type != BPF_MAP_TYPE_PROG_ARRAY)5345			continue;5346 5347		err = init_prog_array_slots(obj, map);5348		if (err < 0)5349			return err;5350	}5351	return 0;5352}5353 5354static int map_set_def_max_entries(struct bpf_map *map)5355{5356	if (map->def.type == BPF_MAP_TYPE_PERF_EVENT_ARRAY && !map->def.max_entries) {5357		int nr_cpus;5358 5359		nr_cpus = libbpf_num_possible_cpus();5360		if (nr_cpus < 0) {5361			pr_warn("map '%s': failed to determine number of system CPUs: %d\n",5362				map->name, nr_cpus);5363			return nr_cpus;5364		}5365		pr_debug("map '%s': setting size to %d\n", map->name, nr_cpus);5366		map->def.max_entries = nr_cpus;5367	}5368 5369	return 0;5370}5371 5372static int5373bpf_object__create_maps(struct bpf_object *obj)5374{5375	struct bpf_map *map;5376	char *cp, errmsg[STRERR_BUFSIZE];5377	unsigned int i, j;5378	int err;5379	bool retried;5380 5381	for (i = 0; i < obj->nr_maps; i++) {5382		map = &obj->maps[i];5383 5384		/* To support old kernels, we skip creating global data maps5385		 * (.rodata, .data, .kconfig, etc); later on, during program5386		 * loading, if we detect that at least one of the to-be-loaded5387		 * programs is referencing any global data map, we'll error5388		 * out with program name and relocation index logged.5389		 * This approach allows to accommodate Clang emitting5390		 * unnecessary .rodata.str1.1 sections for string literals,5391		 * but also it allows to have CO-RE applications that use5392		 * global variables in some of BPF programs, but not others.5393		 * If those global variable-using programs are not loaded at5394		 * runtime due to bpf_program__set_autoload(prog, false),5395		 * bpf_object loading will succeed just fine even on old5396		 * kernels.5397		 */5398		if (bpf_map__is_internal(map) && !kernel_supports(obj, FEAT_GLOBAL_DATA))5399			map->autocreate = false;5400 5401		if (!map->autocreate) {5402			pr_debug("map '%s': skipped auto-creating...\n", map->name);5403			continue;5404		}5405 5406		err = map_set_def_max_entries(map);5407		if (err)5408			goto err_out;5409 5410		retried = false;5411retry:5412		if (map->pin_path) {5413			err = bpf_object__reuse_map(map);5414			if (err) {5415				pr_warn("map '%s': error reusing pinned map\n",5416					map->name);5417				goto err_out;5418			}5419			if (retried && map->fd < 0) {5420				pr_warn("map '%s': cannot find pinned map\n",5421					map->name);5422				err = -ENOENT;5423				goto err_out;5424			}5425		}5426 5427		if (map->reused) {5428			pr_debug("map '%s': skipping creation (preset fd=%d)\n",5429				 map->name, map->fd);5430		} else {5431			err = bpf_object__create_map(obj, map, false);5432			if (err)5433				goto err_out;5434 5435			pr_debug("map '%s': created successfully, fd=%d\n",5436				 map->name, map->fd);5437 5438			if (bpf_map__is_internal(map)) {5439				err = bpf_object__populate_internal_map(obj, map);5440				if (err < 0)5441					goto err_out;5442			}5443			if (map->def.type == BPF_MAP_TYPE_ARENA) {5444				map->mmaped = mmap((void *)(long)map->map_extra,5445						   bpf_map_mmap_sz(map), PROT_READ | PROT_WRITE,5446						   map->map_extra ? MAP_SHARED | MAP_FIXED : MAP_SHARED,5447						   map->fd, 0);5448				if (map->mmaped == MAP_FAILED) {5449					err = -errno;5450					map->mmaped = NULL;5451					pr_warn("map '%s': failed to mmap arena: %d\n",5452						map->name, err);5453					return err;5454				}5455				if (obj->arena_data) {5456					memcpy(map->mmaped, obj->arena_data, obj->arena_data_sz);5457					zfree(&obj->arena_data);5458				}5459			}5460			if (map->init_slots_sz && map->def.type != BPF_MAP_TYPE_PROG_ARRAY) {5461				err = init_map_in_map_slots(obj, map);5462				if (err < 0)5463					goto err_out;5464			}5465		}5466 5467		if (map->pin_path && !map->pinned) {5468			err = bpf_map__pin(map, NULL);5469			if (err) {5470				if (!retried && err == -EEXIST) {5471					retried = true;5472					goto retry;5473				}5474				pr_warn("map '%s': failed to auto-pin at '%s': %d\n",5475					map->name, map->pin_path, err);5476				goto err_out;5477			}5478		}5479	}5480 5481	return 0;5482 5483err_out:5484	cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg));5485	pr_warn("map '%s': failed to create: %s(%d)\n", map->name, cp, err);5486	pr_perm_msg(err);5487	for (j = 0; j < i; j++)5488		zclose(obj->maps[j].fd);5489	return err;5490}5491 5492static bool bpf_core_is_flavor_sep(const char *s)5493{5494	/* check X___Y name pattern, where X and Y are not underscores */5495	return s[0] != '_' &&				      /* X */5496	       s[1] == '_' && s[2] == '_' && s[3] == '_' &&   /* ___ */5497	       s[4] != '_';				      /* Y */5498}5499 5500/* Given 'some_struct_name___with_flavor' return the length of a name prefix5501 * before last triple underscore. Struct name part after last triple5502 * underscore is ignored by BPF CO-RE relocation during relocation matching.5503 */5504size_t bpf_core_essential_name_len(const char *name)5505{5506	size_t n = strlen(name);5507	int i;5508 5509	for (i = n - 5; i >= 0; i--) {5510		if (bpf_core_is_flavor_sep(name + i))5511			return i + 1;5512	}5513	return n;5514}5515 5516void bpf_core_free_cands(struct bpf_core_cand_list *cands)5517{5518	if (!cands)5519		return;5520 5521	free(cands->cands);5522	free(cands);5523}5524 5525int bpf_core_add_cands(struct bpf_core_cand *local_cand,5526		       size_t local_essent_len,5527		       const struct btf *targ_btf,5528		       const char *targ_btf_name,5529		       int targ_start_id,5530		       struct bpf_core_cand_list *cands)5531{5532	struct bpf_core_cand *new_cands, *cand;5533	const struct btf_type *t, *local_t;5534	const char *targ_name, *local_name;5535	size_t targ_essent_len;5536	int n, i;5537 5538	local_t = btf__type_by_id(local_cand->btf, local_cand->id);5539	local_name = btf__str_by_offset(local_cand->btf, local_t->name_off);5540 5541	n = btf__type_cnt(targ_btf);5542	for (i = targ_start_id; i < n; i++) {5543		t = btf__type_by_id(targ_btf, i);5544		if (!btf_kind_core_compat(t, local_t))5545			continue;5546 5547		targ_name = btf__name_by_offset(targ_btf, t->name_off);5548		if (str_is_empty(targ_name))5549			continue;5550 5551		targ_essent_len = bpf_core_essential_name_len(targ_name);5552		if (targ_essent_len != local_essent_len)5553			continue;5554 5555		if (strncmp(local_name, targ_name, local_essent_len) != 0)5556			continue;5557 5558		pr_debug("CO-RE relocating [%d] %s %s: found target candidate [%d] %s %s in [%s]\n",5559			 local_cand->id, btf_kind_str(local_t),5560			 local_name, i, btf_kind_str(t), targ_name,5561			 targ_btf_name);5562		new_cands = libbpf_reallocarray(cands->cands, cands->len + 1,5563					      sizeof(*cands->cands));5564		if (!new_cands)5565			return -ENOMEM;5566 5567		cand = &new_cands[cands->len];5568		cand->btf = targ_btf;5569		cand->id = i;5570 5571		cands->cands = new_cands;5572		cands->len++;5573	}5574	return 0;5575}5576 5577static int load_module_btfs(struct bpf_object *obj)5578{5579	struct bpf_btf_info info;5580	struct module_btf *mod_btf;5581	struct btf *btf;5582	char name[64];5583	__u32 id = 0, len;5584	int err, fd;5585 5586	if (obj->btf_modules_loaded)5587		return 0;5588 5589	if (obj->gen_loader)5590		return 0;5591 5592	/* don't do this again, even if we find no module BTFs */5593	obj->btf_modules_loaded = true;5594 5595	/* kernel too old to support module BTFs */5596	if (!kernel_supports(obj, FEAT_MODULE_BTF))5597		return 0;5598 5599	while (true) {5600		err = bpf_btf_get_next_id(id, &id);5601		if (err && errno == ENOENT)5602			return 0;5603		if (err && errno == EPERM) {5604			pr_debug("skipping module BTFs loading, missing privileges\n");5605			return 0;5606		}5607		if (err) {5608			err = -errno;5609			pr_warn("failed to iterate BTF objects: %d\n", err);5610			return err;5611		}5612 5613		fd = bpf_btf_get_fd_by_id(id);5614		if (fd < 0) {5615			if (errno == ENOENT)5616				continue; /* expected race: BTF was unloaded */5617			err = -errno;5618			pr_warn("failed to get BTF object #%d FD: %d\n", id, err);5619			return err;5620		}5621 5622		len = sizeof(info);5623		memset(&info, 0, sizeof(info));5624		info.name = ptr_to_u64(name);5625		info.name_len = sizeof(name);5626 5627		err = bpf_btf_get_info_by_fd(fd, &info, &len);5628		if (err) {5629			err = -errno;5630			pr_warn("failed to get BTF object #%d info: %d\n", id, err);5631			goto err_out;5632		}5633 5634		/* ignore non-module BTFs */5635		if (!info.kernel_btf || strcmp(name, "vmlinux") == 0) {5636			close(fd);5637			continue;5638		}5639 5640		btf = btf_get_from_fd(fd, obj->btf_vmlinux);5641		err = libbpf_get_error(btf);5642		if (err) {5643			pr_warn("failed to load module [%s]'s BTF object #%d: %d\n",5644				name, id, err);5645			goto err_out;5646		}5647 5648		err = libbpf_ensure_mem((void **)&obj->btf_modules, &obj->btf_module_cap,5649					sizeof(*obj->btf_modules), obj->btf_module_cnt + 1);5650		if (err)5651			goto err_out;5652 5653		mod_btf = &obj->btf_modules[obj->btf_module_cnt++];5654 5655		mod_btf->btf = btf;5656		mod_btf->id = id;5657		mod_btf->fd = fd;5658		mod_btf->name = strdup(name);5659		if (!mod_btf->name) {5660			err = -ENOMEM;5661			goto err_out;5662		}5663		continue;5664 5665err_out:5666		close(fd);5667		return err;5668	}5669 5670	return 0;5671}5672 5673static struct bpf_core_cand_list *5674bpf_core_find_cands(struct bpf_object *obj, const struct btf *local_btf, __u32 local_type_id)5675{5676	struct bpf_core_cand local_cand = {};5677	struct bpf_core_cand_list *cands;5678	const struct btf *main_btf;5679	const struct btf_type *local_t;5680	const char *local_name;5681	size_t local_essent_len;5682	int err, i;5683 5684	local_cand.btf = local_btf;5685	local_cand.id = local_type_id;5686	local_t = btf__type_by_id(local_btf, local_type_id);5687	if (!local_t)5688		return ERR_PTR(-EINVAL);5689 5690	local_name = btf__name_by_offset(local_btf, local_t->name_off);5691	if (str_is_empty(local_name))5692		return ERR_PTR(-EINVAL);5693	local_essent_len = bpf_core_essential_name_len(local_name);5694 5695	cands = calloc(1, sizeof(*cands));5696	if (!cands)5697		return ERR_PTR(-ENOMEM);5698 5699	/* Attempt to find target candidates in vmlinux BTF first */5700	main_btf = obj->btf_vmlinux_override ?: obj->btf_vmlinux;5701	err = bpf_core_add_cands(&local_cand, local_essent_len, main_btf, "vmlinux", 1, cands);5702	if (err)5703		goto err_out;5704 5705	/* if vmlinux BTF has any candidate, don't got for module BTFs */5706	if (cands->len)5707		return cands;5708 5709	/* if vmlinux BTF was overridden, don't attempt to load module BTFs */5710	if (obj->btf_vmlinux_override)5711		return cands;5712 5713	/* now look through module BTFs, trying to still find candidates */5714	err = load_module_btfs(obj);5715	if (err)5716		goto err_out;5717 5718	for (i = 0; i < obj->btf_module_cnt; i++) {5719		err = bpf_core_add_cands(&local_cand, local_essent_len,5720					 obj->btf_modules[i].btf,5721					 obj->btf_modules[i].name,5722					 btf__type_cnt(obj->btf_vmlinux),5723					 cands);5724		if (err)5725			goto err_out;5726	}5727 5728	return cands;5729err_out:5730	bpf_core_free_cands(cands);5731	return ERR_PTR(err);5732}5733 5734/* Check local and target types for compatibility. This check is used for5735 * type-based CO-RE relocations and follow slightly different rules than5736 * field-based relocations. This function assumes that root types were already5737 * checked for name match. Beyond that initial root-level name check, names5738 * are completely ignored. Compatibility rules are as follows:5739 *   - any two STRUCTs/UNIONs/FWDs/ENUMs/INTs are considered compatible, but5740 *     kind should match for local and target types (i.e., STRUCT is not5741 *     compatible with UNION);5742 *   - for ENUMs, the size is ignored;5743 *   - for INT, size and signedness are ignored;5744 *   - for ARRAY, dimensionality is ignored, element types are checked for5745 *     compatibility recursively;5746 *   - CONST/VOLATILE/RESTRICT modifiers are ignored;5747 *   - TYPEDEFs/PTRs are compatible if types they pointing to are compatible;5748 *   - FUNC_PROTOs are compatible if they have compatible signature: same5749 *     number of input args and compatible return and argument types.5750 * These rules are not set in stone and probably will be adjusted as we get5751 * more experience with using BPF CO-RE relocations.5752 */5753int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id,5754			      const struct btf *targ_btf, __u32 targ_id)5755{5756	return __bpf_core_types_are_compat(local_btf, local_id, targ_btf, targ_id, 32);5757}5758 5759int bpf_core_types_match(const struct btf *local_btf, __u32 local_id,5760			 const struct btf *targ_btf, __u32 targ_id)5761{5762	return __bpf_core_types_match(local_btf, local_id, targ_btf, targ_id, false, 32);5763}5764 5765static size_t bpf_core_hash_fn(const long key, void *ctx)5766{5767	return key;5768}5769 5770static bool bpf_core_equal_fn(const long k1, const long k2, void *ctx)5771{5772	return k1 == k2;5773}5774 5775static int record_relo_core(struct bpf_program *prog,5776			    const struct bpf_core_relo *core_relo, int insn_idx)5777{5778	struct reloc_desc *relos, *relo;5779 5780	relos = libbpf_reallocarray(prog->reloc_desc,5781				    prog->nr_reloc + 1, sizeof(*relos));5782	if (!relos)5783		return -ENOMEM;5784	relo = &relos[prog->nr_reloc];5785	relo->type = RELO_CORE;5786	relo->insn_idx = insn_idx;5787	relo->core_relo = core_relo;5788	prog->reloc_desc = relos;5789	prog->nr_reloc++;5790	return 0;5791}5792 5793static const struct bpf_core_relo *find_relo_core(struct bpf_program *prog, int insn_idx)5794{5795	struct reloc_desc *relo;5796	int i;5797 5798	for (i = 0; i < prog->nr_reloc; i++) {5799		relo = &prog->reloc_desc[i];5800		if (relo->type != RELO_CORE || relo->insn_idx != insn_idx)5801			continue;5802 5803		return relo->core_relo;5804	}5805 5806	return NULL;5807}5808 5809static int bpf_core_resolve_relo(struct bpf_program *prog,5810				 const struct bpf_core_relo *relo,5811				 int relo_idx,5812				 const struct btf *local_btf,5813				 struct hashmap *cand_cache,5814				 struct bpf_core_relo_res *targ_res)5815{5816	struct bpf_core_spec specs_scratch[3] = {};5817	struct bpf_core_cand_list *cands = NULL;5818	const char *prog_name = prog->name;5819	const struct btf_type *local_type;5820	const char *local_name;5821	__u32 local_id = relo->type_id;5822	int err;5823 5824	local_type = btf__type_by_id(local_btf, local_id);5825	if (!local_type)5826		return -EINVAL;5827 5828	local_name = btf__name_by_offset(local_btf, local_type->name_off);5829	if (!local_name)5830		return -EINVAL;5831 5832	if (relo->kind != BPF_CORE_TYPE_ID_LOCAL &&5833	    !hashmap__find(cand_cache, local_id, &cands)) {5834		cands = bpf_core_find_cands(prog->obj, local_btf, local_id);5835		if (IS_ERR(cands)) {5836			pr_warn("prog '%s': relo #%d: target candidate search failed for [%d] %s %s: %ld\n",5837				prog_name, relo_idx, local_id, btf_kind_str(local_type),5838				local_name, PTR_ERR(cands));5839			return PTR_ERR(cands);5840		}5841		err = hashmap__set(cand_cache, local_id, cands, NULL, NULL);5842		if (err) {5843			bpf_core_free_cands(cands);5844			return err;5845		}5846	}5847 5848	return bpf_core_calc_relo_insn(prog_name, relo, relo_idx, local_btf, cands, specs_scratch,5849				       targ_res);5850}5851 5852static int5853bpf_object__relocate_core(struct bpf_object *obj, const char *targ_btf_path)5854{5855	const struct btf_ext_info_sec *sec;5856	struct bpf_core_relo_res targ_res;5857	const struct bpf_core_relo *rec;5858	const struct btf_ext_info *seg;5859	struct hashmap_entry *entry;5860	struct hashmap *cand_cache = NULL;5861	struct bpf_program *prog;5862	struct bpf_insn *insn;5863	const char *sec_name;5864	int i, err = 0, insn_idx, sec_idx, sec_num;5865 5866	if (obj->btf_ext->core_relo_info.len == 0)5867		return 0;5868 5869	if (targ_btf_path) {5870		obj->btf_vmlinux_override = btf__parse(targ_btf_path, NULL);5871		err = libbpf_get_error(obj->btf_vmlinux_override);5872		if (err) {5873			pr_warn("failed to parse target BTF: %d\n", err);5874			return err;5875		}5876	}5877 5878	cand_cache = hashmap__new(bpf_core_hash_fn, bpf_core_equal_fn, NULL);5879	if (IS_ERR(cand_cache)) {5880		err = PTR_ERR(cand_cache);5881		goto out;5882	}5883 5884	seg = &obj->btf_ext->core_relo_info;5885	sec_num = 0;5886	for_each_btf_ext_sec(seg, sec) {5887		sec_idx = seg->sec_idxs[sec_num];5888		sec_num++;5889 5890		sec_name = btf__name_by_offset(obj->btf, sec->sec_name_off);5891		if (str_is_empty(sec_name)) {5892			err = -EINVAL;5893			goto out;5894		}5895 5896		pr_debug("sec '%s': found %d CO-RE relocations\n", sec_name, sec->num_info);5897 5898		for_each_btf_ext_rec(seg, sec, i, rec) {5899			if (rec->insn_off % BPF_INSN_SZ)5900				return -EINVAL;5901			insn_idx = rec->insn_off / BPF_INSN_SZ;5902			prog = find_prog_by_sec_insn(obj, sec_idx, insn_idx);5903			if (!prog) {5904				/* When __weak subprog is "overridden" by another instance5905				 * of the subprog from a different object file, linker still5906				 * appends all the .BTF.ext info that used to belong to that5907				 * eliminated subprogram.5908				 * This is similar to what x86-64 linker does for relocations.5909				 * So just ignore such relocations just like we ignore5910				 * subprog instructions when discovering subprograms.5911				 */5912				pr_debug("sec '%s': skipping CO-RE relocation #%d for insn #%d belonging to eliminated weak subprogram\n",5913					 sec_name, i, insn_idx);5914				continue;5915			}5916			/* no need to apply CO-RE relocation if the program is5917			 * not going to be loaded5918			 */5919			if (!prog->autoload)5920				continue;5921 5922			/* adjust insn_idx from section frame of reference to the local5923			 * program's frame of reference; (sub-)program code is not yet5924			 * relocated, so it's enough to just subtract in-section offset5925			 */5926			insn_idx = insn_idx - prog->sec_insn_off;5927			if (insn_idx >= prog->insns_cnt)5928				return -EINVAL;5929			insn = &prog->insns[insn_idx];5930 5931			err = record_relo_core(prog, rec, insn_idx);5932			if (err) {5933				pr_warn("prog '%s': relo #%d: failed to record relocation: %d\n",5934					prog->name, i, err);5935				goto out;5936			}5937 5938			if (prog->obj->gen_loader)5939				continue;5940 5941			err = bpf_core_resolve_relo(prog, rec, i, obj->btf, cand_cache, &targ_res);5942			if (err) {5943				pr_warn("prog '%s': relo #%d: failed to relocate: %d\n",5944					prog->name, i, err);5945				goto out;5946			}5947 5948			err = bpf_core_patch_insn(prog->name, insn, insn_idx, rec, i, &targ_res);5949			if (err) {5950				pr_warn("prog '%s': relo #%d: failed to patch insn #%u: %d\n",5951					prog->name, i, insn_idx, err);5952				goto out;5953			}5954		}5955	}5956 5957out:5958	/* obj->btf_vmlinux and module BTFs are freed after object load */5959	btf__free(obj->btf_vmlinux_override);5960	obj->btf_vmlinux_override = NULL;5961 5962	if (!IS_ERR_OR_NULL(cand_cache)) {5963		hashmap__for_each_entry(cand_cache, entry, i) {5964			bpf_core_free_cands(entry->pvalue);5965		}5966		hashmap__free(cand_cache);5967	}5968	return err;5969}5970 5971/* base map load ldimm64 special constant, used also for log fixup logic */5972#define POISON_LDIMM64_MAP_BASE 20010000005973#define POISON_LDIMM64_MAP_PFX "200100"5974 5975static void poison_map_ldimm64(struct bpf_program *prog, int relo_idx,5976			       int insn_idx, struct bpf_insn *insn,5977			       int map_idx, const struct bpf_map *map)5978{5979	int i;5980 5981	pr_debug("prog '%s': relo #%d: poisoning insn #%d that loads map #%d '%s'\n",5982		 prog->name, relo_idx, insn_idx, map_idx, map->name);5983 5984	/* we turn single ldimm64 into two identical invalid calls */5985	for (i = 0; i < 2; i++) {5986		insn->code = BPF_JMP | BPF_CALL;5987		insn->dst_reg = 0;5988		insn->src_reg = 0;5989		insn->off = 0;5990		/* if this instruction is reachable (not a dead code),5991		 * verifier will complain with something like:5992		 * invalid func unknown#20010001235993		 * where lower 123 is map index into obj->maps[] array5994		 */5995		insn->imm = POISON_LDIMM64_MAP_BASE + map_idx;5996 5997		insn++;5998	}5999}6000 6001/* unresolved kfunc call special constant, used also for log fixup logic */6002#define POISON_CALL_KFUNC_BASE 20020000006003#define POISON_CALL_KFUNC_PFX "2002"6004 6005static void poison_kfunc_call(struct bpf_program *prog, int relo_idx,6006			      int insn_idx, struct bpf_insn *insn,6007			      int ext_idx, const struct extern_desc *ext)6008{6009	pr_debug("prog '%s': relo #%d: poisoning insn #%d that calls kfunc '%s'\n",6010		 prog->name, relo_idx, insn_idx, ext->name);6011 6012	/* we turn kfunc call into invalid helper call with identifiable constant */6013	insn->code = BPF_JMP | BPF_CALL;6014	insn->dst_reg = 0;6015	insn->src_reg = 0;6016	insn->off = 0;6017	/* if this instruction is reachable (not a dead code),6018	 * verifier will complain with something like:6019	 * invalid func unknown#20010001236020	 * where lower 123 is extern index into obj->externs[] array6021	 */6022	insn->imm = POISON_CALL_KFUNC_BASE + ext_idx;6023}6024 6025/* Relocate data references within program code:6026 *  - map references;6027 *  - global variable references;6028 *  - extern references.6029 */6030static int6031bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog)6032{6033	int i;6034 6035	for (i = 0; i < prog->nr_reloc; i++) {6036		struct reloc_desc *relo = &prog->reloc_desc[i];6037		struct bpf_insn *insn = &prog->insns[relo->insn_idx];6038		const struct bpf_map *map;6039		struct extern_desc *ext;6040 6041		switch (relo->type) {6042		case RELO_LD64:6043			map = &obj->maps[relo->map_idx];6044			if (obj->gen_loader) {6045				insn[0].src_reg = BPF_PSEUDO_MAP_IDX;6046				insn[0].imm = relo->map_idx;6047			} else if (map->autocreate) {6048				insn[0].src_reg = BPF_PSEUDO_MAP_FD;6049				insn[0].imm = map->fd;6050			} else {6051				poison_map_ldimm64(prog, i, relo->insn_idx, insn,6052						   relo->map_idx, map);6053			}6054			break;6055		case RELO_DATA:6056			map = &obj->maps[relo->map_idx];6057			insn[1].imm = insn[0].imm + relo->sym_off;6058			if (obj->gen_loader) {6059				insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE;6060				insn[0].imm = relo->map_idx;6061			} else if (map->autocreate) {6062				insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;6063				insn[0].imm = map->fd;6064			} else {6065				poison_map_ldimm64(prog, i, relo->insn_idx, insn,6066						   relo->map_idx, map);6067			}6068			break;6069		case RELO_EXTERN_LD64:6070			ext = &obj->externs[relo->ext_idx];6071			if (ext->type == EXT_KCFG) {6072				if (obj->gen_loader) {6073					insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE;6074					insn[0].imm = obj->kconfig_map_idx;6075				} else {6076					insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;6077					insn[0].imm = obj->maps[obj->kconfig_map_idx].fd;6078				}6079				insn[1].imm = ext->kcfg.data_off;6080			} else /* EXT_KSYM */ {6081				if (ext->ksym.type_id && ext->is_set) { /* typed ksyms */6082					insn[0].src_reg = BPF_PSEUDO_BTF_ID;6083					insn[0].imm = ext->ksym.kernel_btf_id;6084					insn[1].imm = ext->ksym.kernel_btf_obj_fd;6085				} else { /* typeless ksyms or unresolved typed ksyms */6086					insn[0].imm = (__u32)ext->ksym.addr;6087					insn[1].imm = ext->ksym.addr >> 32;6088				}6089			}6090			break;6091		case RELO_EXTERN_CALL:6092			ext = &obj->externs[relo->ext_idx];6093			insn[0].src_reg = BPF_PSEUDO_KFUNC_CALL;6094			if (ext->is_set) {6095				insn[0].imm = ext->ksym.kernel_btf_id;6096				insn[0].off = ext->ksym.btf_fd_idx;6097			} else { /* unresolved weak kfunc call */6098				poison_kfunc_call(prog, i, relo->insn_idx, insn,6099						  relo->ext_idx, ext);6100			}6101			break;6102		case RELO_SUBPROG_ADDR:6103			if (insn[0].src_reg != BPF_PSEUDO_FUNC) {6104				pr_warn("prog '%s': relo #%d: bad insn\n",6105					prog->name, i);6106				return -EINVAL;6107			}6108			/* handled already */6109			break;6110		case RELO_CALL:6111			/* handled already */6112			break;6113		case RELO_CORE:6114			/* will be handled by bpf_program_record_relos() */6115			break;6116		default:6117			pr_warn("prog '%s': relo #%d: bad relo type %d\n",6118				prog->name, i, relo->type);6119			return -EINVAL;6120		}6121	}6122 6123	return 0;6124}6125 6126static int adjust_prog_btf_ext_info(const struct bpf_object *obj,6127				    const struct bpf_program *prog,6128				    const struct btf_ext_info *ext_info,6129				    void **prog_info, __u32 *prog_rec_cnt,6130				    __u32 *prog_rec_sz)6131{6132	void *copy_start = NULL, *copy_end = NULL;6133	void *rec, *rec_end, *new_prog_info;6134	const struct btf_ext_info_sec *sec;6135	size_t old_sz, new_sz;6136	int i, sec_num, sec_idx, off_adj;6137 6138	sec_num = 0;6139	for_each_btf_ext_sec(ext_info, sec) {6140		sec_idx = ext_info->sec_idxs[sec_num];6141		sec_num++;6142		if (prog->sec_idx != sec_idx)6143			continue;6144 6145		for_each_btf_ext_rec(ext_info, sec, i, rec) {6146			__u32 insn_off = *(__u32 *)rec / BPF_INSN_SZ;6147 6148			if (insn_off < prog->sec_insn_off)6149				continue;6150			if (insn_off >= prog->sec_insn_off + prog->sec_insn_cnt)6151				break;6152 6153			if (!copy_start)6154				copy_start = rec;6155			copy_end = rec + ext_info->rec_size;6156		}6157 6158		if (!copy_start)6159			return -ENOENT;6160 6161		/* append func/line info of a given (sub-)program to the main6162		 * program func/line info6163		 */6164		old_sz = (size_t)(*prog_rec_cnt) * ext_info->rec_size;6165		new_sz = old_sz + (copy_end - copy_start);6166		new_prog_info = realloc(*prog_info, new_sz);6167		if (!new_prog_info)6168			return -ENOMEM;6169		*prog_info = new_prog_info;6170		*prog_rec_cnt = new_sz / ext_info->rec_size;6171		memcpy(new_prog_info + old_sz, copy_start, copy_end - copy_start);6172 6173		/* Kernel instruction offsets are in units of 8-byte6174		 * instructions, while .BTF.ext instruction offsets generated6175		 * by Clang are in units of bytes. So convert Clang offsets6176		 * into kernel offsets and adjust offset according to program6177		 * relocated position.6178		 */6179		off_adj = prog->sub_insn_off - prog->sec_insn_off;6180		rec = new_prog_info + old_sz;6181		rec_end = new_prog_info + new_sz;6182		for (; rec < rec_end; rec += ext_info->rec_size) {6183			__u32 *insn_off = rec;6184 6185			*insn_off = *insn_off / BPF_INSN_SZ + off_adj;6186		}6187		*prog_rec_sz = ext_info->rec_size;6188		return 0;6189	}6190 6191	return -ENOENT;6192}6193 6194static int6195reloc_prog_func_and_line_info(const struct bpf_object *obj,6196			      struct bpf_program *main_prog,6197			      const struct bpf_program *prog)6198{6199	int err;6200 6201	/* no .BTF.ext relocation if .BTF.ext is missing or kernel doesn't6202	 * support func/line info6203	 */6204	if (!obj->btf_ext || !kernel_supports(obj, FEAT_BTF_FUNC))6205		return 0;6206 6207	/* only attempt func info relocation if main program's func_info6208	 * relocation was successful6209	 */6210	if (main_prog != prog && !main_prog->func_info)6211		goto line_info;6212 6213	err = adjust_prog_btf_ext_info(obj, prog, &obj->btf_ext->func_info,6214				       &main_prog->func_info,6215				       &main_prog->func_info_cnt,6216				       &main_prog->func_info_rec_size);6217	if (err) {6218		if (err != -ENOENT) {6219			pr_warn("prog '%s': error relocating .BTF.ext function info: %d\n",6220				prog->name, err);6221			return err;6222		}6223		if (main_prog->func_info) {6224			/*6225			 * Some info has already been found but has problem6226			 * in the last btf_ext reloc. Must have to error out.6227			 */6228			pr_warn("prog '%s': missing .BTF.ext function info.\n", prog->name);6229			return err;6230		}6231		/* Have problem loading the very first info. Ignore the rest. */6232		pr_warn("prog '%s': missing .BTF.ext function info for the main program, skipping all of .BTF.ext func info.\n",6233			prog->name);6234	}6235 6236line_info:6237	/* don't relocate line info if main program's relocation failed */6238	if (main_prog != prog && !main_prog->line_info)6239		return 0;6240 6241	err = adjust_prog_btf_ext_info(obj, prog, &obj->btf_ext->line_info,6242				       &main_prog->line_info,6243				       &main_prog->line_info_cnt,6244				       &main_prog->line_info_rec_size);6245	if (err) {6246		if (err != -ENOENT) {6247			pr_warn("prog '%s': error relocating .BTF.ext line info: %d\n",6248				prog->name, err);6249			return err;6250		}6251		if (main_prog->line_info) {6252			/*6253			 * Some info has already been found but has problem6254			 * in the last btf_ext reloc. Must have to error out.6255			 */6256			pr_warn("prog '%s': missing .BTF.ext line info.\n", prog->name);6257			return err;6258		}6259		/* Have problem loading the very first info. Ignore the rest. */6260		pr_warn("prog '%s': missing .BTF.ext line info for the main program, skipping all of .BTF.ext line info.\n",6261			prog->name);6262	}6263	return 0;6264}6265 6266static int cmp_relo_by_insn_idx(const void *key, const void *elem)6267{6268	size_t insn_idx = *(const size_t *)key;6269	const struct reloc_desc *relo = elem;6270 6271	if (insn_idx == relo->insn_idx)6272		return 0;6273	return insn_idx < relo->insn_idx ? -1 : 1;6274}6275 6276static struct reloc_desc *find_prog_insn_relo(const struct bpf_program *prog, size_t insn_idx)6277{6278	if (!prog->nr_reloc)6279		return NULL;6280	return bsearch(&insn_idx, prog->reloc_desc, prog->nr_reloc,6281		       sizeof(*prog->reloc_desc), cmp_relo_by_insn_idx);6282}6283 6284static int append_subprog_relos(struct bpf_program *main_prog, struct bpf_program *subprog)6285{6286	int new_cnt = main_prog->nr_reloc + subprog->nr_reloc;6287	struct reloc_desc *relos;6288	int i;6289 6290	if (main_prog == subprog)6291		return 0;6292	relos = libbpf_reallocarray(main_prog->reloc_desc, new_cnt, sizeof(*relos));6293	/* if new count is zero, reallocarray can return a valid NULL result;6294	 * in this case the previous pointer will be freed, so we *have to*6295	 * reassign old pointer to the new value (even if it's NULL)6296	 */6297	if (!relos && new_cnt)6298		return -ENOMEM;6299	if (subprog->nr_reloc)6300		memcpy(relos + main_prog->nr_reloc, subprog->reloc_desc,6301		       sizeof(*relos) * subprog->nr_reloc);6302 6303	for (i = main_prog->nr_reloc; i < new_cnt; i++)6304		relos[i].insn_idx += subprog->sub_insn_off;6305	/* After insn_idx adjustment the 'relos' array is still sorted6306	 * by insn_idx and doesn't break bsearch.6307	 */6308	main_prog->reloc_desc = relos;6309	main_prog->nr_reloc = new_cnt;6310	return 0;6311}6312 6313static int6314bpf_object__append_subprog_code(struct bpf_object *obj, struct bpf_program *main_prog,6315				struct bpf_program *subprog)6316{6317       struct bpf_insn *insns;6318       size_t new_cnt;6319       int err;6320 6321       subprog->sub_insn_off = main_prog->insns_cnt;6322 6323       new_cnt = main_prog->insns_cnt + subprog->insns_cnt;6324       insns = libbpf_reallocarray(main_prog->insns, new_cnt, sizeof(*insns));6325       if (!insns) {6326               pr_warn("prog '%s': failed to realloc prog code\n", main_prog->name);6327               return -ENOMEM;6328       }6329       main_prog->insns = insns;6330       main_prog->insns_cnt = new_cnt;6331 6332       memcpy(main_prog->insns + subprog->sub_insn_off, subprog->insns,6333              subprog->insns_cnt * sizeof(*insns));6334 6335       pr_debug("prog '%s': added %zu insns from sub-prog '%s'\n",6336                main_prog->name, subprog->insns_cnt, subprog->name);6337 6338       /* The subprog insns are now appended. Append its relos too. */6339       err = append_subprog_relos(main_prog, subprog);6340       if (err)6341               return err;6342       return 0;6343}6344 6345static int6346bpf_object__reloc_code(struct bpf_object *obj, struct bpf_program *main_prog,6347		       struct bpf_program *prog)6348{6349	size_t sub_insn_idx, insn_idx;6350	struct bpf_program *subprog;6351	struct reloc_desc *relo;6352	struct bpf_insn *insn;6353	int err;6354 6355	err = reloc_prog_func_and_line_info(obj, main_prog, prog);6356	if (err)6357		return err;6358 6359	for (insn_idx = 0; insn_idx < prog->sec_insn_cnt; insn_idx++) {6360		insn = &main_prog->insns[prog->sub_insn_off + insn_idx];6361		if (!insn_is_subprog_call(insn) && !insn_is_pseudo_func(insn))6362			continue;6363 6364		relo = find_prog_insn_relo(prog, insn_idx);6365		if (relo && relo->type == RELO_EXTERN_CALL)6366			/* kfunc relocations will be handled later6367			 * in bpf_object__relocate_data()6368			 */6369			continue;6370		if (relo && relo->type != RELO_CALL && relo->type != RELO_SUBPROG_ADDR) {6371			pr_warn("prog '%s': unexpected relo for insn #%zu, type %d\n",6372				prog->name, insn_idx, relo->type);6373			return -LIBBPF_ERRNO__RELOC;6374		}6375		if (relo) {6376			/* sub-program instruction index is a combination of6377			 * an offset of a symbol pointed to by relocation and6378			 * call instruction's imm field; for global functions,6379			 * call always has imm = -1, but for static functions6380			 * relocation is against STT_SECTION and insn->imm6381			 * points to a start of a static function6382			 *6383			 * for subprog addr relocation, the relo->sym_off + insn->imm is6384			 * the byte offset in the corresponding section.6385			 */6386			if (relo->type == RELO_CALL)6387				sub_insn_idx = relo->sym_off / BPF_INSN_SZ + insn->imm + 1;6388			else6389				sub_insn_idx = (relo->sym_off + insn->imm) / BPF_INSN_SZ;6390		} else if (insn_is_pseudo_func(insn)) {6391			/*6392			 * RELO_SUBPROG_ADDR relo is always emitted even if both6393			 * functions are in the same section, so it shouldn't reach here.6394			 */6395			pr_warn("prog '%s': missing subprog addr relo for insn #%zu\n",6396				prog->name, insn_idx);6397			return -LIBBPF_ERRNO__RELOC;6398		} else {6399			/* if subprogram call is to a static function within6400			 * the same ELF section, there won't be any relocation6401			 * emitted, but it also means there is no additional6402			 * offset necessary, insns->imm is relative to6403			 * instruction's original position within the section6404			 */6405			sub_insn_idx = prog->sec_insn_off + insn_idx + insn->imm + 1;6406		}6407 6408		/* we enforce that sub-programs should be in .text section */6409		subprog = find_prog_by_sec_insn(obj, obj->efile.text_shndx, sub_insn_idx);6410		if (!subprog) {6411			pr_warn("prog '%s': no .text section found yet sub-program call exists\n",6412				prog->name);6413			return -LIBBPF_ERRNO__RELOC;6414		}6415 6416		/* if it's the first call instruction calling into this6417		 * subprogram (meaning this subprog hasn't been processed6418		 * yet) within the context of current main program:6419		 *   - append it at the end of main program's instructions blog;6420		 *   - process is recursively, while current program is put on hold;6421		 *   - if that subprogram calls some other not yet processes6422		 *   subprogram, same thing will happen recursively until6423		 *   there are no more unprocesses subprograms left to append6424		 *   and relocate.6425		 */6426		if (subprog->sub_insn_off == 0) {6427			err = bpf_object__append_subprog_code(obj, main_prog, subprog);6428			if (err)6429				return err;6430			err = bpf_object__reloc_code(obj, main_prog, subprog);6431			if (err)6432				return err;6433		}6434 6435		/* main_prog->insns memory could have been re-allocated, so6436		 * calculate pointer again6437		 */6438		insn = &main_prog->insns[prog->sub_insn_off + insn_idx];6439		/* calculate correct instruction position within current main6440		 * prog; each main prog can have a different set of6441		 * subprograms appended (potentially in different order as6442		 * well), so position of any subprog can be different for6443		 * different main programs6444		 */6445		insn->imm = subprog->sub_insn_off - (prog->sub_insn_off + insn_idx) - 1;6446 6447		pr_debug("prog '%s': insn #%zu relocated, imm %d points to subprog '%s' (now at %zu offset)\n",6448			 prog->name, insn_idx, insn->imm, subprog->name, subprog->sub_insn_off);6449	}6450 6451	return 0;6452}6453 6454/*6455 * Relocate sub-program calls.6456 *6457 * Algorithm operates as follows. Each entry-point BPF program (referred to as6458 * main prog) is processed separately. For each subprog (non-entry functions,6459 * that can be called from either entry progs or other subprogs) gets their6460 * sub_insn_off reset to zero. This serves as indicator that this subprogram6461 * hasn't been yet appended and relocated within current main prog. Once its6462 * relocated, sub_insn_off will point at the position within current main prog6463 * where given subprog was appended. This will further be used to relocate all6464 * the call instructions jumping into this subprog.6465 *6466 * We start with main program and process all call instructions. If the call6467 * is into a subprog that hasn't been processed (i.e., subprog->sub_insn_off6468 * is zero), subprog instructions are appended at the end of main program's6469 * instruction array. Then main program is "put on hold" while we recursively6470 * process newly appended subprogram. If that subprogram calls into another6471 * subprogram that hasn't been appended, new subprogram is appended again to6472 * the *main* prog's instructions (subprog's instructions are always left6473 * untouched, as they need to be in unmodified state for subsequent main progs6474 * and subprog instructions are always sent only as part of a main prog) and6475 * the process continues recursively. Once all the subprogs called from a main6476 * prog or any of its subprogs are appended (and relocated), all their6477 * positions within finalized instructions array are known, so it's easy to6478 * rewrite call instructions with correct relative offsets, corresponding to6479 * desired target subprog.6480 *6481 * Its important to realize that some subprogs might not be called from some6482 * main prog and any of its called/used subprogs. Those will keep their6483 * subprog->sub_insn_off as zero at all times and won't be appended to current6484 * main prog and won't be relocated within the context of current main prog.6485 * They might still be used from other main progs later.6486 *6487 * Visually this process can be shown as below. Suppose we have two main6488 * programs mainA and mainB and BPF object contains three subprogs: subA,6489 * subB, and subC. mainA calls only subA, mainB calls only subC, but subA and6490 * subC both call subB:6491 *6492 *        +--------+ +-------+6493 *        |        v v       |6494 *     +--+---+ +--+-+-+ +---+--+6495 *     | subA | | subB | | subC |6496 *     +--+---+ +------+ +---+--+6497 *        ^                  ^6498 *        |                  |6499 *    +---+-------+   +------+----+6500 *    |   mainA   |   |   mainB   |6501 *    +-----------+   +-----------+6502 *6503 * We'll start relocating mainA, will find subA, append it and start6504 * processing sub A recursively:6505 *6506 *    +-----------+------+6507 *    |   mainA   | subA |6508 *    +-----------+------+6509 *6510 * At this point we notice that subB is used from subA, so we append it and6511 * relocate (there are no further subcalls from subB):6512 *6513 *    +-----------+------+------+6514 *    |   mainA   | subA | subB |6515 *    +-----------+------+------+6516 *6517 * At this point, we relocate subA calls, then go one level up and finish with6518 * relocatin mainA calls. mainA is done.6519 *6520 * For mainB process is similar but results in different order. We start with6521 * mainB and skip subA and subB, as mainB never calls them (at least6522 * directly), but we see subC is needed, so we append and start processing it:6523 *6524 *    +-----------+------+6525 *    |   mainB   | subC |6526 *    +-----------+------+6527 * Now we see subC needs subB, so we go back to it, append and relocate it:6528 *6529 *    +-----------+------+------+6530 *    |   mainB   | subC | subB |6531 *    +-----------+------+------+6532 *6533 * At this point we unwind recursion, relocate calls in subC, then in mainB.6534 */6535static int6536bpf_object__relocate_calls(struct bpf_object *obj, struct bpf_program *prog)6537{6538	struct bpf_program *subprog;6539	int i, err;6540 6541	/* mark all subprogs as not relocated (yet) within the context of6542	 * current main program6543	 */6544	for (i = 0; i < obj->nr_programs; i++) {6545		subprog = &obj->programs[i];6546		if (!prog_is_subprog(obj, subprog))6547			continue;6548 6549		subprog->sub_insn_off = 0;6550	}6551 6552	err = bpf_object__reloc_code(obj, prog, prog);6553	if (err)6554		return err;6555 6556	return 0;6557}6558 6559static void6560bpf_object__free_relocs(struct bpf_object *obj)6561{6562	struct bpf_program *prog;6563	int i;6564 6565	/* free up relocation descriptors */6566	for (i = 0; i < obj->nr_programs; i++) {6567		prog = &obj->programs[i];6568		zfree(&prog->reloc_desc);6569		prog->nr_reloc = 0;6570	}6571}6572 6573static int cmp_relocs(const void *_a, const void *_b)6574{6575	const struct reloc_desc *a = _a;6576	const struct reloc_desc *b = _b;6577 6578	if (a->insn_idx != b->insn_idx)6579		return a->insn_idx < b->insn_idx ? -1 : 1;6580 6581	/* no two relocations should have the same insn_idx, but ... */6582	if (a->type != b->type)6583		return a->type < b->type ? -1 : 1;6584 6585	return 0;6586}6587 6588static void bpf_object__sort_relos(struct bpf_object *obj)6589{6590	int i;6591 6592	for (i = 0; i < obj->nr_programs; i++) {6593		struct bpf_program *p = &obj->programs[i];6594 6595		if (!p->nr_reloc)6596			continue;6597 6598		qsort(p->reloc_desc, p->nr_reloc, sizeof(*p->reloc_desc), cmp_relocs);6599	}6600}6601 6602static int bpf_prog_assign_exc_cb(struct bpf_object *obj, struct bpf_program *prog)6603{6604	const char *str = "exception_callback:";6605	size_t pfx_len = strlen(str);6606	int i, j, n;6607 6608	if (!obj->btf || !kernel_supports(obj, FEAT_BTF_DECL_TAG))6609		return 0;6610 6611	n = btf__type_cnt(obj->btf);6612	for (i = 1; i < n; i++) {6613		const char *name;6614		struct btf_type *t;6615 6616		t = btf_type_by_id(obj->btf, i);6617		if (!btf_is_decl_tag(t) || btf_decl_tag(t)->component_idx != -1)6618			continue;6619 6620		name = btf__str_by_offset(obj->btf, t->name_off);6621		if (strncmp(name, str, pfx_len) != 0)6622			continue;6623 6624		t = btf_type_by_id(obj->btf, t->type);6625		if (!btf_is_func(t) || btf_func_linkage(t) != BTF_FUNC_GLOBAL) {6626			pr_warn("prog '%s': exception_callback:<value> decl tag not applied to the main program\n",6627				prog->name);6628			return -EINVAL;6629		}6630		if (strcmp(prog->name, btf__str_by_offset(obj->btf, t->name_off)) != 0)6631			continue;6632		/* Multiple callbacks are specified for the same prog,6633		 * the verifier will eventually return an error for this6634		 * case, hence simply skip appending a subprog.6635		 */6636		if (prog->exception_cb_idx >= 0) {6637			prog->exception_cb_idx = -1;6638			break;6639		}6640 6641		name += pfx_len;6642		if (str_is_empty(name)) {6643			pr_warn("prog '%s': exception_callback:<value> decl tag contains empty value\n",6644				prog->name);6645			return -EINVAL;6646		}6647 6648		for (j = 0; j < obj->nr_programs; j++) {6649			struct bpf_program *subprog = &obj->programs[j];6650 6651			if (!prog_is_subprog(obj, subprog))6652				continue;6653			if (strcmp(name, subprog->name) != 0)6654				continue;6655			/* Enforce non-hidden, as from verifier point of6656			 * view it expects global functions, whereas the6657			 * mark_btf_static fixes up linkage as static.6658			 */6659			if (!subprog->sym_global || subprog->mark_btf_static) {6660				pr_warn("prog '%s': exception callback %s must be a global non-hidden function\n",6661					prog->name, subprog->name);6662				return -EINVAL;6663			}6664			/* Let's see if we already saw a static exception callback with the same name */6665			if (prog->exception_cb_idx >= 0) {6666				pr_warn("prog '%s': multiple subprogs with same name as exception callback '%s'\n",6667					prog->name, subprog->name);6668				return -EINVAL;6669			}6670			prog->exception_cb_idx = j;6671			break;6672		}6673 6674		if (prog->exception_cb_idx >= 0)6675			continue;6676 6677		pr_warn("prog '%s': cannot find exception callback '%s'\n", prog->name, name);6678		return -ENOENT;6679	}6680 6681	return 0;6682}6683 6684static struct {6685	enum bpf_prog_type prog_type;6686	const char *ctx_name;6687} global_ctx_map[] = {6688	{ BPF_PROG_TYPE_CGROUP_DEVICE,           "bpf_cgroup_dev_ctx" },6689	{ BPF_PROG_TYPE_CGROUP_SKB,              "__sk_buff" },6690	{ BPF_PROG_TYPE_CGROUP_SOCK,             "bpf_sock" },6691	{ BPF_PROG_TYPE_CGROUP_SOCK_ADDR,        "bpf_sock_addr" },6692	{ BPF_PROG_TYPE_CGROUP_SOCKOPT,          "bpf_sockopt" },6693	{ BPF_PROG_TYPE_CGROUP_SYSCTL,           "bpf_sysctl" },6694	{ BPF_PROG_TYPE_FLOW_DISSECTOR,          "__sk_buff" },6695	{ BPF_PROG_TYPE_KPROBE,                  "bpf_user_pt_regs_t" },6696	{ BPF_PROG_TYPE_LWT_IN,                  "__sk_buff" },6697	{ BPF_PROG_TYPE_LWT_OUT,                 "__sk_buff" },6698	{ BPF_PROG_TYPE_LWT_SEG6LOCAL,           "__sk_buff" },6699	{ BPF_PROG_TYPE_LWT_XMIT,                "__sk_buff" },6700	{ BPF_PROG_TYPE_NETFILTER,               "bpf_nf_ctx" },6701	{ BPF_PROG_TYPE_PERF_EVENT,              "bpf_perf_event_data" },6702	{ BPF_PROG_TYPE_RAW_TRACEPOINT,          "bpf_raw_tracepoint_args" },6703	{ BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, "bpf_raw_tracepoint_args" },6704	{ BPF_PROG_TYPE_SCHED_ACT,               "__sk_buff" },6705	{ BPF_PROG_TYPE_SCHED_CLS,               "__sk_buff" },6706	{ BPF_PROG_TYPE_SK_LOOKUP,               "bpf_sk_lookup" },6707	{ BPF_PROG_TYPE_SK_MSG,                  "sk_msg_md" },6708	{ BPF_PROG_TYPE_SK_REUSEPORT,            "sk_reuseport_md" },6709	{ BPF_PROG_TYPE_SK_SKB,                  "__sk_buff" },6710	{ BPF_PROG_TYPE_SOCK_OPS,                "bpf_sock_ops" },6711	{ BPF_PROG_TYPE_SOCKET_FILTER,           "__sk_buff" },6712	{ BPF_PROG_TYPE_XDP,                     "xdp_md" },6713	/* all other program types don't have "named" context structs */6714};6715 6716/* forward declarations for arch-specific underlying types of bpf_user_pt_regs_t typedef,6717 * for below __builtin_types_compatible_p() checks;6718 * with this approach we don't need any extra arch-specific #ifdef guards6719 */6720struct pt_regs;6721struct user_pt_regs;6722struct user_regs_struct;6723 6724static bool need_func_arg_type_fixup(const struct btf *btf, const struct bpf_program *prog,6725				     const char *subprog_name, int arg_idx,6726				     int arg_type_id, const char *ctx_name)6727{6728	const struct btf_type *t;6729	const char *tname;6730 6731	/* check if existing parameter already matches verifier expectations */6732	t = skip_mods_and_typedefs(btf, arg_type_id, NULL);6733	if (!btf_is_ptr(t))6734		goto out_warn;6735 6736	/* typedef bpf_user_pt_regs_t is a special PITA case, valid for kprobe6737	 * and perf_event programs, so check this case early on and forget6738	 * about it for subsequent checks6739	 */6740	while (btf_is_mod(t))6741		t = btf__type_by_id(btf, t->type);6742	if (btf_is_typedef(t) &&6743	    (prog->type == BPF_PROG_TYPE_KPROBE || prog->type == BPF_PROG_TYPE_PERF_EVENT)) {6744		tname = btf__str_by_offset(btf, t->name_off) ?: "<anon>";6745		if (strcmp(tname, "bpf_user_pt_regs_t") == 0)6746			return false; /* canonical type for kprobe/perf_event */6747	}6748 6749	/* now we can ignore typedefs moving forward */6750	t = skip_mods_and_typedefs(btf, t->type, NULL);6751 6752	/* if it's `void *`, definitely fix up BTF info */6753	if (btf_is_void(t))6754		return true;6755 6756	/* if it's already proper canonical type, no need to fix up */6757	tname = btf__str_by_offset(btf, t->name_off) ?: "<anon>";6758	if (btf_is_struct(t) && strcmp(tname, ctx_name) == 0)6759		return false;6760 6761	/* special cases */6762	switch (prog->type) {6763	case BPF_PROG_TYPE_KPROBE:6764		/* `struct pt_regs *` is expected, but we need to fix up */6765		if (btf_is_struct(t) && strcmp(tname, "pt_regs") == 0)6766			return true;6767		break;6768	case BPF_PROG_TYPE_PERF_EVENT:6769		if (__builtin_types_compatible_p(bpf_user_pt_regs_t, struct pt_regs) &&6770		    btf_is_struct(t) && strcmp(tname, "pt_regs") == 0)6771			return true;6772		if (__builtin_types_compatible_p(bpf_user_pt_regs_t, struct user_pt_regs) &&6773		    btf_is_struct(t) && strcmp(tname, "user_pt_regs") == 0)6774			return true;6775		if (__builtin_types_compatible_p(bpf_user_pt_regs_t, struct user_regs_struct) &&6776		    btf_is_struct(t) && strcmp(tname, "user_regs_struct") == 0)6777			return true;6778		break;6779	case BPF_PROG_TYPE_RAW_TRACEPOINT:6780	case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:6781		/* allow u64* as ctx */6782		if (btf_is_int(t) && t->size == 8)6783			return true;6784		break;6785	default:6786		break;6787	}6788 6789out_warn:6790	pr_warn("prog '%s': subprog '%s' arg#%d is expected to be of `struct %s *` type\n",6791		prog->name, subprog_name, arg_idx, ctx_name);6792	return false;6793}6794 6795static int clone_func_btf_info(struct btf *btf, int orig_fn_id, struct bpf_program *prog)6796{6797	int fn_id, fn_proto_id, ret_type_id, orig_proto_id;6798	int i, err, arg_cnt, fn_name_off, linkage;6799	struct btf_type *fn_t, *fn_proto_t, *t;6800	struct btf_param *p;6801 6802	/* caller already validated FUNC -> FUNC_PROTO validity */6803	fn_t = btf_type_by_id(btf, orig_fn_id);6804	fn_proto_t = btf_type_by_id(btf, fn_t->type);6805 6806	/* Note that each btf__add_xxx() operation invalidates6807	 * all btf_type and string pointers, so we need to be6808	 * very careful when cloning BTF types. BTF type6809	 * pointers have to be always refetched. And to avoid6810	 * problems with invalidated string pointers, we6811	 * add empty strings initially, then just fix up6812	 * name_off offsets in place. Offsets are stable for6813	 * existing strings, so that works out.6814	 */6815	fn_name_off = fn_t->name_off; /* we are about to invalidate fn_t */6816	linkage = btf_func_linkage(fn_t);6817	orig_proto_id = fn_t->type; /* original FUNC_PROTO ID */6818	ret_type_id = fn_proto_t->type; /* fn_proto_t will be invalidated */6819	arg_cnt = btf_vlen(fn_proto_t);6820 6821	/* clone FUNC_PROTO and its params */6822	fn_proto_id = btf__add_func_proto(btf, ret_type_id);6823	if (fn_proto_id < 0)6824		return -EINVAL;6825 6826	for (i = 0; i < arg_cnt; i++) {6827		int name_off;6828 6829		/* copy original parameter data */6830		t = btf_type_by_id(btf, orig_proto_id);6831		p = &btf_params(t)[i];6832		name_off = p->name_off;6833 6834		err = btf__add_func_param(btf, "", p->type);6835		if (err)6836			return err;6837 6838		fn_proto_t = btf_type_by_id(btf, fn_proto_id);6839		p = &btf_params(fn_proto_t)[i];6840		p->name_off = name_off; /* use remembered str offset */6841	}6842 6843	/* clone FUNC now, btf__add_func() enforces non-empty name, so use6844	 * entry program's name as a placeholder, which we replace immediately6845	 * with original name_off6846	 */6847	fn_id = btf__add_func(btf, prog->name, linkage, fn_proto_id);6848	if (fn_id < 0)6849		return -EINVAL;6850 6851	fn_t = btf_type_by_id(btf, fn_id);6852	fn_t->name_off = fn_name_off; /* reuse original string */6853 6854	return fn_id;6855}6856 6857/* Check if main program or global subprog's function prototype has `arg:ctx`6858 * argument tags, and, if necessary, substitute correct type to match what BPF6859 * verifier would expect, taking into account specific program type. This6860 * allows to support __arg_ctx tag transparently on old kernels that don't yet6861 * have a native support for it in the verifier, making user's life much6862 * easier.6863 */6864static int bpf_program_fixup_func_info(struct bpf_object *obj, struct bpf_program *prog)6865{6866	const char *ctx_name = NULL, *ctx_tag = "arg:ctx", *fn_name;6867	struct bpf_func_info_min *func_rec;6868	struct btf_type *fn_t, *fn_proto_t;6869	struct btf *btf = obj->btf;6870	const struct btf_type *t;6871	struct btf_param *p;6872	int ptr_id = 0, struct_id, tag_id, orig_fn_id;6873	int i, n, arg_idx, arg_cnt, err, rec_idx;6874	int *orig_ids;6875 6876	/* no .BTF.ext, no problem */6877	if (!obj->btf_ext || !prog->func_info)6878		return 0;6879 6880	/* don't do any fix ups if kernel natively supports __arg_ctx */6881	if (kernel_supports(obj, FEAT_ARG_CTX_TAG))6882		return 0;6883 6884	/* some BPF program types just don't have named context structs, so6885	 * this fallback mechanism doesn't work for them6886	 */6887	for (i = 0; i < ARRAY_SIZE(global_ctx_map); i++) {6888		if (global_ctx_map[i].prog_type != prog->type)6889			continue;6890		ctx_name = global_ctx_map[i].ctx_name;6891		break;6892	}6893	if (!ctx_name)6894		return 0;6895 6896	/* remember original func BTF IDs to detect if we already cloned them */6897	orig_ids = calloc(prog->func_info_cnt, sizeof(*orig_ids));6898	if (!orig_ids)6899		return -ENOMEM;6900	for (i = 0; i < prog->func_info_cnt; i++) {6901		func_rec = prog->func_info + prog->func_info_rec_size * i;6902		orig_ids[i] = func_rec->type_id;6903	}6904 6905	/* go through each DECL_TAG with "arg:ctx" and see if it points to one6906	 * of our subprogs; if yes and subprog is global and needs adjustment,6907	 * clone and adjust FUNC -> FUNC_PROTO combo6908	 */6909	for (i = 1, n = btf__type_cnt(btf); i < n; i++) {6910		/* only DECL_TAG with "arg:ctx" value are interesting */6911		t = btf__type_by_id(btf, i);6912		if (!btf_is_decl_tag(t))6913			continue;6914		if (strcmp(btf__str_by_offset(btf, t->name_off), ctx_tag) != 0)6915			continue;6916 6917		/* only global funcs need adjustment, if at all */6918		orig_fn_id = t->type;6919		fn_t = btf_type_by_id(btf, orig_fn_id);6920		if (!btf_is_func(fn_t) || btf_func_linkage(fn_t) != BTF_FUNC_GLOBAL)6921			continue;6922 6923		/* sanity check FUNC -> FUNC_PROTO chain, just in case */6924		fn_proto_t = btf_type_by_id(btf, fn_t->type);6925		if (!fn_proto_t || !btf_is_func_proto(fn_proto_t))6926			continue;6927 6928		/* find corresponding func_info record */6929		func_rec = NULL;6930		for (rec_idx = 0; rec_idx < prog->func_info_cnt; rec_idx++) {6931			if (orig_ids[rec_idx] == t->type) {6932				func_rec = prog->func_info + prog->func_info_rec_size * rec_idx;6933				break;6934			}6935		}6936		/* current main program doesn't call into this subprog */6937		if (!func_rec)6938			continue;6939 6940		/* some more sanity checking of DECL_TAG */6941		arg_cnt = btf_vlen(fn_proto_t);6942		arg_idx = btf_decl_tag(t)->component_idx;6943		if (arg_idx < 0 || arg_idx >= arg_cnt)6944			continue;6945 6946		/* check if we should fix up argument type */6947		p = &btf_params(fn_proto_t)[arg_idx];6948		fn_name = btf__str_by_offset(btf, fn_t->name_off) ?: "<anon>";6949		if (!need_func_arg_type_fixup(btf, prog, fn_name, arg_idx, p->type, ctx_name))6950			continue;6951 6952		/* clone fn/fn_proto, unless we already did it for another arg */6953		if (func_rec->type_id == orig_fn_id) {6954			int fn_id;6955 6956			fn_id = clone_func_btf_info(btf, orig_fn_id, prog);6957			if (fn_id < 0) {6958				err = fn_id;6959				goto err_out;6960			}6961 6962			/* point func_info record to a cloned FUNC type */6963			func_rec->type_id = fn_id;6964		}6965 6966		/* create PTR -> STRUCT type chain to mark PTR_TO_CTX argument;6967		 * we do it just once per main BPF program, as all global6968		 * funcs share the same program type, so need only PTR ->6969		 * STRUCT type chain6970		 */6971		if (ptr_id == 0) {6972			struct_id = btf__add_struct(btf, ctx_name, 0);6973			ptr_id = btf__add_ptr(btf, struct_id);6974			if (ptr_id < 0 || struct_id < 0) {6975				err = -EINVAL;6976				goto err_out;6977			}6978		}6979 6980		/* for completeness, clone DECL_TAG and point it to cloned param */6981		tag_id = btf__add_decl_tag(btf, ctx_tag, func_rec->type_id, arg_idx);6982		if (tag_id < 0) {6983			err = -EINVAL;6984			goto err_out;6985		}6986 6987		/* all the BTF manipulations invalidated pointers, refetch them */6988		fn_t = btf_type_by_id(btf, func_rec->type_id);6989		fn_proto_t = btf_type_by_id(btf, fn_t->type);6990 6991		/* fix up type ID pointed to by param */6992		p = &btf_params(fn_proto_t)[arg_idx];6993		p->type = ptr_id;6994	}6995 6996	free(orig_ids);6997	return 0;6998err_out:6999	free(orig_ids);7000	return err;7001}7002 7003static int bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path)7004{7005	struct bpf_program *prog;7006	size_t i, j;7007	int err;7008 7009	if (obj->btf_ext) {7010		err = bpf_object__relocate_core(obj, targ_btf_path);7011		if (err) {7012			pr_warn("failed to perform CO-RE relocations: %d\n",7013				err);7014			return err;7015		}7016		bpf_object__sort_relos(obj);7017	}7018 7019	/* Before relocating calls pre-process relocations and mark7020	 * few ld_imm64 instructions that points to subprogs.7021	 * Otherwise bpf_object__reloc_code() later would have to consider7022	 * all ld_imm64 insns as relocation candidates. That would7023	 * reduce relocation speed, since amount of find_prog_insn_relo()7024	 * would increase and most of them will fail to find a relo.7025	 */7026	for (i = 0; i < obj->nr_programs; i++) {7027		prog = &obj->programs[i];7028		for (j = 0; j < prog->nr_reloc; j++) {7029			struct reloc_desc *relo = &prog->reloc_desc[j];7030			struct bpf_insn *insn = &prog->insns[relo->insn_idx];7031 7032			/* mark the insn, so it's recognized by insn_is_pseudo_func() */7033			if (relo->type == RELO_SUBPROG_ADDR)7034				insn[0].src_reg = BPF_PSEUDO_FUNC;7035		}7036	}7037 7038	/* relocate subprogram calls and append used subprograms to main7039	 * programs; each copy of subprogram code needs to be relocated7040	 * differently for each main program, because its code location might7041	 * have changed.7042	 * Append subprog relos to main programs to allow data relos to be7043	 * processed after text is completely relocated.7044	 */7045	for (i = 0; i < obj->nr_programs; i++) {7046		prog = &obj->programs[i];7047		/* sub-program's sub-calls are relocated within the context of7048		 * its main program only7049		 */7050		if (prog_is_subprog(obj, prog))7051			continue;7052		if (!prog->autoload)7053			continue;7054 7055		err = bpf_object__relocate_calls(obj, prog);7056		if (err) {7057			pr_warn("prog '%s': failed to relocate calls: %d\n",7058				prog->name, err);7059			return err;7060		}7061 7062		err = bpf_prog_assign_exc_cb(obj, prog);7063		if (err)7064			return err;7065		/* Now, also append exception callback if it has not been done already. */7066		if (prog->exception_cb_idx >= 0) {7067			struct bpf_program *subprog = &obj->programs[prog->exception_cb_idx];7068 7069			/* Calling exception callback directly is disallowed, which the7070			 * verifier will reject later. In case it was processed already,7071			 * we can skip this step, otherwise for all other valid cases we7072			 * have to append exception callback now.7073			 */7074			if (subprog->sub_insn_off == 0) {7075				err = bpf_object__append_subprog_code(obj, prog, subprog);7076				if (err)7077					return err;7078				err = bpf_object__reloc_code(obj, prog, subprog);7079				if (err)7080					return err;7081			}7082		}7083	}7084	for (i = 0; i < obj->nr_programs; i++) {7085		prog = &obj->programs[i];7086		if (prog_is_subprog(obj, prog))7087			continue;7088		if (!prog->autoload)7089			continue;7090 7091		/* Process data relos for main programs */7092		err = bpf_object__relocate_data(obj, prog);7093		if (err) {7094			pr_warn("prog '%s': failed to relocate data references: %d\n",7095				prog->name, err);7096			return err;7097		}7098 7099		/* Fix up .BTF.ext information, if necessary */7100		err = bpf_program_fixup_func_info(obj, prog);7101		if (err) {7102			pr_warn("prog '%s': failed to perform .BTF.ext fix ups: %d\n",7103				prog->name, err);7104			return err;7105		}7106	}7107 7108	return 0;7109}7110 7111static int bpf_object__collect_st_ops_relos(struct bpf_object *obj,7112					    Elf64_Shdr *shdr, Elf_Data *data);7113 7114static int bpf_object__collect_map_relos(struct bpf_object *obj,7115					 Elf64_Shdr *shdr, Elf_Data *data)7116{7117	const int bpf_ptr_sz = 8, host_ptr_sz = sizeof(void *);7118	int i, j, nrels, new_sz;7119	const struct btf_var_secinfo *vi = NULL;7120	const struct btf_type *sec, *var, *def;7121	struct bpf_map *map = NULL, *targ_map = NULL;7122	struct bpf_program *targ_prog = NULL;7123	bool is_prog_array, is_map_in_map;7124	const struct btf_member *member;7125	const char *name, *mname, *type;7126	unsigned int moff;7127	Elf64_Sym *sym;7128	Elf64_Rel *rel;7129	void *tmp;7130 7131	if (!obj->efile.btf_maps_sec_btf_id || !obj->btf)7132		return -EINVAL;7133	sec = btf__type_by_id(obj->btf, obj->efile.btf_maps_sec_btf_id);7134	if (!sec)7135		return -EINVAL;7136 7137	nrels = shdr->sh_size / shdr->sh_entsize;7138	for (i = 0; i < nrels; i++) {7139		rel = elf_rel_by_idx(data, i);7140		if (!rel) {7141			pr_warn(".maps relo #%d: failed to get ELF relo\n", i);7142			return -LIBBPF_ERRNO__FORMAT;7143		}7144 7145		sym = elf_sym_by_idx(obj, ELF64_R_SYM(rel->r_info));7146		if (!sym) {7147			pr_warn(".maps relo #%d: symbol %zx not found\n",7148				i, (size_t)ELF64_R_SYM(rel->r_info));7149			return -LIBBPF_ERRNO__FORMAT;7150		}7151		name = elf_sym_str(obj, sym->st_name) ?: "<?>";7152 7153		pr_debug(".maps relo #%d: for %zd value %zd rel->r_offset %zu name %d ('%s')\n",7154			 i, (ssize_t)(rel->r_info >> 32), (size_t)sym->st_value,7155			 (size_t)rel->r_offset, sym->st_name, name);7156 7157		for (j = 0; j < obj->nr_maps; j++) {7158			map = &obj->maps[j];7159			if (map->sec_idx != obj->efile.btf_maps_shndx)7160				continue;7161 7162			vi = btf_var_secinfos(sec) + map->btf_var_idx;7163			if (vi->offset <= rel->r_offset &&7164			    rel->r_offset + bpf_ptr_sz <= vi->offset + vi->size)7165				break;7166		}7167		if (j == obj->nr_maps) {7168			pr_warn(".maps relo #%d: cannot find map '%s' at rel->r_offset %zu\n",7169				i, name, (size_t)rel->r_offset);7170			return -EINVAL;7171		}7172 7173		is_map_in_map = bpf_map_type__is_map_in_map(map->def.type);7174		is_prog_array = map->def.type == BPF_MAP_TYPE_PROG_ARRAY;7175		type = is_map_in_map ? "map" : "prog";7176		if (is_map_in_map) {7177			if (sym->st_shndx != obj->efile.btf_maps_shndx) {7178				pr_warn(".maps relo #%d: '%s' isn't a BTF-defined map\n",7179					i, name);7180				return -LIBBPF_ERRNO__RELOC;7181			}7182			if (map->def.type == BPF_MAP_TYPE_HASH_OF_MAPS &&7183			    map->def.key_size != sizeof(int)) {7184				pr_warn(".maps relo #%d: hash-of-maps '%s' should have key size %zu.\n",7185					i, map->name, sizeof(int));7186				return -EINVAL;7187			}7188			targ_map = bpf_object__find_map_by_name(obj, name);7189			if (!targ_map) {7190				pr_warn(".maps relo #%d: '%s' isn't a valid map reference\n",7191					i, name);7192				return -ESRCH;7193			}7194		} else if (is_prog_array) {7195			targ_prog = bpf_object__find_program_by_name(obj, name);7196			if (!targ_prog) {7197				pr_warn(".maps relo #%d: '%s' isn't a valid program reference\n",7198					i, name);7199				return -ESRCH;7200			}7201			if (targ_prog->sec_idx != sym->st_shndx ||7202			    targ_prog->sec_insn_off * 8 != sym->st_value ||7203			    prog_is_subprog(obj, targ_prog)) {7204				pr_warn(".maps relo #%d: '%s' isn't an entry-point program\n",7205					i, name);7206				return -LIBBPF_ERRNO__RELOC;7207			}7208		} else {7209			return -EINVAL;7210		}7211 7212		var = btf__type_by_id(obj->btf, vi->type);7213		def = skip_mods_and_typedefs(obj->btf, var->type, NULL);7214		if (btf_vlen(def) == 0)7215			return -EINVAL;7216		member = btf_members(def) + btf_vlen(def) - 1;7217		mname = btf__name_by_offset(obj->btf, member->name_off);7218		if (strcmp(mname, "values"))7219			return -EINVAL;7220 7221		moff = btf_member_bit_offset(def, btf_vlen(def) - 1) / 8;7222		if (rel->r_offset - vi->offset < moff)7223			return -EINVAL;7224 7225		moff = rel->r_offset - vi->offset - moff;7226		/* here we use BPF pointer size, which is always 64 bit, as we7227		 * are parsing ELF that was built for BPF target7228		 */7229		if (moff % bpf_ptr_sz)7230			return -EINVAL;7231		moff /= bpf_ptr_sz;7232		if (moff >= map->init_slots_sz) {7233			new_sz = moff + 1;7234			tmp = libbpf_reallocarray(map->init_slots, new_sz, host_ptr_sz);7235			if (!tmp)7236				return -ENOMEM;7237			map->init_slots = tmp;7238			memset(map->init_slots + map->init_slots_sz, 0,7239			       (new_sz - map->init_slots_sz) * host_ptr_sz);7240			map->init_slots_sz = new_sz;7241		}7242		map->init_slots[moff] = is_map_in_map ? (void *)targ_map : (void *)targ_prog;7243 7244		pr_debug(".maps relo #%d: map '%s' slot [%d] points to %s '%s'\n",7245			 i, map->name, moff, type, name);7246	}7247 7248	return 0;7249}7250 7251static int bpf_object__collect_relos(struct bpf_object *obj)7252{7253	int i, err;7254 7255	for (i = 0; i < obj->efile.sec_cnt; i++) {7256		struct elf_sec_desc *sec_desc = &obj->efile.secs[i];7257		Elf64_Shdr *shdr;7258		Elf_Data *data;7259		int idx;7260 7261		if (sec_desc->sec_type != SEC_RELO)7262			continue;7263 7264		shdr = sec_desc->shdr;7265		data = sec_desc->data;7266		idx = shdr->sh_info;7267 7268		if (shdr->sh_type != SHT_REL || idx < 0 || idx >= obj->efile.sec_cnt) {7269			pr_warn("internal error at %d\n", __LINE__);7270			return -LIBBPF_ERRNO__INTERNAL;7271		}7272 7273		if (obj->efile.secs[idx].sec_type == SEC_ST_OPS)7274			err = bpf_object__collect_st_ops_relos(obj, shdr, data);7275		else if (idx == obj->efile.btf_maps_shndx)7276			err = bpf_object__collect_map_relos(obj, shdr, data);7277		else7278			err = bpf_object__collect_prog_relos(obj, shdr, data);7279		if (err)7280			return err;7281	}7282 7283	bpf_object__sort_relos(obj);7284	return 0;7285}7286 7287static bool insn_is_helper_call(struct bpf_insn *insn, enum bpf_func_id *func_id)7288{7289	if (BPF_CLASS(insn->code) == BPF_JMP &&7290	    BPF_OP(insn->code) == BPF_CALL &&7291	    BPF_SRC(insn->code) == BPF_K &&7292	    insn->src_reg == 0 &&7293	    insn->dst_reg == 0) {7294		    *func_id = insn->imm;7295		    return true;7296	}7297	return false;7298}7299 7300static int bpf_object__sanitize_prog(struct bpf_object *obj, struct bpf_program *prog)7301{7302	struct bpf_insn *insn = prog->insns;7303	enum bpf_func_id func_id;7304	int i;7305 7306	if (obj->gen_loader)7307		return 0;7308 7309	for (i = 0; i < prog->insns_cnt; i++, insn++) {7310		if (!insn_is_helper_call(insn, &func_id))7311			continue;7312 7313		/* on kernels that don't yet support7314		 * bpf_probe_read_{kernel,user}[_str] helpers, fall back7315		 * to bpf_probe_read() which works well for old kernels7316		 */7317		switch (func_id) {7318		case BPF_FUNC_probe_read_kernel:7319		case BPF_FUNC_probe_read_user:7320			if (!kernel_supports(obj, FEAT_PROBE_READ_KERN))7321				insn->imm = BPF_FUNC_probe_read;7322			break;7323		case BPF_FUNC_probe_read_kernel_str:7324		case BPF_FUNC_probe_read_user_str:7325			if (!kernel_supports(obj, FEAT_PROBE_READ_KERN))7326				insn->imm = BPF_FUNC_probe_read_str;7327			break;7328		default:7329			break;7330		}7331	}7332	return 0;7333}7334 7335static int libbpf_find_attach_btf_id(struct bpf_program *prog, const char *attach_name,7336				     int *btf_obj_fd, int *btf_type_id);7337 7338/* this is called as prog->sec_def->prog_prepare_load_fn for libbpf-supported sec_defs */7339static int libbpf_prepare_prog_load(struct bpf_program *prog,7340				    struct bpf_prog_load_opts *opts, long cookie)7341{7342	enum sec_def_flags def = cookie;7343 7344	/* old kernels might not support specifying expected_attach_type */7345	if ((def & SEC_EXP_ATTACH_OPT) && !kernel_supports(prog->obj, FEAT_EXP_ATTACH_TYPE))7346		opts->expected_attach_type = 0;7347 7348	if (def & SEC_SLEEPABLE)7349		opts->prog_flags |= BPF_F_SLEEPABLE;7350 7351	if (prog->type == BPF_PROG_TYPE_XDP && (def & SEC_XDP_FRAGS))7352		opts->prog_flags |= BPF_F_XDP_HAS_FRAGS;7353 7354	/* special check for usdt to use uprobe_multi link */7355	if ((def & SEC_USDT) && kernel_supports(prog->obj, FEAT_UPROBE_MULTI_LINK))7356		prog->expected_attach_type = BPF_TRACE_UPROBE_MULTI;7357 7358	if ((def & SEC_ATTACH_BTF) && !prog->attach_btf_id) {7359		int btf_obj_fd = 0, btf_type_id = 0, err;7360		const char *attach_name;7361 7362		attach_name = strchr(prog->sec_name, '/');7363		if (!attach_name) {7364			/* if BPF program is annotated with just SEC("fentry")7365			 * (or similar) without declaratively specifying7366			 * target, then it is expected that target will be7367			 * specified with bpf_program__set_attach_target() at7368			 * runtime before BPF object load step. If not, then7369			 * there is nothing to load into the kernel as BPF7370			 * verifier won't be able to validate BPF program7371			 * correctness anyways.7372			 */7373			pr_warn("prog '%s': no BTF-based attach target is specified, use bpf_program__set_attach_target()\n",7374				prog->name);7375			return -EINVAL;7376		}7377		attach_name++; /* skip over / */7378 7379		err = libbpf_find_attach_btf_id(prog, attach_name, &btf_obj_fd, &btf_type_id);7380		if (err)7381			return err;7382 7383		/* cache resolved BTF FD and BTF type ID in the prog */7384		prog->attach_btf_obj_fd = btf_obj_fd;7385		prog->attach_btf_id = btf_type_id;7386 7387		/* but by now libbpf common logic is not utilizing7388		 * prog->atach_btf_obj_fd/prog->attach_btf_id anymore because7389		 * this callback is called after opts were populated by7390		 * libbpf, so this callback has to update opts explicitly here7391		 */7392		opts->attach_btf_obj_fd = btf_obj_fd;7393		opts->attach_btf_id = btf_type_id;7394	}7395	return 0;7396}7397 7398static void fixup_verifier_log(struct bpf_program *prog, char *buf, size_t buf_sz);7399 7400static int bpf_object_load_prog(struct bpf_object *obj, struct bpf_program *prog,7401				struct bpf_insn *insns, int insns_cnt,7402				const char *license, __u32 kern_version, int *prog_fd)7403{7404	LIBBPF_OPTS(bpf_prog_load_opts, load_attr);7405	const char *prog_name = NULL;7406	char *cp, errmsg[STRERR_BUFSIZE];7407	size_t log_buf_size = 0;7408	char *log_buf = NULL, *tmp;7409	bool own_log_buf = true;7410	__u32 log_level = prog->log_level;7411	int ret, err;7412 7413	/* Be more helpful by rejecting programs that can't be validated early7414	 * with more meaningful and actionable error message.7415	 */7416	switch (prog->type) {7417	case BPF_PROG_TYPE_UNSPEC:7418		/*7419		 * The program type must be set.  Most likely we couldn't find a proper7420		 * section definition at load time, and thus we didn't infer the type.7421		 */7422		pr_warn("prog '%s': missing BPF prog type, check ELF section name '%s'\n",7423			prog->name, prog->sec_name);7424		return -EINVAL;7425	case BPF_PROG_TYPE_STRUCT_OPS:7426		if (prog->attach_btf_id == 0) {7427			pr_warn("prog '%s': SEC(\"struct_ops\") program isn't referenced anywhere, did you forget to use it?\n",7428				prog->name);7429			return -EINVAL;7430		}7431		break;7432	default:7433		break;7434	}7435 7436	if (!insns || !insns_cnt)7437		return -EINVAL;7438 7439	if (kernel_supports(obj, FEAT_PROG_NAME))7440		prog_name = prog->name;7441	load_attr.attach_prog_fd = prog->attach_prog_fd;7442	load_attr.attach_btf_obj_fd = prog->attach_btf_obj_fd;7443	load_attr.attach_btf_id = prog->attach_btf_id;7444	load_attr.kern_version = kern_version;7445	load_attr.prog_ifindex = prog->prog_ifindex;7446 7447	/* specify func_info/line_info only if kernel supports them */7448	if (obj->btf && btf__fd(obj->btf) >= 0 && kernel_supports(obj, FEAT_BTF_FUNC)) {7449		load_attr.prog_btf_fd = btf__fd(obj->btf);7450		load_attr.func_info = prog->func_info;7451		load_attr.func_info_rec_size = prog->func_info_rec_size;7452		load_attr.func_info_cnt = prog->func_info_cnt;7453		load_attr.line_info = prog->line_info;7454		load_attr.line_info_rec_size = prog->line_info_rec_size;7455		load_attr.line_info_cnt = prog->line_info_cnt;7456	}7457	load_attr.log_level = log_level;7458	load_attr.prog_flags = prog->prog_flags;7459	load_attr.fd_array = obj->fd_array;7460 7461	load_attr.token_fd = obj->token_fd;7462	if (obj->token_fd)7463		load_attr.prog_flags |= BPF_F_TOKEN_FD;7464 7465	/* adjust load_attr if sec_def provides custom preload callback */7466	if (prog->sec_def && prog->sec_def->prog_prepare_load_fn) {7467		err = prog->sec_def->prog_prepare_load_fn(prog, &load_attr, prog->sec_def->cookie);7468		if (err < 0) {7469			pr_warn("prog '%s': failed to prepare load attributes: %d\n",7470				prog->name, err);7471			return err;7472		}7473		insns = prog->insns;7474		insns_cnt = prog->insns_cnt;7475	}7476 7477	/* allow prog_prepare_load_fn to change expected_attach_type */7478	load_attr.expected_attach_type = prog->expected_attach_type;7479 7480	if (obj->gen_loader) {7481		bpf_gen__prog_load(obj->gen_loader, prog->type, prog->name,7482				   license, insns, insns_cnt, &load_attr,7483				   prog - obj->programs);7484		*prog_fd = -1;7485		return 0;7486	}7487 7488retry_load:7489	/* if log_level is zero, we don't request logs initially even if7490	 * custom log_buf is specified; if the program load fails, then we'll7491	 * bump log_level to 1 and use either custom log_buf or we'll allocate7492	 * our own and retry the load to get details on what failed7493	 */7494	if (log_level) {7495		if (prog->log_buf) {7496			log_buf = prog->log_buf;7497			log_buf_size = prog->log_size;7498			own_log_buf = false;7499		} else if (obj->log_buf) {7500			log_buf = obj->log_buf;7501			log_buf_size = obj->log_size;7502			own_log_buf = false;7503		} else {7504			log_buf_size = max((size_t)BPF_LOG_BUF_SIZE, log_buf_size * 2);7505			tmp = realloc(log_buf, log_buf_size);7506			if (!tmp) {7507				ret = -ENOMEM;7508				goto out;7509			}7510			log_buf = tmp;7511			log_buf[0] = '\0';7512			own_log_buf = true;7513		}7514	}7515 7516	load_attr.log_buf = log_buf;7517	load_attr.log_size = log_buf_size;7518	load_attr.log_level = log_level;7519 7520	ret = bpf_prog_load(prog->type, prog_name, license, insns, insns_cnt, &load_attr);7521	if (ret >= 0) {7522		if (log_level && own_log_buf) {7523			pr_debug("prog '%s': -- BEGIN PROG LOAD LOG --\n%s-- END PROG LOAD LOG --\n",7524				 prog->name, log_buf);7525		}7526 7527		if (obj->has_rodata && kernel_supports(obj, FEAT_PROG_BIND_MAP)) {7528			struct bpf_map *map;7529			int i;7530 7531			for (i = 0; i < obj->nr_maps; i++) {7532				map = &prog->obj->maps[i];7533				if (map->libbpf_type != LIBBPF_MAP_RODATA)7534					continue;7535 7536				if (bpf_prog_bind_map(ret, map->fd, NULL)) {7537					cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));7538					pr_warn("prog '%s': failed to bind map '%s': %s\n",7539						prog->name, map->real_name, cp);7540					/* Don't fail hard if can't bind rodata. */7541				}7542			}7543		}7544 7545		*prog_fd = ret;7546		ret = 0;7547		goto out;7548	}7549 7550	if (log_level == 0) {7551		log_level = 1;7552		goto retry_load;7553	}7554	/* On ENOSPC, increase log buffer size and retry, unless custom7555	 * log_buf is specified.7556	 * Be careful to not overflow u32, though. Kernel's log buf size limit7557	 * isn't part of UAPI so it can always be bumped to full 4GB. So don't7558	 * multiply by 2 unless we are sure we'll fit within 32 bits.7559	 * Currently, we'll get -EINVAL when we reach (UINT_MAX >> 2).7560	 */7561	if (own_log_buf && errno == ENOSPC && log_buf_size <= UINT_MAX / 2)7562		goto retry_load;7563 7564	ret = -errno;7565 7566	/* post-process verifier log to improve error descriptions */7567	fixup_verifier_log(prog, log_buf, log_buf_size);7568 7569	cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));7570	pr_warn("prog '%s': BPF program load failed: %s\n", prog->name, cp);7571	pr_perm_msg(ret);7572 7573	if (own_log_buf && log_buf && log_buf[0] != '\0') {7574		pr_warn("prog '%s': -- BEGIN PROG LOAD LOG --\n%s-- END PROG LOAD LOG --\n",7575			prog->name, log_buf);7576	}7577 7578out:7579	if (own_log_buf)7580		free(log_buf);7581	return ret;7582}7583 7584static char *find_prev_line(char *buf, char *cur)7585{7586	char *p;7587 7588	if (cur == buf) /* end of a log buf */7589		return NULL;7590 7591	p = cur - 1;7592	while (p - 1 >= buf && *(p - 1) != '\n')7593		p--;7594 7595	return p;7596}7597 7598static void patch_log(char *buf, size_t buf_sz, size_t log_sz,7599		      char *orig, size_t orig_sz, const char *patch)7600{7601	/* size of the remaining log content to the right from the to-be-replaced part */7602	size_t rem_sz = (buf + log_sz) - (orig + orig_sz);7603	size_t patch_sz = strlen(patch);7604 7605	if (patch_sz != orig_sz) {7606		/* If patch line(s) are longer than original piece of verifier log,7607		 * shift log contents by (patch_sz - orig_sz) bytes to the right7608		 * starting from after to-be-replaced part of the log.7609		 *7610		 * If patch line(s) are shorter than original piece of verifier log,7611		 * shift log contents by (orig_sz - patch_sz) bytes to the left7612		 * starting from after to-be-replaced part of the log7613		 *7614		 * We need to be careful about not overflowing available7615		 * buf_sz capacity. If that's the case, we'll truncate the end7616		 * of the original log, as necessary.7617		 */7618		if (patch_sz > orig_sz) {7619			if (orig + patch_sz >= buf + buf_sz) {7620				/* patch is big enough to cover remaining space completely */7621				patch_sz -= (orig + patch_sz) - (buf + buf_sz) + 1;7622				rem_sz = 0;7623			} else if (patch_sz - orig_sz > buf_sz - log_sz) {7624				/* patch causes part of remaining log to be truncated */7625				rem_sz -= (patch_sz - orig_sz) - (buf_sz - log_sz);7626			}7627		}7628		/* shift remaining log to the right by calculated amount */7629		memmove(orig + patch_sz, orig + orig_sz, rem_sz);7630	}7631 7632	memcpy(orig, patch, patch_sz);7633}7634 7635static void fixup_log_failed_core_relo(struct bpf_program *prog,7636				       char *buf, size_t buf_sz, size_t log_sz,7637				       char *line1, char *line2, char *line3)7638{7639	/* Expected log for failed and not properly guarded CO-RE relocation:7640	 * line1 -> 123: (85) call unknown#1958960807641	 * line2 -> invalid func unknown#1958960807642	 * line3 -> <anything else or end of buffer>7643	 *7644	 * "123" is the index of the instruction that was poisoned. We extract7645	 * instruction index to find corresponding CO-RE relocation and7646	 * replace this part of the log with more relevant information about7647	 * failed CO-RE relocation.7648	 */7649	const struct bpf_core_relo *relo;7650	struct bpf_core_spec spec;7651	char patch[512], spec_buf[256];7652	int insn_idx, err, spec_len;7653 7654	if (sscanf(line1, "%d: (%*d) call unknown#195896080\n", &insn_idx) != 1)7655		return;7656 7657	relo = find_relo_core(prog, insn_idx);7658	if (!relo)7659		return;7660 7661	err = bpf_core_parse_spec(prog->name, prog->obj->btf, relo, &spec);7662	if (err)7663		return;7664 7665	spec_len = bpf_core_format_spec(spec_buf, sizeof(spec_buf), &spec);7666	snprintf(patch, sizeof(patch),7667		 "%d: <invalid CO-RE relocation>\n"7668		 "failed to resolve CO-RE relocation %s%s\n",7669		 insn_idx, spec_buf, spec_len >= sizeof(spec_buf) ? "..." : "");7670 7671	patch_log(buf, buf_sz, log_sz, line1, line3 - line1, patch);7672}7673 7674static void fixup_log_missing_map_load(struct bpf_program *prog,7675				       char *buf, size_t buf_sz, size_t log_sz,7676				       char *line1, char *line2, char *line3)7677{7678	/* Expected log for failed and not properly guarded map reference:7679	 * line1 -> 123: (85) call unknown#20010003457680	 * line2 -> invalid func unknown#20010003457681	 * line3 -> <anything else or end of buffer>7682	 *7683	 * "123" is the index of the instruction that was poisoned.7684	 * "345" in "2001000345" is a map index in obj->maps to fetch map name.7685	 */7686	struct bpf_object *obj = prog->obj;7687	const struct bpf_map *map;7688	int insn_idx, map_idx;7689	char patch[128];7690 7691	if (sscanf(line1, "%d: (%*d) call unknown#%d\n", &insn_idx, &map_idx) != 2)7692		return;7693 7694	map_idx -= POISON_LDIMM64_MAP_BASE;7695	if (map_idx < 0 || map_idx >= obj->nr_maps)7696		return;7697	map = &obj->maps[map_idx];7698 7699	snprintf(patch, sizeof(patch),7700		 "%d: <invalid BPF map reference>\n"7701		 "BPF map '%s' is referenced but wasn't created\n",7702		 insn_idx, map->name);7703 7704	patch_log(buf, buf_sz, log_sz, line1, line3 - line1, patch);7705}7706 7707static void fixup_log_missing_kfunc_call(struct bpf_program *prog,7708					 char *buf, size_t buf_sz, size_t log_sz,7709					 char *line1, char *line2, char *line3)7710{7711	/* Expected log for failed and not properly guarded kfunc call:7712	 * line1 -> 123: (85) call unknown#20020003457713	 * line2 -> invalid func unknown#20020003457714	 * line3 -> <anything else or end of buffer>7715	 *7716	 * "123" is the index of the instruction that was poisoned.7717	 * "345" in "2002000345" is an extern index in obj->externs to fetch kfunc name.7718	 */7719	struct bpf_object *obj = prog->obj;7720	const struct extern_desc *ext;7721	int insn_idx, ext_idx;7722	char patch[128];7723 7724	if (sscanf(line1, "%d: (%*d) call unknown#%d\n", &insn_idx, &ext_idx) != 2)7725		return;7726 7727	ext_idx -= POISON_CALL_KFUNC_BASE;7728	if (ext_idx < 0 || ext_idx >= obj->nr_extern)7729		return;7730	ext = &obj->externs[ext_idx];7731 7732	snprintf(patch, sizeof(patch),7733		 "%d: <invalid kfunc call>\n"7734		 "kfunc '%s' is referenced but wasn't resolved\n",7735		 insn_idx, ext->name);7736 7737	patch_log(buf, buf_sz, log_sz, line1, line3 - line1, patch);7738}7739 7740static void fixup_verifier_log(struct bpf_program *prog, char *buf, size_t buf_sz)7741{7742	/* look for familiar error patterns in last N lines of the log */7743	const size_t max_last_line_cnt = 10;7744	char *prev_line, *cur_line, *next_line;7745	size_t log_sz;7746	int i;7747 7748	if (!buf)7749		return;7750 7751	log_sz = strlen(buf) + 1;7752	next_line = buf + log_sz - 1;7753 7754	for (i = 0; i < max_last_line_cnt; i++, next_line = cur_line) {7755		cur_line = find_prev_line(buf, next_line);7756		if (!cur_line)7757			return;7758 7759		if (str_has_pfx(cur_line, "invalid func unknown#195896080\n")) {7760			prev_line = find_prev_line(buf, cur_line);7761			if (!prev_line)7762				continue;7763 7764			/* failed CO-RE relocation case */7765			fixup_log_failed_core_relo(prog, buf, buf_sz, log_sz,7766						   prev_line, cur_line, next_line);7767			return;7768		} else if (str_has_pfx(cur_line, "invalid func unknown#"POISON_LDIMM64_MAP_PFX)) {7769			prev_line = find_prev_line(buf, cur_line);7770			if (!prev_line)7771				continue;7772 7773			/* reference to uncreated BPF map */7774			fixup_log_missing_map_load(prog, buf, buf_sz, log_sz,7775						   prev_line, cur_line, next_line);7776			return;7777		} else if (str_has_pfx(cur_line, "invalid func unknown#"POISON_CALL_KFUNC_PFX)) {7778			prev_line = find_prev_line(buf, cur_line);7779			if (!prev_line)7780				continue;7781 7782			/* reference to unresolved kfunc */7783			fixup_log_missing_kfunc_call(prog, buf, buf_sz, log_sz,7784						     prev_line, cur_line, next_line);7785			return;7786		}7787	}7788}7789 7790static int bpf_program_record_relos(struct bpf_program *prog)7791{7792	struct bpf_object *obj = prog->obj;7793	int i;7794 7795	for (i = 0; i < prog->nr_reloc; i++) {7796		struct reloc_desc *relo = &prog->reloc_desc[i];7797		struct extern_desc *ext = &obj->externs[relo->ext_idx];7798		int kind;7799 7800		switch (relo->type) {7801		case RELO_EXTERN_LD64:7802			if (ext->type != EXT_KSYM)7803				continue;7804			kind = btf_is_var(btf__type_by_id(obj->btf, ext->btf_id)) ?7805				BTF_KIND_VAR : BTF_KIND_FUNC;7806			bpf_gen__record_extern(obj->gen_loader, ext->name,7807					       ext->is_weak, !ext->ksym.type_id,7808					       true, kind, relo->insn_idx);7809			break;7810		case RELO_EXTERN_CALL:7811			bpf_gen__record_extern(obj->gen_loader, ext->name,7812					       ext->is_weak, false, false, BTF_KIND_FUNC,7813					       relo->insn_idx);7814			break;7815		case RELO_CORE: {7816			struct bpf_core_relo cr = {7817				.insn_off = relo->insn_idx * 8,7818				.type_id = relo->core_relo->type_id,7819				.access_str_off = relo->core_relo->access_str_off,7820				.kind = relo->core_relo->kind,7821			};7822 7823			bpf_gen__record_relo_core(obj->gen_loader, &cr);7824			break;7825		}7826		default:7827			continue;7828		}7829	}7830	return 0;7831}7832 7833static int7834bpf_object__load_progs(struct bpf_object *obj, int log_level)7835{7836	struct bpf_program *prog;7837	size_t i;7838	int err;7839 7840	for (i = 0; i < obj->nr_programs; i++) {7841		prog = &obj->programs[i];7842		err = bpf_object__sanitize_prog(obj, prog);7843		if (err)7844			return err;7845	}7846 7847	for (i = 0; i < obj->nr_programs; i++) {7848		prog = &obj->programs[i];7849		if (prog_is_subprog(obj, prog))7850			continue;7851		if (!prog->autoload) {7852			pr_debug("prog '%s': skipped loading\n", prog->name);7853			continue;7854		}7855		prog->log_level |= log_level;7856 7857		if (obj->gen_loader)7858			bpf_program_record_relos(prog);7859 7860		err = bpf_object_load_prog(obj, prog, prog->insns, prog->insns_cnt,7861					   obj->license, obj->kern_version, &prog->fd);7862		if (err) {7863			pr_warn("prog '%s': failed to load: %d\n", prog->name, err);7864			return err;7865		}7866	}7867 7868	bpf_object__free_relocs(obj);7869	return 0;7870}7871 7872static const struct bpf_sec_def *find_sec_def(const char *sec_name);7873 7874static int bpf_object_init_progs(struct bpf_object *obj, const struct bpf_object_open_opts *opts)7875{7876	struct bpf_program *prog;7877	int err;7878 7879	bpf_object__for_each_program(prog, obj) {7880		prog->sec_def = find_sec_def(prog->sec_name);7881		if (!prog->sec_def) {7882			/* couldn't guess, but user might manually specify */7883			pr_debug("prog '%s': unrecognized ELF section name '%s'\n",7884				prog->name, prog->sec_name);7885			continue;7886		}7887 7888		prog->type = prog->sec_def->prog_type;7889		prog->expected_attach_type = prog->sec_def->expected_attach_type;7890 7891		/* sec_def can have custom callback which should be called7892		 * after bpf_program is initialized to adjust its properties7893		 */7894		if (prog->sec_def->prog_setup_fn) {7895			err = prog->sec_def->prog_setup_fn(prog, prog->sec_def->cookie);7896			if (err < 0) {7897				pr_warn("prog '%s': failed to initialize: %d\n",7898					prog->name, err);7899				return err;7900			}7901		}7902	}7903 7904	return 0;7905}7906 7907static struct bpf_object *bpf_object_open(const char *path, const void *obj_buf, size_t obj_buf_sz,7908					  const char *obj_name,7909					  const struct bpf_object_open_opts *opts)7910{7911	const char *kconfig, *btf_tmp_path, *token_path;7912	struct bpf_object *obj;7913	int err;7914	char *log_buf;7915	size_t log_size;7916	__u32 log_level;7917 7918	if (obj_buf && !obj_name)7919		return ERR_PTR(-EINVAL);7920 7921	if (elf_version(EV_CURRENT) == EV_NONE) {7922		pr_warn("failed to init libelf for %s\n",7923			path ? : "(mem buf)");7924		return ERR_PTR(-LIBBPF_ERRNO__LIBELF);7925	}7926 7927	if (!OPTS_VALID(opts, bpf_object_open_opts))7928		return ERR_PTR(-EINVAL);7929 7930	obj_name = OPTS_GET(opts, object_name, NULL) ?: obj_name;7931	if (obj_buf) {7932		path = obj_name;7933		pr_debug("loading object '%s' from buffer\n", obj_name);7934	} else {7935		pr_debug("loading object from %s\n", path);7936	}7937 7938	log_buf = OPTS_GET(opts, kernel_log_buf, NULL);7939	log_size = OPTS_GET(opts, kernel_log_size, 0);7940	log_level = OPTS_GET(opts, kernel_log_level, 0);7941	if (log_size > UINT_MAX)7942		return ERR_PTR(-EINVAL);7943	if (log_size && !log_buf)7944		return ERR_PTR(-EINVAL);7945 7946	token_path = OPTS_GET(opts, bpf_token_path, NULL);7947	/* if user didn't specify bpf_token_path explicitly, check if7948	 * LIBBPF_BPF_TOKEN_PATH envvar was set and treat it as bpf_token_path7949	 * option7950	 */7951	if (!token_path)7952		token_path = getenv("LIBBPF_BPF_TOKEN_PATH");7953	if (token_path && strlen(token_path) >= PATH_MAX)7954		return ERR_PTR(-ENAMETOOLONG);7955 7956	obj = bpf_object__new(path, obj_buf, obj_buf_sz, obj_name);7957	if (IS_ERR(obj))7958		return obj;7959 7960	obj->log_buf = log_buf;7961	obj->log_size = log_size;7962	obj->log_level = log_level;7963 7964	if (token_path) {7965		obj->token_path = strdup(token_path);7966		if (!obj->token_path) {7967			err = -ENOMEM;7968			goto out;7969		}7970	}7971 7972	btf_tmp_path = OPTS_GET(opts, btf_custom_path, NULL);7973	if (btf_tmp_path) {7974		if (strlen(btf_tmp_path) >= PATH_MAX) {7975			err = -ENAMETOOLONG;7976			goto out;7977		}7978		obj->btf_custom_path = strdup(btf_tmp_path);7979		if (!obj->btf_custom_path) {7980			err = -ENOMEM;7981			goto out;7982		}7983	}7984 7985	kconfig = OPTS_GET(opts, kconfig, NULL);7986	if (kconfig) {7987		obj->kconfig = strdup(kconfig);7988		if (!obj->kconfig) {7989			err = -ENOMEM;7990			goto out;7991		}7992	}7993 7994	err = bpf_object__elf_init(obj);7995	err = err ? : bpf_object__check_endianness(obj);7996	err = err ? : bpf_object__elf_collect(obj);7997	err = err ? : bpf_object__collect_externs(obj);7998	err = err ? : bpf_object_fixup_btf(obj);7999	err = err ? : bpf_object__init_maps(obj, opts);8000	err = err ? : bpf_object_init_progs(obj, opts);8001	err = err ? : bpf_object__collect_relos(obj);8002	if (err)8003		goto out;8004 8005	bpf_object__elf_finish(obj);8006 8007	return obj;8008out:8009	bpf_object__close(obj);8010	return ERR_PTR(err);8011}8012 8013struct bpf_object *8014bpf_object__open_file(const char *path, const struct bpf_object_open_opts *opts)8015{8016	if (!path)8017		return libbpf_err_ptr(-EINVAL);8018 8019	return libbpf_ptr(bpf_object_open(path, NULL, 0, NULL, opts));8020}8021 8022struct bpf_object *bpf_object__open(const char *path)8023{8024	return bpf_object__open_file(path, NULL);8025}8026 8027struct bpf_object *8028bpf_object__open_mem(const void *obj_buf, size_t obj_buf_sz,8029		     const struct bpf_object_open_opts *opts)8030{8031	char tmp_name[64];8032 8033	if (!obj_buf || obj_buf_sz == 0)8034		return libbpf_err_ptr(-EINVAL);8035 8036	/* create a (quite useless) default "name" for this memory buffer object */8037	snprintf(tmp_name, sizeof(tmp_name), "%lx-%zx", (unsigned long)obj_buf, obj_buf_sz);8038 8039	return libbpf_ptr(bpf_object_open(NULL, obj_buf, obj_buf_sz, tmp_name, opts));8040}8041 8042static int bpf_object_unload(struct bpf_object *obj)8043{8044	size_t i;8045 8046	if (!obj)8047		return libbpf_err(-EINVAL);8048 8049	for (i = 0; i < obj->nr_maps; i++) {8050		zclose(obj->maps[i].fd);8051		if (obj->maps[i].st_ops)8052			zfree(&obj->maps[i].st_ops->kern_vdata);8053	}8054 8055	for (i = 0; i < obj->nr_programs; i++)8056		bpf_program__unload(&obj->programs[i]);8057 8058	return 0;8059}8060 8061static int bpf_object__sanitize_maps(struct bpf_object *obj)8062{8063	struct bpf_map *m;8064 8065	bpf_object__for_each_map(m, obj) {8066		if (!bpf_map__is_internal(m))8067			continue;8068		if (!kernel_supports(obj, FEAT_ARRAY_MMAP))8069			m->def.map_flags &= ~BPF_F_MMAPABLE;8070	}8071 8072	return 0;8073}8074 8075typedef int (*kallsyms_cb_t)(unsigned long long sym_addr, char sym_type,8076			     const char *sym_name, void *ctx);8077 8078static int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *ctx)8079{8080	char sym_type, sym_name[500];8081	unsigned long long sym_addr;8082	int ret, err = 0;8083	FILE *f;8084 8085	f = fopen("/proc/kallsyms", "re");8086	if (!f) {8087		err = -errno;8088		pr_warn("failed to open /proc/kallsyms: %d\n", err);8089		return err;8090	}8091 8092	while (true) {8093		ret = fscanf(f, "%llx %c %499s%*[^\n]\n",8094			     &sym_addr, &sym_type, sym_name);8095		if (ret == EOF && feof(f))8096			break;8097		if (ret != 3) {8098			pr_warn("failed to read kallsyms entry: %d\n", ret);8099			err = -EINVAL;8100			break;8101		}8102 8103		err = cb(sym_addr, sym_type, sym_name, ctx);8104		if (err)8105			break;8106	}8107 8108	fclose(f);8109	return err;8110}8111 8112static int kallsyms_cb(unsigned long long sym_addr, char sym_type,8113		       const char *sym_name, void *ctx)8114{8115	struct bpf_object *obj = ctx;8116	const struct btf_type *t;8117	struct extern_desc *ext;8118	char *res;8119 8120	res = strstr(sym_name, ".llvm.");8121	if (sym_type == 'd' && res)8122		ext = find_extern_by_name_with_len(obj, sym_name, res - sym_name);8123	else8124		ext = find_extern_by_name(obj, sym_name);8125	if (!ext || ext->type != EXT_KSYM)8126		return 0;8127 8128	t = btf__type_by_id(obj->btf, ext->btf_id);8129	if (!btf_is_var(t))8130		return 0;8131 8132	if (ext->is_set && ext->ksym.addr != sym_addr) {8133		pr_warn("extern (ksym) '%s': resolution is ambiguous: 0x%llx or 0x%llx\n",8134			sym_name, ext->ksym.addr, sym_addr);8135		return -EINVAL;8136	}8137	if (!ext->is_set) {8138		ext->is_set = true;8139		ext->ksym.addr = sym_addr;8140		pr_debug("extern (ksym) '%s': set to 0x%llx\n", sym_name, sym_addr);8141	}8142	return 0;8143}8144 8145static int bpf_object__read_kallsyms_file(struct bpf_object *obj)8146{8147	return libbpf_kallsyms_parse(kallsyms_cb, obj);8148}8149 8150static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,8151			    __u16 kind, struct btf **res_btf,8152			    struct module_btf **res_mod_btf)8153{8154	struct module_btf *mod_btf;8155	struct btf *btf;8156	int i, id, err;8157 8158	btf = obj->btf_vmlinux;8159	mod_btf = NULL;8160	id = btf__find_by_name_kind(btf, ksym_name, kind);8161 8162	if (id == -ENOENT) {8163		err = load_module_btfs(obj);8164		if (err)8165			return err;8166 8167		for (i = 0; i < obj->btf_module_cnt; i++) {8168			/* we assume module_btf's BTF FD is always >0 */8169			mod_btf = &obj->btf_modules[i];8170			btf = mod_btf->btf;8171			id = btf__find_by_name_kind_own(btf, ksym_name, kind);8172			if (id != -ENOENT)8173				break;8174		}8175	}8176	if (id <= 0)8177		return -ESRCH;8178 8179	*res_btf = btf;8180	*res_mod_btf = mod_btf;8181	return id;8182}8183 8184static int bpf_object__resolve_ksym_var_btf_id(struct bpf_object *obj,8185					       struct extern_desc *ext)8186{8187	const struct btf_type *targ_var, *targ_type;8188	__u32 targ_type_id, local_type_id;8189	struct module_btf *mod_btf = NULL;8190	const char *targ_var_name;8191	struct btf *btf = NULL;8192	int id, err;8193 8194	id = find_ksym_btf_id(obj, ext->name, BTF_KIND_VAR, &btf, &mod_btf);8195	if (id < 0) {8196		if (id == -ESRCH && ext->is_weak)8197			return 0;8198		pr_warn("extern (var ksym) '%s': not found in kernel BTF\n",8199			ext->name);8200		return id;8201	}8202 8203	/* find local type_id */8204	local_type_id = ext->ksym.type_id;8205 8206	/* find target type_id */8207	targ_var = btf__type_by_id(btf, id);8208	targ_var_name = btf__name_by_offset(btf, targ_var->name_off);8209	targ_type = skip_mods_and_typedefs(btf, targ_var->type, &targ_type_id);8210 8211	err = bpf_core_types_are_compat(obj->btf, local_type_id,8212					btf, targ_type_id);8213	if (err <= 0) {8214		const struct btf_type *local_type;8215		const char *targ_name, *local_name;8216 8217		local_type = btf__type_by_id(obj->btf, local_type_id);8218		local_name = btf__name_by_offset(obj->btf, local_type->name_off);8219		targ_name = btf__name_by_offset(btf, targ_type->name_off);8220 8221		pr_warn("extern (var ksym) '%s': incompatible types, expected [%d] %s %s, but kernel has [%d] %s %s\n",8222			ext->name, local_type_id,8223			btf_kind_str(local_type), local_name, targ_type_id,8224			btf_kind_str(targ_type), targ_name);8225		return -EINVAL;8226	}8227 8228	ext->is_set = true;8229	ext->ksym.kernel_btf_obj_fd = mod_btf ? mod_btf->fd : 0;8230	ext->ksym.kernel_btf_id = id;8231	pr_debug("extern (var ksym) '%s': resolved to [%d] %s %s\n",8232		 ext->name, id, btf_kind_str(targ_var), targ_var_name);8233 8234	return 0;8235}8236 8237static int bpf_object__resolve_ksym_func_btf_id(struct bpf_object *obj,8238						struct extern_desc *ext)8239{8240	int local_func_proto_id, kfunc_proto_id, kfunc_id;8241	struct module_btf *mod_btf = NULL;8242	const struct btf_type *kern_func;8243	struct btf *kern_btf = NULL;8244	int ret;8245 8246	local_func_proto_id = ext->ksym.type_id;8247 8248	kfunc_id = find_ksym_btf_id(obj, ext->essent_name ?: ext->name, BTF_KIND_FUNC, &kern_btf,8249				    &mod_btf);8250	if (kfunc_id < 0) {8251		if (kfunc_id == -ESRCH && ext->is_weak)8252			return 0;8253		pr_warn("extern (func ksym) '%s': not found in kernel or module BTFs\n",8254			ext->name);8255		return kfunc_id;8256	}8257 8258	kern_func = btf__type_by_id(kern_btf, kfunc_id);8259	kfunc_proto_id = kern_func->type;8260 8261	ret = bpf_core_types_are_compat(obj->btf, local_func_proto_id,8262					kern_btf, kfunc_proto_id);8263	if (ret <= 0) {8264		if (ext->is_weak)8265			return 0;8266 8267		pr_warn("extern (func ksym) '%s': func_proto [%d] incompatible with %s [%d]\n",8268			ext->name, local_func_proto_id,8269			mod_btf ? mod_btf->name : "vmlinux", kfunc_proto_id);8270		return -EINVAL;8271	}8272 8273	/* set index for module BTF fd in fd_array, if unset */8274	if (mod_btf && !mod_btf->fd_array_idx) {8275		/* insn->off is s16 */8276		if (obj->fd_array_cnt == INT16_MAX) {8277			pr_warn("extern (func ksym) '%s': module BTF fd index %d too big to fit in bpf_insn offset\n",8278				ext->name, mod_btf->fd_array_idx);8279			return -E2BIG;8280		}8281		/* Cannot use index 0 for module BTF fd */8282		if (!obj->fd_array_cnt)8283			obj->fd_array_cnt = 1;8284 8285		ret = libbpf_ensure_mem((void **)&obj->fd_array, &obj->fd_array_cap, sizeof(int),8286					obj->fd_array_cnt + 1);8287		if (ret)8288			return ret;8289		mod_btf->fd_array_idx = obj->fd_array_cnt;8290		/* we assume module BTF FD is always >0 */8291		obj->fd_array[obj->fd_array_cnt++] = mod_btf->fd;8292	}8293 8294	ext->is_set = true;8295	ext->ksym.kernel_btf_id = kfunc_id;8296	ext->ksym.btf_fd_idx = mod_btf ? mod_btf->fd_array_idx : 0;8297	/* Also set kernel_btf_obj_fd to make sure that bpf_object__relocate_data()8298	 * populates FD into ld_imm64 insn when it's used to point to kfunc.8299	 * {kernel_btf_id, btf_fd_idx} -> fixup bpf_call.8300	 * {kernel_btf_id, kernel_btf_obj_fd} -> fixup ld_imm64.8301	 */8302	ext->ksym.kernel_btf_obj_fd = mod_btf ? mod_btf->fd : 0;8303	pr_debug("extern (func ksym) '%s': resolved to %s [%d]\n",8304		 ext->name, mod_btf ? mod_btf->name : "vmlinux", kfunc_id);8305 8306	return 0;8307}8308 8309static int bpf_object__resolve_ksyms_btf_id(struct bpf_object *obj)8310{8311	const struct btf_type *t;8312	struct extern_desc *ext;8313	int i, err;8314 8315	for (i = 0; i < obj->nr_extern; i++) {8316		ext = &obj->externs[i];8317		if (ext->type != EXT_KSYM || !ext->ksym.type_id)8318			continue;8319 8320		if (obj->gen_loader) {8321			ext->is_set = true;8322			ext->ksym.kernel_btf_obj_fd = 0;8323			ext->ksym.kernel_btf_id = 0;8324			continue;8325		}8326		t = btf__type_by_id(obj->btf, ext->btf_id);8327		if (btf_is_var(t))8328			err = bpf_object__resolve_ksym_var_btf_id(obj, ext);8329		else8330			err = bpf_object__resolve_ksym_func_btf_id(obj, ext);8331		if (err)8332			return err;8333	}8334	return 0;8335}8336 8337static int bpf_object__resolve_externs(struct bpf_object *obj,8338				       const char *extra_kconfig)8339{8340	bool need_config = false, need_kallsyms = false;8341	bool need_vmlinux_btf = false;8342	struct extern_desc *ext;8343	void *kcfg_data = NULL;8344	int err, i;8345 8346	if (obj->nr_extern == 0)8347		return 0;8348 8349	if (obj->kconfig_map_idx >= 0)8350		kcfg_data = obj->maps[obj->kconfig_map_idx].mmaped;8351 8352	for (i = 0; i < obj->nr_extern; i++) {8353		ext = &obj->externs[i];8354 8355		if (ext->type == EXT_KSYM) {8356			if (ext->ksym.type_id)8357				need_vmlinux_btf = true;8358			else8359				need_kallsyms = true;8360			continue;8361		} else if (ext->type == EXT_KCFG) {8362			void *ext_ptr = kcfg_data + ext->kcfg.data_off;8363			__u64 value = 0;8364 8365			/* Kconfig externs need actual /proc/config.gz */8366			if (str_has_pfx(ext->name, "CONFIG_")) {8367				need_config = true;8368				continue;8369			}8370 8371			/* Virtual kcfg externs are customly handled by libbpf */8372			if (strcmp(ext->name, "LINUX_KERNEL_VERSION") == 0) {8373				value = get_kernel_version();8374				if (!value) {8375					pr_warn("extern (kcfg) '%s': failed to get kernel version\n", ext->name);8376					return -EINVAL;8377				}8378			} else if (strcmp(ext->name, "LINUX_HAS_BPF_COOKIE") == 0) {8379				value = kernel_supports(obj, FEAT_BPF_COOKIE);8380			} else if (strcmp(ext->name, "LINUX_HAS_SYSCALL_WRAPPER") == 0) {8381				value = kernel_supports(obj, FEAT_SYSCALL_WRAPPER);8382			} else if (!str_has_pfx(ext->name, "LINUX_") || !ext->is_weak) {8383				/* Currently libbpf supports only CONFIG_ and LINUX_ prefixed8384				 * __kconfig externs, where LINUX_ ones are virtual and filled out8385				 * customly by libbpf (their values don't come from Kconfig).8386				 * If LINUX_xxx variable is not recognized by libbpf, but is marked8387				 * __weak, it defaults to zero value, just like for CONFIG_xxx8388				 * externs.8389				 */8390				pr_warn("extern (kcfg) '%s': unrecognized virtual extern\n", ext->name);8391				return -EINVAL;8392			}8393 8394			err = set_kcfg_value_num(ext, ext_ptr, value);8395			if (err)8396				return err;8397			pr_debug("extern (kcfg) '%s': set to 0x%llx\n",8398				 ext->name, (long long)value);8399		} else {8400			pr_warn("extern '%s': unrecognized extern kind\n", ext->name);8401			return -EINVAL;8402		}8403	}8404	if (need_config && extra_kconfig) {8405		err = bpf_object__read_kconfig_mem(obj, extra_kconfig, kcfg_data);8406		if (err)8407			return -EINVAL;8408		need_config = false;8409		for (i = 0; i < obj->nr_extern; i++) {8410			ext = &obj->externs[i];8411			if (ext->type == EXT_KCFG && !ext->is_set) {8412				need_config = true;8413				break;8414			}8415		}8416	}8417	if (need_config) {8418		err = bpf_object__read_kconfig_file(obj, kcfg_data);8419		if (err)8420			return -EINVAL;8421	}8422	if (need_kallsyms) {8423		err = bpf_object__read_kallsyms_file(obj);8424		if (err)8425			return -EINVAL;8426	}8427	if (need_vmlinux_btf) {8428		err = bpf_object__resolve_ksyms_btf_id(obj);8429		if (err)8430			return -EINVAL;8431	}8432	for (i = 0; i < obj->nr_extern; i++) {8433		ext = &obj->externs[i];8434 8435		if (!ext->is_set && !ext->is_weak) {8436			pr_warn("extern '%s' (strong): not resolved\n", ext->name);8437			return -ESRCH;8438		} else if (!ext->is_set) {8439			pr_debug("extern '%s' (weak): not resolved, defaulting to zero\n",8440				 ext->name);8441		}8442	}8443 8444	return 0;8445}8446 8447static void bpf_map_prepare_vdata(const struct bpf_map *map)8448{8449	const struct btf_type *type;8450	struct bpf_struct_ops *st_ops;8451	__u32 i;8452 8453	st_ops = map->st_ops;8454	type = btf__type_by_id(map->obj->btf, st_ops->type_id);8455	for (i = 0; i < btf_vlen(type); i++) {8456		struct bpf_program *prog = st_ops->progs[i];8457		void *kern_data;8458		int prog_fd;8459 8460		if (!prog)8461			continue;8462 8463		prog_fd = bpf_program__fd(prog);8464		kern_data = st_ops->kern_vdata + st_ops->kern_func_off[i];8465		*(unsigned long *)kern_data = prog_fd;8466	}8467}8468 8469static int bpf_object_prepare_struct_ops(struct bpf_object *obj)8470{8471	struct bpf_map *map;8472	int i;8473 8474	for (i = 0; i < obj->nr_maps; i++) {8475		map = &obj->maps[i];8476 8477		if (!bpf_map__is_struct_ops(map))8478			continue;8479 8480		if (!map->autocreate)8481			continue;8482 8483		bpf_map_prepare_vdata(map);8484	}8485 8486	return 0;8487}8488 8489static int bpf_object_load(struct bpf_object *obj, int extra_log_level, const char *target_btf_path)8490{8491	int err, i;8492 8493	if (!obj)8494		return libbpf_err(-EINVAL);8495 8496	if (obj->loaded) {8497		pr_warn("object '%s': load can't be attempted twice\n", obj->name);8498		return libbpf_err(-EINVAL);8499	}8500 8501	if (obj->gen_loader)8502		bpf_gen__init(obj->gen_loader, extra_log_level, obj->nr_programs, obj->nr_maps);8503 8504	err = bpf_object_prepare_token(obj);8505	err = err ? : bpf_object__probe_loading(obj);8506	err = err ? : bpf_object__load_vmlinux_btf(obj, false);8507	err = err ? : bpf_object__resolve_externs(obj, obj->kconfig);8508	err = err ? : bpf_object__sanitize_maps(obj);8509	err = err ? : bpf_object__init_kern_struct_ops_maps(obj);8510	err = err ? : bpf_object_adjust_struct_ops_autoload(obj);8511	err = err ? : bpf_object__relocate(obj, obj->btf_custom_path ? : target_btf_path);8512	err = err ? : bpf_object__sanitize_and_load_btf(obj);8513	err = err ? : bpf_object__create_maps(obj);8514	err = err ? : bpf_object__load_progs(obj, extra_log_level);8515	err = err ? : bpf_object_init_prog_arrays(obj);8516	err = err ? : bpf_object_prepare_struct_ops(obj);8517 8518	if (obj->gen_loader) {8519		/* reset FDs */8520		if (obj->btf)8521			btf__set_fd(obj->btf, -1);8522		if (!err)8523			err = bpf_gen__finish(obj->gen_loader, obj->nr_programs, obj->nr_maps);8524	}8525 8526	/* clean up fd_array */8527	zfree(&obj->fd_array);8528 8529	/* clean up module BTFs */8530	for (i = 0; i < obj->btf_module_cnt; i++) {8531		close(obj->btf_modules[i].fd);8532		btf__free(obj->btf_modules[i].btf);8533		free(obj->btf_modules[i].name);8534	}8535	free(obj->btf_modules);8536 8537	/* clean up vmlinux BTF */8538	btf__free(obj->btf_vmlinux);8539	obj->btf_vmlinux = NULL;8540 8541	obj->loaded = true; /* doesn't matter if successfully or not */8542 8543	if (err)8544		goto out;8545 8546	return 0;8547out:8548	/* unpin any maps that were auto-pinned during load */8549	for (i = 0; i < obj->nr_maps; i++)8550		if (obj->maps[i].pinned && !obj->maps[i].reused)8551			bpf_map__unpin(&obj->maps[i], NULL);8552 8553	bpf_object_unload(obj);8554	pr_warn("failed to load object '%s'\n", obj->path);8555	return libbpf_err(err);8556}8557 8558int bpf_object__load(struct bpf_object *obj)8559{8560	return bpf_object_load(obj, 0, NULL);8561}8562 8563static int make_parent_dir(const char *path)8564{8565	char *cp, errmsg[STRERR_BUFSIZE];8566	char *dname, *dir;8567	int err = 0;8568 8569	dname = strdup(path);8570	if (dname == NULL)8571		return -ENOMEM;8572 8573	dir = dirname(dname);8574	if (mkdir(dir, 0700) && errno != EEXIST)8575		err = -errno;8576 8577	free(dname);8578	if (err) {8579		cp = libbpf_strerror_r(-err, errmsg, sizeof(errmsg));8580		pr_warn("failed to mkdir %s: %s\n", path, cp);8581	}8582	return err;8583}8584 8585static int check_path(const char *path)8586{8587	char *cp, errmsg[STRERR_BUFSIZE];8588	struct statfs st_fs;8589	char *dname, *dir;8590	int err = 0;8591 8592	if (path == NULL)8593		return -EINVAL;8594 8595	dname = strdup(path);8596	if (dname == NULL)8597		return -ENOMEM;8598 8599	dir = dirname(dname);8600	if (statfs(dir, &st_fs)) {8601		cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));8602		pr_warn("failed to statfs %s: %s\n", dir, cp);8603		err = -errno;8604	}8605	free(dname);8606 8607	if (!err && st_fs.f_type != BPF_FS_MAGIC) {8608		pr_warn("specified path %s is not on BPF FS\n", path);8609		err = -EINVAL;8610	}8611 8612	return err;8613}8614 8615int bpf_program__pin(struct bpf_program *prog, const char *path)8616{8617	char *cp, errmsg[STRERR_BUFSIZE];8618	int err;8619 8620	if (prog->fd < 0) {8621		pr_warn("prog '%s': can't pin program that wasn't loaded\n", prog->name);8622		return libbpf_err(-EINVAL);8623	}8624 8625	err = make_parent_dir(path);8626	if (err)8627		return libbpf_err(err);8628 8629	err = check_path(path);8630	if (err)8631		return libbpf_err(err);8632 8633	if (bpf_obj_pin(prog->fd, path)) {8634		err = -errno;8635		cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg));8636		pr_warn("prog '%s': failed to pin at '%s': %s\n", prog->name, path, cp);8637		return libbpf_err(err);8638	}8639 8640	pr_debug("prog '%s': pinned at '%s'\n", prog->name, path);8641	return 0;8642}8643 8644int bpf_program__unpin(struct bpf_program *prog, const char *path)8645{8646	int err;8647 8648	if (prog->fd < 0) {8649		pr_warn("prog '%s': can't unpin program that wasn't loaded\n", prog->name);8650		return libbpf_err(-EINVAL);8651	}8652 8653	err = check_path(path);8654	if (err)8655		return libbpf_err(err);8656 8657	err = unlink(path);8658	if (err)8659		return libbpf_err(-errno);8660 8661	pr_debug("prog '%s': unpinned from '%s'\n", prog->name, path);8662	return 0;8663}8664 8665int bpf_map__pin(struct bpf_map *map, const char *path)8666{8667	char *cp, errmsg[STRERR_BUFSIZE];8668	int err;8669 8670	if (map == NULL) {8671		pr_warn("invalid map pointer\n");8672		return libbpf_err(-EINVAL);8673	}8674 8675	if (map->fd < 0) {8676		pr_warn("map '%s': can't pin BPF map without FD (was it created?)\n", map->name);8677		return libbpf_err(-EINVAL);8678	}8679 8680	if (map->pin_path) {8681		if (path && strcmp(path, map->pin_path)) {8682			pr_warn("map '%s' already has pin path '%s' different from '%s'\n",8683				bpf_map__name(map), map->pin_path, path);8684			return libbpf_err(-EINVAL);8685		} else if (map->pinned) {8686			pr_debug("map '%s' already pinned at '%s'; not re-pinning\n",8687				 bpf_map__name(map), map->pin_path);8688			return 0;8689		}8690	} else {8691		if (!path) {8692			pr_warn("missing a path to pin map '%s' at\n",8693				bpf_map__name(map));8694			return libbpf_err(-EINVAL);8695		} else if (map->pinned) {8696			pr_warn("map '%s' already pinned\n", bpf_map__name(map));8697			return libbpf_err(-EEXIST);8698		}8699 8700		map->pin_path = strdup(path);8701		if (!map->pin_path) {8702			err = -errno;8703			goto out_err;8704		}8705	}8706 8707	err = make_parent_dir(map->pin_path);8708	if (err)8709		return libbpf_err(err);8710 8711	err = check_path(map->pin_path);8712	if (err)8713		return libbpf_err(err);8714 8715	if (bpf_obj_pin(map->fd, map->pin_path)) {8716		err = -errno;8717		goto out_err;8718	}8719 8720	map->pinned = true;8721	pr_debug("pinned map '%s'\n", map->pin_path);8722 8723	return 0;8724 8725out_err:8726	cp = libbpf_strerror_r(-err, errmsg, sizeof(errmsg));8727	pr_warn("failed to pin map: %s\n", cp);8728	return libbpf_err(err);8729}8730 8731int bpf_map__unpin(struct bpf_map *map, const char *path)8732{8733	int err;8734 8735	if (map == NULL) {8736		pr_warn("invalid map pointer\n");8737		return libbpf_err(-EINVAL);8738	}8739 8740	if (map->pin_path) {8741		if (path && strcmp(path, map->pin_path)) {8742			pr_warn("map '%s' already has pin path '%s' different from '%s'\n",8743				bpf_map__name(map), map->pin_path, path);8744			return libbpf_err(-EINVAL);8745		}8746		path = map->pin_path;8747	} else if (!path) {8748		pr_warn("no path to unpin map '%s' from\n",8749			bpf_map__name(map));8750		return libbpf_err(-EINVAL);8751	}8752 8753	err = check_path(path);8754	if (err)8755		return libbpf_err(err);8756 8757	err = unlink(path);8758	if (err != 0)8759		return libbpf_err(-errno);8760 8761	map->pinned = false;8762	pr_debug("unpinned map '%s' from '%s'\n", bpf_map__name(map), path);8763 8764	return 0;8765}8766 8767int bpf_map__set_pin_path(struct bpf_map *map, const char *path)8768{8769	char *new = NULL;8770 8771	if (path) {8772		new = strdup(path);8773		if (!new)8774			return libbpf_err(-errno);8775	}8776 8777	free(map->pin_path);8778	map->pin_path = new;8779	return 0;8780}8781 8782__alias(bpf_map__pin_path)8783const char *bpf_map__get_pin_path(const struct bpf_map *map);8784 8785const char *bpf_map__pin_path(const struct bpf_map *map)8786{8787	return map->pin_path;8788}8789 8790bool bpf_map__is_pinned(const struct bpf_map *map)8791{8792	return map->pinned;8793}8794 8795static void sanitize_pin_path(char *s)8796{8797	/* bpffs disallows periods in path names */8798	while (*s) {8799		if (*s == '.')8800			*s = '_';8801		s++;8802	}8803}8804 8805int bpf_object__pin_maps(struct bpf_object *obj, const char *path)8806{8807	struct bpf_map *map;8808	int err;8809 8810	if (!obj)8811		return libbpf_err(-ENOENT);8812 8813	if (!obj->loaded) {8814		pr_warn("object not yet loaded; load it first\n");8815		return libbpf_err(-ENOENT);8816	}8817 8818	bpf_object__for_each_map(map, obj) {8819		char *pin_path = NULL;8820		char buf[PATH_MAX];8821 8822		if (!map->autocreate)8823			continue;8824 8825		if (path) {8826			err = pathname_concat(buf, sizeof(buf), path, bpf_map__name(map));8827			if (err)8828				goto err_unpin_maps;8829			sanitize_pin_path(buf);8830			pin_path = buf;8831		} else if (!map->pin_path) {8832			continue;8833		}8834 8835		err = bpf_map__pin(map, pin_path);8836		if (err)8837			goto err_unpin_maps;8838	}8839 8840	return 0;8841 8842err_unpin_maps:8843	while ((map = bpf_object__prev_map(obj, map))) {8844		if (!map->pin_path)8845			continue;8846 8847		bpf_map__unpin(map, NULL);8848	}8849 8850	return libbpf_err(err);8851}8852 8853int bpf_object__unpin_maps(struct bpf_object *obj, const char *path)8854{8855	struct bpf_map *map;8856	int err;8857 8858	if (!obj)8859		return libbpf_err(-ENOENT);8860 8861	bpf_object__for_each_map(map, obj) {8862		char *pin_path = NULL;8863		char buf[PATH_MAX];8864 8865		if (path) {8866			err = pathname_concat(buf, sizeof(buf), path, bpf_map__name(map));8867			if (err)8868				return libbpf_err(err);8869			sanitize_pin_path(buf);8870			pin_path = buf;8871		} else if (!map->pin_path) {8872			continue;8873		}8874 8875		err = bpf_map__unpin(map, pin_path);8876		if (err)8877			return libbpf_err(err);8878	}8879 8880	return 0;8881}8882 8883int bpf_object__pin_programs(struct bpf_object *obj, const char *path)8884{8885	struct bpf_program *prog;8886	char buf[PATH_MAX];8887	int err;8888 8889	if (!obj)8890		return libbpf_err(-ENOENT);8891 8892	if (!obj->loaded) {8893		pr_warn("object not yet loaded; load it first\n");8894		return libbpf_err(-ENOENT);8895	}8896 8897	bpf_object__for_each_program(prog, obj) {8898		err = pathname_concat(buf, sizeof(buf), path, prog->name);8899		if (err)8900			goto err_unpin_programs;8901 8902		err = bpf_program__pin(prog, buf);8903		if (err)8904			goto err_unpin_programs;8905	}8906 8907	return 0;8908 8909err_unpin_programs:8910	while ((prog = bpf_object__prev_program(obj, prog))) {8911		if (pathname_concat(buf, sizeof(buf), path, prog->name))8912			continue;8913 8914		bpf_program__unpin(prog, buf);8915	}8916 8917	return libbpf_err(err);8918}8919 8920int bpf_object__unpin_programs(struct bpf_object *obj, const char *path)8921{8922	struct bpf_program *prog;8923	int err;8924 8925	if (!obj)8926		return libbpf_err(-ENOENT);8927 8928	bpf_object__for_each_program(prog, obj) {8929		char buf[PATH_MAX];8930 8931		err = pathname_concat(buf, sizeof(buf), path, prog->name);8932		if (err)8933			return libbpf_err(err);8934 8935		err = bpf_program__unpin(prog, buf);8936		if (err)8937			return libbpf_err(err);8938	}8939 8940	return 0;8941}8942 8943int bpf_object__pin(struct bpf_object *obj, const char *path)8944{8945	int err;8946 8947	err = bpf_object__pin_maps(obj, path);8948	if (err)8949		return libbpf_err(err);8950 8951	err = bpf_object__pin_programs(obj, path);8952	if (err) {8953		bpf_object__unpin_maps(obj, path);8954		return libbpf_err(err);8955	}8956 8957	return 0;8958}8959 8960int bpf_object__unpin(struct bpf_object *obj, const char *path)8961{8962	int err;8963 8964	err = bpf_object__unpin_programs(obj, path);8965	if (err)8966		return libbpf_err(err);8967 8968	err = bpf_object__unpin_maps(obj, path);8969	if (err)8970		return libbpf_err(err);8971 8972	return 0;8973}8974 8975static void bpf_map__destroy(struct bpf_map *map)8976{8977	if (map->inner_map) {8978		bpf_map__destroy(map->inner_map);8979		zfree(&map->inner_map);8980	}8981 8982	zfree(&map->init_slots);8983	map->init_slots_sz = 0;8984 8985	if (map->mmaped && map->mmaped != map->obj->arena_data)8986		munmap(map->mmaped, bpf_map_mmap_sz(map));8987	map->mmaped = NULL;8988 8989	if (map->st_ops) {8990		zfree(&map->st_ops->data);8991		zfree(&map->st_ops->progs);8992		zfree(&map->st_ops->kern_func_off);8993		zfree(&map->st_ops);8994	}8995 8996	zfree(&map->name);8997	zfree(&map->real_name);8998	zfree(&map->pin_path);8999 9000	if (map->fd >= 0)9001		zclose(map->fd);9002}9003 9004void bpf_object__close(struct bpf_object *obj)9005{9006	size_t i;9007 9008	if (IS_ERR_OR_NULL(obj))9009		return;9010 9011	usdt_manager_free(obj->usdt_man);9012	obj->usdt_man = NULL;9013 9014	bpf_gen__free(obj->gen_loader);9015	bpf_object__elf_finish(obj);9016	bpf_object_unload(obj);9017	btf__free(obj->btf);9018	btf__free(obj->btf_vmlinux);9019	btf_ext__free(obj->btf_ext);9020 9021	for (i = 0; i < obj->nr_maps; i++)9022		bpf_map__destroy(&obj->maps[i]);9023 9024	zfree(&obj->btf_custom_path);9025	zfree(&obj->kconfig);9026 9027	for (i = 0; i < obj->nr_extern; i++)9028		zfree(&obj->externs[i].essent_name);9029 9030	zfree(&obj->externs);9031	obj->nr_extern = 0;9032 9033	zfree(&obj->maps);9034	obj->nr_maps = 0;9035 9036	if (obj->programs && obj->nr_programs) {9037		for (i = 0; i < obj->nr_programs; i++)9038			bpf_program__exit(&obj->programs[i]);9039	}9040	zfree(&obj->programs);9041 9042	zfree(&obj->feat_cache);9043	zfree(&obj->token_path);9044	if (obj->token_fd > 0)9045		close(obj->token_fd);9046 9047	zfree(&obj->arena_data);9048 9049	free(obj);9050}9051 9052const char *bpf_object__name(const struct bpf_object *obj)9053{9054	return obj ? obj->name : libbpf_err_ptr(-EINVAL);9055}9056 9057unsigned int bpf_object__kversion(const struct bpf_object *obj)9058{9059	return obj ? obj->kern_version : 0;9060}9061 9062int bpf_object__token_fd(const struct bpf_object *obj)9063{9064	return obj->token_fd ?: -1;9065}9066 9067struct btf *bpf_object__btf(const struct bpf_object *obj)9068{9069	return obj ? obj->btf : NULL;9070}9071 9072int bpf_object__btf_fd(const struct bpf_object *obj)9073{9074	return obj->btf ? btf__fd(obj->btf) : -1;9075}9076 9077int bpf_object__set_kversion(struct bpf_object *obj, __u32 kern_version)9078{9079	if (obj->loaded)9080		return libbpf_err(-EINVAL);9081 9082	obj->kern_version = kern_version;9083 9084	return 0;9085}9086 9087int bpf_object__gen_loader(struct bpf_object *obj, struct gen_loader_opts *opts)9088{9089	struct bpf_gen *gen;9090 9091	if (!opts)9092		return -EFAULT;9093	if (!OPTS_VALID(opts, gen_loader_opts))9094		return -EINVAL;9095	gen = calloc(sizeof(*gen), 1);9096	if (!gen)9097		return -ENOMEM;9098	gen->opts = opts;9099	obj->gen_loader = gen;9100	return 0;9101}9102 9103static struct bpf_program *9104__bpf_program__iter(const struct bpf_program *p, const struct bpf_object *obj,9105		    bool forward)9106{9107	size_t nr_programs = obj->nr_programs;9108	ssize_t idx;9109 9110	if (!nr_programs)9111		return NULL;9112 9113	if (!p)9114		/* Iter from the beginning */9115		return forward ? &obj->programs[0] :9116			&obj->programs[nr_programs - 1];9117 9118	if (p->obj != obj) {9119		pr_warn("error: program handler doesn't match object\n");9120		return errno = EINVAL, NULL;9121	}9122 9123	idx = (p - obj->programs) + (forward ? 1 : -1);9124	if (idx >= obj->nr_programs || idx < 0)9125		return NULL;9126	return &obj->programs[idx];9127}9128 9129struct bpf_program *9130bpf_object__next_program(const struct bpf_object *obj, struct bpf_program *prev)9131{9132	struct bpf_program *prog = prev;9133 9134	do {9135		prog = __bpf_program__iter(prog, obj, true);9136	} while (prog && prog_is_subprog(obj, prog));9137 9138	return prog;9139}9140 9141struct bpf_program *9142bpf_object__prev_program(const struct bpf_object *obj, struct bpf_program *next)9143{9144	struct bpf_program *prog = next;9145 9146	do {9147		prog = __bpf_program__iter(prog, obj, false);9148	} while (prog && prog_is_subprog(obj, prog));9149 9150	return prog;9151}9152 9153void bpf_program__set_ifindex(struct bpf_program *prog, __u32 ifindex)9154{9155	prog->prog_ifindex = ifindex;9156}9157 9158const char *bpf_program__name(const struct bpf_program *prog)9159{9160	return prog->name;9161}9162 9163const char *bpf_program__section_name(const struct bpf_program *prog)9164{9165	return prog->sec_name;9166}9167 9168bool bpf_program__autoload(const struct bpf_program *prog)9169{9170	return prog->autoload;9171}9172 9173int bpf_program__set_autoload(struct bpf_program *prog, bool autoload)9174{9175	if (prog->obj->loaded)9176		return libbpf_err(-EINVAL);9177 9178	prog->autoload = autoload;9179	return 0;9180}9181 9182bool bpf_program__autoattach(const struct bpf_program *prog)9183{9184	return prog->autoattach;9185}9186 9187void bpf_program__set_autoattach(struct bpf_program *prog, bool autoattach)9188{9189	prog->autoattach = autoattach;9190}9191 9192const struct bpf_insn *bpf_program__insns(const struct bpf_program *prog)9193{9194	return prog->insns;9195}9196 9197size_t bpf_program__insn_cnt(const struct bpf_program *prog)9198{9199	return prog->insns_cnt;9200}9201 9202int bpf_program__set_insns(struct bpf_program *prog,9203			   struct bpf_insn *new_insns, size_t new_insn_cnt)9204{9205	struct bpf_insn *insns;9206 9207	if (prog->obj->loaded)9208		return -EBUSY;9209 9210	insns = libbpf_reallocarray(prog->insns, new_insn_cnt, sizeof(*insns));9211	/* NULL is a valid return from reallocarray if the new count is zero */9212	if (!insns && new_insn_cnt) {9213		pr_warn("prog '%s': failed to realloc prog code\n", prog->name);9214		return -ENOMEM;9215	}9216	memcpy(insns, new_insns, new_insn_cnt * sizeof(*insns));9217 9218	prog->insns = insns;9219	prog->insns_cnt = new_insn_cnt;9220	return 0;9221}9222 9223int bpf_program__fd(const struct bpf_program *prog)9224{9225	if (!prog)9226		return libbpf_err(-EINVAL);9227 9228	if (prog->fd < 0)9229		return libbpf_err(-ENOENT);9230 9231	return prog->fd;9232}9233 9234__alias(bpf_program__type)9235enum bpf_prog_type bpf_program__get_type(const struct bpf_program *prog);9236 9237enum bpf_prog_type bpf_program__type(const struct bpf_program *prog)9238{9239	return prog->type;9240}9241 9242static size_t custom_sec_def_cnt;9243static struct bpf_sec_def *custom_sec_defs;9244static struct bpf_sec_def custom_fallback_def;9245static bool has_custom_fallback_def;9246static int last_custom_sec_def_handler_id;9247 9248int bpf_program__set_type(struct bpf_program *prog, enum bpf_prog_type type)9249{9250	if (prog->obj->loaded)9251		return libbpf_err(-EBUSY);9252 9253	/* if type is not changed, do nothing */9254	if (prog->type == type)9255		return 0;9256 9257	prog->type = type;9258 9259	/* If a program type was changed, we need to reset associated SEC()9260	 * handler, as it will be invalid now. The only exception is a generic9261	 * fallback handler, which by definition is program type-agnostic and9262	 * is a catch-all custom handler, optionally set by the application,9263	 * so should be able to handle any type of BPF program.9264	 */9265	if (prog->sec_def != &custom_fallback_def)9266		prog->sec_def = NULL;9267	return 0;9268}9269 9270__alias(bpf_program__expected_attach_type)9271enum bpf_attach_type bpf_program__get_expected_attach_type(const struct bpf_program *prog);9272 9273enum bpf_attach_type bpf_program__expected_attach_type(const struct bpf_program *prog)9274{9275	return prog->expected_attach_type;9276}9277 9278int bpf_program__set_expected_attach_type(struct bpf_program *prog,9279					   enum bpf_attach_type type)9280{9281	if (prog->obj->loaded)9282		return libbpf_err(-EBUSY);9283 9284	prog->expected_attach_type = type;9285	return 0;9286}9287 9288__u32 bpf_program__flags(const struct bpf_program *prog)9289{9290	return prog->prog_flags;9291}9292 9293int bpf_program__set_flags(struct bpf_program *prog, __u32 flags)9294{9295	if (prog->obj->loaded)9296		return libbpf_err(-EBUSY);9297 9298	prog->prog_flags = flags;9299	return 0;9300}9301 9302__u32 bpf_program__log_level(const struct bpf_program *prog)9303{9304	return prog->log_level;9305}9306 9307int bpf_program__set_log_level(struct bpf_program *prog, __u32 log_level)9308{9309	if (prog->obj->loaded)9310		return libbpf_err(-EBUSY);9311 9312	prog->log_level = log_level;9313	return 0;9314}9315 9316const char *bpf_program__log_buf(const struct bpf_program *prog, size_t *log_size)9317{9318	*log_size = prog->log_size;9319	return prog->log_buf;9320}9321 9322int bpf_program__set_log_buf(struct bpf_program *prog, char *log_buf, size_t log_size)9323{9324	if (log_size && !log_buf)9325		return -EINVAL;9326	if (prog->log_size > UINT_MAX)9327		return -EINVAL;9328	if (prog->obj->loaded)9329		return -EBUSY;9330 9331	prog->log_buf = log_buf;9332	prog->log_size = log_size;9333	return 0;9334}9335 9336#define SEC_DEF(sec_pfx, ptype, atype, flags, ...) {			    \9337	.sec = (char *)sec_pfx,						    \9338	.prog_type = BPF_PROG_TYPE_##ptype,				    \9339	.expected_attach_type = atype,					    \9340	.cookie = (long)(flags),					    \9341	.prog_prepare_load_fn = libbpf_prepare_prog_load,		    \9342	__VA_ARGS__							    \9343}9344 9345static int attach_kprobe(const struct bpf_program *prog, long cookie, struct bpf_link **link);9346static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf_link **link);9347static int attach_ksyscall(const struct bpf_program *prog, long cookie, struct bpf_link **link);9348static int attach_usdt(const struct bpf_program *prog, long cookie, struct bpf_link **link);9349static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link);9350static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link);9351static int attach_trace(const struct bpf_program *prog, long cookie, struct bpf_link **link);9352static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);9353static int attach_kprobe_session(const struct bpf_program *prog, long cookie, struct bpf_link **link);9354static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);9355static int attach_lsm(const struct bpf_program *prog, long cookie, struct bpf_link **link);9356static int attach_iter(const struct bpf_program *prog, long cookie, struct bpf_link **link);9357 9358static const struct bpf_sec_def section_defs[] = {9359	SEC_DEF("socket",		SOCKET_FILTER, 0, SEC_NONE),9360	SEC_DEF("sk_reuseport/migrate",	SK_REUSEPORT, BPF_SK_REUSEPORT_SELECT_OR_MIGRATE, SEC_ATTACHABLE),9361	SEC_DEF("sk_reuseport",		SK_REUSEPORT, BPF_SK_REUSEPORT_SELECT, SEC_ATTACHABLE),9362	SEC_DEF("kprobe+",		KPROBE,	0, SEC_NONE, attach_kprobe),9363	SEC_DEF("uprobe+",		KPROBE,	0, SEC_NONE, attach_uprobe),9364	SEC_DEF("uprobe.s+",		KPROBE,	0, SEC_SLEEPABLE, attach_uprobe),9365	SEC_DEF("kretprobe+",		KPROBE, 0, SEC_NONE, attach_kprobe),9366	SEC_DEF("uretprobe+",		KPROBE, 0, SEC_NONE, attach_uprobe),9367	SEC_DEF("uretprobe.s+",		KPROBE, 0, SEC_SLEEPABLE, attach_uprobe),9368	SEC_DEF("kprobe.multi+",	KPROBE,	BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),9369	SEC_DEF("kretprobe.multi+",	KPROBE,	BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),9370	SEC_DEF("kprobe.session+",	KPROBE,	BPF_TRACE_KPROBE_SESSION, SEC_NONE, attach_kprobe_session),9371	SEC_DEF("uprobe.multi+",	KPROBE,	BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),9372	SEC_DEF("uretprobe.multi+",	KPROBE,	BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),9373	SEC_DEF("uprobe.multi.s+",	KPROBE,	BPF_TRACE_UPROBE_MULTI, SEC_SLEEPABLE, attach_uprobe_multi),9374	SEC_DEF("uretprobe.multi.s+",	KPROBE,	BPF_TRACE_UPROBE_MULTI, SEC_SLEEPABLE, attach_uprobe_multi),9375	SEC_DEF("ksyscall+",		KPROBE,	0, SEC_NONE, attach_ksyscall),9376	SEC_DEF("kretsyscall+",		KPROBE, 0, SEC_NONE, attach_ksyscall),9377	SEC_DEF("usdt+",		KPROBE,	0, SEC_USDT, attach_usdt),9378	SEC_DEF("usdt.s+",		KPROBE,	0, SEC_USDT | SEC_SLEEPABLE, attach_usdt),9379	SEC_DEF("tc/ingress",		SCHED_CLS, BPF_TCX_INGRESS, SEC_NONE), /* alias for tcx */9380	SEC_DEF("tc/egress",		SCHED_CLS, BPF_TCX_EGRESS, SEC_NONE),  /* alias for tcx */9381	SEC_DEF("tcx/ingress",		SCHED_CLS, BPF_TCX_INGRESS, SEC_NONE),9382	SEC_DEF("tcx/egress",		SCHED_CLS, BPF_TCX_EGRESS, SEC_NONE),9383	SEC_DEF("tc",			SCHED_CLS, 0, SEC_NONE), /* deprecated / legacy, use tcx */9384	SEC_DEF("classifier",		SCHED_CLS, 0, SEC_NONE), /* deprecated / legacy, use tcx */9385	SEC_DEF("action",		SCHED_ACT, 0, SEC_NONE), /* deprecated / legacy, use tcx */9386	SEC_DEF("netkit/primary",	SCHED_CLS, BPF_NETKIT_PRIMARY, SEC_NONE),9387	SEC_DEF("netkit/peer",		SCHED_CLS, BPF_NETKIT_PEER, SEC_NONE),9388	SEC_DEF("tracepoint+",		TRACEPOINT, 0, SEC_NONE, attach_tp),9389	SEC_DEF("tp+",			TRACEPOINT, 0, SEC_NONE, attach_tp),9390	SEC_DEF("raw_tracepoint+",	RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),9391	SEC_DEF("raw_tp+",		RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),9392	SEC_DEF("raw_tracepoint.w+",	RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),9393	SEC_DEF("raw_tp.w+",		RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),9394	SEC_DEF("tp_btf+",		TRACING, BPF_TRACE_RAW_TP, SEC_ATTACH_BTF, attach_trace),9395	SEC_DEF("fentry+",		TRACING, BPF_TRACE_FENTRY, SEC_ATTACH_BTF, attach_trace),9396	SEC_DEF("fmod_ret+",		TRACING, BPF_MODIFY_RETURN, SEC_ATTACH_BTF, attach_trace),9397	SEC_DEF("fexit+",		TRACING, BPF_TRACE_FEXIT, SEC_ATTACH_BTF, attach_trace),9398	SEC_DEF("fentry.s+",		TRACING, BPF_TRACE_FENTRY, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_trace),9399	SEC_DEF("fmod_ret.s+",		TRACING, BPF_MODIFY_RETURN, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_trace),9400	SEC_DEF("fexit.s+",		TRACING, BPF_TRACE_FEXIT, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_trace),9401	SEC_DEF("freplace+",		EXT, 0, SEC_ATTACH_BTF, attach_trace),9402	SEC_DEF("lsm+",			LSM, BPF_LSM_MAC, SEC_ATTACH_BTF, attach_lsm),9403	SEC_DEF("lsm.s+",		LSM, BPF_LSM_MAC, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_lsm),9404	SEC_DEF("lsm_cgroup+",		LSM, BPF_LSM_CGROUP, SEC_ATTACH_BTF),9405	SEC_DEF("iter+",		TRACING, BPF_TRACE_ITER, SEC_ATTACH_BTF, attach_iter),9406	SEC_DEF("iter.s+",		TRACING, BPF_TRACE_ITER, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_iter),9407	SEC_DEF("syscall",		SYSCALL, 0, SEC_SLEEPABLE),9408	SEC_DEF("xdp.frags/devmap",	XDP, BPF_XDP_DEVMAP, SEC_XDP_FRAGS),9409	SEC_DEF("xdp/devmap",		XDP, BPF_XDP_DEVMAP, SEC_ATTACHABLE),9410	SEC_DEF("xdp.frags/cpumap",	XDP, BPF_XDP_CPUMAP, SEC_XDP_FRAGS),9411	SEC_DEF("xdp/cpumap",		XDP, BPF_XDP_CPUMAP, SEC_ATTACHABLE),9412	SEC_DEF("xdp.frags",		XDP, BPF_XDP, SEC_XDP_FRAGS),9413	SEC_DEF("xdp",			XDP, BPF_XDP, SEC_ATTACHABLE_OPT),9414	SEC_DEF("perf_event",		PERF_EVENT, 0, SEC_NONE),9415	SEC_DEF("lwt_in",		LWT_IN, 0, SEC_NONE),9416	SEC_DEF("lwt_out",		LWT_OUT, 0, SEC_NONE),9417	SEC_DEF("lwt_xmit",		LWT_XMIT, 0, SEC_NONE),9418	SEC_DEF("lwt_seg6local",	LWT_SEG6LOCAL, 0, SEC_NONE),9419	SEC_DEF("sockops",		SOCK_OPS, BPF_CGROUP_SOCK_OPS, SEC_ATTACHABLE_OPT),9420	SEC_DEF("sk_skb/stream_parser",	SK_SKB, BPF_SK_SKB_STREAM_PARSER, SEC_ATTACHABLE_OPT),9421	SEC_DEF("sk_skb/stream_verdict",SK_SKB, BPF_SK_SKB_STREAM_VERDICT, SEC_ATTACHABLE_OPT),9422	SEC_DEF("sk_skb/verdict",	SK_SKB, BPF_SK_SKB_VERDICT, SEC_ATTACHABLE_OPT),9423	SEC_DEF("sk_skb",		SK_SKB, 0, SEC_NONE),9424	SEC_DEF("sk_msg",		SK_MSG, BPF_SK_MSG_VERDICT, SEC_ATTACHABLE_OPT),9425	SEC_DEF("lirc_mode2",		LIRC_MODE2, BPF_LIRC_MODE2, SEC_ATTACHABLE_OPT),9426	SEC_DEF("flow_dissector",	FLOW_DISSECTOR, BPF_FLOW_DISSECTOR, SEC_ATTACHABLE_OPT),9427	SEC_DEF("cgroup_skb/ingress",	CGROUP_SKB, BPF_CGROUP_INET_INGRESS, SEC_ATTACHABLE_OPT),9428	SEC_DEF("cgroup_skb/egress",	CGROUP_SKB, BPF_CGROUP_INET_EGRESS, SEC_ATTACHABLE_OPT),9429	SEC_DEF("cgroup/skb",		CGROUP_SKB, 0, SEC_NONE),9430	SEC_DEF("cgroup/sock_create",	CGROUP_SOCK, BPF_CGROUP_INET_SOCK_CREATE, SEC_ATTACHABLE),9431	SEC_DEF("cgroup/sock_release",	CGROUP_SOCK, BPF_CGROUP_INET_SOCK_RELEASE, SEC_ATTACHABLE),9432	SEC_DEF("cgroup/sock",		CGROUP_SOCK, BPF_CGROUP_INET_SOCK_CREATE, SEC_ATTACHABLE_OPT),9433	SEC_DEF("cgroup/post_bind4",	CGROUP_SOCK, BPF_CGROUP_INET4_POST_BIND, SEC_ATTACHABLE),9434	SEC_DEF("cgroup/post_bind6",	CGROUP_SOCK, BPF_CGROUP_INET6_POST_BIND, SEC_ATTACHABLE),9435	SEC_DEF("cgroup/bind4",		CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_BIND, SEC_ATTACHABLE),9436	SEC_DEF("cgroup/bind6",		CGROUP_SOCK_ADDR, BPF_CGROUP_INET6_BIND, SEC_ATTACHABLE),9437	SEC_DEF("cgroup/connect4",	CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_CONNECT, SEC_ATTACHABLE),9438	SEC_DEF("cgroup/connect6",	CGROUP_SOCK_ADDR, BPF_CGROUP_INET6_CONNECT, SEC_ATTACHABLE),9439	SEC_DEF("cgroup/connect_unix",	CGROUP_SOCK_ADDR, BPF_CGROUP_UNIX_CONNECT, SEC_ATTACHABLE),9440	SEC_DEF("cgroup/sendmsg4",	CGROUP_SOCK_ADDR, BPF_CGROUP_UDP4_SENDMSG, SEC_ATTACHABLE),9441	SEC_DEF("cgroup/sendmsg6",	CGROUP_SOCK_ADDR, BPF_CGROUP_UDP6_SENDMSG, SEC_ATTACHABLE),9442	SEC_DEF("cgroup/sendmsg_unix",	CGROUP_SOCK_ADDR, BPF_CGROUP_UNIX_SENDMSG, SEC_ATTACHABLE),9443	SEC_DEF("cgroup/recvmsg4",	CGROUP_SOCK_ADDR, BPF_CGROUP_UDP4_RECVMSG, SEC_ATTACHABLE),9444	SEC_DEF("cgroup/recvmsg6",	CGROUP_SOCK_ADDR, BPF_CGROUP_UDP6_RECVMSG, SEC_ATTACHABLE),9445	SEC_DEF("cgroup/recvmsg_unix",	CGROUP_SOCK_ADDR, BPF_CGROUP_UNIX_RECVMSG, SEC_ATTACHABLE),9446	SEC_DEF("cgroup/getpeername4",	CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_GETPEERNAME, SEC_ATTACHABLE),9447	SEC_DEF("cgroup/getpeername6",	CGROUP_SOCK_ADDR, BPF_CGROUP_INET6_GETPEERNAME, SEC_ATTACHABLE),9448	SEC_DEF("cgroup/getpeername_unix", CGROUP_SOCK_ADDR, BPF_CGROUP_UNIX_GETPEERNAME, SEC_ATTACHABLE),9449	SEC_DEF("cgroup/getsockname4",	CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_GETSOCKNAME, SEC_ATTACHABLE),9450	SEC_DEF("cgroup/getsockname6",	CGROUP_SOCK_ADDR, BPF_CGROUP_INET6_GETSOCKNAME, SEC_ATTACHABLE),9451	SEC_DEF("cgroup/getsockname_unix", CGROUP_SOCK_ADDR, BPF_CGROUP_UNIX_GETSOCKNAME, SEC_ATTACHABLE),9452	SEC_DEF("cgroup/sysctl",	CGROUP_SYSCTL, BPF_CGROUP_SYSCTL, SEC_ATTACHABLE),9453	SEC_DEF("cgroup/getsockopt",	CGROUP_SOCKOPT, BPF_CGROUP_GETSOCKOPT, SEC_ATTACHABLE),9454	SEC_DEF("cgroup/setsockopt",	CGROUP_SOCKOPT, BPF_CGROUP_SETSOCKOPT, SEC_ATTACHABLE),9455	SEC_DEF("cgroup/dev",		CGROUP_DEVICE, BPF_CGROUP_DEVICE, SEC_ATTACHABLE_OPT),9456	SEC_DEF("struct_ops+",		STRUCT_OPS, 0, SEC_NONE),9457	SEC_DEF("struct_ops.s+",	STRUCT_OPS, 0, SEC_SLEEPABLE),9458	SEC_DEF("sk_lookup",		SK_LOOKUP, BPF_SK_LOOKUP, SEC_ATTACHABLE),9459	SEC_DEF("netfilter",		NETFILTER, BPF_NETFILTER, SEC_NONE),9460};9461 9462int libbpf_register_prog_handler(const char *sec,9463				 enum bpf_prog_type prog_type,9464				 enum bpf_attach_type exp_attach_type,9465				 const struct libbpf_prog_handler_opts *opts)9466{9467	struct bpf_sec_def *sec_def;9468 9469	if (!OPTS_VALID(opts, libbpf_prog_handler_opts))9470		return libbpf_err(-EINVAL);9471 9472	if (last_custom_sec_def_handler_id == INT_MAX) /* prevent overflow */9473		return libbpf_err(-E2BIG);9474 9475	if (sec) {9476		sec_def = libbpf_reallocarray(custom_sec_defs, custom_sec_def_cnt + 1,9477					      sizeof(*sec_def));9478		if (!sec_def)9479			return libbpf_err(-ENOMEM);9480 9481		custom_sec_defs = sec_def;9482		sec_def = &custom_sec_defs[custom_sec_def_cnt];9483	} else {9484		if (has_custom_fallback_def)9485			return libbpf_err(-EBUSY);9486 9487		sec_def = &custom_fallback_def;9488	}9489 9490	sec_def->sec = sec ? strdup(sec) : NULL;9491	if (sec && !sec_def->sec)9492		return libbpf_err(-ENOMEM);9493 9494	sec_def->prog_type = prog_type;9495	sec_def->expected_attach_type = exp_attach_type;9496	sec_def->cookie = OPTS_GET(opts, cookie, 0);9497 9498	sec_def->prog_setup_fn = OPTS_GET(opts, prog_setup_fn, NULL);9499	sec_def->prog_prepare_load_fn = OPTS_GET(opts, prog_prepare_load_fn, NULL);9500	sec_def->prog_attach_fn = OPTS_GET(opts, prog_attach_fn, NULL);9501 9502	sec_def->handler_id = ++last_custom_sec_def_handler_id;9503 9504	if (sec)9505		custom_sec_def_cnt++;9506	else9507		has_custom_fallback_def = true;9508 9509	return sec_def->handler_id;9510}9511 9512int libbpf_unregister_prog_handler(int handler_id)9513{9514	struct bpf_sec_def *sec_defs;9515	int i;9516 9517	if (handler_id <= 0)9518		return libbpf_err(-EINVAL);9519 9520	if (has_custom_fallback_def && custom_fallback_def.handler_id == handler_id) {9521		memset(&custom_fallback_def, 0, sizeof(custom_fallback_def));9522		has_custom_fallback_def = false;9523		return 0;9524	}9525 9526	for (i = 0; i < custom_sec_def_cnt; i++) {9527		if (custom_sec_defs[i].handler_id == handler_id)9528			break;9529	}9530 9531	if (i == custom_sec_def_cnt)9532		return libbpf_err(-ENOENT);9533 9534	free(custom_sec_defs[i].sec);9535	for (i = i + 1; i < custom_sec_def_cnt; i++)9536		custom_sec_defs[i - 1] = custom_sec_defs[i];9537	custom_sec_def_cnt--;9538 9539	/* try to shrink the array, but it's ok if we couldn't */9540	sec_defs = libbpf_reallocarray(custom_sec_defs, custom_sec_def_cnt, sizeof(*sec_defs));9541	/* if new count is zero, reallocarray can return a valid NULL result;9542	 * in this case the previous pointer will be freed, so we *have to*9543	 * reassign old pointer to the new value (even if it's NULL)9544	 */9545	if (sec_defs || custom_sec_def_cnt == 0)9546		custom_sec_defs = sec_defs;9547 9548	return 0;9549}9550 9551static bool sec_def_matches(const struct bpf_sec_def *sec_def, const char *sec_name)9552{9553	size_t len = strlen(sec_def->sec);9554 9555	/* "type/" always has to have proper SEC("type/extras") form */9556	if (sec_def->sec[len - 1] == '/') {9557		if (str_has_pfx(sec_name, sec_def->sec))9558			return true;9559		return false;9560	}9561 9562	/* "type+" means it can be either exact SEC("type") or9563	 * well-formed SEC("type/extras") with proper '/' separator9564	 */9565	if (sec_def->sec[len - 1] == '+') {9566		len--;9567		/* not even a prefix */9568		if (strncmp(sec_name, sec_def->sec, len) != 0)9569			return false;9570		/* exact match or has '/' separator */9571		if (sec_name[len] == '\0' || sec_name[len] == '/')9572			return true;9573		return false;9574	}9575 9576	return strcmp(sec_name, sec_def->sec) == 0;9577}9578 9579static const struct bpf_sec_def *find_sec_def(const char *sec_name)9580{9581	const struct bpf_sec_def *sec_def;9582	int i, n;9583 9584	n = custom_sec_def_cnt;9585	for (i = 0; i < n; i++) {9586		sec_def = &custom_sec_defs[i];9587		if (sec_def_matches(sec_def, sec_name))9588			return sec_def;9589	}9590 9591	n = ARRAY_SIZE(section_defs);9592	for (i = 0; i < n; i++) {9593		sec_def = &section_defs[i];9594		if (sec_def_matches(sec_def, sec_name))9595			return sec_def;9596	}9597 9598	if (has_custom_fallback_def)9599		return &custom_fallback_def;9600 9601	return NULL;9602}9603 9604#define MAX_TYPE_NAME_SIZE 329605 9606static char *libbpf_get_type_names(bool attach_type)9607{9608	int i, len = ARRAY_SIZE(section_defs) * MAX_TYPE_NAME_SIZE;9609	char *buf;9610 9611	buf = malloc(len);9612	if (!buf)9613		return NULL;9614 9615	buf[0] = '\0';9616	/* Forge string buf with all available names */9617	for (i = 0; i < ARRAY_SIZE(section_defs); i++) {9618		const struct bpf_sec_def *sec_def = &section_defs[i];9619 9620		if (attach_type) {9621			if (sec_def->prog_prepare_load_fn != libbpf_prepare_prog_load)9622				continue;9623 9624			if (!(sec_def->cookie & SEC_ATTACHABLE))9625				continue;9626		}9627 9628		if (strlen(buf) + strlen(section_defs[i].sec) + 2 > len) {9629			free(buf);9630			return NULL;9631		}9632		strcat(buf, " ");9633		strcat(buf, section_defs[i].sec);9634	}9635 9636	return buf;9637}9638 9639int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,9640			     enum bpf_attach_type *expected_attach_type)9641{9642	const struct bpf_sec_def *sec_def;9643	char *type_names;9644 9645	if (!name)9646		return libbpf_err(-EINVAL);9647 9648	sec_def = find_sec_def(name);9649	if (sec_def) {9650		*prog_type = sec_def->prog_type;9651		*expected_attach_type = sec_def->expected_attach_type;9652		return 0;9653	}9654 9655	pr_debug("failed to guess program type from ELF section '%s'\n", name);9656	type_names = libbpf_get_type_names(false);9657	if (type_names != NULL) {9658		pr_debug("supported section(type) names are:%s\n", type_names);9659		free(type_names);9660	}9661 9662	return libbpf_err(-ESRCH);9663}9664 9665const char *libbpf_bpf_attach_type_str(enum bpf_attach_type t)9666{9667	if (t < 0 || t >= ARRAY_SIZE(attach_type_name))9668		return NULL;9669 9670	return attach_type_name[t];9671}9672 9673const char *libbpf_bpf_link_type_str(enum bpf_link_type t)9674{9675	if (t < 0 || t >= ARRAY_SIZE(link_type_name))9676		return NULL;9677 9678	return link_type_name[t];9679}9680 9681const char *libbpf_bpf_map_type_str(enum bpf_map_type t)9682{9683	if (t < 0 || t >= ARRAY_SIZE(map_type_name))9684		return NULL;9685 9686	return map_type_name[t];9687}9688 9689const char *libbpf_bpf_prog_type_str(enum bpf_prog_type t)9690{9691	if (t < 0 || t >= ARRAY_SIZE(prog_type_name))9692		return NULL;9693 9694	return prog_type_name[t];9695}9696 9697static struct bpf_map *find_struct_ops_map_by_offset(struct bpf_object *obj,9698						     int sec_idx,9699						     size_t offset)9700{9701	struct bpf_map *map;9702	size_t i;9703 9704	for (i = 0; i < obj->nr_maps; i++) {9705		map = &obj->maps[i];9706		if (!bpf_map__is_struct_ops(map))9707			continue;9708		if (map->sec_idx == sec_idx &&9709		    map->sec_offset <= offset &&9710		    offset - map->sec_offset < map->def.value_size)9711			return map;9712	}9713 9714	return NULL;9715}9716 9717/* Collect the reloc from ELF, populate the st_ops->progs[], and update9718 * st_ops->data for shadow type.9719 */9720static int bpf_object__collect_st_ops_relos(struct bpf_object *obj,9721					    Elf64_Shdr *shdr, Elf_Data *data)9722{9723	const struct btf_type *type;9724	const struct btf_member *member;9725	struct bpf_struct_ops *st_ops;9726	struct bpf_program *prog;9727	unsigned int shdr_idx;9728	const struct btf *btf;9729	struct bpf_map *map;9730	unsigned int moff, insn_idx;9731	const char *name;9732	__u32 member_idx;9733	Elf64_Sym *sym;9734	Elf64_Rel *rel;9735	int i, nrels;9736 9737	btf = obj->btf;9738	nrels = shdr->sh_size / shdr->sh_entsize;9739	for (i = 0; i < nrels; i++) {9740		rel = elf_rel_by_idx(data, i);9741		if (!rel) {9742			pr_warn("struct_ops reloc: failed to get %d reloc\n", i);9743			return -LIBBPF_ERRNO__FORMAT;9744		}9745 9746		sym = elf_sym_by_idx(obj, ELF64_R_SYM(rel->r_info));9747		if (!sym) {9748			pr_warn("struct_ops reloc: symbol %zx not found\n",9749				(size_t)ELF64_R_SYM(rel->r_info));9750			return -LIBBPF_ERRNO__FORMAT;9751		}9752 9753		name = elf_sym_str(obj, sym->st_name) ?: "<?>";9754		map = find_struct_ops_map_by_offset(obj, shdr->sh_info, rel->r_offset);9755		if (!map) {9756			pr_warn("struct_ops reloc: cannot find map at rel->r_offset %zu\n",9757				(size_t)rel->r_offset);9758			return -EINVAL;9759		}9760 9761		moff = rel->r_offset - map->sec_offset;9762		shdr_idx = sym->st_shndx;9763		st_ops = map->st_ops;9764		pr_debug("struct_ops reloc %s: for %lld value %lld shdr_idx %u rel->r_offset %zu map->sec_offset %zu name %d (\'%s\')\n",9765			 map->name,9766			 (long long)(rel->r_info >> 32),9767			 (long long)sym->st_value,9768			 shdr_idx, (size_t)rel->r_offset,9769			 map->sec_offset, sym->st_name, name);9770 9771		if (shdr_idx >= SHN_LORESERVE) {9772			pr_warn("struct_ops reloc %s: rel->r_offset %zu shdr_idx %u unsupported non-static function\n",9773				map->name, (size_t)rel->r_offset, shdr_idx);9774			return -LIBBPF_ERRNO__RELOC;9775		}9776		if (sym->st_value % BPF_INSN_SZ) {9777			pr_warn("struct_ops reloc %s: invalid target program offset %llu\n",9778				map->name, (unsigned long long)sym->st_value);9779			return -LIBBPF_ERRNO__FORMAT;9780		}9781		insn_idx = sym->st_value / BPF_INSN_SZ;9782 9783		type = btf__type_by_id(btf, st_ops->type_id);9784		member = find_member_by_offset(type, moff * 8);9785		if (!member) {9786			pr_warn("struct_ops reloc %s: cannot find member at moff %u\n",9787				map->name, moff);9788			return -EINVAL;9789		}9790		member_idx = member - btf_members(type);9791		name = btf__name_by_offset(btf, member->name_off);9792 9793		if (!resolve_func_ptr(btf, member->type, NULL)) {9794			pr_warn("struct_ops reloc %s: cannot relocate non func ptr %s\n",9795				map->name, name);9796			return -EINVAL;9797		}9798 9799		prog = find_prog_by_sec_insn(obj, shdr_idx, insn_idx);9800		if (!prog) {9801			pr_warn("struct_ops reloc %s: cannot find prog at shdr_idx %u to relocate func ptr %s\n",9802				map->name, shdr_idx, name);9803			return -EINVAL;9804		}9805 9806		/* prevent the use of BPF prog with invalid type */9807		if (prog->type != BPF_PROG_TYPE_STRUCT_OPS) {9808			pr_warn("struct_ops reloc %s: prog %s is not struct_ops BPF program\n",9809				map->name, prog->name);9810			return -EINVAL;9811		}9812 9813		st_ops->progs[member_idx] = prog;9814 9815		/* st_ops->data will be exposed to users, being returned by9816		 * bpf_map__initial_value() as a pointer to the shadow9817		 * type. All function pointers in the original struct type9818		 * should be converted to a pointer to struct bpf_program9819		 * in the shadow type.9820		 */9821		*((struct bpf_program **)(st_ops->data + moff)) = prog;9822	}9823 9824	return 0;9825}9826 9827#define BTF_TRACE_PREFIX "btf_trace_"9828#define BTF_LSM_PREFIX "bpf_lsm_"9829#define BTF_ITER_PREFIX "bpf_iter_"9830#define BTF_MAX_NAME_SIZE 1289831 9832void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type,9833				const char **prefix, int *kind)9834{9835	switch (attach_type) {9836	case BPF_TRACE_RAW_TP:9837		*prefix = BTF_TRACE_PREFIX;9838		*kind = BTF_KIND_TYPEDEF;9839		break;9840	case BPF_LSM_MAC:9841	case BPF_LSM_CGROUP:9842		*prefix = BTF_LSM_PREFIX;9843		*kind = BTF_KIND_FUNC;9844		break;9845	case BPF_TRACE_ITER:9846		*prefix = BTF_ITER_PREFIX;9847		*kind = BTF_KIND_FUNC;9848		break;9849	default:9850		*prefix = "";9851		*kind = BTF_KIND_FUNC;9852	}9853}9854 9855static int find_btf_by_prefix_kind(const struct btf *btf, const char *prefix,9856				   const char *name, __u32 kind)9857{9858	char btf_type_name[BTF_MAX_NAME_SIZE];9859	int ret;9860 9861	ret = snprintf(btf_type_name, sizeof(btf_type_name),9862		       "%s%s", prefix, name);9863	/* snprintf returns the number of characters written excluding the9864	 * terminating null. So, if >= BTF_MAX_NAME_SIZE are written, it9865	 * indicates truncation.9866	 */9867	if (ret < 0 || ret >= sizeof(btf_type_name))9868		return -ENAMETOOLONG;9869	return btf__find_by_name_kind(btf, btf_type_name, kind);9870}9871 9872static inline int find_attach_btf_id(struct btf *btf, const char *name,9873				     enum bpf_attach_type attach_type)9874{9875	const char *prefix;9876	int kind;9877 9878	btf_get_kernel_prefix_kind(attach_type, &prefix, &kind);9879	return find_btf_by_prefix_kind(btf, prefix, name, kind);9880}9881 9882int libbpf_find_vmlinux_btf_id(const char *name,9883			       enum bpf_attach_type attach_type)9884{9885	struct btf *btf;9886	int err;9887 9888	btf = btf__load_vmlinux_btf();9889	err = libbpf_get_error(btf);9890	if (err) {9891		pr_warn("vmlinux BTF is not found\n");9892		return libbpf_err(err);9893	}9894 9895	err = find_attach_btf_id(btf, name, attach_type);9896	if (err <= 0)9897		pr_warn("%s is not found in vmlinux BTF\n", name);9898 9899	btf__free(btf);9900	return libbpf_err(err);9901}9902 9903static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd)9904{9905	struct bpf_prog_info info;9906	__u32 info_len = sizeof(info);9907	struct btf *btf;9908	int err;9909 9910	memset(&info, 0, info_len);9911	err = bpf_prog_get_info_by_fd(attach_prog_fd, &info, &info_len);9912	if (err) {9913		pr_warn("failed bpf_prog_get_info_by_fd for FD %d: %d\n",9914			attach_prog_fd, err);9915		return err;9916	}9917 9918	err = -EINVAL;9919	if (!info.btf_id) {9920		pr_warn("The target program doesn't have BTF\n");9921		goto out;9922	}9923	btf = btf__load_from_kernel_by_id(info.btf_id);9924	err = libbpf_get_error(btf);9925	if (err) {9926		pr_warn("Failed to get BTF %d of the program: %d\n", info.btf_id, err);9927		goto out;9928	}9929	err = btf__find_by_name_kind(btf, name, BTF_KIND_FUNC);9930	btf__free(btf);9931	if (err <= 0) {9932		pr_warn("%s is not found in prog's BTF\n", name);9933		goto out;9934	}9935out:9936	return err;9937}9938 9939static int find_kernel_btf_id(struct bpf_object *obj, const char *attach_name,9940			      enum bpf_attach_type attach_type,9941			      int *btf_obj_fd, int *btf_type_id)9942{9943	int ret, i, mod_len;9944	const char *fn_name, *mod_name = NULL;9945 9946	fn_name = strchr(attach_name, ':');9947	if (fn_name) {9948		mod_name = attach_name;9949		mod_len = fn_name - mod_name;9950		fn_name++;9951	}9952 9953	if (!mod_name || strncmp(mod_name, "vmlinux", mod_len) == 0) {9954		ret = find_attach_btf_id(obj->btf_vmlinux,9955					 mod_name ? fn_name : attach_name,9956					 attach_type);9957		if (ret > 0) {9958			*btf_obj_fd = 0; /* vmlinux BTF */9959			*btf_type_id = ret;9960			return 0;9961		}9962		if (ret != -ENOENT)9963			return ret;9964	}9965 9966	ret = load_module_btfs(obj);9967	if (ret)9968		return ret;9969 9970	for (i = 0; i < obj->btf_module_cnt; i++) {9971		const struct module_btf *mod = &obj->btf_modules[i];9972 9973		if (mod_name && strncmp(mod->name, mod_name, mod_len) != 0)9974			continue;9975 9976		ret = find_attach_btf_id(mod->btf,9977					 mod_name ? fn_name : attach_name,9978					 attach_type);9979		if (ret > 0) {9980			*btf_obj_fd = mod->fd;9981			*btf_type_id = ret;9982			return 0;9983		}9984		if (ret == -ENOENT)9985			continue;9986 9987		return ret;9988	}9989 9990	return -ESRCH;9991}9992 9993static int libbpf_find_attach_btf_id(struct bpf_program *prog, const char *attach_name,9994				     int *btf_obj_fd, int *btf_type_id)9995{9996	enum bpf_attach_type attach_type = prog->expected_attach_type;9997	__u32 attach_prog_fd = prog->attach_prog_fd;9998	int err = 0;9999 10000	/* BPF program's BTF ID */10001	if (prog->type == BPF_PROG_TYPE_EXT || attach_prog_fd) {10002		if (!attach_prog_fd) {10003			pr_warn("prog '%s': attach program FD is not set\n", prog->name);10004			return -EINVAL;10005		}10006		err = libbpf_find_prog_btf_id(attach_name, attach_prog_fd);10007		if (err < 0) {10008			pr_warn("prog '%s': failed to find BPF program (FD %d) BTF ID for '%s': %d\n",10009				 prog->name, attach_prog_fd, attach_name, err);10010			return err;10011		}10012		*btf_obj_fd = 0;10013		*btf_type_id = err;10014		return 0;10015	}10016 10017	/* kernel/module BTF ID */10018	if (prog->obj->gen_loader) {10019		bpf_gen__record_attach_target(prog->obj->gen_loader, attach_name, attach_type);10020		*btf_obj_fd = 0;10021		*btf_type_id = 1;10022	} else {10023		err = find_kernel_btf_id(prog->obj, attach_name,10024					 attach_type, btf_obj_fd,10025					 btf_type_id);10026	}10027	if (err) {10028		pr_warn("prog '%s': failed to find kernel BTF type ID of '%s': %d\n",10029			prog->name, attach_name, err);10030		return err;10031	}10032	return 0;10033}10034 10035int libbpf_attach_type_by_name(const char *name,10036			       enum bpf_attach_type *attach_type)10037{10038	char *type_names;10039	const struct bpf_sec_def *sec_def;10040 10041	if (!name)10042		return libbpf_err(-EINVAL);10043 10044	sec_def = find_sec_def(name);10045	if (!sec_def) {10046		pr_debug("failed to guess attach type based on ELF section name '%s'\n", name);10047		type_names = libbpf_get_type_names(true);10048		if (type_names != NULL) {10049			pr_debug("attachable section(type) names are:%s\n", type_names);10050			free(type_names);10051		}10052 10053		return libbpf_err(-EINVAL);10054	}10055 10056	if (sec_def->prog_prepare_load_fn != libbpf_prepare_prog_load)10057		return libbpf_err(-EINVAL);10058	if (!(sec_def->cookie & SEC_ATTACHABLE))10059		return libbpf_err(-EINVAL);10060 10061	*attach_type = sec_def->expected_attach_type;10062	return 0;10063}10064 10065int bpf_map__fd(const struct bpf_map *map)10066{10067	if (!map)10068		return libbpf_err(-EINVAL);10069	if (!map_is_created(map))10070		return -1;10071	return map->fd;10072}10073 10074static bool map_uses_real_name(const struct bpf_map *map)10075{10076	/* Since libbpf started to support custom .data.* and .rodata.* maps,10077	 * their user-visible name differs from kernel-visible name. Users see10078	 * such map's corresponding ELF section name as a map name.10079	 * This check distinguishes .data/.rodata from .data.* and .rodata.*10080	 * maps to know which name has to be returned to the user.10081	 */10082	if (map->libbpf_type == LIBBPF_MAP_DATA && strcmp(map->real_name, DATA_SEC) != 0)10083		return true;10084	if (map->libbpf_type == LIBBPF_MAP_RODATA && strcmp(map->real_name, RODATA_SEC) != 0)10085		return true;10086	return false;10087}10088 10089const char *bpf_map__name(const struct bpf_map *map)10090{10091	if (!map)10092		return NULL;10093 10094	if (map_uses_real_name(map))10095		return map->real_name;10096 10097	return map->name;10098}10099 10100enum bpf_map_type bpf_map__type(const struct bpf_map *map)10101{10102	return map->def.type;10103}10104 10105int bpf_map__set_type(struct bpf_map *map, enum bpf_map_type type)10106{10107	if (map_is_created(map))10108		return libbpf_err(-EBUSY);10109	map->def.type = type;10110	return 0;10111}10112 10113__u32 bpf_map__map_flags(const struct bpf_map *map)10114{10115	return map->def.map_flags;10116}10117 10118int bpf_map__set_map_flags(struct bpf_map *map, __u32 flags)10119{10120	if (map_is_created(map))10121		return libbpf_err(-EBUSY);10122	map->def.map_flags = flags;10123	return 0;10124}10125 10126__u64 bpf_map__map_extra(const struct bpf_map *map)10127{10128	return map->map_extra;10129}10130 10131int bpf_map__set_map_extra(struct bpf_map *map, __u64 map_extra)10132{10133	if (map_is_created(map))10134		return libbpf_err(-EBUSY);10135	map->map_extra = map_extra;10136	return 0;10137}10138 10139__u32 bpf_map__numa_node(const struct bpf_map *map)10140{10141	return map->numa_node;10142}10143 10144int bpf_map__set_numa_node(struct bpf_map *map, __u32 numa_node)10145{10146	if (map_is_created(map))10147		return libbpf_err(-EBUSY);10148	map->numa_node = numa_node;10149	return 0;10150}10151 10152__u32 bpf_map__key_size(const struct bpf_map *map)10153{10154	return map->def.key_size;10155}10156 10157int bpf_map__set_key_size(struct bpf_map *map, __u32 size)10158{10159	if (map_is_created(map))10160		return libbpf_err(-EBUSY);10161	map->def.key_size = size;10162	return 0;10163}10164 10165__u32 bpf_map__value_size(const struct bpf_map *map)10166{10167	return map->def.value_size;10168}10169 10170static int map_btf_datasec_resize(struct bpf_map *map, __u32 size)10171{10172	struct btf *btf;10173	struct btf_type *datasec_type, *var_type;10174	struct btf_var_secinfo *var;10175	const struct btf_type *array_type;10176	const struct btf_array *array;10177	int vlen, element_sz, new_array_id;10178	__u32 nr_elements;10179 10180	/* check btf existence */10181	btf = bpf_object__btf(map->obj);10182	if (!btf)10183		return -ENOENT;10184 10185	/* verify map is datasec */10186	datasec_type = btf_type_by_id(btf, bpf_map__btf_value_type_id(map));10187	if (!btf_is_datasec(datasec_type)) {10188		pr_warn("map '%s': cannot be resized, map value type is not a datasec\n",10189			bpf_map__name(map));10190		return -EINVAL;10191	}10192 10193	/* verify datasec has at least one var */10194	vlen = btf_vlen(datasec_type);10195	if (vlen == 0) {10196		pr_warn("map '%s': cannot be resized, map value datasec is empty\n",10197			bpf_map__name(map));10198		return -EINVAL;10199	}10200 10201	/* verify last var in the datasec is an array */10202	var = &btf_var_secinfos(datasec_type)[vlen - 1];10203	var_type = btf_type_by_id(btf, var->type);10204	array_type = skip_mods_and_typedefs(btf, var_type->type, NULL);10205	if (!btf_is_array(array_type)) {10206		pr_warn("map '%s': cannot be resized, last var must be an array\n",10207			bpf_map__name(map));10208		return -EINVAL;10209	}10210 10211	/* verify request size aligns with array */10212	array = btf_array(array_type);10213	element_sz = btf__resolve_size(btf, array->type);10214	if (element_sz <= 0 || (size - var->offset) % element_sz != 0) {10215		pr_warn("map '%s': cannot be resized, element size (%d) doesn't align with new total size (%u)\n",10216			bpf_map__name(map), element_sz, size);10217		return -EINVAL;10218	}10219 10220	/* create a new array based on the existing array, but with new length */10221	nr_elements = (size - var->offset) / element_sz;10222	new_array_id = btf__add_array(btf, array->index_type, array->type, nr_elements);10223	if (new_array_id < 0)10224		return new_array_id;10225 10226	/* adding a new btf type invalidates existing pointers to btf objects,10227	 * so refresh pointers before proceeding10228	 */10229	datasec_type = btf_type_by_id(btf, map->btf_value_type_id);10230	var = &btf_var_secinfos(datasec_type)[vlen - 1];10231	var_type = btf_type_by_id(btf, var->type);10232 10233	/* finally update btf info */10234	datasec_type->size = size;10235	var->size = size - var->offset;10236	var_type->type = new_array_id;10237 10238	return 0;10239}10240 10241int bpf_map__set_value_size(struct bpf_map *map, __u32 size)10242{10243	if (map->obj->loaded || map->reused)10244		return libbpf_err(-EBUSY);10245 10246	if (map->mmaped) {10247		size_t mmap_old_sz, mmap_new_sz;10248		int err;10249 10250		if (map->def.type != BPF_MAP_TYPE_ARRAY)10251			return -EOPNOTSUPP;10252 10253		mmap_old_sz = bpf_map_mmap_sz(map);10254		mmap_new_sz = array_map_mmap_sz(size, map->def.max_entries);10255		err = bpf_map_mmap_resize(map, mmap_old_sz, mmap_new_sz);10256		if (err) {10257			pr_warn("map '%s': failed to resize memory-mapped region: %d\n",10258				bpf_map__name(map), err);10259			return err;10260		}10261		err = map_btf_datasec_resize(map, size);10262		if (err && err != -ENOENT) {10263			pr_warn("map '%s': failed to adjust resized BTF, clearing BTF key/value info: %d\n",10264				bpf_map__name(map), err);10265			map->btf_value_type_id = 0;10266			map->btf_key_type_id = 0;10267		}10268	}10269 10270	map->def.value_size = size;10271	return 0;10272}10273 10274__u32 bpf_map__btf_key_type_id(const struct bpf_map *map)10275{10276	return map ? map->btf_key_type_id : 0;10277}10278 10279__u32 bpf_map__btf_value_type_id(const struct bpf_map *map)10280{10281	return map ? map->btf_value_type_id : 0;10282}10283 10284int bpf_map__set_initial_value(struct bpf_map *map,10285			       const void *data, size_t size)10286{10287	size_t actual_sz;10288 10289	if (map->obj->loaded || map->reused)10290		return libbpf_err(-EBUSY);10291 10292	if (!map->mmaped || map->libbpf_type == LIBBPF_MAP_KCONFIG)10293		return libbpf_err(-EINVAL);10294 10295	if (map->def.type == BPF_MAP_TYPE_ARENA)10296		actual_sz = map->obj->arena_data_sz;10297	else10298		actual_sz = map->def.value_size;10299	if (size != actual_sz)10300		return libbpf_err(-EINVAL);10301 10302	memcpy(map->mmaped, data, size);10303	return 0;10304}10305 10306void *bpf_map__initial_value(const struct bpf_map *map, size_t *psize)10307{10308	if (bpf_map__is_struct_ops(map)) {10309		if (psize)10310			*psize = map->def.value_size;10311		return map->st_ops->data;10312	}10313 10314	if (!map->mmaped)10315		return NULL;10316 10317	if (map->def.type == BPF_MAP_TYPE_ARENA)10318		*psize = map->obj->arena_data_sz;10319	else10320		*psize = map->def.value_size;10321 10322	return map->mmaped;10323}10324 10325bool bpf_map__is_internal(const struct bpf_map *map)10326{10327	return map->libbpf_type != LIBBPF_MAP_UNSPEC;10328}10329 10330__u32 bpf_map__ifindex(const struct bpf_map *map)10331{10332	return map->map_ifindex;10333}10334 10335int bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex)10336{10337	if (map_is_created(map))10338		return libbpf_err(-EBUSY);10339	map->map_ifindex = ifindex;10340	return 0;10341}10342 10343int bpf_map__set_inner_map_fd(struct bpf_map *map, int fd)10344{10345	if (!bpf_map_type__is_map_in_map(map->def.type)) {10346		pr_warn("error: unsupported map type\n");10347		return libbpf_err(-EINVAL);10348	}10349	if (map->inner_map_fd != -1) {10350		pr_warn("error: inner_map_fd already specified\n");10351		return libbpf_err(-EINVAL);10352	}10353	if (map->inner_map) {10354		bpf_map__destroy(map->inner_map);10355		zfree(&map->inner_map);10356	}10357	map->inner_map_fd = fd;10358	return 0;10359}10360 10361static struct bpf_map *10362__bpf_map__iter(const struct bpf_map *m, const struct bpf_object *obj, int i)10363{10364	ssize_t idx;10365	struct bpf_map *s, *e;10366 10367	if (!obj || !obj->maps)10368		return errno = EINVAL, NULL;10369 10370	s = obj->maps;10371	e = obj->maps + obj->nr_maps;10372 10373	if ((m < s) || (m >= e)) {10374		pr_warn("error in %s: map handler doesn't belong to object\n",10375			 __func__);10376		return errno = EINVAL, NULL;10377	}10378 10379	idx = (m - obj->maps) + i;10380	if (idx >= obj->nr_maps || idx < 0)10381		return NULL;10382	return &obj->maps[idx];10383}10384 10385struct bpf_map *10386bpf_object__next_map(const struct bpf_object *obj, const struct bpf_map *prev)10387{10388	if (prev == NULL && obj != NULL)10389		return obj->maps;10390 10391	return __bpf_map__iter(prev, obj, 1);10392}10393 10394struct bpf_map *10395bpf_object__prev_map(const struct bpf_object *obj, const struct bpf_map *next)10396{10397	if (next == NULL && obj != NULL) {10398		if (!obj->nr_maps)10399			return NULL;10400		return obj->maps + obj->nr_maps - 1;10401	}10402 10403	return __bpf_map__iter(next, obj, -1);10404}10405 10406struct bpf_map *10407bpf_object__find_map_by_name(const struct bpf_object *obj, const char *name)10408{10409	struct bpf_map *pos;10410 10411	bpf_object__for_each_map(pos, obj) {10412		/* if it's a special internal map name (which always starts10413		 * with dot) then check if that special name matches the10414		 * real map name (ELF section name)10415		 */10416		if (name[0] == '.') {10417			if (pos->real_name && strcmp(pos->real_name, name) == 0)10418				return pos;10419			continue;10420		}10421		/* otherwise map name has to be an exact match */10422		if (map_uses_real_name(pos)) {10423			if (strcmp(pos->real_name, name) == 0)10424				return pos;10425			continue;10426		}10427		if (strcmp(pos->name, name) == 0)10428			return pos;10429	}10430	return errno = ENOENT, NULL;10431}10432 10433int10434bpf_object__find_map_fd_by_name(const struct bpf_object *obj, const char *name)10435{10436	return bpf_map__fd(bpf_object__find_map_by_name(obj, name));10437}10438 10439static int validate_map_op(const struct bpf_map *map, size_t key_sz,10440			   size_t value_sz, bool check_value_sz)10441{10442	if (!map_is_created(map)) /* map is not yet created */10443		return -ENOENT;10444 10445	if (map->def.key_size != key_sz) {10446		pr_warn("map '%s': unexpected key size %zu provided, expected %u\n",10447			map->name, key_sz, map->def.key_size);10448		return -EINVAL;10449	}10450 10451	if (map->fd < 0) {10452		pr_warn("map '%s': can't use BPF map without FD (was it created?)\n", map->name);10453		return -EINVAL;10454	}10455 10456	if (!check_value_sz)10457		return 0;10458 10459	switch (map->def.type) {10460	case BPF_MAP_TYPE_PERCPU_ARRAY:10461	case BPF_MAP_TYPE_PERCPU_HASH:10462	case BPF_MAP_TYPE_LRU_PERCPU_HASH:10463	case BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE: {10464		int num_cpu = libbpf_num_possible_cpus();10465		size_t elem_sz = roundup(map->def.value_size, 8);10466 10467		if (value_sz != num_cpu * elem_sz) {10468			pr_warn("map '%s': unexpected value size %zu provided for per-CPU map, expected %d * %zu = %zd\n",10469				map->name, value_sz, num_cpu, elem_sz, num_cpu * elem_sz);10470			return -EINVAL;10471		}10472		break;10473	}10474	default:10475		if (map->def.value_size != value_sz) {10476			pr_warn("map '%s': unexpected value size %zu provided, expected %u\n",10477				map->name, value_sz, map->def.value_size);10478			return -EINVAL;10479		}10480		break;10481	}10482	return 0;10483}10484 10485int bpf_map__lookup_elem(const struct bpf_map *map,10486			 const void *key, size_t key_sz,10487			 void *value, size_t value_sz, __u64 flags)10488{10489	int err;10490 10491	err = validate_map_op(map, key_sz, value_sz, true);10492	if (err)10493		return libbpf_err(err);10494 10495	return bpf_map_lookup_elem_flags(map->fd, key, value, flags);10496}10497 10498int bpf_map__update_elem(const struct bpf_map *map,10499			 const void *key, size_t key_sz,10500			 const void *value, size_t value_sz, __u64 flags)10501{10502	int err;10503 10504	err = validate_map_op(map, key_sz, value_sz, true);10505	if (err)10506		return libbpf_err(err);10507 10508	return bpf_map_update_elem(map->fd, key, value, flags);10509}10510 10511int bpf_map__delete_elem(const struct bpf_map *map,10512			 const void *key, size_t key_sz, __u64 flags)10513{10514	int err;10515 10516	err = validate_map_op(map, key_sz, 0, false /* check_value_sz */);10517	if (err)10518		return libbpf_err(err);10519 10520	return bpf_map_delete_elem_flags(map->fd, key, flags);10521}10522 10523int bpf_map__lookup_and_delete_elem(const struct bpf_map *map,10524				    const void *key, size_t key_sz,10525				    void *value, size_t value_sz, __u64 flags)10526{10527	int err;10528 10529	err = validate_map_op(map, key_sz, value_sz, true);10530	if (err)10531		return libbpf_err(err);10532 10533	return bpf_map_lookup_and_delete_elem_flags(map->fd, key, value, flags);10534}10535 10536int bpf_map__get_next_key(const struct bpf_map *map,10537			  const void *cur_key, void *next_key, size_t key_sz)10538{10539	int err;10540 10541	err = validate_map_op(map, key_sz, 0, false /* check_value_sz */);10542	if (err)10543		return libbpf_err(err);10544 10545	return bpf_map_get_next_key(map->fd, cur_key, next_key);10546}10547 10548long libbpf_get_error(const void *ptr)10549{10550	if (!IS_ERR_OR_NULL(ptr))10551		return 0;10552 10553	if (IS_ERR(ptr))10554		errno = -PTR_ERR(ptr);10555 10556	/* If ptr == NULL, then errno should be already set by the failing10557	 * API, because libbpf never returns NULL on success and it now always10558	 * sets errno on error. So no extra errno handling for ptr == NULL10559	 * case.10560	 */10561	return -errno;10562}10563 10564/* Replace link's underlying BPF program with the new one */10565int bpf_link__update_program(struct bpf_link *link, struct bpf_program *prog)10566{10567	int ret;10568	int prog_fd = bpf_program__fd(prog);10569 10570	if (prog_fd < 0) {10571		pr_warn("prog '%s': can't use BPF program without FD (was it loaded?)\n",10572			prog->name);10573		return libbpf_err(-EINVAL);10574	}10575 10576	ret = bpf_link_update(bpf_link__fd(link), prog_fd, NULL);10577	return libbpf_err_errno(ret);10578}10579 10580/* Release "ownership" of underlying BPF resource (typically, BPF program10581 * attached to some BPF hook, e.g., tracepoint, kprobe, etc). Disconnected10582 * link, when destructed through bpf_link__destroy() call won't attempt to10583 * detach/unregisted that BPF resource. This is useful in situations where,10584 * say, attached BPF program has to outlive userspace program that attached it10585 * in the system. Depending on type of BPF program, though, there might be10586 * additional steps (like pinning BPF program in BPF FS) necessary to ensure10587 * exit of userspace program doesn't trigger automatic detachment and clean up10588 * inside the kernel.10589 */10590void bpf_link__disconnect(struct bpf_link *link)10591{10592	link->disconnected = true;10593}10594 10595int bpf_link__destroy(struct bpf_link *link)10596{10597	int err = 0;10598 10599	if (IS_ERR_OR_NULL(link))10600		return 0;10601 10602	if (!link->disconnected && link->detach)10603		err = link->detach(link);10604	if (link->pin_path)10605		free(link->pin_path);10606	if (link->dealloc)10607		link->dealloc(link);10608	else10609		free(link);10610 10611	return libbpf_err(err);10612}10613 10614int bpf_link__fd(const struct bpf_link *link)10615{10616	return link->fd;10617}10618 10619const char *bpf_link__pin_path(const struct bpf_link *link)10620{10621	return link->pin_path;10622}10623 10624static int bpf_link__detach_fd(struct bpf_link *link)10625{10626	return libbpf_err_errno(close(link->fd));10627}10628 10629struct bpf_link *bpf_link__open(const char *path)10630{10631	struct bpf_link *link;10632	int fd;10633 10634	fd = bpf_obj_get(path);10635	if (fd < 0) {10636		fd = -errno;10637		pr_warn("failed to open link at %s: %d\n", path, fd);10638		return libbpf_err_ptr(fd);10639	}10640 10641	link = calloc(1, sizeof(*link));10642	if (!link) {10643		close(fd);10644		return libbpf_err_ptr(-ENOMEM);10645	}10646	link->detach = &bpf_link__detach_fd;10647	link->fd = fd;10648 10649	link->pin_path = strdup(path);10650	if (!link->pin_path) {10651		bpf_link__destroy(link);10652		return libbpf_err_ptr(-ENOMEM);10653	}10654 10655	return link;10656}10657 10658int bpf_link__detach(struct bpf_link *link)10659{10660	return bpf_link_detach(link->fd) ? -errno : 0;10661}10662 10663int bpf_link__pin(struct bpf_link *link, const char *path)10664{10665	int err;10666 10667	if (link->pin_path)10668		return libbpf_err(-EBUSY);10669	err = make_parent_dir(path);10670	if (err)10671		return libbpf_err(err);10672	err = check_path(path);10673	if (err)10674		return libbpf_err(err);10675 10676	link->pin_path = strdup(path);10677	if (!link->pin_path)10678		return libbpf_err(-ENOMEM);10679 10680	if (bpf_obj_pin(link->fd, link->pin_path)) {10681		err = -errno;10682		zfree(&link->pin_path);10683		return libbpf_err(err);10684	}10685 10686	pr_debug("link fd=%d: pinned at %s\n", link->fd, link->pin_path);10687	return 0;10688}10689 10690int bpf_link__unpin(struct bpf_link *link)10691{10692	int err;10693 10694	if (!link->pin_path)10695		return libbpf_err(-EINVAL);10696 10697	err = unlink(link->pin_path);10698	if (err != 0)10699		return -errno;10700 10701	pr_debug("link fd=%d: unpinned from %s\n", link->fd, link->pin_path);10702	zfree(&link->pin_path);10703	return 0;10704}10705 10706struct bpf_link_perf {10707	struct bpf_link link;10708	int perf_event_fd;10709	/* legacy kprobe support: keep track of probe identifier and type */10710	char *legacy_probe_name;10711	bool legacy_is_kprobe;10712	bool legacy_is_retprobe;10713};10714 10715static int remove_kprobe_event_legacy(const char *probe_name, bool retprobe);10716static int remove_uprobe_event_legacy(const char *probe_name, bool retprobe);10717 10718static int bpf_link_perf_detach(struct bpf_link *link)10719{10720	struct bpf_link_perf *perf_link = container_of(link, struct bpf_link_perf, link);10721	int err = 0;10722 10723	if (ioctl(perf_link->perf_event_fd, PERF_EVENT_IOC_DISABLE, 0) < 0)10724		err = -errno;10725 10726	if (perf_link->perf_event_fd != link->fd)10727		close(perf_link->perf_event_fd);10728	close(link->fd);10729 10730	/* legacy uprobe/kprobe needs to be removed after perf event fd closure */10731	if (perf_link->legacy_probe_name) {10732		if (perf_link->legacy_is_kprobe) {10733			err = remove_kprobe_event_legacy(perf_link->legacy_probe_name,10734							 perf_link->legacy_is_retprobe);10735		} else {10736			err = remove_uprobe_event_legacy(perf_link->legacy_probe_name,10737							 perf_link->legacy_is_retprobe);10738		}10739	}10740 10741	return err;10742}10743 10744static void bpf_link_perf_dealloc(struct bpf_link *link)10745{10746	struct bpf_link_perf *perf_link = container_of(link, struct bpf_link_perf, link);10747 10748	free(perf_link->legacy_probe_name);10749	free(perf_link);10750}10751 10752struct bpf_link *bpf_program__attach_perf_event_opts(const struct bpf_program *prog, int pfd,10753						     const struct bpf_perf_event_opts *opts)10754{10755	char errmsg[STRERR_BUFSIZE];10756	struct bpf_link_perf *link;10757	int prog_fd, link_fd = -1, err;10758	bool force_ioctl_attach;10759 10760	if (!OPTS_VALID(opts, bpf_perf_event_opts))10761		return libbpf_err_ptr(-EINVAL);10762 10763	if (pfd < 0) {10764		pr_warn("prog '%s': invalid perf event FD %d\n",10765			prog->name, pfd);10766		return libbpf_err_ptr(-EINVAL);10767	}10768	prog_fd = bpf_program__fd(prog);10769	if (prog_fd < 0) {10770		pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",10771			prog->name);10772		return libbpf_err_ptr(-EINVAL);10773	}10774 10775	link = calloc(1, sizeof(*link));10776	if (!link)10777		return libbpf_err_ptr(-ENOMEM);10778	link->link.detach = &bpf_link_perf_detach;10779	link->link.dealloc = &bpf_link_perf_dealloc;10780	link->perf_event_fd = pfd;10781 10782	force_ioctl_attach = OPTS_GET(opts, force_ioctl_attach, false);10783	if (kernel_supports(prog->obj, FEAT_PERF_LINK) && !force_ioctl_attach) {10784		DECLARE_LIBBPF_OPTS(bpf_link_create_opts, link_opts,10785			.perf_event.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0));10786 10787		link_fd = bpf_link_create(prog_fd, pfd, BPF_PERF_EVENT, &link_opts);10788		if (link_fd < 0) {10789			err = -errno;10790			pr_warn("prog '%s': failed to create BPF link for perf_event FD %d: %d (%s)\n",10791				prog->name, pfd,10792				err, libbpf_strerror_r(err, errmsg, sizeof(errmsg)));10793			goto err_out;10794		}10795		link->link.fd = link_fd;10796	} else {10797		if (OPTS_GET(opts, bpf_cookie, 0)) {10798			pr_warn("prog '%s': user context value is not supported\n", prog->name);10799			err = -EOPNOTSUPP;10800			goto err_out;10801		}10802 10803		if (ioctl(pfd, PERF_EVENT_IOC_SET_BPF, prog_fd) < 0) {10804			err = -errno;10805			pr_warn("prog '%s': failed to attach to perf_event FD %d: %s\n",10806				prog->name, pfd, libbpf_strerror_r(err, errmsg, sizeof(errmsg)));10807			if (err == -EPROTO)10808				pr_warn("prog '%s': try add PERF_SAMPLE_CALLCHAIN to or remove exclude_callchain_[kernel|user] from pfd %d\n",10809					prog->name, pfd);10810			goto err_out;10811		}10812		link->link.fd = pfd;10813	}10814	if (ioctl(pfd, PERF_EVENT_IOC_ENABLE, 0) < 0) {10815		err = -errno;10816		pr_warn("prog '%s': failed to enable perf_event FD %d: %s\n",10817			prog->name, pfd, libbpf_strerror_r(err, errmsg, sizeof(errmsg)));10818		goto err_out;10819	}10820 10821	return &link->link;10822err_out:10823	if (link_fd >= 0)10824		close(link_fd);10825	free(link);10826	return libbpf_err_ptr(err);10827}10828 10829struct bpf_link *bpf_program__attach_perf_event(const struct bpf_program *prog, int pfd)10830{10831	return bpf_program__attach_perf_event_opts(prog, pfd, NULL);10832}10833 10834/*10835 * this function is expected to parse integer in the range of [0, 2^31-1] from10836 * given file using scanf format string fmt. If actual parsed value is10837 * negative, the result might be indistinguishable from error10838 */10839static int parse_uint_from_file(const char *file, const char *fmt)10840{10841	char buf[STRERR_BUFSIZE];10842	int err, ret;10843	FILE *f;10844 10845	f = fopen(file, "re");10846	if (!f) {10847		err = -errno;10848		pr_debug("failed to open '%s': %s\n", file,10849			 libbpf_strerror_r(err, buf, sizeof(buf)));10850		return err;10851	}10852	err = fscanf(f, fmt, &ret);10853	if (err != 1) {10854		err = err == EOF ? -EIO : -errno;10855		pr_debug("failed to parse '%s': %s\n", file,10856			libbpf_strerror_r(err, buf, sizeof(buf)));10857		fclose(f);10858		return err;10859	}10860	fclose(f);10861	return ret;10862}10863 10864static int determine_kprobe_perf_type(void)10865{10866	const char *file = "/sys/bus/event_source/devices/kprobe/type";10867 10868	return parse_uint_from_file(file, "%d\n");10869}10870 10871static int determine_uprobe_perf_type(void)10872{10873	const char *file = "/sys/bus/event_source/devices/uprobe/type";10874 10875	return parse_uint_from_file(file, "%d\n");10876}10877 10878static int determine_kprobe_retprobe_bit(void)10879{10880	const char *file = "/sys/bus/event_source/devices/kprobe/format/retprobe";10881 10882	return parse_uint_from_file(file, "config:%d\n");10883}10884 10885static int determine_uprobe_retprobe_bit(void)10886{10887	const char *file = "/sys/bus/event_source/devices/uprobe/format/retprobe";10888 10889	return parse_uint_from_file(file, "config:%d\n");10890}10891 10892#define PERF_UPROBE_REF_CTR_OFFSET_BITS 3210893#define PERF_UPROBE_REF_CTR_OFFSET_SHIFT 3210894 10895static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,10896				 uint64_t offset, int pid, size_t ref_ctr_off)10897{10898	const size_t attr_sz = sizeof(struct perf_event_attr);10899	struct perf_event_attr attr;10900	char errmsg[STRERR_BUFSIZE];10901	int type, pfd;10902 10903	if ((__u64)ref_ctr_off >= (1ULL << PERF_UPROBE_REF_CTR_OFFSET_BITS))10904		return -EINVAL;10905 10906	memset(&attr, 0, attr_sz);10907 10908	type = uprobe ? determine_uprobe_perf_type()10909		      : determine_kprobe_perf_type();10910	if (type < 0) {10911		pr_warn("failed to determine %s perf type: %s\n",10912			uprobe ? "uprobe" : "kprobe",10913			libbpf_strerror_r(type, errmsg, sizeof(errmsg)));10914		return type;10915	}10916	if (retprobe) {10917		int bit = uprobe ? determine_uprobe_retprobe_bit()10918				 : determine_kprobe_retprobe_bit();10919 10920		if (bit < 0) {10921			pr_warn("failed to determine %s retprobe bit: %s\n",10922				uprobe ? "uprobe" : "kprobe",10923				libbpf_strerror_r(bit, errmsg, sizeof(errmsg)));10924			return bit;10925		}10926		attr.config |= 1 << bit;10927	}10928	attr.size = attr_sz;10929	attr.type = type;10930	attr.config |= (__u64)ref_ctr_off << PERF_UPROBE_REF_CTR_OFFSET_SHIFT;10931	attr.config1 = ptr_to_u64(name); /* kprobe_func or uprobe_path */10932	attr.config2 = offset;		 /* kprobe_addr or probe_offset */10933 10934	/* pid filter is meaningful only for uprobes */10935	pfd = syscall(__NR_perf_event_open, &attr,10936		      pid < 0 ? -1 : pid /* pid */,10937		      pid == -1 ? 0 : -1 /* cpu */,10938		      -1 /* group_fd */, PERF_FLAG_FD_CLOEXEC);10939	return pfd >= 0 ? pfd : -errno;10940}10941 10942static int append_to_file(const char *file, const char *fmt, ...)10943{10944	int fd, n, err = 0;10945	va_list ap;10946	char buf[1024];10947 10948	va_start(ap, fmt);10949	n = vsnprintf(buf, sizeof(buf), fmt, ap);10950	va_end(ap);10951 10952	if (n < 0 || n >= sizeof(buf))10953		return -EINVAL;10954 10955	fd = open(file, O_WRONLY | O_APPEND | O_CLOEXEC, 0);10956	if (fd < 0)10957		return -errno;10958 10959	if (write(fd, buf, n) < 0)10960		err = -errno;10961 10962	close(fd);10963	return err;10964}10965 10966#define DEBUGFS "/sys/kernel/debug/tracing"10967#define TRACEFS "/sys/kernel/tracing"10968 10969static bool use_debugfs(void)10970{10971	static int has_debugfs = -1;10972 10973	if (has_debugfs < 0)10974		has_debugfs = faccessat(AT_FDCWD, DEBUGFS, F_OK, AT_EACCESS) == 0;10975 10976	return has_debugfs == 1;10977}10978 10979static const char *tracefs_path(void)10980{10981	return use_debugfs() ? DEBUGFS : TRACEFS;10982}10983 10984static const char *tracefs_kprobe_events(void)10985{10986	return use_debugfs() ? DEBUGFS"/kprobe_events" : TRACEFS"/kprobe_events";10987}10988 10989static const char *tracefs_uprobe_events(void)10990{10991	return use_debugfs() ? DEBUGFS"/uprobe_events" : TRACEFS"/uprobe_events";10992}10993 10994static const char *tracefs_available_filter_functions(void)10995{10996	return use_debugfs() ? DEBUGFS"/available_filter_functions"10997			     : TRACEFS"/available_filter_functions";10998}10999 11000static const char *tracefs_available_filter_functions_addrs(void)11001{11002	return use_debugfs() ? DEBUGFS"/available_filter_functions_addrs"11003			     : TRACEFS"/available_filter_functions_addrs";11004}11005 11006static void gen_kprobe_legacy_event_name(char *buf, size_t buf_sz,11007					 const char *kfunc_name, size_t offset)11008{11009	static int index = 0;11010	int i;11011 11012	snprintf(buf, buf_sz, "libbpf_%u_%s_0x%zx_%d", getpid(), kfunc_name, offset,11013		 __sync_fetch_and_add(&index, 1));11014 11015	/* sanitize binary_path in the probe name */11016	for (i = 0; buf[i]; i++) {11017		if (!isalnum(buf[i]))11018			buf[i] = '_';11019	}11020}11021 11022static int add_kprobe_event_legacy(const char *probe_name, bool retprobe,11023				   const char *kfunc_name, size_t offset)11024{11025	return append_to_file(tracefs_kprobe_events(), "%c:%s/%s %s+0x%zx",11026			      retprobe ? 'r' : 'p',11027			      retprobe ? "kretprobes" : "kprobes",11028			      probe_name, kfunc_name, offset);11029}11030 11031static int remove_kprobe_event_legacy(const char *probe_name, bool retprobe)11032{11033	return append_to_file(tracefs_kprobe_events(), "-:%s/%s",11034			      retprobe ? "kretprobes" : "kprobes", probe_name);11035}11036 11037static int determine_kprobe_perf_type_legacy(const char *probe_name, bool retprobe)11038{11039	char file[256];11040 11041	snprintf(file, sizeof(file), "%s/events/%s/%s/id",11042		 tracefs_path(), retprobe ? "kretprobes" : "kprobes", probe_name);11043 11044	return parse_uint_from_file(file, "%d\n");11045}11046 11047static int perf_event_kprobe_open_legacy(const char *probe_name, bool retprobe,11048					 const char *kfunc_name, size_t offset, int pid)11049{11050	const size_t attr_sz = sizeof(struct perf_event_attr);11051	struct perf_event_attr attr;11052	char errmsg[STRERR_BUFSIZE];11053	int type, pfd, err;11054 11055	err = add_kprobe_event_legacy(probe_name, retprobe, kfunc_name, offset);11056	if (err < 0) {11057		pr_warn("failed to add legacy kprobe event for '%s+0x%zx': %s\n",11058			kfunc_name, offset,11059			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));11060		return err;11061	}11062	type = determine_kprobe_perf_type_legacy(probe_name, retprobe);11063	if (type < 0) {11064		err = type;11065		pr_warn("failed to determine legacy kprobe event id for '%s+0x%zx': %s\n",11066			kfunc_name, offset,11067			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));11068		goto err_clean_legacy;11069	}11070 11071	memset(&attr, 0, attr_sz);11072	attr.size = attr_sz;11073	attr.config = type;11074	attr.type = PERF_TYPE_TRACEPOINT;11075 11076	pfd = syscall(__NR_perf_event_open, &attr,11077		      pid < 0 ? -1 : pid, /* pid */11078		      pid == -1 ? 0 : -1, /* cpu */11079		      -1 /* group_fd */,  PERF_FLAG_FD_CLOEXEC);11080	if (pfd < 0) {11081		err = -errno;11082		pr_warn("legacy kprobe perf_event_open() failed: %s\n",11083			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));11084		goto err_clean_legacy;11085	}11086	return pfd;11087 11088err_clean_legacy:11089	/* Clear the newly added legacy kprobe_event */11090	remove_kprobe_event_legacy(probe_name, retprobe);11091	return err;11092}11093 11094static const char *arch_specific_syscall_pfx(void)11095{11096#if defined(__x86_64__)11097	return "x64";11098#elif defined(__i386__)11099	return "ia32";11100#elif defined(__s390x__)11101	return "s390x";11102#elif defined(__s390__)11103	return "s390";11104#elif defined(__arm__)11105	return "arm";11106#elif defined(__aarch64__)11107	return "arm64";11108#elif defined(__mips__)11109	return "mips";11110#elif defined(__riscv)11111	return "riscv";11112#elif defined(__powerpc__)11113	return "powerpc";11114#elif defined(__powerpc64__)11115	return "powerpc64";11116#else11117	return NULL;11118#endif11119}11120 11121int probe_kern_syscall_wrapper(int token_fd)11122{11123	char syscall_name[64];11124	const char *ksys_pfx;11125 11126	ksys_pfx = arch_specific_syscall_pfx();11127	if (!ksys_pfx)11128		return 0;11129 11130	snprintf(syscall_name, sizeof(syscall_name), "__%s_sys_bpf", ksys_pfx);11131 11132	if (determine_kprobe_perf_type() >= 0) {11133		int pfd;11134 11135		pfd = perf_event_open_probe(false, false, syscall_name, 0, getpid(), 0);11136		if (pfd >= 0)11137			close(pfd);11138 11139		return pfd >= 0 ? 1 : 0;11140	} else { /* legacy mode */11141		char probe_name[128];11142 11143		gen_kprobe_legacy_event_name(probe_name, sizeof(probe_name), syscall_name, 0);11144		if (add_kprobe_event_legacy(probe_name, false, syscall_name, 0) < 0)11145			return 0;11146 11147		(void)remove_kprobe_event_legacy(probe_name, false);11148		return 1;11149	}11150}11151 11152struct bpf_link *11153bpf_program__attach_kprobe_opts(const struct bpf_program *prog,11154				const char *func_name,11155				const struct bpf_kprobe_opts *opts)11156{11157	DECLARE_LIBBPF_OPTS(bpf_perf_event_opts, pe_opts);11158	enum probe_attach_mode attach_mode;11159	char errmsg[STRERR_BUFSIZE];11160	char *legacy_probe = NULL;11161	struct bpf_link *link;11162	size_t offset;11163	bool retprobe, legacy;11164	int pfd, err;11165 11166	if (!OPTS_VALID(opts, bpf_kprobe_opts))11167		return libbpf_err_ptr(-EINVAL);11168 11169	attach_mode = OPTS_GET(opts, attach_mode, PROBE_ATTACH_MODE_DEFAULT);11170	retprobe = OPTS_GET(opts, retprobe, false);11171	offset = OPTS_GET(opts, offset, 0);11172	pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);11173 11174	legacy = determine_kprobe_perf_type() < 0;11175	switch (attach_mode) {11176	case PROBE_ATTACH_MODE_LEGACY:11177		legacy = true;11178		pe_opts.force_ioctl_attach = true;11179		break;11180	case PROBE_ATTACH_MODE_PERF:11181		if (legacy)11182			return libbpf_err_ptr(-ENOTSUP);11183		pe_opts.force_ioctl_attach = true;11184		break;11185	case PROBE_ATTACH_MODE_LINK:11186		if (legacy || !kernel_supports(prog->obj, FEAT_PERF_LINK))11187			return libbpf_err_ptr(-ENOTSUP);11188		break;11189	case PROBE_ATTACH_MODE_DEFAULT:11190		break;11191	default:11192		return libbpf_err_ptr(-EINVAL);11193	}11194 11195	if (!legacy) {11196		pfd = perf_event_open_probe(false /* uprobe */, retprobe,11197					    func_name, offset,11198					    -1 /* pid */, 0 /* ref_ctr_off */);11199	} else {11200		char probe_name[256];11201 11202		gen_kprobe_legacy_event_name(probe_name, sizeof(probe_name),11203					     func_name, offset);11204 11205		legacy_probe = strdup(probe_name);11206		if (!legacy_probe)11207			return libbpf_err_ptr(-ENOMEM);11208 11209		pfd = perf_event_kprobe_open_legacy(legacy_probe, retprobe, func_name,11210						    offset, -1 /* pid */);11211	}11212	if (pfd < 0) {11213		err = -errno;11214		pr_warn("prog '%s': failed to create %s '%s+0x%zx' perf event: %s\n",11215			prog->name, retprobe ? "kretprobe" : "kprobe",11216			func_name, offset,11217			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));11218		goto err_out;11219	}11220	link = bpf_program__attach_perf_event_opts(prog, pfd, &pe_opts);11221	err = libbpf_get_error(link);11222	if (err) {11223		close(pfd);11224		pr_warn("prog '%s': failed to attach to %s '%s+0x%zx': %s\n",11225			prog->name, retprobe ? "kretprobe" : "kprobe",11226			func_name, offset,11227			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));11228		goto err_clean_legacy;11229	}11230	if (legacy) {11231		struct bpf_link_perf *perf_link = container_of(link, struct bpf_link_perf, link);11232 11233		perf_link->legacy_probe_name = legacy_probe;11234		perf_link->legacy_is_kprobe = true;11235		perf_link->legacy_is_retprobe = retprobe;11236	}11237 11238	return link;11239 11240err_clean_legacy:11241	if (legacy)11242		remove_kprobe_event_legacy(legacy_probe, retprobe);11243err_out:11244	free(legacy_probe);11245	return libbpf_err_ptr(err);11246}11247 11248struct bpf_link *bpf_program__attach_kprobe(const struct bpf_program *prog,11249					    bool retprobe,11250					    const char *func_name)11251{11252	DECLARE_LIBBPF_OPTS(bpf_kprobe_opts, opts,11253		.retprobe = retprobe,11254	);11255 11256	return bpf_program__attach_kprobe_opts(prog, func_name, &opts);11257}11258 11259struct bpf_link *bpf_program__attach_ksyscall(const struct bpf_program *prog,11260					      const char *syscall_name,11261					      const struct bpf_ksyscall_opts *opts)11262{11263	LIBBPF_OPTS(bpf_kprobe_opts, kprobe_opts);11264	char func_name[128];11265 11266	if (!OPTS_VALID(opts, bpf_ksyscall_opts))11267		return libbpf_err_ptr(-EINVAL);11268 11269	if (kernel_supports(prog->obj, FEAT_SYSCALL_WRAPPER)) {11270		/* arch_specific_syscall_pfx() should never return NULL here11271		 * because it is guarded by kernel_supports(). However, since11272		 * compiler does not know that we have an explicit conditional11273		 * as well.11274		 */11275		snprintf(func_name, sizeof(func_name), "__%s_sys_%s",11276			 arch_specific_syscall_pfx() ? : "", syscall_name);11277	} else {11278		snprintf(func_name, sizeof(func_name), "__se_sys_%s", syscall_name);11279	}11280 11281	kprobe_opts.retprobe = OPTS_GET(opts, retprobe, false);11282	kprobe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);11283 11284	return bpf_program__attach_kprobe_opts(prog, func_name, &kprobe_opts);11285}11286 11287/* Adapted from perf/util/string.c */11288bool glob_match(const char *str, const char *pat)11289{11290	while (*str && *pat && *pat != '*') {11291		if (*pat == '?') {      /* Matches any single character */11292			str++;11293			pat++;11294			continue;11295		}11296		if (*str != *pat)11297			return false;11298		str++;11299		pat++;11300	}11301	/* Check wild card */11302	if (*pat == '*') {11303		while (*pat == '*')11304			pat++;11305		if (!*pat) /* Tail wild card matches all */11306			return true;11307		while (*str)11308			if (glob_match(str++, pat))11309				return true;11310	}11311	return !*str && !*pat;11312}11313 11314struct kprobe_multi_resolve {11315	const char *pattern;11316	unsigned long *addrs;11317	size_t cap;11318	size_t cnt;11319};11320 11321struct avail_kallsyms_data {11322	char **syms;11323	size_t cnt;11324	struct kprobe_multi_resolve *res;11325};11326 11327static int avail_func_cmp(const void *a, const void *b)11328{11329	return strcmp(*(const char **)a, *(const char **)b);11330}11331 11332static int avail_kallsyms_cb(unsigned long long sym_addr, char sym_type,11333			     const char *sym_name, void *ctx)11334{11335	struct avail_kallsyms_data *data = ctx;11336	struct kprobe_multi_resolve *res = data->res;11337	int err;11338 11339	if (!bsearch(&sym_name, data->syms, data->cnt, sizeof(*data->syms), avail_func_cmp))11340		return 0;11341 11342	err = libbpf_ensure_mem((void **)&res->addrs, &res->cap, sizeof(*res->addrs), res->cnt + 1);11343	if (err)11344		return err;11345 11346	res->addrs[res->cnt++] = (unsigned long)sym_addr;11347	return 0;11348}11349 11350static int libbpf_available_kallsyms_parse(struct kprobe_multi_resolve *res)11351{11352	const char *available_functions_file = tracefs_available_filter_functions();11353	struct avail_kallsyms_data data;11354	char sym_name[500];11355	FILE *f;11356	int err = 0, ret, i;11357	char **syms = NULL;11358	size_t cap = 0, cnt = 0;11359 11360	f = fopen(available_functions_file, "re");11361	if (!f) {11362		err = -errno;11363		pr_warn("failed to open %s: %d\n", available_functions_file, err);11364		return err;11365	}11366 11367	while (true) {11368		char *name;11369 11370		ret = fscanf(f, "%499s%*[^\n]\n", sym_name);11371		if (ret == EOF && feof(f))11372			break;11373 11374		if (ret != 1) {11375			pr_warn("failed to parse available_filter_functions entry: %d\n", ret);11376			err = -EINVAL;11377			goto cleanup;11378		}11379 11380		if (!glob_match(sym_name, res->pattern))11381			continue;11382 11383		err = libbpf_ensure_mem((void **)&syms, &cap, sizeof(*syms), cnt + 1);11384		if (err)11385			goto cleanup;11386 11387		name = strdup(sym_name);11388		if (!name) {11389			err = -errno;11390			goto cleanup;11391		}11392 11393		syms[cnt++] = name;11394	}11395 11396	/* no entries found, bail out */11397	if (cnt == 0) {11398		err = -ENOENT;11399		goto cleanup;11400	}11401 11402	/* sort available functions */11403	qsort(syms, cnt, sizeof(*syms), avail_func_cmp);11404 11405	data.syms = syms;11406	data.res = res;11407	data.cnt = cnt;11408	libbpf_kallsyms_parse(avail_kallsyms_cb, &data);11409 11410	if (res->cnt == 0)11411		err = -ENOENT;11412 11413cleanup:11414	for (i = 0; i < cnt; i++)11415		free((char *)syms[i]);11416	free(syms);11417 11418	fclose(f);11419	return err;11420}11421 11422static bool has_available_filter_functions_addrs(void)11423{11424	return access(tracefs_available_filter_functions_addrs(), R_OK) != -1;11425}11426 11427static int libbpf_available_kprobes_parse(struct kprobe_multi_resolve *res)11428{11429	const char *available_path = tracefs_available_filter_functions_addrs();11430	char sym_name[500];11431	FILE *f;11432	int ret, err = 0;11433	unsigned long long sym_addr;11434 11435	f = fopen(available_path, "re");11436	if (!f) {11437		err = -errno;11438		pr_warn("failed to open %s: %d\n", available_path, err);11439		return err;11440	}11441 11442	while (true) {11443		ret = fscanf(f, "%llx %499s%*[^\n]\n", &sym_addr, sym_name);11444		if (ret == EOF && feof(f))11445			break;11446 11447		if (ret != 2) {11448			pr_warn("failed to parse available_filter_functions_addrs entry: %d\n",11449				ret);11450			err = -EINVAL;11451			goto cleanup;11452		}11453 11454		if (!glob_match(sym_name, res->pattern))11455			continue;11456 11457		err = libbpf_ensure_mem((void **)&res->addrs, &res->cap,11458					sizeof(*res->addrs), res->cnt + 1);11459		if (err)11460			goto cleanup;11461 11462		res->addrs[res->cnt++] = (unsigned long)sym_addr;11463	}11464 11465	if (res->cnt == 0)11466		err = -ENOENT;11467 11468cleanup:11469	fclose(f);11470	return err;11471}11472 11473struct bpf_link *11474bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,11475				      const char *pattern,11476				      const struct bpf_kprobe_multi_opts *opts)11477{11478	LIBBPF_OPTS(bpf_link_create_opts, lopts);11479	struct kprobe_multi_resolve res = {11480		.pattern = pattern,11481	};11482	enum bpf_attach_type attach_type;11483	struct bpf_link *link = NULL;11484	char errmsg[STRERR_BUFSIZE];11485	const unsigned long *addrs;11486	int err, link_fd, prog_fd;11487	bool retprobe, session;11488	const __u64 *cookies;11489	const char **syms;11490	size_t cnt;11491 11492	if (!OPTS_VALID(opts, bpf_kprobe_multi_opts))11493		return libbpf_err_ptr(-EINVAL);11494 11495	prog_fd = bpf_program__fd(prog);11496	if (prog_fd < 0) {11497		pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",11498			prog->name);11499		return libbpf_err_ptr(-EINVAL);11500	}11501 11502	syms    = OPTS_GET(opts, syms, false);11503	addrs   = OPTS_GET(opts, addrs, false);11504	cnt     = OPTS_GET(opts, cnt, false);11505	cookies = OPTS_GET(opts, cookies, false);11506 11507	if (!pattern && !addrs && !syms)11508		return libbpf_err_ptr(-EINVAL);11509	if (pattern && (addrs || syms || cookies || cnt))11510		return libbpf_err_ptr(-EINVAL);11511	if (!pattern && !cnt)11512		return libbpf_err_ptr(-EINVAL);11513	if (addrs && syms)11514		return libbpf_err_ptr(-EINVAL);11515 11516	if (pattern) {11517		if (has_available_filter_functions_addrs())11518			err = libbpf_available_kprobes_parse(&res);11519		else11520			err = libbpf_available_kallsyms_parse(&res);11521		if (err)11522			goto error;11523		addrs = res.addrs;11524		cnt = res.cnt;11525	}11526 11527	retprobe = OPTS_GET(opts, retprobe, false);11528	session  = OPTS_GET(opts, session, false);11529 11530	if (retprobe && session)11531		return libbpf_err_ptr(-EINVAL);11532 11533	attach_type = session ? BPF_TRACE_KPROBE_SESSION : BPF_TRACE_KPROBE_MULTI;11534 11535	lopts.kprobe_multi.syms = syms;11536	lopts.kprobe_multi.addrs = addrs;11537	lopts.kprobe_multi.cookies = cookies;11538	lopts.kprobe_multi.cnt = cnt;11539	lopts.kprobe_multi.flags = retprobe ? BPF_F_KPROBE_MULTI_RETURN : 0;11540 11541	link = calloc(1, sizeof(*link));11542	if (!link) {11543		err = -ENOMEM;11544		goto error;11545	}11546	link->detach = &bpf_link__detach_fd;11547 11548	link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts);11549	if (link_fd < 0) {11550		err = -errno;11551		pr_warn("prog '%s': failed to attach: %s\n",11552			prog->name, libbpf_strerror_r(err, errmsg, sizeof(errmsg)));11553		goto error;11554	}11555	link->fd = link_fd;11556	free(res.addrs);11557	return link;11558 11559error:11560	free(link);11561	free(res.addrs);11562	return libbpf_err_ptr(err);11563}11564 11565static int attach_kprobe(const struct bpf_program *prog, long cookie, struct bpf_link **link)11566{11567	DECLARE_LIBBPF_OPTS(bpf_kprobe_opts, opts);11568	unsigned long offset = 0;11569	const char *func_name;11570	char *func;11571	int n;11572 11573	*link = NULL;11574 11575	/* no auto-attach for SEC("kprobe") and SEC("kretprobe") */11576	if (strcmp(prog->sec_name, "kprobe") == 0 || strcmp(prog->sec_name, "kretprobe") == 0)11577		return 0;11578 11579	opts.retprobe = str_has_pfx(prog->sec_name, "kretprobe/");11580	if (opts.retprobe)11581		func_name = prog->sec_name + sizeof("kretprobe/") - 1;11582	else11583		func_name = prog->sec_name + sizeof("kprobe/") - 1;11584 11585	n = sscanf(func_name, "%m[a-zA-Z0-9_.]+%li", &func, &offset);11586	if (n < 1) {11587		pr_warn("kprobe name is invalid: %s\n", func_name);11588		return -EINVAL;11589	}11590	if (opts.retprobe && offset != 0) {11591		free(func);11592		pr_warn("kretprobes do not support offset specification\n");11593		return -EINVAL;11594	}11595 11596	opts.offset = offset;11597	*link = bpf_program__attach_kprobe_opts(prog, func, &opts);11598	free(func);11599	return libbpf_get_error(*link);11600}11601 11602static int attach_ksyscall(const struct bpf_program *prog, long cookie, struct bpf_link **link)11603{11604	LIBBPF_OPTS(bpf_ksyscall_opts, opts);11605	const char *syscall_name;11606 11607	*link = NULL;11608 11609	/* no auto-attach for SEC("ksyscall") and SEC("kretsyscall") */11610	if (strcmp(prog->sec_name, "ksyscall") == 0 || strcmp(prog->sec_name, "kretsyscall") == 0)11611		return 0;11612 11613	opts.retprobe = str_has_pfx(prog->sec_name, "kretsyscall/");11614	if (opts.retprobe)11615		syscall_name = prog->sec_name + sizeof("kretsyscall/") - 1;11616	else11617		syscall_name = prog->sec_name + sizeof("ksyscall/") - 1;11618 11619	*link = bpf_program__attach_ksyscall(prog, syscall_name, &opts);11620	return *link ? 0 : -errno;11621}11622 11623static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link)11624{11625	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);11626	const char *spec;11627	char *pattern;11628	int n;11629 11630	*link = NULL;11631 11632	/* no auto-attach for SEC("kprobe.multi") and SEC("kretprobe.multi") */11633	if (strcmp(prog->sec_name, "kprobe.multi") == 0 ||11634	    strcmp(prog->sec_name, "kretprobe.multi") == 0)11635		return 0;11636 11637	opts.retprobe = str_has_pfx(prog->sec_name, "kretprobe.multi/");11638	if (opts.retprobe)11639		spec = prog->sec_name + sizeof("kretprobe.multi/") - 1;11640	else11641		spec = prog->sec_name + sizeof("kprobe.multi/") - 1;11642 11643	n = sscanf(spec, "%m[a-zA-Z0-9_.*?]", &pattern);11644	if (n < 1) {11645		pr_warn("kprobe multi pattern is invalid: %s\n", spec);11646		return -EINVAL;11647	}11648 11649	*link = bpf_program__attach_kprobe_multi_opts(prog, pattern, &opts);11650	free(pattern);11651	return libbpf_get_error(*link);11652}11653 11654static int attach_kprobe_session(const struct bpf_program *prog, long cookie,11655				 struct bpf_link **link)11656{11657	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts, .session = true);11658	const char *spec;11659	char *pattern;11660	int n;11661 11662	*link = NULL;11663 11664	/* no auto-attach for SEC("kprobe.session") */11665	if (strcmp(prog->sec_name, "kprobe.session") == 0)11666		return 0;11667 11668	spec = prog->sec_name + sizeof("kprobe.session/") - 1;11669	n = sscanf(spec, "%m[a-zA-Z0-9_.*?]", &pattern);11670	if (n < 1) {11671		pr_warn("kprobe session pattern is invalid: %s\n", spec);11672		return -EINVAL;11673	}11674 11675	*link = bpf_program__attach_kprobe_multi_opts(prog, pattern, &opts);11676	free(pattern);11677	return *link ? 0 : -errno;11678}11679 11680static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link)11681{11682	char *probe_type = NULL, *binary_path = NULL, *func_name = NULL;11683	LIBBPF_OPTS(bpf_uprobe_multi_opts, opts);11684	int n, ret = -EINVAL;11685 11686	*link = NULL;11687 11688	n = sscanf(prog->sec_name, "%m[^/]/%m[^:]:%m[^\n]",11689		   &probe_type, &binary_path, &func_name);11690	switch (n) {11691	case 1:11692		/* handle SEC("u[ret]probe") - format is valid, but auto-attach is impossible. */11693		ret = 0;11694		break;11695	case 3:11696		opts.retprobe = str_has_pfx(probe_type, "uretprobe.multi");11697		*link = bpf_program__attach_uprobe_multi(prog, -1, binary_path, func_name, &opts);11698		ret = libbpf_get_error(*link);11699		break;11700	default:11701		pr_warn("prog '%s': invalid format of section definition '%s'\n", prog->name,11702			prog->sec_name);11703		break;11704	}11705	free(probe_type);11706	free(binary_path);11707	free(func_name);11708	return ret;11709}11710 11711static void gen_uprobe_legacy_event_name(char *buf, size_t buf_sz,11712					 const char *binary_path, uint64_t offset)11713{11714	int i;11715 11716	snprintf(buf, buf_sz, "libbpf_%u_%s_0x%zx", getpid(), binary_path, (size_t)offset);11717 11718	/* sanitize binary_path in the probe name */11719	for (i = 0; buf[i]; i++) {11720		if (!isalnum(buf[i]))11721			buf[i] = '_';11722	}11723}11724 11725static inline int add_uprobe_event_legacy(const char *probe_name, bool retprobe,11726					  const char *binary_path, size_t offset)11727{11728	return append_to_file(tracefs_uprobe_events(), "%c:%s/%s %s:0x%zx",11729			      retprobe ? 'r' : 'p',11730			      retprobe ? "uretprobes" : "uprobes",11731			      probe_name, binary_path, offset);11732}11733 11734static inline int remove_uprobe_event_legacy(const char *probe_name, bool retprobe)11735{11736	return append_to_file(tracefs_uprobe_events(), "-:%s/%s",11737			      retprobe ? "uretprobes" : "uprobes", probe_name);11738}11739 11740static int determine_uprobe_perf_type_legacy(const char *probe_name, bool retprobe)11741{11742	char file[512];11743 11744	snprintf(file, sizeof(file), "%s/events/%s/%s/id",11745		 tracefs_path(), retprobe ? "uretprobes" : "uprobes", probe_name);11746 11747	return parse_uint_from_file(file, "%d\n");11748}11749 11750static int perf_event_uprobe_open_legacy(const char *probe_name, bool retprobe,11751					 const char *binary_path, size_t offset, int pid)11752{11753	const size_t attr_sz = sizeof(struct perf_event_attr);11754	struct perf_event_attr attr;11755	int type, pfd, err;11756 11757	err = add_uprobe_event_legacy(probe_name, retprobe, binary_path, offset);11758	if (err < 0) {11759		pr_warn("failed to add legacy uprobe event for %s:0x%zx: %d\n",11760			binary_path, (size_t)offset, err);11761		return err;11762	}11763	type = determine_uprobe_perf_type_legacy(probe_name, retprobe);11764	if (type < 0) {11765		err = type;11766		pr_warn("failed to determine legacy uprobe event id for %s:0x%zx: %d\n",11767			binary_path, offset, err);11768		goto err_clean_legacy;11769	}11770 11771	memset(&attr, 0, attr_sz);11772	attr.size = attr_sz;11773	attr.config = type;11774	attr.type = PERF_TYPE_TRACEPOINT;11775 11776	pfd = syscall(__NR_perf_event_open, &attr,11777		      pid < 0 ? -1 : pid, /* pid */11778		      pid == -1 ? 0 : -1, /* cpu */11779		      -1 /* group_fd */,  PERF_FLAG_FD_CLOEXEC);11780	if (pfd < 0) {11781		err = -errno;11782		pr_warn("legacy uprobe perf_event_open() failed: %d\n", err);11783		goto err_clean_legacy;11784	}11785	return pfd;11786 11787err_clean_legacy:11788	/* Clear the newly added legacy uprobe_event */11789	remove_uprobe_event_legacy(probe_name, retprobe);11790	return err;11791}11792 11793/* Find offset of function name in archive specified by path. Currently11794 * supported are .zip files that do not compress their contents, as used on11795 * Android in the form of APKs, for example. "file_name" is the name of the ELF11796 * file inside the archive. "func_name" matches symbol name or name@@LIB for11797 * library functions.11798 *11799 * An overview of the APK format specifically provided here:11800 * https://en.wikipedia.org/w/index.php?title=Apk_(file_format)&oldid=1139099120#Package_contents11801 */11802static long elf_find_func_offset_from_archive(const char *archive_path, const char *file_name,11803					      const char *func_name)11804{11805	struct zip_archive *archive;11806	struct zip_entry entry;11807	long ret;11808	Elf *elf;11809 11810	archive = zip_archive_open(archive_path);11811	if (IS_ERR(archive)) {11812		ret = PTR_ERR(archive);11813		pr_warn("zip: failed to open %s: %ld\n", archive_path, ret);11814		return ret;11815	}11816 11817	ret = zip_archive_find_entry(archive, file_name, &entry);11818	if (ret) {11819		pr_warn("zip: could not find archive member %s in %s: %ld\n", file_name,11820			archive_path, ret);11821		goto out;11822	}11823	pr_debug("zip: found entry for %s in %s at 0x%lx\n", file_name, archive_path,11824		 (unsigned long)entry.data_offset);11825 11826	if (entry.compression) {11827		pr_warn("zip: entry %s of %s is compressed and cannot be handled\n", file_name,11828			archive_path);11829		ret = -LIBBPF_ERRNO__FORMAT;11830		goto out;11831	}11832 11833	elf = elf_memory((void *)entry.data, entry.data_length);11834	if (!elf) {11835		pr_warn("elf: could not read elf file %s from %s: %s\n", file_name, archive_path,11836			elf_errmsg(-1));11837		ret = -LIBBPF_ERRNO__LIBELF;11838		goto out;11839	}11840 11841	ret = elf_find_func_offset(elf, file_name, func_name);11842	if (ret > 0) {11843		pr_debug("elf: symbol address match for %s of %s in %s: 0x%x + 0x%lx = 0x%lx\n",11844			 func_name, file_name, archive_path, entry.data_offset, ret,11845			 ret + entry.data_offset);11846		ret += entry.data_offset;11847	}11848	elf_end(elf);11849 11850out:11851	zip_archive_close(archive);11852	return ret;11853}11854 11855static const char *arch_specific_lib_paths(void)11856{11857	/*11858	 * Based on https://packages.debian.org/sid/libc6.11859	 *11860	 * Assume that the traced program is built for the same architecture11861	 * as libbpf, which should cover the vast majority of cases.11862	 */11863#if defined(__x86_64__)11864	return "/lib/x86_64-linux-gnu";11865#elif defined(__i386__)11866	return "/lib/i386-linux-gnu";11867#elif defined(__s390x__)11868	return "/lib/s390x-linux-gnu";11869#elif defined(__s390__)11870	return "/lib/s390-linux-gnu";11871#elif defined(__arm__) && defined(__SOFTFP__)11872	return "/lib/arm-linux-gnueabi";11873#elif defined(__arm__) && !defined(__SOFTFP__)11874	return "/lib/arm-linux-gnueabihf";11875#elif defined(__aarch64__)11876	return "/lib/aarch64-linux-gnu";11877#elif defined(__mips__) && defined(__MIPSEL__) && _MIPS_SZLONG == 6411878	return "/lib/mips64el-linux-gnuabi64";11879#elif defined(__mips__) && defined(__MIPSEL__) && _MIPS_SZLONG == 3211880	return "/lib/mipsel-linux-gnu";11881#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__11882	return "/lib/powerpc64le-linux-gnu";11883#elif defined(__sparc__) && defined(__arch64__)11884	return "/lib/sparc64-linux-gnu";11885#elif defined(__riscv) && __riscv_xlen == 6411886	return "/lib/riscv64-linux-gnu";11887#else11888	return NULL;11889#endif11890}11891 11892/* Get full path to program/shared library. */11893static int resolve_full_path(const char *file, char *result, size_t result_sz)11894{11895	const char *search_paths[3] = {};11896	int i, perm;11897 11898	if (str_has_sfx(file, ".so") || strstr(file, ".so.")) {11899		search_paths[0] = getenv("LD_LIBRARY_PATH");11900		search_paths[1] = "/usr/lib64:/usr/lib";11901		search_paths[2] = arch_specific_lib_paths();11902		perm = R_OK;11903	} else {11904		search_paths[0] = getenv("PATH");11905		search_paths[1] = "/usr/bin:/usr/sbin";11906		perm = R_OK | X_OK;11907	}11908 11909	for (i = 0; i < ARRAY_SIZE(search_paths); i++) {11910		const char *s;11911 11912		if (!search_paths[i])11913			continue;11914		for (s = search_paths[i]; s != NULL; s = strchr(s, ':')) {11915			char *next_path;11916			int seg_len;11917 11918			if (s[0] == ':')11919				s++;11920			next_path = strchr(s, ':');11921			seg_len = next_path ? next_path - s : strlen(s);11922			if (!seg_len)11923				continue;11924			snprintf(result, result_sz, "%.*s/%s", seg_len, s, file);11925			/* ensure it has required permissions */11926			if (faccessat(AT_FDCWD, result, perm, AT_EACCESS) < 0)11927				continue;11928			pr_debug("resolved '%s' to '%s'\n", file, result);11929			return 0;11930		}11931	}11932	return -ENOENT;11933}11934 11935struct bpf_link *11936bpf_program__attach_uprobe_multi(const struct bpf_program *prog,11937				 pid_t pid,11938				 const char *path,11939				 const char *func_pattern,11940				 const struct bpf_uprobe_multi_opts *opts)11941{11942	const unsigned long *ref_ctr_offsets = NULL, *offsets = NULL;11943	LIBBPF_OPTS(bpf_link_create_opts, lopts);11944	unsigned long *resolved_offsets = NULL;11945	int err = 0, link_fd, prog_fd;11946	struct bpf_link *link = NULL;11947	char errmsg[STRERR_BUFSIZE];11948	char full_path[PATH_MAX];11949	const __u64 *cookies;11950	const char **syms;11951	size_t cnt;11952 11953	if (!OPTS_VALID(opts, bpf_uprobe_multi_opts))11954		return libbpf_err_ptr(-EINVAL);11955 11956	prog_fd = bpf_program__fd(prog);11957	if (prog_fd < 0) {11958		pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",11959			prog->name);11960		return libbpf_err_ptr(-EINVAL);11961	}11962 11963	syms = OPTS_GET(opts, syms, NULL);11964	offsets = OPTS_GET(opts, offsets, NULL);11965	ref_ctr_offsets = OPTS_GET(opts, ref_ctr_offsets, NULL);11966	cookies = OPTS_GET(opts, cookies, NULL);11967	cnt = OPTS_GET(opts, cnt, 0);11968 11969	/*11970	 * User can specify 2 mutually exclusive set of inputs:11971	 *11972	 * 1) use only path/func_pattern/pid arguments11973	 *11974	 * 2) use path/pid with allowed combinations of:11975	 *    syms/offsets/ref_ctr_offsets/cookies/cnt11976	 *11977	 *    - syms and offsets are mutually exclusive11978	 *    - ref_ctr_offsets and cookies are optional11979	 *11980	 * Any other usage results in error.11981	 */11982 11983	if (!path)11984		return libbpf_err_ptr(-EINVAL);11985	if (!func_pattern && cnt == 0)11986		return libbpf_err_ptr(-EINVAL);11987 11988	if (func_pattern) {11989		if (syms || offsets || ref_ctr_offsets || cookies || cnt)11990			return libbpf_err_ptr(-EINVAL);11991	} else {11992		if (!!syms == !!offsets)11993			return libbpf_err_ptr(-EINVAL);11994	}11995 11996	if (func_pattern) {11997		if (!strchr(path, '/')) {11998			err = resolve_full_path(path, full_path, sizeof(full_path));11999			if (err) {12000				pr_warn("prog '%s': failed to resolve full path for '%s': %d\n",12001					prog->name, path, err);12002				return libbpf_err_ptr(err);12003			}12004			path = full_path;12005		}12006 12007		err = elf_resolve_pattern_offsets(path, func_pattern,12008						  &resolved_offsets, &cnt);12009		if (err < 0)12010			return libbpf_err_ptr(err);12011		offsets = resolved_offsets;12012	} else if (syms) {12013		err = elf_resolve_syms_offsets(path, cnt, syms, &resolved_offsets, STT_FUNC);12014		if (err < 0)12015			return libbpf_err_ptr(err);12016		offsets = resolved_offsets;12017	}12018 12019	lopts.uprobe_multi.path = path;12020	lopts.uprobe_multi.offsets = offsets;12021	lopts.uprobe_multi.ref_ctr_offsets = ref_ctr_offsets;12022	lopts.uprobe_multi.cookies = cookies;12023	lopts.uprobe_multi.cnt = cnt;12024	lopts.uprobe_multi.flags = OPTS_GET(opts, retprobe, false) ? BPF_F_UPROBE_MULTI_RETURN : 0;12025 12026	if (pid == 0)12027		pid = getpid();12028	if (pid > 0)12029		lopts.uprobe_multi.pid = pid;12030 12031	link = calloc(1, sizeof(*link));12032	if (!link) {12033		err = -ENOMEM;12034		goto error;12035	}12036	link->detach = &bpf_link__detach_fd;12037 12038	link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_UPROBE_MULTI, &lopts);12039	if (link_fd < 0) {12040		err = -errno;12041		pr_warn("prog '%s': failed to attach multi-uprobe: %s\n",12042			prog->name, libbpf_strerror_r(err, errmsg, sizeof(errmsg)));12043		goto error;12044	}12045	link->fd = link_fd;12046	free(resolved_offsets);12047	return link;12048 12049error:12050	free(resolved_offsets);12051	free(link);12052	return libbpf_err_ptr(err);12053}12054 12055LIBBPF_API struct bpf_link *12056bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,12057				const char *binary_path, size_t func_offset,12058				const struct bpf_uprobe_opts *opts)12059{12060	const char *archive_path = NULL, *archive_sep = NULL;12061	char errmsg[STRERR_BUFSIZE], *legacy_probe = NULL;12062	DECLARE_LIBBPF_OPTS(bpf_perf_event_opts, pe_opts);12063	enum probe_attach_mode attach_mode;12064	char full_path[PATH_MAX];12065	struct bpf_link *link;12066	size_t ref_ctr_off;12067	int pfd, err;12068	bool retprobe, legacy;12069	const char *func_name;12070 12071	if (!OPTS_VALID(opts, bpf_uprobe_opts))12072		return libbpf_err_ptr(-EINVAL);12073 12074	attach_mode = OPTS_GET(opts, attach_mode, PROBE_ATTACH_MODE_DEFAULT);12075	retprobe = OPTS_GET(opts, retprobe, false);12076	ref_ctr_off = OPTS_GET(opts, ref_ctr_offset, 0);12077	pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);12078 12079	if (!binary_path)12080		return libbpf_err_ptr(-EINVAL);12081 12082	/* Check if "binary_path" refers to an archive. */12083	archive_sep = strstr(binary_path, "!/");12084	if (archive_sep) {12085		full_path[0] = '\0';12086		libbpf_strlcpy(full_path, binary_path,12087			       min(sizeof(full_path), (size_t)(archive_sep - binary_path + 1)));12088		archive_path = full_path;12089		binary_path = archive_sep + 2;12090	} else if (!strchr(binary_path, '/')) {12091		err = resolve_full_path(binary_path, full_path, sizeof(full_path));12092		if (err) {12093			pr_warn("prog '%s': failed to resolve full path for '%s': %d\n",12094				prog->name, binary_path, err);12095			return libbpf_err_ptr(err);12096		}12097		binary_path = full_path;12098	}12099	func_name = OPTS_GET(opts, func_name, NULL);12100	if (func_name) {12101		long sym_off;12102 12103		if (archive_path) {12104			sym_off = elf_find_func_offset_from_archive(archive_path, binary_path,12105								    func_name);12106			binary_path = archive_path;12107		} else {12108			sym_off = elf_find_func_offset_from_file(binary_path, func_name);12109		}12110		if (sym_off < 0)12111			return libbpf_err_ptr(sym_off);12112		func_offset += sym_off;12113	}12114 12115	legacy = determine_uprobe_perf_type() < 0;12116	switch (attach_mode) {12117	case PROBE_ATTACH_MODE_LEGACY:12118		legacy = true;12119		pe_opts.force_ioctl_attach = true;12120		break;12121	case PROBE_ATTACH_MODE_PERF:12122		if (legacy)12123			return libbpf_err_ptr(-ENOTSUP);12124		pe_opts.force_ioctl_attach = true;12125		break;12126	case PROBE_ATTACH_MODE_LINK:12127		if (legacy || !kernel_supports(prog->obj, FEAT_PERF_LINK))12128			return libbpf_err_ptr(-ENOTSUP);12129		break;12130	case PROBE_ATTACH_MODE_DEFAULT:12131		break;12132	default:12133		return libbpf_err_ptr(-EINVAL);12134	}12135 12136	if (!legacy) {12137		pfd = perf_event_open_probe(true /* uprobe */, retprobe, binary_path,12138					    func_offset, pid, ref_ctr_off);12139	} else {12140		char probe_name[PATH_MAX + 64];12141 12142		if (ref_ctr_off)12143			return libbpf_err_ptr(-EINVAL);12144 12145		gen_uprobe_legacy_event_name(probe_name, sizeof(probe_name),12146					     binary_path, func_offset);12147 12148		legacy_probe = strdup(probe_name);12149		if (!legacy_probe)12150			return libbpf_err_ptr(-ENOMEM);12151 12152		pfd = perf_event_uprobe_open_legacy(legacy_probe, retprobe,12153						    binary_path, func_offset, pid);12154	}12155	if (pfd < 0) {12156		err = -errno;12157		pr_warn("prog '%s': failed to create %s '%s:0x%zx' perf event: %s\n",12158			prog->name, retprobe ? "uretprobe" : "uprobe",12159			binary_path, func_offset,12160			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));12161		goto err_out;12162	}12163 12164	link = bpf_program__attach_perf_event_opts(prog, pfd, &pe_opts);12165	err = libbpf_get_error(link);12166	if (err) {12167		close(pfd);12168		pr_warn("prog '%s': failed to attach to %s '%s:0x%zx': %s\n",12169			prog->name, retprobe ? "uretprobe" : "uprobe",12170			binary_path, func_offset,12171			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));12172		goto err_clean_legacy;12173	}12174	if (legacy) {12175		struct bpf_link_perf *perf_link = container_of(link, struct bpf_link_perf, link);12176 12177		perf_link->legacy_probe_name = legacy_probe;12178		perf_link->legacy_is_kprobe = false;12179		perf_link->legacy_is_retprobe = retprobe;12180	}12181	return link;12182 12183err_clean_legacy:12184	if (legacy)12185		remove_uprobe_event_legacy(legacy_probe, retprobe);12186err_out:12187	free(legacy_probe);12188	return libbpf_err_ptr(err);12189}12190 12191/* Format of u[ret]probe section definition supporting auto-attach:12192 * u[ret]probe/binary:function[+offset]12193 *12194 * binary can be an absolute/relative path or a filename; the latter is resolved to a12195 * full binary path via bpf_program__attach_uprobe_opts.12196 *12197 * Specifying uprobe+ ensures we carry out strict matching; either "uprobe" must be12198 * specified (and auto-attach is not possible) or the above format is specified for12199 * auto-attach.12200 */12201static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf_link **link)12202{12203	DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, opts);12204	char *probe_type = NULL, *binary_path = NULL, *func_name = NULL, *func_off;12205	int n, c, ret = -EINVAL;12206	long offset = 0;12207 12208	*link = NULL;12209 12210	n = sscanf(prog->sec_name, "%m[^/]/%m[^:]:%m[^\n]",12211		   &probe_type, &binary_path, &func_name);12212	switch (n) {12213	case 1:12214		/* handle SEC("u[ret]probe") - format is valid, but auto-attach is impossible. */12215		ret = 0;12216		break;12217	case 2:12218		pr_warn("prog '%s': section '%s' missing ':function[+offset]' specification\n",12219			prog->name, prog->sec_name);12220		break;12221	case 3:12222		/* check if user specifies `+offset`, if yes, this should be12223		 * the last part of the string, make sure sscanf read to EOL12224		 */12225		func_off = strrchr(func_name, '+');12226		if (func_off) {12227			n = sscanf(func_off, "+%li%n", &offset, &c);12228			if (n == 1 && *(func_off + c) == '\0')12229				func_off[0] = '\0';12230			else12231				offset = 0;12232		}12233		opts.retprobe = strcmp(probe_type, "uretprobe") == 0 ||12234				strcmp(probe_type, "uretprobe.s") == 0;12235		if (opts.retprobe && offset != 0) {12236			pr_warn("prog '%s': uretprobes do not support offset specification\n",12237				prog->name);12238			break;12239		}12240		opts.func_name = func_name;12241		*link = bpf_program__attach_uprobe_opts(prog, -1, binary_path, offset, &opts);12242		ret = libbpf_get_error(*link);12243		break;12244	default:12245		pr_warn("prog '%s': invalid format of section definition '%s'\n", prog->name,12246			prog->sec_name);12247		break;12248	}12249	free(probe_type);12250	free(binary_path);12251	free(func_name);12252 12253	return ret;12254}12255 12256struct bpf_link *bpf_program__attach_uprobe(const struct bpf_program *prog,12257					    bool retprobe, pid_t pid,12258					    const char *binary_path,12259					    size_t func_offset)12260{12261	DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, opts, .retprobe = retprobe);12262 12263	return bpf_program__attach_uprobe_opts(prog, pid, binary_path, func_offset, &opts);12264}12265 12266struct bpf_link *bpf_program__attach_usdt(const struct bpf_program *prog,12267					  pid_t pid, const char *binary_path,12268					  const char *usdt_provider, const char *usdt_name,12269					  const struct bpf_usdt_opts *opts)12270{12271	char resolved_path[512];12272	struct bpf_object *obj = prog->obj;12273	struct bpf_link *link;12274	__u64 usdt_cookie;12275	int err;12276 12277	if (!OPTS_VALID(opts, bpf_uprobe_opts))12278		return libbpf_err_ptr(-EINVAL);12279 12280	if (bpf_program__fd(prog) < 0) {12281		pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",12282			prog->name);12283		return libbpf_err_ptr(-EINVAL);12284	}12285 12286	if (!binary_path)12287		return libbpf_err_ptr(-EINVAL);12288 12289	if (!strchr(binary_path, '/')) {12290		err = resolve_full_path(binary_path, resolved_path, sizeof(resolved_path));12291		if (err) {12292			pr_warn("prog '%s': failed to resolve full path for '%s': %d\n",12293				prog->name, binary_path, err);12294			return libbpf_err_ptr(err);12295		}12296		binary_path = resolved_path;12297	}12298 12299	/* USDT manager is instantiated lazily on first USDT attach. It will12300	 * be destroyed together with BPF object in bpf_object__close().12301	 */12302	if (IS_ERR(obj->usdt_man))12303		return libbpf_ptr(obj->usdt_man);12304	if (!obj->usdt_man) {12305		obj->usdt_man = usdt_manager_new(obj);12306		if (IS_ERR(obj->usdt_man))12307			return libbpf_ptr(obj->usdt_man);12308	}12309 12310	usdt_cookie = OPTS_GET(opts, usdt_cookie, 0);12311	link = usdt_manager_attach_usdt(obj->usdt_man, prog, pid, binary_path,12312					usdt_provider, usdt_name, usdt_cookie);12313	err = libbpf_get_error(link);12314	if (err)12315		return libbpf_err_ptr(err);12316	return link;12317}12318 12319static int attach_usdt(const struct bpf_program *prog, long cookie, struct bpf_link **link)12320{12321	char *path = NULL, *provider = NULL, *name = NULL;12322	const char *sec_name;12323	int n, err;12324 12325	sec_name = bpf_program__section_name(prog);12326	if (strcmp(sec_name, "usdt") == 0) {12327		/* no auto-attach for just SEC("usdt") */12328		*link = NULL;12329		return 0;12330	}12331 12332	n = sscanf(sec_name, "usdt/%m[^:]:%m[^:]:%m[^:]", &path, &provider, &name);12333	if (n != 3) {12334		pr_warn("invalid section '%s', expected SEC(\"usdt/<path>:<provider>:<name>\")\n",12335			sec_name);12336		err = -EINVAL;12337	} else {12338		*link = bpf_program__attach_usdt(prog, -1 /* any process */, path,12339						 provider, name, NULL);12340		err = libbpf_get_error(*link);12341	}12342	free(path);12343	free(provider);12344	free(name);12345	return err;12346}12347 12348static int determine_tracepoint_id(const char *tp_category,12349				   const char *tp_name)12350{12351	char file[PATH_MAX];12352	int ret;12353 12354	ret = snprintf(file, sizeof(file), "%s/events/%s/%s/id",12355		       tracefs_path(), tp_category, tp_name);12356	if (ret < 0)12357		return -errno;12358	if (ret >= sizeof(file)) {12359		pr_debug("tracepoint %s/%s path is too long\n",12360			 tp_category, tp_name);12361		return -E2BIG;12362	}12363	return parse_uint_from_file(file, "%d\n");12364}12365 12366static int perf_event_open_tracepoint(const char *tp_category,12367				      const char *tp_name)12368{12369	const size_t attr_sz = sizeof(struct perf_event_attr);12370	struct perf_event_attr attr;12371	char errmsg[STRERR_BUFSIZE];12372	int tp_id, pfd, err;12373 12374	tp_id = determine_tracepoint_id(tp_category, tp_name);12375	if (tp_id < 0) {12376		pr_warn("failed to determine tracepoint '%s/%s' perf event ID: %s\n",12377			tp_category, tp_name,12378			libbpf_strerror_r(tp_id, errmsg, sizeof(errmsg)));12379		return tp_id;12380	}12381 12382	memset(&attr, 0, attr_sz);12383	attr.type = PERF_TYPE_TRACEPOINT;12384	attr.size = attr_sz;12385	attr.config = tp_id;12386 12387	pfd = syscall(__NR_perf_event_open, &attr, -1 /* pid */, 0 /* cpu */,12388		      -1 /* group_fd */, PERF_FLAG_FD_CLOEXEC);12389	if (pfd < 0) {12390		err = -errno;12391		pr_warn("tracepoint '%s/%s' perf_event_open() failed: %s\n",12392			tp_category, tp_name,12393			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));12394		return err;12395	}12396	return pfd;12397}12398 12399struct bpf_link *bpf_program__attach_tracepoint_opts(const struct bpf_program *prog,12400						     const char *tp_category,12401						     const char *tp_name,12402						     const struct bpf_tracepoint_opts *opts)12403{12404	DECLARE_LIBBPF_OPTS(bpf_perf_event_opts, pe_opts);12405	char errmsg[STRERR_BUFSIZE];12406	struct bpf_link *link;12407	int pfd, err;12408 12409	if (!OPTS_VALID(opts, bpf_tracepoint_opts))12410		return libbpf_err_ptr(-EINVAL);12411 12412	pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);12413 12414	pfd = perf_event_open_tracepoint(tp_category, tp_name);12415	if (pfd < 0) {12416		pr_warn("prog '%s': failed to create tracepoint '%s/%s' perf event: %s\n",12417			prog->name, tp_category, tp_name,12418			libbpf_strerror_r(pfd, errmsg, sizeof(errmsg)));12419		return libbpf_err_ptr(pfd);12420	}12421	link = bpf_program__attach_perf_event_opts(prog, pfd, &pe_opts);12422	err = libbpf_get_error(link);12423	if (err) {12424		close(pfd);12425		pr_warn("prog '%s': failed to attach to tracepoint '%s/%s': %s\n",12426			prog->name, tp_category, tp_name,12427			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));12428		return libbpf_err_ptr(err);12429	}12430	return link;12431}12432 12433struct bpf_link *bpf_program__attach_tracepoint(const struct bpf_program *prog,12434						const char *tp_category,12435						const char *tp_name)12436{12437	return bpf_program__attach_tracepoint_opts(prog, tp_category, tp_name, NULL);12438}12439 12440static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link)12441{12442	char *sec_name, *tp_cat, *tp_name;12443 12444	*link = NULL;12445 12446	/* no auto-attach for SEC("tp") or SEC("tracepoint") */12447	if (strcmp(prog->sec_name, "tp") == 0 || strcmp(prog->sec_name, "tracepoint") == 0)12448		return 0;12449 12450	sec_name = strdup(prog->sec_name);12451	if (!sec_name)12452		return -ENOMEM;12453 12454	/* extract "tp/<category>/<name>" or "tracepoint/<category>/<name>" */12455	if (str_has_pfx(prog->sec_name, "tp/"))12456		tp_cat = sec_name + sizeof("tp/") - 1;12457	else12458		tp_cat = sec_name + sizeof("tracepoint/") - 1;12459	tp_name = strchr(tp_cat, '/');12460	if (!tp_name) {12461		free(sec_name);12462		return -EINVAL;12463	}12464	*tp_name = '\0';12465	tp_name++;12466 12467	*link = bpf_program__attach_tracepoint(prog, tp_cat, tp_name);12468	free(sec_name);12469	return libbpf_get_error(*link);12470}12471 12472struct bpf_link *12473bpf_program__attach_raw_tracepoint_opts(const struct bpf_program *prog,12474					const char *tp_name,12475					struct bpf_raw_tracepoint_opts *opts)12476{12477	LIBBPF_OPTS(bpf_raw_tp_opts, raw_opts);12478	char errmsg[STRERR_BUFSIZE];12479	struct bpf_link *link;12480	int prog_fd, pfd;12481 12482	if (!OPTS_VALID(opts, bpf_raw_tracepoint_opts))12483		return libbpf_err_ptr(-EINVAL);12484 12485	prog_fd = bpf_program__fd(prog);12486	if (prog_fd < 0) {12487		pr_warn("prog '%s': can't attach before loaded\n", prog->name);12488		return libbpf_err_ptr(-EINVAL);12489	}12490 12491	link = calloc(1, sizeof(*link));12492	if (!link)12493		return libbpf_err_ptr(-ENOMEM);12494	link->detach = &bpf_link__detach_fd;12495 12496	raw_opts.tp_name = tp_name;12497	raw_opts.cookie = OPTS_GET(opts, cookie, 0);12498	pfd = bpf_raw_tracepoint_open_opts(prog_fd, &raw_opts);12499	if (pfd < 0) {12500		pfd = -errno;12501		free(link);12502		pr_warn("prog '%s': failed to attach to raw tracepoint '%s': %s\n",12503			prog->name, tp_name, libbpf_strerror_r(pfd, errmsg, sizeof(errmsg)));12504		return libbpf_err_ptr(pfd);12505	}12506	link->fd = pfd;12507	return link;12508}12509 12510struct bpf_link *bpf_program__attach_raw_tracepoint(const struct bpf_program *prog,12511						    const char *tp_name)12512{12513	return bpf_program__attach_raw_tracepoint_opts(prog, tp_name, NULL);12514}12515 12516static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link)12517{12518	static const char *const prefixes[] = {12519		"raw_tp",12520		"raw_tracepoint",12521		"raw_tp.w",12522		"raw_tracepoint.w",12523	};12524	size_t i;12525	const char *tp_name = NULL;12526 12527	*link = NULL;12528 12529	for (i = 0; i < ARRAY_SIZE(prefixes); i++) {12530		size_t pfx_len;12531 12532		if (!str_has_pfx(prog->sec_name, prefixes[i]))12533			continue;12534 12535		pfx_len = strlen(prefixes[i]);12536		/* no auto-attach case of, e.g., SEC("raw_tp") */12537		if (prog->sec_name[pfx_len] == '\0')12538			return 0;12539 12540		if (prog->sec_name[pfx_len] != '/')12541			continue;12542 12543		tp_name = prog->sec_name + pfx_len + 1;12544		break;12545	}12546 12547	if (!tp_name) {12548		pr_warn("prog '%s': invalid section name '%s'\n",12549			prog->name, prog->sec_name);12550		return -EINVAL;12551	}12552 12553	*link = bpf_program__attach_raw_tracepoint(prog, tp_name);12554	return libbpf_get_error(*link);12555}12556 12557/* Common logic for all BPF program types that attach to a btf_id */12558static struct bpf_link *bpf_program__attach_btf_id(const struct bpf_program *prog,12559						   const struct bpf_trace_opts *opts)12560{12561	LIBBPF_OPTS(bpf_link_create_opts, link_opts);12562	char errmsg[STRERR_BUFSIZE];12563	struct bpf_link *link;12564	int prog_fd, pfd;12565 12566	if (!OPTS_VALID(opts, bpf_trace_opts))12567		return libbpf_err_ptr(-EINVAL);12568 12569	prog_fd = bpf_program__fd(prog);12570	if (prog_fd < 0) {12571		pr_warn("prog '%s': can't attach before loaded\n", prog->name);12572		return libbpf_err_ptr(-EINVAL);12573	}12574 12575	link = calloc(1, sizeof(*link));12576	if (!link)12577		return libbpf_err_ptr(-ENOMEM);12578	link->detach = &bpf_link__detach_fd;12579 12580	/* libbpf is smart enough to redirect to BPF_RAW_TRACEPOINT_OPEN on old kernels */12581	link_opts.tracing.cookie = OPTS_GET(opts, cookie, 0);12582	pfd = bpf_link_create(prog_fd, 0, bpf_program__expected_attach_type(prog), &link_opts);12583	if (pfd < 0) {12584		pfd = -errno;12585		free(link);12586		pr_warn("prog '%s': failed to attach: %s\n",12587			prog->name, libbpf_strerror_r(pfd, errmsg, sizeof(errmsg)));12588		return libbpf_err_ptr(pfd);12589	}12590	link->fd = pfd;12591	return link;12592}12593 12594struct bpf_link *bpf_program__attach_trace(const struct bpf_program *prog)12595{12596	return bpf_program__attach_btf_id(prog, NULL);12597}12598 12599struct bpf_link *bpf_program__attach_trace_opts(const struct bpf_program *prog,12600						const struct bpf_trace_opts *opts)12601{12602	return bpf_program__attach_btf_id(prog, opts);12603}12604 12605struct bpf_link *bpf_program__attach_lsm(const struct bpf_program *prog)12606{12607	return bpf_program__attach_btf_id(prog, NULL);12608}12609 12610static int attach_trace(const struct bpf_program *prog, long cookie, struct bpf_link **link)12611{12612	*link = bpf_program__attach_trace(prog);12613	return libbpf_get_error(*link);12614}12615 12616static int attach_lsm(const struct bpf_program *prog, long cookie, struct bpf_link **link)12617{12618	*link = bpf_program__attach_lsm(prog);12619	return libbpf_get_error(*link);12620}12621 12622static struct bpf_link *12623bpf_program_attach_fd(const struct bpf_program *prog,12624		      int target_fd, const char *target_name,12625		      const struct bpf_link_create_opts *opts)12626{12627	enum bpf_attach_type attach_type;12628	char errmsg[STRERR_BUFSIZE];12629	struct bpf_link *link;12630	int prog_fd, link_fd;12631 12632	prog_fd = bpf_program__fd(prog);12633	if (prog_fd < 0) {12634		pr_warn("prog '%s': can't attach before loaded\n", prog->name);12635		return libbpf_err_ptr(-EINVAL);12636	}12637 12638	link = calloc(1, sizeof(*link));12639	if (!link)12640		return libbpf_err_ptr(-ENOMEM);12641	link->detach = &bpf_link__detach_fd;12642 12643	attach_type = bpf_program__expected_attach_type(prog);12644	link_fd = bpf_link_create(prog_fd, target_fd, attach_type, opts);12645	if (link_fd < 0) {12646		link_fd = -errno;12647		free(link);12648		pr_warn("prog '%s': failed to attach to %s: %s\n",12649			prog->name, target_name,12650			libbpf_strerror_r(link_fd, errmsg, sizeof(errmsg)));12651		return libbpf_err_ptr(link_fd);12652	}12653	link->fd = link_fd;12654	return link;12655}12656 12657struct bpf_link *12658bpf_program__attach_cgroup(const struct bpf_program *prog, int cgroup_fd)12659{12660	return bpf_program_attach_fd(prog, cgroup_fd, "cgroup", NULL);12661}12662 12663struct bpf_link *12664bpf_program__attach_netns(const struct bpf_program *prog, int netns_fd)12665{12666	return bpf_program_attach_fd(prog, netns_fd, "netns", NULL);12667}12668 12669struct bpf_link *12670bpf_program__attach_sockmap(const struct bpf_program *prog, int map_fd)12671{12672	return bpf_program_attach_fd(prog, map_fd, "sockmap", NULL);12673}12674 12675struct bpf_link *bpf_program__attach_xdp(const struct bpf_program *prog, int ifindex)12676{12677	/* target_fd/target_ifindex use the same field in LINK_CREATE */12678	return bpf_program_attach_fd(prog, ifindex, "xdp", NULL);12679}12680 12681struct bpf_link *12682bpf_program__attach_tcx(const struct bpf_program *prog, int ifindex,12683			const struct bpf_tcx_opts *opts)12684{12685	LIBBPF_OPTS(bpf_link_create_opts, link_create_opts);12686	__u32 relative_id;12687	int relative_fd;12688 12689	if (!OPTS_VALID(opts, bpf_tcx_opts))12690		return libbpf_err_ptr(-EINVAL);12691 12692	relative_id = OPTS_GET(opts, relative_id, 0);12693	relative_fd = OPTS_GET(opts, relative_fd, 0);12694 12695	/* validate we don't have unexpected combinations of non-zero fields */12696	if (!ifindex) {12697		pr_warn("prog '%s': target netdevice ifindex cannot be zero\n",12698			prog->name);12699		return libbpf_err_ptr(-EINVAL);12700	}12701	if (relative_fd && relative_id) {12702		pr_warn("prog '%s': relative_fd and relative_id cannot be set at the same time\n",12703			prog->name);12704		return libbpf_err_ptr(-EINVAL);12705	}12706 12707	link_create_opts.tcx.expected_revision = OPTS_GET(opts, expected_revision, 0);12708	link_create_opts.tcx.relative_fd = relative_fd;12709	link_create_opts.tcx.relative_id = relative_id;12710	link_create_opts.flags = OPTS_GET(opts, flags, 0);12711 12712	/* target_fd/target_ifindex use the same field in LINK_CREATE */12713	return bpf_program_attach_fd(prog, ifindex, "tcx", &link_create_opts);12714}12715 12716struct bpf_link *12717bpf_program__attach_netkit(const struct bpf_program *prog, int ifindex,12718			   const struct bpf_netkit_opts *opts)12719{12720	LIBBPF_OPTS(bpf_link_create_opts, link_create_opts);12721	__u32 relative_id;12722	int relative_fd;12723 12724	if (!OPTS_VALID(opts, bpf_netkit_opts))12725		return libbpf_err_ptr(-EINVAL);12726 12727	relative_id = OPTS_GET(opts, relative_id, 0);12728	relative_fd = OPTS_GET(opts, relative_fd, 0);12729 12730	/* validate we don't have unexpected combinations of non-zero fields */12731	if (!ifindex) {12732		pr_warn("prog '%s': target netdevice ifindex cannot be zero\n",12733			prog->name);12734		return libbpf_err_ptr(-EINVAL);12735	}12736	if (relative_fd && relative_id) {12737		pr_warn("prog '%s': relative_fd and relative_id cannot be set at the same time\n",12738			prog->name);12739		return libbpf_err_ptr(-EINVAL);12740	}12741 12742	link_create_opts.netkit.expected_revision = OPTS_GET(opts, expected_revision, 0);12743	link_create_opts.netkit.relative_fd = relative_fd;12744	link_create_opts.netkit.relative_id = relative_id;12745	link_create_opts.flags = OPTS_GET(opts, flags, 0);12746 12747	return bpf_program_attach_fd(prog, ifindex, "netkit", &link_create_opts);12748}12749 12750struct bpf_link *bpf_program__attach_freplace(const struct bpf_program *prog,12751					      int target_fd,12752					      const char *attach_func_name)12753{12754	int btf_id;12755 12756	if (!!target_fd != !!attach_func_name) {12757		pr_warn("prog '%s': supply none or both of target_fd and attach_func_name\n",12758			prog->name);12759		return libbpf_err_ptr(-EINVAL);12760	}12761 12762	if (prog->type != BPF_PROG_TYPE_EXT) {12763		pr_warn("prog '%s': only BPF_PROG_TYPE_EXT can attach as freplace",12764			prog->name);12765		return libbpf_err_ptr(-EINVAL);12766	}12767 12768	if (target_fd) {12769		LIBBPF_OPTS(bpf_link_create_opts, target_opts);12770 12771		btf_id = libbpf_find_prog_btf_id(attach_func_name, target_fd);12772		if (btf_id < 0)12773			return libbpf_err_ptr(btf_id);12774 12775		target_opts.target_btf_id = btf_id;12776 12777		return bpf_program_attach_fd(prog, target_fd, "freplace",12778					     &target_opts);12779	} else {12780		/* no target, so use raw_tracepoint_open for compatibility12781		 * with old kernels12782		 */12783		return bpf_program__attach_trace(prog);12784	}12785}12786 12787struct bpf_link *12788bpf_program__attach_iter(const struct bpf_program *prog,12789			 const struct bpf_iter_attach_opts *opts)12790{12791	DECLARE_LIBBPF_OPTS(bpf_link_create_opts, link_create_opts);12792	char errmsg[STRERR_BUFSIZE];12793	struct bpf_link *link;12794	int prog_fd, link_fd;12795	__u32 target_fd = 0;12796 12797	if (!OPTS_VALID(opts, bpf_iter_attach_opts))12798		return libbpf_err_ptr(-EINVAL);12799 12800	link_create_opts.iter_info = OPTS_GET(opts, link_info, (void *)0);12801	link_create_opts.iter_info_len = OPTS_GET(opts, link_info_len, 0);12802 12803	prog_fd = bpf_program__fd(prog);12804	if (prog_fd < 0) {12805		pr_warn("prog '%s': can't attach before loaded\n", prog->name);12806		return libbpf_err_ptr(-EINVAL);12807	}12808 12809	link = calloc(1, sizeof(*link));12810	if (!link)12811		return libbpf_err_ptr(-ENOMEM);12812	link->detach = &bpf_link__detach_fd;12813 12814	link_fd = bpf_link_create(prog_fd, target_fd, BPF_TRACE_ITER,12815				  &link_create_opts);12816	if (link_fd < 0) {12817		link_fd = -errno;12818		free(link);12819		pr_warn("prog '%s': failed to attach to iterator: %s\n",12820			prog->name, libbpf_strerror_r(link_fd, errmsg, sizeof(errmsg)));12821		return libbpf_err_ptr(link_fd);12822	}12823	link->fd = link_fd;12824	return link;12825}12826 12827static int attach_iter(const struct bpf_program *prog, long cookie, struct bpf_link **link)12828{12829	*link = bpf_program__attach_iter(prog, NULL);12830	return libbpf_get_error(*link);12831}12832 12833struct bpf_link *bpf_program__attach_netfilter(const struct bpf_program *prog,12834					       const struct bpf_netfilter_opts *opts)12835{12836	LIBBPF_OPTS(bpf_link_create_opts, lopts);12837	struct bpf_link *link;12838	int prog_fd, link_fd;12839 12840	if (!OPTS_VALID(opts, bpf_netfilter_opts))12841		return libbpf_err_ptr(-EINVAL);12842 12843	prog_fd = bpf_program__fd(prog);12844	if (prog_fd < 0) {12845		pr_warn("prog '%s': can't attach before loaded\n", prog->name);12846		return libbpf_err_ptr(-EINVAL);12847	}12848 12849	link = calloc(1, sizeof(*link));12850	if (!link)12851		return libbpf_err_ptr(-ENOMEM);12852 12853	link->detach = &bpf_link__detach_fd;12854 12855	lopts.netfilter.pf = OPTS_GET(opts, pf, 0);12856	lopts.netfilter.hooknum = OPTS_GET(opts, hooknum, 0);12857	lopts.netfilter.priority = OPTS_GET(opts, priority, 0);12858	lopts.netfilter.flags = OPTS_GET(opts, flags, 0);12859 12860	link_fd = bpf_link_create(prog_fd, 0, BPF_NETFILTER, &lopts);12861	if (link_fd < 0) {12862		char errmsg[STRERR_BUFSIZE];12863 12864		link_fd = -errno;12865		free(link);12866		pr_warn("prog '%s': failed to attach to netfilter: %s\n",12867			prog->name, libbpf_strerror_r(link_fd, errmsg, sizeof(errmsg)));12868		return libbpf_err_ptr(link_fd);12869	}12870	link->fd = link_fd;12871 12872	return link;12873}12874 12875struct bpf_link *bpf_program__attach(const struct bpf_program *prog)12876{12877	struct bpf_link *link = NULL;12878	int err;12879 12880	if (!prog->sec_def || !prog->sec_def->prog_attach_fn)12881		return libbpf_err_ptr(-EOPNOTSUPP);12882 12883	if (bpf_program__fd(prog) < 0) {12884		pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",12885			prog->name);12886		return libbpf_err_ptr(-EINVAL);12887	}12888 12889	err = prog->sec_def->prog_attach_fn(prog, prog->sec_def->cookie, &link);12890	if (err)12891		return libbpf_err_ptr(err);12892 12893	/* When calling bpf_program__attach() explicitly, auto-attach support12894	 * is expected to work, so NULL returned link is considered an error.12895	 * This is different for skeleton's attach, see comment in12896	 * bpf_object__attach_skeleton().12897	 */12898	if (!link)12899		return libbpf_err_ptr(-EOPNOTSUPP);12900 12901	return link;12902}12903 12904struct bpf_link_struct_ops {12905	struct bpf_link link;12906	int map_fd;12907};12908 12909static int bpf_link__detach_struct_ops(struct bpf_link *link)12910{12911	struct bpf_link_struct_ops *st_link;12912	__u32 zero = 0;12913 12914	st_link = container_of(link, struct bpf_link_struct_ops, link);12915 12916	if (st_link->map_fd < 0)12917		/* w/o a real link */12918		return bpf_map_delete_elem(link->fd, &zero);12919 12920	return close(link->fd);12921}12922 12923struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map)12924{12925	struct bpf_link_struct_ops *link;12926	__u32 zero = 0;12927	int err, fd;12928 12929	if (!bpf_map__is_struct_ops(map)) {12930		pr_warn("map '%s': can't attach non-struct_ops map\n", map->name);12931		return libbpf_err_ptr(-EINVAL);12932	}12933 12934	if (map->fd < 0) {12935		pr_warn("map '%s': can't attach BPF map without FD (was it created?)\n", map->name);12936		return libbpf_err_ptr(-EINVAL);12937	}12938 12939	link = calloc(1, sizeof(*link));12940	if (!link)12941		return libbpf_err_ptr(-EINVAL);12942 12943	/* kern_vdata should be prepared during the loading phase. */12944	err = bpf_map_update_elem(map->fd, &zero, map->st_ops->kern_vdata, 0);12945	/* It can be EBUSY if the map has been used to create or12946	 * update a link before.  We don't allow updating the value of12947	 * a struct_ops once it is set.  That ensures that the value12948	 * never changed.  So, it is safe to skip EBUSY.12949	 */12950	if (err && (!(map->def.map_flags & BPF_F_LINK) || err != -EBUSY)) {12951		free(link);12952		return libbpf_err_ptr(err);12953	}12954 12955	link->link.detach = bpf_link__detach_struct_ops;12956 12957	if (!(map->def.map_flags & BPF_F_LINK)) {12958		/* w/o a real link */12959		link->link.fd = map->fd;12960		link->map_fd = -1;12961		return &link->link;12962	}12963 12964	fd = bpf_link_create(map->fd, 0, BPF_STRUCT_OPS, NULL);12965	if (fd < 0) {12966		free(link);12967		return libbpf_err_ptr(fd);12968	}12969 12970	link->link.fd = fd;12971	link->map_fd = map->fd;12972 12973	return &link->link;12974}12975 12976/*12977 * Swap the back struct_ops of a link with a new struct_ops map.12978 */12979int bpf_link__update_map(struct bpf_link *link, const struct bpf_map *map)12980{12981	struct bpf_link_struct_ops *st_ops_link;12982	__u32 zero = 0;12983	int err;12984 12985	if (!bpf_map__is_struct_ops(map))12986		return -EINVAL;12987 12988	if (map->fd < 0) {12989		pr_warn("map '%s': can't use BPF map without FD (was it created?)\n", map->name);12990		return -EINVAL;12991	}12992 12993	st_ops_link = container_of(link, struct bpf_link_struct_ops, link);12994	/* Ensure the type of a link is correct */12995	if (st_ops_link->map_fd < 0)12996		return -EINVAL;12997 12998	err = bpf_map_update_elem(map->fd, &zero, map->st_ops->kern_vdata, 0);12999	/* It can be EBUSY if the map has been used to create or13000	 * update a link before.  We don't allow updating the value of13001	 * a struct_ops once it is set.  That ensures that the value13002	 * never changed.  So, it is safe to skip EBUSY.13003	 */13004	if (err && err != -EBUSY)13005		return err;13006 13007	err = bpf_link_update(link->fd, map->fd, NULL);13008	if (err < 0)13009		return err;13010 13011	st_ops_link->map_fd = map->fd;13012 13013	return 0;13014}13015 13016typedef enum bpf_perf_event_ret (*bpf_perf_event_print_t)(struct perf_event_header *hdr,13017							  void *private_data);13018 13019static enum bpf_perf_event_ret13020perf_event_read_simple(void *mmap_mem, size_t mmap_size, size_t page_size,13021		       void **copy_mem, size_t *copy_size,13022		       bpf_perf_event_print_t fn, void *private_data)13023{13024	struct perf_event_mmap_page *header = mmap_mem;13025	__u64 data_head = ring_buffer_read_head(header);13026	__u64 data_tail = header->data_tail;13027	void *base = ((__u8 *)header) + page_size;13028	int ret = LIBBPF_PERF_EVENT_CONT;13029	struct perf_event_header *ehdr;13030	size_t ehdr_size;13031 13032	while (data_head != data_tail) {13033		ehdr = base + (data_tail & (mmap_size - 1));13034		ehdr_size = ehdr->size;13035 13036		if (((void *)ehdr) + ehdr_size > base + mmap_size) {13037			void *copy_start = ehdr;13038			size_t len_first = base + mmap_size - copy_start;13039			size_t len_secnd = ehdr_size - len_first;13040 13041			if (*copy_size < ehdr_size) {13042				free(*copy_mem);13043				*copy_mem = malloc(ehdr_size);13044				if (!*copy_mem) {13045					*copy_size = 0;13046					ret = LIBBPF_PERF_EVENT_ERROR;13047					break;13048				}13049				*copy_size = ehdr_size;13050			}13051 13052			memcpy(*copy_mem, copy_start, len_first);13053			memcpy(*copy_mem + len_first, base, len_secnd);13054			ehdr = *copy_mem;13055		}13056 13057		ret = fn(ehdr, private_data);13058		data_tail += ehdr_size;13059		if (ret != LIBBPF_PERF_EVENT_CONT)13060			break;13061	}13062 13063	ring_buffer_write_tail(header, data_tail);13064	return libbpf_err(ret);13065}13066 13067struct perf_buffer;13068 13069struct perf_buffer_params {13070	struct perf_event_attr *attr;13071	/* if event_cb is specified, it takes precendence */13072	perf_buffer_event_fn event_cb;13073	/* sample_cb and lost_cb are higher-level common-case callbacks */13074	perf_buffer_sample_fn sample_cb;13075	perf_buffer_lost_fn lost_cb;13076	void *ctx;13077	int cpu_cnt;13078	int *cpus;13079	int *map_keys;13080};13081 13082struct perf_cpu_buf {13083	struct perf_buffer *pb;13084	void *base; /* mmap()'ed memory */13085	void *buf; /* for reconstructing segmented data */13086	size_t buf_size;13087	int fd;13088	int cpu;13089	int map_key;13090};13091 13092struct perf_buffer {13093	perf_buffer_event_fn event_cb;13094	perf_buffer_sample_fn sample_cb;13095	perf_buffer_lost_fn lost_cb;13096	void *ctx; /* passed into callbacks */13097 13098	size_t page_size;13099	size_t mmap_size;13100	struct perf_cpu_buf **cpu_bufs;13101	struct epoll_event *events;13102	int cpu_cnt; /* number of allocated CPU buffers */13103	int epoll_fd; /* perf event FD */13104	int map_fd; /* BPF_MAP_TYPE_PERF_EVENT_ARRAY BPF map FD */13105};13106 13107static void perf_buffer__free_cpu_buf(struct perf_buffer *pb,13108				      struct perf_cpu_buf *cpu_buf)13109{13110	if (!cpu_buf)13111		return;13112	if (cpu_buf->base &&13113	    munmap(cpu_buf->base, pb->mmap_size + pb->page_size))13114		pr_warn("failed to munmap cpu_buf #%d\n", cpu_buf->cpu);13115	if (cpu_buf->fd >= 0) {13116		ioctl(cpu_buf->fd, PERF_EVENT_IOC_DISABLE, 0);13117		close(cpu_buf->fd);13118	}13119	free(cpu_buf->buf);13120	free(cpu_buf);13121}13122 13123void perf_buffer__free(struct perf_buffer *pb)13124{13125	int i;13126 13127	if (IS_ERR_OR_NULL(pb))13128		return;13129	if (pb->cpu_bufs) {13130		for (i = 0; i < pb->cpu_cnt; i++) {13131			struct perf_cpu_buf *cpu_buf = pb->cpu_bufs[i];13132 13133			if (!cpu_buf)13134				continue;13135 13136			bpf_map_delete_elem(pb->map_fd, &cpu_buf->map_key);13137			perf_buffer__free_cpu_buf(pb, cpu_buf);13138		}13139		free(pb->cpu_bufs);13140	}13141	if (pb->epoll_fd >= 0)13142		close(pb->epoll_fd);13143	free(pb->events);13144	free(pb);13145}13146 13147static struct perf_cpu_buf *13148perf_buffer__open_cpu_buf(struct perf_buffer *pb, struct perf_event_attr *attr,13149			  int cpu, int map_key)13150{13151	struct perf_cpu_buf *cpu_buf;13152	char msg[STRERR_BUFSIZE];13153	int err;13154 13155	cpu_buf = calloc(1, sizeof(*cpu_buf));13156	if (!cpu_buf)13157		return ERR_PTR(-ENOMEM);13158 13159	cpu_buf->pb = pb;13160	cpu_buf->cpu = cpu;13161	cpu_buf->map_key = map_key;13162 13163	cpu_buf->fd = syscall(__NR_perf_event_open, attr, -1 /* pid */, cpu,13164			      -1, PERF_FLAG_FD_CLOEXEC);13165	if (cpu_buf->fd < 0) {13166		err = -errno;13167		pr_warn("failed to open perf buffer event on cpu #%d: %s\n",13168			cpu, libbpf_strerror_r(err, msg, sizeof(msg)));13169		goto error;13170	}13171 13172	cpu_buf->base = mmap(NULL, pb->mmap_size + pb->page_size,13173			     PROT_READ | PROT_WRITE, MAP_SHARED,13174			     cpu_buf->fd, 0);13175	if (cpu_buf->base == MAP_FAILED) {13176		cpu_buf->base = NULL;13177		err = -errno;13178		pr_warn("failed to mmap perf buffer on cpu #%d: %s\n",13179			cpu, libbpf_strerror_r(err, msg, sizeof(msg)));13180		goto error;13181	}13182 13183	if (ioctl(cpu_buf->fd, PERF_EVENT_IOC_ENABLE, 0) < 0) {13184		err = -errno;13185		pr_warn("failed to enable perf buffer event on cpu #%d: %s\n",13186			cpu, libbpf_strerror_r(err, msg, sizeof(msg)));13187		goto error;13188	}13189 13190	return cpu_buf;13191 13192error:13193	perf_buffer__free_cpu_buf(pb, cpu_buf);13194	return (struct perf_cpu_buf *)ERR_PTR(err);13195}13196 13197static struct perf_buffer *__perf_buffer__new(int map_fd, size_t page_cnt,13198					      struct perf_buffer_params *p);13199 13200struct perf_buffer *perf_buffer__new(int map_fd, size_t page_cnt,13201				     perf_buffer_sample_fn sample_cb,13202				     perf_buffer_lost_fn lost_cb,13203				     void *ctx,13204				     const struct perf_buffer_opts *opts)13205{13206	const size_t attr_sz = sizeof(struct perf_event_attr);13207	struct perf_buffer_params p = {};13208	struct perf_event_attr attr;13209	__u32 sample_period;13210 13211	if (!OPTS_VALID(opts, perf_buffer_opts))13212		return libbpf_err_ptr(-EINVAL);13213 13214	sample_period = OPTS_GET(opts, sample_period, 1);13215	if (!sample_period)13216		sample_period = 1;13217 13218	memset(&attr, 0, attr_sz);13219	attr.size = attr_sz;13220	attr.config = PERF_COUNT_SW_BPF_OUTPUT;13221	attr.type = PERF_TYPE_SOFTWARE;13222	attr.sample_type = PERF_SAMPLE_RAW;13223	attr.sample_period = sample_period;13224	attr.wakeup_events = sample_period;13225 13226	p.attr = &attr;13227	p.sample_cb = sample_cb;13228	p.lost_cb = lost_cb;13229	p.ctx = ctx;13230 13231	return libbpf_ptr(__perf_buffer__new(map_fd, page_cnt, &p));13232}13233 13234struct perf_buffer *perf_buffer__new_raw(int map_fd, size_t page_cnt,13235					 struct perf_event_attr *attr,13236					 perf_buffer_event_fn event_cb, void *ctx,13237					 const struct perf_buffer_raw_opts *opts)13238{13239	struct perf_buffer_params p = {};13240 13241	if (!attr)13242		return libbpf_err_ptr(-EINVAL);13243 13244	if (!OPTS_VALID(opts, perf_buffer_raw_opts))13245		return libbpf_err_ptr(-EINVAL);13246 13247	p.attr = attr;13248	p.event_cb = event_cb;13249	p.ctx = ctx;13250	p.cpu_cnt = OPTS_GET(opts, cpu_cnt, 0);13251	p.cpus = OPTS_GET(opts, cpus, NULL);13252	p.map_keys = OPTS_GET(opts, map_keys, NULL);13253 13254	return libbpf_ptr(__perf_buffer__new(map_fd, page_cnt, &p));13255}13256 13257static struct perf_buffer *__perf_buffer__new(int map_fd, size_t page_cnt,13258					      struct perf_buffer_params *p)13259{13260	const char *online_cpus_file = "/sys/devices/system/cpu/online";13261	struct bpf_map_info map;13262	char msg[STRERR_BUFSIZE];13263	struct perf_buffer *pb;13264	bool *online = NULL;13265	__u32 map_info_len;13266	int err, i, j, n;13267 13268	if (page_cnt == 0 || (page_cnt & (page_cnt - 1))) {13269		pr_warn("page count should be power of two, but is %zu\n",13270			page_cnt);13271		return ERR_PTR(-EINVAL);13272	}13273 13274	/* best-effort sanity checks */13275	memset(&map, 0, sizeof(map));13276	map_info_len = sizeof(map);13277	err = bpf_map_get_info_by_fd(map_fd, &map, &map_info_len);13278	if (err) {13279		err = -errno;13280		/* if BPF_OBJ_GET_INFO_BY_FD is supported, will return13281		 * -EBADFD, -EFAULT, or -E2BIG on real error13282		 */13283		if (err != -EINVAL) {13284			pr_warn("failed to get map info for map FD %d: %s\n",13285				map_fd, libbpf_strerror_r(err, msg, sizeof(msg)));13286			return ERR_PTR(err);13287		}13288		pr_debug("failed to get map info for FD %d; API not supported? Ignoring...\n",13289			 map_fd);13290	} else {13291		if (map.type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) {13292			pr_warn("map '%s' should be BPF_MAP_TYPE_PERF_EVENT_ARRAY\n",13293				map.name);13294			return ERR_PTR(-EINVAL);13295		}13296	}13297 13298	pb = calloc(1, sizeof(*pb));13299	if (!pb)13300		return ERR_PTR(-ENOMEM);13301 13302	pb->event_cb = p->event_cb;13303	pb->sample_cb = p->sample_cb;13304	pb->lost_cb = p->lost_cb;13305	pb->ctx = p->ctx;13306 13307	pb->page_size = getpagesize();13308	pb->mmap_size = pb->page_size * page_cnt;13309	pb->map_fd = map_fd;13310 13311	pb->epoll_fd = epoll_create1(EPOLL_CLOEXEC);13312	if (pb->epoll_fd < 0) {13313		err = -errno;13314		pr_warn("failed to create epoll instance: %s\n",13315			libbpf_strerror_r(err, msg, sizeof(msg)));13316		goto error;13317	}13318 13319	if (p->cpu_cnt > 0) {13320		pb->cpu_cnt = p->cpu_cnt;13321	} else {13322		pb->cpu_cnt = libbpf_num_possible_cpus();13323		if (pb->cpu_cnt < 0) {13324			err = pb->cpu_cnt;13325			goto error;13326		}13327		if (map.max_entries && map.max_entries < pb->cpu_cnt)13328			pb->cpu_cnt = map.max_entries;13329	}13330 13331	pb->events = calloc(pb->cpu_cnt, sizeof(*pb->events));13332	if (!pb->events) {13333		err = -ENOMEM;13334		pr_warn("failed to allocate events: out of memory\n");13335		goto error;13336	}13337	pb->cpu_bufs = calloc(pb->cpu_cnt, sizeof(*pb->cpu_bufs));13338	if (!pb->cpu_bufs) {13339		err = -ENOMEM;13340		pr_warn("failed to allocate buffers: out of memory\n");13341		goto error;13342	}13343 13344	err = parse_cpu_mask_file(online_cpus_file, &online, &n);13345	if (err) {13346		pr_warn("failed to get online CPU mask: %d\n", err);13347		goto error;13348	}13349 13350	for (i = 0, j = 0; i < pb->cpu_cnt; i++) {13351		struct perf_cpu_buf *cpu_buf;13352		int cpu, map_key;13353 13354		cpu = p->cpu_cnt > 0 ? p->cpus[i] : i;13355		map_key = p->cpu_cnt > 0 ? p->map_keys[i] : i;13356 13357		/* in case user didn't explicitly requested particular CPUs to13358		 * be attached to, skip offline/not present CPUs13359		 */13360		if (p->cpu_cnt <= 0 && (cpu >= n || !online[cpu]))13361			continue;13362 13363		cpu_buf = perf_buffer__open_cpu_buf(pb, p->attr, cpu, map_key);13364		if (IS_ERR(cpu_buf)) {13365			err = PTR_ERR(cpu_buf);13366			goto error;13367		}13368 13369		pb->cpu_bufs[j] = cpu_buf;13370 13371		err = bpf_map_update_elem(pb->map_fd, &map_key,13372					  &cpu_buf->fd, 0);13373		if (err) {13374			err = -errno;13375			pr_warn("failed to set cpu #%d, key %d -> perf FD %d: %s\n",13376				cpu, map_key, cpu_buf->fd,13377				libbpf_strerror_r(err, msg, sizeof(msg)));13378			goto error;13379		}13380 13381		pb->events[j].events = EPOLLIN;13382		pb->events[j].data.ptr = cpu_buf;13383		if (epoll_ctl(pb->epoll_fd, EPOLL_CTL_ADD, cpu_buf->fd,13384			      &pb->events[j]) < 0) {13385			err = -errno;13386			pr_warn("failed to epoll_ctl cpu #%d perf FD %d: %s\n",13387				cpu, cpu_buf->fd,13388				libbpf_strerror_r(err, msg, sizeof(msg)));13389			goto error;13390		}13391		j++;13392	}13393	pb->cpu_cnt = j;13394	free(online);13395 13396	return pb;13397 13398error:13399	free(online);13400	if (pb)13401		perf_buffer__free(pb);13402	return ERR_PTR(err);13403}13404 13405struct perf_sample_raw {13406	struct perf_event_header header;13407	uint32_t size;13408	char data[];13409};13410 13411struct perf_sample_lost {13412	struct perf_event_header header;13413	uint64_t id;13414	uint64_t lost;13415	uint64_t sample_id;13416};13417 13418static enum bpf_perf_event_ret13419perf_buffer__process_record(struct perf_event_header *e, void *ctx)13420{13421	struct perf_cpu_buf *cpu_buf = ctx;13422	struct perf_buffer *pb = cpu_buf->pb;13423	void *data = e;13424 13425	/* user wants full control over parsing perf event */13426	if (pb->event_cb)13427		return pb->event_cb(pb->ctx, cpu_buf->cpu, e);13428 13429	switch (e->type) {13430	case PERF_RECORD_SAMPLE: {13431		struct perf_sample_raw *s = data;13432 13433		if (pb->sample_cb)13434			pb->sample_cb(pb->ctx, cpu_buf->cpu, s->data, s->size);13435		break;13436	}13437	case PERF_RECORD_LOST: {13438		struct perf_sample_lost *s = data;13439 13440		if (pb->lost_cb)13441			pb->lost_cb(pb->ctx, cpu_buf->cpu, s->lost);13442		break;13443	}13444	default:13445		pr_warn("unknown perf sample type %d\n", e->type);13446		return LIBBPF_PERF_EVENT_ERROR;13447	}13448	return LIBBPF_PERF_EVENT_CONT;13449}13450 13451static int perf_buffer__process_records(struct perf_buffer *pb,13452					struct perf_cpu_buf *cpu_buf)13453{13454	enum bpf_perf_event_ret ret;13455 13456	ret = perf_event_read_simple(cpu_buf->base, pb->mmap_size,13457				     pb->page_size, &cpu_buf->buf,13458				     &cpu_buf->buf_size,13459				     perf_buffer__process_record, cpu_buf);13460	if (ret != LIBBPF_PERF_EVENT_CONT)13461		return ret;13462	return 0;13463}13464 13465int perf_buffer__epoll_fd(const struct perf_buffer *pb)13466{13467	return pb->epoll_fd;13468}13469 13470int perf_buffer__poll(struct perf_buffer *pb, int timeout_ms)13471{13472	int i, cnt, err;13473 13474	cnt = epoll_wait(pb->epoll_fd, pb->events, pb->cpu_cnt, timeout_ms);13475	if (cnt < 0)13476		return -errno;13477 13478	for (i = 0; i < cnt; i++) {13479		struct perf_cpu_buf *cpu_buf = pb->events[i].data.ptr;13480 13481		err = perf_buffer__process_records(pb, cpu_buf);13482		if (err) {13483			pr_warn("error while processing records: %d\n", err);13484			return libbpf_err(err);13485		}13486	}13487	return cnt;13488}13489 13490/* Return number of PERF_EVENT_ARRAY map slots set up by this perf_buffer13491 * manager.13492 */13493size_t perf_buffer__buffer_cnt(const struct perf_buffer *pb)13494{13495	return pb->cpu_cnt;13496}13497 13498/*13499 * Return perf_event FD of a ring buffer in *buf_idx* slot of13500 * PERF_EVENT_ARRAY BPF map. This FD can be polled for new data using13501 * select()/poll()/epoll() Linux syscalls.13502 */13503int perf_buffer__buffer_fd(const struct perf_buffer *pb, size_t buf_idx)13504{13505	struct perf_cpu_buf *cpu_buf;13506 13507	if (buf_idx >= pb->cpu_cnt)13508		return libbpf_err(-EINVAL);13509 13510	cpu_buf = pb->cpu_bufs[buf_idx];13511	if (!cpu_buf)13512		return libbpf_err(-ENOENT);13513 13514	return cpu_buf->fd;13515}13516 13517int perf_buffer__buffer(struct perf_buffer *pb, int buf_idx, void **buf, size_t *buf_size)13518{13519	struct perf_cpu_buf *cpu_buf;13520 13521	if (buf_idx >= pb->cpu_cnt)13522		return libbpf_err(-EINVAL);13523 13524	cpu_buf = pb->cpu_bufs[buf_idx];13525	if (!cpu_buf)13526		return libbpf_err(-ENOENT);13527 13528	*buf = cpu_buf->base;13529	*buf_size = pb->mmap_size;13530	return 0;13531}13532 13533/*13534 * Consume data from perf ring buffer corresponding to slot *buf_idx* in13535 * PERF_EVENT_ARRAY BPF map without waiting/polling. If there is no data to13536 * consume, do nothing and return success.13537 * Returns:13538 *   - 0 on success;13539 *   - <0 on failure.13540 */13541int perf_buffer__consume_buffer(struct perf_buffer *pb, size_t buf_idx)13542{13543	struct perf_cpu_buf *cpu_buf;13544 13545	if (buf_idx >= pb->cpu_cnt)13546		return libbpf_err(-EINVAL);13547 13548	cpu_buf = pb->cpu_bufs[buf_idx];13549	if (!cpu_buf)13550		return libbpf_err(-ENOENT);13551 13552	return perf_buffer__process_records(pb, cpu_buf);13553}13554 13555int perf_buffer__consume(struct perf_buffer *pb)13556{13557	int i, err;13558 13559	for (i = 0; i < pb->cpu_cnt; i++) {13560		struct perf_cpu_buf *cpu_buf = pb->cpu_bufs[i];13561 13562		if (!cpu_buf)13563			continue;13564 13565		err = perf_buffer__process_records(pb, cpu_buf);13566		if (err) {13567			pr_warn("perf_buffer: failed to process records in buffer #%d: %d\n", i, err);13568			return libbpf_err(err);13569		}13570	}13571	return 0;13572}13573 13574int bpf_program__set_attach_target(struct bpf_program *prog,13575				   int attach_prog_fd,13576				   const char *attach_func_name)13577{13578	int btf_obj_fd = 0, btf_id = 0, err;13579 13580	if (!prog || attach_prog_fd < 0)13581		return libbpf_err(-EINVAL);13582 13583	if (prog->obj->loaded)13584		return libbpf_err(-EINVAL);13585 13586	if (attach_prog_fd && !attach_func_name) {13587		/* remember attach_prog_fd and let bpf_program__load() find13588		 * BTF ID during the program load13589		 */13590		prog->attach_prog_fd = attach_prog_fd;13591		return 0;13592	}13593 13594	if (attach_prog_fd) {13595		btf_id = libbpf_find_prog_btf_id(attach_func_name,13596						 attach_prog_fd);13597		if (btf_id < 0)13598			return libbpf_err(btf_id);13599	} else {13600		if (!attach_func_name)13601			return libbpf_err(-EINVAL);13602 13603		/* load btf_vmlinux, if not yet */13604		err = bpf_object__load_vmlinux_btf(prog->obj, true);13605		if (err)13606			return libbpf_err(err);13607		err = find_kernel_btf_id(prog->obj, attach_func_name,13608					 prog->expected_attach_type,13609					 &btf_obj_fd, &btf_id);13610		if (err)13611			return libbpf_err(err);13612	}13613 13614	prog->attach_btf_id = btf_id;13615	prog->attach_btf_obj_fd = btf_obj_fd;13616	prog->attach_prog_fd = attach_prog_fd;13617	return 0;13618}13619 13620int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz)13621{13622	int err = 0, n, len, start, end = -1;13623	bool *tmp;13624 13625	*mask = NULL;13626	*mask_sz = 0;13627 13628	/* Each sub string separated by ',' has format \d+-\d+ or \d+ */13629	while (*s) {13630		if (*s == ',' || *s == '\n') {13631			s++;13632			continue;13633		}13634		n = sscanf(s, "%d%n-%d%n", &start, &len, &end, &len);13635		if (n <= 0 || n > 2) {13636			pr_warn("Failed to get CPU range %s: %d\n", s, n);13637			err = -EINVAL;13638			goto cleanup;13639		} else if (n == 1) {13640			end = start;13641		}13642		if (start < 0 || start > end) {13643			pr_warn("Invalid CPU range [%d,%d] in %s\n",13644				start, end, s);13645			err = -EINVAL;13646			goto cleanup;13647		}13648		tmp = realloc(*mask, end + 1);13649		if (!tmp) {13650			err = -ENOMEM;13651			goto cleanup;13652		}13653		*mask = tmp;13654		memset(tmp + *mask_sz, 0, start - *mask_sz);13655		memset(tmp + start, 1, end - start + 1);13656		*mask_sz = end + 1;13657		s += len;13658	}13659	if (!*mask_sz) {13660		pr_warn("Empty CPU range\n");13661		return -EINVAL;13662	}13663	return 0;13664cleanup:13665	free(*mask);13666	*mask = NULL;13667	return err;13668}13669 13670int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz)13671{13672	int fd, err = 0, len;13673	char buf[128];13674 13675	fd = open(fcpu, O_RDONLY | O_CLOEXEC);13676	if (fd < 0) {13677		err = -errno;13678		pr_warn("Failed to open cpu mask file %s: %d\n", fcpu, err);13679		return err;13680	}13681	len = read(fd, buf, sizeof(buf));13682	close(fd);13683	if (len <= 0) {13684		err = len ? -errno : -EINVAL;13685		pr_warn("Failed to read cpu mask from %s: %d\n", fcpu, err);13686		return err;13687	}13688	if (len >= sizeof(buf)) {13689		pr_warn("CPU mask is too big in file %s\n", fcpu);13690		return -E2BIG;13691	}13692	buf[len] = '\0';13693 13694	return parse_cpu_mask_str(buf, mask, mask_sz);13695}13696 13697int libbpf_num_possible_cpus(void)13698{13699	static const char *fcpu = "/sys/devices/system/cpu/possible";13700	static int cpus;13701	int err, n, i, tmp_cpus;13702	bool *mask;13703 13704	tmp_cpus = READ_ONCE(cpus);13705	if (tmp_cpus > 0)13706		return tmp_cpus;13707 13708	err = parse_cpu_mask_file(fcpu, &mask, &n);13709	if (err)13710		return libbpf_err(err);13711 13712	tmp_cpus = 0;13713	for (i = 0; i < n; i++) {13714		if (mask[i])13715			tmp_cpus++;13716	}13717	free(mask);13718 13719	WRITE_ONCE(cpus, tmp_cpus);13720	return tmp_cpus;13721}13722 13723static int populate_skeleton_maps(const struct bpf_object *obj,13724				  struct bpf_map_skeleton *maps,13725				  size_t map_cnt, size_t map_skel_sz)13726{13727	int i;13728 13729	for (i = 0; i < map_cnt; i++) {13730		struct bpf_map_skeleton *map_skel = (void *)maps + i * map_skel_sz;13731		struct bpf_map **map = map_skel->map;13732		const char *name = map_skel->name;13733		void **mmaped = map_skel->mmaped;13734 13735		*map = bpf_object__find_map_by_name(obj, name);13736		if (!*map) {13737			pr_warn("failed to find skeleton map '%s'\n", name);13738			return -ESRCH;13739		}13740 13741		/* externs shouldn't be pre-setup from user code */13742		if (mmaped && (*map)->libbpf_type != LIBBPF_MAP_KCONFIG)13743			*mmaped = (*map)->mmaped;13744	}13745	return 0;13746}13747 13748static int populate_skeleton_progs(const struct bpf_object *obj,13749				   struct bpf_prog_skeleton *progs,13750				   size_t prog_cnt, size_t prog_skel_sz)13751{13752	int i;13753 13754	for (i = 0; i < prog_cnt; i++) {13755		struct bpf_prog_skeleton *prog_skel = (void *)progs + i * prog_skel_sz;13756		struct bpf_program **prog = prog_skel->prog;13757		const char *name = prog_skel->name;13758 13759		*prog = bpf_object__find_program_by_name(obj, name);13760		if (!*prog) {13761			pr_warn("failed to find skeleton program '%s'\n", name);13762			return -ESRCH;13763		}13764	}13765	return 0;13766}13767 13768int bpf_object__open_skeleton(struct bpf_object_skeleton *s,13769			      const struct bpf_object_open_opts *opts)13770{13771	struct bpf_object *obj;13772	int err;13773 13774	obj = bpf_object_open(NULL, s->data, s->data_sz, s->name, opts);13775	if (IS_ERR(obj)) {13776		err = PTR_ERR(obj);13777		pr_warn("failed to initialize skeleton BPF object '%s': %d\n", s->name, err);13778		return libbpf_err(err);13779	}13780 13781	*s->obj = obj;13782	err = populate_skeleton_maps(obj, s->maps, s->map_cnt, s->map_skel_sz);13783	if (err) {13784		pr_warn("failed to populate skeleton maps for '%s': %d\n", s->name, err);13785		return libbpf_err(err);13786	}13787 13788	err = populate_skeleton_progs(obj, s->progs, s->prog_cnt, s->prog_skel_sz);13789	if (err) {13790		pr_warn("failed to populate skeleton progs for '%s': %d\n", s->name, err);13791		return libbpf_err(err);13792	}13793 13794	return 0;13795}13796 13797int bpf_object__open_subskeleton(struct bpf_object_subskeleton *s)13798{13799	int err, len, var_idx, i;13800	const char *var_name;13801	const struct bpf_map *map;13802	struct btf *btf;13803	__u32 map_type_id;13804	const struct btf_type *map_type, *var_type;13805	const struct bpf_var_skeleton *var_skel;13806	struct btf_var_secinfo *var;13807 13808	if (!s->obj)13809		return libbpf_err(-EINVAL);13810 13811	btf = bpf_object__btf(s->obj);13812	if (!btf) {13813		pr_warn("subskeletons require BTF at runtime (object %s)\n",13814			bpf_object__name(s->obj));13815		return libbpf_err(-errno);13816	}13817 13818	err = populate_skeleton_maps(s->obj, s->maps, s->map_cnt, s->map_skel_sz);13819	if (err) {13820		pr_warn("failed to populate subskeleton maps: %d\n", err);13821		return libbpf_err(err);13822	}13823 13824	err = populate_skeleton_progs(s->obj, s->progs, s->prog_cnt, s->prog_skel_sz);13825	if (err) {13826		pr_warn("failed to populate subskeleton maps: %d\n", err);13827		return libbpf_err(err);13828	}13829 13830	for (var_idx = 0; var_idx < s->var_cnt; var_idx++) {13831		var_skel = (void *)s->vars + var_idx * s->var_skel_sz;13832		map = *var_skel->map;13833		map_type_id = bpf_map__btf_value_type_id(map);13834		map_type = btf__type_by_id(btf, map_type_id);13835 13836		if (!btf_is_datasec(map_type)) {13837			pr_warn("type for map '%1$s' is not a datasec: %2$s",13838				bpf_map__name(map),13839				__btf_kind_str(btf_kind(map_type)));13840			return libbpf_err(-EINVAL);13841		}13842 13843		len = btf_vlen(map_type);13844		var = btf_var_secinfos(map_type);13845		for (i = 0; i < len; i++, var++) {13846			var_type = btf__type_by_id(btf, var->type);13847			var_name = btf__name_by_offset(btf, var_type->name_off);13848			if (strcmp(var_name, var_skel->name) == 0) {13849				*var_skel->addr = map->mmaped + var->offset;13850				break;13851			}13852		}13853	}13854	return 0;13855}13856 13857void bpf_object__destroy_subskeleton(struct bpf_object_subskeleton *s)13858{13859	if (!s)13860		return;13861	free(s->maps);13862	free(s->progs);13863	free(s->vars);13864	free(s);13865}13866 13867int bpf_object__load_skeleton(struct bpf_object_skeleton *s)13868{13869	int i, err;13870 13871	err = bpf_object__load(*s->obj);13872	if (err) {13873		pr_warn("failed to load BPF skeleton '%s': %d\n", s->name, err);13874		return libbpf_err(err);13875	}13876 13877	for (i = 0; i < s->map_cnt; i++) {13878		struct bpf_map_skeleton *map_skel = (void *)s->maps + i * s->map_skel_sz;13879		struct bpf_map *map = *map_skel->map;13880		size_t mmap_sz = bpf_map_mmap_sz(map);13881		int prot, map_fd = map->fd;13882		void **mmaped = map_skel->mmaped;13883 13884		if (!mmaped)13885			continue;13886 13887		if (!(map->def.map_flags & BPF_F_MMAPABLE)) {13888			*mmaped = NULL;13889			continue;13890		}13891 13892		if (map->def.type == BPF_MAP_TYPE_ARENA) {13893			*mmaped = map->mmaped;13894			continue;13895		}13896 13897		if (map->def.map_flags & BPF_F_RDONLY_PROG)13898			prot = PROT_READ;13899		else13900			prot = PROT_READ | PROT_WRITE;13901 13902		/* Remap anonymous mmap()-ed "map initialization image" as13903		 * a BPF map-backed mmap()-ed memory, but preserving the same13904		 * memory address. This will cause kernel to change process'13905		 * page table to point to a different piece of kernel memory,13906		 * but from userspace point of view memory address (and its13907		 * contents, being identical at this point) will stay the13908		 * same. This mapping will be released by bpf_object__close()13909		 * as per normal clean up procedure, so we don't need to worry13910		 * about it from skeleton's clean up perspective.13911		 */13912		*mmaped = mmap(map->mmaped, mmap_sz, prot, MAP_SHARED | MAP_FIXED, map_fd, 0);13913		if (*mmaped == MAP_FAILED) {13914			err = -errno;13915			*mmaped = NULL;13916			pr_warn("failed to re-mmap() map '%s': %d\n",13917				 bpf_map__name(map), err);13918			return libbpf_err(err);13919		}13920	}13921 13922	return 0;13923}13924 13925int bpf_object__attach_skeleton(struct bpf_object_skeleton *s)13926{13927	int i, err;13928 13929	for (i = 0; i < s->prog_cnt; i++) {13930		struct bpf_prog_skeleton *prog_skel = (void *)s->progs + i * s->prog_skel_sz;13931		struct bpf_program *prog = *prog_skel->prog;13932		struct bpf_link **link = prog_skel->link;13933 13934		if (!prog->autoload || !prog->autoattach)13935			continue;13936 13937		/* auto-attaching not supported for this program */13938		if (!prog->sec_def || !prog->sec_def->prog_attach_fn)13939			continue;13940 13941		/* if user already set the link manually, don't attempt auto-attach */13942		if (*link)13943			continue;13944 13945		err = prog->sec_def->prog_attach_fn(prog, prog->sec_def->cookie, link);13946		if (err) {13947			pr_warn("prog '%s': failed to auto-attach: %d\n",13948				bpf_program__name(prog), err);13949			return libbpf_err(err);13950		}13951 13952		/* It's possible that for some SEC() definitions auto-attach13953		 * is supported in some cases (e.g., if definition completely13954		 * specifies target information), but is not in other cases.13955		 * SEC("uprobe") is one such case. If user specified target13956		 * binary and function name, such BPF program can be13957		 * auto-attached. But if not, it shouldn't trigger skeleton's13958		 * attach to fail. It should just be skipped.13959		 * attach_fn signals such case with returning 0 (no error) and13960		 * setting link to NULL.13961		 */13962	}13963 13964 13965	for (i = 0; i < s->map_cnt; i++) {13966		struct bpf_map_skeleton *map_skel = (void *)s->maps + i * s->map_skel_sz;13967		struct bpf_map *map = *map_skel->map;13968		struct bpf_link **link;13969 13970		if (!map->autocreate || !map->autoattach)13971			continue;13972 13973		/* only struct_ops maps can be attached */13974		if (!bpf_map__is_struct_ops(map))13975			continue;13976 13977		/* skeleton is created with earlier version of bpftool, notify user */13978		if (s->map_skel_sz < offsetofend(struct bpf_map_skeleton, link)) {13979			pr_warn("map '%s': BPF skeleton version is old, skipping map auto-attachment...\n",13980				bpf_map__name(map));13981			continue;13982		}13983 13984		link = map_skel->link;13985		if (*link)13986			continue;13987 13988		*link = bpf_map__attach_struct_ops(map);13989		if (!*link) {13990			err = -errno;13991			pr_warn("map '%s': failed to auto-attach: %d\n", bpf_map__name(map), err);13992			return libbpf_err(err);13993		}13994	}13995 13996	return 0;13997}13998 13999void bpf_object__detach_skeleton(struct bpf_object_skeleton *s)14000{14001	int i;14002 14003	for (i = 0; i < s->prog_cnt; i++) {14004		struct bpf_prog_skeleton *prog_skel = (void *)s->progs + i * s->prog_skel_sz;14005		struct bpf_link **link = prog_skel->link;14006 14007		bpf_link__destroy(*link);14008		*link = NULL;14009	}14010 14011	if (s->map_skel_sz < sizeof(struct bpf_map_skeleton))14012		return;14013 14014	for (i = 0; i < s->map_cnt; i++) {14015		struct bpf_map_skeleton *map_skel = (void *)s->maps + i * s->map_skel_sz;14016		struct bpf_link **link = map_skel->link;14017 14018		if (link) {14019			bpf_link__destroy(*link);14020			*link = NULL;14021		}14022	}14023}14024 14025void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s)14026{14027	if (!s)14028		return;14029 14030	bpf_object__detach_skeleton(s);14031	if (s->obj)14032		bpf_object__close(*s->obj);14033	free(s->maps);14034	free(s->progs);14035	free(s);14036}14037