aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib')
-rw-r--r--tools/lib/bpf/Build2
-rw-r--r--tools/lib/bpf/Makefile30
-rw-r--r--tools/lib/bpf/bpf.c135
-rw-r--r--tools/lib/bpf/bpf.h4
-rw-r--r--tools/lib/bpf/libbpf.c204
-rw-r--r--tools/lib/bpf/libbpf.h6
-rw-r--r--tools/lib/bpf/nlattr.c187
-rw-r--r--tools/lib/bpf/nlattr.h72
-rw-r--r--tools/lib/find_bit.c39
-rw-r--r--tools/lib/subcmd/pager.c5
-rw-r--r--tools/lib/traceevent/event-parse.c62
-rw-r--r--tools/lib/traceevent/event-plugin.c24
-rw-r--r--tools/lib/traceevent/kbuffer-parse.c4
-rw-r--r--tools/lib/traceevent/parse-filter.c22
14 files changed, 699 insertions, 97 deletions
diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build
index d8749756352d..64c679d67109 100644
--- a/tools/lib/bpf/Build
+++ b/tools/lib/bpf/Build
@@ -1 +1 @@
libbpf-y := libbpf.o bpf.o libbpf-y := libbpf.o bpf.o nlattr.o
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index 4555304dc18e..e6d5f8d1477f 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -93,7 +93,6 @@ export prefix libdir src obj
93# Shell quotes 93# Shell quotes
94libdir_SQ = $(subst ','\'',$(libdir)) 94libdir_SQ = $(subst ','\'',$(libdir))
95libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) 95libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
96plugin_dir_SQ = $(subst ','\'',$(plugin_dir))
97 96
98LIB_FILE = libbpf.a libbpf.so 97LIB_FILE = libbpf.a libbpf.so
99 98
@@ -150,7 +149,7 @@ CMD_TARGETS = $(LIB_FILE)
150 149
151TARGETS = $(CMD_TARGETS) 150TARGETS = $(CMD_TARGETS)
152 151
153all: fixdep $(VERSION_FILES) all_cmd 152all: fixdep all_cmd
154 153
155all_cmd: $(CMD_TARGETS) 154all_cmd: $(CMD_TARGETS)
156 155
@@ -161,6 +160,12 @@ $(BPF_IN): force elfdep bpfdep
161 @(test -f ../../include/uapi/linux/bpf_common.h -a -f ../../../include/uapi/linux/bpf_common.h && ( \ 160 @(test -f ../../include/uapi/linux/bpf_common.h -a -f ../../../include/uapi/linux/bpf_common.h && ( \
162 (diff -B ../../include/uapi/linux/bpf_common.h ../../../include/uapi/linux/bpf_common.h >/dev/null) || \ 161 (diff -B ../../include/uapi/linux/bpf_common.h ../../../include/uapi/linux/bpf_common.h >/dev/null) || \
163 echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf_common.h' differs from latest version at 'include/uapi/linux/bpf_common.h'" >&2 )) || true 162 echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf_common.h' differs from latest version at 'include/uapi/linux/bpf_common.h'" >&2 )) || true
163 @(test -f ../../include/uapi/linux/netlink.h -a -f ../../../include/uapi/linux/netlink.h && ( \
164 (diff -B ../../include/uapi/linux/netlink.h ../../../include/uapi/linux/netlink.h >/dev/null) || \
165 echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/netlink.h' differs from latest version at 'include/uapi/linux/netlink.h'" >&2 )) || true
166 @(test -f ../../include/uapi/linux/if_link.h -a -f ../../../include/uapi/linux/if_link.h && ( \
167 (diff -B ../../include/uapi/linux/if_link.h ../../../include/uapi/linux/if_link.h >/dev/null) || \
168 echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_link.h' differs from latest version at 'include/uapi/linux/if_link.h'" >&2 )) || true
164 $(Q)$(MAKE) $(build)=libbpf 169 $(Q)$(MAKE) $(build)=libbpf
165 170
166$(OUTPUT)libbpf.so: $(BPF_IN) 171$(OUTPUT)libbpf.so: $(BPF_IN)
@@ -169,21 +174,11 @@ $(OUTPUT)libbpf.so: $(BPF_IN)
169$(OUTPUT)libbpf.a: $(BPF_IN) 174$(OUTPUT)libbpf.a: $(BPF_IN)
170 $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ 175 $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
171 176
172define update_dir
173 (echo $1 > $@.tmp; \
174 if [ -r $@ ] && cmp -s $@ $@.tmp; then \
175 rm -f $@.tmp; \
176 else \
177 echo ' UPDATE $@'; \
178 mv -f $@.tmp $@; \
179 fi);
180endef
181
182define do_install 177define do_install
183 if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ 178 if [ ! -d '$(DESTDIR_SQ)$2' ]; then \
184 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ 179 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \
185 fi; \ 180 fi; \
186 $(INSTALL) $1 '$(DESTDIR_SQ)$2' 181 $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2'
187endef 182endef
188 183
189install_lib: all_cmd 184install_lib: all_cmd
@@ -192,7 +187,8 @@ install_lib: all_cmd
192 187
193install_headers: 188install_headers:
194 $(call QUIET_INSTALL, headers) \ 189 $(call QUIET_INSTALL, headers) \
195 $(call do_install,bpf.h,$(prefix)/include/bpf,644) 190 $(call do_install,bpf.h,$(prefix)/include/bpf,644); \
191 $(call do_install,libbpf.h,$(prefix)/include/bpf,644);
196 192
197install: install_lib 193install: install_lib
198 194
@@ -203,7 +199,7 @@ config-clean:
203 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null 199 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null
204 200
205clean: 201clean:
206 $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd \ 202 $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so .*.d .*.cmd \
207 $(RM) LIBBPF-CFLAGS 203 $(RM) LIBBPF-CFLAGS
208 $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf 204 $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf
209 205
@@ -213,10 +209,10 @@ PHONY += force elfdep bpfdep
213force: 209force:
214 210
215elfdep: 211elfdep:
216 @if [ "$(feature-libelf)" != "1" ]; then echo "No libelf found"; exit -1 ; fi 212 @if [ "$(feature-libelf)" != "1" ]; then echo "No libelf found"; exit 1 ; fi
217 213
218bpfdep: 214bpfdep:
219 @if [ "$(feature-bpf)" != "1" ]; then echo "BPF API too old"; exit -1 ; fi 215 @if [ "$(feature-bpf)" != "1" ]; then echo "BPF API too old"; exit 1 ; fi
220 216
221# Declare the contents of the .PHONY variable as phony. We keep that 217# Declare the contents of the .PHONY variable as phony. We keep that
222# information in a variable so we can use it in if_changed and friends. 218# information in a variable so we can use it in if_changed and friends.
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 5128677e4117..592a58a2b681 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -1,3 +1,5 @@
1// SPDX-License-Identifier: LGPL-2.1
2
1/* 3/*
2 * common eBPF ELF operations. 4 * common eBPF ELF operations.
3 * 5 *
@@ -25,6 +27,16 @@
25#include <asm/unistd.h> 27#include <asm/unistd.h>
26#include <linux/bpf.h> 28#include <linux/bpf.h>
27#include "bpf.h" 29#include "bpf.h"
30#include "libbpf.h"
31#include "nlattr.h"
32#include <linux/rtnetlink.h>
33#include <linux/if_link.h>
34#include <sys/socket.h>
35#include <errno.h>
36
37#ifndef SOL_NETLINK
38#define SOL_NETLINK 270
39#endif
28 40
29/* 41/*
30 * When building perf, unistd.h is overridden. __NR_bpf is 42 * When building perf, unistd.h is overridden. __NR_bpf is
@@ -46,7 +58,9 @@
46# endif 58# endif
47#endif 59#endif
48 60
61#ifndef min
49#define min(x, y) ((x) < (y) ? (x) : (y)) 62#define min(x, y) ((x) < (y) ? (x) : (y))
63#endif
50 64
51static inline __u64 ptr_to_u64(const void *ptr) 65static inline __u64 ptr_to_u64(const void *ptr)
52{ 66{
@@ -413,3 +427,124 @@ int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
413 427
414 return err; 428 return err;
415} 429}
430
431int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
432{
433 struct sockaddr_nl sa;
434 int sock, seq = 0, len, ret = -1;
435 char buf[4096];
436 struct nlattr *nla, *nla_xdp;
437 struct {
438 struct nlmsghdr nh;
439 struct ifinfomsg ifinfo;
440 char attrbuf[64];
441 } req;
442 struct nlmsghdr *nh;
443 struct nlmsgerr *err;
444 socklen_t addrlen;
445 int one = 1;
446
447 memset(&sa, 0, sizeof(sa));
448 sa.nl_family = AF_NETLINK;
449
450 sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
451 if (sock < 0) {
452 return -errno;
453 }
454
455 if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK,
456 &one, sizeof(one)) < 0) {
457 fprintf(stderr, "Netlink error reporting not supported\n");
458 }
459
460 if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
461 ret = -errno;
462 goto cleanup;
463 }
464
465 addrlen = sizeof(sa);
466 if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0) {
467 ret = -errno;
468 goto cleanup;
469 }
470
471 if (addrlen != sizeof(sa)) {
472 ret = -LIBBPF_ERRNO__INTERNAL;
473 goto cleanup;
474 }
475
476 memset(&req, 0, sizeof(req));
477 req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
478 req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
479 req.nh.nlmsg_type = RTM_SETLINK;
480 req.nh.nlmsg_pid = 0;
481 req.nh.nlmsg_seq = ++seq;
482 req.ifinfo.ifi_family = AF_UNSPEC;
483 req.ifinfo.ifi_index = ifindex;
484
485 /* started nested attribute for XDP */
486 nla = (struct nlattr *)(((char *)&req)
487 + NLMSG_ALIGN(req.nh.nlmsg_len));
488 nla->nla_type = NLA_F_NESTED | IFLA_XDP;
489 nla->nla_len = NLA_HDRLEN;
490
491 /* add XDP fd */
492 nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
493 nla_xdp->nla_type = IFLA_XDP_FD;
494 nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
495 memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
496 nla->nla_len += nla_xdp->nla_len;
497
498 /* if user passed in any flags, add those too */
499 if (flags) {
500 nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
501 nla_xdp->nla_type = IFLA_XDP_FLAGS;
502 nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
503 memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
504 nla->nla_len += nla_xdp->nla_len;
505 }
506
507 req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
508
509 if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
510 ret = -errno;
511 goto cleanup;
512 }
513
514 len = recv(sock, buf, sizeof(buf), 0);
515 if (len < 0) {
516 ret = -errno;
517 goto cleanup;
518 }
519
520 for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
521 nh = NLMSG_NEXT(nh, len)) {
522 if (nh->nlmsg_pid != sa.nl_pid) {
523 ret = -LIBBPF_ERRNO__WRNGPID;
524 goto cleanup;
525 }
526 if (nh->nlmsg_seq != seq) {
527 ret = -LIBBPF_ERRNO__INVSEQ;
528 goto cleanup;
529 }
530 switch (nh->nlmsg_type) {
531 case NLMSG_ERROR:
532 err = (struct nlmsgerr *)NLMSG_DATA(nh);
533 if (!err->error)
534 continue;
535 ret = err->error;
536 nla_dump_errormsg(nh);
537 goto cleanup;
538 case NLMSG_DONE:
539 break;
540 default:
541 break;
542 }
543 }
544
545 ret = 0;
546
547cleanup:
548 close(sock);
549 return ret;
550}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 6534889e2b2f..8d18fb73d7fb 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -1,3 +1,5 @@
1/* SPDX-License-Identifier: LGPL-2.1 */
2
1/* 3/*
2 * common eBPF ELF operations. 4 * common eBPF ELF operations.
3 * 5 *
@@ -40,7 +42,7 @@ int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name,
40 __u32 map_flags); 42 __u32 map_flags);
41 43
42/* Recommend log buffer size */ 44/* Recommend log buffer size */
43#define BPF_LOG_BUF_SIZE 65536 45#define BPF_LOG_BUF_SIZE (256 * 1024)
44int bpf_load_program_name(enum bpf_prog_type type, const char *name, 46int bpf_load_program_name(enum bpf_prog_type type, const char *name,
45 const struct bpf_insn *insns, 47 const struct bpf_insn *insns,
46 size_t insns_cnt, const char *license, 48 size_t insns_cnt, const char *license,
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 5aa45f89da93..71ddc481f349 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1,3 +1,5 @@
1// SPDX-License-Identifier: LGPL-2.1
2
1/* 3/*
2 * Common eBPF ELF object loading operations. 4 * Common eBPF ELF object loading operations.
3 * 5 *
@@ -106,6 +108,8 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
106 [ERRCODE_OFFSET(PROG2BIG)] = "Program too big", 108 [ERRCODE_OFFSET(PROG2BIG)] = "Program too big",
107 [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version", 109 [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version",
108 [ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type", 110 [ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type",
111 [ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message",
112 [ERRCODE_OFFSET(INVSEQ)] = "Invalid netlink sequence",
109}; 113};
110 114
111int libbpf_strerror(int err, char *buf, size_t size) 115int libbpf_strerror(int err, char *buf, size_t size)
@@ -174,12 +178,19 @@ struct bpf_program {
174 char *name; 178 char *name;
175 char *section_name; 179 char *section_name;
176 struct bpf_insn *insns; 180 struct bpf_insn *insns;
177 size_t insns_cnt; 181 size_t insns_cnt, main_prog_cnt;
178 enum bpf_prog_type type; 182 enum bpf_prog_type type;
179 183
180 struct { 184 struct reloc_desc {
185 enum {
186 RELO_LD64,
187 RELO_CALL,
188 } type;
181 int insn_idx; 189 int insn_idx;
182 int map_idx; 190 union {
191 int map_idx;
192 int text_off;
193 };
183 } *reloc_desc; 194 } *reloc_desc;
184 int nr_reloc; 195 int nr_reloc;
185 196
@@ -234,6 +245,7 @@ struct bpf_object {
234 } *reloc; 245 } *reloc;
235 int nr_reloc; 246 int nr_reloc;
236 int maps_shndx; 247 int maps_shndx;
248 int text_shndx;
237 } efile; 249 } efile;
238 /* 250 /*
239 * All loaded bpf_object is linked in a list, which is 251 * All loaded bpf_object is linked in a list, which is
@@ -375,9 +387,13 @@ bpf_object__init_prog_names(struct bpf_object *obj)
375 size_t pi, si; 387 size_t pi, si;
376 388
377 for (pi = 0; pi < obj->nr_programs; pi++) { 389 for (pi = 0; pi < obj->nr_programs; pi++) {
378 char *name = NULL; 390 const char *name = NULL;
379 391
380 prog = &obj->programs[pi]; 392 prog = &obj->programs[pi];
393 if (prog->idx == obj->efile.text_shndx) {
394 name = ".text";
395 goto skip_search;
396 }
381 397
382 for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name; 398 for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name;
383 si++) { 399 si++) {
@@ -387,6 +403,8 @@ bpf_object__init_prog_names(struct bpf_object *obj)
387 continue; 403 continue;
388 if (sym.st_shndx != prog->idx) 404 if (sym.st_shndx != prog->idx)
389 continue; 405 continue;
406 if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL)
407 continue;
390 408
391 name = elf_strptr(obj->efile.elf, 409 name = elf_strptr(obj->efile.elf,
392 obj->efile.strtabidx, 410 obj->efile.strtabidx,
@@ -403,7 +421,7 @@ bpf_object__init_prog_names(struct bpf_object *obj)
403 prog->section_name); 421 prog->section_name);
404 return -EINVAL; 422 return -EINVAL;
405 } 423 }
406 424skip_search:
407 prog->name = strdup(name); 425 prog->name = strdup(name);
408 if (!prog->name) { 426 if (!prog->name) {
409 pr_warning("failed to allocate memory for prog sym %s\n", 427 pr_warning("failed to allocate memory for prog sym %s\n",
@@ -793,6 +811,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
793 } else if ((sh.sh_type == SHT_PROGBITS) && 811 } else if ((sh.sh_type == SHT_PROGBITS) &&
794 (sh.sh_flags & SHF_EXECINSTR) && 812 (sh.sh_flags & SHF_EXECINSTR) &&
795 (data->d_size > 0)) { 813 (data->d_size > 0)) {
814 if (strcmp(name, ".text") == 0)
815 obj->efile.text_shndx = idx;
796 err = bpf_object__add_program(obj, data->d_buf, 816 err = bpf_object__add_program(obj, data->d_buf,
797 data->d_size, name, idx); 817 data->d_size, name, idx);
798 if (err) { 818 if (err) {
@@ -854,11 +874,14 @@ bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx)
854} 874}
855 875
856static int 876static int
857bpf_program__collect_reloc(struct bpf_program *prog, 877bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
858 size_t nr_maps, GElf_Shdr *shdr, 878 Elf_Data *data, struct bpf_object *obj)
859 Elf_Data *data, Elf_Data *symbols,
860 int maps_shndx, struct bpf_map *maps)
861{ 879{
880 Elf_Data *symbols = obj->efile.symbols;
881 int text_shndx = obj->efile.text_shndx;
882 int maps_shndx = obj->efile.maps_shndx;
883 struct bpf_map *maps = obj->maps;
884 size_t nr_maps = obj->nr_maps;
862 int i, nrels; 885 int i, nrels;
863 886
864 pr_debug("collecting relocating info for: '%s'\n", 887 pr_debug("collecting relocating info for: '%s'\n",
@@ -891,8 +914,11 @@ bpf_program__collect_reloc(struct bpf_program *prog,
891 GELF_R_SYM(rel.r_info)); 914 GELF_R_SYM(rel.r_info));
892 return -LIBBPF_ERRNO__FORMAT; 915 return -LIBBPF_ERRNO__FORMAT;
893 } 916 }
917 pr_debug("relo for %lld value %lld name %d\n",
918 (long long) (rel.r_info >> 32),
919 (long long) sym.st_value, sym.st_name);
894 920
895 if (sym.st_shndx != maps_shndx) { 921 if (sym.st_shndx != maps_shndx && sym.st_shndx != text_shndx) {
896 pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n", 922 pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n",
897 prog->section_name, sym.st_shndx); 923 prog->section_name, sym.st_shndx);
898 return -LIBBPF_ERRNO__RELOC; 924 return -LIBBPF_ERRNO__RELOC;
@@ -901,6 +927,17 @@ bpf_program__collect_reloc(struct bpf_program *prog,
901 insn_idx = rel.r_offset / sizeof(struct bpf_insn); 927 insn_idx = rel.r_offset / sizeof(struct bpf_insn);
902 pr_debug("relocation: insn_idx=%u\n", insn_idx); 928 pr_debug("relocation: insn_idx=%u\n", insn_idx);
903 929
930 if (insns[insn_idx].code == (BPF_JMP | BPF_CALL)) {
931 if (insns[insn_idx].src_reg != BPF_PSEUDO_CALL) {
932 pr_warning("incorrect bpf_call opcode\n");
933 return -LIBBPF_ERRNO__RELOC;
934 }
935 prog->reloc_desc[i].type = RELO_CALL;
936 prog->reloc_desc[i].insn_idx = insn_idx;
937 prog->reloc_desc[i].text_off = sym.st_value;
938 continue;
939 }
940
904 if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) { 941 if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) {
905 pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n", 942 pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
906 insn_idx, insns[insn_idx].code); 943 insn_idx, insns[insn_idx].code);
@@ -922,6 +959,7 @@ bpf_program__collect_reloc(struct bpf_program *prog,
922 return -LIBBPF_ERRNO__RELOC; 959 return -LIBBPF_ERRNO__RELOC;
923 } 960 }
924 961
962 prog->reloc_desc[i].type = RELO_LD64;
925 prog->reloc_desc[i].insn_idx = insn_idx; 963 prog->reloc_desc[i].insn_idx = insn_idx;
926 prog->reloc_desc[i].map_idx = map_idx; 964 prog->reloc_desc[i].map_idx = map_idx;
927 } 965 }
@@ -961,27 +999,76 @@ bpf_object__create_maps(struct bpf_object *obj)
961} 999}
962 1000
963static int 1001static int
1002bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
1003 struct reloc_desc *relo)
1004{
1005 struct bpf_insn *insn, *new_insn;
1006 struct bpf_program *text;
1007 size_t new_cnt;
1008
1009 if (relo->type != RELO_CALL)
1010 return -LIBBPF_ERRNO__RELOC;
1011
1012 if (prog->idx == obj->efile.text_shndx) {
1013 pr_warning("relo in .text insn %d into off %d\n",
1014 relo->insn_idx, relo->text_off);
1015 return -LIBBPF_ERRNO__RELOC;
1016 }
1017
1018 if (prog->main_prog_cnt == 0) {
1019 text = bpf_object__find_prog_by_idx(obj, obj->efile.text_shndx);
1020 if (!text) {
1021 pr_warning("no .text section found yet relo into text exist\n");
1022 return -LIBBPF_ERRNO__RELOC;
1023 }
1024 new_cnt = prog->insns_cnt + text->insns_cnt;
1025 new_insn = realloc(prog->insns, new_cnt * sizeof(*insn));
1026 if (!new_insn) {
1027 pr_warning("oom in prog realloc\n");
1028 return -ENOMEM;
1029 }
1030 memcpy(new_insn + prog->insns_cnt, text->insns,
1031 text->insns_cnt * sizeof(*insn));
1032 prog->insns = new_insn;
1033 prog->main_prog_cnt = prog->insns_cnt;
1034 prog->insns_cnt = new_cnt;
1035 }
1036 insn = &prog->insns[relo->insn_idx];
1037 insn->imm += prog->main_prog_cnt - relo->insn_idx;
1038 pr_debug("added %zd insn from %s to prog %s\n",
1039 text->insns_cnt, text->section_name, prog->section_name);
1040 return 0;
1041}
1042
1043static int
964bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj) 1044bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
965{ 1045{
966 int i; 1046 int i, err;
967 1047
968 if (!prog || !prog->reloc_desc) 1048 if (!prog || !prog->reloc_desc)
969 return 0; 1049 return 0;
970 1050
971 for (i = 0; i < prog->nr_reloc; i++) { 1051 for (i = 0; i < prog->nr_reloc; i++) {
972 int insn_idx, map_idx; 1052 if (prog->reloc_desc[i].type == RELO_LD64) {
973 struct bpf_insn *insns = prog->insns; 1053 struct bpf_insn *insns = prog->insns;
1054 int insn_idx, map_idx;
974 1055
975 insn_idx = prog->reloc_desc[i].insn_idx; 1056 insn_idx = prog->reloc_desc[i].insn_idx;
976 map_idx = prog->reloc_desc[i].map_idx; 1057 map_idx = prog->reloc_desc[i].map_idx;
977 1058
978 if (insn_idx >= (int)prog->insns_cnt) { 1059 if (insn_idx >= (int)prog->insns_cnt) {
979 pr_warning("relocation out of range: '%s'\n", 1060 pr_warning("relocation out of range: '%s'\n",
980 prog->section_name); 1061 prog->section_name);
981 return -LIBBPF_ERRNO__RELOC; 1062 return -LIBBPF_ERRNO__RELOC;
1063 }
1064 insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
1065 insns[insn_idx].imm = obj->maps[map_idx].fd;
1066 } else {
1067 err = bpf_program__reloc_text(prog, obj,
1068 &prog->reloc_desc[i]);
1069 if (err)
1070 return err;
982 } 1071 }
983 insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
984 insns[insn_idx].imm = obj->maps[map_idx].fd;
985 } 1072 }
986 1073
987 zfree(&prog->reloc_desc); 1074 zfree(&prog->reloc_desc);
@@ -1024,7 +1111,6 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
1024 Elf_Data *data = obj->efile.reloc[i].data; 1111 Elf_Data *data = obj->efile.reloc[i].data;
1025 int idx = shdr->sh_info; 1112 int idx = shdr->sh_info;
1026 struct bpf_program *prog; 1113 struct bpf_program *prog;
1027 size_t nr_maps = obj->nr_maps;
1028 1114
1029 if (shdr->sh_type != SHT_REL) { 1115 if (shdr->sh_type != SHT_REL) {
1030 pr_warning("internal error at %d\n", __LINE__); 1116 pr_warning("internal error at %d\n", __LINE__);
@@ -1038,11 +1124,9 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
1038 return -LIBBPF_ERRNO__RELOC; 1124 return -LIBBPF_ERRNO__RELOC;
1039 } 1125 }
1040 1126
1041 err = bpf_program__collect_reloc(prog, nr_maps, 1127 err = bpf_program__collect_reloc(prog,
1042 shdr, data, 1128 shdr, data,
1043 obj->efile.symbols, 1129 obj);
1044 obj->efile.maps_shndx,
1045 obj->maps);
1046 if (err) 1130 if (err)
1047 return err; 1131 return err;
1048 } 1132 }
@@ -1195,6 +1279,8 @@ bpf_object__load_progs(struct bpf_object *obj)
1195 int err; 1279 int err;
1196 1280
1197 for (i = 0; i < obj->nr_programs; i++) { 1281 for (i = 0; i < obj->nr_programs; i++) {
1282 if (obj->programs[i].idx == obj->efile.text_shndx)
1283 continue;
1198 err = bpf_program__load(&obj->programs[i], 1284 err = bpf_program__load(&obj->programs[i],
1199 obj->license, 1285 obj->license,
1200 obj->kern_version); 1286 obj->kern_version);
@@ -1721,6 +1807,45 @@ BPF_PROG_TYPE_FNS(tracepoint, BPF_PROG_TYPE_TRACEPOINT);
1721BPF_PROG_TYPE_FNS(xdp, BPF_PROG_TYPE_XDP); 1807BPF_PROG_TYPE_FNS(xdp, BPF_PROG_TYPE_XDP);
1722BPF_PROG_TYPE_FNS(perf_event, BPF_PROG_TYPE_PERF_EVENT); 1808BPF_PROG_TYPE_FNS(perf_event, BPF_PROG_TYPE_PERF_EVENT);
1723 1809
1810#define BPF_PROG_SEC(string, type) { string, sizeof(string) - 1, type }
1811static const struct {
1812 const char *sec;
1813 size_t len;
1814 enum bpf_prog_type prog_type;
1815} section_names[] = {
1816 BPF_PROG_SEC("socket", BPF_PROG_TYPE_SOCKET_FILTER),
1817 BPF_PROG_SEC("kprobe/", BPF_PROG_TYPE_KPROBE),
1818 BPF_PROG_SEC("kretprobe/", BPF_PROG_TYPE_KPROBE),
1819 BPF_PROG_SEC("tracepoint/", BPF_PROG_TYPE_TRACEPOINT),
1820 BPF_PROG_SEC("xdp", BPF_PROG_TYPE_XDP),
1821 BPF_PROG_SEC("perf_event", BPF_PROG_TYPE_PERF_EVENT),
1822 BPF_PROG_SEC("cgroup/skb", BPF_PROG_TYPE_CGROUP_SKB),
1823 BPF_PROG_SEC("cgroup/sock", BPF_PROG_TYPE_CGROUP_SOCK),
1824 BPF_PROG_SEC("cgroup/dev", BPF_PROG_TYPE_CGROUP_DEVICE),
1825 BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS),
1826 BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB),
1827};
1828#undef BPF_PROG_SEC
1829
1830static enum bpf_prog_type bpf_program__guess_type(struct bpf_program *prog)
1831{
1832 int i;
1833
1834 if (!prog->section_name)
1835 goto err;
1836
1837 for (i = 0; i < ARRAY_SIZE(section_names); i++)
1838 if (strncmp(prog->section_name, section_names[i].sec,
1839 section_names[i].len) == 0)
1840 return section_names[i].prog_type;
1841
1842err:
1843 pr_warning("failed to guess program type based on section name %s\n",
1844 prog->section_name);
1845
1846 return BPF_PROG_TYPE_UNSPEC;
1847}
1848
1724int bpf_map__fd(struct bpf_map *map) 1849int bpf_map__fd(struct bpf_map *map)
1725{ 1850{
1726 return map ? map->fd : -EINVAL; 1851 return map ? map->fd : -EINVAL;
@@ -1818,7 +1943,7 @@ long libbpf_get_error(const void *ptr)
1818int bpf_prog_load(const char *file, enum bpf_prog_type type, 1943int bpf_prog_load(const char *file, enum bpf_prog_type type,
1819 struct bpf_object **pobj, int *prog_fd) 1944 struct bpf_object **pobj, int *prog_fd)
1820{ 1945{
1821 struct bpf_program *prog; 1946 struct bpf_program *prog, *first_prog = NULL;
1822 struct bpf_object *obj; 1947 struct bpf_object *obj;
1823 int err; 1948 int err;
1824 1949
@@ -1826,13 +1951,30 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,
1826 if (IS_ERR(obj)) 1951 if (IS_ERR(obj))
1827 return -ENOENT; 1952 return -ENOENT;
1828 1953
1829 prog = bpf_program__next(NULL, obj); 1954 bpf_object__for_each_program(prog, obj) {
1830 if (!prog) { 1955 /*
1956 * If type is not specified, try to guess it based on
1957 * section name.
1958 */
1959 if (type == BPF_PROG_TYPE_UNSPEC) {
1960 type = bpf_program__guess_type(prog);
1961 if (type == BPF_PROG_TYPE_UNSPEC) {
1962 bpf_object__close(obj);
1963 return -EINVAL;
1964 }
1965 }
1966
1967 bpf_program__set_type(prog, type);
1968 if (prog->idx != obj->efile.text_shndx && !first_prog)
1969 first_prog = prog;
1970 }
1971
1972 if (!first_prog) {
1973 pr_warning("object file doesn't contain bpf program\n");
1831 bpf_object__close(obj); 1974 bpf_object__close(obj);
1832 return -ENOENT; 1975 return -ENOENT;
1833 } 1976 }
1834 1977
1835 bpf_program__set_type(prog, type);
1836 err = bpf_object__load(obj); 1978 err = bpf_object__load(obj);
1837 if (err) { 1979 if (err) {
1838 bpf_object__close(obj); 1980 bpf_object__close(obj);
@@ -1840,6 +1982,6 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,
1840 } 1982 }
1841 1983
1842 *pobj = obj; 1984 *pobj = obj;
1843 *prog_fd = bpf_program__fd(prog); 1985 *prog_fd = bpf_program__fd(first_prog);
1844 return 0; 1986 return 0;
1845} 1987}
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 6e20003109e0..f85906533cdd 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -1,3 +1,5 @@
1/* SPDX-License-Identifier: LGPL-2.1 */
2
1/* 3/*
2 * Common eBPF ELF object loading operations. 4 * Common eBPF ELF object loading operations.
3 * 5 *
@@ -42,6 +44,8 @@ enum libbpf_errno {
42 LIBBPF_ERRNO__PROG2BIG, /* Program too big */ 44 LIBBPF_ERRNO__PROG2BIG, /* Program too big */
43 LIBBPF_ERRNO__KVER, /* Incorrect kernel version */ 45 LIBBPF_ERRNO__KVER, /* Incorrect kernel version */
44 LIBBPF_ERRNO__PROGTYPE, /* Kernel doesn't support this program type */ 46 LIBBPF_ERRNO__PROGTYPE, /* Kernel doesn't support this program type */
47 LIBBPF_ERRNO__WRNGPID, /* Wrong pid in netlink message */
48 LIBBPF_ERRNO__INVSEQ, /* Invalid netlink sequence */
45 __LIBBPF_ERRNO__END, 49 __LIBBPF_ERRNO__END,
46}; 50};
47 51
@@ -246,4 +250,6 @@ long libbpf_get_error(const void *ptr);
246 250
247int bpf_prog_load(const char *file, enum bpf_prog_type type, 251int bpf_prog_load(const char *file, enum bpf_prog_type type,
248 struct bpf_object **pobj, int *prog_fd); 252 struct bpf_object **pobj, int *prog_fd);
253
254int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
249#endif 255#endif
diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c
new file mode 100644
index 000000000000..4719434278b2
--- /dev/null
+++ b/tools/lib/bpf/nlattr.c
@@ -0,0 +1,187 @@
1// SPDX-License-Identifier: LGPL-2.1
2
3/*
4 * NETLINK Netlink attributes
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation version 2.1
9 * of the License.
10 *
11 * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
12 */
13
14#include <errno.h>
15#include "nlattr.h"
16#include <linux/rtnetlink.h>
17#include <string.h>
18#include <stdio.h>
19
20static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
21 [NLA_U8] = sizeof(uint8_t),
22 [NLA_U16] = sizeof(uint16_t),
23 [NLA_U32] = sizeof(uint32_t),
24 [NLA_U64] = sizeof(uint64_t),
25 [NLA_STRING] = 1,
26 [NLA_FLAG] = 0,
27};
28
29static int nla_len(const struct nlattr *nla)
30{
31 return nla->nla_len - NLA_HDRLEN;
32}
33
34static struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
35{
36 int totlen = NLA_ALIGN(nla->nla_len);
37
38 *remaining -= totlen;
39 return (struct nlattr *) ((char *) nla + totlen);
40}
41
42static int nla_ok(const struct nlattr *nla, int remaining)
43{
44 return remaining >= sizeof(*nla) &&
45 nla->nla_len >= sizeof(*nla) &&
46 nla->nla_len <= remaining;
47}
48
49static void *nla_data(const struct nlattr *nla)
50{
51 return (char *) nla + NLA_HDRLEN;
52}
53
54static int nla_type(const struct nlattr *nla)
55{
56 return nla->nla_type & NLA_TYPE_MASK;
57}
58
59static int validate_nla(struct nlattr *nla, int maxtype,
60 struct nla_policy *policy)
61{
62 struct nla_policy *pt;
63 unsigned int minlen = 0;
64 int type = nla_type(nla);
65
66 if (type < 0 || type > maxtype)
67 return 0;
68
69 pt = &policy[type];
70
71 if (pt->type > NLA_TYPE_MAX)
72 return 0;
73
74 if (pt->minlen)
75 minlen = pt->minlen;
76 else if (pt->type != NLA_UNSPEC)
77 minlen = nla_attr_minlen[pt->type];
78
79 if (nla_len(nla) < minlen)
80 return -1;
81
82 if (pt->maxlen && nla_len(nla) > pt->maxlen)
83 return -1;
84
85 if (pt->type == NLA_STRING) {
86 char *data = nla_data(nla);
87 if (data[nla_len(nla) - 1] != '\0')
88 return -1;
89 }
90
91 return 0;
92}
93
94static inline int nlmsg_len(const struct nlmsghdr *nlh)
95{
96 return nlh->nlmsg_len - NLMSG_HDRLEN;
97}
98
99/**
100 * Create attribute index based on a stream of attributes.
101 * @arg tb Index array to be filled (maxtype+1 elements).
102 * @arg maxtype Maximum attribute type expected and accepted.
103 * @arg head Head of attribute stream.
104 * @arg len Length of attribute stream.
105 * @arg policy Attribute validation policy.
106 *
107 * Iterates over the stream of attributes and stores a pointer to each
108 * attribute in the index array using the attribute type as index to
109 * the array. Attribute with a type greater than the maximum type
110 * specified will be silently ignored in order to maintain backwards
111 * compatibility. If \a policy is not NULL, the attribute will be
112 * validated using the specified policy.
113 *
114 * @see nla_validate
115 * @return 0 on success or a negative error code.
116 */
117static int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
118 struct nla_policy *policy)
119{
120 struct nlattr *nla;
121 int rem, err;
122
123 memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
124
125 nla_for_each_attr(nla, head, len, rem) {
126 int type = nla_type(nla);
127
128 if (type > maxtype)
129 continue;
130
131 if (policy) {
132 err = validate_nla(nla, maxtype, policy);
133 if (err < 0)
134 goto errout;
135 }
136
137 if (tb[type])
138 fprintf(stderr, "Attribute of type %#x found multiple times in message, "
139 "previous attribute is being ignored.\n", type);
140
141 tb[type] = nla;
142 }
143
144 err = 0;
145errout:
146 return err;
147}
148
149/* dump netlink extended ack error message */
150int nla_dump_errormsg(struct nlmsghdr *nlh)
151{
152 struct nla_policy extack_policy[NLMSGERR_ATTR_MAX + 1] = {
153 [NLMSGERR_ATTR_MSG] = { .type = NLA_STRING },
154 [NLMSGERR_ATTR_OFFS] = { .type = NLA_U32 },
155 };
156 struct nlattr *tb[NLMSGERR_ATTR_MAX + 1], *attr;
157 struct nlmsgerr *err;
158 char *errmsg = NULL;
159 int hlen, alen;
160
161 /* no TLVs, nothing to do here */
162 if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS))
163 return 0;
164
165 err = (struct nlmsgerr *)NLMSG_DATA(nlh);
166 hlen = sizeof(*err);
167
168 /* if NLM_F_CAPPED is set then the inner err msg was capped */
169 if (!(nlh->nlmsg_flags & NLM_F_CAPPED))
170 hlen += nlmsg_len(&err->msg);
171
172 attr = (struct nlattr *) ((void *) err + hlen);
173 alen = nlh->nlmsg_len - hlen;
174
175 if (nla_parse(tb, NLMSGERR_ATTR_MAX, attr, alen, extack_policy) != 0) {
176 fprintf(stderr,
177 "Failed to parse extended error attributes\n");
178 return 0;
179 }
180
181 if (tb[NLMSGERR_ATTR_MSG])
182 errmsg = (char *) nla_data(tb[NLMSGERR_ATTR_MSG]);
183
184 fprintf(stderr, "Kernel error message: %s\n", errmsg);
185
186 return 0;
187}
diff --git a/tools/lib/bpf/nlattr.h b/tools/lib/bpf/nlattr.h
new file mode 100644
index 000000000000..931a71f68f93
--- /dev/null
+++ b/tools/lib/bpf/nlattr.h
@@ -0,0 +1,72 @@
1/* SPDX-License-Identifier: LGPL-2.1 */
2
3/*
4 * NETLINK Netlink attributes
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation version 2.1
9 * of the License.
10 *
11 * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
12 */
13
14#ifndef __NLATTR_H
15#define __NLATTR_H
16
17#include <stdint.h>
18#include <linux/netlink.h>
19/* avoid multiple definition of netlink features */
20#define __LINUX_NETLINK_H
21
22/**
23 * Standard attribute types to specify validation policy
24 */
25enum {
26 NLA_UNSPEC, /**< Unspecified type, binary data chunk */
27 NLA_U8, /**< 8 bit integer */
28 NLA_U16, /**< 16 bit integer */
29 NLA_U32, /**< 32 bit integer */
30 NLA_U64, /**< 64 bit integer */
31 NLA_STRING, /**< NUL terminated character string */
32 NLA_FLAG, /**< Flag */
33 NLA_MSECS, /**< Micro seconds (64bit) */
34 NLA_NESTED, /**< Nested attributes */
35 __NLA_TYPE_MAX,
36};
37
38#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
39
40/**
41 * @ingroup attr
42 * Attribute validation policy.
43 *
44 * See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
45 */
46struct nla_policy {
47 /** Type of attribute or NLA_UNSPEC */
48 uint16_t type;
49
50 /** Minimal length of payload required */
51 uint16_t minlen;
52
53 /** Maximal length of payload allowed */
54 uint16_t maxlen;
55};
56
57/**
58 * @ingroup attr
59 * Iterate over a stream of attributes
60 * @arg pos loop counter, set to current attribute
61 * @arg head head of attribute stream
62 * @arg len length of attribute stream
63 * @arg rem initialized to len, holds bytes currently remaining in stream
64 */
65#define nla_for_each_attr(pos, head, len, rem) \
66 for (pos = head, rem = len; \
67 nla_ok(pos, rem); \
68 pos = nla_next(pos, &(rem)))
69
70int nla_dump_errormsg(struct nlmsghdr *nlh);
71
72#endif /* __NLATTR_H */
diff --git a/tools/lib/find_bit.c b/tools/lib/find_bit.c
index 42c15f906aac..a88bd507091e 100644
--- a/tools/lib/find_bit.c
+++ b/tools/lib/find_bit.c
@@ -22,22 +22,29 @@
22#include <linux/bitmap.h> 22#include <linux/bitmap.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24 24
25#if !defined(find_next_bit) 25#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \
26 !defined(find_next_and_bit)
26 27
27/* 28/*
28 * This is a common helper function for find_next_bit and 29 * This is a common helper function for find_next_bit, find_next_zero_bit, and
29 * find_next_zero_bit. The difference is the "invert" argument, which 30 * find_next_and_bit. The differences are:
30 * is XORed with each fetched word before searching it for one bits. 31 * - The "invert" argument, which is XORed with each fetched word before
32 * searching it for one bits.
33 * - The optional "addr2", which is anded with "addr1" if present.
31 */ 34 */
32static unsigned long _find_next_bit(const unsigned long *addr, 35static inline unsigned long _find_next_bit(const unsigned long *addr1,
33 unsigned long nbits, unsigned long start, unsigned long invert) 36 const unsigned long *addr2, unsigned long nbits,
37 unsigned long start, unsigned long invert)
34{ 38{
35 unsigned long tmp; 39 unsigned long tmp;
36 40
37 if (unlikely(start >= nbits)) 41 if (unlikely(start >= nbits))
38 return nbits; 42 return nbits;
39 43
40 tmp = addr[start / BITS_PER_LONG] ^ invert; 44 tmp = addr1[start / BITS_PER_LONG];
45 if (addr2)
46 tmp &= addr2[start / BITS_PER_LONG];
47 tmp ^= invert;
41 48
42 /* Handle 1st word. */ 49 /* Handle 1st word. */
43 tmp &= BITMAP_FIRST_WORD_MASK(start); 50 tmp &= BITMAP_FIRST_WORD_MASK(start);
@@ -48,7 +55,10 @@ static unsigned long _find_next_bit(const unsigned long *addr,
48 if (start >= nbits) 55 if (start >= nbits)
49 return nbits; 56 return nbits;
50 57
51 tmp = addr[start / BITS_PER_LONG] ^ invert; 58 tmp = addr1[start / BITS_PER_LONG];
59 if (addr2)
60 tmp &= addr2[start / BITS_PER_LONG];
61 tmp ^= invert;
52 } 62 }
53 63
54 return min(start + __ffs(tmp), nbits); 64 return min(start + __ffs(tmp), nbits);
@@ -62,7 +72,7 @@ static unsigned long _find_next_bit(const unsigned long *addr,
62unsigned long find_next_bit(const unsigned long *addr, unsigned long size, 72unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
63 unsigned long offset) 73 unsigned long offset)
64{ 74{
65 return _find_next_bit(addr, size, offset, 0UL); 75 return _find_next_bit(addr, NULL, size, offset, 0UL);
66} 76}
67#endif 77#endif
68 78
@@ -104,6 +114,15 @@ unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
104unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, 114unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
105 unsigned long offset) 115 unsigned long offset)
106{ 116{
107 return _find_next_bit(addr, size, offset, ~0UL); 117 return _find_next_bit(addr, NULL, size, offset, ~0UL);
118}
119#endif
120
121#ifndef find_next_and_bit
122unsigned long find_next_and_bit(const unsigned long *addr1,
123 const unsigned long *addr2, unsigned long size,
124 unsigned long offset)
125{
126 return _find_next_bit(addr1, addr2, size, offset, 0UL);
108} 127}
109#endif 128#endif
diff --git a/tools/lib/subcmd/pager.c b/tools/lib/subcmd/pager.c
index 5ba754d17952..9997a8805a82 100644
--- a/tools/lib/subcmd/pager.c
+++ b/tools/lib/subcmd/pager.c
@@ -30,10 +30,13 @@ static void pager_preexec(void)
30 * have real input 30 * have real input
31 */ 31 */
32 fd_set in; 32 fd_set in;
33 fd_set exception;
33 34
34 FD_ZERO(&in); 35 FD_ZERO(&in);
36 FD_ZERO(&exception);
35 FD_SET(0, &in); 37 FD_SET(0, &in);
36 select(1, &in, NULL, &in, NULL); 38 FD_SET(0, &exception);
39 select(1, &in, NULL, &exception, NULL);
37 40
38 setenv("LESS", "FRSX", 0); 41 setenv("LESS", "FRSX", 0);
39} 42}
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 7ce724fc0544..e5f2acbb70cc 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -1094,7 +1094,7 @@ static enum event_type __read_token(char **tok)
1094 if (strcmp(*tok, "LOCAL_PR_FMT") == 0) { 1094 if (strcmp(*tok, "LOCAL_PR_FMT") == 0) {
1095 free(*tok); 1095 free(*tok);
1096 *tok = NULL; 1096 *tok = NULL;
1097 return force_token("\"\%s\" ", tok); 1097 return force_token("\"%s\" ", tok);
1098 } else if (strcmp(*tok, "STA_PR_FMT") == 0) { 1098 } else if (strcmp(*tok, "STA_PR_FMT") == 0) {
1099 free(*tok); 1099 free(*tok);
1100 *tok = NULL; 1100 *tok = NULL;
@@ -3970,6 +3970,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3970 val &= ~fval; 3970 val &= ~fval;
3971 } 3971 }
3972 } 3972 }
3973 if (val) {
3974 if (print && arg->flags.delim)
3975 trace_seq_puts(s, arg->flags.delim);
3976 trace_seq_printf(s, "0x%llx", val);
3977 }
3973 break; 3978 break;
3974 case PRINT_SYMBOL: 3979 case PRINT_SYMBOL:
3975 val = eval_num_arg(data, size, event, arg->symbol.field); 3980 val = eval_num_arg(data, size, event, arg->symbol.field);
@@ -3980,6 +3985,8 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3980 break; 3985 break;
3981 } 3986 }
3982 } 3987 }
3988 if (!flag)
3989 trace_seq_printf(s, "0x%llx", val);
3983 break; 3990 break;
3984 case PRINT_HEX: 3991 case PRINT_HEX:
3985 case PRINT_HEX_STR: 3992 case PRINT_HEX_STR:
@@ -4293,6 +4300,26 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
4293 goto process_again; 4300 goto process_again;
4294 case 'p': 4301 case 'p':
4295 ls = 1; 4302 ls = 1;
4303 if (isalnum(ptr[1])) {
4304 ptr++;
4305 /* Check for special pointers */
4306 switch (*ptr) {
4307 case 's':
4308 case 'S':
4309 case 'f':
4310 case 'F':
4311 break;
4312 default:
4313 /*
4314 * Older kernels do not process
4315 * dereferenced pointers.
4316 * Only process if the pointer
4317 * value is a printable.
4318 */
4319 if (isprint(*(char *)bptr))
4320 goto process_string;
4321 }
4322 }
4296 /* fall through */ 4323 /* fall through */
4297 case 'd': 4324 case 'd':
4298 case 'u': 4325 case 'u':
@@ -4345,6 +4372,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
4345 4372
4346 break; 4373 break;
4347 case 's': 4374 case 's':
4375 process_string:
4348 arg = alloc_arg(); 4376 arg = alloc_arg();
4349 if (!arg) { 4377 if (!arg) {
4350 do_warning_event(event, "%s(%d): not enough memory!", 4378 do_warning_event(event, "%s(%d): not enough memory!",
@@ -4949,21 +4977,27 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
4949 else 4977 else
4950 ls = 2; 4978 ls = 2;
4951 4979
4952 if (*(ptr+1) == 'F' || *(ptr+1) == 'f' || 4980 if (isalnum(ptr[1]))
4953 *(ptr+1) == 'S' || *(ptr+1) == 's') {
4954 ptr++; 4981 ptr++;
4982
4983 if (arg->type == PRINT_BSTRING) {
4984 trace_seq_puts(s, arg->string.string);
4985 break;
4986 }
4987
4988 if (*ptr == 'F' || *ptr == 'f' ||
4989 *ptr == 'S' || *ptr == 's') {
4955 show_func = *ptr; 4990 show_func = *ptr;
4956 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { 4991 } else if (*ptr == 'M' || *ptr == 'm') {
4957 print_mac_arg(s, *(ptr+1), data, size, event, arg); 4992 print_mac_arg(s, *ptr, data, size, event, arg);
4958 ptr++;
4959 arg = arg->next; 4993 arg = arg->next;
4960 break; 4994 break;
4961 } else if (*(ptr+1) == 'I' || *(ptr+1) == 'i') { 4995 } else if (*ptr == 'I' || *ptr == 'i') {
4962 int n; 4996 int n;
4963 4997
4964 n = print_ip_arg(s, ptr+1, data, size, event, arg); 4998 n = print_ip_arg(s, ptr, data, size, event, arg);
4965 if (n > 0) { 4999 if (n > 0) {
4966 ptr += n; 5000 ptr += n - 1;
4967 arg = arg->next; 5001 arg = arg->next;
4968 break; 5002 break;
4969 } 5003 }
@@ -5532,8 +5566,14 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
5532 5566
5533 event = pevent_find_event_by_record(pevent, record); 5567 event = pevent_find_event_by_record(pevent, record);
5534 if (!event) { 5568 if (!event) {
5535 do_warning("ug! no event found for type %d", 5569 int i;
5536 trace_parse_common_type(pevent, record->data)); 5570 int type = trace_parse_common_type(pevent, record->data);
5571
5572 do_warning("ug! no event found for type %d", type);
5573 trace_seq_printf(s, "[UNKNOWN TYPE %d]", type);
5574 for (i = 0; i < record->size; i++)
5575 trace_seq_printf(s, " %02x",
5576 ((unsigned char *)record->data)[i]);
5537 return; 5577 return;
5538 } 5578 }
5539 5579
diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c
index a16756ae3526..d542cb60ca1a 100644
--- a/tools/lib/traceevent/event-plugin.c
+++ b/tools/lib/traceevent/event-plugin.c
@@ -120,12 +120,12 @@ char **traceevent_plugin_list_options(void)
120 for (op = reg->options; op->name; op++) { 120 for (op = reg->options; op->name; op++) {
121 char *alias = op->plugin_alias ? op->plugin_alias : op->file; 121 char *alias = op->plugin_alias ? op->plugin_alias : op->file;
122 char **temp = list; 122 char **temp = list;
123 int ret;
123 124
124 name = malloc(strlen(op->name) + strlen(alias) + 2); 125 ret = asprintf(&name, "%s:%s", alias, op->name);
125 if (!name) 126 if (ret < 0)
126 goto err; 127 goto err;
127 128
128 sprintf(name, "%s:%s", alias, op->name);
129 list = realloc(list, count + 2); 129 list = realloc(list, count + 2);
130 if (!list) { 130 if (!list) {
131 list = temp; 131 list = temp;
@@ -290,17 +290,14 @@ load_plugin(struct pevent *pevent, const char *path,
290 const char *alias; 290 const char *alias;
291 char *plugin; 291 char *plugin;
292 void *handle; 292 void *handle;
293 int ret;
293 294
294 plugin = malloc(strlen(path) + strlen(file) + 2); 295 ret = asprintf(&plugin, "%s/%s", path, file);
295 if (!plugin) { 296 if (ret < 0) {
296 warning("could not allocate plugin memory\n"); 297 warning("could not allocate plugin memory\n");
297 return; 298 return;
298 } 299 }
299 300
300 strcpy(plugin, path);
301 strcat(plugin, "/");
302 strcat(plugin, file);
303
304 handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL); 301 handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL);
305 if (!handle) { 302 if (!handle) {
306 warning("could not load plugin '%s'\n%s\n", 303 warning("could not load plugin '%s'\n%s\n",
@@ -391,6 +388,7 @@ load_plugins(struct pevent *pevent, const char *suffix,
391 char *home; 388 char *home;
392 char *path; 389 char *path;
393 char *envdir; 390 char *envdir;
391 int ret;
394 392
395 if (pevent->flags & PEVENT_DISABLE_PLUGINS) 393 if (pevent->flags & PEVENT_DISABLE_PLUGINS)
396 return; 394 return;
@@ -421,16 +419,12 @@ load_plugins(struct pevent *pevent, const char *suffix,
421 if (!home) 419 if (!home)
422 return; 420 return;
423 421
424 path = malloc(strlen(home) + strlen(LOCAL_PLUGIN_DIR) + 2); 422 ret = asprintf(&path, "%s/%s", home, LOCAL_PLUGIN_DIR);
425 if (!path) { 423 if (ret < 0) {
426 warning("could not allocate plugin memory\n"); 424 warning("could not allocate plugin memory\n");
427 return; 425 return;
428 } 426 }
429 427
430 strcpy(path, home);
431 strcat(path, "/");
432 strcat(path, LOCAL_PLUGIN_DIR);
433
434 load_plugins_dir(pevent, suffix, path, load_plugin, data); 428 load_plugins_dir(pevent, suffix, path, load_plugin, data);
435 429
436 free(path); 430 free(path);
diff --git a/tools/lib/traceevent/kbuffer-parse.c b/tools/lib/traceevent/kbuffer-parse.c
index c94e3641b046..ca424b157e46 100644
--- a/tools/lib/traceevent/kbuffer-parse.c
+++ b/tools/lib/traceevent/kbuffer-parse.c
@@ -24,8 +24,8 @@
24 24
25#include "kbuffer.h" 25#include "kbuffer.h"
26 26
27#define MISSING_EVENTS (1 << 31) 27#define MISSING_EVENTS (1UL << 31)
28#define MISSING_STORED (1 << 30) 28#define MISSING_STORED (1UL << 30)
29 29
30#define COMMIT_MASK ((1 << 27) - 1) 30#define COMMIT_MASK ((1 << 27) - 1)
31 31
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 315df0a70265..431e8b309f6e 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -287,12 +287,10 @@ find_event(struct pevent *pevent, struct event_list **events,
287 sys_name = NULL; 287 sys_name = NULL;
288 } 288 }
289 289
290 reg = malloc(strlen(event_name) + 3); 290 ret = asprintf(&reg, "^%s$", event_name);
291 if (reg == NULL) 291 if (ret < 0)
292 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 292 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
293 293
294 sprintf(reg, "^%s$", event_name);
295
296 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB); 294 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
297 free(reg); 295 free(reg);
298 296
@@ -300,13 +298,12 @@ find_event(struct pevent *pevent, struct event_list **events,
300 return PEVENT_ERRNO__INVALID_EVENT_NAME; 298 return PEVENT_ERRNO__INVALID_EVENT_NAME;
301 299
302 if (sys_name) { 300 if (sys_name) {
303 reg = malloc(strlen(sys_name) + 3); 301 ret = asprintf(&reg, "^%s$", sys_name);
304 if (reg == NULL) { 302 if (ret < 0) {
305 regfree(&ereg); 303 regfree(&ereg);
306 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 304 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
307 } 305 }
308 306
309 sprintf(reg, "^%s$", sys_name);
310 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB); 307 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
311 free(reg); 308 free(reg);
312 if (ret) { 309 if (ret) {
@@ -1634,6 +1631,7 @@ int pevent_filter_clear_trivial(struct event_filter *filter,
1634 case FILTER_TRIVIAL_FALSE: 1631 case FILTER_TRIVIAL_FALSE:
1635 if (filter_type->filter->boolean.value) 1632 if (filter_type->filter->boolean.value)
1636 continue; 1633 continue;
1634 break;
1637 case FILTER_TRIVIAL_TRUE: 1635 case FILTER_TRIVIAL_TRUE:
1638 if (!filter_type->filter->boolean.value) 1636 if (!filter_type->filter->boolean.value)
1639 continue; 1637 continue;
@@ -1879,17 +1877,25 @@ static const char *get_field_str(struct filter_arg *arg, struct pevent_record *r
1879 struct pevent *pevent; 1877 struct pevent *pevent;
1880 unsigned long long addr; 1878 unsigned long long addr;
1881 const char *val = NULL; 1879 const char *val = NULL;
1880 unsigned int size;
1882 char hex[64]; 1881 char hex[64];
1883 1882
1884 /* If the field is not a string convert it */ 1883 /* If the field is not a string convert it */
1885 if (arg->str.field->flags & FIELD_IS_STRING) { 1884 if (arg->str.field->flags & FIELD_IS_STRING) {
1886 val = record->data + arg->str.field->offset; 1885 val = record->data + arg->str.field->offset;
1886 size = arg->str.field->size;
1887
1888 if (arg->str.field->flags & FIELD_IS_DYNAMIC) {
1889 addr = *(unsigned int *)val;
1890 val = record->data + (addr & 0xffff);
1891 size = addr >> 16;
1892 }
1887 1893
1888 /* 1894 /*
1889 * We need to copy the data since we can't be sure the field 1895 * We need to copy the data since we can't be sure the field
1890 * is null terminated. 1896 * is null terminated.
1891 */ 1897 */
1892 if (*(val + arg->str.field->size - 1)) { 1898 if (*(val + size - 1)) {
1893 /* copy it */ 1899 /* copy it */
1894 memcpy(arg->str.buffer, val, arg->str.field->size); 1900 memcpy(arg->str.buffer, val, arg->str.field->size);
1895 /* the buffer is already NULL terminated */ 1901 /* the buffer is already NULL terminated */