From patchwork Thu Dec 16 21:39:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682753 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95406C433EF for ; Thu, 16 Dec 2021 21:40:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241241AbhLPVkA (ORCPT ); Thu, 16 Dec 2021 16:40:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32810 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241042AbhLPVj7 (ORCPT ); Thu, 16 Dec 2021 16:39:59 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C4A24C06173E for ; Thu, 16 Dec 2021 13:39:59 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6575461F9B for ; Thu, 16 Dec 2021 21:39:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CCA23C36AEA; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003dH-PA; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 01/10] libtraceevent: Fix installing of man pages in remote directory Date: Thu, 16 Dec 2021 16:39:47 -0500 Message-Id: <20211216213956.13934-2-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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 From patchwork Thu Dec 16 21:39:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682765 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3A7AC433F5 for ; Thu, 16 Dec 2021 21:40:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241607AbhLPVkB (ORCPT ); Thu, 16 Dec 2021 16:40:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241298AbhLPVkA (ORCPT ); Thu, 16 Dec 2021 16:40:00 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F7EEC061574 for ; Thu, 16 Dec 2021 13:40:00 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 2324861F98 for ; Thu, 16 Dec 2021 21:40:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C9B03C36AE9; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003dK-Pv; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 02/10] libtraceevent: Rewrite Makefiles to be like libtracefs Date: Thu, 16 Dec 2021 16:39:48 -0500 Message-Id: <20211216213956.13934-3-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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 $( $@.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 , 2015 -# Copyright (C) Linus Torvalds , 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 , 2015 -# Copyright (C) Linus Torvalds , 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 +#include + +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 $( $@ + +$(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) From patchwork Thu Dec 16 21:39:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682759 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5B34AC43219 for ; Thu, 16 Dec 2021 21:40:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241111AbhLPVkB (ORCPT ); Thu, 16 Dec 2021 16:40:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241298AbhLPVkB (ORCPT ); Thu, 16 Dec 2021 16:40:01 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 51E14C061574 for ; Thu, 16 Dec 2021 13:40:01 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 1A4CAB8264D for ; Thu, 16 Dec 2021 21:40:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C24C6C36AE8; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003dN-Qa; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 03/10] libtraceevent: Have make tags and TAGS honor O= build directory Date: Thu, 16 Dec 2021 16:39:49 -0500 Message-Id: <20211216213956.13934-4-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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; \ From patchwork Thu Dec 16 21:39:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682767 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1EF10C4321E for ; Thu, 16 Dec 2021 21:40:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241639AbhLPVkC (ORCPT ); Thu, 16 Dec 2021 16:40:02 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:39060 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241577AbhLPVkB (ORCPT ); Thu, 16 Dec 2021 16:40:01 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 95E2DB82655 for ; Thu, 16 Dec 2021 21:40:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EAF04C36AEE; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003dQ-RE; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 04/10] libtraceevent: Move installed headers into their own directory Date: Thu, 16 Dec 2021 16:39:50 -0500 Message-Id: <20211216213956.13934-5-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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 From patchwork Thu Dec 16 21:39:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682773 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E029DC4167D for ; Thu, 16 Dec 2021 21:40:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241577AbhLPVkC (ORCPT ); Thu, 16 Dec 2021 16:40:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32822 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241636AbhLPVkB (ORCPT ); Thu, 16 Dec 2021 16:40:01 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 883FAC06173E for ; Thu, 16 Dec 2021 13:40:01 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 24754B82651 for ; Thu, 16 Dec 2021 21:40:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CB222C36AE2; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003dT-Rv; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 05/10] libtraceevent: Add unit test framework for library commands Date: Thu, 16 Dec 2021 16:39:51 -0500 Message-Id: <20211216213956.13934-6-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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 + * + * Modified from libtracefs to libtraceevent: + * Copyright (C) 2021, VMware, Steven Rostedt + * + */ +#include +#include +#include +#include + +#include +#include + +#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 + * + * Modified from libtracefs to libtraceevent: + * Copyright (C) 2021, VMware, Steven Rostedt + * + */ +#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 + * + * Modified from libtracefs to libtraceevent: + * Copyright (C) 2021, VMware, Steven Rostedt + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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); +} From patchwork Thu Dec 16 21:39:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682761 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E9859C4332F for ; Thu, 16 Dec 2021 21:40:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236820AbhLPVkA (ORCPT ); Thu, 16 Dec 2021 16:40:00 -0500 Received: from dfw.source.kernel.org ([139.178.84.217]:52964 "EHLO dfw.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241111AbhLPVkA (ORCPT ); Thu, 16 Dec 2021 16:40:00 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id EB13361F9C for ; Thu, 16 Dec 2021 21:39:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E4554C36AED; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003dW-SX; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 06/10] libtraceveent: Add testing of old dynamic string event layout Date: Thu, 16 Dec 2021 16:39:52 -0500 Message-Id: <20211216213956.13934-7-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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); } From patchwork Thu Dec 16 21:39:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682755 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5174C433FE for ; Thu, 16 Dec 2021 21:40:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241042AbhLPVkA (ORCPT ); Thu, 16 Dec 2021 16:40:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236820AbhLPVj7 (ORCPT ); Thu, 16 Dec 2021 16:39:59 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C08E0C061574 for ; Thu, 16 Dec 2021 13:39:59 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5E1DE61F98 for ; Thu, 16 Dec 2021 21:39:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BF38BC36AE7; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003dZ-TC; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 07/10] libraceevent: Add unit test to test print_fmt with dynamic strings Date: Thu, 16 Dec 2021 16:39:53 -0500 Message-Id: <20211216213956.13934-8-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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) From patchwork Thu Dec 16 21:39:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682763 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 926B5C4167B for ; Thu, 16 Dec 2021 21:40:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241298AbhLPVkC (ORCPT ); Thu, 16 Dec 2021 16:40:02 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:39056 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241571AbhLPVkB (ORCPT ); Thu, 16 Dec 2021 16:40:01 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 920C0B82653 for ; Thu, 16 Dec 2021 21:40:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D7B73C36AEC; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003dc-Tp; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 08/10] libtraceevent: Account for old dynamic string formats and honor size Date: Thu, 16 Dec 2021 16:39:54 -0500 Message-Id: <20211216213956.13934-9-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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) From patchwork Thu Dec 16 21:39:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682771 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF601C433EF for ; Thu, 16 Dec 2021 21:40:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241625AbhLPVkD (ORCPT ); Thu, 16 Dec 2021 16:40:03 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:39076 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241637AbhLPVkC (ORCPT ); Thu, 16 Dec 2021 16:40:02 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 348E0B82658 for ; Thu, 16 Dec 2021 21:40:01 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EFC97C36AEF; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003df-UR; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 09/10] libtraceevent: Replace tep_print_field() with tep_print_field_content() Date: Thu, 16 Dec 2021 16:39:55 -0500 Message-Id: <20211216213956.13934-10-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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 * *#include * -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); From patchwork Thu Dec 16 21:39:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 12682769 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1EF89C4167E for ; Thu, 16 Dec 2021 21:40:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241636AbhLPVkD (ORCPT ); Thu, 16 Dec 2021 16:40:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32828 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241646AbhLPVkC (ORCPT ); Thu, 16 Dec 2021 16:40:02 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A6C5C061574 for ; Thu, 16 Dec 2021 13:40:02 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A2EC5B82650 for ; Thu, 16 Dec 2021 21:40:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F1654C36AF1; Thu, 16 Dec 2021 21:39:58 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.95) (envelope-from ) id 1mxyTl-0003dr-V6; Thu, 16 Dec 2021 16:39:57 -0500 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: "Steven Rostedt (VMware)" Subject: [PATCH 10/10] libtraceevent: Have print_field_raw() handle old data layout Date: Thu, 16 Dec 2021 16:39:56 -0500 Message-Id: <20211216213956.13934-11-rostedt@goodmis.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211216213956.13934-1-rostedt@goodmis.org> References: <20211216213956.13934-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (VMware)" 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) --- 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;