aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib')
-rw-r--r--tools/lib/bpf/Makefile24
-rw-r--r--tools/lib/bpf/bpf.h2
-rw-r--r--tools/lib/bpf/libbpf.c200
-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
7 files changed, 253 insertions, 85 deletions
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index 4555304dc18e..83714ca1f22b 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
@@ -169,21 +168,11 @@ $(OUTPUT)libbpf.so: $(BPF_IN)
169$(OUTPUT)libbpf.a: $(BPF_IN) 168$(OUTPUT)libbpf.a: $(BPF_IN)
170 $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ 169 $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
171 170
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 171define do_install
183 if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ 172 if [ ! -d '$(DESTDIR_SQ)$2' ]; then \
184 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ 173 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \
185 fi; \ 174 fi; \
186 $(INSTALL) $1 '$(DESTDIR_SQ)$2' 175 $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2'
187endef 176endef
188 177
189install_lib: all_cmd 178install_lib: all_cmd
@@ -192,7 +181,8 @@ install_lib: all_cmd
192 181
193install_headers: 182install_headers:
194 $(call QUIET_INSTALL, headers) \ 183 $(call QUIET_INSTALL, headers) \
195 $(call do_install,bpf.h,$(prefix)/include/bpf,644) 184 $(call do_install,bpf.h,$(prefix)/include/bpf,644); \
185 $(call do_install,libbpf.h,$(prefix)/include/bpf,644);
196 186
197install: install_lib 187install: install_lib
198 188
@@ -203,7 +193,7 @@ config-clean:
203 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null 193 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null
204 194
205clean: 195clean:
206 $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd \ 196 $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so .*.d .*.cmd \
207 $(RM) LIBBPF-CFLAGS 197 $(RM) LIBBPF-CFLAGS
208 $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf 198 $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf
209 199
@@ -213,10 +203,10 @@ PHONY += force elfdep bpfdep
213force: 203force:
214 204
215elfdep: 205elfdep:
216 @if [ "$(feature-libelf)" != "1" ]; then echo "No libelf found"; exit -1 ; fi 206 @if [ "$(feature-libelf)" != "1" ]; then echo "No libelf found"; exit 1 ; fi
217 207
218bpfdep: 208bpfdep:
219 @if [ "$(feature-bpf)" != "1" ]; then echo "BPF API too old"; exit -1 ; fi 209 @if [ "$(feature-bpf)" != "1" ]; then echo "BPF API too old"; exit 1 ; fi
220 210
221# Declare the contents of the .PHONY variable as phony. We keep that 211# 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. 212# information in a variable so we can use it in if_changed and friends.
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 6534889e2b2f..9f44c196931e 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -40,7 +40,7 @@ int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name,
40 __u32 map_flags); 40 __u32 map_flags);
41 41
42/* Recommend log buffer size */ 42/* Recommend log buffer size */
43#define BPF_LOG_BUF_SIZE 65536 43#define BPF_LOG_BUF_SIZE (256 * 1024)
44int bpf_load_program_name(enum bpf_prog_type type, const char *name, 44int bpf_load_program_name(enum bpf_prog_type type, const char *name,
45 const struct bpf_insn *insns, 45 const struct bpf_insn *insns,
46 size_t insns_cnt, const char *license, 46 size_t insns_cnt, const char *license,
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 5aa45f89da93..30c776375118 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -174,12 +174,19 @@ struct bpf_program {
174 char *name; 174 char *name;
175 char *section_name; 175 char *section_name;
176 struct bpf_insn *insns; 176 struct bpf_insn *insns;
177 size_t insns_cnt; 177 size_t insns_cnt, main_prog_cnt;
178 enum bpf_prog_type type; 178 enum bpf_prog_type type;
179 179
180 struct { 180 struct reloc_desc {
181 enum {
182 RELO_LD64,
183 RELO_CALL,
184 } type;
181 int insn_idx; 185 int insn_idx;
182 int map_idx; 186 union {
187 int map_idx;
188 int text_off;
189 };
183 } *reloc_desc; 190 } *reloc_desc;
184 int nr_reloc; 191 int nr_reloc;
185 192
@@ -234,6 +241,7 @@ struct bpf_object {
234 } *reloc; 241 } *reloc;
235 int nr_reloc; 242 int nr_reloc;
236 int maps_shndx; 243 int maps_shndx;
244 int text_shndx;
237 } efile; 245 } efile;
238 /* 246 /*
239 * All loaded bpf_object is linked in a list, which is 247 * All loaded bpf_object is linked in a list, which is
@@ -375,9 +383,13 @@ bpf_object__init_prog_names(struct bpf_object *obj)
375 size_t pi, si; 383 size_t pi, si;
376 384
377 for (pi = 0; pi < obj->nr_programs; pi++) { 385 for (pi = 0; pi < obj->nr_programs; pi++) {
378 char *name = NULL; 386 const char *name = NULL;
379 387
380 prog = &obj->programs[pi]; 388 prog = &obj->programs[pi];
389 if (prog->idx == obj->efile.text_shndx) {
390 name = ".text";
391 goto skip_search;
392 }
381 393
382 for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name; 394 for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name;
383 si++) { 395 si++) {
@@ -387,6 +399,8 @@ bpf_object__init_prog_names(struct bpf_object *obj)
387 continue; 399 continue;
388 if (sym.st_shndx != prog->idx) 400 if (sym.st_shndx != prog->idx)
389 continue; 401 continue;
402 if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL)
403 continue;
390 404
391 name = elf_strptr(obj->efile.elf, 405 name = elf_strptr(obj->efile.elf,
392 obj->efile.strtabidx, 406 obj->efile.strtabidx,
@@ -403,7 +417,7 @@ bpf_object__init_prog_names(struct bpf_object *obj)
403 prog->section_name); 417 prog->section_name);
404 return -EINVAL; 418 return -EINVAL;
405 } 419 }
406 420skip_search:
407 prog->name = strdup(name); 421 prog->name = strdup(name);
408 if (!prog->name) { 422 if (!prog->name) {
409 pr_warning("failed to allocate memory for prog sym %s\n", 423 pr_warning("failed to allocate memory for prog sym %s\n",
@@ -793,6 +807,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
793 } else if ((sh.sh_type == SHT_PROGBITS) && 807 } else if ((sh.sh_type == SHT_PROGBITS) &&
794 (sh.sh_flags & SHF_EXECINSTR) && 808 (sh.sh_flags & SHF_EXECINSTR) &&
795 (data->d_size > 0)) { 809 (data->d_size > 0)) {
810 if (strcmp(name, ".text") == 0)
811 obj->efile.text_shndx = idx;
796 err = bpf_object__add_program(obj, data->d_buf, 812 err = bpf_object__add_program(obj, data->d_buf,
797 data->d_size, name, idx); 813 data->d_size, name, idx);
798 if (err) { 814 if (err) {
@@ -854,11 +870,14 @@ bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx)
854} 870}
855 871
856static int 872static int
857bpf_program__collect_reloc(struct bpf_program *prog, 873bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
858 size_t nr_maps, GElf_Shdr *shdr, 874 Elf_Data *data, struct bpf_object *obj)
859 Elf_Data *data, Elf_Data *symbols,
860 int maps_shndx, struct bpf_map *maps)
861{ 875{
876 Elf_Data *symbols = obj->efile.symbols;
877 int text_shndx = obj->efile.text_shndx;
878 int maps_shndx = obj->efile.maps_shndx;
879 struct bpf_map *maps = obj->maps;
880 size_t nr_maps = obj->nr_maps;
862 int i, nrels; 881 int i, nrels;
863 882
864 pr_debug("collecting relocating info for: '%s'\n", 883 pr_debug("collecting relocating info for: '%s'\n",
@@ -891,8 +910,11 @@ bpf_program__collect_reloc(struct bpf_program *prog,
891 GELF_R_SYM(rel.r_info)); 910 GELF_R_SYM(rel.r_info));
892 return -LIBBPF_ERRNO__FORMAT; 911 return -LIBBPF_ERRNO__FORMAT;
893 } 912 }
913 pr_debug("relo for %lld value %lld name %d\n",
914 (long long) (rel.r_info >> 32),
915 (long long) sym.st_value, sym.st_name);
894 916
895 if (sym.st_shndx != maps_shndx) { 917 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", 918 pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n",
897 prog->section_name, sym.st_shndx); 919 prog->section_name, sym.st_shndx);
898 return -LIBBPF_ERRNO__RELOC; 920 return -LIBBPF_ERRNO__RELOC;
@@ -901,6 +923,17 @@ bpf_program__collect_reloc(struct bpf_program *prog,
901 insn_idx = rel.r_offset / sizeof(struct bpf_insn); 923 insn_idx = rel.r_offset / sizeof(struct bpf_insn);
902 pr_debug("relocation: insn_idx=%u\n", insn_idx); 924 pr_debug("relocation: insn_idx=%u\n", insn_idx);
903 925
926 if (insns[insn_idx].code == (BPF_JMP | BPF_CALL)) {
927 if (insns[insn_idx].src_reg != BPF_PSEUDO_CALL) {
928 pr_warning("incorrect bpf_call opcode\n");
929 return -LIBBPF_ERRNO__RELOC;
930 }
931 prog->reloc_desc[i].type = RELO_CALL;
932 prog->reloc_desc[i].insn_idx = insn_idx;
933 prog->reloc_desc[i].text_off = sym.st_value;
934 continue;
935 }
936
904 if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) { 937 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", 938 pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
906 insn_idx, insns[insn_idx].code); 939 insn_idx, insns[insn_idx].code);
@@ -922,6 +955,7 @@ bpf_program__collect_reloc(struct bpf_program *prog,
922 return -LIBBPF_ERRNO__RELOC; 955 return -LIBBPF_ERRNO__RELOC;
923 } 956 }
924 957
958 prog->reloc_desc[i].type = RELO_LD64;
925 prog->reloc_desc[i].insn_idx = insn_idx; 959 prog->reloc_desc[i].insn_idx = insn_idx;
926 prog->reloc_desc[i].map_idx = map_idx; 960 prog->reloc_desc[i].map_idx = map_idx;
927 } 961 }
@@ -961,27 +995,76 @@ bpf_object__create_maps(struct bpf_object *obj)
961} 995}
962 996
963static int 997static int
998bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
999 struct reloc_desc *relo)
1000{
1001 struct bpf_insn *insn, *new_insn;
1002 struct bpf_program *text;
1003 size_t new_cnt;
1004
1005 if (relo->type != RELO_CALL)
1006 return -LIBBPF_ERRNO__RELOC;
1007
1008 if (prog->idx == obj->efile.text_shndx) {
1009 pr_warning("relo in .text insn %d into off %d\n",
1010 relo->insn_idx, relo->text_off);
1011 return -LIBBPF_ERRNO__RELOC;
1012 }
1013
1014 if (prog->main_prog_cnt == 0) {
1015 text = bpf_object__find_prog_by_idx(obj, obj->efile.text_shndx);
1016 if (!text) {
1017 pr_warning("no .text section found yet relo into text exist\n");
1018 return -LIBBPF_ERRNO__RELOC;
1019 }
1020 new_cnt = prog->insns_cnt + text->insns_cnt;
1021 new_insn = realloc(prog->insns, new_cnt * sizeof(*insn));
1022 if (!new_insn) {
1023 pr_warning("oom in prog realloc\n");
1024 return -ENOMEM;
1025 }
1026 memcpy(new_insn + prog->insns_cnt, text->insns,
1027 text->insns_cnt * sizeof(*insn));
1028 prog->insns = new_insn;
1029 prog->main_prog_cnt = prog->insns_cnt;
1030 prog->insns_cnt = new_cnt;
1031 }
1032 insn = &prog->insns[relo->insn_idx];
1033 insn->imm += prog->main_prog_cnt - relo->insn_idx;
1034 pr_debug("added %zd insn from %s to prog %s\n",
1035 text->insns_cnt, text->section_name, prog->section_name);
1036 return 0;
1037}
1038
1039static int
964bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj) 1040bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
965{ 1041{
966 int i; 1042 int i, err;
967 1043
968 if (!prog || !prog->reloc_desc) 1044 if (!prog || !prog->reloc_desc)
969 return 0; 1045 return 0;
970 1046
971 for (i = 0; i < prog->nr_reloc; i++) { 1047 for (i = 0; i < prog->nr_reloc; i++) {
972 int insn_idx, map_idx; 1048 if (prog->reloc_desc[i].type == RELO_LD64) {
973 struct bpf_insn *insns = prog->insns; 1049 struct bpf_insn *insns = prog->insns;
1050 int insn_idx, map_idx;
974 1051
975 insn_idx = prog->reloc_desc[i].insn_idx; 1052 insn_idx = prog->reloc_desc[i].insn_idx;
976 map_idx = prog->reloc_desc[i].map_idx; 1053 map_idx = prog->reloc_desc[i].map_idx;
977 1054
978 if (insn_idx >= (int)prog->insns_cnt) { 1055 if (insn_idx >= (int)prog->insns_cnt) {
979 pr_warning("relocation out of range: '%s'\n", 1056 pr_warning("relocation out of range: '%s'\n",
980 prog->section_name); 1057 prog->section_name);
981 return -LIBBPF_ERRNO__RELOC; 1058 return -LIBBPF_ERRNO__RELOC;
1059 }
1060 insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
1061 insns[insn_idx].imm = obj->maps[map_idx].fd;
1062 } else {
1063 err = bpf_program__reloc_text(prog, obj,
1064 &prog->reloc_desc[i]);
1065 if (err)
1066 return err;
982 } 1067 }
983 insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
984 insns[insn_idx].imm = obj->maps[map_idx].fd;
985 } 1068 }
986 1069
987 zfree(&prog->reloc_desc); 1070 zfree(&prog->reloc_desc);
@@ -1024,7 +1107,6 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
1024 Elf_Data *data = obj->efile.reloc[i].data; 1107 Elf_Data *data = obj->efile.reloc[i].data;
1025 int idx = shdr->sh_info; 1108 int idx = shdr->sh_info;
1026 struct bpf_program *prog; 1109 struct bpf_program *prog;
1027 size_t nr_maps = obj->nr_maps;
1028 1110
1029 if (shdr->sh_type != SHT_REL) { 1111 if (shdr->sh_type != SHT_REL) {
1030 pr_warning("internal error at %d\n", __LINE__); 1112 pr_warning("internal error at %d\n", __LINE__);
@@ -1038,11 +1120,9 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
1038 return -LIBBPF_ERRNO__RELOC; 1120 return -LIBBPF_ERRNO__RELOC;
1039 } 1121 }
1040 1122
1041 err = bpf_program__collect_reloc(prog, nr_maps, 1123 err = bpf_program__collect_reloc(prog,
1042 shdr, data, 1124 shdr, data,
1043 obj->efile.symbols, 1125 obj);
1044 obj->efile.maps_shndx,
1045 obj->maps);
1046 if (err) 1126 if (err)
1047 return err; 1127 return err;
1048 } 1128 }
@@ -1195,6 +1275,8 @@ bpf_object__load_progs(struct bpf_object *obj)
1195 int err; 1275 int err;
1196 1276
1197 for (i = 0; i < obj->nr_programs; i++) { 1277 for (i = 0; i < obj->nr_programs; i++) {
1278 if (obj->programs[i].idx == obj->efile.text_shndx)
1279 continue;
1198 err = bpf_program__load(&obj->programs[i], 1280 err = bpf_program__load(&obj->programs[i],
1199 obj->license, 1281 obj->license,
1200 obj->kern_version); 1282 obj->kern_version);
@@ -1721,6 +1803,45 @@ BPF_PROG_TYPE_FNS(tracepoint, BPF_PROG_TYPE_TRACEPOINT);
1721BPF_PROG_TYPE_FNS(xdp, BPF_PROG_TYPE_XDP); 1803BPF_PROG_TYPE_FNS(xdp, BPF_PROG_TYPE_XDP);
1722BPF_PROG_TYPE_FNS(perf_event, BPF_PROG_TYPE_PERF_EVENT); 1804BPF_PROG_TYPE_FNS(perf_event, BPF_PROG_TYPE_PERF_EVENT);
1723 1805
1806#define BPF_PROG_SEC(string, type) { string, sizeof(string) - 1, type }
1807static const struct {
1808 const char *sec;
1809 size_t len;
1810 enum bpf_prog_type prog_type;
1811} section_names[] = {
1812 BPF_PROG_SEC("socket", BPF_PROG_TYPE_SOCKET_FILTER),
1813 BPF_PROG_SEC("kprobe/", BPF_PROG_TYPE_KPROBE),
1814 BPF_PROG_SEC("kretprobe/", BPF_PROG_TYPE_KPROBE),
1815 BPF_PROG_SEC("tracepoint/", BPF_PROG_TYPE_TRACEPOINT),
1816 BPF_PROG_SEC("xdp", BPF_PROG_TYPE_XDP),
1817 BPF_PROG_SEC("perf_event", BPF_PROG_TYPE_PERF_EVENT),
1818 BPF_PROG_SEC("cgroup/skb", BPF_PROG_TYPE_CGROUP_SKB),
1819 BPF_PROG_SEC("cgroup/sock", BPF_PROG_TYPE_CGROUP_SOCK),
1820 BPF_PROG_SEC("cgroup/dev", BPF_PROG_TYPE_CGROUP_DEVICE),
1821 BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS),
1822 BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB),
1823};
1824#undef BPF_PROG_SEC
1825
1826static enum bpf_prog_type bpf_program__guess_type(struct bpf_program *prog)
1827{
1828 int i;
1829
1830 if (!prog->section_name)
1831 goto err;
1832
1833 for (i = 0; i < ARRAY_SIZE(section_names); i++)
1834 if (strncmp(prog->section_name, section_names[i].sec,
1835 section_names[i].len) == 0)
1836 return section_names[i].prog_type;
1837
1838err:
1839 pr_warning("failed to guess program type based on section name %s\n",
1840 prog->section_name);
1841
1842 return BPF_PROG_TYPE_UNSPEC;
1843}
1844
1724int bpf_map__fd(struct bpf_map *map) 1845int bpf_map__fd(struct bpf_map *map)
1725{ 1846{
1726 return map ? map->fd : -EINVAL; 1847 return map ? map->fd : -EINVAL;
@@ -1818,7 +1939,7 @@ long libbpf_get_error(const void *ptr)
1818int bpf_prog_load(const char *file, enum bpf_prog_type type, 1939int bpf_prog_load(const char *file, enum bpf_prog_type type,
1819 struct bpf_object **pobj, int *prog_fd) 1940 struct bpf_object **pobj, int *prog_fd)
1820{ 1941{
1821 struct bpf_program *prog; 1942 struct bpf_program *prog, *first_prog = NULL;
1822 struct bpf_object *obj; 1943 struct bpf_object *obj;
1823 int err; 1944 int err;
1824 1945
@@ -1826,13 +1947,30 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,
1826 if (IS_ERR(obj)) 1947 if (IS_ERR(obj))
1827 return -ENOENT; 1948 return -ENOENT;
1828 1949
1829 prog = bpf_program__next(NULL, obj); 1950 bpf_object__for_each_program(prog, obj) {
1830 if (!prog) { 1951 /*
1952 * If type is not specified, try to guess it based on
1953 * section name.
1954 */
1955 if (type == BPF_PROG_TYPE_UNSPEC) {
1956 type = bpf_program__guess_type(prog);
1957 if (type == BPF_PROG_TYPE_UNSPEC) {
1958 bpf_object__close(obj);
1959 return -EINVAL;
1960 }
1961 }
1962
1963 bpf_program__set_type(prog, type);
1964 if (prog->idx != obj->efile.text_shndx && !first_prog)
1965 first_prog = prog;
1966 }
1967
1968 if (!first_prog) {
1969 pr_warning("object file doesn't contain bpf program\n");
1831 bpf_object__close(obj); 1970 bpf_object__close(obj);
1832 return -ENOENT; 1971 return -ENOENT;
1833 } 1972 }
1834 1973
1835 bpf_program__set_type(prog, type);
1836 err = bpf_object__load(obj); 1974 err = bpf_object__load(obj);
1837 if (err) { 1975 if (err) {
1838 bpf_object__close(obj); 1976 bpf_object__close(obj);
@@ -1840,6 +1978,6 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,
1840 } 1978 }
1841 1979
1842 *pobj = obj; 1980 *pobj = obj;
1843 *prog_fd = bpf_program__fd(prog); 1981 *prog_fd = bpf_program__fd(first_prog);
1844 return 0; 1982 return 0;
1845} 1983}
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 */