Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
   1/*
   2 * Common eBPF ELF object loading operations.
   3 *
   4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
   5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
   6 * Copyright (C) 2015 Huawei Inc.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU Lesser General Public
  10 * License as published by the Free Software Foundation;
  11 * version 2.1 of the License (not later!)
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU Lesser General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU Lesser General Public
  19 * License along with this program; if not,  see <http://www.gnu.org/licenses>
  20 */
  21
  22#include <stdlib.h>
  23#include <stdio.h>
  24#include <stdarg.h>
  25#include <inttypes.h>
  26#include <string.h>
  27#include <unistd.h>
  28#include <fcntl.h>
  29#include <errno.h>
  30#include <asm/unistd.h>
  31#include <linux/kernel.h>
  32#include <linux/bpf.h>
  33#include <linux/list.h>
  34#include <libelf.h>
  35#include <gelf.h>
  36
  37#include "libbpf.h"
  38#include "bpf.h"
  39
  40#ifndef EM_BPF
  41#define EM_BPF 247
  42#endif
  43
  44#define __printf(a, b)	__attribute__((format(printf, a, b)))
  45
  46__printf(1, 2)
  47static int __base_pr(const char *format, ...)
  48{
  49	va_list args;
  50	int err;
  51
  52	va_start(args, format);
  53	err = vfprintf(stderr, format, args);
  54	va_end(args);
  55	return err;
  56}
  57
  58static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr;
  59static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr;
  60static __printf(1, 2) libbpf_print_fn_t __pr_debug;
  61
  62#define __pr(func, fmt, ...)	\
  63do {				\
  64	if ((func))		\
  65		(func)("libbpf: " fmt, ##__VA_ARGS__); \
  66} while (0)
  67
  68#define pr_warning(fmt, ...)	__pr(__pr_warning, fmt, ##__VA_ARGS__)
  69#define pr_info(fmt, ...)	__pr(__pr_info, fmt, ##__VA_ARGS__)
  70#define pr_debug(fmt, ...)	__pr(__pr_debug, fmt, ##__VA_ARGS__)
  71
  72void libbpf_set_print(libbpf_print_fn_t warn,
  73		      libbpf_print_fn_t info,
  74		      libbpf_print_fn_t debug)
  75{
  76	__pr_warning = warn;
  77	__pr_info = info;
  78	__pr_debug = debug;
  79}
  80
  81#define STRERR_BUFSIZE  128
  82
  83#define ERRNO_OFFSET(e)		((e) - __LIBBPF_ERRNO__START)
  84#define ERRCODE_OFFSET(c)	ERRNO_OFFSET(LIBBPF_ERRNO__##c)
  85#define NR_ERRNO	(__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
  86
  87static const char *libbpf_strerror_table[NR_ERRNO] = {
  88	[ERRCODE_OFFSET(LIBELF)]	= "Something wrong in libelf",
  89	[ERRCODE_OFFSET(FORMAT)]	= "BPF object format invalid",
  90	[ERRCODE_OFFSET(KVERSION)]	= "'version' section incorrect or lost",
  91	[ERRCODE_OFFSET(ENDIAN)]	= "Endian mismatch",
  92	[ERRCODE_OFFSET(INTERNAL)]	= "Internal error in libbpf",
  93	[ERRCODE_OFFSET(RELOC)]		= "Relocation failed",
  94	[ERRCODE_OFFSET(VERIFY)]	= "Kernel verifier blocks program loading",
  95	[ERRCODE_OFFSET(PROG2BIG)]	= "Program too big",
  96	[ERRCODE_OFFSET(KVER)]		= "Incorrect kernel version",
  97	[ERRCODE_OFFSET(PROGTYPE)]	= "Kernel doesn't support this program type",
  98};
  99
 100int libbpf_strerror(int err, char *buf, size_t size)
 101{
 102	if (!buf || !size)
 103		return -1;
 104
 105	err = err > 0 ? err : -err;
 106
 107	if (err < __LIBBPF_ERRNO__START) {
 108		int ret;
 109
 110		ret = strerror_r(err, buf, size);
 111		buf[size - 1] = '\0';
 112		return ret;
 113	}
 114
 115	if (err < __LIBBPF_ERRNO__END) {
 116		const char *msg;
 117
 118		msg = libbpf_strerror_table[ERRNO_OFFSET(err)];
 119		snprintf(buf, size, "%s", msg);
 120		buf[size - 1] = '\0';
 121		return 0;
 122	}
 123
 124	snprintf(buf, size, "Unknown libbpf error %d", err);
 125	buf[size - 1] = '\0';
 126	return -1;
 127}
 128
 129#define CHECK_ERR(action, err, out) do {	\
 130	err = action;			\
 131	if (err)			\
 132		goto out;		\
 133} while(0)
 134
 135
 136/* Copied from tools/perf/util/util.h */
 137#ifndef zfree
 138# define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
 139#endif
 140
 141#ifndef zclose
 142# define zclose(fd) ({			\
 143	int ___err = 0;			\
 144	if ((fd) >= 0)			\
 145		___err = close((fd));	\
 146	fd = -1;			\
 147	___err; })
 148#endif
 149
 150#ifdef HAVE_LIBELF_MMAP_SUPPORT
 151# define LIBBPF_ELF_C_READ_MMAP ELF_C_READ_MMAP
 152#else
 153# define LIBBPF_ELF_C_READ_MMAP ELF_C_READ
 154#endif
 155
 156/*
 157 * bpf_prog should be a better name but it has been used in
 158 * linux/filter.h.
 159 */
 160struct bpf_program {
 161	/* Index in elf obj file, for relocation use. */
 162	int idx;
 163	char *section_name;
 164	struct bpf_insn *insns;
 165	size_t insns_cnt;
 166	enum bpf_prog_type type;
 167
 168	struct {
 169		int insn_idx;
 170		int map_idx;
 171	} *reloc_desc;
 172	int nr_reloc;
 173
 174	struct {
 175		int nr;
 176		int *fds;
 177	} instances;
 178	bpf_program_prep_t preprocessor;
 179
 180	struct bpf_object *obj;
 181	void *priv;
 182	bpf_program_clear_priv_t clear_priv;
 183};
 184
 185struct bpf_map {
 186	int fd;
 187	char *name;
 188	size_t offset;
 189	struct bpf_map_def def;
 190	void *priv;
 191	bpf_map_clear_priv_t clear_priv;
 192};
 193
 194static LIST_HEAD(bpf_objects_list);
 195
 196struct bpf_object {
 197	char license[64];
 198	u32 kern_version;
 199
 200	struct bpf_program *programs;
 201	size_t nr_programs;
 202	struct bpf_map *maps;
 203	size_t nr_maps;
 204
 205	bool loaded;
 206
 207	/*
 208	 * Information when doing elf related work. Only valid if fd
 209	 * is valid.
 210	 */
 211	struct {
 212		int fd;
 213		void *obj_buf;
 214		size_t obj_buf_sz;
 215		Elf *elf;
 216		GElf_Ehdr ehdr;
 217		Elf_Data *symbols;
 218		size_t strtabidx;
 219		struct {
 220			GElf_Shdr shdr;
 221			Elf_Data *data;
 222		} *reloc;
 223		int nr_reloc;
 224		int maps_shndx;
 225	} efile;
 226	/*
 227	 * All loaded bpf_object is linked in a list, which is
 228	 * hidden to caller. bpf_objects__<func> handlers deal with
 229	 * all objects.
 230	 */
 231	struct list_head list;
 232
 233	void *priv;
 234	bpf_object_clear_priv_t clear_priv;
 235
 236	char path[];
 237};
 238#define obj_elf_valid(o)	((o)->efile.elf)
 239
 240static void bpf_program__unload(struct bpf_program *prog)
 241{
 242	int i;
 243
 244	if (!prog)
 245		return;
 246
 247	/*
 248	 * If the object is opened but the program was never loaded,
 249	 * it is possible that prog->instances.nr == -1.
 250	 */
 251	if (prog->instances.nr > 0) {
 252		for (i = 0; i < prog->instances.nr; i++)
 253			zclose(prog->instances.fds[i]);
 254	} else if (prog->instances.nr != -1) {
 255		pr_warning("Internal error: instances.nr is %d\n",
 256			   prog->instances.nr);
 257	}
 258
 259	prog->instances.nr = -1;
 260	zfree(&prog->instances.fds);
 261}
 262
 263static void bpf_program__exit(struct bpf_program *prog)
 264{
 265	if (!prog)
 266		return;
 267
 268	if (prog->clear_priv)
 269		prog->clear_priv(prog, prog->priv);
 270
 271	prog->priv = NULL;
 272	prog->clear_priv = NULL;
 273
 274	bpf_program__unload(prog);
 275	zfree(&prog->section_name);
 276	zfree(&prog->insns);
 277	zfree(&prog->reloc_desc);
 278
 279	prog->nr_reloc = 0;
 280	prog->insns_cnt = 0;
 281	prog->idx = -1;
 282}
 283
 284static int
 285bpf_program__init(void *data, size_t size, char *name, int idx,
 286		    struct bpf_program *prog)
 287{
 288	if (size < sizeof(struct bpf_insn)) {
 289		pr_warning("corrupted section '%s'\n", name);
 290		return -EINVAL;
 291	}
 292
 293	bzero(prog, sizeof(*prog));
 294
 295	prog->section_name = strdup(name);
 296	if (!prog->section_name) {
 297		pr_warning("failed to alloc name for prog %s\n",
 298			   name);
 299		goto errout;
 300	}
 301
 302	prog->insns = malloc(size);
 303	if (!prog->insns) {
 304		pr_warning("failed to alloc insns for %s\n", name);
 305		goto errout;
 306	}
 307	prog->insns_cnt = size / sizeof(struct bpf_insn);
 308	memcpy(prog->insns, data,
 309	       prog->insns_cnt * sizeof(struct bpf_insn));
 310	prog->idx = idx;
 311	prog->instances.fds = NULL;
 312	prog->instances.nr = -1;
 313	prog->type = BPF_PROG_TYPE_KPROBE;
 314
 315	return 0;
 316errout:
 317	bpf_program__exit(prog);
 318	return -ENOMEM;
 319}
 320
 321static int
 322bpf_object__add_program(struct bpf_object *obj, void *data, size_t size,
 323			char *name, int idx)
 324{
 325	struct bpf_program prog, *progs;
 326	int nr_progs, err;
 327
 328	err = bpf_program__init(data, size, name, idx, &prog);
 329	if (err)
 330		return err;
 331
 332	progs = obj->programs;
 333	nr_progs = obj->nr_programs;
 334
 335	progs = realloc(progs, sizeof(progs[0]) * (nr_progs + 1));
 336	if (!progs) {
 337		/*
 338		 * In this case the original obj->programs
 339		 * is still valid, so don't need special treat for
 340		 * bpf_close_object().
 341		 */
 342		pr_warning("failed to alloc a new program '%s'\n",
 343			   name);
 344		bpf_program__exit(&prog);
 345		return -ENOMEM;
 346	}
 347
 348	pr_debug("found program %s\n", prog.section_name);
 349	obj->programs = progs;
 350	obj->nr_programs = nr_progs + 1;
 351	prog.obj = obj;
 352	progs[nr_progs] = prog;
 353	return 0;
 354}
 355
 356static struct bpf_object *bpf_object__new(const char *path,
 357					  void *obj_buf,
 358					  size_t obj_buf_sz)
 359{
 360	struct bpf_object *obj;
 361
 362	obj = calloc(1, sizeof(struct bpf_object) + strlen(path) + 1);
 363	if (!obj) {
 364		pr_warning("alloc memory failed for %s\n", path);
 365		return ERR_PTR(-ENOMEM);
 366	}
 367
 368	strcpy(obj->path, path);
 369	obj->efile.fd = -1;
 370
 371	/*
 372	 * Caller of this function should also calls
 373	 * bpf_object__elf_finish() after data collection to return
 374	 * obj_buf to user. If not, we should duplicate the buffer to
 375	 * avoid user freeing them before elf finish.
 376	 */
 377	obj->efile.obj_buf = obj_buf;
 378	obj->efile.obj_buf_sz = obj_buf_sz;
 379	obj->efile.maps_shndx = -1;
 380
 381	obj->loaded = false;
 382
 383	INIT_LIST_HEAD(&obj->list);
 384	list_add(&obj->list, &bpf_objects_list);
 385	return obj;
 386}
 387
 388static void bpf_object__elf_finish(struct bpf_object *obj)
 389{
 390	if (!obj_elf_valid(obj))
 391		return;
 392
 393	if (obj->efile.elf) {
 394		elf_end(obj->efile.elf);
 395		obj->efile.elf = NULL;
 396	}
 397	obj->efile.symbols = NULL;
 398
 399	zfree(&obj->efile.reloc);
 400	obj->efile.nr_reloc = 0;
 401	zclose(obj->efile.fd);
 402	obj->efile.obj_buf = NULL;
 403	obj->efile.obj_buf_sz = 0;
 404}
 405
 406static int bpf_object__elf_init(struct bpf_object *obj)
 407{
 408	int err = 0;
 409	GElf_Ehdr *ep;
 410
 411	if (obj_elf_valid(obj)) {
 412		pr_warning("elf init: internal error\n");
 413		return -LIBBPF_ERRNO__LIBELF;
 414	}
 415
 416	if (obj->efile.obj_buf_sz > 0) {
 417		/*
 418		 * obj_buf should have been validated by
 419		 * bpf_object__open_buffer().
 420		 */
 421		obj->efile.elf = elf_memory(obj->efile.obj_buf,
 422					    obj->efile.obj_buf_sz);
 423	} else {
 424		obj->efile.fd = open(obj->path, O_RDONLY);
 425		if (obj->efile.fd < 0) {
 426			pr_warning("failed to open %s: %s\n", obj->path,
 427					strerror(errno));
 428			return -errno;
 429		}
 430
 431		obj->efile.elf = elf_begin(obj->efile.fd,
 432				LIBBPF_ELF_C_READ_MMAP,
 433				NULL);
 434	}
 435
 436	if (!obj->efile.elf) {
 437		pr_warning("failed to open %s as ELF file\n",
 438				obj->path);
 439		err = -LIBBPF_ERRNO__LIBELF;
 440		goto errout;
 441	}
 442
 443	if (!gelf_getehdr(obj->efile.elf, &obj->efile.ehdr)) {
 444		pr_warning("failed to get EHDR from %s\n",
 445				obj->path);
 446		err = -LIBBPF_ERRNO__FORMAT;
 447		goto errout;
 448	}
 449	ep = &obj->efile.ehdr;
 450
 451	/* Old LLVM set e_machine to EM_NONE */
 452	if ((ep->e_type != ET_REL) || (ep->e_machine && (ep->e_machine != EM_BPF))) {
 453		pr_warning("%s is not an eBPF object file\n",
 454			obj->path);
 455		err = -LIBBPF_ERRNO__FORMAT;
 456		goto errout;
 457	}
 458
 459	return 0;
 460errout:
 461	bpf_object__elf_finish(obj);
 462	return err;
 463}
 464
 465static int
 466bpf_object__check_endianness(struct bpf_object *obj)
 467{
 468	static unsigned int const endian = 1;
 469
 470	switch (obj->efile.ehdr.e_ident[EI_DATA]) {
 471	case ELFDATA2LSB:
 472		/* We are big endian, BPF obj is little endian. */
 473		if (*(unsigned char const *)&endian != 1)
 474			goto mismatch;
 475		break;
 476
 477	case ELFDATA2MSB:
 478		/* We are little endian, BPF obj is big endian. */
 479		if (*(unsigned char const *)&endian != 0)
 480			goto mismatch;
 481		break;
 482	default:
 483		return -LIBBPF_ERRNO__ENDIAN;
 484	}
 485
 486	return 0;
 487
 488mismatch:
 489	pr_warning("Error: endianness mismatch.\n");
 490	return -LIBBPF_ERRNO__ENDIAN;
 491}
 492
 493static int
 494bpf_object__init_license(struct bpf_object *obj,
 495			 void *data, size_t size)
 496{
 497	memcpy(obj->license, data,
 498	       min(size, sizeof(obj->license) - 1));
 499	pr_debug("license of %s is %s\n", obj->path, obj->license);
 500	return 0;
 501}
 502
 503static int
 504bpf_object__init_kversion(struct bpf_object *obj,
 505			  void *data, size_t size)
 506{
 507	u32 kver;
 508
 509	if (size != sizeof(kver)) {
 510		pr_warning("invalid kver section in %s\n", obj->path);
 511		return -LIBBPF_ERRNO__FORMAT;
 512	}
 513	memcpy(&kver, data, sizeof(kver));
 514	obj->kern_version = kver;
 515	pr_debug("kernel version of %s is %x\n", obj->path,
 516		 obj->kern_version);
 517	return 0;
 518}
 519
 520static int
 521bpf_object__validate_maps(struct bpf_object *obj)
 522{
 523	int i;
 524
 525	/*
 526	 * If there's only 1 map, the only error case should have been
 527	 * catched in bpf_object__init_maps().
 528	 */
 529	if (!obj->maps || !obj->nr_maps || (obj->nr_maps == 1))
 530		return 0;
 531
 532	for (i = 1; i < obj->nr_maps; i++) {
 533		const struct bpf_map *a = &obj->maps[i - 1];
 534		const struct bpf_map *b = &obj->maps[i];
 535
 536		if (b->offset - a->offset < sizeof(struct bpf_map_def)) {
 537			pr_warning("corrupted map section in %s: map \"%s\" too small\n",
 538				   obj->path, a->name);
 539			return -EINVAL;
 540		}
 541	}
 542	return 0;
 543}
 544
 545static int compare_bpf_map(const void *_a, const void *_b)
 546{
 547	const struct bpf_map *a = _a;
 548	const struct bpf_map *b = _b;
 549
 550	return a->offset - b->offset;
 551}
 552
 553static int
 554bpf_object__init_maps(struct bpf_object *obj)
 555{
 556	int i, map_idx, nr_maps = 0;
 557	Elf_Scn *scn;
 558	Elf_Data *data;
 559	Elf_Data *symbols = obj->efile.symbols;
 560
 561	if (obj->efile.maps_shndx < 0)
 562		return -EINVAL;
 563	if (!symbols)
 564		return -EINVAL;
 565
 566	scn = elf_getscn(obj->efile.elf, obj->efile.maps_shndx);
 567	if (scn)
 568		data = elf_getdata(scn, NULL);
 569	if (!scn || !data) {
 570		pr_warning("failed to get Elf_Data from map section %d\n",
 571			   obj->efile.maps_shndx);
 572		return -EINVAL;
 573	}
 574
 575	/*
 576	 * Count number of maps. Each map has a name.
 577	 * Array of maps is not supported: only the first element is
 578	 * considered.
 579	 *
 580	 * TODO: Detect array of map and report error.
 581	 */
 582	for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) {
 583		GElf_Sym sym;
 584
 585		if (!gelf_getsym(symbols, i, &sym))
 586			continue;
 587		if (sym.st_shndx != obj->efile.maps_shndx)
 588			continue;
 589		nr_maps++;
 590	}
 591
 592	/* Alloc obj->maps and fill nr_maps. */
 593	pr_debug("maps in %s: %d maps in %zd bytes\n", obj->path,
 594		 nr_maps, data->d_size);
 595
 596	if (!nr_maps)
 597		return 0;
 598
 599	obj->maps = calloc(nr_maps, sizeof(obj->maps[0]));
 600	if (!obj->maps) {
 601		pr_warning("alloc maps for object failed\n");
 602		return -ENOMEM;
 603	}
 604	obj->nr_maps = nr_maps;
 605
 606	/*
 607	 * fill all fd with -1 so won't close incorrect
 608	 * fd (fd=0 is stdin) when failure (zclose won't close
 609	 * negative fd)).
 610	 */
 611	for (i = 0; i < nr_maps; i++)
 612		obj->maps[i].fd = -1;
 613
 614	/*
 615	 * Fill obj->maps using data in "maps" section.
 616	 */
 617	for (i = 0, map_idx = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) {
 618		GElf_Sym sym;
 619		const char *map_name;
 620		struct bpf_map_def *def;
 621
 622		if (!gelf_getsym(symbols, i, &sym))
 623			continue;
 624		if (sym.st_shndx != obj->efile.maps_shndx)
 625			continue;
 626
 627		map_name = elf_strptr(obj->efile.elf,
 628				      obj->efile.strtabidx,
 629				      sym.st_name);
 630		obj->maps[map_idx].offset = sym.st_value;
 631		if (sym.st_value + sizeof(struct bpf_map_def) > data->d_size) {
 632			pr_warning("corrupted maps section in %s: last map \"%s\" too small\n",
 633				   obj->path, map_name);
 634			return -EINVAL;
 635		}
 636
 637		obj->maps[map_idx].name = strdup(map_name);
 638		if (!obj->maps[map_idx].name) {
 639			pr_warning("failed to alloc map name\n");
 640			return -ENOMEM;
 641		}
 642		pr_debug("map %d is \"%s\"\n", map_idx,
 643			 obj->maps[map_idx].name);
 644		def = (struct bpf_map_def *)(data->d_buf + sym.st_value);
 645		obj->maps[map_idx].def = *def;
 646		map_idx++;
 647	}
 648
 649	qsort(obj->maps, obj->nr_maps, sizeof(obj->maps[0]), compare_bpf_map);
 650	return bpf_object__validate_maps(obj);
 651}
 652
 653static int bpf_object__elf_collect(struct bpf_object *obj)
 654{
 655	Elf *elf = obj->efile.elf;
 656	GElf_Ehdr *ep = &obj->efile.ehdr;
 657	Elf_Scn *scn = NULL;
 658	int idx = 0, err = 0;
 659
 660	/* Elf is corrupted/truncated, avoid calling elf_strptr. */
 661	if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) {
 662		pr_warning("failed to get e_shstrndx from %s\n",
 663			   obj->path);
 664		return -LIBBPF_ERRNO__FORMAT;
 665	}
 666
 667	while ((scn = elf_nextscn(elf, scn)) != NULL) {
 668		char *name;
 669		GElf_Shdr sh;
 670		Elf_Data *data;
 671
 672		idx++;
 673		if (gelf_getshdr(scn, &sh) != &sh) {
 674			pr_warning("failed to get section header from %s\n",
 675				   obj->path);
 676			err = -LIBBPF_ERRNO__FORMAT;
 677			goto out;
 678		}
 679
 680		name = elf_strptr(elf, ep->e_shstrndx, sh.sh_name);
 681		if (!name) {
 682			pr_warning("failed to get section name from %s\n",
 683				   obj->path);
 684			err = -LIBBPF_ERRNO__FORMAT;
 685			goto out;
 686		}
 687
 688		data = elf_getdata(scn, 0);
 689		if (!data) {
 690			pr_warning("failed to get section data from %s(%s)\n",
 691				   name, obj->path);
 692			err = -LIBBPF_ERRNO__FORMAT;
 693			goto out;
 694		}
 695		pr_debug("section %s, size %ld, link %d, flags %lx, type=%d\n",
 696			 name, (unsigned long)data->d_size,
 697			 (int)sh.sh_link, (unsigned long)sh.sh_flags,
 698			 (int)sh.sh_type);
 699
 700		if (strcmp(name, "license") == 0)
 701			err = bpf_object__init_license(obj,
 702						       data->d_buf,
 703						       data->d_size);
 704		else if (strcmp(name, "version") == 0)
 705			err = bpf_object__init_kversion(obj,
 706							data->d_buf,
 707							data->d_size);
 708		else if (strcmp(name, "maps") == 0)
 709			obj->efile.maps_shndx = idx;
 710		else if (sh.sh_type == SHT_SYMTAB) {
 711			if (obj->efile.symbols) {
 712				pr_warning("bpf: multiple SYMTAB in %s\n",
 713					   obj->path);
 714				err = -LIBBPF_ERRNO__FORMAT;
 715			} else {
 716				obj->efile.symbols = data;
 717				obj->efile.strtabidx = sh.sh_link;
 718			}
 719		} else if ((sh.sh_type == SHT_PROGBITS) &&
 720			   (sh.sh_flags & SHF_EXECINSTR) &&
 721			   (data->d_size > 0)) {
 722			err = bpf_object__add_program(obj, data->d_buf,
 723						      data->d_size, name, idx);
 724			if (err) {
 725				char errmsg[STRERR_BUFSIZE];
 726
 727				strerror_r(-err, errmsg, sizeof(errmsg));
 728				pr_warning("failed to alloc program %s (%s): %s",
 729					   name, obj->path, errmsg);
 730			}
 731		} else if (sh.sh_type == SHT_REL) {
 732			void *reloc = obj->efile.reloc;
 733			int nr_reloc = obj->efile.nr_reloc + 1;
 734
 735			reloc = realloc(reloc,
 736					sizeof(*obj->efile.reloc) * nr_reloc);
 737			if (!reloc) {
 738				pr_warning("realloc failed\n");
 739				err = -ENOMEM;
 740			} else {
 741				int n = nr_reloc - 1;
 742
 743				obj->efile.reloc = reloc;
 744				obj->efile.nr_reloc = nr_reloc;
 745
 746				obj->efile.reloc[n].shdr = sh;
 747				obj->efile.reloc[n].data = data;
 748			}
 749		}
 750		if (err)
 751			goto out;
 752	}
 753
 754	if (!obj->efile.strtabidx || obj->efile.strtabidx >= idx) {
 755		pr_warning("Corrupted ELF file: index of strtab invalid\n");
 756		return LIBBPF_ERRNO__FORMAT;
 757	}
 758	if (obj->efile.maps_shndx >= 0)
 759		err = bpf_object__init_maps(obj);
 760out:
 761	return err;
 762}
 763
 764static struct bpf_program *
 765bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx)
 766{
 767	struct bpf_program *prog;
 768	size_t i;
 769
 770	for (i = 0; i < obj->nr_programs; i++) {
 771		prog = &obj->programs[i];
 772		if (prog->idx == idx)
 773			return prog;
 774	}
 775	return NULL;
 776}
 777
 778static int
 779bpf_program__collect_reloc(struct bpf_program *prog,
 780			   size_t nr_maps, GElf_Shdr *shdr,
 781			   Elf_Data *data, Elf_Data *symbols,
 782			   int maps_shndx)
 783{
 784	int i, nrels;
 785
 786	pr_debug("collecting relocating info for: '%s'\n",
 787		 prog->section_name);
 788	nrels = shdr->sh_size / shdr->sh_entsize;
 789
 790	prog->reloc_desc = malloc(sizeof(*prog->reloc_desc) * nrels);
 791	if (!prog->reloc_desc) {
 792		pr_warning("failed to alloc memory in relocation\n");
 793		return -ENOMEM;
 794	}
 795	prog->nr_reloc = nrels;
 796
 797	for (i = 0; i < nrels; i++) {
 798		GElf_Sym sym;
 799		GElf_Rel rel;
 800		unsigned int insn_idx;
 801		struct bpf_insn *insns = prog->insns;
 802		size_t map_idx;
 803
 804		if (!gelf_getrel(data, i, &rel)) {
 805			pr_warning("relocation: failed to get %d reloc\n", i);
 806			return -LIBBPF_ERRNO__FORMAT;
 807		}
 808
 809		if (!gelf_getsym(symbols,
 810				 GELF_R_SYM(rel.r_info),
 811				 &sym)) {
 812			pr_warning("relocation: symbol %"PRIx64" not found\n",
 813				   GELF_R_SYM(rel.r_info));
 814			return -LIBBPF_ERRNO__FORMAT;
 815		}
 816
 817		if (sym.st_shndx != maps_shndx) {
 818			pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n",
 819				   prog->section_name, sym.st_shndx);
 820			return -LIBBPF_ERRNO__RELOC;
 821		}
 822
 823		insn_idx = rel.r_offset / sizeof(struct bpf_insn);
 824		pr_debug("relocation: insn_idx=%u\n", insn_idx);
 825
 826		if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) {
 827			pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
 828				   insn_idx, insns[insn_idx].code);
 829			return -LIBBPF_ERRNO__RELOC;
 830		}
 831
 832		map_idx = sym.st_value / sizeof(struct bpf_map_def);
 833		if (map_idx >= nr_maps) {
 834			pr_warning("bpf relocation: map_idx %d large than %d\n",
 835				   (int)map_idx, (int)nr_maps - 1);
 836			return -LIBBPF_ERRNO__RELOC;
 837		}
 838
 839		prog->reloc_desc[i].insn_idx = insn_idx;
 840		prog->reloc_desc[i].map_idx = map_idx;
 841	}
 842	return 0;
 843}
 844
 845static int
 846bpf_object__create_maps(struct bpf_object *obj)
 847{
 848	unsigned int i;
 849
 850	for (i = 0; i < obj->nr_maps; i++) {
 851		struct bpf_map_def *def = &obj->maps[i].def;
 852		int *pfd = &obj->maps[i].fd;
 853
 854		*pfd = bpf_create_map(def->type,
 855				      def->key_size,
 856				      def->value_size,
 857				      def->max_entries,
 858				      0);
 859		if (*pfd < 0) {
 860			size_t j;
 861			int err = *pfd;
 862
 863			pr_warning("failed to create map: %s\n",
 864				   strerror(errno));
 865			for (j = 0; j < i; j++)
 866				zclose(obj->maps[j].fd);
 867			return err;
 868		}
 869		pr_debug("create map %s: fd=%d\n", obj->maps[i].name, *pfd);
 870	}
 871
 872	return 0;
 873}
 874
 875static int
 876bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
 877{
 878	int i;
 879
 880	if (!prog || !prog->reloc_desc)
 881		return 0;
 882
 883	for (i = 0; i < prog->nr_reloc; i++) {
 884		int insn_idx, map_idx;
 885		struct bpf_insn *insns = prog->insns;
 886
 887		insn_idx = prog->reloc_desc[i].insn_idx;
 888		map_idx = prog->reloc_desc[i].map_idx;
 889
 890		if (insn_idx >= (int)prog->insns_cnt) {
 891			pr_warning("relocation out of range: '%s'\n",
 892				   prog->section_name);
 893			return -LIBBPF_ERRNO__RELOC;
 894		}
 895		insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
 896		insns[insn_idx].imm = obj->maps[map_idx].fd;
 897	}
 898
 899	zfree(&prog->reloc_desc);
 900	prog->nr_reloc = 0;
 901	return 0;
 902}
 903
 904
 905static int
 906bpf_object__relocate(struct bpf_object *obj)
 907{
 908	struct bpf_program *prog;
 909	size_t i;
 910	int err;
 911
 912	for (i = 0; i < obj->nr_programs; i++) {
 913		prog = &obj->programs[i];
 914
 915		err = bpf_program__relocate(prog, obj);
 916		if (err) {
 917			pr_warning("failed to relocate '%s'\n",
 918				   prog->section_name);
 919			return err;
 920		}
 921	}
 922	return 0;
 923}
 924
 925static int bpf_object__collect_reloc(struct bpf_object *obj)
 926{
 927	int i, err;
 928
 929	if (!obj_elf_valid(obj)) {
 930		pr_warning("Internal error: elf object is closed\n");
 931		return -LIBBPF_ERRNO__INTERNAL;
 932	}
 933
 934	for (i = 0; i < obj->efile.nr_reloc; i++) {
 935		GElf_Shdr *shdr = &obj->efile.reloc[i].shdr;
 936		Elf_Data *data = obj->efile.reloc[i].data;
 937		int idx = shdr->sh_info;
 938		struct bpf_program *prog;
 939		size_t nr_maps = obj->nr_maps;
 940
 941		if (shdr->sh_type != SHT_REL) {
 942			pr_warning("internal error at %d\n", __LINE__);
 943			return -LIBBPF_ERRNO__INTERNAL;
 944		}
 945
 946		prog = bpf_object__find_prog_by_idx(obj, idx);
 947		if (!prog) {
 948			pr_warning("relocation failed: no %d section\n",
 949				   idx);
 950			return -LIBBPF_ERRNO__RELOC;
 951		}
 952
 953		err = bpf_program__collect_reloc(prog, nr_maps,
 954						 shdr, data,
 955						 obj->efile.symbols,
 956						 obj->efile.maps_shndx);
 957		if (err)
 958			return err;
 959	}
 960	return 0;
 961}
 962
 963static int
 964load_program(enum bpf_prog_type type, struct bpf_insn *insns,
 965	     int insns_cnt, char *license, u32 kern_version, int *pfd)
 966{
 967	int ret;
 968	char *log_buf;
 969
 970	if (!insns || !insns_cnt)
 971		return -EINVAL;
 972
 973	log_buf = malloc(BPF_LOG_BUF_SIZE);
 974	if (!log_buf)
 975		pr_warning("Alloc log buffer for bpf loader error, continue without log\n");
 976
 977	ret = bpf_load_program(type, insns, insns_cnt, license,
 978			       kern_version, log_buf, BPF_LOG_BUF_SIZE);
 979
 980	if (ret >= 0) {
 981		*pfd = ret;
 982		ret = 0;
 983		goto out;
 984	}
 985
 986	ret = -LIBBPF_ERRNO__LOAD;
 987	pr_warning("load bpf program failed: %s\n", strerror(errno));
 988
 989	if (log_buf && log_buf[0] != '\0') {
 990		ret = -LIBBPF_ERRNO__VERIFY;
 991		pr_warning("-- BEGIN DUMP LOG ---\n");
 992		pr_warning("\n%s\n", log_buf);
 993		pr_warning("-- END LOG --\n");
 994	} else if (insns_cnt >= BPF_MAXINSNS) {
 995		pr_warning("Program too large (%d insns), at most %d insns\n",
 996			   insns_cnt, BPF_MAXINSNS);
 997		ret = -LIBBPF_ERRNO__PROG2BIG;
 998	} else {
 999		/* Wrong program type? */
1000		if (type != BPF_PROG_TYPE_KPROBE) {
1001			int fd;
1002
1003			fd = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
1004					      insns_cnt, license, kern_version,
1005					      NULL, 0);
1006			if (fd >= 0) {
1007				close(fd);
1008				ret = -LIBBPF_ERRNO__PROGTYPE;
1009				goto out;
1010			}
1011		}
1012
1013		if (log_buf)
1014			ret = -LIBBPF_ERRNO__KVER;
1015	}
1016
1017out:
1018	free(log_buf);
1019	return ret;
1020}
1021
1022static int
1023bpf_program__load(struct bpf_program *prog,
1024		  char *license, u32 kern_version)
1025{
1026	int err = 0, fd, i;
1027
1028	if (prog->instances.nr < 0 || !prog->instances.fds) {
1029		if (prog->preprocessor) {
1030			pr_warning("Internal error: can't load program '%s'\n",
1031				   prog->section_name);
1032			return -LIBBPF_ERRNO__INTERNAL;
1033		}
1034
1035		prog->instances.fds = malloc(sizeof(int));
1036		if (!prog->instances.fds) {
1037			pr_warning("Not enough memory for BPF fds\n");
1038			return -ENOMEM;
1039		}
1040		prog->instances.nr = 1;
1041		prog->instances.fds[0] = -1;
1042	}
1043
1044	if (!prog->preprocessor) {
1045		if (prog->instances.nr != 1) {
1046			pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n",
1047				   prog->section_name, prog->instances.nr);
1048		}
1049		err = load_program(prog->type, prog->insns, prog->insns_cnt,
1050				   license, kern_version, &fd);
1051		if (!err)
1052			prog->instances.fds[0] = fd;
1053		goto out;
1054	}
1055
1056	for (i = 0; i < prog->instances.nr; i++) {
1057		struct bpf_prog_prep_result result;
1058		bpf_program_prep_t preprocessor = prog->preprocessor;
1059
1060		bzero(&result, sizeof(result));
1061		err = preprocessor(prog, i, prog->insns,
1062				   prog->insns_cnt, &result);
1063		if (err) {
1064			pr_warning("Preprocessing the %dth instance of program '%s' failed\n",
1065				   i, prog->section_name);
1066			goto out;
1067		}
1068
1069		if (!result.new_insn_ptr || !result.new_insn_cnt) {
1070			pr_debug("Skip loading the %dth instance of program '%s'\n",
1071				 i, prog->section_name);
1072			prog->instances.fds[i] = -1;
1073			if (result.pfd)
1074				*result.pfd = -1;
1075			continue;
1076		}
1077
1078		err = load_program(prog->type, result.new_insn_ptr,
1079				   result.new_insn_cnt,
1080				   license, kern_version, &fd);
1081
1082		if (err) {
1083			pr_warning("Loading the %dth instance of program '%s' failed\n",
1084					i, prog->section_name);
1085			goto out;
1086		}
1087
1088		if (result.pfd)
1089			*result.pfd = fd;
1090		prog->instances.fds[i] = fd;
1091	}
1092out:
1093	if (err)
1094		pr_warning("failed to load program '%s'\n",
1095			   prog->section_name);
1096	zfree(&prog->insns);
1097	prog->insns_cnt = 0;
1098	return err;
1099}
1100
1101static int
1102bpf_object__load_progs(struct bpf_object *obj)
1103{
1104	size_t i;
1105	int err;
1106
1107	for (i = 0; i < obj->nr_programs; i++) {
1108		err = bpf_program__load(&obj->programs[i],
1109					obj->license,
1110					obj->kern_version);
1111		if (err)
1112			return err;
1113	}
1114	return 0;
1115}
1116
1117static int bpf_object__validate(struct bpf_object *obj)
1118{
1119	if (obj->kern_version == 0) {
1120		pr_warning("%s doesn't provide kernel version\n",
1121			   obj->path);
1122		return -LIBBPF_ERRNO__KVERSION;
1123	}
1124	return 0;
1125}
1126
1127static struct bpf_object *
1128__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
1129{
1130	struct bpf_object *obj;
1131	int err;
1132
1133	if (elf_version(EV_CURRENT) == EV_NONE) {
1134		pr_warning("failed to init libelf for %s\n", path);
1135		return ERR_PTR(-LIBBPF_ERRNO__LIBELF);
1136	}
1137
1138	obj = bpf_object__new(path, obj_buf, obj_buf_sz);
1139	if (IS_ERR(obj))
1140		return obj;
1141
1142	CHECK_ERR(bpf_object__elf_init(obj), err, out);
1143	CHECK_ERR(bpf_object__check_endianness(obj), err, out);
1144	CHECK_ERR(bpf_object__elf_collect(obj), err, out);
1145	CHECK_ERR(bpf_object__collect_reloc(obj), err, out);
1146	CHECK_ERR(bpf_object__validate(obj), err, out);
1147
1148	bpf_object__elf_finish(obj);
1149	return obj;
1150out:
1151	bpf_object__close(obj);
1152	return ERR_PTR(err);
1153}
1154
1155struct bpf_object *bpf_object__open(const char *path)
1156{
1157	/* param validation */
1158	if (!path)
1159		return NULL;
1160
1161	pr_debug("loading %s\n", path);
1162
1163	return __bpf_object__open(path, NULL, 0);
1164}
1165
1166struct bpf_object *bpf_object__open_buffer(void *obj_buf,
1167					   size_t obj_buf_sz,
1168					   const char *name)
1169{
1170	char tmp_name[64];
1171
1172	/* param validation */
1173	if (!obj_buf || obj_buf_sz <= 0)
1174		return NULL;
1175
1176	if (!name) {
1177		snprintf(tmp_name, sizeof(tmp_name), "%lx-%lx",
1178			 (unsigned long)obj_buf,
1179			 (unsigned long)obj_buf_sz);
1180		tmp_name[sizeof(tmp_name) - 1] = '\0';
1181		name = tmp_name;
1182	}
1183	pr_debug("loading object '%s' from buffer\n",
1184		 name);
1185
1186	return __bpf_object__open(name, obj_buf, obj_buf_sz);
1187}
1188
1189int bpf_object__unload(struct bpf_object *obj)
1190{
1191	size_t i;
1192
1193	if (!obj)
1194		return -EINVAL;
1195
1196	for (i = 0; i < obj->nr_maps; i++)
1197		zclose(obj->maps[i].fd);
1198
1199	for (i = 0; i < obj->nr_programs; i++)
1200		bpf_program__unload(&obj->programs[i]);
1201
1202	return 0;
1203}
1204
1205int bpf_object__load(struct bpf_object *obj)
1206{
1207	int err;
1208
1209	if (!obj)
1210		return -EINVAL;
1211
1212	if (obj->loaded) {
1213		pr_warning("object should not be loaded twice\n");
1214		return -EINVAL;
1215	}
1216
1217	obj->loaded = true;
1218
1219	CHECK_ERR(bpf_object__create_maps(obj), err, out);
1220	CHECK_ERR(bpf_object__relocate(obj), err, out);
1221	CHECK_ERR(bpf_object__load_progs(obj), err, out);
1222
1223	return 0;
1224out:
1225	bpf_object__unload(obj);
1226	pr_warning("failed to load object '%s'\n", obj->path);
1227	return err;
1228}
1229
1230void bpf_object__close(struct bpf_object *obj)
1231{
1232	size_t i;
1233
1234	if (!obj)
1235		return;
1236
1237	if (obj->clear_priv)
1238		obj->clear_priv(obj, obj->priv);
1239
1240	bpf_object__elf_finish(obj);
1241	bpf_object__unload(obj);
1242
1243	for (i = 0; i < obj->nr_maps; i++) {
1244		zfree(&obj->maps[i].name);
1245		if (obj->maps[i].clear_priv)
1246			obj->maps[i].clear_priv(&obj->maps[i],
1247						obj->maps[i].priv);
1248		obj->maps[i].priv = NULL;
1249		obj->maps[i].clear_priv = NULL;
1250	}
1251	zfree(&obj->maps);
1252	obj->nr_maps = 0;
1253
1254	if (obj->programs && obj->nr_programs) {
1255		for (i = 0; i < obj->nr_programs; i++)
1256			bpf_program__exit(&obj->programs[i]);
1257	}
1258	zfree(&obj->programs);
1259
1260	list_del(&obj->list);
1261	free(obj);
1262}
1263
1264struct bpf_object *
1265bpf_object__next(struct bpf_object *prev)
1266{
1267	struct bpf_object *next;
1268
1269	if (!prev)
1270		next = list_first_entry(&bpf_objects_list,
1271					struct bpf_object,
1272					list);
1273	else
1274		next = list_next_entry(prev, list);
1275
1276	/* Empty list is noticed here so don't need checking on entry. */
1277	if (&next->list == &bpf_objects_list)
1278		return NULL;
1279
1280	return next;
1281}
1282
1283const char *bpf_object__name(struct bpf_object *obj)
1284{
1285	return obj ? obj->path : ERR_PTR(-EINVAL);
1286}
1287
1288unsigned int bpf_object__kversion(struct bpf_object *obj)
1289{
1290	return obj ? obj->kern_version : 0;
1291}
1292
1293int bpf_object__set_priv(struct bpf_object *obj, void *priv,
1294			 bpf_object_clear_priv_t clear_priv)
1295{
1296	if (obj->priv && obj->clear_priv)
1297		obj->clear_priv(obj, obj->priv);
1298
1299	obj->priv = priv;
1300	obj->clear_priv = clear_priv;
1301	return 0;
1302}
1303
1304void *bpf_object__priv(struct bpf_object *obj)
1305{
1306	return obj ? obj->priv : ERR_PTR(-EINVAL);
1307}
1308
1309struct bpf_program *
1310bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
1311{
1312	size_t idx;
1313
1314	if (!obj->programs)
1315		return NULL;
1316	/* First handler */
1317	if (prev == NULL)
1318		return &obj->programs[0];
1319
1320	if (prev->obj != obj) {
1321		pr_warning("error: program handler doesn't match object\n");
1322		return NULL;
1323	}
1324
1325	idx = (prev - obj->programs) + 1;
1326	if (idx >= obj->nr_programs)
1327		return NULL;
1328	return &obj->programs[idx];
1329}
1330
1331int bpf_program__set_priv(struct bpf_program *prog, void *priv,
1332			  bpf_program_clear_priv_t clear_priv)
1333{
1334	if (prog->priv && prog->clear_priv)
1335		prog->clear_priv(prog, prog->priv);
1336
1337	prog->priv = priv;
1338	prog->clear_priv = clear_priv;
1339	return 0;
1340}
1341
1342void *bpf_program__priv(struct bpf_program *prog)
1343{
1344	return prog ? prog->priv : ERR_PTR(-EINVAL);
1345}
1346
1347const char *bpf_program__title(struct bpf_program *prog, bool needs_copy)
1348{
1349	const char *title;
1350
1351	title = prog->section_name;
1352	if (needs_copy) {
1353		title = strdup(title);
1354		if (!title) {
1355			pr_warning("failed to strdup program title\n");
1356			return ERR_PTR(-ENOMEM);
1357		}
1358	}
1359
1360	return title;
1361}
1362
1363int bpf_program__fd(struct bpf_program *prog)
1364{
1365	return bpf_program__nth_fd(prog, 0);
1366}
1367
1368int bpf_program__set_prep(struct bpf_program *prog, int nr_instances,
1369			  bpf_program_prep_t prep)
1370{
1371	int *instances_fds;
1372
1373	if (nr_instances <= 0 || !prep)
1374		return -EINVAL;
1375
1376	if (prog->instances.nr > 0 || prog->instances.fds) {
1377		pr_warning("Can't set pre-processor after loading\n");
1378		return -EINVAL;
1379	}
1380
1381	instances_fds = malloc(sizeof(int) * nr_instances);
1382	if (!instances_fds) {
1383		pr_warning("alloc memory failed for fds\n");
1384		return -ENOMEM;
1385	}
1386
1387	/* fill all fd with -1 */
1388	memset(instances_fds, -1, sizeof(int) * nr_instances);
1389
1390	prog->instances.nr = nr_instances;
1391	prog->instances.fds = instances_fds;
1392	prog->preprocessor = prep;
1393	return 0;
1394}
1395
1396int bpf_program__nth_fd(struct bpf_program *prog, int n)
1397{
1398	int fd;
1399
1400	if (n >= prog->instances.nr || n < 0) {
1401		pr_warning("Can't get the %dth fd from program %s: only %d instances\n",
1402			   n, prog->section_name, prog->instances.nr);
1403		return -EINVAL;
1404	}
1405
1406	fd = prog->instances.fds[n];
1407	if (fd < 0) {
1408		pr_warning("%dth instance of program '%s' is invalid\n",
1409			   n, prog->section_name);
1410		return -ENOENT;
1411	}
1412
1413	return fd;
1414}
1415
1416static void bpf_program__set_type(struct bpf_program *prog,
1417				  enum bpf_prog_type type)
1418{
1419	prog->type = type;
1420}
1421
1422int bpf_program__set_tracepoint(struct bpf_program *prog)
1423{
1424	if (!prog)
1425		return -EINVAL;
1426	bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
1427	return 0;
1428}
1429
1430int bpf_program__set_kprobe(struct bpf_program *prog)
1431{
1432	if (!prog)
1433		return -EINVAL;
1434	bpf_program__set_type(prog, BPF_PROG_TYPE_KPROBE);
1435	return 0;
1436}
1437
1438static bool bpf_program__is_type(struct bpf_program *prog,
1439				 enum bpf_prog_type type)
1440{
1441	return prog ? (prog->type == type) : false;
1442}
1443
1444bool bpf_program__is_tracepoint(struct bpf_program *prog)
1445{
1446	return bpf_program__is_type(prog, BPF_PROG_TYPE_TRACEPOINT);
1447}
1448
1449bool bpf_program__is_kprobe(struct bpf_program *prog)
1450{
1451	return bpf_program__is_type(prog, BPF_PROG_TYPE_KPROBE);
1452}
1453
1454int bpf_map__fd(struct bpf_map *map)
1455{
1456	return map ? map->fd : -EINVAL;
1457}
1458
1459const struct bpf_map_def *bpf_map__def(struct bpf_map *map)
1460{
1461	return map ? &map->def : ERR_PTR(-EINVAL);
1462}
1463
1464const char *bpf_map__name(struct bpf_map *map)
1465{
1466	return map ? map->name : NULL;
1467}
1468
1469int bpf_map__set_priv(struct bpf_map *map, void *priv,
1470		     bpf_map_clear_priv_t clear_priv)
1471{
1472	if (!map)
1473		return -EINVAL;
1474
1475	if (map->priv) {
1476		if (map->clear_priv)
1477			map->clear_priv(map, map->priv);
1478	}
1479
1480	map->priv = priv;
1481	map->clear_priv = clear_priv;
1482	return 0;
1483}
1484
1485void *bpf_map__priv(struct bpf_map *map)
1486{
1487	return map ? map->priv : ERR_PTR(-EINVAL);
1488}
1489
1490struct bpf_map *
1491bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
1492{
1493	size_t idx;
1494	struct bpf_map *s, *e;
1495
1496	if (!obj || !obj->maps)
1497		return NULL;
1498
1499	s = obj->maps;
1500	e = obj->maps + obj->nr_maps;
1501
1502	if (prev == NULL)
1503		return s;
1504
1505	if ((prev < s) || (prev >= e)) {
1506		pr_warning("error in %s: map handler doesn't belong to object\n",
1507			   __func__);
1508		return NULL;
1509	}
1510
1511	idx = (prev - obj->maps) + 1;
1512	if (idx >= obj->nr_maps)
1513		return NULL;
1514	return &obj->maps[idx];
1515}
1516
1517struct bpf_map *
1518bpf_object__find_map_by_name(struct bpf_object *obj, const char *name)
1519{
1520	struct bpf_map *pos;
1521
1522	bpf_map__for_each(pos, obj) {
1523		if (pos->name && !strcmp(pos->name, name))
1524			return pos;
1525	}
1526	return NULL;
1527}
1528
1529struct bpf_map *
1530bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset)
1531{
1532	int i;
1533
1534	for (i = 0; i < obj->nr_maps; i++) {
1535		if (obj->maps[i].offset == offset)
1536			return &obj->maps[i];
1537	}
1538	return ERR_PTR(-ENOENT);
1539}