aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib')
-rw-r--r--tools/lib/api/Build2
-rw-r--r--tools/lib/api/Makefile58
-rw-r--r--tools/lib/api/fd/Build1
-rw-r--r--tools/lib/api/fs/Build4
-rw-r--r--tools/lib/api/fs/debugfs.c69
-rw-r--r--tools/lib/api/fs/debugfs.h13
-rw-r--r--tools/lib/api/fs/findfs.c63
-rw-r--r--tools/lib/api/fs/findfs.h23
-rw-r--r--tools/lib/api/fs/tracefs.c78
-rw-r--r--tools/lib/api/fs/tracefs.h21
-rw-r--r--tools/lib/lockdep/Build1
-rw-r--r--tools/lib/lockdep/Makefile132
-rw-r--r--tools/lib/traceevent/Build17
-rw-r--r--tools/lib/traceevent/Makefile169
-rw-r--r--tools/lib/traceevent/event-parse.c288
-rw-r--r--tools/lib/traceevent/event-parse.h24
-rw-r--r--tools/lib/traceevent/event-plugin.c60
-rw-r--r--tools/lib/traceevent/kbuffer-parse.c12
-rw-r--r--tools/lib/traceevent/kbuffer.h1
-rw-r--r--tools/lib/traceevent/parse-filter.c2
-rw-r--r--tools/lib/traceevent/trace-seq.c13
21 files changed, 673 insertions, 378 deletions
diff --git a/tools/lib/api/Build b/tools/lib/api/Build
new file mode 100644
index 000000000000..3653965cf481
--- /dev/null
+++ b/tools/lib/api/Build
@@ -0,0 +1,2 @@
1libapi-y += fd/
2libapi-y += fs/
diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile
index 36c08b1f4afb..d8fe29fc19a4 100644
--- a/tools/lib/api/Makefile
+++ b/tools/lib/api/Makefile
@@ -1,49 +1,43 @@
1include ../../scripts/Makefile.include 1include ../../scripts/Makefile.include
2include ../../perf/config/utilities.mak # QUIET_CLEAN 2include ../../perf/config/utilities.mak # QUIET_CLEAN
3 3
4ifeq ($(srctree),)
5srctree := $(patsubst %/,%,$(dir $(shell pwd)))
6srctree := $(patsubst %/,%,$(dir $(srctree)))
7srctree := $(patsubst %/,%,$(dir $(srctree)))
8#$(info Determined 'srctree' to be $(srctree))
9endif
10
4CC = $(CROSS_COMPILE)gcc 11CC = $(CROSS_COMPILE)gcc
5AR = $(CROSS_COMPILE)ar 12AR = $(CROSS_COMPILE)ar
6 13
7# guard against environment variables 14MAKEFLAGS += --no-print-directory
8LIB_H=
9LIB_OBJS=
10
11LIB_H += fs/debugfs.h
12LIB_H += fs/fs.h
13# See comment below about piggybacking...
14LIB_H += fd/array.h
15
16LIB_OBJS += $(OUTPUT)fs/debugfs.o
17LIB_OBJS += $(OUTPUT)fs/fs.o
18# XXX piggybacking here, need to introduce libapikfd, or rename this
19# to plain libapik.a and make it have it all api goodies
20LIB_OBJS += $(OUTPUT)fd/array.o
21 15
22LIBFILE = libapikfs.a 16LIBFILE = $(OUTPUT)libapi.a
23 17
24CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC 18CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
25EXTLIBS = -lelf -lpthread -lrt -lm 19CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 -fPIC
26ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 20CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
27ALL_LDFLAGS = $(LDFLAGS)
28 21
29RM = rm -f 22RM = rm -f
30 23
31$(LIBFILE): $(LIB_OBJS) 24build := -f $(srctree)/tools/build/Makefile.build dir=. obj
32 $(QUIET_AR)$(RM) $@ && $(AR) rcs $(OUTPUT)$@ $(LIB_OBJS) 25API_IN := $(OUTPUT)libapi-in.o
33 26
34$(LIB_OBJS): $(LIB_H) 27export srctree OUTPUT CC LD CFLAGS V
35 28
36libapi_dirs: 29all: $(LIBFILE)
37 $(QUIET_MKDIR)mkdir -p $(OUTPUT)fd $(OUTPUT)fs
38 30
39$(OUTPUT)%.o: %.c libapi_dirs 31$(API_IN): FORCE
40 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< 32 @$(MAKE) $(build)=libapi
41$(OUTPUT)%.s: %.c libapi_dirs 33
42 $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< 34$(LIBFILE): $(API_IN)
43$(OUTPUT)%.o: %.S libapi_dirs 35 $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(API_IN)
44 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
45 36
46clean: 37clean:
47 $(call QUIET_CLEAN, libapi) $(RM) $(LIB_OBJS) $(LIBFILE) 38 $(call QUIET_CLEAN, libapi) $(RM) $(LIBFILE); \
39 find $(if $(OUTPUT),$(OUTPUT),.) -name \*.o | xargs $(RM)
40
41FORCE:
48 42
49.PHONY: clean 43.PHONY: clean FORCE
diff --git a/tools/lib/api/fd/Build b/tools/lib/api/fd/Build
new file mode 100644
index 000000000000..605d99f6d71a
--- /dev/null
+++ b/tools/lib/api/fd/Build
@@ -0,0 +1 @@
libapi-y += array.o
diff --git a/tools/lib/api/fs/Build b/tools/lib/api/fs/Build
new file mode 100644
index 000000000000..6de5a4f0b501
--- /dev/null
+++ b/tools/lib/api/fs/Build
@@ -0,0 +1,4 @@
1libapi-y += fs.o
2libapi-y += debugfs.o
3libapi-y += findfs.o
4libapi-y += tracefs.o
diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c
index d2b18e887071..8305b3e9d48e 100644
--- a/tools/lib/api/fs/debugfs.c
+++ b/tools/lib/api/fs/debugfs.c
@@ -3,75 +3,50 @@
3#include <stdio.h> 3#include <stdio.h>
4#include <stdlib.h> 4#include <stdlib.h>
5#include <string.h> 5#include <string.h>
6#include <unistd.h>
6#include <stdbool.h> 7#include <stdbool.h>
7#include <sys/vfs.h> 8#include <sys/vfs.h>
9#include <sys/types.h>
10#include <sys/stat.h>
8#include <sys/mount.h> 11#include <sys/mount.h>
9#include <linux/kernel.h> 12#include <linux/kernel.h>
10 13
11#include "debugfs.h" 14#include "debugfs.h"
12 15
13char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug"; 16#ifndef DEBUGFS_DEFAULT_PATH
17#define DEBUGFS_DEFAULT_PATH "/sys/kernel/debug"
18#endif
19
20char debugfs_mountpoint[PATH_MAX + 1] = DEBUGFS_DEFAULT_PATH;
14 21
15static const char * const debugfs_known_mountpoints[] = { 22static const char * const debugfs_known_mountpoints[] = {
16 "/sys/kernel/debug", 23 DEBUGFS_DEFAULT_PATH,
17 "/debug", 24 "/debug",
18 0, 25 0,
19}; 26};
20 27
21static bool debugfs_found; 28static bool debugfs_found;
22 29
30bool debugfs_configured(void)
31{
32 return debugfs_find_mountpoint() != NULL;
33}
34
23/* find the path to the mounted debugfs */ 35/* find the path to the mounted debugfs */
24const char *debugfs_find_mountpoint(void) 36const char *debugfs_find_mountpoint(void)
25{ 37{
26 const char * const *ptr; 38 const char *ret;
27 char type[100];
28 FILE *fp;
29 39
30 if (debugfs_found) 40 if (debugfs_found)
31 return (const char *)debugfs_mountpoint; 41 return (const char *)debugfs_mountpoint;
32 42
33 ptr = debugfs_known_mountpoints; 43 ret = find_mountpoint("debugfs", (long) DEBUGFS_MAGIC,
34 while (*ptr) { 44 debugfs_mountpoint, PATH_MAX + 1,
35 if (debugfs_valid_mountpoint(*ptr) == 0) { 45 debugfs_known_mountpoints);
36 debugfs_found = true; 46 if (ret)
37 strcpy(debugfs_mountpoint, *ptr); 47 debugfs_found = true;
38 return debugfs_mountpoint;
39 }
40 ptr++;
41 }
42
43 /* give up and parse /proc/mounts */
44 fp = fopen("/proc/mounts", "r");
45 if (fp == NULL)
46 return NULL;
47
48 while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
49 debugfs_mountpoint, type) == 2) {
50 if (strcmp(type, "debugfs") == 0)
51 break;
52 }
53 fclose(fp);
54 48
55 if (strcmp(type, "debugfs") != 0) 49 return ret;
56 return NULL;
57
58 debugfs_found = true;
59
60 return debugfs_mountpoint;
61}
62
63/* verify that a mountpoint is actually a debugfs instance */
64
65int debugfs_valid_mountpoint(const char *debugfs)
66{
67 struct statfs st_fs;
68
69 if (statfs(debugfs, &st_fs) < 0)
70 return -ENOENT;
71 else if ((long)st_fs.f_type != (long)DEBUGFS_MAGIC)
72 return -ENOENT;
73
74 return 0;
75} 50}
76 51
77/* mount the debugfs somewhere if it's not mounted */ 52/* mount the debugfs somewhere if it's not mounted */
@@ -87,7 +62,7 @@ char *debugfs_mount(const char *mountpoint)
87 mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT); 62 mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT);
88 /* if no environment variable, use default */ 63 /* if no environment variable, use default */
89 if (mountpoint == NULL) 64 if (mountpoint == NULL)
90 mountpoint = "/sys/kernel/debug"; 65 mountpoint = DEBUGFS_DEFAULT_PATH;
91 } 66 }
92 67
93 if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0) 68 if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0)
diff --git a/tools/lib/api/fs/debugfs.h b/tools/lib/api/fs/debugfs.h
index 0739881a9897..455023698d2b 100644
--- a/tools/lib/api/fs/debugfs.h
+++ b/tools/lib/api/fs/debugfs.h
@@ -1,16 +1,7 @@
1#ifndef __API_DEBUGFS_H__ 1#ifndef __API_DEBUGFS_H__
2#define __API_DEBUGFS_H__ 2#define __API_DEBUGFS_H__
3 3
4#define _STR(x) #x 4#include "findfs.h"
5#define STR(x) _STR(x)
6
7/*
8 * On most systems <limits.h> would have given us this, but not on some systems
9 * (e.g. GNU/Hurd).
10 */
11#ifndef PATH_MAX
12#define PATH_MAX 4096
13#endif
14 5
15#ifndef DEBUGFS_MAGIC 6#ifndef DEBUGFS_MAGIC
16#define DEBUGFS_MAGIC 0x64626720 7#define DEBUGFS_MAGIC 0x64626720
@@ -20,8 +11,8 @@
20#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" 11#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
21#endif 12#endif
22 13
14bool debugfs_configured(void);
23const char *debugfs_find_mountpoint(void); 15const char *debugfs_find_mountpoint(void);
24int debugfs_valid_mountpoint(const char *debugfs);
25char *debugfs_mount(const char *mountpoint); 16char *debugfs_mount(const char *mountpoint);
26 17
27extern char debugfs_mountpoint[]; 18extern char debugfs_mountpoint[];
diff --git a/tools/lib/api/fs/findfs.c b/tools/lib/api/fs/findfs.c
new file mode 100644
index 000000000000..49946cb6d7af
--- /dev/null
+++ b/tools/lib/api/fs/findfs.c
@@ -0,0 +1,63 @@
1#include <errno.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <stdbool.h>
6#include <sys/vfs.h>
7
8#include "findfs.h"
9
10/* verify that a mountpoint is actually the type we want */
11
12int valid_mountpoint(const char *mount, long magic)
13{
14 struct statfs st_fs;
15
16 if (statfs(mount, &st_fs) < 0)
17 return -ENOENT;
18 else if ((long)st_fs.f_type != magic)
19 return -ENOENT;
20
21 return 0;
22}
23
24/* find the path to a mounted file system */
25const char *find_mountpoint(const char *fstype, long magic,
26 char *mountpoint, int len,
27 const char * const *known_mountpoints)
28{
29 const char * const *ptr;
30 char format[128];
31 char type[100];
32 FILE *fp;
33
34 if (known_mountpoints) {
35 ptr = known_mountpoints;
36 while (*ptr) {
37 if (valid_mountpoint(*ptr, magic) == 0) {
38 strncpy(mountpoint, *ptr, len - 1);
39 mountpoint[len-1] = 0;
40 return mountpoint;
41 }
42 ptr++;
43 }
44 }
45
46 /* give up and parse /proc/mounts */
47 fp = fopen("/proc/mounts", "r");
48 if (fp == NULL)
49 return NULL;
50
51 snprintf(format, 128, "%%*s %%%ds %%99s %%*s %%*d %%*d\n", len);
52
53 while (fscanf(fp, format, mountpoint, type) == 2) {
54 if (strcmp(type, fstype) == 0)
55 break;
56 }
57 fclose(fp);
58
59 if (strcmp(type, fstype) != 0)
60 return NULL;
61
62 return mountpoint;
63}
diff --git a/tools/lib/api/fs/findfs.h b/tools/lib/api/fs/findfs.h
new file mode 100644
index 000000000000..b6f5d05acc42
--- /dev/null
+++ b/tools/lib/api/fs/findfs.h
@@ -0,0 +1,23 @@
1#ifndef __API_FINDFS_H__
2#define __API_FINDFS_H__
3
4#include <stdbool.h>
5
6#define _STR(x) #x
7#define STR(x) _STR(x)
8
9/*
10 * On most systems <limits.h> would have given us this, but not on some systems
11 * (e.g. GNU/Hurd).
12 */
13#ifndef PATH_MAX
14#define PATH_MAX 4096
15#endif
16
17const char *find_mountpoint(const char *fstype, long magic,
18 char *mountpoint, int len,
19 const char * const *known_mountpoints);
20
21int valid_mountpoint(const char *mount, long magic);
22
23#endif /* __API_FINDFS_H__ */
diff --git a/tools/lib/api/fs/tracefs.c b/tools/lib/api/fs/tracefs.c
new file mode 100644
index 000000000000..e4aa9688b71e
--- /dev/null
+++ b/tools/lib/api/fs/tracefs.c
@@ -0,0 +1,78 @@
1#include <errno.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <unistd.h>
6#include <stdbool.h>
7#include <sys/vfs.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <sys/mount.h>
11#include <linux/kernel.h>
12
13#include "tracefs.h"
14
15#ifndef TRACEFS_DEFAULT_PATH
16#define TRACEFS_DEFAULT_PATH "/sys/kernel/tracing"
17#endif
18
19char tracefs_mountpoint[PATH_MAX + 1] = TRACEFS_DEFAULT_PATH;
20
21static const char * const tracefs_known_mountpoints[] = {
22 TRACEFS_DEFAULT_PATH,
23 "/sys/kernel/debug/tracing",
24 "/tracing",
25 "/trace",
26 0,
27};
28
29static bool tracefs_found;
30
31bool tracefs_configured(void)
32{
33 return tracefs_find_mountpoint() != NULL;
34}
35
36/* find the path to the mounted tracefs */
37const char *tracefs_find_mountpoint(void)
38{
39 const char *ret;
40
41 if (tracefs_found)
42 return (const char *)tracefs_mountpoint;
43
44 ret = find_mountpoint("tracefs", (long) TRACEFS_MAGIC,
45 tracefs_mountpoint, PATH_MAX + 1,
46 tracefs_known_mountpoints);
47
48 if (ret)
49 tracefs_found = true;
50
51 return ret;
52}
53
54/* mount the tracefs somewhere if it's not mounted */
55char *tracefs_mount(const char *mountpoint)
56{
57 /* see if it's already mounted */
58 if (tracefs_find_mountpoint())
59 goto out;
60
61 /* if not mounted and no argument */
62 if (mountpoint == NULL) {
63 /* see if environment variable set */
64 mountpoint = getenv(PERF_TRACEFS_ENVIRONMENT);
65 /* if no environment variable, use default */
66 if (mountpoint == NULL)
67 mountpoint = TRACEFS_DEFAULT_PATH;
68 }
69
70 if (mount(NULL, mountpoint, "tracefs", 0, NULL) < 0)
71 return NULL;
72
73 /* save the mountpoint */
74 tracefs_found = true;
75 strncpy(tracefs_mountpoint, mountpoint, sizeof(tracefs_mountpoint));
76out:
77 return tracefs_mountpoint;
78}
diff --git a/tools/lib/api/fs/tracefs.h b/tools/lib/api/fs/tracefs.h
new file mode 100644
index 000000000000..da780ac49acb
--- /dev/null
+++ b/tools/lib/api/fs/tracefs.h
@@ -0,0 +1,21 @@
1#ifndef __API_TRACEFS_H__
2#define __API_TRACEFS_H__
3
4#include "findfs.h"
5
6#ifndef TRACEFS_MAGIC
7#define TRACEFS_MAGIC 0x74726163
8#endif
9
10#ifndef PERF_TRACEFS_ENVIRONMENT
11#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
12#endif
13
14bool tracefs_configured(void);
15const char *tracefs_find_mountpoint(void);
16int tracefs_valid_mountpoint(const char *debugfs);
17char *tracefs_mount(const char *mountpoint);
18
19extern char tracefs_mountpoint[];
20
21#endif /* __API_DEBUGFS_H__ */
diff --git a/tools/lib/lockdep/Build b/tools/lib/lockdep/Build
new file mode 100644
index 000000000000..6f667355b068
--- /dev/null
+++ b/tools/lib/lockdep/Build
@@ -0,0 +1 @@
liblockdep-y += common.o lockdep.o preload.o rbtree.o
diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
index 4b866c54f624..0c356fb65022 100644
--- a/tools/lib/lockdep/Makefile
+++ b/tools/lib/lockdep/Makefile
@@ -35,6 +35,10 @@ bindir = $(prefix)/$(bindir_relative)
35 35
36export DESTDIR DESTDIR_SQ INSTALL 36export DESTDIR DESTDIR_SQ INSTALL
37 37
38MAKEFLAGS += --no-print-directory
39
40include ../../scripts/Makefile.include
41
38# copy a bit from Linux kbuild 42# copy a bit from Linux kbuild
39 43
40ifeq ("$(origin V)", "command line") 44ifeq ("$(origin V)", "command line")
@@ -44,56 +48,21 @@ ifndef VERBOSE
44 VERBOSE = 0 48 VERBOSE = 0
45endif 49endif
46 50
47ifeq ("$(origin O)", "command line") 51ifeq ($(srctree),)
48 BUILD_OUTPUT := $(O) 52srctree := $(patsubst %/,%,$(dir $(shell pwd)))
53srctree := $(patsubst %/,%,$(dir $(srctree)))
54srctree := $(patsubst %/,%,$(dir $(srctree)))
55#$(info Determined 'srctree' to be $(srctree))
49endif 56endif
50 57
51ifeq ($(BUILD_SRC),)
52ifneq ($(BUILD_OUTPUT),)
53
54define build_output
55 $(if $(VERBOSE:1=),@)$(MAKE) -C $(BUILD_OUTPUT) \
56 BUILD_SRC=$(CURDIR) -f $(CURDIR)/Makefile $1
57endef
58
59saved-output := $(BUILD_OUTPUT)
60BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd)
61$(if $(BUILD_OUTPUT),, \
62 $(error output directory "$(saved-output)" does not exist))
63
64all: sub-make
65
66gui: force
67 $(call build_output, all_cmd)
68
69$(filter-out gui,$(MAKECMDGOALS)): sub-make
70
71sub-make: force
72 $(call build_output, $(MAKECMDGOALS))
73
74
75# Leave processing to above invocation of make
76skip-makefile := 1
77
78endif # BUILD_OUTPUT
79endif # BUILD_SRC
80
81# We process the rest of the Makefile if this is the final invocation of make
82ifeq ($(skip-makefile),)
83
84srctree := $(realpath $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR)))
85objtree := $(realpath $(CURDIR))
86src := $(srctree)
87obj := $(objtree)
88
89export prefix libdir bindir src obj
90
91# Shell quotes 58# Shell quotes
92libdir_SQ = $(subst ','\'',$(libdir)) 59libdir_SQ = $(subst ','\'',$(libdir))
93bindir_SQ = $(subst ','\'',$(bindir)) 60bindir_SQ = $(subst ','\'',$(bindir))
94 61
95LIB_FILE = liblockdep.a liblockdep.so.$(LIBLOCKDEP_VERSION) 62LIB_IN := $(OUTPUT)liblockdep-in.o
63
96BIN_FILE = lockdep 64BIN_FILE = lockdep
65LIB_FILE = $(OUTPUT)liblockdep.a $(OUTPUT)liblockdep.so.$(LIBLOCKDEP_VERSION)
97 66
98CONFIG_INCLUDES = 67CONFIG_INCLUDES =
99CONFIG_LIBS = 68CONFIG_LIBS =
@@ -108,33 +77,23 @@ INCLUDES = -I. -I./uinclude -I./include -I../../include $(CONFIG_INCLUDES)
108 77
109# Set compile option CFLAGS if not set elsewhere 78# Set compile option CFLAGS if not set elsewhere
110CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g 79CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g
80CFLAGS += -fPIC
111 81
112override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) 82override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
113 83
114ifeq ($(VERBOSE),1) 84ifeq ($(VERBOSE),1)
115 Q = 85 Q =
116 print_compile =
117 print_app_build =
118 print_fpic_compile =
119 print_shared_lib_compile = 86 print_shared_lib_compile =
120 print_install = 87 print_install =
121else 88else
122 Q = @ 89 Q = @
123 print_compile = echo ' CC '$(OBJ); 90 print_shared_lib_compile = echo ' LD '$(OBJ);
124 print_app_build = echo ' BUILD '$(OBJ); 91 print_static_lib_build = echo ' LD '$(OBJ);
125 print_fpic_compile = echo ' CC FPIC '$(OBJ); 92 print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2';
126 print_shared_lib_compile = echo ' BUILD SHARED LIB '$(OBJ);
127 print_static_lib_build = echo ' BUILD STATIC LIB '$(OBJ);
128 print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2';
129endif 93endif
130 94
131do_fpic_compile = \ 95export srctree OUTPUT CC LD CFLAGS V
132 ($(print_fpic_compile) \ 96build := -f $(srctree)/tools/build/Makefile.build dir=. obj
133 $(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@)
134
135do_app_build = \
136 ($(print_app_build) \
137 $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS))
138 97
139do_compile_shared_library = \ 98do_compile_shared_library = \
140 ($(print_shared_lib_compile) \ 99 ($(print_shared_lib_compile) \
@@ -144,22 +103,6 @@ do_build_static_lib = \
144 ($(print_static_lib_build) \ 103 ($(print_static_lib_build) \
145 $(RM) $@; $(AR) rcs $@ $^) 104 $(RM) $@; $(AR) rcs $@ $^)
146 105
147
148define do_compile
149 $(print_compile) \
150 $(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@;
151endef
152
153$(obj)/%.o: $(src)/%.c
154 $(Q)$(call do_compile)
155
156%.o: $(src)/%.c
157 $(Q)$(call do_compile)
158
159PEVENT_LIB_OBJS = common.o lockdep.o preload.o rbtree.o
160
161ALL_OBJS = $(PEVENT_LIB_OBJS)
162
163CMD_TARGETS = $(LIB_FILE) 106CMD_TARGETS = $(LIB_FILE)
164 107
165TARGETS = $(CMD_TARGETS) 108TARGETS = $(CMD_TARGETS)
@@ -169,42 +112,15 @@ all: all_cmd
169 112
170all_cmd: $(CMD_TARGETS) 113all_cmd: $(CMD_TARGETS)
171 114
172liblockdep.so.$(LIBLOCKDEP_VERSION): $(PEVENT_LIB_OBJS) 115$(LIB_IN): force
116 $(Q)$(MAKE) $(build)=liblockdep
117
118liblockdep.so.$(LIBLOCKDEP_VERSION): $(LIB_IN)
173 $(Q)$(do_compile_shared_library) 119 $(Q)$(do_compile_shared_library)
174 120
175liblockdep.a: $(PEVENT_LIB_OBJS) 121liblockdep.a: $(LIB_IN)
176 $(Q)$(do_build_static_lib) 122 $(Q)$(do_build_static_lib)
177 123
178$(PEVENT_LIB_OBJS): %.o: $(src)/%.c
179 $(Q)$(do_fpic_compile)
180
181## make deps
182
183all_objs := $(sort $(ALL_OBJS))
184all_deps := $(all_objs:%.o=.%.d)
185
186# let .d file also depends on the source and header files
187define check_deps
188 @set -e; $(RM) $@; \
189 $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
190 sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
191 $(RM) $@.$$$$
192endef
193
194$(all_deps): .%.d: $(src)/%.c
195 $(Q)$(call check_deps)
196
197$(all_objs) : %.o : .%.d
198
199dep_includes := $(wildcard $(all_deps))
200
201ifneq ($(dep_includes),)
202 include $(dep_includes)
203endif
204
205### Detect environment changes
206TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
207
208tags: force 124tags: force
209 $(RM) tags 125 $(RM) tags
210 find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ 126 find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
@@ -233,8 +149,6 @@ clean:
233 $(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d 149 $(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d
234 $(RM) tags TAGS 150 $(RM) tags TAGS
235 151
236endif # skip-makefile
237
238PHONY += force 152PHONY += force
239force: 153force:
240 154
diff --git a/tools/lib/traceevent/Build b/tools/lib/traceevent/Build
new file mode 100644
index 000000000000..c681d0575d16
--- /dev/null
+++ b/tools/lib/traceevent/Build
@@ -0,0 +1,17 @@
1libtraceevent-y += event-parse.o
2libtraceevent-y += event-plugin.o
3libtraceevent-y += trace-seq.o
4libtraceevent-y += parse-filter.o
5libtraceevent-y += parse-utils.o
6libtraceevent-y += kbuffer-parse.o
7
8plugin_jbd2-y += plugin_jbd2.o
9plugin_hrtimer-y += plugin_hrtimer.o
10plugin_kmem-y += plugin_kmem.o
11plugin_kvm-y += plugin_kvm.o
12plugin_mac80211-y += plugin_mac80211.o
13plugin_sched_switch-y += plugin_sched_switch.o
14plugin_function-y += plugin_function.o
15plugin_xen-y += plugin_xen.o
16plugin_scsi-y += plugin_scsi.o
17plugin_cfg80211-y += plugin_cfg80211.o
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 005c9cc06935..d410da335e3d 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -67,7 +67,7 @@ PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)"
67PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' 67PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))'
68endif 68endif
69 69
70include $(if $(BUILD_SRC),$(BUILD_SRC)/)../../scripts/Makefile.include 70include ../../scripts/Makefile.include
71 71
72# copy a bit from Linux kbuild 72# copy a bit from Linux kbuild
73 73
@@ -78,40 +78,13 @@ ifndef VERBOSE
78 VERBOSE = 0 78 VERBOSE = 0
79endif 79endif
80 80
81ifeq ("$(origin O)", "command line") 81ifeq ($(srctree),)
82 BUILD_OUTPUT := $(O) 82srctree := $(patsubst %/,%,$(dir $(shell pwd)))
83srctree := $(patsubst %/,%,$(dir $(srctree)))
84srctree := $(patsubst %/,%,$(dir $(srctree)))
85#$(info Determined 'srctree' to be $(srctree))
83endif 86endif
84 87
85ifeq ($(BUILD_SRC),)
86ifneq ($(OUTPUT),)
87
88define build_output
89 $(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \
90 BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1
91endef
92
93all: sub-make
94
95$(MAKECMDGOALS): sub-make
96
97sub-make: force
98 $(call build_output, $(MAKECMDGOALS))
99
100
101# Leave processing to above invocation of make
102skip-makefile := 1
103
104endif # OUTPUT
105endif # BUILD_SRC
106
107# We process the rest of the Makefile if this is the final invocation of make
108ifeq ($(skip-makefile),)
109
110srctree := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR))
111objtree := $(CURDIR)
112src := $(srctree)
113obj := $(objtree)
114
115export prefix bindir src obj 88export prefix bindir src obj
116 89
117# Shell quotes 90# Shell quotes
@@ -132,16 +105,19 @@ EXTRAVERSION = $(EP_EXTRAVERSION)
132OBJ = $@ 105OBJ = $@
133N = 106N =
134 107
135export Q VERBOSE
136
137EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) 108EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION)
138 109
139INCLUDES = -I. -I $(srctree)/../../include $(CONFIG_INCLUDES) 110INCLUDES = -I. -I $(srctree)/tools/include $(CONFIG_INCLUDES)
140 111
141# Set compile option CFLAGS if not set elsewhere 112# Set compile option CFLAGS
142CFLAGS ?= -g -Wall 113ifdef EXTRA_CFLAGS
114 CFLAGS := $(EXTRA_CFLAGS)
115else
116 CFLAGS := -g -Wall
117endif
143 118
144# Append required CFLAGS 119# Append required CFLAGS
120override CFLAGS += -fPIC
145override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) 121override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
146override CFLAGS += $(udis86-flags) -D_GNU_SOURCE 122override CFLAGS += $(udis86-flags) -D_GNU_SOURCE
147 123
@@ -151,74 +127,58 @@ else
151 Q = @ 127 Q = @
152endif 128endif
153 129
154do_compile_shared_library = \ 130# Disable command line variables (CFLAGS) overide from top
155 ($(print_shared_lib_compile) \ 131# level Makefile (perf), otherwise build Makefile will get
156 $(CC) --shared $^ -o $@) 132# the same command line setup.
157 133MAKEOVERRIDES=
158do_plugin_build = \
159 ($(print_plugin_build) \
160 $(CC) $(CFLAGS) -shared -nostartfiles -o $@ $<)
161
162do_build_static_lib = \
163 ($(print_static_lib_build) \
164 $(RM) $@; $(AR) rcs $@ $^)
165
166
167do_compile = $(QUIET_CC)$(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@;
168 134
169$(obj)/%.o: $(src)/%.c 135export srctree OUTPUT CC LD CFLAGS V
170 $(call do_compile) 136build := -f $(srctree)/tools/build/Makefile.build dir=. obj
171 137
172%.o: $(src)/%.c 138PLUGINS = plugin_jbd2.so
173 $(call do_compile) 139PLUGINS += plugin_hrtimer.so
140PLUGINS += plugin_kmem.so
141PLUGINS += plugin_kvm.so
142PLUGINS += plugin_mac80211.so
143PLUGINS += plugin_sched_switch.so
144PLUGINS += plugin_function.so
145PLUGINS += plugin_xen.so
146PLUGINS += plugin_scsi.so
147PLUGINS += plugin_cfg80211.so
174 148
175PEVENT_LIB_OBJS = event-parse.o 149PLUGINS := $(addprefix $(OUTPUT),$(PLUGINS))
176PEVENT_LIB_OBJS += event-plugin.o 150PLUGINS_IN := $(PLUGINS:.so=-in.o)
177PEVENT_LIB_OBJS += trace-seq.o
178PEVENT_LIB_OBJS += parse-filter.o
179PEVENT_LIB_OBJS += parse-utils.o
180PEVENT_LIB_OBJS += kbuffer-parse.o
181 151
182PLUGIN_OBJS = plugin_jbd2.o 152TE_IN := $(OUTPUT)libtraceevent-in.o
183PLUGIN_OBJS += plugin_hrtimer.o 153LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
184PLUGIN_OBJS += plugin_kmem.o
185PLUGIN_OBJS += plugin_kvm.o
186PLUGIN_OBJS += plugin_mac80211.o
187PLUGIN_OBJS += plugin_sched_switch.o
188PLUGIN_OBJS += plugin_function.o
189PLUGIN_OBJS += plugin_xen.o
190PLUGIN_OBJS += plugin_scsi.o
191PLUGIN_OBJS += plugin_cfg80211.o
192
193PLUGINS := $(PLUGIN_OBJS:.o=.so)
194
195ALL_OBJS = $(PEVENT_LIB_OBJS) $(PLUGIN_OBJS)
196 154
197CMD_TARGETS = $(LIB_FILE) $(PLUGINS) 155CMD_TARGETS = $(LIB_FILE) $(PLUGINS)
198 156
199TARGETS = $(CMD_TARGETS) 157TARGETS = $(CMD_TARGETS)
200 158
201
202all: all_cmd 159all: all_cmd
203 160
204all_cmd: $(CMD_TARGETS) 161all_cmd: $(CMD_TARGETS)
205 162
206libtraceevent.so: $(PEVENT_LIB_OBJS) 163$(TE_IN): force
164 $(Q)$(MAKE) $(build)=libtraceevent
165
166$(OUTPUT)libtraceevent.so: $(TE_IN)
207 $(QUIET_LINK)$(CC) --shared $^ -o $@ 167 $(QUIET_LINK)$(CC) --shared $^ -o $@
208 168
209libtraceevent.a: $(PEVENT_LIB_OBJS) 169$(OUTPUT)libtraceevent.a: $(TE_IN)
210 $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ 170 $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
211 171
212plugins: $(PLUGINS) 172plugins: $(PLUGINS)
213 173
214$(PEVENT_LIB_OBJS): %.o: $(src)/%.c TRACEEVENT-CFLAGS 174__plugin_obj = $(notdir $@)
215 $(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@ 175 plugin_obj = $(__plugin_obj:-in.o=)
216 176
217$(PLUGIN_OBJS): %.o : $(src)/%.c 177$(PLUGINS_IN): force
218 $(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) -fPIC -o $@ $< 178 $(Q)$(MAKE) $(build)=$(plugin_obj)
219 179
220$(PLUGINS): %.so: %.o 180$(OUTPUT)%.so: $(OUTPUT)%-in.o
221 $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $< 181 $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $^
222 182
223define make_version.h 183define make_version.h
224 (echo '/* This file is automatically generated. Do not modify. */'; \ 184 (echo '/* This file is automatically generated. Do not modify. */'; \
@@ -255,40 +215,6 @@ define update_dir
255 fi); 215 fi);
256endef 216endef
257 217
258## make deps
259
260all_objs := $(sort $(ALL_OBJS))
261all_deps := $(all_objs:%.o=.%.d)
262
263# let .d file also depends on the source and header files
264define check_deps
265 @set -e; $(RM) $@; \
266 $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
267 sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
268 $(RM) $@.$$$$
269endef
270
271$(all_deps): .%.d: $(src)/%.c
272 $(Q)$(call check_deps)
273
274$(all_objs) : %.o : .%.d
275
276dep_includes := $(wildcard $(all_deps))
277
278ifneq ($(dep_includes),)
279 include $(dep_includes)
280endif
281
282### Detect environment changes
283TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
284
285TRACEEVENT-CFLAGS: force
286 @FLAGS='$(TRACK_CFLAGS)'; \
287 if test x"$$FLAGS" != x"`cat TRACEEVENT-CFLAGS 2>/dev/null`" ; then \
288 echo 1>&2 " FLAGS: * new build flags or cross compiler"; \
289 echo "$$FLAGS" >TRACEEVENT-CFLAGS; \
290 fi
291
292tags: force 218tags: force
293 $(RM) tags 219 $(RM) tags
294 find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ 220 find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
@@ -327,14 +253,9 @@ clean:
327 $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \ 253 $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \
328 $(RM) TRACEEVENT-CFLAGS tags TAGS 254 $(RM) TRACEEVENT-CFLAGS tags TAGS
329 255
330endif # skip-makefile
331
332PHONY += force plugins 256PHONY += force plugins
333force: 257force:
334 258
335plugins:
336 @echo > /dev/null
337
338# Declare the contents of the .PHONY variable as phony. We keep that 259# Declare the contents of the .PHONY variable as phony. We keep that
339# information in a variable so we can use it in if_changed and friends. 260# information in a variable so we can use it in if_changed and friends.
340.PHONY: $(PHONY) 261.PHONY: $(PHONY)
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index afe20ed9fac8..6d31b6419d37 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -304,7 +304,10 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
304 if (!item) 304 if (!item)
305 return -1; 305 return -1;
306 306
307 item->comm = strdup(comm); 307 if (comm)
308 item->comm = strdup(comm);
309 else
310 item->comm = strdup("<...>");
308 if (!item->comm) { 311 if (!item->comm) {
309 free(item); 312 free(item);
310 return -1; 313 return -1;
@@ -318,9 +321,14 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
318 return 0; 321 return 0;
319} 322}
320 323
321void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock) 324int pevent_register_trace_clock(struct pevent *pevent, const char *trace_clock)
322{ 325{
323 pevent->trace_clock = trace_clock; 326 pevent->trace_clock = strdup(trace_clock);
327 if (!pevent->trace_clock) {
328 errno = ENOMEM;
329 return -1;
330 }
331 return 0;
324} 332}
325 333
326struct func_map { 334struct func_map {
@@ -758,6 +766,11 @@ static void free_arg(struct print_arg *arg)
758 free_arg(arg->hex.field); 766 free_arg(arg->hex.field);
759 free_arg(arg->hex.size); 767 free_arg(arg->hex.size);
760 break; 768 break;
769 case PRINT_INT_ARRAY:
770 free_arg(arg->int_array.field);
771 free_arg(arg->int_array.count);
772 free_arg(arg->int_array.el_size);
773 break;
761 case PRINT_TYPE: 774 case PRINT_TYPE:
762 free(arg->typecast.type); 775 free(arg->typecast.type);
763 free_arg(arg->typecast.item); 776 free_arg(arg->typecast.item);
@@ -2014,6 +2027,38 @@ process_entry(struct event_format *event __maybe_unused, struct print_arg *arg,
2014 return EVENT_ERROR; 2027 return EVENT_ERROR;
2015} 2028}
2016 2029
2030static int alloc_and_process_delim(struct event_format *event, char *next_token,
2031 struct print_arg **print_arg)
2032{
2033 struct print_arg *field;
2034 enum event_type type;
2035 char *token;
2036 int ret = 0;
2037
2038 field = alloc_arg();
2039 if (!field) {
2040 do_warning_event(event, "%s: not enough memory!", __func__);
2041 errno = ENOMEM;
2042 return -1;
2043 }
2044
2045 type = process_arg(event, field, &token);
2046
2047 if (test_type_token(type, token, EVENT_DELIM, next_token)) {
2048 errno = EINVAL;
2049 ret = -1;
2050 free_arg(field);
2051 goto out_free_token;
2052 }
2053
2054 *print_arg = field;
2055
2056out_free_token:
2057 free_token(token);
2058
2059 return ret;
2060}
2061
2017static char *arg_eval (struct print_arg *arg); 2062static char *arg_eval (struct print_arg *arg);
2018 2063
2019static unsigned long long 2064static unsigned long long
@@ -2486,49 +2531,46 @@ out_free:
2486static enum event_type 2531static enum event_type
2487process_hex(struct event_format *event, struct print_arg *arg, char **tok) 2532process_hex(struct event_format *event, struct print_arg *arg, char **tok)
2488{ 2533{
2489 struct print_arg *field;
2490 enum event_type type;
2491 char *token = NULL;
2492
2493 memset(arg, 0, sizeof(*arg)); 2534 memset(arg, 0, sizeof(*arg));
2494 arg->type = PRINT_HEX; 2535 arg->type = PRINT_HEX;
2495 2536
2496 field = alloc_arg(); 2537 if (alloc_and_process_delim(event, ",", &arg->hex.field))
2497 if (!field) { 2538 goto out;
2498 do_warning_event(event, "%s: not enough memory!", __func__);
2499 goto out_free;
2500 }
2501
2502 type = process_arg(event, field, &token);
2503 2539
2504 if (test_type_token(type, token, EVENT_DELIM, ",")) 2540 if (alloc_and_process_delim(event, ")", &arg->hex.size))
2505 goto out_free; 2541 goto free_field;
2506 2542
2507 arg->hex.field = field; 2543 return read_token_item(tok);
2508 2544
2509 free_token(token); 2545free_field:
2546 free_arg(arg->hex.field);
2547out:
2548 *tok = NULL;
2549 return EVENT_ERROR;
2550}
2510 2551
2511 field = alloc_arg(); 2552static enum event_type
2512 if (!field) { 2553process_int_array(struct event_format *event, struct print_arg *arg, char **tok)
2513 do_warning_event(event, "%s: not enough memory!", __func__); 2554{
2514 *tok = NULL; 2555 memset(arg, 0, sizeof(*arg));
2515 return EVENT_ERROR; 2556 arg->type = PRINT_INT_ARRAY;
2516 }
2517 2557
2518 type = process_arg(event, field, &token); 2558 if (alloc_and_process_delim(event, ",", &arg->int_array.field))
2559 goto out;
2519 2560
2520 if (test_type_token(type, token, EVENT_DELIM, ")")) 2561 if (alloc_and_process_delim(event, ",", &arg->int_array.count))
2521 goto out_free; 2562 goto free_field;
2522 2563
2523 arg->hex.size = field; 2564 if (alloc_and_process_delim(event, ")", &arg->int_array.el_size))
2565 goto free_size;
2524 2566
2525 free_token(token); 2567 return read_token_item(tok);
2526 type = read_token_item(tok);
2527 return type;
2528 2568
2529 out_free: 2569free_size:
2530 free_arg(field); 2570 free_arg(arg->int_array.count);
2531 free_token(token); 2571free_field:
2572 free_arg(arg->int_array.field);
2573out:
2532 *tok = NULL; 2574 *tok = NULL;
2533 return EVENT_ERROR; 2575 return EVENT_ERROR;
2534} 2576}
@@ -2828,6 +2870,10 @@ process_function(struct event_format *event, struct print_arg *arg,
2828 free_token(token); 2870 free_token(token);
2829 return process_hex(event, arg, tok); 2871 return process_hex(event, arg, tok);
2830 } 2872 }
2873 if (strcmp(token, "__print_array") == 0) {
2874 free_token(token);
2875 return process_int_array(event, arg, tok);
2876 }
2831 if (strcmp(token, "__get_str") == 0) { 2877 if (strcmp(token, "__get_str") == 0) {
2832 free_token(token); 2878 free_token(token);
2833 return process_str(event, arg, tok); 2879 return process_str(event, arg, tok);
@@ -3356,6 +3402,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
3356 break; 3402 break;
3357 case PRINT_FLAGS: 3403 case PRINT_FLAGS:
3358 case PRINT_SYMBOL: 3404 case PRINT_SYMBOL:
3405 case PRINT_INT_ARRAY:
3359 case PRINT_HEX: 3406 case PRINT_HEX:
3360 break; 3407 break;
3361 case PRINT_TYPE: 3408 case PRINT_TYPE:
@@ -3568,7 +3615,7 @@ static const struct flag flags[] = {
3568 { "HRTIMER_RESTART", 1 }, 3615 { "HRTIMER_RESTART", 1 },
3569}; 3616};
3570 3617
3571static unsigned long long eval_flag(const char *flag) 3618static long long eval_flag(const char *flag)
3572{ 3619{
3573 int i; 3620 int i;
3574 3621
@@ -3584,7 +3631,7 @@ static unsigned long long eval_flag(const char *flag)
3584 if (strcmp(flags[i].name, flag) == 0) 3631 if (strcmp(flags[i].name, flag) == 0)
3585 return flags[i].value; 3632 return flags[i].value;
3586 3633
3587 return 0; 3634 return -1LL;
3588} 3635}
3589 3636
3590static void print_str_to_seq(struct trace_seq *s, const char *format, 3637static void print_str_to_seq(struct trace_seq *s, const char *format,
@@ -3658,7 +3705,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3658 struct print_flag_sym *flag; 3705 struct print_flag_sym *flag;
3659 struct format_field *field; 3706 struct format_field *field;
3660 struct printk_map *printk; 3707 struct printk_map *printk;
3661 unsigned long long val, fval; 3708 long long val, fval;
3662 unsigned long addr; 3709 unsigned long addr;
3663 char *str; 3710 char *str;
3664 unsigned char *hex; 3711 unsigned char *hex;
@@ -3717,11 +3764,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3717 print = 0; 3764 print = 0;
3718 for (flag = arg->flags.flags; flag; flag = flag->next) { 3765 for (flag = arg->flags.flags; flag; flag = flag->next) {
3719 fval = eval_flag(flag->value); 3766 fval = eval_flag(flag->value);
3720 if (!val && !fval) { 3767 if (!val && fval < 0) {
3721 print_str_to_seq(s, format, len_arg, flag->str); 3768 print_str_to_seq(s, format, len_arg, flag->str);
3722 break; 3769 break;
3723 } 3770 }
3724 if (fval && (val & fval) == fval) { 3771 if (fval > 0 && (val & fval) == fval) {
3725 if (print && arg->flags.delim) 3772 if (print && arg->flags.delim)
3726 trace_seq_puts(s, arg->flags.delim); 3773 trace_seq_puts(s, arg->flags.delim);
3727 print_str_to_seq(s, format, len_arg, flag->str); 3774 print_str_to_seq(s, format, len_arg, flag->str);
@@ -3766,6 +3813,54 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3766 } 3813 }
3767 break; 3814 break;
3768 3815
3816 case PRINT_INT_ARRAY: {
3817 void *num;
3818 int el_size;
3819
3820 if (arg->int_array.field->type == PRINT_DYNAMIC_ARRAY) {
3821 unsigned long offset;
3822 struct format_field *field =
3823 arg->int_array.field->dynarray.field;
3824 offset = pevent_read_number(pevent,
3825 data + field->offset,
3826 field->size);
3827 num = data + (offset & 0xffff);
3828 } else {
3829 field = arg->int_array.field->field.field;
3830 if (!field) {
3831 str = arg->int_array.field->field.name;
3832 field = pevent_find_any_field(event, str);
3833 if (!field)
3834 goto out_warning_field;
3835 arg->int_array.field->field.field = field;
3836 }
3837 num = data + field->offset;
3838 }
3839 len = eval_num_arg(data, size, event, arg->int_array.count);
3840 el_size = eval_num_arg(data, size, event,
3841 arg->int_array.el_size);
3842 for (i = 0; i < len; i++) {
3843 if (i)
3844 trace_seq_putc(s, ' ');
3845
3846 if (el_size == 1) {
3847 trace_seq_printf(s, "%u", *(uint8_t *)num);
3848 } else if (el_size == 2) {
3849 trace_seq_printf(s, "%u", *(uint16_t *)num);
3850 } else if (el_size == 4) {
3851 trace_seq_printf(s, "%u", *(uint32_t *)num);
3852 } else if (el_size == 8) {
3853 trace_seq_printf(s, "%lu", *(uint64_t *)num);
3854 } else {
3855 trace_seq_printf(s, "BAD SIZE:%d 0x%x",
3856 el_size, *(uint8_t *)num);
3857 el_size = 1;
3858 }
3859
3860 num += el_size;
3861 }
3862 break;
3863 }
3769 case PRINT_TYPE: 3864 case PRINT_TYPE:
3770 break; 3865 break;
3771 case PRINT_STRING: { 3866 case PRINT_STRING: {
@@ -3997,6 +4092,10 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3997 goto process_again; 4092 goto process_again;
3998 case '.': 4093 case '.':
3999 goto process_again; 4094 goto process_again;
4095 case 'z':
4096 case 'Z':
4097 ls = 1;
4098 goto process_again;
4000 case 'p': 4099 case 'p':
4001 ls = 1; 4100 ls = 1;
4002 /* fall through */ 4101 /* fall through */
@@ -4939,6 +5038,96 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
4939 return comm; 5038 return comm;
4940} 5039}
4941 5040
5041static struct cmdline *
5042pid_from_cmdlist(struct pevent *pevent, const char *comm, struct cmdline *next)
5043{
5044 struct cmdline_list *cmdlist = (struct cmdline_list *)next;
5045
5046 if (cmdlist)
5047 cmdlist = cmdlist->next;
5048 else
5049 cmdlist = pevent->cmdlist;
5050
5051 while (cmdlist && strcmp(cmdlist->comm, comm) != 0)
5052 cmdlist = cmdlist->next;
5053
5054 return (struct cmdline *)cmdlist;
5055}
5056
5057/**
5058 * pevent_data_pid_from_comm - return the pid from a given comm
5059 * @pevent: a handle to the pevent
5060 * @comm: the cmdline to find the pid from
5061 * @next: the cmdline structure to find the next comm
5062 *
5063 * This returns the cmdline structure that holds a pid for a given
5064 * comm, or NULL if none found. As there may be more than one pid for
5065 * a given comm, the result of this call can be passed back into
5066 * a recurring call in the @next paramater, and then it will find the
5067 * next pid.
5068 * Also, it does a linear seach, so it may be slow.
5069 */
5070struct cmdline *pevent_data_pid_from_comm(struct pevent *pevent, const char *comm,
5071 struct cmdline *next)
5072{
5073 struct cmdline *cmdline;
5074
5075 /*
5076 * If the cmdlines have not been converted yet, then use
5077 * the list.
5078 */
5079 if (!pevent->cmdlines)
5080 return pid_from_cmdlist(pevent, comm, next);
5081
5082 if (next) {
5083 /*
5084 * The next pointer could have been still from
5085 * a previous call before cmdlines were created
5086 */
5087 if (next < pevent->cmdlines ||
5088 next >= pevent->cmdlines + pevent->cmdline_count)
5089 next = NULL;
5090 else
5091 cmdline = next++;
5092 }
5093
5094 if (!next)
5095 cmdline = pevent->cmdlines;
5096
5097 while (cmdline < pevent->cmdlines + pevent->cmdline_count) {
5098 if (strcmp(cmdline->comm, comm) == 0)
5099 return cmdline;
5100 cmdline++;
5101 }
5102 return NULL;
5103}
5104
5105/**
5106 * pevent_cmdline_pid - return the pid associated to a given cmdline
5107 * @cmdline: The cmdline structure to get the pid from
5108 *
5109 * Returns the pid for a give cmdline. If @cmdline is NULL, then
5110 * -1 is returned.
5111 */
5112int pevent_cmdline_pid(struct pevent *pevent, struct cmdline *cmdline)
5113{
5114 struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline;
5115
5116 if (!cmdline)
5117 return -1;
5118
5119 /*
5120 * If cmdlines have not been created yet, or cmdline is
5121 * not part of the array, then treat it as a cmdlist instead.
5122 */
5123 if (!pevent->cmdlines ||
5124 cmdline < pevent->cmdlines ||
5125 cmdline >= pevent->cmdlines + pevent->cmdline_count)
5126 return cmdlist->pid;
5127
5128 return cmdline->pid;
5129}
5130
4942/** 5131/**
4943 * pevent_data_comm_from_pid - parse the data into the print format 5132 * pevent_data_comm_from_pid - parse the data into the print format
4944 * @s: the trace_seq to write to 5133 * @s: the trace_seq to write to
@@ -5256,6 +5445,15 @@ static void print_args(struct print_arg *args)
5256 print_args(args->hex.size); 5445 print_args(args->hex.size);
5257 printf(")"); 5446 printf(")");
5258 break; 5447 break;
5448 case PRINT_INT_ARRAY:
5449 printf("__print_array(");
5450 print_args(args->int_array.field);
5451 printf(", ");
5452 print_args(args->int_array.count);
5453 printf(", ");
5454 print_args(args->int_array.el_size);
5455 printf(")");
5456 break;
5259 case PRINT_STRING: 5457 case PRINT_STRING:
5260 case PRINT_BSTRING: 5458 case PRINT_BSTRING:
5261 printf("__get_str(%s)", args->string.string); 5459 printf("__get_str(%s)", args->string.string);
@@ -6228,15 +6426,20 @@ void pevent_ref(struct pevent *pevent)
6228 pevent->ref_count++; 6426 pevent->ref_count++;
6229} 6427}
6230 6428
6429void pevent_free_format_field(struct format_field *field)
6430{
6431 free(field->type);
6432 free(field->name);
6433 free(field);
6434}
6435
6231static void free_format_fields(struct format_field *field) 6436static void free_format_fields(struct format_field *field)
6232{ 6437{
6233 struct format_field *next; 6438 struct format_field *next;
6234 6439
6235 while (field) { 6440 while (field) {
6236 next = field->next; 6441 next = field->next;
6237 free(field->type); 6442 pevent_free_format_field(field);
6238 free(field->name);
6239 free(field);
6240 field = next; 6443 field = next;
6241 } 6444 }
6242} 6445}
@@ -6341,6 +6544,7 @@ void pevent_free(struct pevent *pevent)
6341 free_handler(handle); 6544 free_handler(handle);
6342 } 6545 }
6343 6546
6547 free(pevent->trace_clock);
6344 free(pevent->events); 6548 free(pevent->events);
6345 free(pevent->sort_events); 6549 free(pevent->sort_events);
6346 6550
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 7a3873ff9a4f..86a5839fb048 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -22,6 +22,7 @@
22 22
23#include <stdbool.h> 23#include <stdbool.h>
24#include <stdarg.h> 24#include <stdarg.h>
25#include <stdio.h>
25#include <regex.h> 26#include <regex.h>
26#include <string.h> 27#include <string.h>
27 28
@@ -91,6 +92,7 @@ extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
91 92
92extern void trace_seq_terminate(struct trace_seq *s); 93extern void trace_seq_terminate(struct trace_seq *s);
93 94
95extern int trace_seq_do_fprintf(struct trace_seq *s, FILE *fp);
94extern int trace_seq_do_printf(struct trace_seq *s); 96extern int trace_seq_do_printf(struct trace_seq *s);
95 97
96 98
@@ -114,7 +116,7 @@ struct pevent_plugin_option {
114 char *name; 116 char *name;
115 char *plugin_alias; 117 char *plugin_alias;
116 char *description; 118 char *description;
117 char *value; 119 const char *value;
118 void *priv; 120 void *priv;
119 int set; 121 int set;
120}; 122};
@@ -152,6 +154,10 @@ struct pevent_plugin_option {
152 * .plugin_alias is used to give a shorter name to access 154 * .plugin_alias is used to give a shorter name to access
153 * the vairable. Useful if a plugin handles more than one event. 155 * the vairable. Useful if a plugin handles more than one event.
154 * 156 *
157 * If .value is not set, then it is considered a boolean and only
158 * .set will be processed. If .value is defined, then it is considered
159 * a string option and .set will be ignored.
160 *
155 * PEVENT_PLUGIN_ALIAS: (optional) 161 * PEVENT_PLUGIN_ALIAS: (optional)
156 * The name to use for finding options (uses filename if not defined) 162 * The name to use for finding options (uses filename if not defined)
157 */ 163 */
@@ -245,6 +251,12 @@ struct print_arg_hex {
245 struct print_arg *size; 251 struct print_arg *size;
246}; 252};
247 253
254struct print_arg_int_array {
255 struct print_arg *field;
256 struct print_arg *count;
257 struct print_arg *el_size;
258};
259
248struct print_arg_dynarray { 260struct print_arg_dynarray {
249 struct format_field *field; 261 struct format_field *field;
250 struct print_arg *index; 262 struct print_arg *index;
@@ -273,6 +285,7 @@ enum print_arg_type {
273 PRINT_FLAGS, 285 PRINT_FLAGS,
274 PRINT_SYMBOL, 286 PRINT_SYMBOL,
275 PRINT_HEX, 287 PRINT_HEX,
288 PRINT_INT_ARRAY,
276 PRINT_TYPE, 289 PRINT_TYPE,
277 PRINT_STRING, 290 PRINT_STRING,
278 PRINT_BSTRING, 291 PRINT_BSTRING,
@@ -292,6 +305,7 @@ struct print_arg {
292 struct print_arg_flags flags; 305 struct print_arg_flags flags;
293 struct print_arg_symbol symbol; 306 struct print_arg_symbol symbol;
294 struct print_arg_hex hex; 307 struct print_arg_hex hex;
308 struct print_arg_int_array int_array;
295 struct print_arg_func func; 309 struct print_arg_func func;
296 struct print_arg_string string; 310 struct print_arg_string string;
297 struct print_arg_bitmask bitmask; 311 struct print_arg_bitmask bitmask;
@@ -597,7 +611,7 @@ enum trace_flag_type {
597}; 611};
598 612
599int pevent_register_comm(struct pevent *pevent, const char *comm, int pid); 613int pevent_register_comm(struct pevent *pevent, const char *comm, int pid);
600void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock); 614int pevent_register_trace_clock(struct pevent *pevent, const char *trace_clock);
601int pevent_register_function(struct pevent *pevent, char *name, 615int pevent_register_function(struct pevent *pevent, char *name,
602 unsigned long long addr, char *mod); 616 unsigned long long addr, char *mod);
603int pevent_register_print_string(struct pevent *pevent, const char *fmt, 617int pevent_register_print_string(struct pevent *pevent, const char *fmt,
@@ -617,6 +631,7 @@ enum pevent_errno pevent_parse_format(struct pevent *pevent,
617 const char *buf, 631 const char *buf,
618 unsigned long size, const char *sys); 632 unsigned long size, const char *sys);
619void pevent_free_format(struct event_format *event); 633void pevent_free_format(struct event_format *event);
634void pevent_free_format_field(struct format_field *field);
620 635
621void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event, 636void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
622 const char *name, struct pevent_record *record, 637 const char *name, struct pevent_record *record,
@@ -675,6 +690,11 @@ int pevent_data_type(struct pevent *pevent, struct pevent_record *rec);
675struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type); 690struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type);
676int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec); 691int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec);
677const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid); 692const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid);
693struct cmdline;
694struct cmdline *pevent_data_pid_from_comm(struct pevent *pevent, const char *comm,
695 struct cmdline *next);
696int pevent_cmdline_pid(struct pevent *pevent, struct cmdline *cmdline);
697
678void pevent_event_info(struct trace_seq *s, struct event_format *event, 698void pevent_event_info(struct trace_seq *s, struct event_format *event,
679 struct pevent_record *record); 699 struct pevent_record *record);
680int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, 700int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c
index 136162c03af1..a16756ae3526 100644
--- a/tools/lib/traceevent/event-plugin.c
+++ b/tools/lib/traceevent/event-plugin.c
@@ -18,6 +18,7 @@
18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19 */ 19 */
20 20
21#include <ctype.h>
21#include <stdio.h> 22#include <stdio.h>
22#include <string.h> 23#include <string.h>
23#include <dlfcn.h> 24#include <dlfcn.h>
@@ -49,6 +50,52 @@ struct plugin_list {
49 void *handle; 50 void *handle;
50}; 51};
51 52
53static void lower_case(char *str)
54{
55 if (!str)
56 return;
57 for (; *str; str++)
58 *str = tolower(*str);
59}
60
61static int update_option_value(struct pevent_plugin_option *op, const char *val)
62{
63 char *op_val;
64
65 if (!val) {
66 /* toggle, only if option is boolean */
67 if (op->value)
68 /* Warn? */
69 return 0;
70 op->set ^= 1;
71 return 0;
72 }
73
74 /*
75 * If the option has a value then it takes a string
76 * otherwise the option is a boolean.
77 */
78 if (op->value) {
79 op->value = val;
80 return 0;
81 }
82
83 /* Option is boolean, must be either "1", "0", "true" or "false" */
84
85 op_val = strdup(val);
86 if (!op_val)
87 return -1;
88 lower_case(op_val);
89
90 if (strcmp(val, "1") == 0 || strcmp(val, "true") == 0)
91 op->set = 1;
92 else if (strcmp(val, "0") == 0 || strcmp(val, "false") == 0)
93 op->set = 0;
94 free(op_val);
95
96 return 0;
97}
98
52/** 99/**
53 * traceevent_plugin_list_options - get list of plugin options 100 * traceevent_plugin_list_options - get list of plugin options
54 * 101 *
@@ -120,6 +167,7 @@ update_option(const char *file, struct pevent_plugin_option *option)
120{ 167{
121 struct trace_plugin_options *op; 168 struct trace_plugin_options *op;
122 char *plugin; 169 char *plugin;
170 int ret = 0;
123 171
124 if (option->plugin_alias) { 172 if (option->plugin_alias) {
125 plugin = strdup(option->plugin_alias); 173 plugin = strdup(option->plugin_alias);
@@ -144,9 +192,10 @@ update_option(const char *file, struct pevent_plugin_option *option)
144 if (strcmp(op->option, option->name) != 0) 192 if (strcmp(op->option, option->name) != 0)
145 continue; 193 continue;
146 194
147 option->value = op->value; 195 ret = update_option_value(option, op->value);
148 option->set ^= 1; 196 if (ret)
149 goto out; 197 goto out;
198 break;
150 } 199 }
151 200
152 /* first look for unnamed options */ 201 /* first look for unnamed options */
@@ -156,14 +205,13 @@ update_option(const char *file, struct pevent_plugin_option *option)
156 if (strcmp(op->option, option->name) != 0) 205 if (strcmp(op->option, option->name) != 0)
157 continue; 206 continue;
158 207
159 option->value = op->value; 208 ret = update_option_value(option, op->value);
160 option->set ^= 1;
161 break; 209 break;
162 } 210 }
163 211
164 out: 212 out:
165 free(plugin); 213 free(plugin);
166 return 0; 214 return ret;
167} 215}
168 216
169/** 217/**
diff --git a/tools/lib/traceevent/kbuffer-parse.c b/tools/lib/traceevent/kbuffer-parse.c
index dcc665228c71..3bcada3ae05a 100644
--- a/tools/lib/traceevent/kbuffer-parse.c
+++ b/tools/lib/traceevent/kbuffer-parse.c
@@ -372,7 +372,6 @@ translate_data(struct kbuffer *kbuf, void *data, void **rptr,
372 switch (type_len) { 372 switch (type_len) {
373 case KBUFFER_TYPE_PADDING: 373 case KBUFFER_TYPE_PADDING:
374 *length = read_4(kbuf, data); 374 *length = read_4(kbuf, data);
375 data += *length;
376 break; 375 break;
377 376
378 case KBUFFER_TYPE_TIME_EXTEND: 377 case KBUFFER_TYPE_TIME_EXTEND:
@@ -730,3 +729,14 @@ void kbuffer_set_old_format(struct kbuffer *kbuf)
730 729
731 kbuf->next_event = __old_next_event; 730 kbuf->next_event = __old_next_event;
732} 731}
732
733/**
734 * kbuffer_start_of_data - return offset of where data starts on subbuffer
735 * @kbuf: The kbuffer
736 *
737 * Returns the location on the subbuffer where the data starts.
738 */
739int kbuffer_start_of_data(struct kbuffer *kbuf)
740{
741 return kbuf->start;
742}
diff --git a/tools/lib/traceevent/kbuffer.h b/tools/lib/traceevent/kbuffer.h
index c831f64b17a0..03dce757553f 100644
--- a/tools/lib/traceevent/kbuffer.h
+++ b/tools/lib/traceevent/kbuffer.h
@@ -63,5 +63,6 @@ int kbuffer_missed_events(struct kbuffer *kbuf);
63int kbuffer_subbuffer_size(struct kbuffer *kbuf); 63int kbuffer_subbuffer_size(struct kbuffer *kbuf);
64 64
65void kbuffer_set_old_format(struct kbuffer *kbuf); 65void kbuffer_set_old_format(struct kbuffer *kbuf);
66int kbuffer_start_of_data(struct kbuffer *kbuf);
66 67
67#endif /* _K_BUFFER_H */ 68#endif /* _K_BUFFER_H */
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index b50234402fc2..0144b3d1bb77 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -1058,6 +1058,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
1058 *parg = current_op; 1058 *parg = current_op;
1059 else 1059 else
1060 *parg = current_exp; 1060 *parg = current_exp;
1061 free(token);
1061 return PEVENT_ERRNO__UNBALANCED_PAREN; 1062 return PEVENT_ERRNO__UNBALANCED_PAREN;
1062 } 1063 }
1063 break; 1064 break;
@@ -1168,6 +1169,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
1168 1169
1169 *parg = current_op; 1170 *parg = current_op;
1170 1171
1172 free(token);
1171 return 0; 1173 return 0;
1172 1174
1173 fail_alloc: 1175 fail_alloc:
diff --git a/tools/lib/traceevent/trace-seq.c b/tools/lib/traceevent/trace-seq.c
index ec3bd16a5488..292dc9f1d233 100644
--- a/tools/lib/traceevent/trace-seq.c
+++ b/tools/lib/traceevent/trace-seq.c
@@ -231,19 +231,24 @@ void trace_seq_terminate(struct trace_seq *s)
231 s->buffer[s->len] = 0; 231 s->buffer[s->len] = 0;
232} 232}
233 233
234int trace_seq_do_printf(struct trace_seq *s) 234int trace_seq_do_fprintf(struct trace_seq *s, FILE *fp)
235{ 235{
236 TRACE_SEQ_CHECK(s); 236 TRACE_SEQ_CHECK(s);
237 237
238 switch (s->state) { 238 switch (s->state) {
239 case TRACE_SEQ__GOOD: 239 case TRACE_SEQ__GOOD:
240 return printf("%.*s", s->len, s->buffer); 240 return fprintf(fp, "%.*s", s->len, s->buffer);
241 case TRACE_SEQ__BUFFER_POISONED: 241 case TRACE_SEQ__BUFFER_POISONED:
242 puts("Usage of trace_seq after it was destroyed"); 242 fprintf(fp, "%s\n", "Usage of trace_seq after it was destroyed");
243 break; 243 break;
244 case TRACE_SEQ__MEM_ALLOC_FAILED: 244 case TRACE_SEQ__MEM_ALLOC_FAILED:
245 puts("Can't allocate trace_seq buffer memory"); 245 fprintf(fp, "%s\n", "Can't allocate trace_seq buffer memory");
246 break; 246 break;
247 } 247 }
248 return -1; 248 return -1;
249} 249}
250
251int trace_seq_do_printf(struct trace_seq *s)
252{
253 return trace_seq_do_fprintf(s, stdout);
254}