* [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests
@ 2021-12-16 21:39 Steven Rostedt
2021-12-16 21:39 ` [PATCH 01/10] libtraceevent: Fix installing of man pages in remote directory Steven Rostedt
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt
The libtraceevent Makefiles are a result of its several foster homes.
It started at trace-cmd and then went into the kernel, and now lives in
its own repository. The Makefiles were brought over from the previous
homes and modified and tweaked to get them to work. This added a bunch
of unnecessary logic that is not needed for just this library.
The Makefiles were rewritten to be more consistent with libtracefs and
with trace-cmd, which greatly simplified them.
A unit test was added to start testing event parsing and reading to lay
the ground work for more unit tests that will help keep libtraceevent
from having more regressions (like one that slipped in).
The processing of the old dynamic string format (which had just he
offset where the length of the string was simply determined by the size
of the string at the offset) stopped working. It actually worked by
shear luck, but changes to add the rel_loc parsing took away all that
luck. It had to be refactored to be more specific in knowing that the
format is of the old size.
Deprecate tep_print_field() as it does not give the user to pass the in
the size of the data to parse, and since it could be from untrusted
sources, that would make it a security issue.
Add tep_print_field_content() that requires a size also passed in.
Use the size more to verify that only the data gets looked at and does
not rely on the data to stay within bounds.
*** NOTE *** there needs to be an audit of all the code to add checks to
make sure all access are within the data. Even though the size is now
passed in, there are many cases where what is parsed is going to be
within those limits.
Steven Rostedt (VMware) (10):
libtraceevent: Fix installing of man pages in remote directory
libtraceevent: Rewrite Makefiles to be like libtracefs
libtraceevent: Have make tags and TAGS honor O= build directory
libtraceevent: Move installed headers into their own directory
libtraceevent: Add unit test framework for library commands
libtraceveent: Add testing of old dynamic string event layout
libraceevent: Add unit test to test print_fmt with dynamic strings
libtraceevent: Account for old dynamic string formats and honor size
libtraceevent: Replace tep_print_field() with
tep_print_field_content()
libtraceevent: Have print_field_raw() handle old data layout
Documentation/Makefile | 16 +-
Documentation/libtraceevent-field_print.txt | 10 +-
Documentation/libtraceevent.txt | 2 +-
Makefile | 215 +++++++++++---------
build/Build.include | 103 ----------
build/Makefile.build | 162 ---------------
{src => include/traceevent}/event-parse.h | 8 +-
{src => include/traceevent}/event-utils.h | 0
{src => include/traceevent}/kbuffer.h | 0
{src => include/traceevent}/trace-seq.h | 0
plugins/Makefile | 63 ++----
scripts/Makefile.include | 135 ------------
scripts/features.mk | 37 ++++
scripts/utils.mk | 174 ++++++++++++++++
src/Makefile | 51 ++++-
src/event-parse.c | 96 ++++++---
utest/Makefile | 38 ++++
utest/README | 17 ++
utest/trace-utest.c | 86 ++++++++
utest/trace-utest.h | 14 ++
utest/traceevent-utest.c | 172 ++++++++++++++++
21 files changed, 807 insertions(+), 592 deletions(-)
delete mode 100644 build/Build.include
delete mode 100644 build/Makefile.build
rename {src => include/traceevent}/event-parse.h (99%)
rename {src => include/traceevent}/event-utils.h (100%)
rename {src => include/traceevent}/kbuffer.h (100%)
rename {src => include/traceevent}/trace-seq.h (100%)
delete mode 100644 scripts/Makefile.include
create mode 100644 scripts/features.mk
create mode 100644 scripts/utils.mk
create mode 100644 utest/Makefile
create mode 100644 utest/README
create mode 100644 utest/trace-utest.c
create mode 100644 utest/trace-utest.h
create mode 100644 utest/traceevent-utest.c
--
2.33.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 01/10] libtraceevent: Fix installing of man pages in remote directory
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
2021-12-16 21:39 ` [PATCH 02/10] libtraceevent: Rewrite Makefiles to be like libtracefs Steven Rostedt
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
When the building of the man pages is done in a directory other than the
repo directory (with the O= option), the intermediate build file name
incorrectly appends a "install-" prefix to the path and not to the file,
causing the installation to fail.
Fix it by using patsubst instead of addprefix to append the "install-"
name to the intermediate files for the installation.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
Documentation/Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 73dbe2ae4d43..af124572c863 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -154,12 +154,12 @@ ifdef missing_tools
$(error "You need to install $(missing_tools) for man pages")
endif
-install-%.3: $(OUTPUT)%.3
+$(OUTPUT)install-%.3: $(OUTPUT)%.3
$(call QUIET_INSTALL, $<) \
$(INSTALL) -d -m 755 $(DESTDIR)$(man3dir); \
$(INSTALL) -m 644 $< $(DESTDIR)$(man3dir);
-do-install-man: man $(addprefix install-,$(wildcard $(OUTPUT)*.3))
+do-install-man: man $(patsubst $(OUTPUT)%,$(OUTPUT)install-%,$(wildcard $(OUTPUT)*.3))
install-man: check-man-tools man
$(Q)$(MAKE) -C . do-install-man
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 02/10] libtraceevent: Rewrite Makefiles to be like libtracefs
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
2021-12-16 21:39 ` [PATCH 01/10] libtraceevent: Fix installing of man pages in remote directory Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
2021-12-16 21:39 ` [PATCH 03/10] libtraceevent: Have make tags and TAGS honor O= build directory Steven Rostedt
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
The libtraceevent code has moved around various homes. It originated in
the trace-cmd.git repository and then moved to the Linux kernel under
tools/libs. Finally it made its home in its own libtraceevent git repo.
During its time at different foster homes, it took with it various ways to
build it from the other homes and this was incorporated into the
Makefiles. But the kernel Makefiles were rather complex as it had to build
not only libtraceevent but other tooling.
Unfortunately, that complexity made it's way into libtraceevent, making it
difficult to add new functionality. Instead, rewrite it to be more like
libtracefs that has a much simpler Makefile structure.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
Documentation/Makefile | 12 ++-
Makefile | 185 ++++++++++++++++++++-------------------
build/Build.include | 103 ----------------------
build/Makefile.build | 162 ----------------------------------
plugins/Makefile | 61 +++----------
scripts/Makefile.include | 135 ----------------------------
scripts/features.mk | 37 ++++++++
scripts/utils.mk | 174 ++++++++++++++++++++++++++++++++++++
src/Makefile | 51 ++++++++++-
9 files changed, 371 insertions(+), 549 deletions(-)
delete mode 100644 build/Build.include
delete mode 100644 build/Makefile.build
delete mode 100644 scripts/Makefile.include
create mode 100644 scripts/features.mk
create mode 100644 scripts/utils.mk
diff --git a/Documentation/Makefile b/Documentation/Makefile
index af124572c863..5904b798b786 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,5 +1,5 @@
-include ../scripts/Makefile.include
include ../scripts/utilities.mak
+include ../scripts/utils.mk
# This Makefile and manpage XSL files were taken from tools/perf/Documentation
# and modified for libtraceevent.
@@ -13,6 +13,8 @@ _MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
_MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT))
_DOC_MAN3=$(patsubst %.txt,%.m,$(MAN3_TXT))
+OUTPUT := $(obj)/Documentation/
+
MAN_XML=$(addprefix $(OUTPUT),$(_MAN_XML))
MAN_HTML=$(addprefix $(OUTPUT),$(_MAN_HTML))
DOC_MAN3=$(addprefix $(OUTPUT),$(_DOC_MAN3))
@@ -155,9 +157,7 @@ ifdef missing_tools
endif
$(OUTPUT)install-%.3: $(OUTPUT)%.3
- $(call QUIET_INSTALL, $<) \
- $(INSTALL) -d -m 755 $(DESTDIR)$(man3dir); \
- $(INSTALL) -m 644 $< $(DESTDIR)$(man3dir);
+ $(Q)$(call do_install,$<,$(man3dir),644)
do-install-man: man $(patsubst $(OUTPUT)%,$(OUTPUT)install-%,$(wildcard $(OUTPUT)*.3))
@@ -165,9 +165,7 @@ install-man: check-man-tools man
$(Q)$(MAKE) -C . do-install-man
install-%.txt: $(OUTPUT)%.html
- $(call QUIET_INSTALL, $<) \
- $(INSTALL) -d -m 755 $(DESTDIR)$(htmldir); \
- $(INSTALL) -m 644 $< $(DESTDIR)$(htmldir);
+ $(Q)$(call do_install,$<,$(htmldir),644)
do-install-html: html $(addprefix install-,$(wildcard *.txt))
diff --git a/Makefile b/Makefile
index 194bbdd2666f..4363e9b73dc3 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@
EP_VERSION = 1
EP_PATCHLEVEL = 4
EP_EXTRAVERSION = 0
+EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION)
MAKEFLAGS += --no-print-directory
@@ -56,12 +57,7 @@ includedir_SQ = '$(subst ','\'',$(includedir))'
export man_dir man_dir_SQ INSTALL
export DESTDIR DESTDIR_SQ
-export EVENT_PARSE_VERSION
-
-include scripts/Makefile.include
-
-PKG_CONFIG_SOURCE_FILE = libtraceevent.pc
-PKG_CONFIG_FILE := $(addprefix $(OUTPUT),$(PKG_CONFIG_SOURCE_FILE))
+export EP_VERSION EVENT_PARSE_VERSION
# copy a bit from Linux kbuild
@@ -72,12 +68,36 @@ ifndef VERBOSE
VERBOSE = 0
endif
-ifeq ($(srctree),)
-srctree := $(CURDIR)
-#$(info Determined 'srctree' to be $(srctree))
+SILENT := $(if $(findstring s,$(filter-out --%,$(MAKEFLAGS))),1)
+
+ifeq ("$(origin O)", "command line")
+
+ saved-output := $(O)
+ BUILD_OUTPUT := $(shell cd $(O) && /bin/pwd)
+ $(if $(BUILD_OUTPUT),, \
+ $(error output directory "$(saved-output)" does not exist))
+
+else
+ BUILD_OUTPUT = $(CURDIR)
endif
-export prefix libdir
+srctree := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR))
+objtree := $(BUILD_OUTPUT)
+src := $(srctree)
+obj := $(objtree)
+bdir := $(obj)/lib
+
+export prefix src obj bdir
+
+PKG_CONFIG_SOURCE_FILE = libtraceevent.pc
+PKG_CONFIG_FILE := $(addprefix $(obj)/,$(PKG_CONFIG_SOURCE_FILE))
+
+export Q SILENT VERBOSE EXT
+
+# Include the utils
+include scripts/utils.mk
+
+include $(src)/scripts/features.mk
# Shell quotes
libdir_SQ = $(subst ','\'',$(libdir))
@@ -94,21 +114,13 @@ EXTRAVERSION = $(EP_EXTRAVERSION)
OBJ = $@
N =
-EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION)
-
-bdir = lib
-
-export bdir
-
LIBTRACEEVENT_STATIC = $(bdir)/libtraceevent.a
LIBTRACEEVENT_SHARED = $(bdir)/libtraceevent.so.$(EVENT_PARSE_VERSION)
-LIB_TARGET = $(LIBTRACEEVENT_STATIC) $(bdir)/libtraceevent.so $(bdir)/libtraceevent.so.$(EP_VERSION) $(LIBTRACEEVENT_SHARED)
-LIB_INSTALL = $(LIBTRACEEVENT_STATIC) $(bdir)/libtraceevent.so*
-LIB_INSTALL := $(addprefix $(OUTPUT),$(LIB_INSTALL))
-
INCLUDES = -I. -I $(srctree)/include $(CONFIG_INCLUDES)
+export LIBTRACEEVENT_STATIC LIBTRACEEVENT_SHARED
+
# Set compile option CFLAGS
ifdef EXTRA_CFLAGS
CFLAGS := $(EXTRA_CFLAGS)
@@ -120,7 +132,7 @@ LIBS = -ldl
set_plugin_dir := 1
-# Set plugin_dir to preffered global plugin location
+# Set plugin_dir to prefered global plugin location
# If we install under $HOME directory we go under
# $(HOME)/.local/lib/traceevent/plugins
#
@@ -160,11 +172,10 @@ endif
# the same command line setup.
MAKEOVERRIDES=
-export srctree OUTPUT CC LD CFLAGS V
+export srctree CC LD CFLAGS V
build := -f $(srctree)/build/Makefile.build dir=. obj
-TE_IN := $(OUTPUT)src/libtraceevent-in.o
-LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET))
+LIB_TARGET := libtraceevent.so libtraceevent.a
CMD_TARGETS = $(LIB_TARGET) $(PKG_CONFIG_FILE)
@@ -172,27 +183,33 @@ TARGETS = $(CMD_TARGETS)
all: all_cmd plugins
-all_cmd: $(CMD_TARGETS)
+$(bdir):
+ $(Q)mkdir -p $(bdir)
-$(TE_IN): force
- $(Q)$(call descend,src,libtraceevent)
+LIB_TARGET = libtraceevent.a libtraceevent.so
+LIB_INSTALL = libtraceevent.a libtraceevent.so*
+LIB_INSTALL := $(addprefix $(bdir)/,$(LIB_INSTALL))
-$(OUTPUT)$(LIBTRACEEVENT_SHARED): $(TE_IN)
- $(Q)mkdir -p $(OUTPUT)$(bdir)
- $(QUIET_LINK)$(CC) --shared $(LDFLAGS) $^ -Wl,-soname,libtraceevent.so.$(EP_VERSION) -o $@ $(LIBS)
+LIBTRACEEVENT_SHARED_SO = $(bdir)/libtraceevent.so
+LIBTRACEEVENT_SHARED_VERSION = $(bdir)/libtraceevent.so.$(EP_VERSION)
-$(OUTPUT)$(bdir)/libtraceevent.so: $(OUTPUT)$(bdir)/libtraceevent.so.$(EP_VERSION)
- @ln -sf $(<F) $@
+export LIBTRACEEVENT_SHARED_SO LIBTRACEEVENT_SHARED_VERSION
-$(OUTPUT)$(bdir)/libtraceevent.so.$(EP_VERSION): $(OUTPUT)$(LIBTRACEEVENT_SHARED)
- @ln -sf $(<F) $@
+all_cmd: $(CMD_TARGETS)
+
+libtraceevent.a: $(bdir) $(LIBTRACEEVENT_STATIC)
+libtraceevent.so: $(bdir) $(LIBTRACEEVENT_SHARED)
-$(OUTPUT)$(LIBTRACEEVENT_STATIC): $(TE_IN)
- $(Q)mkdir -p $(OUTPUT)$(bdir)
- $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
+libs: libtraceevent.a libtraceevent.so
-$(OUTPUT)$(bdir)/%.so: $(OUTPUT)%-in.o
- $(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^ $(LIBS)
+$(LIBTRACEEVENT_STATIC): force
+ $(Q)$(call descend,$(src)/src,$@)
+
+$(LIBTRACEEVENT_SHARED): force
+ $(Q)$(call descend,$(src)/src,libtraceevent.so)
+
+$(bdir)/libtraceevent.so: $(bdir)/libtraceevent.so.$(EP_VERSION)
+ @ln -sf $(<F) $@
define make_version.h
(echo '/* This file is automatically generated. Do not modify. */'; \
@@ -214,10 +231,10 @@ define update_version.h
fi);
endef
-ep_version.h: force
- $(Q)$(N)$(call update_version.h)
+VERSION_FILE = $(obj)/ep_version.h
-VERSION_FILES = ep_version.h
+$(VERSION_FILE): force
+ $(Q)$(N)$(call update_version.h)
define update_dir
(echo $1 > $@.tmp; \
@@ -249,22 +266,11 @@ define build_prefix
fi);
endef
-BUILD_PREFIX := $(OUTPUT)build_prefix
+BUILD_PREFIX := $(obj)/build_prefix
$(BUILD_PREFIX): force
$(Q)$(call build_prefix,$(prefix))
-define do_install_mkdir
- if [ ! -d '$(DESTDIR_SQ)$1' ]; then \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \
- fi
-endef
-
-define do_install
- $(call do_install_mkdir,$2); \
- $(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2'
-endef
-
define do_make_pkgconfig_file
cp -f ${PKG_CONFIG_SOURCE_FILE}.template ${PKG_CONFIG_FILE}; \
sed -i "s|INSTALL_PREFIX|${1}|g" ${PKG_CONFIG_FILE}; \
@@ -273,8 +279,8 @@ define do_make_pkgconfig_file
sed -i "s|HEADER_DIR|$(includedir_relative)|g" ${PKG_CONFIG_FILE};
endef
-$(PKG_CONFIG_FILE) : ${PKG_CONFIG_SOURCE_FILE}.template $(BUILD_PREFIX) $(VERSION_FILES)
- $(QUIET_GEN) $(call do_make_pkgconfig_file,$(prefix))
+$(PKG_CONFIG_FILE) : ${PKG_CONFIG_SOURCE_FILE}.template $(BUILD_PREFIX) $(VERSION_FILE)
+ $(Q)$(print_gen)$(call do_make_pkgconfig_file,$(prefix))
define do_install_pkgconfig_file
if [ -n "${pkgconfig_dir}" ]; then \
@@ -292,14 +298,14 @@ ifeq ("$(DESTDIR)", "")
define install_ld_config
if $(LDCONFIG); then \
if ! grep -q "^$(libdir)$$" $(LD_SO_CONF_PATH)/* ; then \
- $(CC) -o $(OUTPUT)test $(srctree)/test.c -I $(includedir_SQ) \
- -L $(libdir_SQ) -ltraceevent &>/dev/null; \
- if ! $(OUTPUT)test &> /dev/null; then \
- $(call PRINT_INSTALL, trace.conf) \
+ $(CC) -o $(objtree)/test $(srctree)/test.c -I $(includedir_SQ) \
+ -L $(libdir_SQ) -ltraceevent &> /dev/null; \
+ if ! $(objtree)/test &> /dev/null; then \
+ $(call print_install, trace.conf, $(LD_SO_CONF_PATH)) \
echo $(libdir_SQ) >> $(LD_SO_CONF_PATH)/trace.conf; \
$(LDCONFIG); \
fi; \
- $(RM) $(OUTPUT)test; \
+ $(RM) $(objtree)/test; \
fi; \
fi
endef
@@ -310,34 +316,30 @@ define install_ld_config
endef
endif # DESTDIR = ""
-install_lib: all_cmd install_plugins install_headers install_pkgconfig
- $(call QUIET_INSTALL, $(LIB_TARGET)) \
- $(call do_install_mkdir,$(libdir_SQ)); \
- cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ); \
- $(call install_ld_config)
+install: install_libs install_plugins
+
+install_libs: libs install_headers install_pkgconfig
+ $(Q)$(call do_install,$(LIBTRACEEVENT_SHARED),$(libdir_SQ)); \
+ cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ)
+ $(Q)$(call install_ld_config)
install_pkgconfig: $(PKG_CONFIG_FILE)
- $(call QUIET_INSTALL, $(PKG_CONFIG_FILE)) \
- $(call do_install_pkgconfig_file,$(prefix))
+ $(Q)$(call do_install_pkgconfig_file,$(prefix))
install_headers:
- $(call QUIET_INSTALL, headers) \
- $(call do_install,src/event-parse.h,$(includedir_SQ),644); \
- $(call do_install,src/event-utils.h,$(includedir_SQ),644); \
- $(call do_install,src/trace-seq.h,$(includedir_SQ),644); \
- $(call do_install,src/kbuffer.h,$(includedir_SQ),644)
+ $(Q)$(call do_install,src/event-parse.h,$(includedir_SQ),644);
+ $(Q)$(call do_install,src/event-utils.h,$(includedir_SQ),644);
+ $(Q)$(call do_install,src/trace-seq.h,$(includedir_SQ),644);
+ $(Q)$(call do_install,src/kbuffer.h,$(includedir_SQ),644)
-install: install_lib
+install: install_libs
clean: clean_plugins clean_src
- $(call QUIET_CLEAN, libtraceevent) \
- $(RM) $(OUTPUT)*.o $(OUTPUT)*~ $(TARGETS) $(OUTPUT)*.a $(OUTPUT)*.so $(VERSION_FILES) $(OUTPUT).*.d $(OUTPUT).*.cmd; \
- $(RM) TRACEEVENT-CFLAGS $(OUTPUT)tags $(OUTPUT)TAGS; \
- $(RM) $(PKG_CONFIG_FILE)
-ifneq ($(OUTPUT),)
-else
-BUILD_OUTPUT := $(shell pwd)
-endif
+ $(Q)$(call do_clean,\
+ $(VERSION_FILE) $(obj)/tags $(obj)/TAGS $(PKG_CONFIG_FILE) \
+ $(LIBTRACEEVENT_STATIC) $(LIBTRACEEVENT_SHARED) \
+ $(LIBTRACEEVENT_SHARED_SO) $(LIBTRACEEVENT_SHARED_VERSION) \
+ $(BUILD_PREFIX))
define build_uninstall_script
$(Q)mkdir $(BUILD_OUTPUT)/tmp_build
@@ -362,19 +364,20 @@ uninstall: $(BUILD_OUTPUT)/build_uninstall
PHONY += doc
doc:
- $(call descend,Documentation)
+ $(Q)$(call descend,$(src)/Documentation,)
PHONY += doc-clean
doc-clean:
- $(call descend,Documentation,clean)
+ $(MAKE) -C $(src)/Documentation clean
PHONY += doc-install
doc-install:
- $(call descend,Documentation,install)
+ $(Q)$(call descend,$(src)/Documentation,install)
+
PHONY += doc-uninstall
doc-uninstall:
- $(call descend,Documentation,uninstall)
+ $(MAKE) -C $(src)/Documentation uninstall
PHONY += help
help:
@@ -395,19 +398,19 @@ help:
PHONY += plugins
plugins:
- $(call descend,plugins)
+ $(Q)$(call descend,plugins,)
PHONY += install_plugins
-install_plugins:
- $(call descend,plugins,install)
+install_plugins: plugins
+ $(Q)$(call descend,plugins,install)
PHONY += clean_plugins
clean_plugins:
- $(call descend,plugins,clean)
+ $(Q)$(call descend_clean,plugins)
PHONY += clean_src
clean_src:
- $(call descend,src,clean)
+ $(Q)$(call descend_clean,src)
force:
diff --git a/build/Build.include b/build/Build.include
deleted file mode 100644
index b4c1786cbe4a..000000000000
--- a/build/Build.include
+++ /dev/null
@@ -1,103 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-###
-# build: Generic definitions
-#
-# Lots of this code have been borrowed or heavily inspired from parts
-# of kbuild code, which is not credited, but mostly developed by:
-#
-# Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015
-# Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015
-#
-
-###
-# Convenient variables
-comma := ,
-squote := '
-pound := \#
-
-###
-# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
-dot-target = $(dir $@).$(notdir $@)
-
-###
-# filename of target with directory and extension stripped
-basetarget = $(basename $(notdir $@))
-
-###
-# The temporary file to save gcc -MD generated dependencies must not
-# contain a comma
-depfile = $(subst $(comma),_,$(dot-target).d)
-
-###
-# Check if both arguments has same arguments. Result is empty string if equal.
-arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
- $(filter-out $(cmd_$@), $(cmd_$(1))) )
-
-###
-# Escape single quote for use in echo statements
-escsq = $(subst $(squote),'\$(squote)',$1)
-
-# Echo command
-# Short version is used, if $(quiet) equals `quiet_', otherwise full one.
-echo-cmd = $(if $($(quiet)cmd_$(1)),\
- echo ' $(call escsq,$($(quiet)cmd_$(1)))';)
-
-###
-# Replace >$< with >$$< to preserve $ when reloading the .cmd file
-# (needed for make)
-# Replace >#< with >$(pound)< to avoid starting a comment in the .cmd file
-# (needed for make)
-# Replace >'< with >'\''< to be able to enclose the whole string in '...'
-# (needed for the shell)
-make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1)))))
-
-###
-# Find any prerequisites that is newer than target or that does not exist.
-# PHONY targets skipped in both cases.
-any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
-
-###
-# Copy dependency data into .cmd file
-# - gcc -M dependency info
-# - command line to create object 'cmd_object :='
-dep-cmd = $(if $(wildcard $(fixdep)), \
- $(fixdep) $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp; \
- rm -f $(depfile); \
- mv -f $(dot-target).tmp $(dot-target).cmd, \
- printf '$(pound) cannot find fixdep (%s)\n' $(fixdep) > $(dot-target).cmd; \
- printf '$(pound) using basic dep data\n\n' >> $(dot-target).cmd; \
- cat $(depfile) >> $(dot-target).cmd; \
- printf '\n%s\n' 'cmd_$@ := $(make-cmd)' >> $(dot-target).cmd)
-
-###
-# if_changed_dep - execute command if any prerequisite is newer than
-# target, or command line has changed and update
-# dependencies in the cmd file
-if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)), \
- @set -e; \
- $(echo-cmd) $(cmd_$(1)); \
- $(dep-cmd))
-
-# if_changed - execute command if any prerequisite is newer than
-# target, or command line has changed
-if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
- @set -e; \
- $(echo-cmd) $(cmd_$(1)); \
- printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
-
-###
-# C flags to be used in rule definitions, includes:
-# - depfile generation
-# - global $(CFLAGS)
-# - per target C flags
-# - per object C flags
-# - BUILD_STR macro to allow '-D"$(variable)"' constructs
-c_flags_1 = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CFLAGS) -D"BUILD_STR(s)=\#s" $(CFLAGS_$(basetarget).o) $(CFLAGS_$(obj))
-c_flags_2 = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(c_flags_1))
-c_flags = $(filter-out $(CFLAGS_REMOVE_$(obj)), $(c_flags_2))
-cxx_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CXXFLAGS) -D"BUILD_STR(s)=\#s" $(CXXFLAGS_$(basetarget).o) $(CXXFLAGS_$(obj))
-
-###
-## HOSTCC C flags
-
-host_c_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(KBUILD_HOSTCFLAGS) -D"BUILD_STR(s)=\#s" $(HOSTCFLAGS_$(basetarget).o) $(HOSTCFLAGS_$(obj))
diff --git a/build/Makefile.build b/build/Makefile.build
deleted file mode 100644
index c267572f5bf0..000000000000
--- a/build/Makefile.build
+++ /dev/null
@@ -1,162 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-###
-# Main build makefile.
-#
-# Lots of this code have been borrowed or heavily inspired from parts
-# of kbuild code, which is not credited, but mostly developed by:
-#
-# Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015
-# Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015
-#
-
-PHONY := __build
-__build:
-
-ifeq ($(V),1)
- quiet =
- Q =
-else
- quiet=quiet_
- Q=@
-endif
-
-ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
- quiet=silent_
-endif
-
-build-dir := $(srctree)/build
-
-# Define $(fixdep) for dep-cmd function
-ifeq ($(OUTPUT),)
- fixdep := $(build-dir)/fixdep
-else
- fixdep := $(OUTPUT)/fixdep
-endif
-
-# Generic definitions
-include $(build-dir)/Build.include
-
-# do not force detected configuration
--include $(OUTPUT).config-detected
-
-# Init all relevant variables used in build files so
-# 1) they have correct type
-# 2) they do not inherit any value from the environment
-subdir-y :=
-obj-y :=
-subdir-y :=
-subdir-obj-y :=
-
-# Build definitions
-build-file := $(dir)/Build
--include $(build-file)
-
-quiet_cmd_flex = FLEX $@
-quiet_cmd_bison = BISON $@
-
-# Create directory unless it exists
-quiet_cmd_mkdir = MKDIR $(dir $@)
- cmd_mkdir = mkdir -p $(dir $@)
- rule_mkdir = $(if $(wildcard $(dir $@)),,@$(call echo-cmd,mkdir) $(cmd_mkdir))
-
-# Compile command
-quiet_cmd_cc_o_c = CC $@
- cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
-
-quiet_cmd_host_cc_o_c = HOSTCC $@
- cmd_host_cc_o_c = $(HOSTCC) $(host_c_flags) -c -o $@ $<
-
-quiet_cmd_cxx_o_c = CXX $@
- cmd_cxx_o_c = $(CXX) $(cxx_flags) -c -o $@ $<
-
-quiet_cmd_cpp_i_c = CPP $@
- cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $<
-
-quiet_cmd_cc_s_c = AS $@
- cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
-
-quiet_cmd_gen = GEN $@
-
-# Link agregate command
-# If there's nothing to link, create empty $@ object.
-quiet_cmd_ld_multi = LD $@
- cmd_ld_multi = $(if $(strip $(obj-y)),\
- $(LD) -r -o $@ $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@)
-
-quiet_cmd_host_ld_multi = HOSTLD $@
- cmd_host_ld_multi = $(if $(strip $(obj-y)),\
- $(HOSTLD) -r -o $@ $(filter $(obj-y),$^),rm -f $@; $(HOSTAR) rcs $@)
-
-ifneq ($(filter $(obj),$(hostprogs)),)
- host = host_
-endif
-
-# Build rules
-$(OUTPUT)%.o: %.c FORCE
- $(call rule_mkdir)
- $(call if_changed_dep,$(host)cc_o_c)
-
-$(OUTPUT)%.o: %.cpp FORCE
- $(call rule_mkdir)
- $(call if_changed_dep,cxx_o_c)
-
-$(OUTPUT)%.o: %.S FORCE
- $(call rule_mkdir)
- $(call if_changed_dep,$(host)cc_o_c)
-
-$(OUTPUT)%.i: %.c FORCE
- $(call rule_mkdir)
- $(call if_changed_dep,cpp_i_c)
-
-$(OUTPUT)%.s: %.S FORCE
- $(call rule_mkdir)
- $(call if_changed_dep,cpp_i_c)
-
-$(OUTPUT)%.s: %.c FORCE
- $(call rule_mkdir)
- $(call if_changed_dep,cc_s_c)
-
-# Gather build data:
-# obj-y - list of build objects
-# subdir-y - list of directories to nest
-# subdir-obj-y - list of directories objects 'dir/$(obj)-in.o'
-obj-y := $($(obj)-y)
-subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
-obj-y := $(patsubst %/, %/$(obj)-in.o, $(obj-y))
-subdir-obj-y := $(filter %/$(obj)-in.o, $(obj-y))
-
-# '$(OUTPUT)/dir' prefix to all objects
-objprefix := $(subst ./,,$(OUTPUT)$(dir)/)
-obj-y := $(addprefix $(objprefix),$(obj-y))
-subdir-obj-y := $(addprefix $(objprefix),$(subdir-obj-y))
-
-# Final '$(obj)-in.o' object
-in-target := $(objprefix)$(obj)-in.o
-
-PHONY += $(subdir-y)
-
-$(subdir-y):
- $(Q)$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj)
-
-$(sort $(subdir-obj-y)): $(subdir-y) ;
-
-$(in-target): $(obj-y) FORCE
- $(call rule_mkdir)
- $(call if_changed,$(host)ld_multi)
-
-__build: $(in-target)
- @:
-
-PHONY += FORCE
-FORCE:
-
-# Include all cmd files to get all the dependency rules
-# for all objects included
-targets := $(wildcard $(sort $(obj-y) $(in-target) $(MAKECMDGOALS)))
-cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
-
-ifneq ($(cmd_files),)
- include $(cmd_files)
-endif
-
-.PHONY: $(PHONY)
diff --git a/plugins/Makefile b/plugins/Makefile
index b60352da7816..8b1dbf68757c 100644
--- a/plugins/Makefile
+++ b/plugins/Makefile
@@ -41,7 +41,7 @@ libdir_relative ?= $(libdir_relative_tmp)
prefix ?= /usr/local
libdir = $(prefix)/$(libdir_relative)
-include ../scripts/Makefile.include
+include ../scripts/utils.mk
# copy a bit from Linux kbuild
@@ -52,13 +52,6 @@ ifndef VERBOSE
VERBOSE = 0
endif
-ifeq ($(srctree),)
-srctree := $(patsubst %/,%,$(dir $(CURDIR)))
-#$(info Determined 'srctree' to be $(srctree))
-endif
-
-export prefix libdir
-
# Shell quotes
plugin_dir_SQ = $(subst ','\'',$(plugin_dir))
@@ -89,16 +82,9 @@ else
Q = @
endif
-# Disable command line variables (CFLAGS) override from top
-# level Makefile (perf), otherwise build Makefile will get
-# the same command line setup.
-MAKEOVERRIDES=
-
export srctree OUTPUT CC LD CFLAGS V
-build := -f $(srctree)/build/Makefile.build dir=. obj
-
-DYNAMIC_LIST_FILE := $(OUTPUT)libtraceevent-dynamic-list
+DYNAMIC_LIST_FILE := $(bdir)/libtraceevent-dynamic-list
PLUGINS = plugin_jbd2.so
PLUGINS += plugin_hrtimer.so
@@ -113,22 +99,16 @@ PLUGINS += plugin_scsi.so
PLUGINS += plugin_cfg80211.so
PLUGINS += plugin_tlb.so
-PLUGINS := $(addprefix $(OUTPUT),$(PLUGINS))
-PLUGINS_IN := $(PLUGINS:.so=-in.o)
+PLUGINS := $(PLUGINS:%.so=$(bdir)/%.so)
+DEPS := $(PLUGINS:$(bdir)/%.so=$(bdir)/.%.d)
plugins: $(PLUGINS) $(DYNAMIC_LIST_FILE)
-__plugin_obj = $(notdir $@)
- plugin_obj = $(__plugin_obj:-in.o=)
-
-$(PLUGINS_IN): force
- $(Q)$(MAKE) $(build)=$(plugin_obj)
+$(PLUGINS): | $(bdir)
+$(DEPS): | $(bdir)
-$(OUTPUT)libtraceevent-dynamic-list: $(PLUGINS)
- $(QUIET_GEN)$(call do_generate_dynamic_list_file, $(PLUGINS), $@)
-
-$(OUTPUT)%.so: $(OUTPUT)%-in.o
- $(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^
+$(bdir)/%.so: $(srctree)/plugins/%.c
+ $(Q)$(call do_plugin_build)
define update_dir
(echo $1 > $@.tmp; \
@@ -150,17 +130,6 @@ TAGS: force
find . -name '*.[ch]' | xargs etags \
--regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/'
-define do_install_mkdir
- if [ ! -d '$(DESTDIR_SQ)$1' ]; then \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \
- fi
-endef
-
-define do_install
- $(call do_install_mkdir,$2); \
- $(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2'
-endef
-
define do_install_plugins
for plugin in $1; do \
$(call do_install,$$plugin,$(plugin_dir_SQ)); \
@@ -180,18 +149,16 @@ define do_generate_dynamic_list_file
fi
endef
+$(DYNAMIC_LIST_FILE): $(PLUGINS)
+ $(Q)($(print_gen)$(call do_generate_dynamic_list_file, $(PLUGINS), $@))
+
install: $(PLUGINS)
- $(call QUIET_INSTALL, trace_plugins) \
- $(call do_install_plugins, $(PLUGINS))
+ $(Q)$(call do_install_plugins, $(PLUGINS))
clean:
- $(call QUIET_CLEAN, trace_plugins) \
- $(RM) $(OUTPUT)*.o $(OUTPUT)*~ $(TARGETS) $(OUTPUT)*.a $(OUTPUT)*.so $(VERSION_FILES) .*.d .*.cmd; \
- $(RM) $(OUTPUT)libtraceevent-dynamic-list; \
- $(RM) $(PLUGINS); \
- $(RM) TRACEEVENT-CFLAGS tags TAGS;
+ $(Q)$(call do_clean, $(DYNAMIC_LIST_FILE) $(PLUGINS))
-PHONY += force plugins
+PHONY += force plugins $(DYNAMIC_LIST_FILE)
force:
# Declare the contents of the .PHONY variable as phony. We keep that
diff --git a/scripts/Makefile.include b/scripts/Makefile.include
deleted file mode 100644
index 1c9266c34d2a..000000000000
--- a/scripts/Makefile.include
+++ /dev/null
@@ -1,135 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-ifneq ($(O),)
-ifeq ($(origin O), command line)
- dummy := $(if $(shell cd $(PWD); test -d $(O) || echo $(O)),$(error O=$(O) does not exist),)
- ABSOLUTE_O := $(shell cd $(PWD); cd $(O) ; pwd)
- OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/)
- COMMAND_O := O=$(ABSOLUTE_O)
-ifeq ($(objtree),)
- objtree := $(O)
-endif
-endif
-endif
-
-# check that the output directory actually exists
-ifneq ($(OUTPUT),)
-OUTDIR := $(shell cd $(OUTPUT) && pwd)
-$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
-endif
-
-#
-# Include saner warnings here, which can catch bugs:
-#
-EXTRA_WARNINGS := -Wbad-function-cast
-EXTRA_WARNINGS += -Wdeclaration-after-statement
-EXTRA_WARNINGS += -Wformat-security
-EXTRA_WARNINGS += -Wformat-y2k
-EXTRA_WARNINGS += -Winit-self
-EXTRA_WARNINGS += -Wmissing-declarations
-EXTRA_WARNINGS += -Wmissing-prototypes
-EXTRA_WARNINGS += -Wnested-externs
-EXTRA_WARNINGS += -Wno-system-headers
-EXTRA_WARNINGS += -Wold-style-definition
-EXTRA_WARNINGS += -Wpacked
-EXTRA_WARNINGS += -Wredundant-decls
-EXTRA_WARNINGS += -Wstrict-prototypes
-EXTRA_WARNINGS += -Wswitch-default
-EXTRA_WARNINGS += -Wswitch-enum
-EXTRA_WARNINGS += -Wundef
-EXTRA_WARNINGS += -Wwrite-strings
-EXTRA_WARNINGS += -Wformat
-
-CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?)
-
-# Makefiles suck: This macro sets a default value of $(2) for the
-# variable named by $(1), unless the variable has been set by
-# environment or command line. This is necessary for CC and AR
-# because make sets default values, so the simpler ?= approach
-# won't work as expected.
-define allow-override
- $(if $(or $(findstring environment,$(origin $(1))),\
- $(findstring command line,$(origin $(1)))),,\
- $(eval $(1) = $(2)))
-endef
-
-# Allow setting various cross-compile vars or setting CROSS_COMPILE as a prefix.
-$(call allow-override,CC,$(CROSS_COMPILE)gcc)
-$(call allow-override,AR,$(CROSS_COMPILE)ar)
-$(call allow-override,LD,$(CROSS_COMPILE)ld)
-$(call allow-override,CXX,$(CROSS_COMPILE)g++)
-$(call allow-override,STRIP,$(CROSS_COMPILE)strip)
-
-ifeq ($(CC_NO_CLANG), 1)
-EXTRA_WARNINGS += -Wstrict-aliasing=3
-endif
-
-# Hack to avoid type-punned warnings on old systems such as RHEL5:
-# We should be changing CFLAGS and checking gcc version, but this
-# will do for now and keep the above -Wstrict-aliasing=3 in place
-# in newer systems.
-# Needed for the __raw_cmpxchg in tools/arch/x86/include/asm/cmpxchg.h
-#
-# See https://lkml.org/lkml/2006/11/28/253 and https://gcc.gnu.org/gcc-4.8/changes.html,
-# that takes into account Linus's comments (search for Wshadow) for the reasoning about
-# -Wshadow not being interesting before gcc 4.8.
-
-ifneq ($(filter 3.%,$(MAKE_VERSION)),) # make-3
-EXTRA_WARNINGS += -fno-strict-aliasing
-EXTRA_WARNINGS += -Wno-shadow
-else
-EXTRA_WARNINGS += -Wshadow
-endif
-
-ifneq ($(findstring $(MAKEFLAGS), w),w)
-PRINT_DIR = --no-print-directory
-else
-NO_SUBDIR = :
-endif
-
-ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
- silent=1
-endif
-
-#
-# Define a callable command for descending to a new directory
-#
-# Call by doing: $(call descend,directory[,target])
-#
-descend = \
- +mkdir -p $(OUTPUT)$(1) && \
- $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2)
-
-QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
-QUIET_SUBDIR1 =
-
-ifneq ($(silent),1)
- ifneq ($(V),1)
- QUIET_CC = @echo ' CC '$@;
- QUIET_CC_FPIC = @echo ' CC FPIC '$@;
- QUIET_CLANG = @echo ' CLANG '$@;
- QUIET_AR = @echo ' AR '$@;
- QUIET_LINK = @echo ' LINK '$@;
- QUIET_MKDIR = @echo ' MKDIR '$@;
- PRINT_GEN = echo ' GEN '$@;
- QUIET_GEN = @echo ' GEN '$@;
- QUIET_SUBDIR0 = +@subdir=
- QUIET_SUBDIR1 = ;$(NO_SUBDIR) \
- echo ' SUBDIR '$$subdir; \
- $(MAKE) $(PRINT_DIR) -C $$subdir
- QUIET_FLEX = @echo ' FLEX '$@;
- QUIET_BISON = @echo ' BISON '$@;
-
- descend = \
- +@echo ' DESCEND '$(1); \
- mkdir -p $(OUTPUT)$(1) && \
- $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2)
-
- PRINT_INSTALL = printf ' INSTALL %s\n' $1;
- PRINT_UNINST = printf ' UNINST %s\n' $1;
- QUIET_CLEAN = @printf ' CLEAN %s\n' $1;
- QUIET_INSTALL = @printf ' INSTALL %s\n' $1;
- QUIET_UNINST = @printf ' UNINST %s\n' $1;
- endif
-endif
-
-pound := \#
diff --git a/scripts/features.mk b/scripts/features.mk
new file mode 100644
index 000000000000..9c7f8c3076b3
--- /dev/null
+++ b/scripts/features.mk
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# taken from perf which was based on Linux Kbuild
+# try-cc
+# Usage: option = $(call try-cc, source-to-build, cc-options)
+try-cc = $(shell sh -c \
+ 'TMP="$(BUILD_OUTPUT)$(TMPOUT).$$$$"; \
+ echo "$(1)" | \
+ $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \
+ rm -f "$$TMP"')
+
+define SOURCE_PTRACE
+#include <stdio.h>
+#include <sys/ptrace.h>
+
+int main (void)
+{
+ int ret;
+ ret = ptrace(PTRACE_ATTACH, 0, NULL, 0);
+ ptrace(PTRACE_TRACEME, 0, NULL, 0);
+ ptrace(PTRACE_GETSIGINFO, 0, NULL, NULL);
+ ptrace(PTRACE_GETEVENTMSG, 0, NULL, NULL);
+ ptrace(PTRACE_SETOPTIONS, NULL, NULL,
+ PTRACE_O_TRACEFORK |
+ PTRACE_O_TRACEVFORK |
+ PTRACE_O_TRACECLONE |
+ PTRACE_O_TRACEEXIT);
+ ptrace(PTRACE_CONT, NULL, NULL, 0);
+ ptrace(PTRACE_DETACH, 0, NULL, NULL);
+ ptrace(PTRACE_SETOPTIONS, 0, NULL,
+ PTRACE_O_TRACEFORK |
+ PTRACE_O_TRACEVFORK |
+ PTRACE_O_TRACECLONE |
+ PTRACE_O_TRACEEXIT);
+ return ret;
+}
+endef
diff --git a/scripts/utils.mk b/scripts/utils.mk
new file mode 100644
index 000000000000..e33a8176049f
--- /dev/null
+++ b/scripts/utils.mk
@@ -0,0 +1,174 @@
+# SPDX-License-Identifier: LGPL-2.1
+
+# Utils
+
+ PWD := $(shell /bin/pwd)
+ GOBJ = $(notdir $(strip $@))
+ BASE1 = $(notdir $(strip $1))
+ BASE2 = $(notdir $(strip $2))
+ BASEPWD = $(notdir $(strip $(PWD)))
+
+
+ifeq ($(VERBOSE),1)
+ Q =
+ S =
+else
+ Q = @
+ S = -s
+endif
+
+# Use empty print_* macros if either SILENT or VERBOSE.
+ifeq ($(findstring 1,$(SILENT)$(VERBOSE)),1)
+ print_compile =
+ print_app_build =
+ print_fpic_compile =
+ print_shared_lib_compile =
+ print_plugin_obj_compile =
+ print_plugin_build =
+ print_install =
+ print_uninstall =
+ print_gen =
+ print_update =
+ print_descend =
+ print_clean =
+else
+ print_compile = echo ' COMPILE '$(GOBJ);
+ print_app_build = echo ' BUILD '$(GOBJ);
+ print_fpic_compile = echo ' COMPILE FPIC '$(GOBJ);
+ print_shared_lib_compile = echo ' COMPILE SHARED LIB '$(GOBJ);
+ print_plugin_obj_compile = echo ' COMPILE PLUGIN OBJ '$(GOBJ);
+ print_plugin_build = echo ' BUILD PLUGIN '$(GOBJ);
+ print_static_lib_build = echo ' BUILD STATIC LIB '$(GOBJ);
+ print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2';
+ print_uninstall = echo ' UNINSTALL $(DESTDIR_SQ)$1';
+ print_gen = echo ' GEN '$(GOBJ);
+ print_update = echo ' UPDATE '$(GOBJ);
+ print_descend = echo ' DESCEND '$(BASE1) $(BASE2);
+ print_clean = echo ' CLEAN '$(BASEPWD);
+endif
+
+do_fpic_compile = \
+ ($(print_fpic_compile) \
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(EXT) -fPIC $< -o $@)
+
+do_compile = \
+ ($(if $(GENERATE_PIC), $(do_fpic_compile), \
+ $(print_compile) \
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(EXT) $< -o $@))
+
+do_app_build = \
+ ($(print_app_build) \
+ $(CC) $^ -rdynamic -o $@ $(LDFLAGS) $(CONFIG_LIBS) $(LIBS))
+
+do_build_static_lib = \
+ ($(print_static_lib_build) \
+ if [ -f $@ ]; then \
+ mv $@ $@.rm; $(RM) $@.rm; \
+ fi; \
+ $(AR) rcs $@ $^)
+
+do_compile_shared_library = \
+ ($(print_shared_lib_compile) \
+ $(CC) --shared $^ '-Wl,-soname,$(1),-rpath=$$ORIGIN' -o $@ $(LDFLAGS) $(LIBS))
+
+do_compile_plugin_obj = \
+ ($(print_plugin_obj_compile) \
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ $<)
+
+do_plugin_build = \
+ ($(print_plugin_build) \
+ $(CC) $(CFLAGS) $(LDFLAGS) -shared -nostartfiles -o $@ $<)
+
+do_compile_python_plugin_obj = \
+ ($(print_plugin_obj_compile) \
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PYTHON_DIR_SQ) $(PYTHON_INCLUDES) -fPIC -o $@ $<)
+
+do_python_plugin_build = \
+ ($(print_plugin_build) \
+ $(CC) $< -shared $(LDFLAGS) $(PYTHON_LDFLAGS) -o $@)
+
+do_clean = \
+ ($(print_clean) \
+ $(RM) $1)
+
+#
+# Define a callable command for descending to a new directory
+#
+# Call by doing: $(call descend,directory[,target])
+#
+descend = \
+ ($(print_descend) \
+ mkdir -p $(obj)/$(BASE1); \
+ $(MAKE) $(PRINT_DIR) bdir=$(obj)/$(BASE1) -C $(1) $(2))
+
+descend_clean = \
+ $(MAKE) $(PRINT_DIR) bdir=$(obj)/$(BASE1) -C $(1) clean
+
+define make_version.h
+ (echo '/* This file is automatically generated. Do not modify. */'; \
+ echo \#define VERSION_CODE $(shell \
+ expr $(VERSION) \* 256 + $(PATCHLEVEL)); \
+ echo '#define EXTRAVERSION ' $(EXTRAVERSION); \
+ echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \
+ echo '#define FILE_VERSION '$(FILE_VERSION); \
+ if [ -d $(src)/.git ]; then \
+ d=`git diff`; \
+ x=""; \
+ if [ ! -z "$$d" ]; then x="+"; fi; \
+ echo '#define VERSION_GIT "'$(shell \
+ git log -1 --pretty=format:"%H" 2>/dev/null)$$x'"'; \
+ else \
+ echo '#define VERSION_GIT "not-a-git-repo"'; \
+ fi \
+ ) > $1
+endef
+
+define update_version.h
+ ($(call make_version.h, $@.tmp); \
+ if [ -r $@ ] && cmp -s $@ $@.tmp; then \
+ rm -f $@.tmp; \
+ else \
+ $(print_update) \
+ mv -f $@.tmp $@; \
+ fi);
+endef
+
+define update_dir
+ (echo $1 > $@.tmp; \
+ if [ -r $@ ] && cmp -s $@ $@.tmp; then \
+ rm -f $@.tmp; \
+ else \
+ $(print_update) \
+ mv -f $@.tmp $@; \
+ fi);
+endef
+
+define build_prefix
+ (echo $1 > $@.tmp; \
+ if [ -r $@ ] && cmp -s $@ $@.tmp; then \
+ rm -f $@.tmp; \
+ else \
+ $(print_update) \
+ mv -f $@.tmp $@; \
+ fi);
+endef
+
+define do_install_mkdir
+ if [ ! -d '$(DESTDIR_SQ)$1' ]; then \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \
+ fi
+endef
+
+define do_install
+ $(print_install) \
+ $(call do_install_mkdir,$2); \
+ $(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2'
+endef
+
+define do_install_pkgconfig_file
+ if [ -n "${pkgconfig_dir}" ]; then \
+ $(call do_install,$(PKG_CONFIG_FILE),$(pkgconfig_dir),644); \
+ else \
+ (echo Failed to locate pkg-config directory) 1>&2; \
+ fi
+endef
diff --git a/src/Makefile b/src/Makefile
index b7159bed9b68..53bb570182d2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,12 +1,55 @@
# SPDX-License-Identifier: LGPL-2.1
-include ../scripts/Makefile.include
+include $(src)/scripts/utils.mk
-build := -f $(srctree)/build/Makefile.build dir=. obj
+OBJS =
+OBJS += event-parse-api.o
+OBJS += event-parse.o
+OBJS += event-plugin.o
+OBJS += kbuffer-parse.o
+OBJS += parse-filter.o
+OBJS += parse-utils.o
+OBJS += tep_strerror.o
+OBJS += trace-seq.o
+
+OBJS := $(OBJS:%.o=$(bdir)/%.o)
+DEPS := $(OBJS:$(bdir)/%.o=$(bdir)/.%.d)
+
+$(bdir)/%.o: %.c
+ $(Q)$(call do_fpic_compile)
+
+$(LIBTRACEEVENT_STATIC): $(OBJS)
+ $(Q)$(call do_build_static_lib)
+
+$(LIBTRACEEVENT_SHARED): $(OBJS)
+ $(Q)$(call do_compile_shared_library,$(notdir $(LIBTRACEEVENT_SHARED_VERSION)))
+
+$(LIBTRACEEVENT_SHARED_VERSION): $(LIBTRACEEVENT_SHARED)
+ @ln -sf $(<F) $@
+
+$(LIBTRACEEVENT_SHARED_SO): $(LIBTRACEEVENT_SHARED_VERSION)
+ @ln -sf $(<F) $@
+
+libtraceevent.so: $(LIBTRACEEVENT_SHARED_SO)
libtraceevent: $(libtraceevent-y)
$(Q)$(MAKE) $(build)=libtraceevent
+$(DEPS): $(bdir)/.%.d: %.c
+ $(Q)$(CC) -M -MT $(bdir)/$*.o $(CPPFLAGS) $(CFLAGS) $< > $@
+
+$(OBJS): $(bdir)/%.o : $(bdir)/.%.d
+
+$(OBJS): | $(bdir)
+$(DEPS): | $(bdir)
+
clean:
- $(call QUIET_CLEAN, trace_src) \
- $(RM) $(OUTPUT)*.o $(OUTPUT)*~ .*.d .*.cmd
+ $(Q)$(call do_clean,$(OBJS) $(DEPS))
+
+dep_includes := $(wildcard $(DEPS))
+
+ifneq ($(dep_includes),)
+ include $(dep_includes)
+endif
+
+.PHONY: $(LIBTRACEEVENT_SHARED_SO) $(LIBTRACEEVENT_STATIC)
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 03/10] libtraceevent: Have make tags and TAGS honor O= build directory
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
2021-12-16 21:39 ` [PATCH 01/10] libtraceevent: Fix installing of man pages in remote directory Steven Rostedt
2021-12-16 21:39 ` [PATCH 02/10] libtraceevent: Rewrite Makefiles to be like libtracefs Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
2021-12-16 21:39 ` [PATCH 04/10] libtraceevent: Move installed headers into their own directory Steven Rostedt
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Currently if one does a "make O=/tmp/build tags" the tags are still built
in the source directory. Although this is uncommon to do, the tags (and
TAGS) target should still honor the build directory.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
Makefile | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/Makefile b/Makefile
index 4363e9b73dc3..8b3b5cc1ea35 100644
--- a/Makefile
+++ b/Makefile
@@ -246,15 +246,22 @@ define update_dir
fi);
endef
-tags: force
- $(RM) tags
- find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
- --regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/'
-
-TAGS: force
- $(RM) TAGS
- find . -name '*.[ch]' | xargs etags \
- --regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/'
+VIM_TAGS = $(obj)/tags
+EMACS_TAGS = $(obj)/TAGS
+
+$(VIM_TAGS): force
+ $(RM) $(VIM_TAGS)
+ find $(src) -name '*.[ch]' | (cd $(obj) && xargs ctags --extra=+f --c-kinds=+px \
+ --regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/')
+
+tags: $(VIM_TAGS)
+
+$(EMACS_TAGS): force
+ $(RM) $(EMACS_TAGS)
+ find $(src) -name '*.[ch]' | (cd $(obj) && xargs etags \
+ --regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/')
+
+TAGS: $(EMACS_TAGS)
define build_prefix
(echo $1 > $@.tmp; \
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 04/10] libtraceevent: Move installed headers into their own directory
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
` (2 preceding siblings ...)
2021-12-16 21:39 ` [PATCH 03/10] libtraceevent: Have make tags and TAGS honor O= build directory Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
2021-12-16 21:39 ` [PATCH 05/10] libtraceevent: Add unit test framework for library commands Steven Rostedt
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
It was noted that it is confusing that the headers that get installed and
are API are in the same directory as the source code. Create a
include/traceevent directory and move the headers that get installed onto
the system into that directory.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
Makefile | 14 ++++++++------
{src => include/traceevent}/event-parse.h | 0
{src => include/traceevent}/event-utils.h | 0
{src => include/traceevent}/kbuffer.h | 0
{src => include/traceevent}/trace-seq.h | 0
plugins/Makefile | 2 +-
6 files changed, 9 insertions(+), 7 deletions(-)
rename {src => include/traceevent}/event-parse.h (100%)
rename {src => include/traceevent}/event-utils.h (100%)
rename {src => include/traceevent}/kbuffer.h (100%)
rename {src => include/traceevent}/trace-seq.h (100%)
diff --git a/Makefile b/Makefile
index 8b3b5cc1ea35..965eb56a8ea0 100644
--- a/Makefile
+++ b/Makefile
@@ -117,9 +117,11 @@ N =
LIBTRACEEVENT_STATIC = $(bdir)/libtraceevent.a
LIBTRACEEVENT_SHARED = $(bdir)/libtraceevent.so.$(EVENT_PARSE_VERSION)
-INCLUDES = -I. -I $(srctree)/include $(CONFIG_INCLUDES)
+EP_HEADERS_DIR = $(src)/include/traceevent
-export LIBTRACEEVENT_STATIC LIBTRACEEVENT_SHARED
+INCLUDES = -I. -I $(srctree)/include -I $(EP_HEADERS_DIR) $(CONFIG_INCLUDES)
+
+export LIBTRACEEVENT_STATIC LIBTRACEEVENT_SHARED EP_HEADERS_DIR
# Set compile option CFLAGS
ifdef EXTRA_CFLAGS
@@ -334,10 +336,10 @@ install_pkgconfig: $(PKG_CONFIG_FILE)
$(Q)$(call do_install_pkgconfig_file,$(prefix))
install_headers:
- $(Q)$(call do_install,src/event-parse.h,$(includedir_SQ),644);
- $(Q)$(call do_install,src/event-utils.h,$(includedir_SQ),644);
- $(Q)$(call do_install,src/trace-seq.h,$(includedir_SQ),644);
- $(Q)$(call do_install,src/kbuffer.h,$(includedir_SQ),644)
+ $(Q)$(call do_install,$(EP_HEADERS_DIR)/event-parse.h,$(includedir_SQ),644);
+ $(Q)$(call do_install,$(EP_HEADERS_DIR)/event-utils.h,$(includedir_SQ),644);
+ $(Q)$(call do_install,$(EP_HEADERS_DIR)/trace-seq.h,$(includedir_SQ),644);
+ $(Q)$(call do_install,$(EP_HEADERS_DIR)/kbuffer.h,$(includedir_SQ),644)
install: install_libs
diff --git a/src/event-parse.h b/include/traceevent/event-parse.h
similarity index 100%
rename from src/event-parse.h
rename to include/traceevent/event-parse.h
diff --git a/src/event-utils.h b/include/traceevent/event-utils.h
similarity index 100%
rename from src/event-utils.h
rename to include/traceevent/event-utils.h
diff --git a/src/kbuffer.h b/include/traceevent/kbuffer.h
similarity index 100%
rename from src/kbuffer.h
rename to include/traceevent/kbuffer.h
diff --git a/src/trace-seq.h b/include/traceevent/trace-seq.h
similarity index 100%
rename from src/trace-seq.h
rename to include/traceevent/trace-seq.h
diff --git a/plugins/Makefile b/plugins/Makefile
index 8b1dbf68757c..4c8cb177b668 100644
--- a/plugins/Makefile
+++ b/plugins/Makefile
@@ -62,7 +62,7 @@ CONFIG_FLAGS =
OBJ = $@
N =
-INCLUDES = -I. -I.. -I../src -I $(srctree)/include $(CONFIG_INCLUDES)
+INCLUDES = -I. -I.. -I../src -I $(srctree)/include -I $(EP_HEADERS_DIR) $(CONFIG_INCLUDES)
# Set compile option CFLAGS
ifdef EXTRA_CFLAGS
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 05/10] libtraceevent: Add unit test framework for library commands
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
` (3 preceding siblings ...)
2021-12-16 21:39 ` [PATCH 04/10] libtraceevent: Move installed headers into their own directory Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
2021-12-16 21:39 ` [PATCH 06/10] libtraceveent: Add testing of old dynamic string event layout Steven Rostedt
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Add the frame work to start adding CUnit test framework. This also adds
one test to test dynamic strings, but more should be added.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
Makefile | 5 ++
utest/Makefile | 38 +++++++++++++
utest/README | 17 ++++++
utest/trace-utest.c | 86 +++++++++++++++++++++++++++++
utest/trace-utest.h | 14 +++++
utest/traceevent-utest.c | 114 +++++++++++++++++++++++++++++++++++++++
6 files changed, 274 insertions(+)
create mode 100644 utest/Makefile
create mode 100644 utest/README
create mode 100644 utest/trace-utest.c
create mode 100644 utest/trace-utest.h
create mode 100644 utest/traceevent-utest.c
diff --git a/Makefile b/Makefile
index 965eb56a8ea0..b26b0d5804ce 100644
--- a/Makefile
+++ b/Makefile
@@ -248,6 +248,11 @@ define update_dir
fi);
endef
+UTEST_DIR = utest
+
+test: force $(LIBTRACEEVENT_STATIC)
+ $(Q)$(call descend,$(UTEST_DIR),test)
+
VIM_TAGS = $(obj)/tags
EMACS_TAGS = $(obj)/TAGS
diff --git a/utest/Makefile b/utest/Makefile
new file mode 100644
index 000000000000..160bdb434653
--- /dev/null
+++ b/utest/Makefile
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: LGPL-2.1
+
+include $(src)/scripts/utils.mk
+
+TARGETS = $(bdir)/trace-utest
+
+OBJS =
+OBJS += trace-utest.o
+OBJS += traceevent-utest.o
+
+LIBS += -lcunit \
+ -ldl \
+ $(LIBTRACEEVENT_STATIC)
+
+OBJS := $(OBJS:%.o=$(bdir)/%.o)
+DEPS := $(OBJS:$(bdir)/%.o=$(bdir)/.%.d)
+
+$(OBJS): | $(bdir)
+$(DEPS): | $(bdir)
+
+$(bdir)/trace-utest: $(OBJS) $(LIBTRACEEVENT_STATIC)
+ $(Q)$(do_app_build)
+
+$(bdir)/%.o: %.c
+ $(Q)$(call do_fpic_compile)
+
+$(DEPS): $(bdir)/.%.d: %.c
+ $(Q)$(CC) -M $(CPPFLAGS) $(CFLAGS) $< > $@
+ $(Q)$(CC) -M -MT $(bdir)/$*.o $(CPPFLAGS) $(CFLAGS) $< > $@
+
+$(OBJS): $(bdir)/%.o : $(bdir)/.%.d
+
+dep_includes := $(wildcard $(DEPS))
+
+test: $(TARGETS)
+
+clean:
+ $(Q)$(call do_clean,$(TARGETS) $(bdir)/*.o $(bdir)/.*.d)
diff --git a/utest/README b/utest/README
new file mode 100644
index 000000000000..87d6bd9b82dc
--- /dev/null
+++ b/utest/README
@@ -0,0 +1,17 @@
+
+Unit tests for libtraceevent library. The tests use CUnit framework:
+
+ http://cunit.sourceforge.net/
+
+which must be pre installed on the system, before building the unit tests.
+The framework can be downloaded, compiled and installed manually, or
+using a precompiled distro package:
+
+ Fedora:
+ CUnit
+ CUnit-devel
+
+ Ubuntu and Debian:
+ libcunit1
+ libcunit1-doc
+ libcunit1-dev
diff --git a/utest/trace-utest.c b/utest/trace-utest.c
new file mode 100644
index 000000000000..1403c861e741
--- /dev/null
+++ b/utest/trace-utest.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * Copyright (C) 2020, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
+ *
+ * Modified from libtracefs to libtraceevent:
+ * Copyright (C) 2021, VMware, Steven Rostedt <rostedt@goodmis.org>
+ *
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdlib.h>
+
+#include <CUnit/CUnit.h>
+#include <CUnit/Basic.h>
+
+#include "trace-utest.h"
+
+enum unit_tests {
+ RUN_NONE = 0,
+ RUN_TRACEEVENT = (1 << 0),
+ RUN_ALL = 0xFFFF
+};
+
+static void print_help(char **argv)
+{
+ printf("Usage: %s [OPTIONS]\n", basename(argv[0]));
+ printf("\t-s, --silent\tPrint test summary\n");
+ printf("\t-r, --run test\tRun specific test:\n");
+ printf("\t\t traceevent run libtraceevent tests\n");
+ printf("\t-h, --help\tPrint usage information\n");
+ exit(0);
+}
+
+int main(int argc, char **argv)
+{
+ CU_BasicRunMode verbose = CU_BRM_VERBOSE;
+ enum unit_tests tests = RUN_NONE;
+
+ for (;;) {
+ int c;
+ int index = 0;
+ const char *opts = "+hsr:";
+ static struct option long_options[] = {
+ {"silent", no_argument, NULL, 's'},
+ {"run", required_argument, NULL, 'r'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long (argc, argv, opts, long_options, &index);
+ if (c == -1)
+ break;
+ switch (c) {
+ case 'r':
+ if (strcmp(optarg, "traceevent") == 0)
+ tests |= RUN_TRACEEVENT;
+ else
+ print_help(argv);
+ break;
+ case 's':
+ verbose = CU_BRM_SILENT;
+ break;
+ case 'h':
+ default:
+ print_help(argv);
+ break;
+ }
+ }
+
+ if (tests == RUN_NONE)
+ tests = RUN_ALL;
+
+ if (CU_initialize_registry() != CUE_SUCCESS) {
+ printf("Test registry cannot be initialized\n");
+ return -1;
+ }
+
+ if (tests & RUN_TRACEEVENT)
+ test_traceevent_lib();
+
+ CU_basic_set_mode(verbose);
+ CU_basic_run_tests();
+ CU_cleanup_registry();
+ return 0;
+}
diff --git a/utest/trace-utest.h b/utest/trace-utest.h
new file mode 100644
index 000000000000..2aa3455e7696
--- /dev/null
+++ b/utest/trace-utest.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+/*
+ * Copyright (C) 2020, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
+ *
+ * Modified from libtracefs to libtraceevent:
+ * Copyright (C) 2021, VMware, Steven Rostedt <rostedt@goodmis.org>
+ *
+ */
+#ifndef _TRACE_UTEST_H_
+#define _TRACE_UTEST_H_
+
+void test_traceevent_lib(void);
+
+#endif /* _TRACE_UTEST_H_ */
diff --git a/utest/traceevent-utest.c b/utest/traceevent-utest.c
new file mode 100644
index 000000000000..2910b95d01e6
--- /dev/null
+++ b/utest/traceevent-utest.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * Copyright (C) 2020, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
+ *
+ * Modified from libtracefs to libtraceevent:
+ * Copyright (C) 2021, VMware, Steven Rostedt <rostedt@goodmis.org>
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <dirent.h>
+#include <ftw.h>
+
+#include <CUnit/CUnit.h>
+#include <CUnit/Basic.h>
+
+#include "event-parse.h"
+#include "trace-seq.h"
+
+#define TRACEEVENT_SUITE "traceevent library"
+
+#define DYN_STR_EVENT_SYSTEM "irq"
+#define DYN_STR_FIELD "name"
+#define DYN_STRING "hello"
+static const char dyn_str_event[] =
+ "name: irq_handler_entry\n"
+ "ID: 1\n"
+ "format:\n"
+ "\tfield:unsigned short common_type;\toffset:0;\tsize:2;\tsigned:0;\n"
+ "\tfield:unsigned char common_flags;\toffset:2;\tsize:1;\tsigned:0;\n"
+ "\tfield:unsigned char common_preempt_count;\toffset:3;\tsize:1;\tsigned:0;\n"
+ "\tfield:int common_pid;\toffset:4;\tsize:4;\tsigned:1;\n"
+ "\n"
+ "\tfield:int irq;\toffset:8;\tsize:4;\tsigned:1;\n"
+ "\tfield:__data_loc char[] name;\toffset:12;\tsize:4;\tsigned:1;\n"
+ "\n"
+ "print fmt: \"irq=%d handler=%s\", REC->irq, __get_str(name)\n";
+
+static char dyn_str_data[] = {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ /* common type */ 1, 0x00,
+#else
+ /* common type */ 0x00, 1
+#endif
+ /* common flags */ 0x00,
+ /* common_preempt_count */ 0x00,
+ /* common_pid */ 0x00, 0x00, 0x00, 0x00,
+ /* irq */ 0x00, 0x00, 0x00, 0x00,
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ /* name : offset */ 16, 0x00,
+ /* name : length */ 6, 0x00,
+#else
+ /* name : length */ 0x00, 6,
+ /* name : offset */ 0x00, 16,
+#endif
+ /* name */ 'h', 'e', 'l', 'l', 'o', '\0',
+ /* padding */ 0x00, 0x00
+};
+static void *dyn_str_event_data = (void *)dyn_str_data;
+
+static struct tep_handle *test_tep;
+static struct trace_seq *test_seq;
+static struct trace_seq seq_storage;
+
+static void test_parse_dyn_str_event(void)
+{
+ struct tep_format_field *field;
+ struct tep_event *event;
+
+ CU_TEST(tep_parse_format(test_tep, &event,
+ dyn_str_event, strlen(dyn_str_event),
+ DYN_STR_EVENT_SYSTEM) == TEP_ERRNO__SUCCESS);
+
+ field = tep_find_any_field(event, DYN_STR_FIELD);
+ CU_TEST(field != NULL);
+ trace_seq_reset(test_seq);
+ tep_print_field(test_seq, dyn_str_event_data, field);
+ CU_TEST(strcmp(test_seq->buffer, DYN_STRING) == 0);
+}
+
+static int test_suite_destroy(void)
+{
+ tep_free(test_tep);
+ trace_seq_destroy(test_seq);
+ return 0;
+}
+
+static int test_suite_init(void)
+{
+ test_seq = &seq_storage;
+ trace_seq_init(test_seq);
+ test_tep = tep_alloc();
+ if (!test_tep)
+ return 1;
+ return 0;
+}
+
+void test_traceevent_lib(void)
+{
+ CU_pSuite suite = NULL;
+
+ suite = CU_add_suite(TRACEEVENT_SUITE, test_suite_init, test_suite_destroy);
+ if (suite == NULL) {
+ fprintf(stderr, "Suite \"%s\" cannot be ceated\n", TRACEEVENT_SUITE);
+ return;
+ }
+ CU_add_test(suite, "parse dynamic string event",
+ test_parse_dyn_str_event);
+}
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 06/10] libtraceveent: Add testing of old dynamic string event layout
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
` (4 preceding siblings ...)
2021-12-16 21:39 ` [PATCH 05/10] libtraceevent: Add unit test framework for library commands Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
2021-12-16 21:39 ` [PATCH 07/10] libraceevent: Add unit test to test print_fmt with dynamic strings Steven Rostedt
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
When running against old trace.dat files, the output would not print
strings. This was due to a change that did not take into account the old
dynamic format that did not have strings as an array.
Add a unit test to cover this case so that it does not break again.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
utest/traceevent-utest.c | 54 +++++++++++++++++++++++++++++++++++++---
1 file changed, 51 insertions(+), 3 deletions(-)
diff --git a/utest/traceevent-utest.c b/utest/traceevent-utest.c
index 2910b95d01e6..f4fdc86664ca 100644
--- a/utest/traceevent-utest.c
+++ b/utest/traceevent-utest.c
@@ -63,26 +63,72 @@ static char dyn_str_data[] = {
};
static void *dyn_str_event_data = (void *)dyn_str_data;
+static const char dyn_str_old_event[] =
+ "name: irq_handler_entry\n"
+ "ID: 2\n"
+ "format:\n"
+ "\tfield:unsigned short common_type;\toffset:0;\tsize:2;\n"
+ "\tfield:unsigned char common_flags;\toffset:2;\tsize:1;\n"
+ "\tfield:unsigned char common_preempt_count;\toffset:3;\tsize:1;\n"
+ "\tfield:int common_pid;\toffset:4;\tsize:4;\n"
+ "\n"
+ "\tfield:int irq;\toffset:8;\tsize:4;\n"
+ "\tfield:__data_loc name;\toffset:12;\tsize:2;\n"
+ "\n"
+ "print fmt: \"irq=%d handler=%s\", REC->irq, __get_str(name)\n";
+
+static char dyn_str_old_data[] = {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ /* common type */ 2, 0x00,
+#else
+ /* common type */ 0x00, 2
+#endif
+ /* common flags */ 0x00,
+ /* common_preempt_count */ 0x00,
+ /* common_pid */ 0x00, 0x00, 0x00, 0x00,
+ /* irq */ 0x00, 0x00, 0x00, 0x00,
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ /* name : offset */ 16, 0x00,
+#else
+ /* name : offset */ 0x00, 16,
+#endif
+ /* padding */ 0x00, 0x00,
+ /* name */ 'h', 'e', 'l', 'l', 'o', '\0',
+ /* padding */ 0x00, 0x00, 0x00
+};
+static void *dyn_str_old_event_data = (void *)dyn_str_old_data;
+
static struct tep_handle *test_tep;
static struct trace_seq *test_seq;
static struct trace_seq seq_storage;
-static void test_parse_dyn_str_event(void)
+static void parse_dyn_str(const char *dyn_str, void *data)
{
struct tep_format_field *field;
struct tep_event *event;
CU_TEST(tep_parse_format(test_tep, &event,
- dyn_str_event, strlen(dyn_str_event),
+ dyn_str, strlen(dyn_str),
DYN_STR_EVENT_SYSTEM) == TEP_ERRNO__SUCCESS);
field = tep_find_any_field(event, DYN_STR_FIELD);
CU_TEST(field != NULL);
trace_seq_reset(test_seq);
- tep_print_field(test_seq, dyn_str_event_data, field);
+ tep_print_field(test_seq, data, field);
CU_TEST(strcmp(test_seq->buffer, DYN_STRING) == 0);
}
+static void test_parse_dyn_str_event(void)
+{
+ parse_dyn_str(dyn_str_event, dyn_str_event_data);
+}
+
+static void test_parse_dyn_str_old_event(void)
+{
+ parse_dyn_str(dyn_str_old_event, dyn_str_old_event_data);
+}
+
static int test_suite_destroy(void)
{
tep_free(test_tep);
@@ -111,4 +157,6 @@ void test_traceevent_lib(void)
}
CU_add_test(suite, "parse dynamic string event",
test_parse_dyn_str_event);
+ CU_add_test(suite, "parse old dynamic string event",
+ test_parse_dyn_str_old_event);
}
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 07/10] libraceevent: Add unit test to test print_fmt with dynamic strings
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
` (5 preceding siblings ...)
2021-12-16 21:39 ` [PATCH 06/10] libtraceveent: Add testing of old dynamic string event layout Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
2021-12-16 21:39 ` [PATCH 08/10] libtraceevent: Account for old dynamic string formats and honor size Steven Rostedt
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Add a unit test that calls tep_print_event() with the TEP_PRINT_INFO with
an event that has dynamic strings (with both the old and new formats).
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
utest/traceevent-utest.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/utest/traceevent-utest.c b/utest/traceevent-utest.c
index f4fdc86664ca..a0d808e5c1a5 100644
--- a/utest/traceevent-utest.c
+++ b/utest/traceevent-utest.c
@@ -26,6 +26,7 @@
#define DYN_STR_EVENT_SYSTEM "irq"
#define DYN_STR_FIELD "name"
#define DYN_STRING "hello"
+#define DYN_STRING_FMT "irq=0 handler=hello"
static const char dyn_str_event[] =
"name: irq_handler_entry\n"
"ID: 1\n"
@@ -107,6 +108,9 @@ static void parse_dyn_str(const char *dyn_str, void *data)
{
struct tep_format_field *field;
struct tep_event *event;
+ struct tep_record record;
+
+ record.data = data;
CU_TEST(tep_parse_format(test_tep, &event,
dyn_str, strlen(dyn_str),
@@ -117,6 +121,11 @@ static void parse_dyn_str(const char *dyn_str, void *data)
trace_seq_reset(test_seq);
tep_print_field(test_seq, data, field);
CU_TEST(strcmp(test_seq->buffer, DYN_STRING) == 0);
+
+ trace_seq_reset(test_seq);
+ tep_print_event(test_tep, test_seq, &record, "%s", TEP_PRINT_INFO);
+ trace_seq_do_printf(test_seq);
+ CU_TEST(strcmp(test_seq->buffer, DYN_STRING_FMT) == 0);
}
static void test_parse_dyn_str_event(void)
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 08/10] libtraceevent: Account for old dynamic string formats and honor size
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
` (6 preceding siblings ...)
2021-12-16 21:39 ` [PATCH 07/10] libraceevent: Add unit test to test print_fmt with dynamic strings Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
2021-12-16 21:39 ` [PATCH 09/10] libtraceevent: Replace tep_print_field() with tep_print_field_content() Steven Rostedt
2021-12-16 21:39 ` [PATCH 10/10] libtraceevent: Have print_field_raw() handle old data layout Steven Rostedt
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Old kernels that started with dynamic strings did not place the length of
the dynamic string into the place holder. Instead, it only had a two byte
offset to where the string was located in the data payload.
It just worked by shear luck that the reading of the string would look at
he length (which was just random numbers) and if it wasn't zero, it would
print the string normally. With the update to include rel_loc, the size of
the place holder is no longer hard coded as 4, and the actual size is used
(2 for the old format). This caused the length of the string to always be
zero, which triggered the check to not bother printing strings of size
zero. Hence the strings stopped being printed.
Start using the size of the data payload to limit the string parsing. More
work needs to be done in this regard, but having an application trust the
size of the payload of unknown data can be dangerous. Use this as an
opportunity to parse by size. Make the length of the string from the old
format the rest of the data payload, and not depend on it ending with
'\0'.
Note, tep_print_field() does not allow the user to pass in the size of the
data to parse. Currently use 4096, but this will need to be deprecated.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
src/event-parse.c | 67 ++++++++++++++++++++++++++--------------
utest/traceevent-utest.c | 7 +++--
2 files changed, 47 insertions(+), 27 deletions(-)
diff --git a/src/event-parse.c b/src/event-parse.c
index 34d6c9616f08..62afe86f2c6d 100644
--- a/src/event-parse.c
+++ b/src/event-parse.c
@@ -3878,9 +3878,10 @@ static unsigned long long test_for_symbol(struct tep_handle *tep,
#define TEP_LEN_SHIFT 16
static void dynamic_offset(struct tep_handle *tep, int size, void *data,
- unsigned int *offset, unsigned int *len)
+ int data_size, unsigned int *offset, unsigned int *len)
{
unsigned long long val;
+ unsigned int o, l;
/*
* The total allocated length of the dynamic array is
@@ -3889,19 +3890,36 @@ static void dynamic_offset(struct tep_handle *tep, int size, void *data,
*/
val = tep_read_number(tep, data, size);
+ /* Check for overflows */
+ o = (unsigned int)(val & TEP_OFFSET_LEN_MASK);
+
+ /* If there's no length, then just make the length the size of the data */
+ if (size == 2)
+ l = data_size - o;
+ else
+ l = (unsigned int)((val >> TEP_LEN_SHIFT) & TEP_OFFSET_LEN_MASK);
+
if (offset)
- *offset = (unsigned int)(val & TEP_OFFSET_LEN_MASK);
+ *offset = o > data_size ? 0 : o;
if (len)
- *len = (unsigned int)((val >> TEP_LEN_SHIFT) & TEP_OFFSET_LEN_MASK);
+ *len = o + l > data_size ? 0 : l;
}
static inline void dynamic_offset_field(struct tep_handle *tep,
struct tep_format_field *field,
- void *data,
+ void *data, int size,
unsigned int *offset,
unsigned int *len)
{
- dynamic_offset(tep, field->size, data + field->offset, offset, len);
+ /* Test for overflow */
+ if (field->offset + field->size > size) {
+ if (*offset)
+ *offset = 0;
+ if (*len)
+ *len = 0;
+ return;
+ }
+ dynamic_offset(tep, field->size, data + field->offset, size, offset, len);
if (field->flags & TEP_FIELD_IS_RELATIVE)
*offset += field->offset + field->size;
}
@@ -3978,7 +3996,7 @@ eval_num_arg(void *data, int size, struct tep_event *event, struct tep_print_arg
switch (larg->type) {
case TEP_PRINT_DYNAMIC_ARRAY:
dynamic_offset_field(tep, larg->dynarray.field, data,
- &offset, NULL);
+ size, &offset, NULL);
offset += right;
if (larg->dynarray.field->elementsize)
field_size = larg->dynarray.field->elementsize;
@@ -4100,13 +4118,13 @@ eval_num_arg(void *data, int size, struct tep_event *event, struct tep_print_arg
}
break;
case TEP_PRINT_DYNAMIC_ARRAY_LEN:
- dynamic_offset_field(tep, arg->dynarray.field, data,
+ dynamic_offset_field(tep, arg->dynarray.field, data, size,
NULL, &field_size);
val = field_size;
break;
case TEP_PRINT_DYNAMIC_ARRAY:
/* Without [], we pass the address to the dynamic data */
- dynamic_offset_field(tep, arg->dynarray.field, data,
+ dynamic_offset_field(tep, arg->dynarray.field, data, size,
&offset, NULL);
val = (unsigned long long)((unsigned long)data + offset);
val = (unsigned long)data + offset;
@@ -4348,7 +4366,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
case TEP_PRINT_HEX_STR:
if (arg->hex.field->type == TEP_PRINT_DYNAMIC_ARRAY) {
dynamic_offset_field(tep, arg->hex.field->dynarray.field, data,
- &offset, NULL);
+ size, &offset, NULL);
hex = data + offset;
} else {
field = arg->hex.field->field.field;
@@ -4375,7 +4393,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
if (arg->int_array.field->type == TEP_PRINT_DYNAMIC_ARRAY) {
dynamic_offset_field(tep, arg->int_array.field->dynarray.field, data,
- &offset, NULL);
+ size, &offset, NULL);
num = data + offset;
} else {
field = arg->int_array.field->field.field;
@@ -4420,7 +4438,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
arg->string.field = tep_find_any_field(event, arg->string.string);
if (!arg->string.field)
break;
- dynamic_offset_field(tep, arg->string.field, data, &offset, &len);
+ dynamic_offset_field(tep, arg->string.field, data, size, &offset, &len);
/* Do not attempt to save zero length dynamic strings */
if (!len)
break;
@@ -4435,7 +4453,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
arg->bitmask.field = tep_find_any_field(event, arg->bitmask.bitmask);
if (!arg->bitmask.field)
break;
- dynamic_offset_field(tep, arg->bitmask.field, data, &offset, &len);
+ dynamic_offset_field(tep, arg->bitmask.field, data, size, &offset, &len);
print_bitmask_to_seq(tep, s, format, len_arg,
data + offset, len);
break;
@@ -5312,7 +5330,7 @@ static int print_raw_buff_arg(struct trace_seq *s, const char *ptr,
return ret;
}
- dynamic_offset_field(event->tep, arg->dynarray.field, data,
+ dynamic_offset_field(event->tep, arg->dynarray.field, data, size,
&offset, &arr_len);
buf = data + offset;
@@ -5339,7 +5357,7 @@ static int is_printable_array(char *p, unsigned int len)
return 1;
}
-static void print_field_raw(struct trace_seq *s, void *data,
+static void print_field_raw(struct trace_seq *s, void *data, int size,
struct tep_format_field *field)
{
struct tep_handle *tep = field->event->tep;
@@ -5348,7 +5366,7 @@ static void print_field_raw(struct trace_seq *s, void *data,
if (field->flags & TEP_FIELD_IS_ARRAY) {
if (field->flags & TEP_FIELD_IS_DYNAMIC) {
- dynamic_offset_field(tep, field, data, &offset, &len);
+ dynamic_offset_field(tep, field, data, size, &offset, &len);
} else {
offset = field->offset;
len = field->size;
@@ -5405,7 +5423,7 @@ static void print_field_raw(struct trace_seq *s, void *data,
static int print_parse_data(struct tep_print_parse *parse, struct trace_seq *s,
void *data, int size, struct tep_event *event);
-void static inline print_field(struct trace_seq *s, void *data,
+void static inline print_field(struct trace_seq *s, void *data, int size,
struct tep_format_field *field,
struct tep_print_parse **parse_ptr)
{
@@ -5460,17 +5478,18 @@ void static inline print_field(struct trace_seq *s, void *data,
out:
/* Not found. */
- print_field_raw(s, data, field);
+ print_field_raw(s, data, size, field);
}
void tep_print_field(struct trace_seq *s, void *data,
struct tep_format_field *field)
{
- print_field(s, data, field, NULL);
+ /* unsafe to use, should pass in size */
+ print_field(s, data, 4096, field, NULL);
}
static inline void
-print_selected_fields(struct trace_seq *s, void *data,
+print_selected_fields(struct trace_seq *s, void *data, int size,
struct tep_event *event,
unsigned long long ignore_mask)
{
@@ -5484,14 +5503,14 @@ print_selected_fields(struct trace_seq *s, void *data,
continue;
trace_seq_printf(s, " %s=", field->name);
- print_field(s, data, field, &parse);
+ print_field(s, data, size, field, &parse);
}
}
void tep_print_fields(struct trace_seq *s, void *data,
- int size __maybe_unused, struct tep_event *event)
+ int size, struct tep_event *event)
{
- print_selected_fields(s, data, event, 0);
+ print_selected_fields(s, data, size, event, 0);
}
/**
@@ -5505,7 +5524,7 @@ void tep_record_print_fields(struct trace_seq *s,
struct tep_record *record,
struct tep_event *event)
{
- print_selected_fields(s, record->data, event, 0);
+ print_selected_fields(s, record->data, record->size, event, 0);
}
/**
@@ -5523,7 +5542,7 @@ void tep_record_print_selected_fields(struct trace_seq *s,
{
unsigned long long ignore_mask = ~select_mask;
- print_selected_fields(s, record->data, event, ignore_mask);
+ print_selected_fields(s, record->data, record->size, event, ignore_mask);
}
static int print_function(struct trace_seq *s, const char *format,
diff --git a/utest/traceevent-utest.c b/utest/traceevent-utest.c
index a0d808e5c1a5..0f4f17e655ae 100644
--- a/utest/traceevent-utest.c
+++ b/utest/traceevent-utest.c
@@ -104,13 +104,14 @@ static struct tep_handle *test_tep;
static struct trace_seq *test_seq;
static struct trace_seq seq_storage;
-static void parse_dyn_str(const char *dyn_str, void *data)
+static void parse_dyn_str(const char *dyn_str, void *data, int size)
{
struct tep_format_field *field;
struct tep_event *event;
struct tep_record record;
record.data = data;
+ record.size = size;
CU_TEST(tep_parse_format(test_tep, &event,
dyn_str, strlen(dyn_str),
@@ -130,12 +131,12 @@ static void parse_dyn_str(const char *dyn_str, void *data)
static void test_parse_dyn_str_event(void)
{
- parse_dyn_str(dyn_str_event, dyn_str_event_data);
+ parse_dyn_str(dyn_str_event, dyn_str_event_data, sizeof(dyn_str_data));
}
static void test_parse_dyn_str_old_event(void)
{
- parse_dyn_str(dyn_str_old_event, dyn_str_old_event_data);
+ parse_dyn_str(dyn_str_old_event, dyn_str_old_event_data, sizeof(dyn_str_old_data));
}
static int test_suite_destroy(void)
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 09/10] libtraceevent: Replace tep_print_field() with tep_print_field_content()
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
` (7 preceding siblings ...)
2021-12-16 21:39 ` [PATCH 08/10] libtraceevent: Account for old dynamic string formats and honor size Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
2021-12-16 21:39 ` [PATCH 10/10] libtraceevent: Have print_field_raw() handle old data layout Steven Rostedt
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
The API tep_print_field() does not let the user define the size of the
payload that is being parsed. This can lead to dangerous code if the data
itself is untrusted. It could define a string and offset to read other
parts of the application.
Add a new tep_print_field_content() that adds the size variable that can
be used to prevent accesses outside the data.
Note, there is still many ways to circumvent the size limitation that
needs to be fixed, but having an API that will not let you fix it is a
problem.
Also fixed at formatting issue with print_field() that had void before the
"static inline".
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
Documentation/libtraceevent-field_print.txt | 10 +++++-----
Documentation/libtraceevent.txt | 2 +-
include/traceevent/event-parse.h | 8 ++++++--
src/event-parse.c | 21 ++++++++++++++++++++-
utest/traceevent-utest.c | 2 +-
5 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/Documentation/libtraceevent-field_print.txt b/Documentation/libtraceevent-field_print.txt
index c201c134c42e..05b458b29e8e 100644
--- a/Documentation/libtraceevent-field_print.txt
+++ b/Documentation/libtraceevent-field_print.txt
@@ -3,7 +3,7 @@ libtraceevent(3)
NAME
----
-tep_print_field, tep_print_fields, tep_print_num_field, tep_print_func_field, tep_record_print_fields, tep_record_print_selected_fields -
+tep_print_field_content, tep_print_fields, tep_print_num_field, tep_print_func_field, tep_record_print_fields, tep_record_print_selected_fields -
Print the field content.
SYNOPSIS
@@ -13,7 +13,7 @@ SYNOPSIS
*#include <event-parse.h>*
*#include <trace-seq.h>*
-void *tep_print_field*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, struct tep_format_field pass:[*]_field_);
+void *tep_print_field_content*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int size, struct tep_format_field pass:[*]_field_);
void *tep_print_fields*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int _size_, struct tep_event pass:[*]_event_);
int *tep_print_num_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_);
int *tep_print_func_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_);
@@ -25,7 +25,7 @@ DESCRIPTION
-----------
These functions print recorded field's data, according to the field's type.
-The _tep_print_field()_ function extracts from the recorded raw _data_ value of
+The _tep_print_field_content()_ function extracts from the recorded raw _data_ value of
the _field_ and prints it into _s_, according to the field type.
The _tep_print_fields()_ prints each field name followed by the record's field
@@ -34,7 +34,7 @@ value according to the field's type:
--
"field1_name=field1_value field2_name=field2_value ..."
--
-It iterates all fields of the _event_, and calls _tep_print_field()_ for each of
+It iterates all fields of the _event_, and calls _tep_print_field_content()_ for each of
them.
The _tep_print_num_field()_ function prints a numeric field with given format
@@ -83,7 +83,7 @@ void process_record(struct tep_record *record)
trace_seq_reset(&seq);
/* Print the value of "common_pid" */
- tep_print_field(&seq, record->data, field_pid);
+ tep_print_field_content(&seq, record->data, record->size, field_pid);
/* Print all fields of the "hrtimer_start" event */
tep_print_fields(&seq, record->data, record->size, event);
diff --git a/Documentation/libtraceevent.txt b/Documentation/libtraceevent.txt
index 01014b7ca719..95465521bcf4 100644
--- a/Documentation/libtraceevent.txt
+++ b/Documentation/libtraceevent.txt
@@ -76,7 +76,7 @@ APIs related to fields from event's format files:
int *tep_read_number_field*(struct tep_format_field pass:[*]_field_, const void pass:[*]_data_, unsigned long long pass:[*]_value_);
Event fields printing:
- void *tep_print_field*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, struct tep_format_field pass:[*]_field_);
+ void *tep_print_field_content*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int size, struct tep_format_field pass:[*]_field_);
void *tep_print_fields*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int _size_, struct tep_event pass:[*]_event_);
int *tep_print_num_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_);
int *tep_print_func_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_);
diff --git a/include/traceevent/event-parse.h b/include/traceevent/event-parse.h
index 97234062a057..27cba06f55cb 100644
--- a/include/traceevent/event-parse.h
+++ b/include/traceevent/event-parse.h
@@ -544,8 +544,8 @@ struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *tep, const char *c
struct tep_cmdline *next);
int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline);
-void tep_print_field(struct trace_seq *s, void *data,
- struct tep_format_field *field);
+void tep_print_field_content(struct trace_seq *s, void *data, int size,
+ struct tep_format_field *field);
void tep_record_print_fields(struct trace_seq *s,
struct tep_record *record,
struct tep_event *event);
@@ -770,4 +770,8 @@ enum tep_loglevel {
};
void tep_set_loglevel(enum tep_loglevel level);
+/* DEPRECATED */
+void tep_print_field(struct trace_seq *s, void *data,
+ struct tep_format_field *field);
+
#endif /* _PARSE_EVENTS_H */
diff --git a/src/event-parse.c b/src/event-parse.c
index 62afe86f2c6d..40af92f4295f 100644
--- a/src/event-parse.c
+++ b/src/event-parse.c
@@ -5423,7 +5423,7 @@ static void print_field_raw(struct trace_seq *s, void *data, int size,
static int print_parse_data(struct tep_print_parse *parse, struct trace_seq *s,
void *data, int size, struct tep_event *event);
-void static inline print_field(struct trace_seq *s, void *data, int size,
+static inline void print_field(struct trace_seq *s, void *data, int size,
struct tep_format_field *field,
struct tep_print_parse **parse_ptr)
{
@@ -5481,6 +5481,25 @@ void static inline print_field(struct trace_seq *s, void *data, int size,
print_field_raw(s, data, size, field);
}
+/**
+ * tep_print_field_content - write out the raw content of a field
+ * @s: The trace_seq to write the content into
+ * @data: The payload to extract the field from.
+ * @size: The size of the payload.
+ * @field: The field to extract
+ *
+ * Use @field to find the field content from within @data and write it
+ * in human readable format into @s.
+ *
+ * It will not write anything on error (s->len will not move)
+ */
+void tep_print_field_content(struct trace_seq *s, void *data, int size,
+ struct tep_format_field *field)
+{
+ print_field(s, data, size, field, NULL);
+}
+
+/** DEPRECATED **/
void tep_print_field(struct trace_seq *s, void *data,
struct tep_format_field *field)
{
diff --git a/utest/traceevent-utest.c b/utest/traceevent-utest.c
index 0f4f17e655ae..99900de50355 100644
--- a/utest/traceevent-utest.c
+++ b/utest/traceevent-utest.c
@@ -120,7 +120,7 @@ static void parse_dyn_str(const char *dyn_str, void *data, int size)
field = tep_find_any_field(event, DYN_STR_FIELD);
CU_TEST(field != NULL);
trace_seq_reset(test_seq);
- tep_print_field(test_seq, data, field);
+ tep_print_field_content(test_seq, data, size, field);
CU_TEST(strcmp(test_seq->buffer, DYN_STRING) == 0);
trace_seq_reset(test_seq);
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 10/10] libtraceevent: Have print_field_raw() handle old data layout
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
` (8 preceding siblings ...)
2021-12-16 21:39 ` [PATCH 09/10] libtraceevent: Replace tep_print_field() with tep_print_field_content() Steven Rostedt
@ 2021-12-16 21:39 ` Steven Rostedt
9 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2021-12-16 21:39 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Steven Rostedt (VMware)
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Old kernels would produce dynamic strings with only a two byte offset. The
length of the array was determined by the string length. When parsing, if
the field is dynamic with a size of 2, then it is the old dynamic string
layout. Set the field to both a string and an array.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
src/event-parse.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/event-parse.c b/src/event-parse.c
index 40af92f4295f..9bd605d74b1f 100644
--- a/src/event-parse.c
+++ b/src/event-parse.c
@@ -1828,6 +1828,16 @@ static int event_read_fields(struct tep_event *event, struct tep_format_field **
field->size = strtoul(token, NULL, 0);
free_token(token);
+ /*
+ * The old data format before dynamic arrays had dynamic
+ * strings defined with just a 2 byte offset (the length
+ * is defined by the strlen() of the string. To process them
+ * correctly, check if the field is dynamic and has a size of
+ * 2 bytes. All current dynamic events have a size of 4.
+ */
+ if ((field->flags & TEP_FIELD_IS_DYNAMIC) && field->size == 2)
+ field->flags |= TEP_FIELD_IS_STRING | TEP_FIELD_IS_ARRAY;
+
if (read_expected(TEP_EVENT_OP, ";") < 0)
goto fail_expect;
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2021-12-16 21:40 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-12-16 21:39 [PATCH 00/10] libtraceevent: Makefile updates fixes and unit tests Steven Rostedt
2021-12-16 21:39 ` [PATCH 01/10] libtraceevent: Fix installing of man pages in remote directory Steven Rostedt
2021-12-16 21:39 ` [PATCH 02/10] libtraceevent: Rewrite Makefiles to be like libtracefs Steven Rostedt
2021-12-16 21:39 ` [PATCH 03/10] libtraceevent: Have make tags and TAGS honor O= build directory Steven Rostedt
2021-12-16 21:39 ` [PATCH 04/10] libtraceevent: Move installed headers into their own directory Steven Rostedt
2021-12-16 21:39 ` [PATCH 05/10] libtraceevent: Add unit test framework for library commands Steven Rostedt
2021-12-16 21:39 ` [PATCH 06/10] libtraceveent: Add testing of old dynamic string event layout Steven Rostedt
2021-12-16 21:39 ` [PATCH 07/10] libraceevent: Add unit test to test print_fmt with dynamic strings Steven Rostedt
2021-12-16 21:39 ` [PATCH 08/10] libtraceevent: Account for old dynamic string formats and honor size Steven Rostedt
2021-12-16 21:39 ` [PATCH 09/10] libtraceevent: Replace tep_print_field() with tep_print_field_content() Steven Rostedt
2021-12-16 21:39 ` [PATCH 10/10] libtraceevent: Have print_field_raw() handle old data layout Steven Rostedt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).