Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp7285790rwb; Mon, 12 Dec 2022 12:34:34 -0800 (PST) X-Google-Smtp-Source: AA0mqf4rssclAxjOoIb5dxU8XvMU3YoLD4SP+chD+ehZ0vG8wXKYT9js7myba0L8c3rlQ8RFHNLX X-Received: by 2002:a05:6a21:c014:b0:ac:4f99:b8cd with SMTP id bm20-20020a056a21c01400b000ac4f99b8cdmr23190971pzc.8.1670877273821; Mon, 12 Dec 2022 12:34:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670877273; cv=none; d=google.com; s=arc-20160816; b=JYpK17pVk6h+MD95qPm6XFSenQUxfM1tnIVuB1Noq1jOJJL+fGgDTbdgvgy32qhD5T FmmbQYC2r3iYhcK1HVGSG5joCJQ2I66q99mI2j6c2/NRzvIyGbtj57GYBmHpV2m6KwHG QtIR9dmFm41Y+ui5ZW1HJuTmdlj87zL9DmsF8siYM5DPwmMvVazHOVLd+xCdWK+Z5cNN sjDiYMFLDHGCEATYGMIbYrE6bE+CURugf1jP1nsh+4/3SKxBIIyaoPovLc0tifzvXpIa 5eyPHtpylz271PikzqwLQXTgkTjfBZNCvQklA3sHe2SwzjLCaYDJggk9e7FZX9b8fAym AtlQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=MKKRjSoqXVY8mBwBTtCimn8oFll7dNhHSwaN3OVHCq8=; b=EnjW5oT81/QgExnEtVedMdDPGuUwM5BVIcShM+Ok1XApiiuaQlUlUiYg7TkgjAXLIm 6OoTD+lE4jcxyLBGR50eNyoBM2CHO7tosGAzuFQqql6u53vYKmuf9dWQmZUlzWJR7Hey zPebjtARI3TkkuxBxrw7iF6IT42kFmBObOgYc/iQqG9wijPL+zRP3EaQHvow/e7vPRQS StjVI2qGHGGfgzutpKS2WFG0njPvGLEh1/x/EOsoEfOkQolW+d/jsAlRCfhKb1pO3RK5 /UNYVJOR7mmy87R+xJ4Xl03oZMVmrsJ8EmJqZRaM8HQlCZST3am8KCPeOasodSKaz+eE 6Cmw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=fK5Ldm4f; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k6-20020a632406000000b00478c967a88bsi10360571pgk.379.2022.12.12.12.34.23; Mon, 12 Dec 2022 12:34:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=fK5Ldm4f; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232871AbiLLTxB (ORCPT + 74 others); Mon, 12 Dec 2022 14:53:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229497AbiLLTw6 (ORCPT ); Mon, 12 Dec 2022 14:52:58 -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 5F5602AD2; Mon, 12 Dec 2022 11:52:56 -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 339D3B80E05; Mon, 12 Dec 2022 19:52:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BF256C433EF; Mon, 12 Dec 2022 19:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1670874770; bh=v7+5fU/TDSWlgm6zLFF+T9b36jVmH+lVw8YHcQgS1qE=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=fK5Ldm4f7sZn1fJ1CLJIVoyrghEMH347KhE5x23deOzFumvl9hWYE3dOdUhR50mKZ oEKfoCKE3bymYcIXPywZIPsjBpZpTlAnvTqs34vlbF3wiL3lQlxZK3wqFUbL/jlRNv kqNUt8PbRHWXaHR0wjJ9DpRNxWdiJ+BfaYWK/s52bELWWyNjqvAsdaRvk+m+yfeq+G jaWAz8FU7+hwDDL3JbA3W6x6ojDvR/UvPca4l3cka1TkZVD3+wiWhljqRmPBF9qtKj s7sQpj0hYCkJ4vXa2Z87x6K9BPz9BcAY5FV1R9KuusM6g6I4xmUNrtshdAGJdYz2Uk 0zrKTPcrMSimQ== Received: by quaco.ghostprotocols.net (Postfix, from userid 1000) id 37D2940483; Mon, 12 Dec 2022 16:52:47 -0300 (-03) Date: Mon, 12 Dec 2022 16:52:47 -0300 From: Arnaldo Carvalho de Melo To: Ian Rogers Cc: Peter Zijlstra , Ingo Molnar , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Masami Hiramatsu , Steven Rostedt , Adrian Hunter , Leo Yan , Kan Liang , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Stephane Eranian Subject: Re: [PATCH v2 4/4] tools lib traceevent: Remove libtraceevent Message-ID: References: <20221130062935.2219247-1-irogers@google.com> <20221130062935.2219247-5-irogers@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20221130062935.2219247-5-irogers@google.com> X-Url: http://acmel.wordpress.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Em Tue, Nov 29, 2022 at 10:29:35PM -0800, Ian Rogers escreveu: > libtraceevent is now out-of-date and it is better to depend on the > system version. Remove this code that is no longer depended upon by > any builds. Thanks, applied and Added Steven's Acked-by. - Arnaldo > Signed-off-by: Ian Rogers > --- > tools/lib/traceevent/.gitignore | 4 - > tools/lib/traceevent/Build | 8 - > tools/lib/traceevent/Documentation/Makefile | 207 - > .../traceevent/Documentation/asciidoc.conf | 120 - > .../Documentation/libtraceevent-commands.txt | 153 - > .../Documentation/libtraceevent-cpus.txt | 77 - > .../libtraceevent-endian_read.txt | 78 - > .../libtraceevent-event_find.txt | 103 - > .../Documentation/libtraceevent-event_get.txt | 99 - > .../libtraceevent-event_list.txt | 122 - > .../libtraceevent-event_print.txt | 130 - > .../libtraceevent-field_find.txt | 118 - > .../libtraceevent-field_get_val.txt | 122 - > .../libtraceevent-field_print.txt | 126 - > .../libtraceevent-field_read.txt | 81 - > .../Documentation/libtraceevent-fields.txt | 105 - > .../libtraceevent-file_endian.txt | 91 - > .../Documentation/libtraceevent-filter.txt | 209 - > .../Documentation/libtraceevent-func_apis.txt | 183 - > .../Documentation/libtraceevent-func_find.txt | 88 - > .../Documentation/libtraceevent-handle.txt | 101 - > .../libtraceevent-header_page.txt | 102 - > .../libtraceevent-host_endian.txt | 104 - > .../Documentation/libtraceevent-long_size.txt | 78 - > .../Documentation/libtraceevent-page_size.txt | 82 - > .../libtraceevent-parse_event.txt | 90 - > .../libtraceevent-parse_head.txt | 82 - > .../Documentation/libtraceevent-plugins.txt | 122 - > .../libtraceevent-record_parse.txt | 137 - > .../libtraceevent-reg_event_handler.txt | 156 - > .../libtraceevent-reg_print_func.txt | 155 - > .../Documentation/libtraceevent-set_flag.txt | 104 - > .../Documentation/libtraceevent-strerror.txt | 85 - > .../Documentation/libtraceevent-tseq.txt | 158 - > .../Documentation/libtraceevent.txt | 192 - > .../traceevent/Documentation/manpage-1.72.xsl | 14 - > .../traceevent/Documentation/manpage-base.xsl | 35 - > .../Documentation/manpage-bold-literal.xsl | 17 - > .../Documentation/manpage-normal.xsl | 13 - > .../Documentation/manpage-suppress-sp.xsl | 21 - > tools/lib/traceevent/Makefile | 300 - > tools/lib/traceevent/event-parse-api.c | 333 - > tools/lib/traceevent/event-parse-local.h | 123 - > tools/lib/traceevent/event-parse.c | 7624 ----------------- > tools/lib/traceevent/event-parse.h | 750 -- > tools/lib/traceevent/event-plugin.c | 711 -- > tools/lib/traceevent/event-utils.h | 67 - > tools/lib/traceevent/kbuffer-parse.c | 809 -- > tools/lib/traceevent/kbuffer.h | 68 - > .../lib/traceevent/libtraceevent.pc.template | 10 - > tools/lib/traceevent/parse-filter.c | 2281 ----- > tools/lib/traceevent/parse-utils.c | 71 - > tools/lib/traceevent/plugins/Build | 12 - > tools/lib/traceevent/plugins/Makefile | 225 - > .../lib/traceevent/plugins/plugin_cfg80211.c | 43 - > .../lib/traceevent/plugins/plugin_function.c | 282 - > tools/lib/traceevent/plugins/plugin_futex.c | 123 - > tools/lib/traceevent/plugins/plugin_hrtimer.c | 74 - > tools/lib/traceevent/plugins/plugin_jbd2.c | 61 - > tools/lib/traceevent/plugins/plugin_kmem.c | 80 - > tools/lib/traceevent/plugins/plugin_kvm.c | 527 -- > .../lib/traceevent/plugins/plugin_mac80211.c | 88 - > .../traceevent/plugins/plugin_sched_switch.c | 146 - > tools/lib/traceevent/plugins/plugin_scsi.c | 434 - > tools/lib/traceevent/plugins/plugin_tlb.c | 66 - > tools/lib/traceevent/plugins/plugin_xen.c | 138 - > tools/lib/traceevent/tep_strerror.c | 53 - > tools/lib/traceevent/trace-seq.c | 249 - > tools/lib/traceevent/trace-seq.h | 55 - > 69 files changed, 19875 deletions(-) > delete mode 100644 tools/lib/traceevent/.gitignore > delete mode 100644 tools/lib/traceevent/Build > delete mode 100644 tools/lib/traceevent/Documentation/Makefile > delete mode 100644 tools/lib/traceevent/Documentation/asciidoc.conf > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-commands.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-cpus.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-event_find.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-event_get.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-event_list.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-event_print.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-field_find.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-field_print.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-field_read.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-fields.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-filter.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-func_find.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-handle.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-header_page.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-long_size.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-page_size.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-plugins.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-strerror.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-tseq.txt > delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent.txt > delete mode 100644 tools/lib/traceevent/Documentation/manpage-1.72.xsl > delete mode 100644 tools/lib/traceevent/Documentation/manpage-base.xsl > delete mode 100644 tools/lib/traceevent/Documentation/manpage-bold-literal.xsl > delete mode 100644 tools/lib/traceevent/Documentation/manpage-normal.xsl > delete mode 100644 tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl > delete mode 100644 tools/lib/traceevent/Makefile > delete mode 100644 tools/lib/traceevent/event-parse-api.c > delete mode 100644 tools/lib/traceevent/event-parse-local.h > delete mode 100644 tools/lib/traceevent/event-parse.c > delete mode 100644 tools/lib/traceevent/event-parse.h > delete mode 100644 tools/lib/traceevent/event-plugin.c > delete mode 100644 tools/lib/traceevent/event-utils.h > delete mode 100644 tools/lib/traceevent/kbuffer-parse.c > delete mode 100644 tools/lib/traceevent/kbuffer.h > delete mode 100644 tools/lib/traceevent/libtraceevent.pc.template > delete mode 100644 tools/lib/traceevent/parse-filter.c > delete mode 100644 tools/lib/traceevent/parse-utils.c > delete mode 100644 tools/lib/traceevent/plugins/Build > delete mode 100644 tools/lib/traceevent/plugins/Makefile > delete mode 100644 tools/lib/traceevent/plugins/plugin_cfg80211.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_function.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_futex.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_hrtimer.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_jbd2.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_kmem.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_kvm.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_mac80211.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_sched_switch.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_scsi.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_tlb.c > delete mode 100644 tools/lib/traceevent/plugins/plugin_xen.c > delete mode 100644 tools/lib/traceevent/tep_strerror.c > delete mode 100644 tools/lib/traceevent/trace-seq.c > delete mode 100644 tools/lib/traceevent/trace-seq.h > > diff --git a/tools/lib/traceevent/.gitignore b/tools/lib/traceevent/.gitignore > deleted file mode 100644 > index 7123c70b9ebc..000000000000 > --- a/tools/lib/traceevent/.gitignore > +++ /dev/null > @@ -1,4 +0,0 @@ > -# SPDX-License-Identifier: GPL-2.0-only > -TRACEEVENT-CFLAGS > -libtraceevent-dynamic-list > -libtraceevent.so.* > diff --git a/tools/lib/traceevent/Build b/tools/lib/traceevent/Build > deleted file mode 100644 > index f9a5d79578f5..000000000000 > --- a/tools/lib/traceevent/Build > +++ /dev/null > @@ -1,8 +0,0 @@ > -libtraceevent-y += event-parse.o > -libtraceevent-y += event-plugin.o > -libtraceevent-y += trace-seq.o > -libtraceevent-y += parse-filter.o > -libtraceevent-y += parse-utils.o > -libtraceevent-y += kbuffer-parse.o > -libtraceevent-y += tep_strerror.o > -libtraceevent-y += event-parse-api.o > diff --git a/tools/lib/traceevent/Documentation/Makefile b/tools/lib/traceevent/Documentation/Makefile > deleted file mode 100644 > index aa72ab96c3c1..000000000000 > --- a/tools/lib/traceevent/Documentation/Makefile > +++ /dev/null > @@ -1,207 +0,0 @@ > -include ../../../scripts/Makefile.include > -include ../../../scripts/utilities.mak > - > -# This Makefile and manpage XSL files were taken from tools/perf/Documentation > -# and modified for libtraceevent. > - > -MAN3_TXT= \ > - $(wildcard libtraceevent-*.txt) \ > - libtraceevent.txt > - > -MAN_TXT = $(MAN3_TXT) > -_MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT)) > -_MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT)) > -_DOC_MAN3=$(patsubst %.txt,%.3,$(MAN3_TXT)) > - > -MAN_XML=$(addprefix $(OUTPUT),$(_MAN_XML)) > -MAN_HTML=$(addprefix $(OUTPUT),$(_MAN_HTML)) > -DOC_MAN3=$(addprefix $(OUTPUT),$(_DOC_MAN3)) > - > -# Make the path relative to DESTDIR, not prefix > -ifndef DESTDIR > -prefix?=$(HOME) > -endif > -bindir?=$(prefix)/bin > -htmldir?=$(prefix)/share/doc/libtraceevent-doc > -pdfdir?=$(prefix)/share/doc/libtraceevent-doc > -mandir?=$(prefix)/share/man > -man3dir=$(mandir)/man3 > - > -ASCIIDOC=asciidoc > -ASCIIDOC_EXTRA = --unsafe -f asciidoc.conf > -ASCIIDOC_HTML = xhtml11 > -MANPAGE_XSL = manpage-normal.xsl > -XMLTO_EXTRA = > -INSTALL?=install > -RM ?= rm -f > - > -ifdef USE_ASCIIDOCTOR > -ASCIIDOC = asciidoctor > -ASCIIDOC_EXTRA = -a compat-mode > -ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions > -ASCIIDOC_EXTRA += -a mansource="libtraceevent" -a manmanual="libtraceevent Manual" > -ASCIIDOC_HTML = xhtml5 > -endif > - > -XMLTO=xmlto > - > -_tmp_tool_path := $(call get-executable,$(ASCIIDOC)) > -ifeq ($(_tmp_tool_path),) > - missing_tools = $(ASCIIDOC) > -endif > - > -ifndef USE_ASCIIDOCTOR > -_tmp_tool_path := $(call get-executable,$(XMLTO)) > -ifeq ($(_tmp_tool_path),) > - missing_tools += $(XMLTO) > -endif > -endif > - > -# > -# For asciidoc ... > -# -7.1.2, no extra settings are needed. > -# 8.0-, set ASCIIDOC8. > -# > - > -# > -# For docbook-xsl ... > -# -1.68.1, set ASCIIDOC_NO_ROFF? (based on changelog from 1.73.0) > -# 1.69.0, no extra settings are needed? > -# 1.69.1-1.71.0, set DOCBOOK_SUPPRESS_SP? > -# 1.71.1, no extra settings are needed? > -# 1.72.0, set DOCBOOK_XSL_172. > -# 1.73.0-, set ASCIIDOC_NO_ROFF > -# > - > -# > -# If you had been using DOCBOOK_XSL_172 in an attempt to get rid > -# of 'the ".ft C" problem' in your generated manpages, and you > -# instead ended up with weird characters around callouts, try > -# using ASCIIDOC_NO_ROFF instead (it works fine with ASCIIDOC8). > -# > - > -ifdef ASCIIDOC8 > -ASCIIDOC_EXTRA += -a asciidoc7compatible > -endif > -ifdef DOCBOOK_XSL_172 > -ASCIIDOC_EXTRA += -a libtraceevent-asciidoc-no-roff > -MANPAGE_XSL = manpage-1.72.xsl > -else > - ifdef ASCIIDOC_NO_ROFF > - # docbook-xsl after 1.72 needs the regular XSL, but will not > - # pass-thru raw roff codes from asciidoc.conf, so turn them off. > - ASCIIDOC_EXTRA += -a libtraceevent-asciidoc-no-roff > - endif > -endif > -ifdef MAN_BOLD_LITERAL > -XMLTO_EXTRA += -m manpage-bold-literal.xsl > -endif > -ifdef DOCBOOK_SUPPRESS_SP > -XMLTO_EXTRA += -m manpage-suppress-sp.xsl > -endif > - > -SHELL_PATH ?= $(SHELL) > -# Shell quote; > -SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) > - > -DESTDIR ?= > -DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' > - > -export DESTDIR DESTDIR_SQ > - > -# > -# Please note that there is a minor bug in asciidoc. > -# The version after 6.0.3 _will_ include the patch found here: > -# http://marc.theaimsgroup.com/?l=libtraceevent&m=111558757202243&w=2 > -# > -# Until that version is released you may have to apply the patch > -# yourself - yes, all 6 characters of it! > -# > -QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir > -QUIET_SUBDIR1 = > - > -ifneq ($(findstring $(MAKEFLAGS),w),w) > -PRINT_DIR = --no-print-directory > -else # "make -w" > -NO_SUBDIR = : > -endif > - > -ifneq ($(findstring $(MAKEFLAGS),s),s) > -ifneq ($(V),1) > - QUIET_ASCIIDOC = @echo ' ASCIIDOC '$@; > - QUIET_XMLTO = @echo ' XMLTO '$@; > - QUIET_SUBDIR0 = +@subdir= > - QUIET_SUBDIR1 = ;$(NO_SUBDIR) \ > - echo ' SUBDIR ' $$subdir; \ > - $(MAKE) $(PRINT_DIR) -C $$subdir > - export V > -endif > -endif > - > -all: html man > - > -man: man3 > -man3: $(DOC_MAN3) > - > -html: $(MAN_HTML) > - > -$(MAN_HTML) $(DOC_MAN3): asciidoc.conf > - > -install: install-man > - > -check-man-tools: > -ifdef missing_tools > - $(error "You need to install $(missing_tools) for man pages") > -endif > - > -do-install-man: man > - $(call QUIET_INSTALL, Documentation-man) \ > - $(INSTALL) -d -m 755 $(DESTDIR)$(man3dir); \ > - $(INSTALL) -m 644 $(DOC_MAN3) $(DESTDIR)$(man3dir); > - > -install-man: check-man-tools man do-install-man > - > -uninstall: uninstall-man > - > -uninstall-man: > - $(call QUIET_UNINST, Documentation-man) \ > - $(Q)$(RM) $(addprefix $(DESTDIR)$(man3dir)/,$(DOC_MAN3)) > - > - > -ifdef missing_tools > - DO_INSTALL_MAN = $(warning Please install $(missing_tools) to have the man pages installed) > -else > - DO_INSTALL_MAN = do-install-man > -endif > - > -CLEAN_FILES = \ > - $(MAN_XML) $(addsuffix +,$(MAN_XML)) \ > - $(MAN_HTML) $(addsuffix +,$(MAN_HTML)) \ > - $(DOC_MAN3) *.3 > - > -clean: > - $(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES) > - > -ifdef USE_ASCIIDOCTOR > -$(OUTPUT)%.3 : $(OUTPUT)%.txt > - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ > - $(ASCIIDOC) -b manpage -d manpage \ > - $(ASCIIDOC_EXTRA) -alibtraceevent_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ > - mv $@+ $@ > -endif > - > -$(OUTPUT)%.3 : $(OUTPUT)%.xml > - $(QUIET_XMLTO)$(RM) $@ && \ > - $(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< > - > -$(OUTPUT)%.xml : %.txt > - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ > - $(ASCIIDOC) -b docbook -d manpage \ > - $(ASCIIDOC_EXTRA) -alibtraceevent_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ > - mv $@+ $@ > - > -$(MAN_HTML): $(OUTPUT)%.html : %.txt > - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ > - $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage \ > - $(ASCIIDOC_EXTRA) -aperf_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ > - mv $@+ $@ > diff --git a/tools/lib/traceevent/Documentation/asciidoc.conf b/tools/lib/traceevent/Documentation/asciidoc.conf > deleted file mode 100644 > index 07595717f06e..000000000000 > --- a/tools/lib/traceevent/Documentation/asciidoc.conf > +++ /dev/null > @@ -1,120 +0,0 @@ > -## linktep: macro > -# > -# Usage: linktep:command[manpage-section] > -# > -# Note, {0} is the manpage section, while {target} is the command. > -# > -# Show TEP link as: (
); if section is defined, else just show > -# the command. > - > -[macros] > -(?su)[\\]?(?Plinktep):(?P\S*?)\[(?P.*?)\]= > - > -[attributes] > -asterisk=* > -plus=+ > -caret=^ > -startsb=[ > -endsb=] > -tilde=~ > - > -ifdef::backend-docbook[] > -[linktep-inlinemacro] > -{0%{target}} > -{0#} > -{0#{target}{0}} > -{0#} > -endif::backend-docbook[] > - > -ifdef::backend-docbook[] > -ifndef::tep-asciidoc-no-roff[] > -# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this. > -# v1.72 breaks with this because it replaces dots not in roff requests. > -[listingblock] > -{title} > - > -ifdef::doctype-manpage[] > - .ft C > -endif::doctype-manpage[] > -| > -ifdef::doctype-manpage[] > - .ft > -endif::doctype-manpage[] > - > -{title#} > -endif::tep-asciidoc-no-roff[] > - > -ifdef::tep-asciidoc-no-roff[] > -ifdef::doctype-manpage[] > -# The following two small workarounds insert a simple paragraph after screen > -[listingblock] > -{title} > - > -| > - > -{title#} > - > -[verseblock] > -{title} > -{title%} > -{title#} > -| > - > -{title#} > -{title%} > -endif::doctype-manpage[] > -endif::tep-asciidoc-no-roff[] > -endif::backend-docbook[] > - > -ifdef::doctype-manpage[] > -ifdef::backend-docbook[] > -[header] > -template::[header-declarations] > - > - > -{mantitle} > -{manvolnum} > -libtraceevent > -{libtraceevent_version} > -libtraceevent Manual > - > - > - {manname1} > - {manname2} > - {manname3} > - {manname4} > - {manname5} > - {manname6} > - {manname7} > - {manname8} > - {manname9} > - {manname10} > - {manname11} > - {manname12} > - {manname13} > - {manname14} > - {manname15} > - {manname16} > - {manname17} > - {manname18} > - {manname19} > - {manname20} > - {manname21} > - {manname22} > - {manname23} > - {manname24} > - {manname25} > - {manname26} > - {manname27} > - {manname28} > - {manname29} > - {manname30} > - {manpurpose} > - > -endif::backend-docbook[] > -endif::doctype-manpage[] > - > -ifdef::backend-xhtml11[] > -[linktep-inlinemacro] > -{target}{0?({0})} > -endif::backend-xhtml11[] > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-commands.txt b/tools/lib/traceevent/Documentation/libtraceevent-commands.txt > deleted file mode 100644 > index bec552001f8e..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-commands.txt > +++ /dev/null > @@ -1,153 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_register_comm, tep_override_comm, tep_pid_is_registered, > -tep_data_comm_from_pid, tep_data_pid_from_comm, tep_cmdline_pid - > -Manage pid to process name mappings. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -int *tep_register_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); > -int *tep_override_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); > -bool *tep_is_pid_registered*(struct tep_handle pass:[*]_tep_, int _pid_); > -const char pass:[*]*tep_data_comm_from_pid*(struct tep_handle pass:[*]_pevent_, int _pid_); > -struct cmdline pass:[*]*tep_data_pid_from_comm*(struct tep_handle pass:[*]_pevent_, const char pass:[*]_comm_, struct cmdline pass:[*]_next_); > -int *tep_cmdline_pid*(struct tep_handle pass:[*]_pevent_, struct cmdline pass:[*]_cmdline_); > --- > - > -DESCRIPTION > ------------ > -These functions can be used to handle the mapping between pid and process name. > -The library builds a cache of these mappings, which is used to display the name > -of the process, instead of its pid. This information can be retrieved from > -tracefs/saved_cmdlines file. > - > -The _tep_register_comm()_ function registers a _pid_ / process name mapping. > -If a command with the same _pid_ is already registered, an error is returned. > -The _pid_ argument is the process ID, the _comm_ argument is the process name, > -_tep_ is the event context. The _comm_ is duplicated internally. > - > -The _tep_override_comm()_ function registers a _pid_ / process name mapping. > -If a process with the same pid is already registered, the process name string is > -udapted with the new one. The _pid_ argument is the process ID, the _comm_ > -argument is the process name, _tep_ is the event context. The _comm_ is > -duplicated internally. > - > -The _tep_is_pid_registered()_ function checks if a pid has a process name > -mapping registered. The _pid_ argument is the process ID, _tep_ is the event > -context. > - > -The _tep_data_comm_from_pid()_ function returns the process name for a given > -pid. The _pid_ argument is the process ID, _tep_ is the event context. > -The returned string should not be freed, but will be freed when the _tep_ > -handler is closed. > - > -The _tep_data_pid_from_comm()_ function returns a pid for a given process name. > -The _comm_ argument is the process name, _tep_ is the event context. > -The argument _next_ is the cmdline structure to search for the next pid. > -As there may be more than one pid for a given process, the result of this call > -can be passed back into a recurring call in the _next_ parameter, to search for > -the next pid. If _next_ is NULL, it will return the first pid associated with > -the _comm_. The function performs a linear search, so it may be slow. > - > -The _tep_cmdline_pid()_ function returns the pid associated with a given > -_cmdline_. The _tep_ argument is the event context. > - > -RETURN VALUE > ------------- > -_tep_register_comm()_ function returns 0 on success. In case of an error -1 is > -returned and errno is set to indicate the cause of the problem: ENOMEM, if there > -is not enough memory to duplicate the _comm_ or EEXIST if a mapping for this > -_pid_ is already registered. > - > -_tep_override_comm()_ function returns 0 on success. In case of an error -1 is > -returned and errno is set to indicate the cause of the problem: ENOMEM, if there > -is not enough memory to duplicate the _comm_. > - > -_tep_is_pid_registered()_ function returns true if the _pid_ has a process name > -mapped to it, false otherwise. > - > -_tep_data_comm_from_pid()_ function returns the process name as string, or the > -string "<...>" if there is no mapping for the given pid. > - > -_tep_data_pid_from_comm()_ function returns a pointer to a struct cmdline, that > -holds a pid for a given process, or NULL if none is found. This result can be > -passed back into a recurring call as the _next_ parameter of the function. > - > -_tep_cmdline_pid()_ functions returns the pid for the give cmdline. If _cmdline_ > - is NULL, then -1 is returned. > - > -EXAMPLE > -------- > -The following example registers pid for command "ls", in context of event _tep_ > -and performs various searches for pid / process name mappings: > -[source,c] > --- > -#include > -... > -int ret; > -int ls_pid = 1021; > -struct tep_handle *tep = tep_alloc(); > -... > - ret = tep_register_comm(tep, "ls", ls_pid); > - if (ret != 0 && errno == EEXIST) > - ret = tep_override_comm(tep, "ls", ls_pid); > - if (ret != 0) { > - /* Failed to register pid / command mapping */ > - } > -... > - if (tep_is_pid_registered(tep, ls_pid) == 0) { > - /* Command mapping for ls_pid is not registered */ > - } > -... > - const char *comm = tep_data_comm_from_pid(tep, ls_pid); > - if (comm) { > - /* Found process name for ls_pid */ > - } > -... > - int pid; > - struct cmdline *cmd = tep_data_pid_from_comm(tep, "ls", NULL); > - while (cmd) { > - pid = tep_cmdline_pid(tep, cmd); > - /* Found pid for process "ls" */ > - cmd = tep_data_pid_from_comm(tep, "ls", cmd); > - } > --- > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-cpus.txt b/tools/lib/traceevent/Documentation/libtraceevent-cpus.txt > deleted file mode 100644 > index 5ad70e43b752..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-cpus.txt > +++ /dev/null > @@ -1,77 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_get_cpus, tep_set_cpus - Get / set the number of CPUs, which have a tracing > -buffer representing it. Note, the buffer may be empty. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -int *tep_get_cpus*(struct tep_handle pass:[*]_tep_); > -void *tep_set_cpus*(struct tep_handle pass:[*]_tep_, int _cpus_); > --- > - > -DESCRIPTION > ------------ > -The _tep_get_cpus()_ function gets the number of CPUs, which have a tracing > -buffer representing it. The _tep_ argument is trace event parser context. > - > -The _tep_set_cpus()_ function sets the number of CPUs, which have a tracing > -buffer representing it. The _tep_ argument is trace event parser context. > -The _cpu_ argument is the number of CPUs with tracing data. > - > -RETURN VALUE > ------------- > -The _tep_get_cpus()_ functions returns the number of CPUs, which have tracing > -data recorded. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > - tep_set_cpus(tep, 5); > -... > - printf("We have tracing data for %d CPUs", tep_get_cpus(tep)); > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt b/tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt > deleted file mode 100644 > index e64851b6e189..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt > +++ /dev/null > @@ -1,78 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_read_number - Reads a number from raw data. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, const void pass:[*]_ptr_, int _size_); > --- > - > -DESCRIPTION > ------------ > -The _tep_read_number()_ function reads an integer from raw data, taking into > -account the endianness of the raw data and the current host. The _tep_ argument > -is the trace event parser context. The _ptr_ is a pointer to the raw data, where > -the integer is, and the _size_ is the size of the integer. > - > -RETURN VALUE > ------------- > -The _tep_read_number()_ function returns the integer in the byte order of > -the current host. In case of an error, 0 is returned. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -void process_record(struct tep_record *record) > -{ > - int offset = 24; > - int data = tep_read_number(tep, record->data + offset, 4); > - > - /* Read the 4 bytes at the offset 24 of data as an integer */ > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_find.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_find.txt > deleted file mode 100644 > index 7bc062c9f76f..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-event_find.txt > +++ /dev/null > @@ -1,103 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_find_event,tep_find_event_by_name,tep_find_event_by_record - > -Find events by given key. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_); > -struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_); > -struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_); > --- > - > -DESCRIPTION > ------------ > -This set of functions can be used to search for an event, based on a given > -criteria. All functions require a pointer to a _tep_, trace event parser > -context. > - > -The _tep_find_event()_ function searches for an event by given event _id_. The > -event ID is assigned dynamically and can be viewed in event's format file, > -"ID" field. > - > -The tep_find_event_by_name()_ function searches for an event by given > -event _name_, under the system _sys_. If the _sys_ is NULL (not specified), > -the first event with _name_ is returned. > - > -The tep_find_event_by_record()_ function searches for an event from a given > -_record_. > - > -RETURN VALUE > ------------- > -All these functions return a pointer to the found event, or NULL if there is no > -such event. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -struct tep_event *event; > - > -event = tep_find_event(tep, 1857); > -if (event == NULL) { > - /* There is no event with ID 1857 */ > -} > - > -event = tep_find_event_by_name(tep, "kvm", "kvm_exit"); > -if (event == NULL) { > - /* There is no kvm_exit event, from kvm system */ > -} > - > -void event_from_record(struct tep_record *record) > -{ > - struct tep_event *event = tep_find_event_by_record(tep, record); > - if (event == NULL) { > - /* There is no event from given record */ > - } > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_get.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_get.txt > deleted file mode 100644 > index 6525092fc417..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-event_get.txt > +++ /dev/null > @@ -1,99 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_get_event, tep_get_first_event, tep_get_events_count - Access events. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -struct tep_event pass:[*]*tep_get_event*(struct tep_handle pass:[*]_tep_, int _index_); > -struct tep_event pass:[*]*tep_get_first_event*(struct tep_handle pass:[*]_tep_); > -int *tep_get_events_count*(struct tep_handle pass:[*]_tep_); > --- > - > -DESCRIPTION > ------------ > -The _tep_get_event()_ function returns a pointer to event at the given _index_. > -The _tep_ argument is trace event parser context, the _index_ is the index of > -the requested event. > - > -The _tep_get_first_event()_ function returns a pointer to the first event. > -As events are stored in an array, this function returns the pointer to the > -beginning of the array. The _tep_ argument is trace event parser context. > - > -The _tep_get_events_count()_ function returns the number of the events > -in the array. The _tep_ argument is trace event parser context. > - > -RETURN VALUE > ------------- > -The _tep_get_event()_ returns a pointer to the event located at _index_. > -NULL is returned in case of error, in case there are no events or _index_ is > -out of range. > - > -The _tep_get_first_event()_ returns a pointer to the first event. NULL is > -returned in case of error, or in case there are no events. > - > -The _tep_get_events_count()_ returns the number of the events. 0 is > -returned in case of error, or in case there are no events. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -int i,count = tep_get_events_count(tep); > -struct tep_event *event, *events = tep_get_first_event(tep); > - > -if (events == NULL) { > - /* There are no events */ > -} else { > - for (i = 0; i < count; i++) { > - event = (events+i); > - /* process events[i] */ > - } > - > - /* Get the last event */ > - event = tep_get_event(tep, count-1); > -} > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_list.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_list.txt > deleted file mode 100644 > index fba350e5a4cb..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-event_list.txt > +++ /dev/null > @@ -1,122 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_list_events, tep_list_events_copy - > -Get list of events, sorted by given criteria. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -enum *tep_event_sort_type* { > - _TEP_EVENT_SORT_ID_, > - _TEP_EVENT_SORT_NAME_, > - _TEP_EVENT_SORT_SYSTEM_, > -}; > - > -struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); > -struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); > --- > - > -DESCRIPTION > ------------ > -The _tep_list_events()_ function returns an array of pointers to the events, > -sorted by the _sort_type_ criteria. The last element of the array is NULL. > -The returned memory must not be freed, it is managed by the library. > -The function is not thread safe. The _tep_ argument is trace event parser > -context. The _sort_type_ argument is the required sort criteria: > -[verse] > --- > - _TEP_EVENT_SORT_ID_ - sort by the event ID. > - _TEP_EVENT_SORT_NAME_ - sort by the event (name, system, id) triplet. > - _TEP_EVENT_SORT_SYSTEM_ - sort by the event (system, name, id) triplet. > --- > - > -The _tep_list_events_copy()_ is a thread safe version of _tep_list_events()_. > -It has the same behavior, but the returned array is allocated internally and > -must be freed by the caller. Note that the content of the array must not be > -freed (see the EXAMPLE below). > - > -RETURN VALUE > ------------- > -The _tep_list_events()_ function returns an array of pointers to events. > -In case of an error, NULL is returned. The returned array must not be freed, > -it is managed by the library. > - > -The _tep_list_events_copy()_ function returns an array of pointers to events. > -In case of an error, NULL is returned. The returned array must be freed by > -the caller. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -int i; > -struct tep_event_format **events; > - > -i=0; > -events = tep_list_events(tep, TEP_EVENT_SORT_ID); > -if (events == NULL) { > - /* Failed to get the events, sorted by ID */ > -} else { > - while(events[i]) { > - /* walk through the list of the events, sorted by ID */ > - i++; > - } > -} > - > -i=0; > -events = tep_list_events_copy(tep, TEP_EVENT_SORT_NAME); > -if (events == NULL) { > - /* Failed to get the events, sorted by name */ > -} else { > - while(events[i]) { > - /* walk through the list of the events, sorted by name */ > - i++; > - } > - free(events); > -} > - > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_print.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_print.txt > deleted file mode 100644 > index 2c6a61811118..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-event_print.txt > +++ /dev/null > @@ -1,130 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_print_event - Writes event information into a trace sequence. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > -*#include * > - > -void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seqpass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._) > --- > - > -DESCRIPTION > ------------ > - > -The _tep_print_event()_ function parses the event information of the given > -_record_ and writes it into the trace sequence _s_, according to the format > -string _fmt_. The desired information is specified after the format string. > -The _fmt_ is printf-like format string, following arguments are supported: > -[verse] > --- > - TEP_PRINT_PID, "%d" - PID of the event. > - TEP_PRINT_CPU, "%d" - Event CPU. > - TEP_PRINT_COMM, "%s" - Event command string. > - TEP_PRINT_NAME, "%s" - Event name. > - TEP_PRINT_LATENCY, "%s" - Latency of the event. It prints 4 or more > - fields - interrupt state, scheduling state, > - current context, and preemption count. > - Field 1 is the interrupt enabled state: > - d : Interrupts are disabled > - . : Interrupts are enabled > - X : The architecture does not support this > - information > - Field 2 is the "need resched" state. > - N : The task is set to call the scheduler when > - possible, as another higher priority task > - may need to be scheduled in. > - . : The task is not set to call the scheduler. > - Field 3 is the context state. > - . : Normal context > - s : Soft interrupt context > - h : Hard interrupt context > - H : Hard interrupt context which triggered > - during soft interrupt context. > - z : NMI context > - Z : NMI context which triggered during hard > - interrupt context > - Field 4 is the preemption count. > - . : The preempt count is zero. > - On preemptible kernels (where the task can be scheduled > - out in arbitrary locations while in kernel context), the > - preempt count, when non zero, will prevent the kernel > - from scheduling out the current task. The preempt count > - number is displayed when it is not zero. > - Depending on the kernel, it may show other fields > - (lock depth, or migration disabled, which are unique to > - specialized kernels). > - TEP_PRINT_TIME, %d - event time stamp. A divisor and precision can be > - specified as part of this format string: > - "%precision.divisord". Example: > - "%3.1000d" - divide the time by 1000 and print the first > - 3 digits before the dot. Thus, the time stamp > - "123456000" will be printed as "123.456" > - TEP_PRINT_INFO, "%s" - event information. > - TEP_PRINT_INFO_RAW, "%s" - event information, in raw format. > - > --- > -EXAMPLE > -------- > -[source,c] > --- > -#include > -#include > -... > -struct trace_seq seq; > -trace_seq_init(&seq); > -struct tep_handle *tep = tep_alloc(); > -... > -void print_my_event(struct tep_record *record) > -{ > - trace_seq_reset(&seq); > - tep_print_event(tep, s, record, "%16s-%-5d [%03d] %s %6.1000d %s %s", > - TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU, > - TEP_PRINT_LATENCY, TEP_PRINT_TIME, TEP_PRINT_NAME, > - TEP_PRINT_INFO); > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*trace-seq.h* > - Header file to include in order to have access to trace sequences related APIs. > - Trace sequences are used to allow a function to call several other functions > - to create a string of data to use. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_find.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_find.txt > deleted file mode 100644 > index 0896af5b9eff..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-field_find.txt > +++ /dev/null > @@ -1,118 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_find_common_field, tep_find_field, tep_find_any_field - > -Search for a field in an event. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -struct tep_format_field pass:[*]*tep_find_common_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); > -struct tep_format_field pass:[*]*tep_find_field*(struct tep_event_ormat pass:[*]_event_, const char pass:[*]_name_); > -struct tep_format_field pass:[*]*tep_find_any_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); > --- > - > -DESCRIPTION > ------------ > -These functions search for a field with given name in an event. The field > -returned can be used to find the field content from within a data record. > - > -The _tep_find_common_field()_ function searches for a common field with _name_ > -in the _event_. > - > -The _tep_find_field()_ function searches for an event specific field with > -_name_ in the _event_. > - > -The _tep_find_any_field()_ function searches for any field with _name_ in the > -_event_. > - > -RETURN VALUE > ------------- > -The _tep_find_common_field(), _tep_find_field()_ and _tep_find_any_field()_ > -functions return a pointer to the found field, or NULL in case there is no field > -with the requested name. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -void get_htimer_info(struct tep_handle *tep, struct tep_record *record) > -{ > - struct tep_format_field *field; > - struct tep_event *event; > - long long softexpires; > - int mode; > - int pid; > - > - event = tep_find_event_by_name(tep, "timer", "hrtimer_start"); > - > - field = tep_find_common_field(event, "common_pid"); > - if (field == NULL) { > - /* Cannot find "common_pid" field in the event */ > - } else { > - /* Get pid from the data record */ > - pid = tep_read_number(tep, record->data + field->offset, > - field->size); > - } > - > - field = tep_find_field(event, "softexpires"); > - if (field == NULL) { > - /* Cannot find "softexpires" event specific field in the event */ > - } else { > - /* Get softexpires parameter from the data record */ > - softexpires = tep_read_number(tep, record->data + field->offset, > - field->size); > - } > - > - field = tep_find_any_field(event, "mode"); > - if (field == NULL) { > - /* Cannot find "mode" field in the event */ > - } else > - { > - /* Get mode parameter from the data record */ > - mode = tep_read_number(tep, record->data + field->offset, > - field->size); > - } > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt > deleted file mode 100644 > index 6324f0d48aeb..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt > +++ /dev/null > @@ -1,122 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_get_any_field_val, tep_get_common_field_val, tep_get_field_val, > -tep_get_field_raw - Get value of a field. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > -*#include * > - > -int *tep_get_any_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); > -int *tep_get_common_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); > -int *tep_get_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); > -void pass:[*]*tep_get_field_raw*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int pass:[*]_len_, int _err_); > --- > - > -DESCRIPTION > ------------ > -These functions can be used to find a field and retrieve its value. > - > -The _tep_get_any_field_val()_ function searches in the _record_ for a field > -with _name_, part of the _event_. If the field is found, its value is stored in > -_val_. If there is an error and _err_ is not zero, then an error string is > -written into _s_. > - > -The _tep_get_common_field_val()_ function does the same as > -_tep_get_any_field_val()_, but searches only in the common fields. This works > -for any event as all events include the common fields. > - > -The _tep_get_field_val()_ function does the same as _tep_get_any_field_val()_, > -but searches only in the event specific fields. > - > -The _tep_get_field_raw()_ function searches in the _record_ for a field with > -_name_, part of the _event_. If the field is found, a pointer to where the field > -exists in the record's raw data is returned. The size of the data is stored in > -_len_. If there is an error and _err_ is not zero, then an error string is > -written into _s_. > - > -RETURN VALUE > ------------- > -The _tep_get_any_field_val()_, _tep_get_common_field_val()_ and > -_tep_get_field_val()_ functions return 0 on success, or -1 in case of an error. > - > -The _tep_get_field_raw()_ function returns a pointer to field's raw data, and > -places the length of this data in _len_. In case of an error NULL is returned. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -struct tep_event *event = tep_find_event_by_name(tep, "kvm", "kvm_exit"); > -... > -void process_record(struct tep_record *record) > -{ > - int len; > - char *comm; > - struct tep_event_format *event; > - unsigned long long val; > - > - event = tep_find_event_by_record(pevent, record); > - if (event != NULL) { > - if (tep_get_common_field_val(NULL, event, "common_type", > - record, &val, 0) == 0) { > - /* Got the value of common type field */ > - } > - if (tep_get_field_val(NULL, event, "pid", record, &val, 0) == 0) { > - /* Got the value of pid specific field */ > - } > - comm = tep_get_field_raw(NULL, event, "comm", record, &len, 0); > - if (comm != NULL) { > - /* Got a pointer to the comm event specific field */ > - } > - } > -} > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*trace-seq.h* > - Header file to include in order to have access to trace sequences > - related APIs. Trace sequences are used to allow a function to call > - several other functions to create a string of data to use. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_print.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_print.txt > deleted file mode 100644 > index 9a9df98ac44d..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-field_print.txt > +++ /dev/null > @@ -1,126 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_print_field, tep_print_fields, tep_print_num_field, tep_print_func_field - > -Print the field content. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > -*#include * > - > -void *tep_print_field*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, 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_); > --- > - > -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 _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 > -value according to the field's type: > -[verse] > --- > -"field1_name=field1_value field2_name=field2_value ..." > --- > -It iterates all fields of the _event_, and calls _tep_print_field()_ for each of > -them. > - > -The _tep_print_num_field()_ function prints a numeric field with given format > -string. A search is performed in the _event_ for a field with _name_. If such > -field is found, its value is extracted from the _record_ and is printed in the > -_s_, according to the given format string _fmt_. If the argument _err_ is > -non-zero, and an error occures - it is printed in the _s_. > - > -The _tep_print_func_field()_ function prints a function field with given format > -string. A search is performed in the _event_ for a field with _name_. If such > -field is found, its value is extracted from the _record_. The value is assumed > -to be a function address, and a search is perform to find the name of this > -function. The function name (if found) and its address are printed in the _s_, > -according to the given format string _fmt_. If the argument _err_ is non-zero, > -and an error occures - it is printed in _s_. > - > -RETURN VALUE > ------------- > -The _tep_print_num_field()_ and _tep_print_func_field()_ functions return 1 > -on success, -1 in case of an error or 0 if the print buffer _s_ is full. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -struct trace_seq seq; > -trace_seq_init(&seq); > -struct tep_event *event = tep_find_event_by_name(tep, "timer", "hrtimer_start"); > -... > -void process_record(struct tep_record *record) > -{ > - struct tep_format_field *field_pid = tep_find_common_field(event, "common_pid"); > - > - trace_seq_reset(&seq); > - > - /* Print the value of "common_pid" */ > - tep_print_field(&seq, record->data, field_pid); > - > - /* Print all fields of the "hrtimer_start" event */ > - tep_print_fields(&seq, record->data, record->size, event); > - > - /* Print the value of "expires" field with custom format string */ > - tep_print_num_field(&seq, " timer expires in %llu ", event, "expires", record, 0); > - > - /* Print the address and the name of "function" field with custom format string */ > - tep_print_func_field(&seq, " timer function is %s ", event, "function", record, 0); > - } > - ... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*trace-seq.h* > - Header file to include in order to have access to trace sequences related APIs. > - Trace sequences are used to allow a function to call several other functions > - to create a string of data to use. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_read.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_read.txt > deleted file mode 100644 > index 64e9e25d3fd9..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-field_read.txt > +++ /dev/null > @@ -1,81 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_read_number_field - Reads a number from raw data. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -int *tep_read_number_field*(struct tep_format_field pass:[*]_field_, const void pass:[*]_data_, unsigned long long pass:[*]_value_); > --- > - > -DESCRIPTION > ------------ > -The _tep_read_number_field()_ function reads the value of the _field_ from the > -raw _data_ and stores it in the _value_. The function sets the _value_ according > -to the endianness of the raw data and the current machine and stores it in > -_value_. > - > -RETURN VALUE > ------------- > -The _tep_read_number_field()_ function retunrs 0 in case of success, or -1 in > -case of an error. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -struct tep_event *event = tep_find_event_by_name(tep, "timer", "hrtimer_start"); > -... > -void process_record(struct tep_record *record) > -{ > - unsigned long long pid; > - struct tep_format_field *field_pid = tep_find_common_field(event, "common_pid"); > - > - if (tep_read_number_field(field_pid, record->data, &pid) != 0) { > - /* Failed to get "common_pid" value */ > - } > -} > -... > --- > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-fields.txt b/tools/lib/traceevent/Documentation/libtraceevent-fields.txt > deleted file mode 100644 > index 1ccb531d5114..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-fields.txt > +++ /dev/null > @@ -1,105 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_event_common_fields, tep_event_fields - Get a list of fields for an event. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -struct tep_format_field pass:[*]pass:[*]*tep_event_common_fields*(struct tep_event pass:[*]_event_); > -struct tep_format_field pass:[*]pass:[*]*tep_event_fields*(struct tep_event pass:[*]_event_); > --- > - > -DESCRIPTION > ------------ > -The _tep_event_common_fields()_ function returns an array of pointers to common > -fields for the _event_. The array is allocated in the function and must be freed > -by free(). The last element of the array is NULL. > - > -The _tep_event_fields()_ function returns an array of pointers to event specific > -fields for the _event_. The array is allocated in the function and must be freed > -by free(). The last element of the array is NULL. > - > -RETURN VALUE > ------------- > -Both _tep_event_common_fields()_ and _tep_event_fields()_ functions return > -an array of pointers to tep_format_field structures in case of success, or > -NULL in case of an error. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -int i; > -struct tep_format_field **fields; > -struct tep_event *event = tep_find_event_by_name(tep, "kvm", "kvm_exit"); > -if (event != NULL) { > - fields = tep_event_common_fields(event); > - if (fields != NULL) { > - i = 0; > - while (fields[i]) { > - /* > - walk through the list of the common fields > - of the kvm_exit event > - */ > - i++; > - } > - free(fields); > - } > - fields = tep_event_fields(event); > - if (fields != NULL) { > - i = 0; > - while (fields[i]) { > - /* > - walk through the list of the event specific > - fields of the kvm_exit event > - */ > - i++; > - } > - free(fields); > - } > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt b/tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt > deleted file mode 100644 > index f401ad311047..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt > +++ /dev/null > @@ -1,91 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_is_file_bigendian, tep_set_file_bigendian - Get / set the endianness of the > -raw data being accessed by the tep handler. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -enum *tep_endian* { > - TEP_LITTLE_ENDIAN = 0, > - TEP_BIG_ENDIAN > -}; > - > -bool *tep_is_file_bigendian*(struct tep_handle pass:[*]_tep_); > -void *tep_set_file_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); > - > --- > -DESCRIPTION > ------------ > -The _tep_is_file_bigendian()_ function gets the endianness of the raw data, > -being accessed by the tep handler. The _tep_ argument is trace event parser > -context. > - > -The _tep_set_file_bigendian()_ function sets the endianness of raw data being > -accessed by the tep handler. The _tep_ argument is trace event parser context. > -[verse] > --- > -The _endian_ argument is the endianness: > - _TEP_LITTLE_ENDIAN_ - the raw data is in little endian format, > - _TEP_BIG_ENDIAN_ - the raw data is in big endian format. > --- > -RETURN VALUE > ------------- > -The _tep_is_file_bigendian()_ function returns true if the data is in bigendian > -format, false otherwise. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > - tep_set_file_bigendian(tep, TEP_LITTLE_ENDIAN); > -... > - if (tep_is_file_bigendian(tep)) { > - /* The raw data is in big endian */ > - } else { > - /* The raw data is in little endian */ > - } > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-filter.txt b/tools/lib/traceevent/Documentation/libtraceevent-filter.txt > deleted file mode 100644 > index 4a9962d8cb59..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-filter.txt > +++ /dev/null > @@ -1,209 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_filter_alloc, tep_filter_free, tep_filter_reset, tep_filter_make_string, > -tep_filter_copy, tep_filter_compare, tep_filter_match, tep_event_filtered, > -tep_filter_remove_event, tep_filter_strerror, tep_filter_add_filter_str - > -Event filter related APIs. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -struct tep_event_filter pass:[*]*tep_filter_alloc*(struct tep_handle pass:[*]_tep_); > -void *tep_filter_free*(struct tep_event_filter pass:[*]_filter_); > -void *tep_filter_reset*(struct tep_event_filter pass:[*]_filter_); > -enum tep_errno *tep_filter_add_filter_str*(struct tep_event_filter pass:[*]_filter_, const char pass:[*]_filter_str_); > -int *tep_event_filtered*(struct tep_event_filter pass:[*]_filter_, int _event_id_); > -int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, int _event_id_); > -enum tep_errno *tep_filter_match*(struct tep_event_filter pass:[*]_filter_, struct tep_record pass:[*]_record_); > -int *tep_filter_copy*(struct tep_event_filter pass:[*]_dest_, struct tep_event_filter pass:[*]_source_); > -int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_); > -char pass:[*]*tep_filter_make_string*(struct tep_event_filter pass:[*]_filter_, int _event_id_); > -int *tep_filter_strerror*(struct tep_event_filter pass:[*]_filter_, enum tep_errno _err_, char pass:[*]buf, size_t _buflen_); > --- > - > -DESCRIPTION > ------------ > -Filters can be attached to traced events. They can be used to filter out various > -events when outputting them. Each event can be filtered based on its parameters, > -described in the event's format file. This set of functions can be used to > -create, delete, modify and attach event filters. > - > -The _tep_filter_alloc()_ function creates a new event filter. The _tep_ argument > -is the trace event parser context. > - > -The _tep_filter_free()_ function frees an event filter and all resources that it > -had used. > - > -The _tep_filter_reset()_ function removes all rules from an event filter and > -resets it. > - > -The _tep_filter_add_filter_str()_ function adds a new rule to the _filter_. The > -_filter_str_ argument is the filter string, that contains the rule. > - > -The _tep_event_filtered()_ function checks if the event with _event_id_ has > -_filter_. > - > -The _tep_filter_remove_event()_ function removes a _filter_ for an event with > -_event_id_. > - > -The _tep_filter_match()_ function tests if a _record_ matches given _filter_. > - > -The _tep_filter_copy()_ function copies a _source_ filter into a _dest_ filter. > - > -The _tep_filter_compare()_ function compares two filers - _filter1_ and _filter2_. > - > -The _tep_filter_make_string()_ function constructs a string, displaying > -the _filter_ contents for given _event_id_. > - > -The _tep_filter_strerror()_ function copies the _filter_ error buffer into the > -given _buf_ with the size _buflen_. If the error buffer is empty, in the _buf_ > -is copied a string, describing the error _err_. > - > -RETURN VALUE > ------------- > -The _tep_filter_alloc()_ function returns a pointer to the newly created event > -filter, or NULL in case of an error. > - > -The _tep_filter_add_filter_str()_ function returns 0 if the rule was > -successfully added or a negative error code. Use _tep_filter_strerror()_ to see > -actual error message in case of an error. > - > -The _tep_event_filtered()_ function returns 1 if the filter is found for given > -event, or 0 otherwise. > - > -The _tep_filter_remove_event()_ function returns 1 if the vent was removed, or > -0 if the event was not found. > - > -The _tep_filter_match()_ function returns _tep_errno_, according to the result: > -[verse] > --- > -_pass:[TEP_ERRNO__FILTER_MATCH]_ - filter found for event, the record matches. > -_pass:[TEP_ERRNO__FILTER_MISS]_ - filter found for event, the record does not match. > -_pass:[TEP_ERRNO__FILTER_NOT_FOUND]_ - no filter found for record's event. > -_pass:[TEP_ERRNO__NO_FILTER]_ - no rules in the filter. > --- > -or any other _tep_errno_, if an error occurred during the test. > - > -The _tep_filter_copy()_ function returns 0 on success or -1 if not all rules > - were copied. > - > -The _tep_filter_compare()_ function returns 1 if the two filters hold the same > -content, or 0 if they do not. > - > -The _tep_filter_make_string()_ function returns a string, which must be freed > -with free(), or NULL in case of an error. > - > -The _tep_filter_strerror()_ function returns 0 if message was filled > -successfully, or -1 in case of an error. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -char errstr[200]; > -int ret; > - > -struct tep_event_filter *filter = tep_filter_alloc(tep); > -struct tep_event_filter *filter1 = tep_filter_alloc(tep); > -ret = tep_filter_add_filter_str(filter, "sched/sched_wakeup:target_cpu==1"); > -if(ret < 0) { > - tep_filter_strerror(filter, ret, errstr, sizeof(errstr)); > - /* Failed to add a new rule to the filter, the error string is in errstr */ > -} > -if (tep_filter_copy(filter1, filter) != 0) { > - /* Failed to copy filter in filter1 */ > -} > -... > -if (tep_filter_compare(filter, filter1) != 1) { > - /* Both filters are different */ > -} > -... > -void process_record(struct tep_handle *tep, struct tep_record *record) > -{ > - struct tep_event *event; > - char *fstring; > - > - event = tep_find_event_by_record(tep, record); > - > - if (tep_event_filtered(filter, event->id) == 1) { > - /* The event has filter */ > - fstring = tep_filter_make_string(filter, event->id); > - if (fstring != NULL) { > - /* The filter for the event is in fstring */ > - free(fstring); > - } > - } > - > - switch (tep_filter_match(filter, record)) { > - case TEP_ERRNO__FILTER_MATCH: > - /* The filter matches the record */ > - break; > - case TEP_ERRNO__FILTER_MISS: > - /* The filter does not match the record */ > - break; > - case TEP_ERRNO__FILTER_NOT_FOUND: > - /* No filter found for record's event */ > - break; > - case TEP_ERRNO__NO_FILTER: > - /* There are no rules in the filter */ > - break > - default: > - /* An error occurred during the test */ > - break; > - } > - > - if (tep_filter_remove_event(filter, event->id) == 1) { > - /* The event was removed from the filter */ > - } > -} > - > -... > -tep_filter_reset(filter); > -... > -tep_filter_free(filter); > -tep_filter_free(filter1); > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt b/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt > deleted file mode 100644 > index f6aca0df2151..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt > +++ /dev/null > @@ -1,183 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_find_function, tep_find_function_address, tep_set_function_resolver, > -tep_reset_function_resolver, tep_register_function, tep_register_print_string - > -function related tep APIs > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -typedef char pass:[*](*tep_func_resolver_t*)(void pass:[*]_priv_, unsigned long long pass:[*]_addrp_, char pass:[**]_modp_); > -int *tep_set_function_resolver*(struct tep_handle pass:[*]_tep_, tep_func_resolver_t pass:[*]_func_, void pass:[*]_priv_); > -void *tep_reset_function_resolver*(struct tep_handle pass:[*]_tep_); > -const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); > -unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); > -int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_); > -int *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const char pass:[*]_fmt_, unsigned long long _addr_); > --- > - > -DESCRIPTION > ------------ > -Some tools may have already a way to resolve the kernel functions. These APIs > -allow them to keep using it instead of duplicating all the entries inside. > - > -The _tep_func_resolver_t_ type is the prototype of the alternative kernel > -functions resolver. This function receives a pointer to its custom context > -(set with the _tep_set_function_resolver()_ call ) and the address of a kernel > -function, which has to be resolved. In case of success, it should return > -the name of the function and its module (if any) in _modp_. > - > -The _tep_set_function_resolver()_ function registers _func_ as an alternative > -kernel functions resolver. The _tep_ argument is trace event parser context. > -The _priv_ argument is a custom context of the _func_ function. The function > -resolver is used by the APIs _tep_find_function()_, > -_tep_find_function_address()_, and _tep_print_func_field()_ to resolve > -a function address to a function name. > - > -The _tep_reset_function_resolver()_ function resets the kernel functions > -resolver to the default function. The _tep_ argument is trace event parser > -context. > - > - > -These APIs can be used to find function name and start address, by given > -address. The given address does not have to be exact, it will select > -the function that would contain it. > - > -The _tep_find_function()_ function returns the function name, which contains the > -given address _addr_. The _tep_ argument is the trace event parser context. > - > -The _tep_find_function_address()_ function returns the function start address, > -by given address _addr_. The _addr_ does not have to be exact, it will select > -the function that would contain it. The _tep_ argument is the trace event > -parser context. > - > -The _tep_register_function()_ function registers a function name mapped to an > -address and (optional) module. This mapping is used in case the function tracer > -or events have "%pS" parameter in its format string. It is common to pass in > -the kallsyms function names with their corresponding addresses with this > -function. The _tep_ argument is the trace event parser context. The _name_ is > -the name of the function, the string is copied internally. The _addr_ is the > -start address of the function. The _mod_ is the kernel module the function may > -be in (NULL for none). > - > -The _tep_register_print_string()_ function registers a string by the address > -it was stored in the kernel. Some strings internal to the kernel with static > -address are passed to certain events. The "%s" in the event's format field > -which has an address needs to know what string would be at that address. The > -tep_register_print_string() supplies the parsing with the mapping between kernel > -addresses and those strings. The _tep_ argument is the trace event parser > -context. The _fmt_ is the string to register, it is copied internally. > -The _addr_ is the address the string was located at. > - > - > -RETURN VALUE > ------------- > -The _tep_set_function_resolver()_ function returns 0 in case of success, or -1 > -in case of an error. > - > -The _tep_find_function()_ function returns the function name, or NULL in case > -it cannot be found. > - > -The _tep_find_function_address()_ function returns the function start address, > -or 0 in case it cannot be found. > - > -The _tep_register_function()_ function returns 0 in case of success. In case of > -an error -1 is returned, and errno is set to the appropriate error number. > - > -The _tep_register_print_string()_ function returns 0 in case of success. In case > -of an error -1 is returned, and errno is set to the appropriate error number. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -char *my_resolve_kernel_addr(void *context, > - unsigned long long *addrp, char **modp) > -{ > - struct db *function_database = context; > - struct symbol *sym = sql_lookup(function_database, *addrp); > - > - if (!sym) > - return NULL; > - > - *modp = sym->module_name; > - return sym->name; > -} > - > -void show_function( unsigned long long addr) > -{ > - unsigned long long fstart; > - const char *fname; > - > - if (tep_set_function_resolver(tep, my_resolve_kernel_addr, > - function_database) != 0) { > - /* failed to register my_resolve_kernel_addr */ > - } > - > - /* These APIs use my_resolve_kernel_addr() to resolve the addr */ > - fname = tep_find_function(tep, addr); > - fstart = tep_find_function_address(tep, addr); > - > - /* > - addr is in function named fname, starting at fstart address, > - at offset (addr - fstart) > - */ > - > - tep_reset_function_resolver(tep); > - > -} > -... > - if (tep_register_function(tep, "kvm_exit", > - (unsigned long long) 0x12345678, "kvm") != 0) { > - /* Failed to register kvm_exit address mapping */ > - } > -... > - if (tep_register_print_string(tep, "print string", > - (unsigned long long) 0x87654321, NULL) != 0) { > - /* Failed to register "print string" address mapping */ > - } > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-func_find.txt b/tools/lib/traceevent/Documentation/libtraceevent-func_find.txt > deleted file mode 100644 > index 04840e244445..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-func_find.txt > +++ /dev/null > @@ -1,88 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_find_function,tep_find_function_address - Find function name / start address. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); > -unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); > --- > - > -DESCRIPTION > ------------ > -These functions can be used to find function name and start address, by given > -address. The given address does not have to be exact, it will select the function > -that would contain it. > - > -The _tep_find_function()_ function returns the function name, which contains the > -given address _addr_. The _tep_ argument is the trace event parser context. > - > -The _tep_find_function_address()_ function returns the function start address, > -by given address _addr_. The _addr_ does not have to be exact, it will select the > -function that would contain it. The _tep_ argument is the trace event parser context. > - > -RETURN VALUE > ------------- > -The _tep_find_function()_ function returns the function name, or NULL in case > -it cannot be found. > - > -The _tep_find_function_address()_ function returns the function start address, > -or 0 in case it cannot be found. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -void show_function( unsigned long long addr) > -{ > - const char *fname = tep_find_function(tep, addr); > - unsigned long long fstart = tep_find_function_address(tep, addr); > - > - /* addr is in function named fname, starting at fstart address, at offset (addr - fstart) */ > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-handle.txt b/tools/lib/traceevent/Documentation/libtraceevent-handle.txt > deleted file mode 100644 > index 45b20172e262..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-handle.txt > +++ /dev/null > @@ -1,101 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_alloc, tep_free,tep_ref, tep_unref,tep_get_ref - Create, destroy, manage > -references of trace event parser context. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -struct tep_handle pass:[*]*tep_alloc*(void); > -void *tep_free*(struct tep_handle pass:[*]_tep_); > -void *tep_ref*(struct tep_handle pass:[*]_tep_); > -void *tep_unref*(struct tep_handle pass:[*]_tep_); > -int *tep_get_ref*(struct tep_handle pass:[*]_tep_); > --- > - > -DESCRIPTION > ------------ > -These are the main functions to create and destroy tep_handle - the main > -structure, representing the trace event parser context. This context is used as > -the input parameter of most library APIs. > - > -The _tep_alloc()_ function allocates and initializes the tep context. > - > -The _tep_free()_ function will decrement the reference of the _tep_ handler. > -When there is no more references, then it will free the handler, as well > -as clean up all its resources that it had used. The argument _tep_ is > -the pointer to the trace event parser context. > - > -The _tep_ref()_ function adds a reference to the _tep_ handler. > - > -The _tep_unref()_ function removes a reference from the _tep_ handler. When > -the last reference is removed, the _tep_ is destroyed, and all resources that > -it had used are cleaned up. > - > -The _tep_ref_get()_ functions gets the current references of the _tep_ handler. > - > -RETURN VALUE > ------------- > -_tep_alloc()_ returns a pointer to a newly created tep_handle structure. > -NULL is returned in case there is not enough free memory to allocate it. > - > -_tep_ref_get()_ returns the current references of _tep_. > -If _tep_ is NULL, 0 is returned. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > - > -... > -struct tep_handle *tep = tep_alloc(); > -... > -int ref = tep_get_ref(tep); > -tep_ref(tep); > -if ( (ref+1) != tep_get_ref(tep)) { > - /* Something wrong happened, the counter is not incremented by 1 */ > -} > -tep_unref(tep); > -... > -tep_free(tep); > -... > --- > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-header_page.txt b/tools/lib/traceevent/Documentation/libtraceevent-header_page.txt > deleted file mode 100644 > index 615d117dc39f..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-header_page.txt > +++ /dev/null > @@ -1,102 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_get_header_page_size, tep_get_header_timestamp_size, tep_is_old_format - > -Get the data stored in the header page, in kernel context. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_); > -int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_); > -bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_); > --- > -DESCRIPTION > ------------ > -These functions retrieve information from kernel context, stored in tracefs > -events/header_page. Old kernels do not have header page info, so default values > -from user space context are used. > - > -The _tep_get_header_page_size()_ function returns the size of a long integer, > -in kernel context. The _tep_ argument is trace event parser context. > -This information is retrieved from tracefs events/header_page, "commit" field. > - > -The _tep_get_header_timestamp_size()_ function returns the size of timestamps, > -in kernel context. The _tep_ argument is trace event parser context. This > -information is retrieved from tracefs events/header_page, "timestamp" field. > - > -The _tep_is_old_format()_ function returns true if the kernel predates > -the addition of events/header_page, otherwise it returns false. > - > -RETURN VALUE > ------------- > -The _tep_get_header_page_size()_ function returns the size of a long integer, > -in bytes. > - > -The _tep_get_header_timestamp_size()_ function returns the size of timestamps, > -in bytes. > - > -The _tep_is_old_format()_ function returns true, if an old kernel is used to > -generate the tracing data, which has no event/header_page. If the kernel is new, > -or _tep_ is NULL, false is returned. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > - int longsize; > - int timesize; > - bool old; > - > - longsize = tep_get_header_page_size(tep); > - timesize = tep_get_header_timestamp_size(tep); > - old = tep_is_old_format(tep); > - > - printf ("%s kernel is used to generate the tracing data.\n", > - old?"Old":"New"); > - printf("The size of a long integer is %d bytes.\n", longsize); > - printf("The timestamps size is %d bytes.\n", timesize); > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt b/tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt > deleted file mode 100644 > index d5d375eb8d1e..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt > +++ /dev/null > @@ -1,104 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_is_bigendian, tep_is_local_bigendian, tep_set_local_bigendian - Get / set > -the endianness of the local machine. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -enum *tep_endian* { > - TEP_LITTLE_ENDIAN = 0, > - TEP_BIG_ENDIAN > -}; > - > -int *tep_is_bigendian*(void); > -bool *tep_is_local_bigendian*(struct tep_handle pass:[*]_tep_); > -void *tep_set_local_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); > --- > - > -DESCRIPTION > ------------ > - > -The _tep_is_bigendian()_ gets the endianness of the machine, executing > -the function. > - > -The _tep_is_local_bigendian()_ function gets the endianness of the local > -machine, saved in the _tep_ handler. The _tep_ argument is the trace event > -parser context. This API is a bit faster than _tep_is_bigendian()_, as it > -returns cached endianness of the local machine instead of checking it each time. > - > -The _tep_set_local_bigendian()_ function sets the endianness of the local > -machine in the _tep_ handler. The _tep_ argument is trace event parser context. > -The _endian_ argument is the endianness: > -[verse] > --- > - _TEP_LITTLE_ENDIAN_ - the machine is little endian, > - _TEP_BIG_ENDIAN_ - the machine is big endian. > --- > - > -RETURN VALUE > ------------- > -The _tep_is_bigendian()_ function returns non zero if the endianness of the > -machine, executing the code, is big endian and zero otherwise. > - > -The _tep_is_local_bigendian()_ function returns true, if the endianness of the > -local machine, saved in the _tep_ handler, is big endian, or false otherwise. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > - if (tep_is_bigendian()) > - tep_set_local_bigendian(tep, TEP_BIG_ENDIAN); > - else > - tep_set_local_bigendian(tep, TEP_LITTLE_ENDIAN); > -... > - if (tep_is_local_bigendian(tep)) > - printf("This machine you are running on is bigendian\n"); > - else > - printf("This machine you are running on is little endian\n"); > - > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-long_size.txt b/tools/lib/traceevent/Documentation/libtraceevent-long_size.txt > deleted file mode 100644 > index 01d78ea2519a..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-long_size.txt > +++ /dev/null > @@ -1,78 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_get_long_size, tep_set_long_size - Get / set the size of a long integer on > -the machine, where the trace is generated, in bytes > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -int *tep_get_long_size*(strucqt tep_handle pass:[*]_tep_); > -void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_); > --- > - > -DESCRIPTION > ------------ > -The _tep_get_long_size()_ function returns the size of a long integer on the machine, > -where the trace is generated. The _tep_ argument is trace event parser context. > - > -The _tep_set_long_size()_ function sets the size of a long integer on the machine, > -where the trace is generated. The _tep_ argument is trace event parser context. > -The _long_size_ is the size of a long integer, in bytes. > - > -RETURN VALUE > ------------- > -The _tep_get_long_size()_ function returns the size of a long integer on the machine, > -where the trace is generated, in bytes. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -tep_set_long_size(tep, 4); > -... > -int long_size = tep_get_long_size(tep); > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-page_size.txt b/tools/lib/traceevent/Documentation/libtraceevent-page_size.txt > deleted file mode 100644 > index 452c0cfa1822..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-page_size.txt > +++ /dev/null > @@ -1,82 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_get_page_size, tep_set_page_size - Get / set the size of a memory page on > -the machine, where the trace is generated > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -int *tep_get_page_size*(struct tep_handle pass:[*]_tep_); > -void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_); > --- > - > -DESCRIPTION > ------------ > -The _tep_get_page_size()_ function returns the size of a memory page on > -the machine, where the trace is generated. The _tep_ argument is trace > -event parser context. > - > -The _tep_set_page_size()_ function stores in the _tep_ context the size of a > -memory page on the machine, where the trace is generated. > -The _tep_ argument is trace event parser context. > -The _page_size_ argument is the size of a memory page, in bytes. > - > -RETURN VALUE > ------------- > -The _tep_get_page_size()_ function returns size of the memory page, in bytes. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > - int page_size = getpagesize(); > - > - tep_set_page_size(tep, page_size); > - > - printf("The page size for this machine is %d\n", tep_get_page_size(tep)); > - > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt b/tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt > deleted file mode 100644 > index f248114ca1ff..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt > +++ /dev/null > @@ -1,90 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_parse_event, tep_parse_format - Parse the event format information > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -enum tep_errno *tep_parse_event*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); > -enum tep_errno *tep_parse_format*(struct tep_handle pass:[*]_tep_, struct tep_event pass:[*]pass:[*]_eventp_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); > --- > - > -DESCRIPTION > ------------ > -The _tep_parse_event()_ function parses the event format and creates an event > -structure to quickly parse raw data for a given event. The _tep_ argument is > -the trace event parser context. The created event structure is stored in the > -_tep_ context. The _buf_ argument is a buffer with _size_, where the event > -format data is. The event format data can be taken from > -tracefs/events/.../.../format files. The _sys_ argument is the system of > -the event. > - > -The _tep_parse_format()_ function does the same as _tep_parse_event()_. The only > -difference is in the extra _eventp_ argument, where the newly created event > -structure is returned. > - > -RETURN VALUE > ------------- > -Both _tep_parse_event()_ and _tep_parse_format()_ functions return 0 on success, > -or TEP_ERRNO__... in case of an error. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -char *buf; > -int size; > -struct tep_event *event = NULL; > -buf = read_file("/sys/kernel/tracing/events/ftrace/print/format", &size); > -if (tep_parse_event(tep, buf, size, "ftrace") != 0) { > - /* Failed to parse the ftrace print format */ > -} > - > -if (tep_parse_format(tep, &event, buf, size, "ftrace") != 0) { > - /* Failed to parse the ftrace print format */ > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt b/tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt > deleted file mode 100644 > index c90f16c7d8e6..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt > +++ /dev/null > @@ -1,82 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_parse_header_page - Parses the data stored in the header page. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -int *tep_parse_header_page*(struct tep_handle pass:[*]_tep_, char pass:[*]_buf_, unsigned long _size_, int _long_size_); > --- > - > -DESCRIPTION > ------------ > -The _tep_parse_header_page()_ function parses the header page data from _buf_, > -and initializes the _tep_, trace event parser context, with it. The buffer > -_buf_ is with _size_, and is supposed to be copied from > -tracefs/events/header_page. > - > -Some old kernels do not have header page info, in this case the > -_tep_parse_header_page()_ function can be called with _size_ equal to 0. The > -_tep_ context is initialized with default values. The _long_size_ can be used in > -this use case, to set the size of a long integer to be used. > - > -RETURN VALUE > ------------- > -The _tep_parse_header_page()_ function returns 0 in case of success, or -1 > -in case of an error. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -char *buf; > -int size; > -buf = read_file("/sys/kernel/tracing/events/header_page", &size); > -if (tep_parse_header_page(tep, buf, size, sizeof(unsigned long)) != 0) { > - /* Failed to parse the header page */ > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-plugins.txt b/tools/lib/traceevent/Documentation/libtraceevent-plugins.txt > deleted file mode 100644 > index 4d6394397d92..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-plugins.txt > +++ /dev/null > @@ -1,122 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_load_plugins, tep_unload_plugins, tep_load_plugins_hook - Load / unload traceevent plugins. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -struct tep_plugin_list pass:[*]*tep_load_plugins*(struct tep_handle pass:[*]_tep_); > -void *tep_unload_plugins*(struct tep_plugin_list pass:[*]_plugin_list_, struct tep_handle pass:[*]_tep_); > -void *tep_load_plugins_hook*(struct tep_handle pass:[*]_tep_, const char pass:[*]_suffix_, > - void (pass:[*]_load_plugin_)(struct tep_handle pass:[*]tep, > - const char pass:[*]path, > - const char pass:[*]name, > - void pass:[*]data), > - void pass:[*]_data_); > --- > - > -DESCRIPTION > ------------ > -The _tep_load_plugins()_ function loads all plugins, located in the plugin > -directories. The _tep_ argument is trace event parser context. > -The plugin directories are : > -[verse] > --- > - - Directories, specified in _tep_->plugins_dir with priority TEP_PLUGIN_FIRST > - - System's plugin directory, defined at the library compile time. It > - depends on the library installation prefix and usually is > - _(install_preffix)/lib/traceevent/plugins_ > - - Directory, defined by the environment variable _TRACEEVENT_PLUGIN_DIR_ > - - User's plugin directory, located at _~/.local/lib/traceevent/plugins_ > - - Directories, specified in _tep_->plugins_dir with priority TEP_PLUGIN_LAST > --- > -Loading of plugins can be controlled by the _tep_flags_, using the > -_tep_set_flag()_ API: > -[verse] > --- > - _TEP_DISABLE_SYS_PLUGINS_ - do not load plugins, located in > - the system's plugin directory. > - _TEP_DISABLE_PLUGINS_ - do not load any plugins. > --- > -The _tep_set_flag()_ API needs to be called before _tep_load_plugins()_, if > -loading of all plugins is not the desired case. > - > -The _tep_unload_plugins()_ function unloads the plugins, previously loaded by > -_tep_load_plugins()_. The _tep_ argument is trace event parser context. The > -_plugin_list_ is the list of loaded plugins, returned by > -the _tep_load_plugins()_ function. > - > -The _tep_load_plugins_hook_ function walks through all directories with plugins > -and calls user specified _load_plugin()_ hook for each plugin file. Only files > -with given _suffix_ are considered to be plugins. The _data_ is a user specified > -context, passed to _load_plugin()_. Directories and the walk order are the same > -as in _tep_load_plugins()_ API. > - > -RETURN VALUE > ------------- > -The _tep_load_plugins()_ function returns a list of successfully loaded plugins, > -or NULL in case no plugins are loaded. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -struct tep_plugin_list *plugins = tep_load_plugins(tep); > -if (plugins == NULL) { > - /* no plugins are loaded */ > -} > -... > -tep_unload_plugins(plugins, tep); > -... > -void print_plugin(struct tep_handle *tep, const char *path, > - const char *name, void *data) > -{ > - pritnf("Found libtraceevent plugin %s/%s\n", path, name); > -} > -... > -tep_load_plugins_hook(tep, ".so", print_plugin, NULL); > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_, _tep_set_flag(3)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt b/tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt > deleted file mode 100644 > index e9a69116c78b..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt > +++ /dev/null > @@ -1,137 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_data_type, tep_data_pid,tep_data_preempt_count, tep_data_flags - > -Extract common fields from a record. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -enum *trace_flag_type* { > - _TRACE_FLAG_IRQS_OFF_, > - _TRACE_FLAG_IRQS_NOSUPPORT_, > - _TRACE_FLAG_NEED_RESCHED_, > - _TRACE_FLAG_HARDIRQ_, > - _TRACE_FLAG_SOFTIRQ_, > -}; > - > -int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); > -int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); > -int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); > -int *tep_data_flags*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); > --- > - > -DESCRIPTION > ------------ > -This set of functions can be used to extract common fields from a record. > - > -The _tep_data_type()_ function gets the event id from the record _rec_. > -It reads the "common_type" field. The _tep_ argument is the trace event parser > -context. > - > -The _tep_data_pid()_ function gets the process id from the record _rec_. > -It reads the "common_pid" field. The _tep_ argument is the trace event parser > -context. > - > -The _tep_data_preempt_count()_ function gets the preemption count from the > -record _rec_. It reads the "common_preempt_count" field. The _tep_ argument is > -the trace event parser context. > - > -The _tep_data_flags()_ function gets the latency flags from the record _rec_. > -It reads the "common_flags" field. The _tep_ argument is the trace event parser > -context. Supported latency flags are: > -[verse] > --- > - _TRACE_FLAG_IRQS_OFF_, Interrupts are disabled. > - _TRACE_FLAG_IRQS_NOSUPPORT_, Reading IRQ flag is not supported by the architecture. > - _TRACE_FLAG_NEED_RESCHED_, Task needs rescheduling. > - _TRACE_FLAG_HARDIRQ_, Hard IRQ is running. > - _TRACE_FLAG_SOFTIRQ_, Soft IRQ is running. > --- > - > -RETURN VALUE > ------------- > -The _tep_data_type()_ function returns an integer, representing the event id. > - > -The _tep_data_pid()_ function returns an integer, representing the process id > - > -The _tep_data_preempt_count()_ function returns an integer, representing the > -preemption count. > - > -The _tep_data_flags()_ function returns an integer, representing the latency > -flags. Look at the _trace_flag_type_ enum for supported flags. > - > -All these functions in case of an error return a negative integer. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -void process_record(struct tep_record *record) > -{ > - int data; > - > - data = tep_data_type(tep, record); > - if (data >= 0) { > - /* Got the ID of the event */ > - } > - > - data = tep_data_pid(tep, record); > - if (data >= 0) { > - /* Got the process ID */ > - } > - > - data = tep_data_preempt_count(tep, record); > - if (data >= 0) { > - /* Got the preemption count */ > - } > - > - data = tep_data_flags(tep, record); > - if (data >= 0) { > - /* Got the latency flags */ > - } > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt b/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt > deleted file mode 100644 > index 53d37d72a1c1..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt > +++ /dev/null > @@ -1,156 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_register_event_handler, tep_unregister_event_handler - Register / > -unregisters a callback function to parse an event information. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -enum *tep_reg_handler* { > - _TEP_REGISTER_SUCCESS_, > - _TEP_REGISTER_SUCCESS_OVERWRITE_, > -}; > - > -int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_); > -int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_); > - > -typedef int (*pass:[*]tep_event_handler_func*)(struct trace_seq pass:[*]s, struct tep_record pass:[*]record, struct tep_event pass:[*]event, void pass:[*]context); > --- > - > -DESCRIPTION > ------------ > -The _tep_register_event_handler()_ function registers a handler function, > -which is going to be called to parse the information for a given event. > -The _tep_ argument is the trace event parser context. The _id_ argument is > -the id of the event. The _sys_name_ argument is the name of the system, > -the event belongs to. The _event_name_ argument is the name of the event. > -If _id_ is >= 0, it is used to find the event, otherwise _sys_name_ and > -_event_name_ are used. The _func_ is a pointer to the function, which is going > -to be called to parse the event information. The _context_ argument is a pointer > -to the context data, which will be passed to the _func_. If a handler function > -for the same event is already registered, it will be overridden with the new > -one. This mechanism allows a developer to override the parsing of a given event. > -If for some reason the default print format is not sufficient, the developer > -can register a function for an event to be used to parse the data instead. > - > -The _tep_unregister_event_handler()_ function unregisters the handler function, > -previously registered with _tep_register_event_handler()_. The _tep_ argument > -is the trace event parser context. The _id_, _sys_name_, _event_name_, _func_, > -and _context_ are the same arguments, as when the callback function _func_ was > -registered. > - > -The _tep_event_handler_func_ is the type of the custom event handler > -function. The _s_ argument is the trace sequence, it can be used to create a > -custom string, describing the event. A _record_ to get the event from is passed > -as input parameter and also the _event_ - the handle to the record's event. The > -_context_ is custom context, set when the custom event handler is registered. > - > -RETURN VALUE > ------------- > -The _tep_register_event_handler()_ function returns _TEP_REGISTER_SUCCESS_ > -if the new handler is registered successfully or > -_TEP_REGISTER_SUCCESS_OVERWRITE_ if an existing handler is overwritten. > -If there is not enough memory to complete the registration, > -TEP_ERRNO__MEM_ALLOC_FAILED is returned. > - > -The _tep_unregister_event_handler()_ function returns 0 if _func_ was removed > -successful or, -1 if the event was not found. > - > -The _tep_event_handler_func_ should return -1 in case of an error, > -or 0 otherwise. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -int timer_expire_handler(struct trace_seq *s, struct tep_record *record, > - struct tep_event *event, void *context) > -{ > - trace_seq_printf(s, "hrtimer="); > - > - if (tep_print_num_field(s, "0x%llx", event, "timer", record, 0) == -1) > - tep_print_num_field(s, "0x%llx", event, "hrtimer", record, 1); > - > - trace_seq_printf(s, " now="); > - > - tep_print_num_field(s, "%llu", event, "now", record, 1); > - > - tep_print_func_field(s, " function=%s", event, "function", record, 0); > - > - return 0; > -} > -... > - int ret; > - > - ret = tep_register_event_handler(tep, -1, "timer", "hrtimer_expire_entry", > - timer_expire_handler, NULL); > - if (ret < 0) { > - char buf[32]; > - > - tep_strerror(tep, ret, buf, 32) > - printf("Failed to register handler for hrtimer_expire_entry: %s\n", buf); > - } else { > - switch (ret) { > - case TEP_REGISTER_SUCCESS: > - printf ("Registered handler for hrtimer_expire_entry\n"); > - break; > - case TEP_REGISTER_SUCCESS_OVERWRITE: > - printf ("Overwrote handler for hrtimer_expire_entry\n"); > - break; > - } > - } > -... > - ret = tep_unregister_event_handler(tep, -1, "timer", "hrtimer_expire_entry", > - timer_expire_handler, NULL); > - if ( ret ) > - printf ("Failed to unregister handler for hrtimer_expire_entry\n"); > - > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*trace-seq.h* > - Header file to include in order to have access to trace sequences > - related APIs. Trace sequences are used to allow a function to call > - several other functions to create a string of data to use. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt b/tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt > deleted file mode 100644 > index 708dce91ebd8..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt > +++ /dev/null > @@ -1,155 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_register_print_function,tep_unregister_print_function - > -Registers / Unregisters a helper function. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -enum *tep_func_arg_type* { > - TEP_FUNC_ARG_VOID, > - TEP_FUNC_ARG_INT, > - TEP_FUNC_ARG_LONG, > - TEP_FUNC_ARG_STRING, > - TEP_FUNC_ARG_PTR, > - TEP_FUNC_ARG_MAX_TYPES > -}; > - > -typedef unsigned long long (*pass:[*]tep_func_handler*)(struct trace_seq pass:[*]s, unsigned long long pass:[*]args); > - > -int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, enum tep_func_arg_type _ret_type_, char pass:[*]_name_, _..._); > -int *tep_unregister_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, char pass:[*]_name_); > --- > - > -DESCRIPTION > ------------ > -Some events may have helper functions in the print format arguments. > -This allows a plugin to dynamically create a way to process one of > -these functions. > - > -The _tep_register_print_function()_ registers such helper function. The _tep_ > -argument is the trace event parser context. The _func_ argument is a pointer > -to the helper function. The _ret_type_ argument is the return type of the > -helper function, value from the _tep_func_arg_type_ enum. The _name_ is the name > -of the helper function, as seen in the print format arguments. The _..._ is a > -variable list of _tep_func_arg_type_ enums, the _func_ function arguments. > -This list must end with _TEP_FUNC_ARG_VOID_. See 'EXAMPLE' section. > - > -The _tep_unregister_print_function()_ unregisters a helper function, previously > -registered with _tep_register_print_function()_. The _tep_ argument is the > -trace event parser context. The _func_ and _name_ arguments are the same, used > -when the helper function was registered. > - > -The _tep_func_handler_ is the type of the helper function. The _s_ argument is > -the trace sequence, it can be used to create a custom string. > -The _args_ is a list of arguments, defined when the helper function was > -registered. > - > -RETURN VALUE > ------------- > -The _tep_register_print_function()_ function returns 0 in case of success. > -In case of an error, TEP_ERRNO_... code is returned. > - > -The _tep_unregister_print_function()_ returns 0 in case of success, or -1 in > -case of an error. > - > -EXAMPLE > -------- > -Some events have internal functions calls, that appear in the print format > -output. For example "tracefs/events/i915/g4x_wm/format" has: > -[source,c] > --- > -print fmt: "pipe %c, frame=%u, scanline=%u, wm %d/%d/%d, sr %s/%d/%d/%d, hpll %s/%d/%d/%d, fbc %s", > - ((REC->pipe) + 'A'), REC->frame, REC->scanline, REC->primary, > - REC->sprite, REC->cursor, yesno(REC->cxsr), REC->sr_plane, > - REC->sr_cursor, REC->sr_fbc, yesno(REC->hpll), REC->hpll_plane, > - REC->hpll_cursor, REC->hpll_fbc, yesno(REC->fbc) > --- > -Notice the call to function _yesno()_ in the print arguments. In the kernel > -context, this function has the following implementation: > -[source,c] > --- > -static const char *yesno(int x) > -{ > - static const char *yes = "yes"; > - static const char *no = "no"; > - > - return x ? yes : no; > -} > --- > -The user space event parser has no idea how to handle this _yesno()_ function. > -The _tep_register_print_function()_ API can be used to register a user space > -helper function, mapped to the kernel's _yesno()_: > -[source,c] > --- > -#include > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -static const char *yes_no_helper(int x) > -{ > - return x ? "yes" : "no"; > -} > -... > - if ( tep_register_print_function(tep, > - yes_no_helper, > - TEP_FUNC_ARG_STRING, > - "yesno", > - TEP_FUNC_ARG_INT, > - TEP_FUNC_ARG_VOID) != 0) { > - /* Failed to register yes_no_helper function */ > - } > - > -/* > - Now, when the event parser encounters this yesno() function, it will know > - how to handle it. > -*/ > -... > - if (tep_unregister_print_function(tep, yes_no_helper, "yesno") != 0) { > - /* Failed to unregister yes_no_helper function */ > - } > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*trace-seq.h* > - Header file to include in order to have access to trace sequences > - related APIs. Trace sequences are used to allow a function to call > - several other functions to create a string of data to use. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt b/tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt > deleted file mode 100644 > index b0599780b9a6..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt > +++ /dev/null > @@ -1,104 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_set_flag, tep_clear_flag, tep_test_flag - > -Manage flags of trace event parser context. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -enum *tep_flag* { > - _TEP_NSEC_OUTPUT_, > - _TEP_DISABLE_SYS_PLUGINS_, > - _TEP_DISABLE_PLUGINS_ > -}; > -void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); > -void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); > -bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); > --- > - > -DESCRIPTION > ------------ > -Trace event parser context flags are defined in *enum tep_flag*: > -[verse] > --- > -_TEP_NSEC_OUTPUT_ - print event's timestamp in nano seconds, instead of micro seconds. > -_TEP_DISABLE_SYS_PLUGINS_ - disable plugins, located in system's plugin > - directory. This directory is defined at library compile > - time, and usually depends on library installation > - prefix: (install_preffix)/lib/traceevent/plugins > -_TEP_DISABLE_PLUGINS_ - disable all library plugins: > - - in system's plugin directory > - - in directory, defined by the environment variable _TRACEEVENT_PLUGIN_DIR_ > - - in user's home directory, _~/.traceevent/plugins_ > --- > -Note: plugin related flags must me set before calling _tep_load_plugins()_ API. > - > -The _tep_set_flag()_ function sets _flag_ to _tep_ context. > - > -The _tep_clear_flag()_ function clears _flag_ from _tep_ context. > - > -The _tep_test_flag()_ function tests if _flag_ is set to _tep_ context. > - > -RETURN VALUE > ------------- > -_tep_test_flag()_ function returns true if _flag_ is set, false otherwise. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -/* Print timestamps in nanoseconds */ > -tep_set_flag(tep, TEP_NSEC_OUTPUT); > -... > -if (tep_test_flag(tep, TEP_NSEC_OUTPUT)) { > - /* print timestamps in nanoseconds */ > -} else { > - /* print timestamps in microseconds */ > -} > -... > -/* Print timestamps in microseconds */ > -tep_clear_flag(tep, TEP_NSEC_OUTPUT); > -... > --- > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-strerror.txt b/tools/lib/traceevent/Documentation/libtraceevent-strerror.txt > deleted file mode 100644 > index ee4062a00c9f..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-strerror.txt > +++ /dev/null > @@ -1,85 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -tep_strerror - Returns a string describing regular errno and tep error number. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_); > - > --- > -DESCRIPTION > ------------ > -The _tep_strerror()_ function converts tep error number into a human > -readable string. > -The _tep_ argument is trace event parser context. The _errnum_ is a regular > -errno, defined in errno.h, or a tep error number. The string, describing this > -error number is copied in the _buf_ argument. The _buflen_ argument is > -the size of the _buf_. > - > -It as a thread safe wrapper around strerror_r(). The library function has two > -different behaviors - POSIX and GNU specific. The _tep_strerror()_ API always > -behaves as the POSIX version - the error string is copied in the user supplied > -buffer. > - > -RETURN VALUE > ------------- > -The _tep_strerror()_ function returns 0, if a valid _errnum_ is passed and the > -string is copied into _buf_. If _errnum_ is not a valid error number, > --1 is returned and _buf_ is not modified. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -... > -struct tep_handle *tep = tep_alloc(); > -... > -char buf[32]; > -char *pool = calloc(1, 128); > -if (tep == NULL) { > - tep_strerror(tep, TEP_ERRNO__MEM_ALLOC_FAILED, buf, 32); > - printf ("The pool is not initialized, %s", buf); > -} > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent-tseq.txt b/tools/lib/traceevent/Documentation/libtraceevent-tseq.txt > deleted file mode 100644 > index 8ac6aa174e12..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent-tseq.txt > +++ /dev/null > @@ -1,158 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -trace_seq_init, trace_seq_destroy, trace_seq_reset, trace_seq_terminate, > -trace_seq_putc, trace_seq_puts, trace_seq_printf, trace_seq_vprintf, > -trace_seq_do_fprintf, trace_seq_do_printf - > -Initialize / destroy a trace sequence. > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > -*#include * > - > -void *trace_seq_init*(struct trace_seq pass:[*]_s_); > -void *trace_seq_destroy*(struct trace_seq pass:[*]_s_); > -void *trace_seq_reset*(struct trace_seq pass:[*]_s_); > -void *trace_seq_terminate*(struct trace_seq pass:[*]_s_); > -int *trace_seq_putc*(struct trace_seq pass:[*]_s_, unsigned char _c_); > -int *trace_seq_puts*(struct trace_seq pass:[*]_s_, const char pass:[*]_str_); > -int *trace_seq_printf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, _..._); > -int *trace_seq_vprintf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, va_list _args_); > -int *trace_seq_do_printf*(struct trace_seq pass:[*]_s_); > -int *trace_seq_do_fprintf*(struct trace_seq pass:[*]_s_, FILE pass:[*]_fp_); > --- > - > -DESCRIPTION > ------------ > -Trace sequences are used to allow a function to call several other functions > -to create a string of data to use. > - > -The _trace_seq_init()_ function initializes the trace sequence _s_. > - > -The _trace_seq_destroy()_ function destroys the trace sequence _s_ and frees > -all its resources that it had used. > - > -The _trace_seq_reset()_ function re-initializes the trace sequence _s_. All > -characters already written in _s_ will be deleted. > - > -The _trace_seq_terminate()_ function terminates the trace sequence _s_. It puts > -the null character pass:['\0'] at the end of the buffer. > - > -The _trace_seq_putc()_ function puts a single character _c_ in the trace > -sequence _s_. > - > -The _trace_seq_puts()_ function puts a NULL terminated string _str_ in the > -trace sequence _s_. > - > -The _trace_seq_printf()_ function puts a formated string _fmt _with > -variable arguments _..._ in the trace sequence _s_. > - > -The _trace_seq_vprintf()_ function puts a formated string _fmt _with > -list of arguments _args_ in the trace sequence _s_. > - > -The _trace_seq_do_printf()_ function prints the buffer of trace sequence _s_ to > -the standard output stdout. > - > -The _trace_seq_do_fprintf()_ function prints the buffer of trace sequence _s_ > -to the given file _fp_. > - > -RETURN VALUE > ------------- > -Both _trace_seq_putc()_ and _trace_seq_puts()_ functions return the number of > -characters put in the trace sequence, or 0 in case of an error > - > -Both _trace_seq_printf()_ and _trace_seq_vprintf()_ functions return 0 if the > -trace oversizes the buffer's free space, the number of characters printed, or > -a negative value in case of an error. > - > -Both _trace_seq_do_printf()_ and _trace_seq_do_fprintf()_ functions return the > -number of printed characters, or -1 in case of an error. > - > -EXAMPLE > -------- > -[source,c] > --- > -#include > -#include > -... > -struct trace_seq seq; > -trace_seq_init(&seq); > -... > -void foo_seq_print(struct trace_seq *tseq, char *format, ...) > -{ > - va_list ap; > - va_start(ap, format); > - if (trace_seq_vprintf(tseq, format, ap) <= 0) { > - /* Failed to print in the trace sequence */ > - } > - va_end(ap); > -} > - > -trace_seq_reset(&seq); > - > -char *str = " MAN page example"; > -if (trace_seq_puts(&seq, str) != strlen(str)) { > - /* Failed to put str in the trace sequence */ > -} > -if (trace_seq_putc(&seq, ':') != 1) { > - /* Failed to put ':' in the trace sequence */ > -} > -if (trace_seq_printf(&seq, " trace sequence: %d", 1) <= 0) { > - /* Failed to print in the trace sequence */ > -} > -foo_seq_print( &seq, " %d\n", 2); > - > -trace_seq_terminate(&seq); > -... > - > -if (trace_seq_do_printf(&seq) < 0 ) { > - /* Failed to print the sequence buffer to the standard output */ > -} > -FILE *fp = fopen("trace.txt", "w"); > -if (trace_seq_do_fprintf(&seq, fp) < 0 ) [ > - /* Failed to print the sequence buffer to the trace.txt file */ > -} > - > -trace_seq_destroy(&seq); > -... > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*trace-seq.h* > - Header file to include in order to have access to trace sequences related APIs. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_libtraceevent(3)_, _trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/libtraceevent.txt b/tools/lib/traceevent/Documentation/libtraceevent.txt > deleted file mode 100644 > index d530a7ce8fb2..000000000000 > --- a/tools/lib/traceevent/Documentation/libtraceevent.txt > +++ /dev/null > @@ -1,192 +0,0 @@ > -libtraceevent(3) > -================ > - > -NAME > ----- > -libtraceevent - Linux kernel trace event library > - > -SYNOPSIS > --------- > -[verse] > --- > -*#include * > - > -Management of tep handler data structure and access of its members: > - struct tep_handle pass:[*]*tep_alloc*(void); > - void *tep_free*(struct tep_handle pass:[*]_tep_); > - void *tep_ref*(struct tep_handle pass:[*]_tep_); > - void *tep_unref*(struct tep_handle pass:[*]_tep_); > - int *tep_get_ref*(struct tep_handle pass:[*]_tep_); > - void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); > - void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); > - bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flags_); > - int *tep_get_cpus*(struct tep_handle pass:[*]_tep_); > - void *tep_set_cpus*(struct tep_handle pass:[*]_tep_, int _cpus_); > - int *tep_get_long_size*(strucqt tep_handle pass:[*]_tep_); > - void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_); > - int *tep_get_page_size*(struct tep_handle pass:[*]_tep_); > - void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_); > - int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_); > - int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_); > - bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_); > - int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_); > - > -Register / unregister APIs: > - int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_); > - int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_); > - int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_); > - int *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const char pass:[*]_fmt_, unsigned long long _addr_); > - int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, enum tep_func_arg_type _ret_type_, char pass:[*]_name_, _..._); > - int *tep_unregister_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, char pass:[*]_name_); > - > -Plugins management: > - struct tep_plugin_list pass:[*]*tep_load_plugins*(struct tep_handle pass:[*]_tep_); > - void *tep_unload_plugins*(struct tep_plugin_list pass:[*]_plugin_list_, struct tep_handle pass:[*]_tep_); > - char pass:[*]pass:[*]*tep_plugin_list_options*(void); > - void *tep_plugin_free_options_list*(char pass:[*]pass:[*]_list_); > - int *tep_plugin_add_options*(const char pass:[*]_name_, struct tep_plugin_option pass:[*]_options_); > - void *tep_plugin_remove_options*(struct tep_plugin_option pass:[*]_options_); > - void *tep_print_plugins*(struct trace_seq pass:[*]_s_, const char pass:[*]_prefix_, const char pass:[*]_suffix_, const struct tep_plugin_list pass:[*]_list_); > - > -Event related APIs: > - struct tep_event pass:[*]*tep_get_event*(struct tep_handle pass:[*]_tep_, int _index_); > - struct tep_event pass:[*]*tep_get_first_event*(struct tep_handle pass:[*]_tep_); > - int *tep_get_events_count*(struct tep_handle pass:[*]_tep_); > - struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); > - struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); > - void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._); > - > -Event finding: > - struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_); > - struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_); > - struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_); > - > -Parsing of event files: > - int *tep_parse_header_page*(struct tep_handle pass:[*]_tep_, char pass:[*]_buf_, unsigned long _size_, int _long_size_); > - enum tep_errno *tep_parse_event*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); > - enum tep_errno *tep_parse_format*(struct tep_handle pass:[*]_tep_, struct tep_event pass:[*]pass:[*]_eventp_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); > - > -APIs related to fields from event's format files: > - struct tep_format_field pass:[*]pass:[*]*tep_event_common_fields*(struct tep_event pass:[*]_event_); > - struct tep_format_field pass:[*]pass:[*]*tep_event_fields*(struct tep_event pass:[*]_event_); > - void pass:[*]*tep_get_field_raw*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int pass:[*]_len_, int _err_); > - int *tep_get_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); > - int *tep_get_common_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); > - int *tep_get_any_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); > - 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_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_); > - > -Event fields finding: > - struct tep_format_field pass:[*]*tep_find_common_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); > - struct tep_format_field pass:[*]*tep_find_field*(struct tep_event_ormat pass:[*]_event_, const char pass:[*]_name_); > - struct tep_format_field pass:[*]*tep_find_any_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); > - > -Functions resolver: > - int *tep_set_function_resolver*(struct tep_handle pass:[*]_tep_, tep_func_resolver_t pass:[*]_func_, void pass:[*]_priv_); > - void *tep_reset_function_resolver*(struct tep_handle pass:[*]_tep_); > - const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); > - unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); > - > -Filter management: > - struct tep_event_filter pass:[*]*tep_filter_alloc*(struct tep_handle pass:[*]_tep_); > - enum tep_errno *tep_filter_add_filter_str*(struct tep_event_filter pass:[*]_filter_, const char pass:[*]_filter_str_); > - enum tep_errno *tep_filter_match*(struct tep_event_filter pass:[*]_filter_, struct tep_record pass:[*]_record_); > - int *tep_filter_strerror*(struct tep_event_filter pass:[*]_filter_, enum tep_errno _err_, char pass:[*]buf, size_t _buflen_); > - int *tep_event_filtered*(struct tep_event_filter pass:[*]_filter_, int _event_id_); > - void *tep_filter_reset*(struct tep_event_filter pass:[*]_filter_); > - void *tep_filter_free*(struct tep_event_filter pass:[*]_filter_); > - char pass:[*]*tep_filter_make_string*(struct tep_event_filter pass:[*]_filter_, int _event_id_); > - int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, int _event_id_); > - int *tep_filter_copy*(struct tep_event_filter pass:[*]_dest_, struct tep_event_filter pass:[*]_source_); > - int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_); > - > -Parsing various data from the records: > - int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); > - int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); > - int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); > - int *tep_data_flags*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); > - > -Command and task related APIs: > - const char pass:[*]*tep_data_comm_from_pid*(struct tep_handle pass:[*]_tep_, int _pid_); > - struct cmdline pass:[*]*tep_data_pid_from_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, struct cmdline pass:[*]_next_); > - int *tep_register_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); > - int *tep_override_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); > - bool *tep_is_pid_registered*(struct tep_handle pass:[*]_tep_, int _pid_); > - int *tep_cmdline_pid*(struct tep_handle pass:[*]_tep_, struct cmdline pass:[*]_cmdline_); > - > -Endian related APIs: > - int *tep_is_bigendian*(void); > - unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, const void pass:[*]_ptr_, int _size_); > - bool *tep_is_file_bigendian*(struct tep_handle pass:[*]_tep_); > - void *tep_set_file_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); > - bool *tep_is_local_bigendian*(struct tep_handle pass:[*]_tep_); > - void *tep_set_local_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); > - > -Trace sequences: > -*#include * > - void *trace_seq_init*(struct trace_seq pass:[*]_s_); > - void *trace_seq_reset*(struct trace_seq pass:[*]_s_); > - void *trace_seq_destroy*(struct trace_seq pass:[*]_s_); > - int *trace_seq_printf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, ...); > - int *trace_seq_vprintf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, va_list _args_); > - int *trace_seq_puts*(struct trace_seq pass:[*]_s_, const char pass:[*]_str_); > - int *trace_seq_putc*(struct trace_seq pass:[*]_s_, unsigned char _c_); > - void *trace_seq_terminate*(struct trace_seq pass:[*]_s_); > - int *trace_seq_do_fprintf*(struct trace_seq pass:[*]_s_, FILE pass:[*]_fp_); > - int *trace_seq_do_printf*(struct trace_seq pass:[*]_s_); > --- > - > -DESCRIPTION > ------------ > -The libtraceevent(3) library provides APIs to access kernel tracepoint events, > -located in the tracefs file system under the events directory. > - > -ENVIRONMENT > ------------ > -[verse] > --- > -TRACEEVENT_PLUGIN_DIR > - Additional plugin directory. All shared object files, located in this directory will be loaded as traceevent plugins. > --- > - > -FILES > ------ > -[verse] > --- > -*event-parse.h* > - Header file to include in order to have access to the library APIs. > -*trace-seq.h* > - Header file to include in order to have access to trace sequences related APIs. > - Trace sequences are used to allow a function to call several other functions > - to create a string of data to use. > -*-ltraceevent* > - Linker switch to add when building a program that uses the library. > --- > - > -SEE ALSO > --------- > -_trace-cmd(1)_ > - > -AUTHOR > ------- > -[verse] > --- > -*Steven Rostedt* , author of *libtraceevent*. > -*Tzvetomir Stoyanov* , author of this man page. > --- > -REPORTING BUGS > --------------- > -Report bugs to > - > -LICENSE > -------- > -libtraceevent is Free Software licensed under the GNU LGPL 2.1 > - > -RESOURCES > ---------- > -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > diff --git a/tools/lib/traceevent/Documentation/manpage-1.72.xsl b/tools/lib/traceevent/Documentation/manpage-1.72.xsl > deleted file mode 100644 > index b4d315cb8c47..000000000000 > --- a/tools/lib/traceevent/Documentation/manpage-1.72.xsl > +++ /dev/null > @@ -1,14 +0,0 @@ > - > - - version="1.0"> > - > - > - > - > - > - > - > - > diff --git a/tools/lib/traceevent/Documentation/manpage-base.xsl b/tools/lib/traceevent/Documentation/manpage-base.xsl > deleted file mode 100644 > index a264fa616093..000000000000 > --- a/tools/lib/traceevent/Documentation/manpage-base.xsl > +++ /dev/null > @@ -1,35 +0,0 @@ > - > - - version="1.0"> > - > - > - > - > - > - > - > - > - > - > - > - sp > - > - > - > - > - > - > - > - br > - > - > - > diff --git a/tools/lib/traceevent/Documentation/manpage-bold-literal.xsl b/tools/lib/traceevent/Documentation/manpage-bold-literal.xsl > deleted file mode 100644 > index 608eb5df6281..000000000000 > --- a/tools/lib/traceevent/Documentation/manpage-bold-literal.xsl > +++ /dev/null > @@ -1,17 +0,0 @@ > - > - - version="1.0"> > - > - > - > - > - fB > - > - > - fR > - > - > - > diff --git a/tools/lib/traceevent/Documentation/manpage-normal.xsl b/tools/lib/traceevent/Documentation/manpage-normal.xsl > deleted file mode 100644 > index a48f5b11f3dc..000000000000 > --- a/tools/lib/traceevent/Documentation/manpage-normal.xsl > +++ /dev/null > @@ -1,13 +0,0 @@ > - > - - version="1.0"> > - > - > - > - > -\ > -. > - > - > diff --git a/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl b/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl > deleted file mode 100644 > index a63c7632a87d..000000000000 > --- a/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl > +++ /dev/null > @@ -1,21 +0,0 @@ > - > - - version="1.0"> > - > - > - > - > - > - > - > - > - > - > - > - > - > diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile > deleted file mode 100644 > index 98dfd4badea3..000000000000 > --- a/tools/lib/traceevent/Makefile > +++ /dev/null > @@ -1,300 +0,0 @@ > -# SPDX-License-Identifier: GPL-2.0 > -# trace-cmd version > -EP_VERSION = 1 > -EP_PATCHLEVEL = 1 > -EP_EXTRAVERSION = 0 > - > -# file format version > -FILE_VERSION = 6 > - > -MAKEFLAGS += --no-print-directory > - > - > -# 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 CC and AR, or setting CROSS_COMPILE as a prefix. > -$(call allow-override,CC,$(CROSS_COMPILE)gcc) > -$(call allow-override,AR,$(CROSS_COMPILE)ar) > -$(call allow-override,NM,$(CROSS_COMPILE)nm) > -$(call allow-override,PKG_CONFIG,pkg-config) > - > -EXT = -std=gnu99 > -INSTALL = install > - > -# Use DESTDIR for installing into a different root directory. > -# This is useful for building a package. The program will be > -# installed in this directory as if it was the root directory. > -# Then the build tool can move it later. > -DESTDIR ?= > -DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' > - > -LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) > -ifeq ($(LP64), 1) > - libdir_relative_temp = lib64 > -else > - libdir_relative_temp = lib > -endif > - > -libdir_relative ?= $(libdir_relative_temp) > -prefix ?= /usr/local > -libdir = $(prefix)/$(libdir_relative) > -man_dir = $(prefix)/share/man > -man_dir_SQ = '$(subst ','\'',$(man_dir))' > -pkgconfig_dir ?= $(word 1,$(shell $(PKG_CONFIG) \ > - --variable pc_path pkg-config | tr ":" " ")) > -includedir_relative = traceevent > -includedir = $(prefix)/include/$(includedir_relative) > -includedir_SQ = '$(subst ','\'',$(includedir))' > - > -export man_dir man_dir_SQ INSTALL > -export DESTDIR DESTDIR_SQ > -export EVENT_PARSE_VERSION > - > -include ../../scripts/Makefile.include > - > -# copy a bit from Linux kbuild > - > -ifeq ("$(origin V)", "command line") > - VERBOSE = $(V) > -endif > -ifndef VERBOSE > - VERBOSE = 0 > -endif > - > -ifeq ($(srctree),) > -srctree := $(patsubst %/,%,$(dir $(CURDIR))) > -srctree := $(patsubst %/,%,$(dir $(srctree))) > -srctree := $(patsubst %/,%,$(dir $(srctree))) > -#$(info Determined 'srctree' to be $(srctree)) > -endif > - > -export prefix libdir src obj > - > -# Shell quotes > -libdir_SQ = $(subst ','\'',$(libdir)) > -libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) > - > -CONFIG_INCLUDES = > -CONFIG_LIBS = > -CONFIG_FLAGS = > - > -VERSION = $(EP_VERSION) > -PATCHLEVEL = $(EP_PATCHLEVEL) > -EXTRAVERSION = $(EP_EXTRAVERSION) > - > -OBJ = $@ > -N = > - > -EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) > - > -LIB_TARGET = libtraceevent.a libtraceevent.so.$(EVENT_PARSE_VERSION) > -LIB_INSTALL = libtraceevent.a libtraceevent.so* > -LIB_INSTALL := $(addprefix $(OUTPUT),$(LIB_INSTALL)) > - > -INCLUDES = -I. -I $(srctree)/tools/include $(CONFIG_INCLUDES) > - > -# Set compile option CFLAGS > -ifdef EXTRA_CFLAGS > - CFLAGS := $(EXTRA_CFLAGS) > -else > - CFLAGS := -g -Wall > -endif > - > -# Append required CFLAGS > -override CFLAGS += -fPIC > -override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) > -override CFLAGS += $(udis86-flags) -D_GNU_SOURCE > - > -ifeq ($(VERBOSE),1) > - Q = > -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)/tools/build/Makefile.build dir=. obj > - > -TE_IN := $(OUTPUT)libtraceevent-in.o > -LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) > - > -CMD_TARGETS = $(LIB_TARGET) > - > -TARGETS = $(CMD_TARGETS) > - > -all: all_cmd plugins > - > -all_cmd: $(CMD_TARGETS) > - > -$(TE_IN): force > - $(Q)$(MAKE) $(build)=libtraceevent > - > -$(OUTPUT)libtraceevent.so.$(EVENT_PARSE_VERSION): $(TE_IN) > - $(QUIET_LINK)$(CC) --shared $(LDFLAGS) $^ -Wl,-soname,libtraceevent.so.$(EP_VERSION) -o $@ > - @ln -sf $(@F) $(OUTPUT)libtraceevent.so > - @ln -sf $(@F) $(OUTPUT)libtraceevent.so.$(EP_VERSION) > - > -$(OUTPUT)libtraceevent.a: $(TE_IN) > - $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ > - > -$(OUTPUT)%.so: $(OUTPUT)%-in.o > - $(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^ > - > -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); \ > - ) > $1 > -endef > - > -define update_version.h > - ($(call make_version.h, $@.tmp); \ > - if [ -r $@ ] && cmp -s $@ $@.tmp; then \ > - rm -f $@.tmp; \ > - else \ > - echo ' UPDATE $@'; \ > - mv -f $@.tmp $@; \ > - fi); > -endef > - > -ep_version.h: force > - $(Q)$(N)$(call update_version.h) > - > -VERSION_FILES = ep_version.h > - > -define update_dir > - (echo $1 > $@.tmp; \ > - if [ -r $@ ] && cmp -s $@ $@.tmp; then \ > - rm -f $@.tmp; \ > - else \ > - echo ' UPDATE $@'; \ > - mv -f $@.tmp $@; \ > - 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/' > - > -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 > - > -PKG_CONFIG_SOURCE_FILE = libtraceevent.pc > -PKG_CONFIG_FILE := $(addprefix $(OUTPUT),$(PKG_CONFIG_SOURCE_FILE)) > -define do_install_pkgconfig_file > - if [ -n "${pkgconfig_dir}" ]; then \ > - cp -f ${PKG_CONFIG_SOURCE_FILE}.template ${PKG_CONFIG_FILE}; \ > - sed -i "s|INSTALL_PREFIX|${1}|g" ${PKG_CONFIG_FILE}; \ > - sed -i "s|LIB_VERSION|${EVENT_PARSE_VERSION}|g" ${PKG_CONFIG_FILE}; \ > - sed -i "s|LIB_DIR|${libdir}|g" ${PKG_CONFIG_FILE}; \ > - sed -i "s|HEADER_DIR|$(includedir)|g" ${PKG_CONFIG_FILE}; \ > - $(call do_install,$(PKG_CONFIG_FILE),$(pkgconfig_dir),644); \ > - else \ > - (echo Failed to locate pkg-config directory) 1>&2; \ > - fi > -endef > - > -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) > - > -install_pkgconfig: > - $(call QUIET_INSTALL, $(PKG_CONFIG_FILE)) \ > - $(call do_install_pkgconfig_file,$(prefix)) > - > -install_headers: > - $(call QUIET_INSTALL, traceevent_headers) \ > - $(call do_install,event-parse.h,$(includedir_SQ),644); \ > - $(call do_install,event-utils.h,$(includedir_SQ),644); \ > - $(call do_install,trace-seq.h,$(includedir_SQ),644); \ > - $(call do_install,kbuffer.h,$(includedir_SQ),644); > - > -install: install_lib > - > -clean: clean_plugins > - $(call QUIET_CLEAN, libtraceevent) \ > - $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd; \ > - $(RM) TRACEEVENT-CFLAGS tags TAGS; \ > - $(RM) $(PKG_CONFIG_FILE) > - > -PHONY += doc > -doc: > - $(call descend,Documentation) > - > -PHONY += doc-clean > -doc-clean: > - $(call descend,Documentation,clean) > - > -PHONY += doc-install > -doc-install: > - $(call descend,Documentation,install) > - > -PHONY += doc-uninstall > -doc-uninstall: > - $(call descend,Documentation,uninstall) > - > -PHONY += help > -help: > - @echo 'Possible targets:' > - @echo'' > - @echo ' all - default, compile the library and the'\ > - 'plugins' > - @echo ' plugins - compile the plugins' > - @echo ' install - install the library, the plugins,'\ > - 'the header and pkgconfig files' > - @echo ' clean - clean the library and the plugins object files' > - @echo ' doc - compile the documentation files - man'\ > - 'and html pages, in the Documentation directory' > - @echo ' doc-clean - clean the documentation files' > - @echo ' doc-install - install the man pages' > - @echo ' doc-uninstall - uninstall the man pages' > - @echo'' > - > -PHONY += plugins > -plugins: > - $(call descend,plugins) > - > -PHONY += install_plugins > -install_plugins: > - $(call descend,plugins,install) > - > -PHONY += clean_plugins > -clean_plugins: > - $(call descend,plugins,clean) > - > -force: > - > -# Declare the contents of the .PHONY variable as phony. We keep that > -# information in a variable so we can use it in if_changed and friends. > -.PHONY: $(PHONY) > diff --git a/tools/lib/traceevent/event-parse-api.c b/tools/lib/traceevent/event-parse-api.c > deleted file mode 100644 > index f8361e45d446..000000000000 > --- a/tools/lib/traceevent/event-parse-api.c > +++ /dev/null > @@ -1,333 +0,0 @@ > -// SPDX-License-Identifier: LGPL-2.1 > -/* > - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt > - * > - */ > - > -#include "event-parse.h" > -#include "event-parse-local.h" > -#include "event-utils.h" > - > -/** > - * tep_get_event - returns the event with the given index > - * @tep: a handle to the tep_handle > - * @index: index of the requested event, in the range 0 .. nr_events > - * > - * This returns pointer to the element of the events array with the given index > - * If @tep is NULL, or @index is not in the range 0 .. nr_events, NULL is returned. > - */ > -struct tep_event *tep_get_event(struct tep_handle *tep, int index) > -{ > - if (tep && tep->events && index < tep->nr_events) > - return tep->events[index]; > - > - return NULL; > -} > - > -/** > - * tep_get_first_event - returns the first event in the events array > - * @tep: a handle to the tep_handle > - * > - * This returns pointer to the first element of the events array > - * If @tep is NULL, NULL is returned. > - */ > -struct tep_event *tep_get_first_event(struct tep_handle *tep) > -{ > - return tep_get_event(tep, 0); > -} > - > -/** > - * tep_get_events_count - get the number of defined events > - * @tep: a handle to the tep_handle > - * > - * This returns number of elements in event array > - * If @tep is NULL, 0 is returned. > - */ > -int tep_get_events_count(struct tep_handle *tep) > -{ > - if (tep) > - return tep->nr_events; > - return 0; > -} > - > -/** > - * tep_set_flag - set event parser flag > - * @tep: a handle to the tep_handle > - * @flag: flag, or combination of flags to be set > - * can be any combination from enum tep_flag > - * > - * This sets a flag or combination of flags from enum tep_flag > - */ > -void tep_set_flag(struct tep_handle *tep, int flag) > -{ > - if (tep) > - tep->flags |= flag; > -} > - > -/** > - * tep_clear_flag - clear event parser flag > - * @tep: a handle to the tep_handle > - * @flag: flag to be cleared > - * > - * This clears a tep flag > - */ > -void tep_clear_flag(struct tep_handle *tep, enum tep_flag flag) > -{ > - if (tep) > - tep->flags &= ~flag; > -} > - > -/** > - * tep_test_flag - check the state of event parser flag > - * @tep: a handle to the tep_handle > - * @flag: flag to be checked > - * > - * This returns the state of the requested tep flag. > - * Returns: true if the flag is set, false otherwise. > - */ > -bool tep_test_flag(struct tep_handle *tep, enum tep_flag flag) > -{ > - if (tep) > - return tep->flags & flag; > - return false; > -} > - > -__hidden unsigned short data2host2(struct tep_handle *tep, unsigned short data) > -{ > - unsigned short swap; > - > - if (!tep || tep->host_bigendian == tep->file_bigendian) > - return data; > - > - swap = ((data & 0xffULL) << 8) | > - ((data & (0xffULL << 8)) >> 8); > - > - return swap; > -} > - > -__hidden unsigned int data2host4(struct tep_handle *tep, unsigned int data) > -{ > - unsigned int swap; > - > - if (!tep || tep->host_bigendian == tep->file_bigendian) > - return data; > - > - swap = ((data & 0xffULL) << 24) | > - ((data & (0xffULL << 8)) << 8) | > - ((data & (0xffULL << 16)) >> 8) | > - ((data & (0xffULL << 24)) >> 24); > - > - return swap; > -} > - > -__hidden unsigned long long > -data2host8(struct tep_handle *tep, unsigned long long data) > -{ > - unsigned long long swap; > - > - if (!tep || tep->host_bigendian == tep->file_bigendian) > - return data; > - > - swap = ((data & 0xffULL) << 56) | > - ((data & (0xffULL << 8)) << 40) | > - ((data & (0xffULL << 16)) << 24) | > - ((data & (0xffULL << 24)) << 8) | > - ((data & (0xffULL << 32)) >> 8) | > - ((data & (0xffULL << 40)) >> 24) | > - ((data & (0xffULL << 48)) >> 40) | > - ((data & (0xffULL << 56)) >> 56); > - > - return swap; > -} > - > -/** > - * tep_get_header_page_size - get size of the header page > - * @tep: a handle to the tep_handle > - * > - * This returns size of the header page > - * If @tep is NULL, 0 is returned. > - */ > -int tep_get_header_page_size(struct tep_handle *tep) > -{ > - if (tep) > - return tep->header_page_size_size; > - return 0; > -} > - > -/** > - * tep_get_header_timestamp_size - get size of the timestamp in the header page > - * @tep: a handle to the tep_handle > - * > - * This returns size of the timestamp in the header page > - * If @tep is NULL, 0 is returned. > - */ > -int tep_get_header_timestamp_size(struct tep_handle *tep) > -{ > - if (tep) > - return tep->header_page_ts_size; > - return 0; > -} > - > -/** > - * tep_get_cpus - get the number of CPUs > - * @tep: a handle to the tep_handle > - * > - * This returns the number of CPUs > - * If @tep is NULL, 0 is returned. > - */ > -int tep_get_cpus(struct tep_handle *tep) > -{ > - if (tep) > - return tep->cpus; > - return 0; > -} > - > -/** > - * tep_set_cpus - set the number of CPUs > - * @tep: a handle to the tep_handle > - * > - * This sets the number of CPUs > - */ > -void tep_set_cpus(struct tep_handle *tep, int cpus) > -{ > - if (tep) > - tep->cpus = cpus; > -} > - > -/** > - * tep_get_long_size - get the size of a long integer on the traced machine > - * @tep: a handle to the tep_handle > - * > - * This returns the size of a long integer on the traced machine > - * If @tep is NULL, 0 is returned. > - */ > -int tep_get_long_size(struct tep_handle *tep) > -{ > - if (tep) > - return tep->long_size; > - return 0; > -} > - > -/** > - * tep_set_long_size - set the size of a long integer on the traced machine > - * @tep: a handle to the tep_handle > - * @size: size, in bytes, of a long integer > - * > - * This sets the size of a long integer on the traced machine > - */ > -void tep_set_long_size(struct tep_handle *tep, int long_size) > -{ > - if (tep) > - tep->long_size = long_size; > -} > - > -/** > - * tep_get_page_size - get the size of a memory page on the traced machine > - * @tep: a handle to the tep_handle > - * > - * This returns the size of a memory page on the traced machine > - * If @tep is NULL, 0 is returned. > - */ > -int tep_get_page_size(struct tep_handle *tep) > -{ > - if (tep) > - return tep->page_size; > - return 0; > -} > - > -/** > - * tep_set_page_size - set the size of a memory page on the traced machine > - * @tep: a handle to the tep_handle > - * @_page_size: size of a memory page, in bytes > - * > - * This sets the size of a memory page on the traced machine > - */ > -void tep_set_page_size(struct tep_handle *tep, int _page_size) > -{ > - if (tep) > - tep->page_size = _page_size; > -} > - > -/** > - * tep_is_file_bigendian - return the endian of the file > - * @tep: a handle to the tep_handle > - * > - * This returns true if the file is in big endian order > - * If @tep is NULL, false is returned. > - */ > -bool tep_is_file_bigendian(struct tep_handle *tep) > -{ > - if (tep) > - return (tep->file_bigendian == TEP_BIG_ENDIAN); > - return false; > -} > - > -/** > - * tep_set_file_bigendian - set if the file is in big endian order > - * @tep: a handle to the tep_handle > - * @endian: non zero, if the file is in big endian order > - * > - * This sets if the file is in big endian order > - */ > -void tep_set_file_bigendian(struct tep_handle *tep, enum tep_endian endian) > -{ > - if (tep) > - tep->file_bigendian = endian; > -} > - > -/** > - * tep_is_local_bigendian - return the endian of the saved local machine > - * @tep: a handle to the tep_handle > - * > - * This returns true if the saved local machine in @tep is big endian. > - * If @tep is NULL, false is returned. > - */ > -bool tep_is_local_bigendian(struct tep_handle *tep) > -{ > - if (tep) > - return (tep->host_bigendian == TEP_BIG_ENDIAN); > - return 0; > -} > - > -/** > - * tep_set_local_bigendian - set the stored local machine endian order > - * @tep: a handle to the tep_handle > - * @endian: non zero, if the local host has big endian order > - * > - * This sets the endian order for the local machine. > - */ > -void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian) > -{ > - if (tep) > - tep->host_bigendian = endian; > -} > - > -/** > - * tep_is_old_format - get if an old kernel is used > - * @tep: a handle to the tep_handle > - * > - * This returns true, if an old kernel is used to generate the tracing events or > - * false if a new kernel is used. Old kernels did not have header page info. > - * If @tep is NULL, false is returned. > - */ > -bool tep_is_old_format(struct tep_handle *tep) > -{ > - if (tep) > - return tep->old_format; > - return false; > -} > - > -/** > - * tep_set_test_filters - set a flag to test a filter string > - * @tep: a handle to the tep_handle > - * @test_filters: the new value of the test_filters flag > - * > - * This sets a flag to test a filter string. If this flag is set, when > - * tep_filter_add_filter_str() API as called,it will print the filter string > - * instead of adding it. > - */ > -void tep_set_test_filters(struct tep_handle *tep, int test_filters) > -{ > - if (tep) > - tep->test_filters = test_filters; > -} > diff --git a/tools/lib/traceevent/event-parse-local.h b/tools/lib/traceevent/event-parse-local.h > deleted file mode 100644 > index fd4bbcfbb849..000000000000 > --- a/tools/lib/traceevent/event-parse-local.h > +++ /dev/null > @@ -1,123 +0,0 @@ > -// SPDX-License-Identifier: LGPL-2.1 > -/* > - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt > - * > - */ > - > -#ifndef _PARSE_EVENTS_INT_H > -#define _PARSE_EVENTS_INT_H > - > -struct tep_cmdline; > -struct cmdline_list; > -struct func_map; > -struct func_list; > -struct event_handler; > -struct func_resolver; > -struct tep_plugins_dir; > - > -#define __hidden __attribute__((visibility ("hidden"))) > - > -struct tep_handle { > - int ref_count; > - > - int header_page_ts_offset; > - int header_page_ts_size; > - int header_page_size_offset; > - int header_page_size_size; > - int header_page_data_offset; > - int header_page_data_size; > - int header_page_overwrite; > - > - enum tep_endian file_bigendian; > - enum tep_endian host_bigendian; > - > - int old_format; > - > - int cpus; > - int long_size; > - int page_size; > - > - struct tep_cmdline *cmdlines; > - struct cmdline_list *cmdlist; > - int cmdline_count; > - > - struct func_map *func_map; > - struct func_resolver *func_resolver; > - struct func_list *funclist; > - unsigned int func_count; > - > - struct printk_map *printk_map; > - struct printk_list *printklist; > - unsigned int printk_count; > - > - struct tep_event **events; > - int nr_events; > - struct tep_event **sort_events; > - enum tep_event_sort_type last_type; > - > - int type_offset; > - int type_size; > - > - int pid_offset; > - int pid_size; > - > - int pc_offset; > - int pc_size; > - > - int flags_offset; > - int flags_size; > - > - int ld_offset; > - int ld_size; > - > - int test_filters; > - > - int flags; > - > - struct tep_format_field *bprint_ip_field; > - struct tep_format_field *bprint_fmt_field; > - struct tep_format_field *bprint_buf_field; > - > - struct event_handler *handlers; > - struct tep_function_handler *func_handlers; > - > - /* cache */ > - struct tep_event *last_event; > - > - struct tep_plugins_dir *plugins_dir; > -}; > - > -enum tep_print_parse_type { > - PRINT_FMT_STRING, > - PRINT_FMT_ARG_DIGIT, > - PRINT_FMT_ARG_POINTER, > - PRINT_FMT_ARG_STRING, > -}; > - > -struct tep_print_parse { > - struct tep_print_parse *next; > - > - char *format; > - int ls; > - enum tep_print_parse_type type; > - struct tep_print_arg *arg; > - struct tep_print_arg *len_as_arg; > -}; > - > -void free_tep_event(struct tep_event *event); > -void free_tep_format_field(struct tep_format_field *field); > -void free_tep_plugin_paths(struct tep_handle *tep); > - > -unsigned short data2host2(struct tep_handle *tep, unsigned short data); > -unsigned int data2host4(struct tep_handle *tep, unsigned int data); > -unsigned long long data2host8(struct tep_handle *tep, unsigned long long data); > - > -/* access to the internal parser */ > -int peek_char(void); > -void init_input_buf(const char *buf, unsigned long long size); > -unsigned long long get_input_buf_ptr(void); > -const char *get_input_buf(void); > -enum tep_event_type read_token(char **tok); > -void free_token(char *tok); > - > -#endif /* _PARSE_EVENTS_INT_H */ > diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c > deleted file mode 100644 > index 8e24c4c78c7f..000000000000 > --- a/tools/lib/traceevent/event-parse.c > +++ /dev/null > @@ -1,7624 +0,0 @@ > -// SPDX-License-Identifier: LGPL-2.1 > -/* > - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt > - * > - * > - * The parts for function graph printing was taken and modified from the > - * Linux Kernel that were written by > - * - Copyright (C) 2009 Frederic Weisbecker, > - * Frederic Weisbecker gave his permission to relicense the code to > - * the Lesser General Public License. > - */ > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > - > -#include > -#include "event-parse.h" > - > -#include "event-parse-local.h" > -#include "event-utils.h" > -#include "trace-seq.h" > - > -static const char *input_buf; > -static unsigned long long input_buf_ptr; > -static unsigned long long input_buf_siz; > - > -static int is_flag_field; > -static int is_symbolic_field; > - > -static int show_warning = 1; > - > -#define do_warning(fmt, ...) \ > - do { \ > - if (show_warning) \ > - warning(fmt, ##__VA_ARGS__); \ > - } while (0) > - > -#define do_warning_event(event, fmt, ...) \ > - do { \ > - if (!show_warning) \ > - continue; \ > - \ > - if (event) \ > - warning("[%s:%s] " fmt, event->system, \ > - event->name, ##__VA_ARGS__); \ > - else \ > - warning(fmt, ##__VA_ARGS__); \ > - } while (0) > - > -/** > - * init_input_buf - init buffer for parsing > - * @buf: buffer to parse > - * @size: the size of the buffer > - * > - * Initializes the internal buffer that tep_read_token() will parse. > - */ > -__hidden void init_input_buf(const char *buf, unsigned long long size) > -{ > - input_buf = buf; > - input_buf_siz = size; > - input_buf_ptr = 0; > -} > - > -__hidden const char *get_input_buf(void) > -{ > - return input_buf; > -} > - > -__hidden unsigned long long get_input_buf_ptr(void) > -{ > - return input_buf_ptr; > -} > - > -struct event_handler { > - struct event_handler *next; > - int id; > - const char *sys_name; > - const char *event_name; > - tep_event_handler_func func; > - void *context; > -}; > - > -struct func_params { > - struct func_params *next; > - enum tep_func_arg_type type; > -}; > - > -struct tep_function_handler { > - struct tep_function_handler *next; > - enum tep_func_arg_type ret_type; > - char *name; > - tep_func_handler func; > - struct func_params *params; > - int nr_args; > -}; > - > -static unsigned long long > -process_defined_func(struct trace_seq *s, void *data, int size, > - struct tep_event *event, struct tep_print_arg *arg); > - > -static void free_func_handle(struct tep_function_handler *func); > - > -void breakpoint(void) > -{ > - static int x; > - x++; > -} > - > -static struct tep_print_arg *alloc_arg(void) > -{ > - return calloc(1, sizeof(struct tep_print_arg)); > -} > - > -struct tep_cmdline { > - char *comm; > - int pid; > -}; > - > -static int cmdline_cmp(const void *a, const void *b) > -{ > - const struct tep_cmdline *ca = a; > - const struct tep_cmdline *cb = b; > - > - if (ca->pid < cb->pid) > - return -1; > - if (ca->pid > cb->pid) > - return 1; > - > - return 0; > -} > - > -/* Looking for where to place the key */ > -static int cmdline_slot_cmp(const void *a, const void *b) > -{ > - const struct tep_cmdline *ca = a; > - const struct tep_cmdline *cb = b; > - const struct tep_cmdline *cb1 = cb + 1; > - > - if (ca->pid < cb->pid) > - return -1; > - > - if (ca->pid > cb->pid) { > - if (ca->pid <= cb1->pid) > - return 0; > - return 1; > - } > - > - return 0; > -} > - > -struct cmdline_list { > - struct cmdline_list *next; > - char *comm; > - int pid; > -}; > - > -static int cmdline_init(struct tep_handle *tep) > -{ > - struct cmdline_list *cmdlist = tep->cmdlist; > - struct cmdline_list *item; > - struct tep_cmdline *cmdlines; > - int i; > - > - cmdlines = malloc(sizeof(*cmdlines) * tep->cmdline_count); > - if (!cmdlines) > - return -1; > - > - i = 0; > - while (cmdlist) { > - cmdlines[i].pid = cmdlist->pid; > - cmdlines[i].comm = cmdlist->comm; > - i++; > - item = cmdlist; > - cmdlist = cmdlist->next; > - free(item); > - } > - > - qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp); > - > - tep->cmdlines = cmdlines; > - tep->cmdlist = NULL; > - > - return 0; > -} > - > -static const char *find_cmdline(struct tep_handle *tep, int pid) > -{ > - const struct tep_cmdline *comm; > - struct tep_cmdline key; > - > - if (!pid) > - return ""; > - > - if (!tep->cmdlines && cmdline_init(tep)) > - return ""; > - > - key.pid = pid; > - > - comm = bsearch(&key, tep->cmdlines, tep->cmdline_count, > - sizeof(*tep->cmdlines), cmdline_cmp); > - > - if (comm) > - return comm->comm; > - return "<...>"; > -} > - > -/** > - * tep_is_pid_registered - return if a pid has a cmdline registered > - * @tep: a handle to the trace event parser context > - * @pid: The pid to check if it has a cmdline registered with. > - * > - * Returns true if the pid has a cmdline mapped to it > - * false otherwise. > - */ > -bool tep_is_pid_registered(struct tep_handle *tep, int pid) > -{ > - const struct tep_cmdline *comm; > - struct tep_cmdline key; > - > - if (!pid) > - return true; > - > - if (!tep->cmdlines && cmdline_init(tep)) > - return false; > - > - key.pid = pid; > - > - comm = bsearch(&key, tep->cmdlines, tep->cmdline_count, > - sizeof(*tep->cmdlines), cmdline_cmp); > - > - if (comm) > - return true; > - return false; > -} > - > -/* > - * If the command lines have been converted to an array, then > - * we must add this pid. This is much slower than when cmdlines > - * are added before the array is initialized. > - */ > -static int add_new_comm(struct tep_handle *tep, > - const char *comm, int pid, bool override) > -{ > - struct tep_cmdline *cmdlines = tep->cmdlines; > - struct tep_cmdline *cmdline; > - struct tep_cmdline key; > - char *new_comm; > - int cnt; > - > - if (!pid) > - return 0; > - > - /* avoid duplicates */ > - key.pid = pid; > - > - cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count, > - sizeof(*tep->cmdlines), cmdline_cmp); > - if (cmdline) { > - if (!override) { > - errno = EEXIST; > - return -1; > - } > - new_comm = strdup(comm); > - if (!new_comm) { > - errno = ENOMEM; > - return -1; > - } > - free(cmdline->comm); > - cmdline->comm = new_comm; > - > - return 0; > - } > - > - cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (tep->cmdline_count + 1)); > - if (!cmdlines) { > - errno = ENOMEM; > - return -1; > - } > - tep->cmdlines = cmdlines; > - > - key.comm = strdup(comm); > - if (!key.comm) { > - errno = ENOMEM; > - return -1; > - } > - > - if (!tep->cmdline_count) { > - /* no entries yet */ > - tep->cmdlines[0] = key; > - tep->cmdline_count++; > - return 0; > - } > - > - /* Now find where we want to store the new cmdline */ > - cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count - 1, > - sizeof(*tep->cmdlines), cmdline_slot_cmp); > - > - cnt = tep->cmdline_count; > - if (cmdline) { > - /* cmdline points to the one before the spot we want */ > - cmdline++; > - cnt -= cmdline - tep->cmdlines; > - > - } else { > - /* The new entry is either before or after the list */ > - if (key.pid > tep->cmdlines[tep->cmdline_count - 1].pid) { > - tep->cmdlines[tep->cmdline_count++] = key; > - return 0; > - } > - cmdline = &tep->cmdlines[0]; > - } > - memmove(cmdline + 1, cmdline, (cnt * sizeof(*cmdline))); > - *cmdline = key; > - > - tep->cmdline_count++; > - > - return 0; > -} > - > -static int _tep_register_comm(struct tep_handle *tep, > - const char *comm, int pid, bool override) > -{ > - struct cmdline_list *item; > - > - if (tep->cmdlines) > - return add_new_comm(tep, comm, pid, override); > - > - item = malloc(sizeof(*item)); > - if (!item) > - return -1; > - > - if (comm) > - item->comm = strdup(comm); > - else > - item->comm = strdup("<...>"); > - if (!item->comm) { > - free(item); > - return -1; > - } > - item->pid = pid; > - item->next = tep->cmdlist; > - > - tep->cmdlist = item; > - tep->cmdline_count++; > - > - return 0; > -} > - > -/** > - * tep_register_comm - register a pid / comm mapping > - * @tep: a handle to the trace event parser context > - * @comm: the command line to register > - * @pid: the pid to map the command line to > - * > - * This adds a mapping to search for command line names with > - * a given pid. The comm is duplicated. If a command with the same pid > - * already exist, -1 is returned and errno is set to EEXIST > - */ > -int tep_register_comm(struct tep_handle *tep, const char *comm, int pid) > -{ > - return _tep_register_comm(tep, comm, pid, false); > -} > - > -/** > - * tep_override_comm - register a pid / comm mapping > - * @tep: a handle to the trace event parser context > - * @comm: the command line to register > - * @pid: the pid to map the command line to > - * > - * This adds a mapping to search for command line names with > - * a given pid. The comm is duplicated. If a command with the same pid > - * already exist, the command string is udapted with the new one > - */ > -int tep_override_comm(struct tep_handle *tep, const char *comm, int pid) > -{ > - if (!tep->cmdlines && cmdline_init(tep)) { > - errno = ENOMEM; > - return -1; > - } > - return _tep_register_comm(tep, comm, pid, true); > -} > - > -struct func_map { > - unsigned long long addr; > - char *func; > - char *mod; > -}; > - > -struct func_list { > - struct func_list *next; > - unsigned long long addr; > - char *func; > - char *mod; > -}; > - > -static int func_cmp(const void *a, const void *b) > -{ > - const struct func_map *fa = a; > - const struct func_map *fb = b; > - > - if (fa->addr < fb->addr) > - return -1; > - if (fa->addr > fb->addr) > - return 1; > - > - return 0; > -} > - > -/* > - * We are searching for a record in between, not an exact > - * match. > - */ > -static int func_bcmp(const void *a, const void *b) > -{ > - const struct func_map *fa = a; > - const struct func_map *fb = b; > - > - if ((fa->addr == fb->addr) || > - > - (fa->addr > fb->addr && > - fa->addr < (fb+1)->addr)) > - return 0; > - > - if (fa->addr < fb->addr) > - return -1; > - > - return 1; > -} > - > -static int func_map_init(struct tep_handle *tep) > -{ > - struct func_list *funclist; > - struct func_list *item; > - struct func_map *func_map; > - int i; > - > - func_map = malloc(sizeof(*func_map) * (tep->func_count + 1)); > - if (!func_map) > - return -1; > - > - funclist = tep->funclist; > - > - i = 0; > - while (funclist) { > - func_map[i].func = funclist->func; > - func_map[i].addr = funclist->addr; > - func_map[i].mod = funclist->mod; > - i++; > - item = funclist; > - funclist = funclist->next; > - free(item); > - } > - > - qsort(func_map, tep->func_count, sizeof(*func_map), func_cmp); > - > - /* > - * Add a special record at the end. > - */ > - func_map[tep->func_count].func = NULL; > - func_map[tep->func_count].addr = 0; > - func_map[tep->func_count].mod = NULL; > - > - tep->func_map = func_map; > - tep->funclist = NULL; > - > - return 0; > -} > - > -static struct func_map * > -__find_func(struct tep_handle *tep, unsigned long long addr) > -{ > - struct func_map *func; > - struct func_map key; > - > - if (!tep->func_map) > - func_map_init(tep); > - > - key.addr = addr; > - > - func = bsearch(&key, tep->func_map, tep->func_count, > - sizeof(*tep->func_map), func_bcmp); > - > - return func; > -} > - > -struct func_resolver { > - tep_func_resolver_t *func; > - void *priv; > - struct func_map map; > -}; > - > -/** > - * tep_set_function_resolver - set an alternative function resolver > - * @tep: a handle to the trace event parser context > - * @resolver: function to be used > - * @priv: resolver function private state. > - * > - * Some tools may have already a way to resolve kernel functions, allow them to > - * keep using it instead of duplicating all the entries inside tep->funclist. > - */ > -int tep_set_function_resolver(struct tep_handle *tep, > - tep_func_resolver_t *func, void *priv) > -{ > - struct func_resolver *resolver = malloc(sizeof(*resolver)); > - > - if (resolver == NULL) > - return -1; > - > - resolver->func = func; > - resolver->priv = priv; > - > - free(tep->func_resolver); > - tep->func_resolver = resolver; > - > - return 0; > -} > - > -/** > - * tep_reset_function_resolver - reset alternative function resolver > - * @tep: a handle to the trace event parser context > - * > - * Stop using whatever alternative resolver was set, use the default > - * one instead. > - */ > -void tep_reset_function_resolver(struct tep_handle *tep) > -{ > - free(tep->func_resolver); > - tep->func_resolver = NULL; > -} > - > -static struct func_map * > -find_func(struct tep_handle *tep, unsigned long long addr) > -{ > - struct func_map *map; > - > - if (!tep->func_resolver) > - return __find_func(tep, addr); > - > - map = &tep->func_resolver->map; > - map->mod = NULL; > - map->addr = addr; > - map->func = tep->func_resolver->func(tep->func_resolver->priv, > - &map->addr, &map->mod); > - if (map->func == NULL) > - return NULL; > - > - return map; > -} > - > -/** > - * tep_find_function - find a function by a given address > - * @tep: a handle to the trace event parser context > - * @addr: the address to find the function with > - * > - * Returns a pointer to the function stored that has the given > - * address. Note, the address does not have to be exact, it > - * will select the function that would contain the address. > - */ > -const char *tep_find_function(struct tep_handle *tep, unsigned long long addr) > -{ > - struct func_map *map; > - > - map = find_func(tep, addr); > - if (!map) > - return NULL; > - > - return map->func; > -} > - > -/** > - * tep_find_function_address - find a function address by a given address > - * @tep: a handle to the trace event parser context > - * @addr: the address to find the function with > - * > - * Returns the address the function starts at. This can be used in > - * conjunction with tep_find_function to print both the function > - * name and the function offset. > - */ > -unsigned long long > -tep_find_function_address(struct tep_handle *tep, unsigned long long addr) > -{ > - struct func_map *map; > - > - map = find_func(tep, addr); > - if (!map) > - return 0; > - > - return map->addr; > -} > - > -/** > - * tep_register_function - register a function with a given address > - * @tep: a handle to the trace event parser context > - * @function: the function name to register > - * @addr: the address the function starts at > - * @mod: the kernel module the function may be in (NULL for none) > - * > - * This registers a function name with an address and module. > - * The @func passed in is duplicated. > - */ > -int tep_register_function(struct tep_handle *tep, char *func, > - unsigned long long addr, char *mod) > -{ > - struct func_list *item = malloc(sizeof(*item)); > - > - if (!item) > - return -1; > - > - item->next = tep->funclist; > - item->func = strdup(func); > - if (!item->func) > - goto out_free; > - > - if (mod) { > - item->mod = strdup(mod); > - if (!item->mod) > - goto out_free_func; > - } else > - item->mod = NULL; > - item->addr = addr; > - > - tep->funclist = item; > - tep->func_count++; > - > - return 0; > - > -out_free_func: > - free(item->func); > - item->func = NULL; > -out_free: > - free(item); > - errno = ENOMEM; > - return -1; > -} > - > -/** > - * tep_print_funcs - print out the stored functions > - * @tep: a handle to the trace event parser context > - * > - * This prints out the stored functions. > - */ > -void tep_print_funcs(struct tep_handle *tep) > -{ > - int i; > - > - if (!tep->func_map) > - func_map_init(tep); > - > - for (i = 0; i < (int)tep->func_count; i++) { > - printf("%016llx %s", > - tep->func_map[i].addr, > - tep->func_map[i].func); > - if (tep->func_map[i].mod) > - printf(" [%s]\n", tep->func_map[i].mod); > - else > - printf("\n"); > - } > -} > - > -struct printk_map { > - unsigned long long addr; > - char *printk; > -}; > - > -struct printk_list { > - struct printk_list *next; > - unsigned long long addr; > - char *printk; > -}; > - > -static int printk_cmp(const void *a, const void *b) > -{ > - const struct printk_map *pa = a; > - const struct printk_map *pb = b; > - > - if (pa->addr < pb->addr) > - return -1; > - if (pa->addr > pb->addr) > - return 1; > - > - return 0; > -} > - > -static int printk_map_init(struct tep_handle *tep) > -{ > - struct printk_list *printklist; > - struct printk_list *item; > - struct printk_map *printk_map; > - int i; > - > - printk_map = malloc(sizeof(*printk_map) * (tep->printk_count + 1)); > - if (!printk_map) > - return -1; > - > - printklist = tep->printklist; > - > - i = 0; > - while (printklist) { > - printk_map[i].printk = printklist->printk; > - printk_map[i].addr = printklist->addr; > - i++; > - item = printklist; > - printklist = printklist->next; > - free(item); > - } > - > - qsort(printk_map, tep->printk_count, sizeof(*printk_map), printk_cmp); > - > - tep->printk_map = printk_map; > - tep->printklist = NULL; > - > - return 0; > -} > - > -static struct printk_map * > -find_printk(struct tep_handle *tep, unsigned long long addr) > -{ > - struct printk_map *printk; > - struct printk_map key; > - > - if (!tep->printk_map && printk_map_init(tep)) > - return NULL; > - > - key.addr = addr; > - > - printk = bsearch(&key, tep->printk_map, tep->printk_count, > - sizeof(*tep->printk_map), printk_cmp); > - > - return printk; > -} > - > -/** > - * tep_register_print_string - register a string by its address > - * @tep: a handle to the trace event parser context > - * @fmt: the string format to register > - * @addr: the address the string was located at > - * > - * This registers a string by the address it was stored in the kernel. > - * The @fmt passed in is duplicated. > - */ > -int tep_register_print_string(struct tep_handle *tep, const char *fmt, > - unsigned long long addr) > -{ > - struct printk_list *item = malloc(sizeof(*item)); > - char *p; > - > - if (!item) > - return -1; > - > - item->next = tep->printklist; > - item->addr = addr; > - > - /* Strip off quotes and '\n' from the end */ > - if (fmt[0] == '"') > - fmt++; > - item->printk = strdup(fmt); > - if (!item->printk) > - goto out_free; > - > - p = item->printk + strlen(item->printk) - 1; > - if (*p == '"') > - *p = 0; > - > - p -= 2; > - if (strcmp(p, "\\n") == 0) > - *p = 0; > - > - tep->printklist = item; > - tep->printk_count++; > - > - return 0; > - > -out_free: > - free(item); > - errno = ENOMEM; > - return -1; > -} > - > -/** > - * tep_print_printk - print out the stored strings > - * @tep: a handle to the trace event parser context > - * > - * This prints the string formats that were stored. > - */ > -void tep_print_printk(struct tep_handle *tep) > -{ > - int i; > - > - if (!tep->printk_map) > - printk_map_init(tep); > - > - for (i = 0; i < (int)tep->printk_count; i++) { > - printf("%016llx %s\n", > - tep->printk_map[i].addr, > - tep->printk_map[i].printk); > - } > -} > - > -static struct tep_event *alloc_event(void) > -{ > - return calloc(1, sizeof(struct tep_event)); > -} > - > -static int add_event(struct tep_handle *tep, struct tep_event *event) > -{ > - int i; > - struct tep_event **events = realloc(tep->events, sizeof(event) * > - (tep->nr_events + 1)); > - if (!events) > - return -1; > - > - tep->events = events; > - > - for (i = 0; i < tep->nr_events; i++) { > - if (tep->events[i]->id > event->id) > - break; > - } > - if (i < tep->nr_events) > - memmove(&tep->events[i + 1], > - &tep->events[i], > - sizeof(event) * (tep->nr_events - i)); > - > - tep->events[i] = event; > - tep->nr_events++; > - > - event->tep = tep; > - > - return 0; > -} > - > -static int event_item_type(enum tep_event_type type) > -{ > - switch (type) { > - case TEP_EVENT_ITEM ... TEP_EVENT_SQUOTE: > - return 1; > - case TEP_EVENT_ERROR ... TEP_EVENT_DELIM: > - default: > - return 0; > - } > -} > - > -static void free_flag_sym(struct tep_print_flag_sym *fsym) > -{ > - struct tep_print_flag_sym *next; > - > - while (fsym) { > - next = fsym->next; > - free(fsym->value); > - free(fsym->str); > - free(fsym); > - fsym = next; > - } > -} > - > -static void free_arg(struct tep_print_arg *arg) > -{ > - struct tep_print_arg *farg; > - > - if (!arg) > - return; > - > - switch (arg->type) { > - case TEP_PRINT_ATOM: > - free(arg->atom.atom); > - break; > - case TEP_PRINT_FIELD: > - free(arg->field.name); > - break; > - case TEP_PRINT_FLAGS: > - free_arg(arg->flags.field); > - free(arg->flags.delim); > - free_flag_sym(arg->flags.flags); > - break; > - case TEP_PRINT_SYMBOL: > - free_arg(arg->symbol.field); > - free_flag_sym(arg->symbol.symbols); > - break; > - case TEP_PRINT_HEX: > - case TEP_PRINT_HEX_STR: > - free_arg(arg->hex.field); > - free_arg(arg->hex.size); > - break; > - case TEP_PRINT_INT_ARRAY: > - free_arg(arg->int_array.field); > - free_arg(arg->int_array.count); > - free_arg(arg->int_array.el_size); > - break; > - case TEP_PRINT_TYPE: > - free(arg->typecast.type); > - free_arg(arg->typecast.item); > - break; > - case TEP_PRINT_STRING: > - case TEP_PRINT_BSTRING: > - free(arg->string.string); > - break; > - case TEP_PRINT_BITMASK: > - free(arg->bitmask.bitmask); > - break; > - case TEP_PRINT_DYNAMIC_ARRAY: > - case TEP_PRINT_DYNAMIC_ARRAY_LEN: > - free(arg->dynarray.index); > - break; > - case TEP_PRINT_OP: > - free(arg->op.op); > - free_arg(arg->op.left); > - free_arg(arg->op.right); > - break; > - case TEP_PRINT_FUNC: > - while (arg->func.args) { > - farg = arg->func.args; > - arg->func.args = farg->next; > - free_arg(farg); > - } > - break; > - > - case TEP_PRINT_NULL: > - default: > - break; > - } > - > - free(arg); > -} > - > -static enum tep_event_type get_type(int ch) > -{ > - if (ch == '\n') > - return TEP_EVENT_NEWLINE; > - if (isspace(ch)) > - return TEP_EVENT_SPACE; > - if (isalnum(ch) || ch == '_') > - return TEP_EVENT_ITEM; > - if (ch == '\'') > - return TEP_EVENT_SQUOTE; > - if (ch == '"') > - return TEP_EVENT_DQUOTE; > - if (!isprint(ch)) > - return TEP_EVENT_NONE; > - if (ch == '(' || ch == ')' || ch == ',') > - return TEP_EVENT_DELIM; > - > - return TEP_EVENT_OP; > -} > - > -static int __read_char(void) > -{ > - if (input_buf_ptr >= input_buf_siz) > - return -1; > - > - return input_buf[input_buf_ptr++]; > -} > - > -/** > - * peek_char - peek at the next character that will be read > - * > - * Returns the next character read, or -1 if end of buffer. > - */ > -__hidden int peek_char(void) > -{ > - if (input_buf_ptr >= input_buf_siz) > - return -1; > - > - return input_buf[input_buf_ptr]; > -} > - > -static int extend_token(char **tok, char *buf, int size) > -{ > - char *newtok = realloc(*tok, size); > - > - if (!newtok) { > - free(*tok); > - *tok = NULL; > - return -1; > - } > - > - if (!*tok) > - strcpy(newtok, buf); > - else > - strcat(newtok, buf); > - *tok = newtok; > - > - return 0; > -} > - > -static enum tep_event_type force_token(const char *str, char **tok); > - > -static enum tep_event_type __read_token(char **tok) > -{ > - char buf[BUFSIZ]; > - int ch, last_ch, quote_ch, next_ch; > - int i = 0; > - int tok_size = 0; > - enum tep_event_type type; > - > - *tok = NULL; > - > - > - ch = __read_char(); > - if (ch < 0) > - return TEP_EVENT_NONE; > - > - type = get_type(ch); > - if (type == TEP_EVENT_NONE) > - return type; > - > - buf[i++] = ch; > - > - switch (type) { > - case TEP_EVENT_NEWLINE: > - case TEP_EVENT_DELIM: > - if (asprintf(tok, "%c", ch) < 0) > - return TEP_EVENT_ERROR; > - > - return type; > - > - case TEP_EVENT_OP: > - switch (ch) { > - case '-': > - next_ch = peek_char(); > - if (next_ch == '>') { > - buf[i++] = __read_char(); > - break; > - } > - /* fall through */ > - case '+': > - case '|': > - case '&': > - case '>': > - case '<': > - last_ch = ch; > - ch = peek_char(); > - if (ch != last_ch) > - goto test_equal; > - buf[i++] = __read_char(); > - switch (last_ch) { > - case '>': > - case '<': > - goto test_equal; > - default: > - break; > - } > - break; > - case '!': > - case '=': > - goto test_equal; > - default: /* what should we do instead? */ > - break; > - } > - buf[i] = 0; > - *tok = strdup(buf); > - return type; > - > - test_equal: > - ch = peek_char(); > - if (ch == '=') > - buf[i++] = __read_char(); > - goto out; > - > - case TEP_EVENT_DQUOTE: > - case TEP_EVENT_SQUOTE: > - /* don't keep quotes */ > - i--; > - quote_ch = ch; > - last_ch = 0; > - concat: > - do { > - if (i == (BUFSIZ - 1)) { > - buf[i] = 0; > - tok_size += BUFSIZ; > - > - if (extend_token(tok, buf, tok_size) < 0) > - return TEP_EVENT_NONE; > - i = 0; > - } > - last_ch = ch; > - ch = __read_char(); > - buf[i++] = ch; > - /* the '\' '\' will cancel itself */ > - if (ch == '\\' && last_ch == '\\') > - last_ch = 0; > - } while (ch != quote_ch || last_ch == '\\'); > - /* remove the last quote */ > - i--; > - > - /* > - * For strings (double quotes) check the next token. > - * If it is another string, concatinate the two. > - */ > - if (type == TEP_EVENT_DQUOTE) { > - unsigned long long save_input_buf_ptr = input_buf_ptr; > - > - do { > - ch = __read_char(); > - } while (isspace(ch)); > - if (ch == '"') > - goto concat; > - input_buf_ptr = save_input_buf_ptr; > - } > - > - goto out; > - > - case TEP_EVENT_ERROR ... TEP_EVENT_SPACE: > - case TEP_EVENT_ITEM: > - default: > - break; > - } > - > - while (get_type(peek_char()) == type) { > - if (i == (BUFSIZ - 1)) { > - buf[i] = 0; > - tok_size += BUFSIZ; > - > - if (extend_token(tok, buf, tok_size) < 0) > - return TEP_EVENT_NONE; > - i = 0; > - } > - ch = __read_char(); > - buf[i++] = ch; > - } > - > - out: > - buf[i] = 0; > - if (extend_token(tok, buf, tok_size + i + 1) < 0) > - return TEP_EVENT_NONE; > - > - if (type == TEP_EVENT_ITEM) { > - /* > - * Older versions of the kernel has a bug that > - * creates invalid symbols and will break the mac80211 > - * parsing. This is a work around to that bug. > - * > - * See Linux kernel commit: > - * 811cb50baf63461ce0bdb234927046131fc7fa8b > - */ > - if (strcmp(*tok, "LOCAL_PR_FMT") == 0) { > - free(*tok); > - *tok = NULL; > - return force_token("\"%s\" ", tok); > - } else if (strcmp(*tok, "STA_PR_FMT") == 0) { > - free(*tok); > - *tok = NULL; > - return force_token("\" sta:%pM\" ", tok); > - } else if (strcmp(*tok, "VIF_PR_FMT") == 0) { > - free(*tok); > - *tok = NULL; > - return force_token("\" vif:%p(%d)\" ", tok); > - } > - } > - > - return type; > -} > - > -static enum tep_event_type force_token(const char *str, char **tok) > -{ > - const char *save_input_buf; > - unsigned long long save_input_buf_ptr; > - unsigned long long save_input_buf_siz; > - enum tep_event_type type; > - > - /* save off the current input pointers */ > - save_input_buf = input_buf; > - save_input_buf_ptr = input_buf_ptr; > - save_input_buf_siz = input_buf_siz; > - > - init_input_buf(str, strlen(str)); > - > - type = __read_token(tok); > - > - /* reset back to original token */ > - input_buf = save_input_buf; > - input_buf_ptr = save_input_buf_ptr; > - input_buf_siz = save_input_buf_siz; > - > - return type; > -} > - > -/** > - * free_token - free a token returned by tep_read_token > - * @token: the token to free > - */ > -__hidden void free_token(char *tok) > -{ > - if (tok) > - free(tok); > -} > - > -/** > - * read_token - access to utilities to use the tep parser > - * @tok: The token to return > - * > - * This will parse tokens from the string given by > - * tep_init_data(). > - * > - * Returns the token type. > - */ > -__hidden enum tep_event_type read_token(char **tok) > -{ > - enum tep_event_type type; > - > - for (;;) { > - type = __read_token(tok); > - if (type != TEP_EVENT_SPACE) > - return type; > - > - free_token(*tok); > - } > - > - /* not reached */ > - *tok = NULL; > - return TEP_EVENT_NONE; > -} > - > -/* no newline */ > -static enum tep_event_type read_token_item(char **tok) > -{ > - enum tep_event_type type; > - > - for (;;) { > - type = __read_token(tok); > - if (type != TEP_EVENT_SPACE && type != TEP_EVENT_NEWLINE) > - return type; > - free_token(*tok); > - *tok = NULL; > - } > - > - /* not reached */ > - *tok = NULL; > - return TEP_EVENT_NONE; > -} > - > -static int test_type(enum tep_event_type type, enum tep_event_type expect) > -{ > - if (type != expect) { > - do_warning("Error: expected type %d but read %d", > - expect, type); > - return -1; > - } > - return 0; > -} > - > -static int test_type_token(enum tep_event_type type, const char *token, > - enum tep_event_type expect, const char *expect_tok) > -{ > - if (type != expect) { > - do_warning("Error: expected type %d but read %d", > - expect, type); > - return -1; > - } > - > - if (strcmp(token, expect_tok) != 0) { > - do_warning("Error: expected '%s' but read '%s'", > - expect_tok, token); > - return -1; > - } > - return 0; > -} > - > -static int __read_expect_type(enum tep_event_type expect, char **tok, int newline_ok) > -{ > - enum tep_event_type type; > - > - if (newline_ok) > - type = read_token(tok); > - else > - type = read_token_item(tok); > - return test_type(type, expect); > -} > - > -static int read_expect_type(enum tep_event_type expect, char **tok) > -{ > - return __read_expect_type(expect, tok, 1); > -} > - > -static int __read_expected(enum tep_event_type expect, const char *str, > - int newline_ok) > -{ > - enum tep_event_type type; > - char *token; > - int ret; > - > - if (newline_ok) > - type = read_token(&token); > - else > - type = read_token_item(&token); > - > - ret = test_type_token(type, token, expect, str); > - > - free_token(token); > - > - return ret; > -} > - > -static int read_expected(enum tep_event_type expect, const char *str) > -{ > - return __read_expected(expect, str, 1); > -} > - > -static int read_expected_item(enum tep_event_type expect, const char *str) > -{ > - return __read_expected(expect, str, 0); > -} > - > -static char *event_read_name(void) > -{ > - char *token; > - > - if (read_expected(TEP_EVENT_ITEM, "name") < 0) > - return NULL; > - > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - return NULL; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto fail; > - > - return token; > - > - fail: > - free_token(token); > - return NULL; > -} > - > -static int event_read_id(void) > -{ > - char *token; > - int id; > - > - if (read_expected_item(TEP_EVENT_ITEM, "ID") < 0) > - return -1; > - > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - return -1; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto fail; > - > - id = strtoul(token, NULL, 0); > - free_token(token); > - return id; > - > - fail: > - free_token(token); > - return -1; > -} > - > -static int field_is_string(struct tep_format_field *field) > -{ > - if ((field->flags & TEP_FIELD_IS_ARRAY) && > - (strstr(field->type, "char") || strstr(field->type, "u8") || > - strstr(field->type, "s8"))) > - return 1; > - > - return 0; > -} > - > -static int field_is_dynamic(struct tep_format_field *field) > -{ > - if (strncmp(field->type, "__data_loc", 10) == 0) > - return 1; > - > - return 0; > -} > - > -static int field_is_relative_dynamic(struct tep_format_field *field) > -{ > - if (strncmp(field->type, "__rel_loc", 9) == 0) > - return 1; > - > - return 0; > -} > - > -static int field_is_long(struct tep_format_field *field) > -{ > - /* includes long long */ > - if (strstr(field->type, "long")) > - return 1; > - > - return 0; > -} > - > -static unsigned int type_size(const char *name) > -{ > - /* This covers all TEP_FIELD_IS_STRING types. */ > - static struct { > - const char *type; > - unsigned int size; > - } table[] = { > - { "u8", 1 }, > - { "u16", 2 }, > - { "u32", 4 }, > - { "u64", 8 }, > - { "s8", 1 }, > - { "s16", 2 }, > - { "s32", 4 }, > - { "s64", 8 }, > - { "char", 1 }, > - { }, > - }; > - int i; > - > - for (i = 0; table[i].type; i++) { > - if (!strcmp(table[i].type, name)) > - return table[i].size; > - } > - > - return 0; > -} > - > -static int append(char **buf, const char *delim, const char *str) > -{ > - char *new_buf; > - > - new_buf = realloc(*buf, strlen(*buf) + strlen(delim) + strlen(str) + 1); > - if (!new_buf) > - return -1; > - strcat(new_buf, delim); > - strcat(new_buf, str); > - *buf = new_buf; > - return 0; > -} > - > -static int event_read_fields(struct tep_event *event, struct tep_format_field **fields) > -{ > - struct tep_format_field *field = NULL; > - enum tep_event_type type; > - char *token; > - char *last_token; > - char *delim = " "; > - int count = 0; > - int ret; > - > - do { > - unsigned int size_dynamic = 0; > - > - type = read_token(&token); > - if (type == TEP_EVENT_NEWLINE) { > - free_token(token); > - return count; > - } > - > - count++; > - > - if (test_type_token(type, token, TEP_EVENT_ITEM, "field")) > - goto fail; > - free_token(token); > - > - type = read_token(&token); > - /* > - * The ftrace fields may still use the "special" name. > - * Just ignore it. > - */ > - if (event->flags & TEP_EVENT_FL_ISFTRACE && > - type == TEP_EVENT_ITEM && strcmp(token, "special") == 0) { > - free_token(token); > - type = read_token(&token); > - } > - > - if (test_type_token(type, token, TEP_EVENT_OP, ":") < 0) > - goto fail; > - > - free_token(token); > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto fail; > - > - last_token = token; > - > - field = calloc(1, sizeof(*field)); > - if (!field) > - goto fail; > - > - field->event = event; > - > - /* read the rest of the type */ > - for (;;) { > - type = read_token(&token); > - if (type == TEP_EVENT_ITEM || > - (type == TEP_EVENT_OP && strcmp(token, "*") == 0) || > - /* > - * Some of the ftrace fields are broken and have > - * an illegal "." in them. > - */ > - (event->flags & TEP_EVENT_FL_ISFTRACE && > - type == TEP_EVENT_OP && strcmp(token, ".") == 0)) { > - > - if (strcmp(token, "*") == 0) > - field->flags |= TEP_FIELD_IS_POINTER; > - > - if (field->type) { > - ret = append(&field->type, delim, last_token); > - free(last_token); > - if (ret < 0) > - goto fail; > - } else > - field->type = last_token; > - last_token = token; > - delim = " "; > - continue; > - } > - > - /* Handle __attribute__((user)) */ > - if ((type == TEP_EVENT_DELIM) && > - strcmp("__attribute__", last_token) == 0 && > - token[0] == '(') { > - int depth = 1; > - int ret; > - > - ret = append(&field->type, " ", last_token); > - ret |= append(&field->type, "", "("); > - if (ret < 0) > - goto fail; > - > - delim = " "; > - while ((type = read_token(&token)) != TEP_EVENT_NONE) { > - if (type == TEP_EVENT_DELIM) { > - if (token[0] == '(') > - depth++; > - else if (token[0] == ')') > - depth--; > - if (!depth) > - break; > - ret = append(&field->type, "", token); > - delim = ""; > - } else { > - ret = append(&field->type, delim, token); > - delim = " "; > - } > - if (ret < 0) > - goto fail; > - free(last_token); > - last_token = token; > - } > - continue; > - } > - break; > - } > - > - if (!field->type) { > - do_warning_event(event, "%s: no type found", __func__); > - goto fail; > - } > - field->name = field->alias = last_token; > - > - if (test_type(type, TEP_EVENT_OP)) > - goto fail; > - > - if (strcmp(token, "[") == 0) { > - enum tep_event_type last_type = type; > - char *brackets = token; > - > - field->flags |= TEP_FIELD_IS_ARRAY; > - > - type = read_token(&token); > - > - if (type == TEP_EVENT_ITEM) > - field->arraylen = strtoul(token, NULL, 0); > - else > - field->arraylen = 0; > - > - while (strcmp(token, "]") != 0) { > - const char *delim; > - > - if (last_type == TEP_EVENT_ITEM && > - type == TEP_EVENT_ITEM) > - delim = " "; > - else > - delim = ""; > - > - last_type = type; > - > - ret = append(&brackets, delim, token); > - if (ret < 0) { > - free(brackets); > - goto fail; > - } > - /* We only care about the last token */ > - field->arraylen = strtoul(token, NULL, 0); > - free_token(token); > - type = read_token(&token); > - if (type == TEP_EVENT_NONE) { > - free(brackets); > - do_warning_event(event, "failed to find token"); > - goto fail; > - } > - } > - > - free_token(token); > - > - ret = append(&brackets, "", "]"); > - if (ret < 0) { > - free(brackets); > - goto fail; > - } > - > - /* add brackets to type */ > - > - type = read_token(&token); > - /* > - * If the next token is not an OP, then it is of > - * the format: type [] item; > - */ > - if (type == TEP_EVENT_ITEM) { > - ret = append(&field->type, " ", field->name); > - if (ret < 0) { > - free(brackets); > - goto fail; > - } > - ret = append(&field->type, "", brackets); > - > - size_dynamic = type_size(field->name); > - free_token(field->name); > - field->name = field->alias = token; > - type = read_token(&token); > - } else { > - ret = append(&field->type, "", brackets); > - if (ret < 0) { > - free(brackets); > - goto fail; > - } > - } > - free(brackets); > - } > - > - if (field_is_string(field)) > - field->flags |= TEP_FIELD_IS_STRING; > - if (field_is_dynamic(field)) > - field->flags |= TEP_FIELD_IS_DYNAMIC; > - if (field_is_relative_dynamic(field)) > - field->flags |= TEP_FIELD_IS_DYNAMIC | TEP_FIELD_IS_RELATIVE; > - if (field_is_long(field)) > - field->flags |= TEP_FIELD_IS_LONG; > - > - if (test_type_token(type, token, TEP_EVENT_OP, ";")) > - goto fail; > - free_token(token); > - > - if (read_expected(TEP_EVENT_ITEM, "offset") < 0) > - goto fail_expect; > - > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - goto fail_expect; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token)) > - goto fail; > - field->offset = strtoul(token, NULL, 0); > - free_token(token); > - > - if (read_expected(TEP_EVENT_OP, ";") < 0) > - goto fail_expect; > - > - if (read_expected(TEP_EVENT_ITEM, "size") < 0) > - goto fail_expect; > - > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - goto fail_expect; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token)) > - goto fail; > - field->size = strtoul(token, NULL, 0); > - free_token(token); > - > - if (read_expected(TEP_EVENT_OP, ";") < 0) > - goto fail_expect; > - > - type = read_token(&token); > - if (type != TEP_EVENT_NEWLINE) { > - /* newer versions of the kernel have a "signed" type */ > - if (test_type_token(type, token, TEP_EVENT_ITEM, "signed")) > - goto fail; > - > - free_token(token); > - > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - goto fail_expect; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token)) > - goto fail; > - > - if (strtoul(token, NULL, 0)) > - field->flags |= TEP_FIELD_IS_SIGNED; > - > - free_token(token); > - if (read_expected(TEP_EVENT_OP, ";") < 0) > - goto fail_expect; > - > - if (read_expect_type(TEP_EVENT_NEWLINE, &token)) > - goto fail; > - } > - > - free_token(token); > - > - if (field->flags & TEP_FIELD_IS_ARRAY) { > - if (field->arraylen) > - field->elementsize = field->size / field->arraylen; > - else if (field->flags & TEP_FIELD_IS_DYNAMIC) > - field->elementsize = size_dynamic; > - else if (field->flags & TEP_FIELD_IS_STRING) > - field->elementsize = 1; > - else if (field->flags & TEP_FIELD_IS_LONG) > - field->elementsize = event->tep ? > - event->tep->long_size : > - sizeof(long); > - } else > - field->elementsize = field->size; > - > - *fields = field; > - fields = &field->next; > - > - } while (1); > - > - return 0; > - > -fail: > - free_token(token); > -fail_expect: > - if (field) { > - free(field->type); > - free(field->name); > - free(field); > - } > - return -1; > -} > - > -static int event_read_format(struct tep_event *event) > -{ > - char *token; > - int ret; > - > - if (read_expected_item(TEP_EVENT_ITEM, "format") < 0) > - return -1; > - > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - return -1; > - > - if (read_expect_type(TEP_EVENT_NEWLINE, &token)) > - goto fail; > - free_token(token); > - > - ret = event_read_fields(event, &event->format.common_fields); > - if (ret < 0) > - return ret; > - event->format.nr_common = ret; > - > - ret = event_read_fields(event, &event->format.fields); > - if (ret < 0) > - return ret; > - event->format.nr_fields = ret; > - > - return 0; > - > - fail: > - free_token(token); > - return -1; > -} > - > -static enum tep_event_type > -process_arg_token(struct tep_event *event, struct tep_print_arg *arg, > - char **tok, enum tep_event_type type); > - > -static enum tep_event_type > -process_arg(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - enum tep_event_type type; > - char *token; > - > - type = read_token(&token); > - *tok = token; > - > - return process_arg_token(event, arg, tok, type); > -} > - > -static enum tep_event_type > -process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok); > - > -/* > - * For __print_symbolic() and __print_flags, we need to completely > - * evaluate the first argument, which defines what to print next. > - */ > -static enum tep_event_type > -process_field_arg(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - enum tep_event_type type; > - > - type = process_arg(event, arg, tok); > - > - while (type == TEP_EVENT_OP) { > - type = process_op(event, arg, tok); > - } > - > - return type; > -} > - > -static enum tep_event_type > -process_cond(struct tep_event *event, struct tep_print_arg *top, char **tok) > -{ > - struct tep_print_arg *arg, *left, *right; > - enum tep_event_type type; > - char *token = NULL; > - > - arg = alloc_arg(); > - left = alloc_arg(); > - right = alloc_arg(); > - > - if (!arg || !left || !right) { > - do_warning_event(event, "%s: not enough memory!", __func__); > - /* arg will be freed at out_free */ > - free_arg(left); > - free_arg(right); > - goto out_free; > - } > - > - arg->type = TEP_PRINT_OP; > - arg->op.left = left; > - arg->op.right = right; > - > - *tok = NULL; > - type = process_arg(event, left, &token); > - > - again: > - if (type == TEP_EVENT_ERROR) > - goto out_free; > - > - /* Handle other operations in the arguments */ > - if (type == TEP_EVENT_OP && strcmp(token, ":") != 0) { > - type = process_op(event, left, &token); > - goto again; > - } > - > - if (test_type_token(type, token, TEP_EVENT_OP, ":")) > - goto out_free; > - > - arg->op.op = token; > - > - type = process_arg(event, right, &token); > - > - top->op.right = arg; > - > - *tok = token; > - return type; > - > -out_free: > - /* Top may point to itself */ > - top->op.right = NULL; > - free_token(token); > - free_arg(arg); > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_array(struct tep_event *event, struct tep_print_arg *top, char **tok) > -{ > - struct tep_print_arg *arg; > - enum tep_event_type type; > - char *token = NULL; > - > - arg = alloc_arg(); > - if (!arg) { > - do_warning_event(event, "%s: not enough memory!", __func__); > - /* '*tok' is set to top->op.op. No need to free. */ > - *tok = NULL; > - return TEP_EVENT_ERROR; > - } > - > - *tok = NULL; > - type = process_arg(event, arg, &token); > - if (test_type_token(type, token, TEP_EVENT_OP, "]")) > - goto out_free; > - > - top->op.right = arg; > - > - free_token(token); > - type = read_token_item(&token); > - *tok = token; > - > - return type; > - > -out_free: > - free_token(token); > - free_arg(arg); > - return TEP_EVENT_ERROR; > -} > - > -static int get_op_prio(char *op) > -{ > - if (!op[1]) { > - switch (op[0]) { > - case '~': > - case '!': > - return 4; > - case '*': > - case '/': > - case '%': > - return 6; > - case '+': > - case '-': > - return 7; > - /* '>>' and '<<' are 8 */ > - case '<': > - case '>': > - return 9; > - /* '==' and '!=' are 10 */ > - case '&': > - return 11; > - case '^': > - return 12; > - case '|': > - return 13; > - case '?': > - return 16; > - default: > - do_warning("unknown op '%c'", op[0]); > - return -1; > - } > - } else { > - if (strcmp(op, "++") == 0 || > - strcmp(op, "--") == 0) { > - return 3; > - } else if (strcmp(op, ">>") == 0 || > - strcmp(op, "<<") == 0) { > - return 8; > - } else if (strcmp(op, ">=") == 0 || > - strcmp(op, "<=") == 0) { > - return 9; > - } else if (strcmp(op, "==") == 0 || > - strcmp(op, "!=") == 0) { > - return 10; > - } else if (strcmp(op, "&&") == 0) { > - return 14; > - } else if (strcmp(op, "||") == 0) { > - return 15; > - } else { > - do_warning("unknown op '%s'", op); > - return -1; > - } > - } > -} > - > -static int set_op_prio(struct tep_print_arg *arg) > -{ > - > - /* single ops are the greatest */ > - if (!arg->op.left || arg->op.left->type == TEP_PRINT_NULL) > - arg->op.prio = 0; > - else > - arg->op.prio = get_op_prio(arg->op.op); > - > - return arg->op.prio; > -} > - > -/* Note, *tok does not get freed, but will most likely be saved */ > -static enum tep_event_type > -process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - struct tep_print_arg *left, *right = NULL; > - enum tep_event_type type; > - char *token; > - > - /* the op is passed in via tok */ > - token = *tok; > - > - if (arg->type == TEP_PRINT_OP && !arg->op.left) { > - /* handle single op */ > - if (token[1]) { > - do_warning_event(event, "bad op token %s", token); > - goto out_free; > - } > - switch (token[0]) { > - case '~': > - case '!': > - case '+': > - case '-': > - break; > - default: > - do_warning_event(event, "bad op token %s", token); > - goto out_free; > - > - } > - > - /* make an empty left */ > - left = alloc_arg(); > - if (!left) > - goto out_warn_free; > - > - left->type = TEP_PRINT_NULL; > - arg->op.left = left; > - > - right = alloc_arg(); > - if (!right) > - goto out_warn_free; > - > - arg->op.right = right; > - > - /* do not free the token, it belongs to an op */ > - *tok = NULL; > - type = process_arg(event, right, tok); > - > - } else if (strcmp(token, "?") == 0) { > - > - left = alloc_arg(); > - if (!left) > - goto out_warn_free; > - > - /* copy the top arg to the left */ > - *left = *arg; > - > - arg->type = TEP_PRINT_OP; > - arg->op.op = token; > - arg->op.left = left; > - arg->op.prio = 0; > - > - /* it will set arg->op.right */ > - type = process_cond(event, arg, tok); > - > - } else if (strcmp(token, ">>") == 0 || > - strcmp(token, "<<") == 0 || > - strcmp(token, "&") == 0 || > - strcmp(token, "|") == 0 || > - strcmp(token, "&&") == 0 || > - strcmp(token, "||") == 0 || > - strcmp(token, "-") == 0 || > - strcmp(token, "+") == 0 || > - strcmp(token, "*") == 0 || > - strcmp(token, "^") == 0 || > - strcmp(token, "/") == 0 || > - strcmp(token, "%") == 0 || > - strcmp(token, "<") == 0 || > - strcmp(token, ">") == 0 || > - strcmp(token, "<=") == 0 || > - strcmp(token, ">=") == 0 || > - strcmp(token, "==") == 0 || > - strcmp(token, "!=") == 0) { > - > - left = alloc_arg(); > - if (!left) > - goto out_warn_free; > - > - /* copy the top arg to the left */ > - *left = *arg; > - > - arg->type = TEP_PRINT_OP; > - arg->op.op = token; > - arg->op.left = left; > - arg->op.right = NULL; > - > - if (set_op_prio(arg) == -1) { > - event->flags |= TEP_EVENT_FL_FAILED; > - /* arg->op.op (= token) will be freed at out_free */ > - arg->op.op = NULL; > - goto out_free; > - } > - > - type = read_token_item(&token); > - *tok = token; > - > - /* could just be a type pointer */ > - if ((strcmp(arg->op.op, "*") == 0) && > - type == TEP_EVENT_DELIM && (strcmp(token, ")") == 0)) { > - int ret; > - > - if (left->type != TEP_PRINT_ATOM) { > - do_warning_event(event, "bad pointer type"); > - goto out_free; > - } > - ret = append(&left->atom.atom, " ", "*"); > - if (ret < 0) > - goto out_warn_free; > - > - free(arg->op.op); > - *arg = *left; > - free(left); > - > - return type; > - } > - > - right = alloc_arg(); > - if (!right) > - goto out_warn_free; > - > - type = process_arg_token(event, right, tok, type); > - if (type == TEP_EVENT_ERROR) { > - free_arg(right); > - /* token was freed in process_arg_token() via *tok */ > - token = NULL; > - goto out_free; > - } > - > - if (right->type == TEP_PRINT_OP && > - get_op_prio(arg->op.op) < get_op_prio(right->op.op)) { > - struct tep_print_arg tmp; > - > - /* rotate ops according to the priority */ > - arg->op.right = right->op.left; > - > - tmp = *arg; > - *arg = *right; > - *right = tmp; > - > - arg->op.left = right; > - } else { > - arg->op.right = right; > - } > - > - } else if (strcmp(token, "[") == 0) { > - > - left = alloc_arg(); > - if (!left) > - goto out_warn_free; > - > - *left = *arg; > - > - arg->type = TEP_PRINT_OP; > - arg->op.op = token; > - arg->op.left = left; > - > - arg->op.prio = 0; > - > - /* it will set arg->op.right */ > - type = process_array(event, arg, tok); > - > - } else { > - do_warning_event(event, "unknown op '%s'", token); > - event->flags |= TEP_EVENT_FL_FAILED; > - /* the arg is now the left side */ > - goto out_free; > - } > - > - if (type == TEP_EVENT_OP && strcmp(*tok, ":") != 0) { > - int prio; > - > - /* higher prios need to be closer to the root */ > - prio = get_op_prio(*tok); > - > - if (prio > arg->op.prio) > - return process_op(event, arg, tok); > - > - return process_op(event, right, tok); > - } > - > - return type; > - > -out_warn_free: > - do_warning_event(event, "%s: not enough memory!", __func__); > -out_free: > - free_token(token); > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_entry(struct tep_event *event __maybe_unused, struct tep_print_arg *arg, > - char **tok) > -{ > - enum tep_event_type type; > - char *field; > - char *token; > - > - if (read_expected(TEP_EVENT_OP, "->") < 0) > - goto out_err; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto out_free; > - field = token; > - > - arg->type = TEP_PRINT_FIELD; > - arg->field.name = field; > - > - if (is_flag_field) { > - arg->field.field = tep_find_any_field(event, arg->field.name); > - arg->field.field->flags |= TEP_FIELD_IS_FLAG; > - is_flag_field = 0; > - } else if (is_symbolic_field) { > - arg->field.field = tep_find_any_field(event, arg->field.name); > - arg->field.field->flags |= TEP_FIELD_IS_SYMBOLIC; > - is_symbolic_field = 0; > - } > - > - type = read_token(&token); > - *tok = token; > - > - return type; > - > - out_free: > - free_token(token); > - out_err: > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static int alloc_and_process_delim(struct tep_event *event, char *next_token, > - struct tep_print_arg **print_arg) > -{ > - struct tep_print_arg *field; > - enum tep_event_type type; > - char *token; > - int ret = 0; > - > - field = alloc_arg(); > - if (!field) { > - do_warning_event(event, "%s: not enough memory!", __func__); > - errno = ENOMEM; > - return -1; > - } > - > - type = process_arg(event, field, &token); > - > - if (test_type_token(type, token, TEP_EVENT_DELIM, next_token)) { > - errno = EINVAL; > - ret = -1; > - free_arg(field); > - goto out_free_token; > - } > - > - *print_arg = field; > - > -out_free_token: > - free_token(token); > - > - return ret; > -} > - > -static char *arg_eval (struct tep_print_arg *arg); > - > -static unsigned long long > -eval_type_str(unsigned long long val, const char *type, int pointer) > -{ > - int sign = 0; > - char *ref; > - int len; > - > - len = strlen(type); > - > - if (pointer) { > - > - if (type[len-1] != '*') { > - do_warning("pointer expected with non pointer type"); > - return val; > - } > - > - ref = malloc(len); > - if (!ref) { > - do_warning("%s: not enough memory!", __func__); > - return val; > - } > - memcpy(ref, type, len); > - > - /* chop off the " *" */ > - ref[len - 2] = 0; > - > - val = eval_type_str(val, ref, 0); > - free(ref); > - return val; > - } > - > - /* check if this is a pointer */ > - if (type[len - 1] == '*') > - return val; > - > - /* Try to figure out the arg size*/ > - if (strncmp(type, "struct", 6) == 0) > - /* all bets off */ > - return val; > - > - if (strcmp(type, "u8") == 0) > - return val & 0xff; > - > - if (strcmp(type, "u16") == 0) > - return val & 0xffff; > - > - if (strcmp(type, "u32") == 0) > - return val & 0xffffffff; > - > - if (strcmp(type, "u64") == 0 || > - strcmp(type, "s64") == 0) > - return val; > - > - if (strcmp(type, "s8") == 0) > - return (unsigned long long)(char)val & 0xff; > - > - if (strcmp(type, "s16") == 0) > - return (unsigned long long)(short)val & 0xffff; > - > - if (strcmp(type, "s32") == 0) > - return (unsigned long long)(int)val & 0xffffffff; > - > - if (strncmp(type, "unsigned ", 9) == 0) { > - sign = 0; > - type += 9; > - } > - > - if (strcmp(type, "char") == 0) { > - if (sign) > - return (unsigned long long)(char)val & 0xff; > - else > - return val & 0xff; > - } > - > - if (strcmp(type, "short") == 0) { > - if (sign) > - return (unsigned long long)(short)val & 0xffff; > - else > - return val & 0xffff; > - } > - > - if (strcmp(type, "int") == 0) { > - if (sign) > - return (unsigned long long)(int)val & 0xffffffff; > - else > - return val & 0xffffffff; > - } > - > - return val; > -} > - > -/* > - * Try to figure out the type. > - */ > -static unsigned long long > -eval_type(unsigned long long val, struct tep_print_arg *arg, int pointer) > -{ > - if (arg->type != TEP_PRINT_TYPE) { > - do_warning("expected type argument"); > - return 0; > - } > - > - return eval_type_str(val, arg->typecast.type, pointer); > -} > - > -static int arg_num_eval(struct tep_print_arg *arg, long long *val) > -{ > - long long left, right; > - int ret = 1; > - > - switch (arg->type) { > - case TEP_PRINT_ATOM: > - *val = strtoll(arg->atom.atom, NULL, 0); > - break; > - case TEP_PRINT_TYPE: > - ret = arg_num_eval(arg->typecast.item, val); > - if (!ret) > - break; > - *val = eval_type(*val, arg, 0); > - break; > - case TEP_PRINT_OP: > - switch (arg->op.op[0]) { > - case '|': > - ret = arg_num_eval(arg->op.left, &left); > - if (!ret) > - break; > - ret = arg_num_eval(arg->op.right, &right); > - if (!ret) > - break; > - if (arg->op.op[1]) > - *val = left || right; > - else > - *val = left | right; > - break; > - case '&': > - ret = arg_num_eval(arg->op.left, &left); > - if (!ret) > - break; > - ret = arg_num_eval(arg->op.right, &right); > - if (!ret) > - break; > - if (arg->op.op[1]) > - *val = left && right; > - else > - *val = left & right; > - break; > - case '<': > - ret = arg_num_eval(arg->op.left, &left); > - if (!ret) > - break; > - ret = arg_num_eval(arg->op.right, &right); > - if (!ret) > - break; > - switch (arg->op.op[1]) { > - case 0: > - *val = left < right; > - break; > - case '<': > - *val = left << right; > - break; > - case '=': > - *val = left <= right; > - break; > - default: > - do_warning("unknown op '%s'", arg->op.op); > - ret = 0; > - } > - break; > - case '>': > - ret = arg_num_eval(arg->op.left, &left); > - if (!ret) > - break; > - ret = arg_num_eval(arg->op.right, &right); > - if (!ret) > - break; > - switch (arg->op.op[1]) { > - case 0: > - *val = left > right; > - break; > - case '>': > - *val = left >> right; > - break; > - case '=': > - *val = left >= right; > - break; > - default: > - do_warning("unknown op '%s'", arg->op.op); > - ret = 0; > - } > - break; > - case '=': > - ret = arg_num_eval(arg->op.left, &left); > - if (!ret) > - break; > - ret = arg_num_eval(arg->op.right, &right); > - if (!ret) > - break; > - > - if (arg->op.op[1] != '=') { > - do_warning("unknown op '%s'", arg->op.op); > - ret = 0; > - } else > - *val = left == right; > - break; > - case '!': > - ret = arg_num_eval(arg->op.left, &left); > - if (!ret) > - break; > - ret = arg_num_eval(arg->op.right, &right); > - if (!ret) > - break; > - > - switch (arg->op.op[1]) { > - case '=': > - *val = left != right; > - break; > - default: > - do_warning("unknown op '%s'", arg->op.op); > - ret = 0; > - } > - break; > - case '-': > - /* check for negative */ > - if (arg->op.left->type == TEP_PRINT_NULL) > - left = 0; > - else > - ret = arg_num_eval(arg->op.left, &left); > - if (!ret) > - break; > - ret = arg_num_eval(arg->op.right, &right); > - if (!ret) > - break; > - *val = left - right; > - break; > - case '+': > - if (arg->op.left->type == TEP_PRINT_NULL) > - left = 0; > - else > - ret = arg_num_eval(arg->op.left, &left); > - if (!ret) > - break; > - ret = arg_num_eval(arg->op.right, &right); > - if (!ret) > - break; > - *val = left + right; > - break; > - case '~': > - ret = arg_num_eval(arg->op.right, &right); > - if (!ret) > - break; > - *val = ~right; > - break; > - default: > - do_warning("unknown op '%s'", arg->op.op); > - ret = 0; > - } > - break; > - > - case TEP_PRINT_NULL: > - case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL: > - case TEP_PRINT_STRING: > - case TEP_PRINT_BSTRING: > - case TEP_PRINT_BITMASK: > - default: > - do_warning("invalid eval type %d", arg->type); > - ret = 0; > - > - } > - return ret; > -} > - > -static char *arg_eval (struct tep_print_arg *arg) > -{ > - long long val; > - static char buf[24]; > - > - switch (arg->type) { > - case TEP_PRINT_ATOM: > - return arg->atom.atom; > - case TEP_PRINT_TYPE: > - return arg_eval(arg->typecast.item); > - case TEP_PRINT_OP: > - if (!arg_num_eval(arg, &val)) > - break; > - sprintf(buf, "%lld", val); > - return buf; > - > - case TEP_PRINT_NULL: > - case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL: > - case TEP_PRINT_STRING: > - case TEP_PRINT_BSTRING: > - case TEP_PRINT_BITMASK: > - default: > - do_warning("invalid eval type %d", arg->type); > - break; > - } > - > - return NULL; > -} > - > -static enum tep_event_type > -process_fields(struct tep_event *event, struct tep_print_flag_sym **list, char **tok) > -{ > - enum tep_event_type type; > - struct tep_print_arg *arg = NULL; > - struct tep_print_flag_sym *field; > - char *token = *tok; > - char *value; > - > - do { > - free_token(token); > - type = read_token_item(&token); > - if (test_type_token(type, token, TEP_EVENT_OP, "{")) > - break; > - > - arg = alloc_arg(); > - if (!arg) > - goto out_free; > - > - free_token(token); > - type = process_arg(event, arg, &token); > - > - if (type == TEP_EVENT_OP) > - type = process_op(event, arg, &token); > - > - if (type == TEP_EVENT_ERROR) > - goto out_free; > - > - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) > - goto out_free; > - > - field = calloc(1, sizeof(*field)); > - if (!field) > - goto out_free; > - > - value = arg_eval(arg); > - if (value == NULL) > - goto out_free_field; > - field->value = strdup(value); > - if (field->value == NULL) > - goto out_free_field; > - > - free_arg(arg); > - arg = alloc_arg(); > - if (!arg) > - goto out_free; > - > - free_token(token); > - type = process_arg(event, arg, &token); > - if (test_type_token(type, token, TEP_EVENT_OP, "}")) > - goto out_free_field; > - > - value = arg_eval(arg); > - if (value == NULL) > - goto out_free_field; > - field->str = strdup(value); > - if (field->str == NULL) > - goto out_free_field; > - free_arg(arg); > - arg = NULL; > - > - *list = field; > - list = &field->next; > - > - free_token(token); > - type = read_token_item(&token); > - } while (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0); > - > - *tok = token; > - return type; > - > -out_free_field: > - free_flag_sym(field); > -out_free: > - free_arg(arg); > - free_token(token); > - *tok = NULL; > - > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_flags(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - struct tep_print_arg *field; > - enum tep_event_type type; > - char *token = NULL; > - > - memset(arg, 0, sizeof(*arg)); > - arg->type = TEP_PRINT_FLAGS; > - > - field = alloc_arg(); > - if (!field) { > - do_warning_event(event, "%s: not enough memory!", __func__); > - goto out_free; > - } > - > - type = process_field_arg(event, field, &token); > - > - /* Handle operations in the first argument */ > - while (type == TEP_EVENT_OP) > - type = process_op(event, field, &token); > - > - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) > - goto out_free_field; > - free_token(token); > - > - arg->flags.field = field; > - > - type = read_token_item(&token); > - if (event_item_type(type)) { > - arg->flags.delim = token; > - type = read_token_item(&token); > - } > - > - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) > - goto out_free; > - > - type = process_fields(event, &arg->flags.flags, &token); > - if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) > - goto out_free; > - > - free_token(token); > - type = read_token_item(tok); > - return type; > - > -out_free_field: > - free_arg(field); > -out_free: > - free_token(token); > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_symbols(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - struct tep_print_arg *field; > - enum tep_event_type type; > - char *token = NULL; > - > - memset(arg, 0, sizeof(*arg)); > - arg->type = TEP_PRINT_SYMBOL; > - > - field = alloc_arg(); > - if (!field) { > - do_warning_event(event, "%s: not enough memory!", __func__); > - goto out_free; > - } > - > - type = process_field_arg(event, field, &token); > - > - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) > - goto out_free_field; > - > - arg->symbol.field = field; > - > - type = process_fields(event, &arg->symbol.symbols, &token); > - if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) > - goto out_free; > - > - free_token(token); > - type = read_token_item(tok); > - return type; > - > -out_free_field: > - free_arg(field); > -out_free: > - free_token(token); > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_hex_common(struct tep_event *event, struct tep_print_arg *arg, > - char **tok, enum tep_print_arg_type type) > -{ > - memset(arg, 0, sizeof(*arg)); > - arg->type = type; > - > - if (alloc_and_process_delim(event, ",", &arg->hex.field)) > - goto out; > - > - if (alloc_and_process_delim(event, ")", &arg->hex.size)) > - goto free_field; > - > - return read_token_item(tok); > - > -free_field: > - free_arg(arg->hex.field); > - arg->hex.field = NULL; > -out: > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_hex(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - return process_hex_common(event, arg, tok, TEP_PRINT_HEX); > -} > - > -static enum tep_event_type > -process_hex_str(struct tep_event *event, struct tep_print_arg *arg, > - char **tok) > -{ > - return process_hex_common(event, arg, tok, TEP_PRINT_HEX_STR); > -} > - > -static enum tep_event_type > -process_int_array(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - memset(arg, 0, sizeof(*arg)); > - arg->type = TEP_PRINT_INT_ARRAY; > - > - if (alloc_and_process_delim(event, ",", &arg->int_array.field)) > - goto out; > - > - if (alloc_and_process_delim(event, ",", &arg->int_array.count)) > - goto free_field; > - > - if (alloc_and_process_delim(event, ")", &arg->int_array.el_size)) > - goto free_size; > - > - return read_token_item(tok); > - > -free_size: > - free_arg(arg->int_array.count); > - arg->int_array.count = NULL; > -free_field: > - free_arg(arg->int_array.field); > - arg->int_array.field = NULL; > -out: > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_dynamic_array(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - struct tep_format_field *field; > - enum tep_event_type type; > - char *token; > - > - memset(arg, 0, sizeof(*arg)); > - arg->type = TEP_PRINT_DYNAMIC_ARRAY; > - > - /* > - * The item within the parenthesis is another field that holds > - * the index into where the array starts. > - */ > - type = read_token(&token); > - *tok = token; > - if (type != TEP_EVENT_ITEM) > - goto out_free; > - > - /* Find the field */ > - > - field = tep_find_field(event, token); > - if (!field) > - goto out_free; > - > - arg->dynarray.field = field; > - arg->dynarray.index = 0; > - > - if (read_expected(TEP_EVENT_DELIM, ")") < 0) > - goto out_free; > - > - free_token(token); > - type = read_token_item(&token); > - *tok = token; > - if (type != TEP_EVENT_OP || strcmp(token, "[") != 0) > - return type; > - > - free_token(token); > - arg = alloc_arg(); > - if (!arg) { > - do_warning_event(event, "%s: not enough memory!", __func__); > - *tok = NULL; > - return TEP_EVENT_ERROR; > - } > - > - type = process_arg(event, arg, &token); > - if (type == TEP_EVENT_ERROR) > - goto out_free_arg; > - > - if (!test_type_token(type, token, TEP_EVENT_OP, "]")) > - goto out_free_arg; > - > - free_token(token); > - type = read_token_item(tok); > - return type; > - > - out_free_arg: > - free_arg(arg); > - out_free: > - free_token(token); > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_dynamic_array_len(struct tep_event *event, struct tep_print_arg *arg, > - char **tok) > -{ > - struct tep_format_field *field; > - enum tep_event_type type; > - char *token; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto out_free; > - > - arg->type = TEP_PRINT_DYNAMIC_ARRAY_LEN; > - > - /* Find the field */ > - field = tep_find_field(event, token); > - if (!field) > - goto out_free; > - > - arg->dynarray.field = field; > - arg->dynarray.index = 0; > - > - if (read_expected(TEP_EVENT_DELIM, ")") < 0) > - goto out_err; > - > - free_token(token); > - type = read_token(&token); > - *tok = token; > - > - return type; > - > - out_free: > - free_token(token); > - out_err: > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_paren(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - struct tep_print_arg *item_arg; > - enum tep_event_type type; > - char *token; > - > - type = process_arg(event, arg, &token); > - > - if (type == TEP_EVENT_ERROR) > - goto out_free; > - > - if (type == TEP_EVENT_OP) > - type = process_op(event, arg, &token); > - > - if (type == TEP_EVENT_ERROR) > - goto out_free; > - > - if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) > - goto out_free; > - > - free_token(token); > - type = read_token_item(&token); > - > - /* > - * If the next token is an item or another open paren, then > - * this was a typecast. > - */ > - if (event_item_type(type) || > - (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0)) { > - > - /* make this a typecast and contine */ > - > - /* prevous must be an atom */ > - if (arg->type != TEP_PRINT_ATOM) { > - do_warning_event(event, "previous needed to be TEP_PRINT_ATOM"); > - goto out_free; > - } > - > - item_arg = alloc_arg(); > - if (!item_arg) { > - do_warning_event(event, "%s: not enough memory!", > - __func__); > - goto out_free; > - } > - > - arg->type = TEP_PRINT_TYPE; > - arg->typecast.type = arg->atom.atom; > - arg->typecast.item = item_arg; > - type = process_arg_token(event, item_arg, &token, type); > - > - } > - > - *tok = token; > - return type; > - > - out_free: > - free_token(token); > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > - > -static enum tep_event_type > -process_str(struct tep_event *event __maybe_unused, struct tep_print_arg *arg, > - char **tok) > -{ > - enum tep_event_type type; > - char *token; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto out_free; > - > - arg->type = TEP_PRINT_STRING; > - arg->string.string = token; > - arg->string.field = NULL; > - > - if (read_expected(TEP_EVENT_DELIM, ")") < 0) > - goto out_err; > - > - type = read_token(&token); > - *tok = token; > - > - return type; > - > - out_free: > - free_token(token); > - out_err: > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_bitmask(struct tep_event *event __maybe_unused, struct tep_print_arg *arg, > - char **tok) > -{ > - enum tep_event_type type; > - char *token; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto out_free; > - > - arg->type = TEP_PRINT_BITMASK; > - arg->bitmask.bitmask = token; > - arg->bitmask.field = NULL; > - > - if (read_expected(TEP_EVENT_DELIM, ")") < 0) > - goto out_err; > - > - type = read_token(&token); > - *tok = token; > - > - return type; > - > - out_free: > - free_token(token); > - out_err: > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static struct tep_function_handler * > -find_func_handler(struct tep_handle *tep, char *func_name) > -{ > - struct tep_function_handler *func; > - > - if (!tep) > - return NULL; > - > - for (func = tep->func_handlers; func; func = func->next) { > - if (strcmp(func->name, func_name) == 0) > - break; > - } > - > - return func; > -} > - > -static void remove_func_handler(struct tep_handle *tep, char *func_name) > -{ > - struct tep_function_handler *func; > - struct tep_function_handler **next; > - > - next = &tep->func_handlers; > - while ((func = *next)) { > - if (strcmp(func->name, func_name) == 0) { > - *next = func->next; > - free_func_handle(func); > - break; > - } > - next = &func->next; > - } > -} > - > -static enum tep_event_type > -process_func_handler(struct tep_event *event, struct tep_function_handler *func, > - struct tep_print_arg *arg, char **tok) > -{ > - struct tep_print_arg **next_arg; > - struct tep_print_arg *farg; > - enum tep_event_type type; > - char *token; > - int i; > - > - arg->type = TEP_PRINT_FUNC; > - arg->func.func = func; > - > - *tok = NULL; > - > - next_arg = &(arg->func.args); > - for (i = 0; i < func->nr_args; i++) { > - farg = alloc_arg(); > - if (!farg) { > - do_warning_event(event, "%s: not enough memory!", > - __func__); > - return TEP_EVENT_ERROR; > - } > - > - type = process_arg(event, farg, &token); > - if (i < (func->nr_args - 1)) { > - if (type != TEP_EVENT_DELIM || strcmp(token, ",") != 0) { > - do_warning_event(event, > - "Error: function '%s()' expects %d arguments but event %s only uses %d", > - func->name, func->nr_args, > - event->name, i + 1); > - goto err; > - } > - } else { > - if (type != TEP_EVENT_DELIM || strcmp(token, ")") != 0) { > - do_warning_event(event, > - "Error: function '%s()' only expects %d arguments but event %s has more", > - func->name, func->nr_args, event->name); > - goto err; > - } > - } > - > - *next_arg = farg; > - next_arg = &(farg->next); > - free_token(token); > - } > - > - type = read_token(&token); > - *tok = token; > - > - return type; > - > -err: > - free_arg(farg); > - free_token(token); > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_builtin_expect(struct tep_event *event, struct tep_print_arg *arg, char **tok) > -{ > - enum tep_event_type type; > - char *token = NULL; > - > - /* Handle __builtin_expect( cond, #) */ > - type = process_arg(event, arg, &token); > - > - if (type != TEP_EVENT_DELIM || token[0] != ',') > - goto out_free; > - > - free_token(token); > - > - /* We don't care what the second parameter is of the __builtin_expect() */ > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto out_free; > - > - if (read_expected(TEP_EVENT_DELIM, ")") < 0) > - goto out_free; > - > - free_token(token); > - type = read_token_item(tok); > - return type; > - > -out_free: > - free_token(token); > - *tok = NULL; > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_function(struct tep_event *event, struct tep_print_arg *arg, > - char *token, char **tok) > -{ > - struct tep_function_handler *func; > - > - if (strcmp(token, "__print_flags") == 0) { > - free_token(token); > - is_flag_field = 1; > - return process_flags(event, arg, tok); > - } > - if (strcmp(token, "__print_symbolic") == 0) { > - free_token(token); > - is_symbolic_field = 1; > - return process_symbols(event, arg, tok); > - } > - if (strcmp(token, "__print_hex") == 0) { > - free_token(token); > - return process_hex(event, arg, tok); > - } > - if (strcmp(token, "__print_hex_str") == 0) { > - free_token(token); > - return process_hex_str(event, arg, tok); > - } > - if (strcmp(token, "__print_array") == 0) { > - free_token(token); > - return process_int_array(event, arg, tok); > - } > - if (strcmp(token, "__get_str") == 0 || > - strcmp(token, "__get_rel_str") == 0) { > - free_token(token); > - return process_str(event, arg, tok); > - } > - if (strcmp(token, "__get_bitmask") == 0 || > - strcmp(token, "__get_rel_bitmask") == 0) { > - free_token(token); > - return process_bitmask(event, arg, tok); > - } > - if (strcmp(token, "__get_dynamic_array") == 0 || > - strcmp(token, "__get_rel_dynamic_array") == 0) { > - free_token(token); > - return process_dynamic_array(event, arg, tok); > - } > - if (strcmp(token, "__get_dynamic_array_len") == 0 || > - strcmp(token, "__get_rel_dynamic_array_len") == 0) { > - free_token(token); > - return process_dynamic_array_len(event, arg, tok); > - } > - if (strcmp(token, "__builtin_expect") == 0) { > - free_token(token); > - return process_builtin_expect(event, arg, tok); > - } > - > - func = find_func_handler(event->tep, token); > - if (func) { > - free_token(token); > - return process_func_handler(event, func, arg, tok); > - } > - > - do_warning_event(event, "function %s not defined", token); > - free_token(token); > - return TEP_EVENT_ERROR; > -} > - > -static enum tep_event_type > -process_arg_token(struct tep_event *event, struct tep_print_arg *arg, > - char **tok, enum tep_event_type type) > -{ > - char *token; > - char *atom; > - > - token = *tok; > - > - switch (type) { > - case TEP_EVENT_ITEM: > - if (strcmp(token, "REC") == 0) { > - free_token(token); > - type = process_entry(event, arg, &token); > - break; > - } > - atom = token; > - /* test the next token */ > - type = read_token_item(&token); > - > - /* > - * If the next token is a parenthesis, then this > - * is a function. > - */ > - if (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0) { > - free_token(token); > - token = NULL; > - /* this will free atom. */ > - type = process_function(event, arg, atom, &token); > - break; > - } > - /* atoms can be more than one token long */ > - while (type == TEP_EVENT_ITEM) { > - int ret; > - > - ret = append(&atom, " ", token); > - if (ret < 0) { > - free(atom); > - *tok = NULL; > - free_token(token); > - return TEP_EVENT_ERROR; > - } > - free_token(token); > - type = read_token_item(&token); > - } > - > - arg->type = TEP_PRINT_ATOM; > - arg->atom.atom = atom; > - break; > - > - case TEP_EVENT_DQUOTE: > - case TEP_EVENT_SQUOTE: > - arg->type = TEP_PRINT_ATOM; > - arg->atom.atom = token; > - type = read_token_item(&token); > - break; > - case TEP_EVENT_DELIM: > - if (strcmp(token, "(") == 0) { > - free_token(token); > - type = process_paren(event, arg, &token); > - break; > - } > - case TEP_EVENT_OP: > - /* handle single ops */ > - arg->type = TEP_PRINT_OP; > - arg->op.op = token; > - arg->op.left = NULL; > - type = process_op(event, arg, &token); > - > - /* On error, the op is freed */ > - if (type == TEP_EVENT_ERROR) > - arg->op.op = NULL; > - > - /* return error type if errored */ > - break; > - > - case TEP_EVENT_ERROR ... TEP_EVENT_NEWLINE: > - default: > - do_warning_event(event, "unexpected type %d", type); > - return TEP_EVENT_ERROR; > - } > - *tok = token; > - > - return type; > -} > - > -static int event_read_print_args(struct tep_event *event, struct tep_print_arg **list) > -{ > - enum tep_event_type type = TEP_EVENT_ERROR; > - struct tep_print_arg *arg; > - char *token; > - int args = 0; > - > - do { > - if (type == TEP_EVENT_NEWLINE) { > - type = read_token_item(&token); > - continue; > - } > - > - arg = alloc_arg(); > - if (!arg) { > - do_warning_event(event, "%s: not enough memory!", > - __func__); > - return -1; > - } > - > - type = process_arg(event, arg, &token); > - > - if (type == TEP_EVENT_ERROR) { > - free_token(token); > - free_arg(arg); > - return -1; > - } > - > - *list = arg; > - args++; > - > - if (type == TEP_EVENT_OP) { > - type = process_op(event, arg, &token); > - free_token(token); > - if (type == TEP_EVENT_ERROR) { > - *list = NULL; > - free_arg(arg); > - return -1; > - } > - list = &arg->next; > - continue; > - } > - > - if (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0) { > - free_token(token); > - *list = arg; > - list = &arg->next; > - continue; > - } > - break; > - } while (type != TEP_EVENT_NONE); > - > - if (type != TEP_EVENT_NONE && type != TEP_EVENT_ERROR) > - free_token(token); > - > - return args; > -} > - > -static int event_read_print(struct tep_event *event) > -{ > - enum tep_event_type type; > - char *token; > - int ret; > - > - if (read_expected_item(TEP_EVENT_ITEM, "print") < 0) > - return -1; > - > - if (read_expected(TEP_EVENT_ITEM, "fmt") < 0) > - return -1; > - > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - return -1; > - > - if (read_expect_type(TEP_EVENT_DQUOTE, &token) < 0) > - goto fail; > - > - concat: > - event->print_fmt.format = token; > - event->print_fmt.args = NULL; > - > - /* ok to have no arg */ > - type = read_token_item(&token); > - > - if (type == TEP_EVENT_NONE) > - return 0; > - > - /* Handle concatenation of print lines */ > - if (type == TEP_EVENT_DQUOTE) { > - char *cat; > - > - if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0) > - goto fail; > - free_token(token); > - free_token(event->print_fmt.format); > - event->print_fmt.format = NULL; > - token = cat; > - goto concat; > - } > - > - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) > - goto fail; > - > - free_token(token); > - > - ret = event_read_print_args(event, &event->print_fmt.args); > - if (ret < 0) > - return -1; > - > - return ret; > - > - fail: > - free_token(token); > - return -1; > -} > - > -/** > - * tep_find_common_field - return a common field by event > - * @event: handle for the event > - * @name: the name of the common field to return > - * > - * Returns a common field from the event by the given @name. > - * This only searches the common fields and not all field. > - */ > -struct tep_format_field * > -tep_find_common_field(struct tep_event *event, const char *name) > -{ > - struct tep_format_field *format; > - > - for (format = event->format.common_fields; > - format; format = format->next) { > - if (strcmp(format->name, name) == 0) > - break; > - } > - > - return format; > -} > - > -/** > - * tep_find_field - find a non-common field > - * @event: handle for the event > - * @name: the name of the non-common field > - * > - * Returns a non-common field by the given @name. > - * This does not search common fields. > - */ > -struct tep_format_field * > -tep_find_field(struct tep_event *event, const char *name) > -{ > - struct tep_format_field *format; > - > - for (format = event->format.fields; > - format; format = format->next) { > - if (strcmp(format->name, name) == 0) > - break; > - } > - > - return format; > -} > - > -/** > - * tep_find_any_field - find any field by name > - * @event: handle for the event > - * @name: the name of the field > - * > - * Returns a field by the given @name. > - * This searches the common field names first, then > - * the non-common ones if a common one was not found. > - */ > -struct tep_format_field * > -tep_find_any_field(struct tep_event *event, const char *name) > -{ > - struct tep_format_field *format; > - > - format = tep_find_common_field(event, name); > - if (format) > - return format; > - return tep_find_field(event, name); > -} > - > -/** > - * tep_read_number - read a number from data > - * @tep: a handle to the trace event parser context > - * @ptr: the raw data > - * @size: the size of the data that holds the number > - * > - * Returns the number (converted to host) from the > - * raw data. > - */ > -unsigned long long tep_read_number(struct tep_handle *tep, > - const void *ptr, int size) > -{ > - unsigned long long val; > - > - switch (size) { > - case 1: > - return *(unsigned char *)ptr; > - case 2: > - return data2host2(tep, *(unsigned short *)ptr); > - case 4: > - return data2host4(tep, *(unsigned int *)ptr); > - case 8: > - memcpy(&val, (ptr), sizeof(unsigned long long)); > - return data2host8(tep, val); > - default: > - /* BUG! */ > - return 0; > - } > -} > - > -/** > - * tep_read_number_field - read a number from data > - * @field: a handle to the field > - * @data: the raw data to read > - * @value: the value to place the number in > - * > - * Reads raw data according to a field offset and size, > - * and translates it into @value. > - * > - * Returns 0 on success, -1 otherwise. > - */ > -int tep_read_number_field(struct tep_format_field *field, const void *data, > - unsigned long long *value) > -{ > - if (!field) > - return -1; > - switch (field->size) { > - case 1: > - case 2: > - case 4: > - case 8: > - *value = tep_read_number(field->event->tep, > - data + field->offset, field->size); > - return 0; > - default: > - return -1; > - } > -} > - > -static int get_common_info(struct tep_handle *tep, > - const char *type, int *offset, int *size) > -{ > - struct tep_event *event; > - struct tep_format_field *field; > - > - /* > - * All events should have the same common elements. > - * Pick any event to find where the type is; > - */ > - if (!tep->events) { > - do_warning("no event_list!"); > - return -1; > - } > - > - event = tep->events[0]; > - field = tep_find_common_field(event, type); > - if (!field) > - return -1; > - > - *offset = field->offset; > - *size = field->size; > - > - return 0; > -} > - > -static int __parse_common(struct tep_handle *tep, void *data, > - int *size, int *offset, const char *name) > -{ > - int ret; > - > - if (!*size) { > - ret = get_common_info(tep, name, offset, size); > - if (ret < 0) > - return ret; > - } > - return tep_read_number(tep, data + *offset, *size); > -} > - > -static int trace_parse_common_type(struct tep_handle *tep, void *data) > -{ > - return __parse_common(tep, data, > - &tep->type_size, &tep->type_offset, > - "common_type"); > -} > - > -static int parse_common_pid(struct tep_handle *tep, void *data) > -{ > - return __parse_common(tep, data, > - &tep->pid_size, &tep->pid_offset, > - "common_pid"); > -} > - > -static int parse_common_pc(struct tep_handle *tep, void *data) > -{ > - return __parse_common(tep, data, > - &tep->pc_size, &tep->pc_offset, > - "common_preempt_count"); > -} > - > -static int parse_common_flags(struct tep_handle *tep, void *data) > -{ > - return __parse_common(tep, data, > - &tep->flags_size, &tep->flags_offset, > - "common_flags"); > -} > - > -static int parse_common_lock_depth(struct tep_handle *tep, void *data) > -{ > - return __parse_common(tep, data, > - &tep->ld_size, &tep->ld_offset, > - "common_lock_depth"); > -} > - > -static int parse_common_migrate_disable(struct tep_handle *tep, void *data) > -{ > - return __parse_common(tep, data, > - &tep->ld_size, &tep->ld_offset, > - "common_migrate_disable"); > -} > - > -static int events_id_cmp(const void *a, const void *b); > - > -/** > - * tep_find_event - find an event by given id > - * @tep: a handle to the trace event parser context > - * @id: the id of the event > - * > - * Returns an event that has a given @id. > - */ > -struct tep_event *tep_find_event(struct tep_handle *tep, int id) > -{ > - struct tep_event **eventptr; > - struct tep_event key; > - struct tep_event *pkey = &key; > - > - /* Check cache first */ > - if (tep->last_event && tep->last_event->id == id) > - return tep->last_event; > - > - key.id = id; > - > - eventptr = bsearch(&pkey, tep->events, tep->nr_events, > - sizeof(*tep->events), events_id_cmp); > - > - if (eventptr) { > - tep->last_event = *eventptr; > - return *eventptr; > - } > - > - return NULL; > -} > - > -/** > - * tep_find_event_by_name - find an event by given name > - * @tep: a handle to the trace event parser context > - * @sys: the system name to search for > - * @name: the name of the event to search for > - * > - * This returns an event with a given @name and under the system > - * @sys. If @sys is NULL the first event with @name is returned. > - */ > -struct tep_event * > -tep_find_event_by_name(struct tep_handle *tep, > - const char *sys, const char *name) > -{ > - struct tep_event *event = NULL; > - int i; > - > - if (tep->last_event && > - strcmp(tep->last_event->name, name) == 0 && > - (!sys || strcmp(tep->last_event->system, sys) == 0)) > - return tep->last_event; > - > - for (i = 0; i < tep->nr_events; i++) { > - event = tep->events[i]; > - if (strcmp(event->name, name) == 0) { > - if (!sys) > - break; > - if (strcmp(event->system, sys) == 0) > - break; > - } > - } > - if (i == tep->nr_events) > - event = NULL; > - > - tep->last_event = event; > - return event; > -} > - > -static unsigned long long > -eval_num_arg(void *data, int size, struct tep_event *event, struct tep_print_arg *arg) > -{ > - struct tep_handle *tep = event->tep; > - unsigned long long val = 0; > - unsigned long long left, right; > - struct tep_print_arg *typearg = NULL; > - struct tep_print_arg *larg; > - unsigned long offset; > - unsigned int field_size; > - > - switch (arg->type) { > - case TEP_PRINT_NULL: > - /* ?? */ > - return 0; > - case TEP_PRINT_ATOM: > - return strtoull(arg->atom.atom, NULL, 0); > - case TEP_PRINT_FIELD: > - if (!arg->field.field) { > - arg->field.field = tep_find_any_field(event, arg->field.name); > - if (!arg->field.field) > - goto out_warning_field; > - > - } > - /* must be a number */ > - val = tep_read_number(tep, data + arg->field.field->offset, > - arg->field.field->size); > - break; > - case TEP_PRINT_FLAGS: > - case TEP_PRINT_SYMBOL: > - case TEP_PRINT_INT_ARRAY: > - case TEP_PRINT_HEX: > - case TEP_PRINT_HEX_STR: > - break; > - case TEP_PRINT_TYPE: > - val = eval_num_arg(data, size, event, arg->typecast.item); > - return eval_type(val, arg, 0); > - case TEP_PRINT_STRING: > - case TEP_PRINT_BSTRING: > - case TEP_PRINT_BITMASK: > - return 0; > - case TEP_PRINT_FUNC: { > - struct trace_seq s; > - trace_seq_init(&s); > - val = process_defined_func(&s, data, size, event, arg); > - trace_seq_destroy(&s); > - return val; > - } > - case TEP_PRINT_OP: > - if (strcmp(arg->op.op, "[") == 0) { > - /* > - * Arrays are special, since we don't want > - * to read the arg as is. > - */ > - right = eval_num_arg(data, size, event, arg->op.right); > - > - /* handle typecasts */ > - larg = arg->op.left; > - while (larg->type == TEP_PRINT_TYPE) { > - if (!typearg) > - typearg = larg; > - larg = larg->typecast.item; > - } > - > - /* Default to long size */ > - field_size = tep->long_size; > - > - switch (larg->type) { > - case TEP_PRINT_DYNAMIC_ARRAY: > - offset = tep_read_number(tep, > - data + larg->dynarray.field->offset, > - larg->dynarray.field->size); > - if (larg->dynarray.field->elementsize) > - field_size = larg->dynarray.field->elementsize; > - /* > - * The actual length of the dynamic array is stored > - * in the top half of the field, and the offset > - * is in the bottom half of the 32 bit field. > - */ > - offset &= 0xffff; > - offset += right; > - break; > - case TEP_PRINT_FIELD: > - if (!larg->field.field) { > - larg->field.field = > - tep_find_any_field(event, larg->field.name); > - if (!larg->field.field) { > - arg = larg; > - goto out_warning_field; > - } > - } > - field_size = larg->field.field->elementsize; > - offset = larg->field.field->offset + > - right * larg->field.field->elementsize; > - break; > - default: > - goto default_op; /* oops, all bets off */ > - } > - val = tep_read_number(tep, > - data + offset, field_size); > - if (typearg) > - val = eval_type(val, typearg, 1); > - break; > - } else if (strcmp(arg->op.op, "?") == 0) { > - left = eval_num_arg(data, size, event, arg->op.left); > - arg = arg->op.right; > - if (left) > - val = eval_num_arg(data, size, event, arg->op.left); > - else > - val = eval_num_arg(data, size, event, arg->op.right); > - break; > - } > - default_op: > - left = eval_num_arg(data, size, event, arg->op.left); > - right = eval_num_arg(data, size, event, arg->op.right); > - switch (arg->op.op[0]) { > - case '!': > - switch (arg->op.op[1]) { > - case 0: > - val = !right; > - break; > - case '=': > - val = left != right; > - break; > - default: > - goto out_warning_op; > - } > - break; > - case '~': > - val = ~right; > - break; > - case '|': > - if (arg->op.op[1]) > - val = left || right; > - else > - val = left | right; > - break; > - case '&': > - if (arg->op.op[1]) > - val = left && right; > - else > - val = left & right; > - break; > - case '<': > - switch (arg->op.op[1]) { > - case 0: > - val = left < right; > - break; > - case '<': > - val = left << right; > - break; > - case '=': > - val = left <= right; > - break; > - default: > - goto out_warning_op; > - } > - break; > - case '>': > - switch (arg->op.op[1]) { > - case 0: > - val = left > right; > - break; > - case '>': > - val = left >> right; > - break; > - case '=': > - val = left >= right; > - break; > - default: > - goto out_warning_op; > - } > - break; > - case '=': > - if (arg->op.op[1] != '=') > - goto out_warning_op; > - > - val = left == right; > - break; > - case '-': > - val = left - right; > - break; > - case '+': > - val = left + right; > - break; > - case '/': > - val = left / right; > - break; > - case '%': > - val = left % right; > - break; > - case '*': > - val = left * right; > - break; > - default: > - goto out_warning_op; > - } > - break; > - case TEP_PRINT_DYNAMIC_ARRAY_LEN: > - offset = tep_read_number(tep, > - data + arg->dynarray.field->offset, > - arg->dynarray.field->size); > - /* > - * The total allocated length of the dynamic array is > - * stored in the top half of the field, and the offset > - * is in the bottom half of the 32 bit field. > - */ > - val = (unsigned long long)(offset >> 16); > - break; > - case TEP_PRINT_DYNAMIC_ARRAY: > - /* Without [], we pass the address to the dynamic data */ > - offset = tep_read_number(tep, > - data + arg->dynarray.field->offset, > - arg->dynarray.field->size); > - /* > - * The total allocated length of the dynamic array is > - * stored in the top half of the field, and the offset > - * is in the bottom half of the 32 bit field. > - */ > - offset &= 0xffff; > - val = (unsigned long long)((unsigned long)data + offset); > - break; > - default: /* not sure what to do there */ > - return 0; > - } > - return val; > - > -out_warning_op: > - do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op); > - return 0; > - > -out_warning_field: > - do_warning_event(event, "%s: field %s not found", > - __func__, arg->field.name); > - return 0; > -} > - > -struct flag { > - const char *name; > - unsigned long long value; > -}; > - > -static const struct flag flags[] = { > - { "HI_SOFTIRQ", 0 }, > - { "TIMER_SOFTIRQ", 1 }, > - { "NET_TX_SOFTIRQ", 2 }, > - { "NET_RX_SOFTIRQ", 3 }, > - { "BLOCK_SOFTIRQ", 4 }, > - { "IRQ_POLL_SOFTIRQ", 5 }, > - { "TASKLET_SOFTIRQ", 6 }, > - { "SCHED_SOFTIRQ", 7 }, > - { "HRTIMER_SOFTIRQ", 8 }, > - { "RCU_SOFTIRQ", 9 }, > - > - { "HRTIMER_NORESTART", 0 }, > - { "HRTIMER_RESTART", 1 }, > -}; > - > -static long long eval_flag(const char *flag) > -{ > - int i; > - > - /* > - * Some flags in the format files do not get converted. > - * If the flag is not numeric, see if it is something that > - * we already know about. > - */ > - if (isdigit(flag[0])) > - return strtoull(flag, NULL, 0); > - > - for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) > - if (strcmp(flags[i].name, flag) == 0) > - return flags[i].value; > - > - return -1LL; > -} > - > -static void print_str_to_seq(struct trace_seq *s, const char *format, > - int len_arg, const char *str) > -{ > - if (len_arg >= 0) > - trace_seq_printf(s, format, len_arg, str); > - else > - trace_seq_printf(s, format, str); > -} > - > -static void print_bitmask_to_seq(struct tep_handle *tep, > - struct trace_seq *s, const char *format, > - int len_arg, const void *data, int size) > -{ > - int nr_bits = size * 8; > - int str_size = (nr_bits + 3) / 4; > - int len = 0; > - char buf[3]; > - char *str; > - int index; > - int i; > - > - /* > - * The kernel likes to put in commas every 32 bits, we > - * can do the same. > - */ > - str_size += (nr_bits - 1) / 32; > - > - str = malloc(str_size + 1); > - if (!str) { > - do_warning("%s: not enough memory!", __func__); > - return; > - } > - str[str_size] = 0; > - > - /* Start out with -2 for the two chars per byte */ > - for (i = str_size - 2; i >= 0; i -= 2) { > - /* > - * data points to a bit mask of size bytes. > - * In the kernel, this is an array of long words, thus > - * endianness is very important. > - */ > - if (tep->file_bigendian) > - index = size - (len + 1); > - else > - index = len; > - > - snprintf(buf, 3, "%02x", *((unsigned char *)data + index)); > - memcpy(str + i, buf, 2); > - len++; > - if (!(len & 3) && i > 0) { > - i--; > - str[i] = ','; > - } > - } > - > - if (len_arg >= 0) > - trace_seq_printf(s, format, len_arg, str); > - else > - trace_seq_printf(s, format, str); > - > - free(str); > -} > - > -static void print_str_arg(struct trace_seq *s, void *data, int size, > - struct tep_event *event, const char *format, > - int len_arg, struct tep_print_arg *arg) > -{ > - struct tep_handle *tep = event->tep; > - struct tep_print_flag_sym *flag; > - struct tep_format_field *field; > - struct printk_map *printk; > - long long val, fval; > - unsigned long long addr; > - char *str; > - unsigned char *hex; > - int print; > - int i, len; > - > - switch (arg->type) { > - case TEP_PRINT_NULL: > - /* ?? */ > - return; > - case TEP_PRINT_ATOM: > - print_str_to_seq(s, format, len_arg, arg->atom.atom); > - return; > - case TEP_PRINT_FIELD: > - field = arg->field.field; > - if (!field) { > - field = tep_find_any_field(event, arg->field.name); > - if (!field) { > - str = arg->field.name; > - goto out_warning_field; > - } > - arg->field.field = field; > - } > - /* Zero sized fields, mean the rest of the data */ > - len = field->size ? : size - field->offset; > - > - /* > - * Some events pass in pointers. If this is not an array > - * and the size is the same as long_size, assume that it > - * is a pointer. > - */ > - if (!(field->flags & TEP_FIELD_IS_ARRAY) && > - field->size == tep->long_size) { > - > - /* Handle heterogeneous recording and processing > - * architectures > - * > - * CASE I: > - * Traces recorded on 32-bit devices (32-bit > - * addressing) and processed on 64-bit devices: > - * In this case, only 32 bits should be read. > - * > - * CASE II: > - * Traces recorded on 64 bit devices and processed > - * on 32-bit devices: > - * In this case, 64 bits must be read. > - */ > - addr = (tep->long_size == 8) ? > - *(unsigned long long *)(data + field->offset) : > - (unsigned long long)*(unsigned int *)(data + field->offset); > - > - /* Check if it matches a print format */ > - printk = find_printk(tep, addr); > - if (printk) > - trace_seq_puts(s, printk->printk); > - else > - trace_seq_printf(s, "%llx", addr); > - break; > - } > - str = malloc(len + 1); > - if (!str) { > - do_warning_event(event, "%s: not enough memory!", > - __func__); > - return; > - } > - memcpy(str, data + field->offset, len); > - str[len] = 0; > - print_str_to_seq(s, format, len_arg, str); > - free(str); > - break; > - case TEP_PRINT_FLAGS: > - val = eval_num_arg(data, size, event, arg->flags.field); > - print = 0; > - for (flag = arg->flags.flags; flag; flag = flag->next) { > - fval = eval_flag(flag->value); > - if (!val && fval < 0) { > - print_str_to_seq(s, format, len_arg, flag->str); > - break; > - } > - if (fval > 0 && (val & fval) == fval) { > - if (print && arg->flags.delim) > - trace_seq_puts(s, arg->flags.delim); > - print_str_to_seq(s, format, len_arg, flag->str); > - print = 1; > - val &= ~fval; > - } > - } > - if (val) { > - if (print && arg->flags.delim) > - trace_seq_puts(s, arg->flags.delim); > - trace_seq_printf(s, "0x%llx", val); > - } > - break; > - case TEP_PRINT_SYMBOL: > - val = eval_num_arg(data, size, event, arg->symbol.field); > - for (flag = arg->symbol.symbols; flag; flag = flag->next) { > - fval = eval_flag(flag->value); > - if (val == fval) { > - print_str_to_seq(s, format, len_arg, flag->str); > - break; > - } > - } > - if (!flag) > - trace_seq_printf(s, "0x%llx", val); > - break; > - case TEP_PRINT_HEX: > - case TEP_PRINT_HEX_STR: > - if (arg->hex.field->type == TEP_PRINT_DYNAMIC_ARRAY) { > - unsigned long offset; > - offset = tep_read_number(tep, > - data + arg->hex.field->dynarray.field->offset, > - arg->hex.field->dynarray.field->size); > - hex = data + (offset & 0xffff); > - } else { > - field = arg->hex.field->field.field; > - if (!field) { > - str = arg->hex.field->field.name; > - field = tep_find_any_field(event, str); > - if (!field) > - goto out_warning_field; > - arg->hex.field->field.field = field; > - } > - hex = data + field->offset; > - } > - len = eval_num_arg(data, size, event, arg->hex.size); > - for (i = 0; i < len; i++) { > - if (i && arg->type == TEP_PRINT_HEX) > - trace_seq_putc(s, ' '); > - trace_seq_printf(s, "%02x", hex[i]); > - } > - break; > - > - case TEP_PRINT_INT_ARRAY: { > - void *num; > - int el_size; > - > - if (arg->int_array.field->type == TEP_PRINT_DYNAMIC_ARRAY) { > - unsigned long offset; > - struct tep_format_field *field = > - arg->int_array.field->dynarray.field; > - offset = tep_read_number(tep, > - data + field->offset, > - field->size); > - num = data + (offset & 0xffff); > - } else { > - field = arg->int_array.field->field.field; > - if (!field) { > - str = arg->int_array.field->field.name; > - field = tep_find_any_field(event, str); > - if (!field) > - goto out_warning_field; > - arg->int_array.field->field.field = field; > - } > - num = data + field->offset; > - } > - len = eval_num_arg(data, size, event, arg->int_array.count); > - el_size = eval_num_arg(data, size, event, > - arg->int_array.el_size); > - for (i = 0; i < len; i++) { > - if (i) > - trace_seq_putc(s, ' '); > - > - if (el_size == 1) { > - trace_seq_printf(s, "%u", *(uint8_t *)num); > - } else if (el_size == 2) { > - trace_seq_printf(s, "%u", *(uint16_t *)num); > - } else if (el_size == 4) { > - trace_seq_printf(s, "%u", *(uint32_t *)num); > - } else if (el_size == 8) { > - trace_seq_printf(s, "%"PRIu64, *(uint64_t *)num); > - } else { > - trace_seq_printf(s, "BAD SIZE:%d 0x%x", > - el_size, *(uint8_t *)num); > - el_size = 1; > - } > - > - num += el_size; > - } > - break; > - } > - case TEP_PRINT_TYPE: > - break; > - case TEP_PRINT_STRING: { > - int str_offset; > - > - if (!arg->string.field) > - arg->string.field = tep_find_any_field(event, arg->string.string); > - if (!arg->string.field) > - break; > - > - str_offset = data2host4(tep, > - *(unsigned int *)(data + arg->string.field->offset)); > - str_offset &= 0xffff; > - if (arg->string.field->flags & TEP_FIELD_IS_RELATIVE) > - str_offset += arg->string.field->offset + arg->string.field->size; > - print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset); > - break; > - } > - case TEP_PRINT_BSTRING: > - print_str_to_seq(s, format, len_arg, arg->string.string); > - break; > - case TEP_PRINT_BITMASK: { > - int bitmask_offset; > - int bitmask_size; > - > - if (!arg->bitmask.field) > - arg->bitmask.field = tep_find_any_field(event, arg->bitmask.bitmask); > - if (!arg->bitmask.field) > - break; > - bitmask_offset = data2host4(tep, > - *(unsigned int *)(data + arg->bitmask.field->offset)); > - bitmask_size = bitmask_offset >> 16; > - bitmask_offset &= 0xffff; > - if (arg->bitmask.field->flags & TEP_FIELD_IS_RELATIVE) > - bitmask_offset += arg->bitmask.field->offset + arg->bitmask.field->size; > - print_bitmask_to_seq(tep, s, format, len_arg, > - data + bitmask_offset, bitmask_size); > - break; > - } > - case TEP_PRINT_OP: > - /* > - * The only op for string should be ? : > - */ > - if (arg->op.op[0] != '?') > - return; > - val = eval_num_arg(data, size, event, arg->op.left); > - if (val) > - print_str_arg(s, data, size, event, > - format, len_arg, arg->op.right->op.left); > - else > - print_str_arg(s, data, size, event, > - format, len_arg, arg->op.right->op.right); > - break; > - case TEP_PRINT_FUNC: > - process_defined_func(s, data, size, event, arg); > - break; > - default: > - /* well... */ > - break; > - } > - > - return; > - > -out_warning_field: > - do_warning_event(event, "%s: field %s not found", > - __func__, arg->field.name); > -} > - > -static unsigned long long > -process_defined_func(struct trace_seq *s, void *data, int size, > - struct tep_event *event, struct tep_print_arg *arg) > -{ > - struct tep_function_handler *func_handle = arg->func.func; > - struct func_params *param; > - unsigned long long *args; > - unsigned long long ret; > - struct tep_print_arg *farg; > - struct trace_seq str; > - struct save_str { > - struct save_str *next; > - char *str; > - } *strings = NULL, *string; > - int i; > - > - if (!func_handle->nr_args) { > - ret = (*func_handle->func)(s, NULL); > - goto out; > - } > - > - farg = arg->func.args; > - param = func_handle->params; > - > - ret = ULLONG_MAX; > - args = malloc(sizeof(*args) * func_handle->nr_args); > - if (!args) > - goto out; > - > - for (i = 0; i < func_handle->nr_args; i++) { > - switch (param->type) { > - case TEP_FUNC_ARG_INT: > - case TEP_FUNC_ARG_LONG: > - case TEP_FUNC_ARG_PTR: > - args[i] = eval_num_arg(data, size, event, farg); > - break; > - case TEP_FUNC_ARG_STRING: > - trace_seq_init(&str); > - print_str_arg(&str, data, size, event, "%s", -1, farg); > - trace_seq_terminate(&str); > - string = malloc(sizeof(*string)); > - if (!string) { > - do_warning_event(event, "%s(%d): malloc str", > - __func__, __LINE__); > - goto out_free; > - } > - string->next = strings; > - string->str = strdup(str.buffer); > - if (!string->str) { > - free(string); > - do_warning_event(event, "%s(%d): malloc str", > - __func__, __LINE__); > - goto out_free; > - } > - args[i] = (uintptr_t)string->str; > - strings = string; > - trace_seq_destroy(&str); > - break; > - default: > - /* > - * Something went totally wrong, this is not > - * an input error, something in this code broke. > - */ > - do_warning_event(event, "Unexpected end of arguments\n"); > - goto out_free; > - } > - farg = farg->next; > - param = param->next; > - } > - > - ret = (*func_handle->func)(s, args); > -out_free: > - free(args); > - while (strings) { > - string = strings; > - strings = string->next; > - free(string->str); > - free(string); > - } > - > - out: > - /* TBD : handle return type here */ > - return ret; > -} > - > -static void free_args(struct tep_print_arg *args) > -{ > - struct tep_print_arg *next; > - > - while (args) { > - next = args->next; > - > - free_arg(args); > - args = next; > - } > -} > - > -static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, struct tep_event *event) > -{ > - struct tep_handle *tep = event->tep; > - struct tep_format_field *field, *ip_field; > - struct tep_print_arg *args, *arg, **next; > - unsigned long long ip, val; > - char *ptr; > - void *bptr; > - int vsize = 0; > - > - field = tep->bprint_buf_field; > - ip_field = tep->bprint_ip_field; > - > - if (!field) { > - field = tep_find_field(event, "buf"); > - if (!field) { > - do_warning_event(event, "can't find buffer field for binary printk"); > - return NULL; > - } > - ip_field = tep_find_field(event, "ip"); > - if (!ip_field) { > - do_warning_event(event, "can't find ip field for binary printk"); > - return NULL; > - } > - tep->bprint_buf_field = field; > - tep->bprint_ip_field = ip_field; > - } > - > - ip = tep_read_number(tep, data + ip_field->offset, ip_field->size); > - > - /* > - * The first arg is the IP pointer. > - */ > - args = alloc_arg(); > - if (!args) { > - do_warning_event(event, "%s(%d): not enough memory!", > - __func__, __LINE__); > - return NULL; > - } > - arg = args; > - arg->next = NULL; > - next = &arg->next; > - > - arg->type = TEP_PRINT_ATOM; > - > - if (asprintf(&arg->atom.atom, "%lld", ip) < 0) > - goto out_free; > - > - /* skip the first "%ps: " */ > - for (ptr = fmt + 5, bptr = data + field->offset; > - bptr < data + size && *ptr; ptr++) { > - int ls = 0; > - > - if (*ptr == '%') { > - process_again: > - ptr++; > - switch (*ptr) { > - case '%': > - break; > - case 'l': > - ls++; > - goto process_again; > - case 'L': > - ls = 2; > - goto process_again; > - case '0' ... '9': > - goto process_again; > - case '.': > - goto process_again; > - case 'z': > - case 'Z': > - ls = 1; > - goto process_again; > - case 'p': > - ls = 1; > - if (isalnum(ptr[1])) { > - ptr++; > - /* Check for special pointers */ > - switch (*ptr) { > - case 's': > - case 'S': > - case 'x': > - break; > - case 'f': > - case 'F': > - /* > - * Pre-5.5 kernels use %pf and > - * %pF for printing symbols > - * while kernels since 5.5 use > - * %pfw for fwnodes. So check > - * %p[fF] isn't followed by 'w'. > - */ > - if (ptr[1] != 'w') > - break; > - /* fall through */ > - default: > - /* > - * Older kernels do not process > - * dereferenced pointers. > - * Only process if the pointer > - * value is a printable. > - */ > - if (isprint(*(char *)bptr)) > - goto process_string; > - } > - } > - /* fall through */ > - case 'd': > - case 'u': > - case 'i': > - case 'x': > - case 'X': > - case 'o': > - switch (ls) { > - case 0: > - vsize = 4; > - break; > - case 1: > - vsize = tep->long_size; > - break; > - case 2: > - vsize = 8; > - break; > - default: > - vsize = ls; /* ? */ > - break; > - } > - /* fall through */ > - case '*': > - if (*ptr == '*') > - vsize = 4; > - > - /* the pointers are always 4 bytes aligned */ > - bptr = (void *)(((unsigned long)bptr + 3) & > - ~3); > - val = tep_read_number(tep, bptr, vsize); > - bptr += vsize; > - arg = alloc_arg(); > - if (!arg) { > - do_warning_event(event, "%s(%d): not enough memory!", > - __func__, __LINE__); > - goto out_free; > - } > - arg->next = NULL; > - arg->type = TEP_PRINT_ATOM; > - if (asprintf(&arg->atom.atom, "%lld", val) < 0) { > - free(arg); > - goto out_free; > - } > - *next = arg; > - next = &arg->next; > - /* > - * The '*' case means that an arg is used as the length. > - * We need to continue to figure out for what. > - */ > - if (*ptr == '*') > - goto process_again; > - > - break; > - case 's': > - process_string: > - arg = alloc_arg(); > - if (!arg) { > - do_warning_event(event, "%s(%d): not enough memory!", > - __func__, __LINE__); > - goto out_free; > - } > - arg->next = NULL; > - arg->type = TEP_PRINT_BSTRING; > - arg->string.string = strdup(bptr); > - if (!arg->string.string) > - goto out_free; > - bptr += strlen(bptr) + 1; > - *next = arg; > - next = &arg->next; > - default: > - break; > - } > - } > - } > - > - return args; > - > -out_free: > - free_args(args); > - return NULL; > -} > - > -static char * > -get_bprint_format(void *data, int size __maybe_unused, > - struct tep_event *event) > -{ > - struct tep_handle *tep = event->tep; > - unsigned long long addr; > - struct tep_format_field *field; > - struct printk_map *printk; > - char *format; > - > - field = tep->bprint_fmt_field; > - > - if (!field) { > - field = tep_find_field(event, "fmt"); > - if (!field) { > - do_warning_event(event, "can't find format field for binary printk"); > - return NULL; > - } > - tep->bprint_fmt_field = field; > - } > - > - addr = tep_read_number(tep, data + field->offset, field->size); > - > - printk = find_printk(tep, addr); > - if (!printk) { > - if (asprintf(&format, "%%ps: (NO FORMAT FOUND at %llx)\n", addr) < 0) > - return NULL; > - return format; > - } > - > - if (asprintf(&format, "%s: %s", "%ps", printk->printk) < 0) > - return NULL; > - > - return format; > -} > - > -static int print_mac_arg(struct trace_seq *s, const char *format, > - void *data, int size, struct tep_event *event, > - struct tep_print_arg *arg) > -{ > - const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"; > - bool reverse = false; > - unsigned char *buf; > - int ret = 0; > - > - if (arg->type == TEP_PRINT_FUNC) { > - process_defined_func(s, data, size, event, arg); > - return 0; > - } > - > - if (arg->type != TEP_PRINT_FIELD) { > - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", > - arg->type); > - return 0; > - } > - > - if (format[0] == 'm') { > - fmt = "%.2x%.2x%.2x%.2x%.2x%.2x"; > - } else if (format[0] == 'M' && format[1] == 'F') { > - fmt = "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x"; > - ret++; > - } > - if (format[1] == 'R') { > - reverse = true; > - ret++; > - } > - > - if (!arg->field.field) { > - arg->field.field = > - tep_find_any_field(event, arg->field.name); > - if (!arg->field.field) { > - do_warning_event(event, "%s: field %s not found", > - __func__, arg->field.name); > - return ret; > - } > - } > - if (arg->field.field->size != 6) { > - trace_seq_printf(s, "INVALIDMAC"); > - return ret; > - } > - > - buf = data + arg->field.field->offset; > - if (reverse) > - trace_seq_printf(s, fmt, buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]); > - else > - trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); > - > - return ret; > -} > - > -static int parse_ip4_print_args(struct tep_handle *tep, > - const char *ptr, bool *reverse) > -{ > - int ret = 0; > - > - *reverse = false; > - > - /* hnbl */ > - switch (*ptr) { > - case 'h': > - if (tep->file_bigendian) > - *reverse = false; > - else > - *reverse = true; > - ret++; > - break; > - case 'l': > - *reverse = true; > - ret++; > - break; > - case 'n': > - case 'b': > - ret++; > - /* fall through */ > - default: > - *reverse = false; > - break; > - } > - > - return ret; > -} > - > -static void print_ip4_addr(struct trace_seq *s, char i, bool reverse, unsigned char *buf) > -{ > - const char *fmt; > - > - if (i == 'i') > - fmt = "%03d.%03d.%03d.%03d"; > - else > - fmt = "%d.%d.%d.%d"; > - > - if (reverse) > - trace_seq_printf(s, fmt, buf[3], buf[2], buf[1], buf[0]); > - else > - trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3]); > - > -} > - > -static inline bool ipv6_addr_v4mapped(const struct in6_addr *a) > -{ > - return ((unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) | > - (unsigned long)(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL; > -} > - > -static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr) > -{ > - return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE); > -} > - > -static void print_ip6c_addr(struct trace_seq *s, unsigned char *addr) > -{ > - int i, j, range; > - unsigned char zerolength[8]; > - int longest = 1; > - int colonpos = -1; > - uint16_t word; > - uint8_t hi, lo; > - bool needcolon = false; > - bool useIPv4; > - struct in6_addr in6; > - > - memcpy(&in6, addr, sizeof(struct in6_addr)); > - > - useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6); > - > - memset(zerolength, 0, sizeof(zerolength)); > - > - if (useIPv4) > - range = 6; > - else > - range = 8; > - > - /* find position of longest 0 run */ > - for (i = 0; i < range; i++) { > - for (j = i; j < range; j++) { > - if (in6.s6_addr16[j] != 0) > - break; > - zerolength[i]++; > - } > - } > - for (i = 0; i < range; i++) { > - if (zerolength[i] > longest) { > - longest = zerolength[i]; > - colonpos = i; > - } > - } > - if (longest == 1) /* don't compress a single 0 */ > - colonpos = -1; > - > - /* emit address */ > - for (i = 0; i < range; i++) { > - if (i == colonpos) { > - if (needcolon || i == 0) > - trace_seq_printf(s, ":"); > - trace_seq_printf(s, ":"); > - needcolon = false; > - i += longest - 1; > - continue; > - } > - if (needcolon) { > - trace_seq_printf(s, ":"); > - needcolon = false; > - } > - /* hex u16 without leading 0s */ > - word = ntohs(in6.s6_addr16[i]); > - hi = word >> 8; > - lo = word & 0xff; > - if (hi) > - trace_seq_printf(s, "%x%02x", hi, lo); > - else > - trace_seq_printf(s, "%x", lo); > - > - needcolon = true; > - } > - > - if (useIPv4) { > - if (needcolon) > - trace_seq_printf(s, ":"); > - print_ip4_addr(s, 'I', false, &in6.s6_addr[12]); > - } > - > - return; > -} > - > -static void print_ip6_addr(struct trace_seq *s, char i, unsigned char *buf) > -{ > - int j; > - > - for (j = 0; j < 16; j += 2) { > - trace_seq_printf(s, "%02x%02x", buf[j], buf[j+1]); > - if (i == 'I' && j < 14) > - trace_seq_printf(s, ":"); > - } > -} > - > -/* > - * %pi4 print an IPv4 address with leading zeros > - * %pI4 print an IPv4 address without leading zeros > - * %pi6 print an IPv6 address without colons > - * %pI6 print an IPv6 address with colons > - * %pI6c print an IPv6 address in compressed form with colons > - * %pISpc print an IP address based on sockaddr; p adds port. > - */ > -static int print_ipv4_arg(struct trace_seq *s, const char *ptr, char i, > - void *data, int size, struct tep_event *event, > - struct tep_print_arg *arg) > -{ > - bool reverse = false; > - unsigned char *buf; > - int ret; > - > - ret = parse_ip4_print_args(event->tep, ptr, &reverse); > - > - if (arg->type == TEP_PRINT_FUNC) { > - process_defined_func(s, data, size, event, arg); > - return ret; > - } > - > - if (arg->type != TEP_PRINT_FIELD) { > - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); > - return ret; > - } > - > - if (!arg->field.field) { > - arg->field.field = > - tep_find_any_field(event, arg->field.name); > - if (!arg->field.field) { > - do_warning("%s: field %s not found", > - __func__, arg->field.name); > - return ret; > - } > - } > - > - buf = data + arg->field.field->offset; > - > - if (arg->field.field->size != 4) { > - trace_seq_printf(s, "INVALIDIPv4"); > - return ret; > - } > - > - print_ip4_addr(s, i, reverse, buf); > - return ret; > - > -} > - > -static int print_ipv6_arg(struct trace_seq *s, const char *ptr, char i, > - void *data, int size, struct tep_event *event, > - struct tep_print_arg *arg) > -{ > - char have_c = 0; > - unsigned char *buf; > - int rc = 0; > - > - /* pI6c */ > - if (i == 'I' && *ptr == 'c') { > - have_c = 1; > - ptr++; > - rc++; > - } > - > - if (arg->type == TEP_PRINT_FUNC) { > - process_defined_func(s, data, size, event, arg); > - return rc; > - } > - > - if (arg->type != TEP_PRINT_FIELD) { > - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); > - return rc; > - } > - > - if (!arg->field.field) { > - arg->field.field = > - tep_find_any_field(event, arg->field.name); > - if (!arg->field.field) { > - do_warning("%s: field %s not found", > - __func__, arg->field.name); > - return rc; > - } > - } > - > - buf = data + arg->field.field->offset; > - > - if (arg->field.field->size != 16) { > - trace_seq_printf(s, "INVALIDIPv6"); > - return rc; > - } > - > - if (have_c) > - print_ip6c_addr(s, buf); > - else > - print_ip6_addr(s, i, buf); > - > - return rc; > -} > - > -static int print_ipsa_arg(struct trace_seq *s, const char *ptr, char i, > - void *data, int size, struct tep_event *event, > - struct tep_print_arg *arg) > -{ > - char have_c = 0, have_p = 0; > - unsigned char *buf; > - struct sockaddr_storage *sa; > - bool reverse = false; > - int rc = 0; > - int ret; > - > - /* pISpc */ > - if (i == 'I') { > - if (*ptr == 'p') { > - have_p = 1; > - ptr++; > - rc++; > - } > - if (*ptr == 'c') { > - have_c = 1; > - ptr++; > - rc++; > - } > - } > - ret = parse_ip4_print_args(event->tep, ptr, &reverse); > - ptr += ret; > - rc += ret; > - > - if (arg->type == TEP_PRINT_FUNC) { > - process_defined_func(s, data, size, event, arg); > - return rc; > - } > - > - if (arg->type != TEP_PRINT_FIELD) { > - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); > - return rc; > - } > - > - if (!arg->field.field) { > - arg->field.field = > - tep_find_any_field(event, arg->field.name); > - if (!arg->field.field) { > - do_warning("%s: field %s not found", > - __func__, arg->field.name); > - return rc; > - } > - } > - > - sa = (struct sockaddr_storage *) (data + arg->field.field->offset); > - > - if (sa->ss_family == AF_INET) { > - struct sockaddr_in *sa4 = (struct sockaddr_in *) sa; > - > - if (arg->field.field->size < sizeof(struct sockaddr_in)) { > - trace_seq_printf(s, "INVALIDIPv4"); > - return rc; > - } > - > - print_ip4_addr(s, i, reverse, (unsigned char *) &sa4->sin_addr); > - if (have_p) > - trace_seq_printf(s, ":%d", ntohs(sa4->sin_port)); > - > - > - } else if (sa->ss_family == AF_INET6) { > - struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa; > - > - if (arg->field.field->size < sizeof(struct sockaddr_in6)) { > - trace_seq_printf(s, "INVALIDIPv6"); > - return rc; > - } > - > - if (have_p) > - trace_seq_printf(s, "["); > - > - buf = (unsigned char *) &sa6->sin6_addr; > - if (have_c) > - print_ip6c_addr(s, buf); > - else > - print_ip6_addr(s, i, buf); > - > - if (have_p) > - trace_seq_printf(s, "]:%d", ntohs(sa6->sin6_port)); > - } > - > - return rc; > -} > - > -static int print_ip_arg(struct trace_seq *s, const char *ptr, > - void *data, int size, struct tep_event *event, > - struct tep_print_arg *arg) > -{ > - char i = *ptr; /* 'i' or 'I' */ > - int rc = 1; > - > - /* IP version */ > - ptr++; > - > - switch (*ptr) { > - case '4': > - rc += print_ipv4_arg(s, ptr + 1, i, data, size, event, arg); > - break; > - case '6': > - rc += print_ipv6_arg(s, ptr + 1, i, data, size, event, arg); > - break; > - case 'S': > - rc += print_ipsa_arg(s, ptr + 1, i, data, size, event, arg); > - break; > - default: > - return 0; > - } > - > - return rc; > -} > - > -static const int guid_index[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15}; > -static const int uuid_index[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; > - > -static int print_uuid_arg(struct trace_seq *s, const char *ptr, > - void *data, int size, struct tep_event *event, > - struct tep_print_arg *arg) > -{ > - const int *index = uuid_index; > - char *format = "%02x"; > - int ret = 0; > - char *buf; > - int i; > - > - switch (*(ptr + 1)) { > - case 'L': > - format = "%02X"; > - /* fall through */ > - case 'l': > - index = guid_index; > - ret++; > - break; > - case 'B': > - format = "%02X"; > - /* fall through */ > - case 'b': > - ret++; > - break; > - } > - > - if (arg->type == TEP_PRINT_FUNC) { > - process_defined_func(s, data, size, event, arg); > - return ret; > - } > - > - if (arg->type != TEP_PRINT_FIELD) { > - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); > - return ret; > - } > - > - if (!arg->field.field) { > - arg->field.field = > - tep_find_any_field(event, arg->field.name); > - if (!arg->field.field) { > - do_warning("%s: field %s not found", > - __func__, arg->field.name); > - return ret; > - } > - } > - > - if (arg->field.field->size != 16) { > - trace_seq_printf(s, "INVALIDUUID"); > - return ret; > - } > - > - buf = data + arg->field.field->offset; > - > - for (i = 0; i < 16; i++) { > - trace_seq_printf(s, format, buf[index[i]] & 0xff); > - switch (i) { > - case 3: > - case 5: > - case 7: > - case 9: > - trace_seq_printf(s, "-"); > - break; > - } > - } > - > - return ret; > -} > - > -static int print_raw_buff_arg(struct trace_seq *s, const char *ptr, > - void *data, int size, struct tep_event *event, > - struct tep_print_arg *arg, int print_len) > -{ > - int plen = print_len; > - char *delim = " "; > - int ret = 0; > - char *buf; > - int i; > - unsigned long offset; > - int arr_len; > - > - switch (*(ptr + 1)) { > - case 'C': > - delim = ":"; > - ret++; > - break; > - case 'D': > - delim = "-"; > - ret++; > - break; > - case 'N': > - delim = ""; > - ret++; > - break; > - } > - > - if (arg->type == TEP_PRINT_FUNC) { > - process_defined_func(s, data, size, event, arg); > - return ret; > - } > - > - if (arg->type != TEP_PRINT_DYNAMIC_ARRAY) { > - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); > - return ret; > - } > - > - offset = tep_read_number(event->tep, > - data + arg->dynarray.field->offset, > - arg->dynarray.field->size); > - arr_len = (unsigned long long)(offset >> 16); > - buf = data + (offset & 0xffff); > - > - if (arr_len < plen) > - plen = arr_len; > - > - if (plen < 1) > - return ret; > - > - trace_seq_printf(s, "%02x", buf[0] & 0xff); > - for (i = 1; i < plen; i++) > - trace_seq_printf(s, "%s%02x", delim, buf[i] & 0xff); > - > - return ret; > -} > - > -static int is_printable_array(char *p, unsigned int len) > -{ > - unsigned int i; > - > - for (i = 0; i < len && p[i]; i++) > - if (!isprint(p[i]) && !isspace(p[i])) > - return 0; > - return 1; > -} > - > -void tep_print_field(struct trace_seq *s, void *data, > - struct tep_format_field *field) > -{ > - unsigned long long val; > - unsigned int offset, len, i; > - struct tep_handle *tep = field->event->tep; > - > - if (field->flags & TEP_FIELD_IS_ARRAY) { > - offset = field->offset; > - len = field->size; > - if (field->flags & TEP_FIELD_IS_DYNAMIC) { > - val = tep_read_number(tep, data + offset, len); > - offset = val; > - len = offset >> 16; > - offset &= 0xffff; > - if (field->flags & TEP_FIELD_IS_RELATIVE) > - offset += field->offset + field->size; > - } > - if (field->flags & TEP_FIELD_IS_STRING && > - is_printable_array(data + offset, len)) { > - trace_seq_printf(s, "%s", (char *)data + offset); > - } else { > - trace_seq_puts(s, "ARRAY["); > - for (i = 0; i < len; i++) { > - if (i) > - trace_seq_puts(s, ", "); > - trace_seq_printf(s, "%02x", > - *((unsigned char *)data + offset + i)); > - } > - trace_seq_putc(s, ']'); > - field->flags &= ~TEP_FIELD_IS_STRING; > - } > - } else { > - val = tep_read_number(tep, data + field->offset, > - field->size); > - if (field->flags & TEP_FIELD_IS_POINTER) { > - trace_seq_printf(s, "0x%llx", val); > - } else if (field->flags & TEP_FIELD_IS_SIGNED) { > - switch (field->size) { > - case 4: > - /* > - * If field is long then print it in hex. > - * A long usually stores pointers. > - */ > - if (field->flags & TEP_FIELD_IS_LONG) > - trace_seq_printf(s, "0x%x", (int)val); > - else > - trace_seq_printf(s, "%d", (int)val); > - break; > - case 2: > - trace_seq_printf(s, "%2d", (short)val); > - break; > - case 1: > - trace_seq_printf(s, "%1d", (char)val); > - break; > - default: > - trace_seq_printf(s, "%lld", val); > - } > - } else { > - if (field->flags & TEP_FIELD_IS_LONG) > - trace_seq_printf(s, "0x%llx", val); > - else > - trace_seq_printf(s, "%llu", val); > - } > - } > -} > - > -void tep_print_fields(struct trace_seq *s, void *data, > - int size __maybe_unused, struct tep_event *event) > -{ > - struct tep_format_field *field; > - > - field = event->format.fields; > - while (field) { > - trace_seq_printf(s, " %s=", field->name); > - tep_print_field(s, data, field); > - field = field->next; > - } > -} > - > -static int print_function(struct trace_seq *s, const char *format, > - void *data, int size, struct tep_event *event, > - struct tep_print_arg *arg) > -{ > - struct func_map *func; > - unsigned long long val; > - > - val = eval_num_arg(data, size, event, arg); > - func = find_func(event->tep, val); > - if (func) { > - trace_seq_puts(s, func->func); > - if (*format == 'F' || *format == 'S') > - trace_seq_printf(s, "+0x%llx", val - func->addr); > - } else { > - if (event->tep->long_size == 4) > - trace_seq_printf(s, "0x%lx", (long)val); > - else > - trace_seq_printf(s, "0x%llx", (long long)val); > - } > - > - return 0; > -} > - > -static int print_arg_pointer(struct trace_seq *s, const char *format, int plen, > - void *data, int size, > - struct tep_event *event, struct tep_print_arg *arg) > -{ > - unsigned long long val; > - int ret = 1; > - > - if (arg->type == TEP_PRINT_BSTRING) { > - trace_seq_puts(s, arg->string.string); > - return 0; > - } > - while (*format) { > - if (*format == 'p') { > - format++; > - break; > - } > - format++; > - } > - > - switch (*format) { > - case 'F': > - case 'f': > - case 'S': > - case 's': > - ret += print_function(s, format, data, size, event, arg); > - break; > - case 'M': > - case 'm': > - ret += print_mac_arg(s, format, data, size, event, arg); > - break; > - case 'I': > - case 'i': > - ret += print_ip_arg(s, format, data, size, event, arg); > - break; > - case 'U': > - ret += print_uuid_arg(s, format, data, size, event, arg); > - break; > - case 'h': > - ret += print_raw_buff_arg(s, format, data, size, event, arg, plen); > - break; > - default: > - ret = 0; > - val = eval_num_arg(data, size, event, arg); > - trace_seq_printf(s, "%p", (void *)(intptr_t)val); > - break; > - } > - > - return ret; > - > -} > - > -static int print_arg_number(struct trace_seq *s, const char *format, int plen, > - void *data, int size, int ls, > - struct tep_event *event, struct tep_print_arg *arg) > -{ > - unsigned long long val; > - > - val = eval_num_arg(data, size, event, arg); > - > - switch (ls) { > - case -2: > - if (plen >= 0) > - trace_seq_printf(s, format, plen, (char)val); > - else > - trace_seq_printf(s, format, (char)val); > - break; > - case -1: > - if (plen >= 0) > - trace_seq_printf(s, format, plen, (short)val); > - else > - trace_seq_printf(s, format, (short)val); > - break; > - case 0: > - if (plen >= 0) > - trace_seq_printf(s, format, plen, (int)val); > - else > - trace_seq_printf(s, format, (int)val); > - break; > - case 1: > - if (plen >= 0) > - trace_seq_printf(s, format, plen, (long)val); > - else > - trace_seq_printf(s, format, (long)val); > - break; > - case 2: > - if (plen >= 0) > - trace_seq_printf(s, format, plen, (long long)val); > - else > - trace_seq_printf(s, format, (long long)val); > - break; > - default: > - do_warning_event(event, "bad count (%d)", ls); > - event->flags |= TEP_EVENT_FL_FAILED; > - } > - return 0; > -} > - > - > -static void print_arg_string(struct trace_seq *s, const char *format, int plen, > - void *data, int size, > - struct tep_event *event, struct tep_print_arg *arg) > -{ > - struct trace_seq p; > - > - /* Use helper trace_seq */ > - trace_seq_init(&p); > - print_str_arg(&p, data, size, event, > - format, plen, arg); > - trace_seq_terminate(&p); > - trace_seq_puts(s, p.buffer); > - trace_seq_destroy(&p); > -} > - > -static int parse_arg_format_pointer(const char *format) > -{ > - int ret = 0; > - int index; > - int loop; > - > - switch (*format) { > - case 'F': > - case 'S': > - case 'f': > - case 's': > - ret++; > - break; > - case 'M': > - case 'm': > - /* [mM]R , [mM]F */ > - switch (format[1]) { > - case 'R': > - case 'F': > - ret++; > - break; > - } > - ret++; > - break; > - case 'I': > - case 'i': > - index = 2; > - loop = 1; > - switch (format[1]) { > - case 'S': > - /*[S][pfs]*/ > - while (loop) { > - switch (format[index]) { > - case 'p': > - case 'f': > - case 's': > - ret++; > - index++; > - break; > - default: > - loop = 0; > - break; > - } > - } > - /* fall through */ > - case '4': > - /* [4S][hnbl] */ > - switch (format[index]) { > - case 'h': > - case 'n': > - case 'l': > - case 'b': > - ret++; > - index++; > - break; > - } > - if (format[1] == '4') { > - ret++; > - break; > - } > - /* fall through */ > - case '6': > - /* [6S]c */ > - if (format[index] == 'c') > - ret++; > - ret++; > - break; > - } > - ret++; > - break; > - case 'U': > - switch (format[1]) { > - case 'L': > - case 'l': > - case 'B': > - case 'b': > - ret++; > - break; > - } > - ret++; > - break; > - case 'h': > - switch (format[1]) { > - case 'C': > - case 'D': > - case 'N': > - ret++; > - break; > - } > - ret++; > - break; > - default: > - break; > - } > - > - return ret; > -} > - > -static void free_parse_args(struct tep_print_parse *arg) > -{ > - struct tep_print_parse *del; > - > - while (arg) { > - del = arg; > - arg = del->next; > - free(del->format); > - free(del); > - } > -} > - > -static int parse_arg_add(struct tep_print_parse **parse, char *format, > - enum tep_print_parse_type type, > - struct tep_print_arg *arg, > - struct tep_print_arg *len_as_arg, > - int ls) > -{ > - struct tep_print_parse *parg = NULL; > - > - parg = calloc(1, sizeof(*parg)); > - if (!parg) > - goto error; > - parg->format = strdup(format); > - if (!parg->format) > - goto error; > - parg->type = type; > - parg->arg = arg; > - parg->len_as_arg = len_as_arg; > - parg->ls = ls; > - *parse = parg; > - return 0; > -error: > - if (parg) { > - free(parg->format); > - free(parg); > - } > - return -1; > -} > - > -static int parse_arg_format(struct tep_print_parse **parse, > - struct tep_event *event, > - const char *format, struct tep_print_arg **arg) > -{ > - struct tep_print_arg *len_arg = NULL; > - char print_format[32]; > - const char *start = format; > - int ret = 0; > - int ls = 0; > - int res; > - int len; > - > - format++; > - ret++; > - for (; *format; format++) { > - switch (*format) { > - case '#': > - /* FIXME: need to handle properly */ > - break; > - case 'h': > - ls--; > - break; > - case 'l': > - ls++; > - break; > - case 'L': > - ls = 2; > - break; > - case '.': > - case 'z': > - case 'Z': > - case '0' ... '9': > - case '-': > - break; > - case '*': > - /* The argument is the length. */ > - if (!*arg) { > - do_warning_event(event, "no argument match"); > - event->flags |= TEP_EVENT_FL_FAILED; > - goto out_failed; > - } > - if (len_arg) { > - do_warning_event(event, "argument already matched"); > - event->flags |= TEP_EVENT_FL_FAILED; > - goto out_failed; > - } > - len_arg = *arg; > - *arg = (*arg)->next; > - break; > - case 'p': > - if (!*arg) { > - do_warning_event(event, "no argument match"); > - event->flags |= TEP_EVENT_FL_FAILED; > - goto out_failed; > - } > - res = parse_arg_format_pointer(format + 1); > - if (res > 0) { > - format += res; > - ret += res; > - } > - len = ((unsigned long)format + 1) - > - (unsigned long)start; > - /* should never happen */ > - if (len > 31) { > - do_warning_event(event, "bad format!"); > - event->flags |= TEP_EVENT_FL_FAILED; > - len = 31; > - } > - memcpy(print_format, start, len); > - print_format[len] = 0; > - > - parse_arg_add(parse, print_format, > - PRINT_FMT_ARG_POINTER, *arg, len_arg, ls); > - *arg = (*arg)->next; > - ret++; > - return ret; > - case 'd': > - case 'u': > - case 'i': > - case 'x': > - case 'X': > - case 'o': > - if (!*arg) { > - do_warning_event(event, "no argument match"); > - event->flags |= TEP_EVENT_FL_FAILED; > - goto out_failed; > - } > - > - len = ((unsigned long)format + 1) - > - (unsigned long)start; > - > - /* should never happen */ > - if (len > 30) { > - do_warning_event(event, "bad format!"); > - event->flags |= TEP_EVENT_FL_FAILED; > - len = 31; > - } > - memcpy(print_format, start, len); > - print_format[len] = 0; > - > - if (event->tep->long_size == 8 && ls == 1 && > - sizeof(long) != 8) { > - char *p; > - > - /* make %l into %ll */ > - if (ls == 1 && (p = strchr(print_format, 'l'))) > - memmove(p+1, p, strlen(p)+1); > - ls = 2; > - } > - if (ls < -2 || ls > 2) { > - do_warning_event(event, "bad count (%d)", ls); > - event->flags |= TEP_EVENT_FL_FAILED; > - } > - parse_arg_add(parse, print_format, > - PRINT_FMT_ARG_DIGIT, *arg, len_arg, ls); > - *arg = (*arg)->next; > - ret++; > - return ret; > - case 's': > - if (!*arg) { > - do_warning_event(event, "no matching argument"); > - event->flags |= TEP_EVENT_FL_FAILED; > - goto out_failed; > - } > - > - len = ((unsigned long)format + 1) - > - (unsigned long)start; > - > - /* should never happen */ > - if (len > 31) { > - do_warning_event(event, "bad format!"); > - event->flags |= TEP_EVENT_FL_FAILED; > - len = 31; > - } > - > - memcpy(print_format, start, len); > - print_format[len] = 0; > - > - parse_arg_add(parse, print_format, > - PRINT_FMT_ARG_STRING, *arg, len_arg, 0); > - *arg = (*arg)->next; > - ret++; > - return ret; > - default: > - snprintf(print_format, 32, ">%c<", *format); > - parse_arg_add(parse, print_format, > - PRINT_FMT_STRING, NULL, NULL, 0); > - ret++; > - return ret; > - } > - ret++; > - } > - > -out_failed: > - return ret; > - > -} > - > -static int parse_arg_string(struct tep_print_parse **parse, const char *format) > -{ > - struct trace_seq s; > - int ret = 0; > - > - trace_seq_init(&s); > - for (; *format; format++) { > - if (*format == '\\') { > - format++; > - ret++; > - switch (*format) { > - case 'n': > - trace_seq_putc(&s, '\n'); > - break; > - case 't': > - trace_seq_putc(&s, '\t'); > - break; > - case 'r': > - trace_seq_putc(&s, '\r'); > - break; > - case '\\': > - trace_seq_putc(&s, '\\'); > - break; > - default: > - trace_seq_putc(&s, *format); > - break; > - } > - } else if (*format == '%') { > - if (*(format + 1) == '%') { > - trace_seq_putc(&s, '%'); > - format++; > - ret++; > - } else > - break; > - } else > - trace_seq_putc(&s, *format); > - > - ret++; > - } > - trace_seq_terminate(&s); > - parse_arg_add(parse, s.buffer, PRINT_FMT_STRING, NULL, NULL, 0); > - trace_seq_destroy(&s); > - > - return ret; > -} > - > -static struct tep_print_parse * > -parse_args(struct tep_event *event, const char *format, struct tep_print_arg *arg) > -{ > - struct tep_print_parse *parse_ret = NULL; > - struct tep_print_parse **parse = NULL; > - int ret; > - int len; > - > - len = strlen(format); > - while (*format) { > - if (!parse_ret) > - parse = &parse_ret; > - if (*format == '%' && *(format + 1) != '%') > - ret = parse_arg_format(parse, event, format, &arg); > - else > - ret = parse_arg_string(parse, format); > - if (*parse) > - parse = &((*parse)->next); > - > - len -= ret; > - if (len > 0) > - format += ret; > - else > - break; > - } > - return parse_ret; > -} > - > -static void print_event_cache(struct tep_print_parse *parse, struct trace_seq *s, > - void *data, int size, struct tep_event *event) > -{ > - int len_arg; > - > - while (parse) { > - if (parse->len_as_arg) > - len_arg = eval_num_arg(data, size, event, parse->len_as_arg); > - switch (parse->type) { > - case PRINT_FMT_ARG_DIGIT: > - print_arg_number(s, parse->format, > - parse->len_as_arg ? len_arg : -1, data, > - size, parse->ls, event, parse->arg); > - break; > - case PRINT_FMT_ARG_POINTER: > - print_arg_pointer(s, parse->format, > - parse->len_as_arg ? len_arg : 1, > - data, size, event, parse->arg); > - break; > - case PRINT_FMT_ARG_STRING: > - print_arg_string(s, parse->format, > - parse->len_as_arg ? len_arg : -1, > - data, size, event, parse->arg); > - break; > - case PRINT_FMT_STRING: > - default: > - trace_seq_printf(s, "%s", parse->format); > - break; > - } > - parse = parse->next; > - } > -} > - > -static void pretty_print(struct trace_seq *s, void *data, int size, struct tep_event *event) > -{ > - struct tep_print_parse *parse = event->print_fmt.print_cache; > - struct tep_print_arg *args = NULL; > - char *bprint_fmt = NULL; > - > - if (event->flags & TEP_EVENT_FL_FAILED) { > - trace_seq_printf(s, "[FAILED TO PARSE]"); > - tep_print_fields(s, data, size, event); > - return; > - } > - > - if (event->flags & TEP_EVENT_FL_ISBPRINT) { > - bprint_fmt = get_bprint_format(data, size, event); > - args = make_bprint_args(bprint_fmt, data, size, event); > - parse = parse_args(event, bprint_fmt, args); > - } > - > - print_event_cache(parse, s, data, size, event); > - > - if (event->flags & TEP_EVENT_FL_ISBPRINT) { > - free_parse_args(parse); > - free_args(args); > - free(bprint_fmt); > - } > -} > - > -/* > - * This parses out the Latency format (interrupts disabled, > - * need rescheduling, in hard/soft interrupt, preempt count > - * and lock depth) and places it into the trace_seq. > - */ > -static void data_latency_format(struct tep_handle *tep, struct trace_seq *s, > - char *format, struct tep_record *record) > -{ > - static int check_lock_depth = 1; > - static int check_migrate_disable = 1; > - static int lock_depth_exists; > - static int migrate_disable_exists; > - unsigned int lat_flags; > - struct trace_seq sq; > - unsigned int pc; > - int lock_depth = 0; > - int migrate_disable = 0; > - int hardirq; > - int softirq; > - void *data = record->data; > - > - trace_seq_init(&sq); > - lat_flags = parse_common_flags(tep, data); > - pc = parse_common_pc(tep, data); > - /* lock_depth may not always exist */ > - if (lock_depth_exists) > - lock_depth = parse_common_lock_depth(tep, data); > - else if (check_lock_depth) { > - lock_depth = parse_common_lock_depth(tep, data); > - if (lock_depth < 0) > - check_lock_depth = 0; > - else > - lock_depth_exists = 1; > - } > - > - /* migrate_disable may not always exist */ > - if (migrate_disable_exists) > - migrate_disable = parse_common_migrate_disable(tep, data); > - else if (check_migrate_disable) { > - migrate_disable = parse_common_migrate_disable(tep, data); > - if (migrate_disable < 0) > - check_migrate_disable = 0; > - else > - migrate_disable_exists = 1; > - } > - > - hardirq = lat_flags & TRACE_FLAG_HARDIRQ; > - softirq = lat_flags & TRACE_FLAG_SOFTIRQ; > - > - trace_seq_printf(&sq, "%c%c%c", > - (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : > - (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? > - 'X' : '.', > - (lat_flags & TRACE_FLAG_NEED_RESCHED) ? > - 'N' : '.', > - (hardirq && softirq) ? 'H' : > - hardirq ? 'h' : softirq ? 's' : '.'); > - > - if (pc) > - trace_seq_printf(&sq, "%x", pc); > - else > - trace_seq_printf(&sq, "."); > - > - if (migrate_disable_exists) { > - if (migrate_disable < 0) > - trace_seq_printf(&sq, "."); > - else > - trace_seq_printf(&sq, "%d", migrate_disable); > - } > - > - if (lock_depth_exists) { > - if (lock_depth < 0) > - trace_seq_printf(&sq, "."); > - else > - trace_seq_printf(&sq, "%d", lock_depth); > - } > - > - if (sq.state == TRACE_SEQ__MEM_ALLOC_FAILED) { > - s->state = TRACE_SEQ__MEM_ALLOC_FAILED; > - return; > - } > - > - trace_seq_terminate(&sq); > - trace_seq_puts(s, sq.buffer); > - trace_seq_destroy(&sq); > - trace_seq_terminate(s); > -} > - > -/** > - * tep_data_type - parse out the given event type > - * @tep: a handle to the trace event parser context > - * @rec: the record to read from > - * > - * This returns the event id from the @rec. > - */ > -int tep_data_type(struct tep_handle *tep, struct tep_record *rec) > -{ > - return trace_parse_common_type(tep, rec->data); > -} > - > -/** > - * tep_data_pid - parse the PID from record > - * @tep: a handle to the trace event parser context > - * @rec: the record to parse > - * > - * This returns the PID from a record. > - */ > -int tep_data_pid(struct tep_handle *tep, struct tep_record *rec) > -{ > - return parse_common_pid(tep, rec->data); > -} > - > -/** > - * tep_data_preempt_count - parse the preempt count from the record > - * @tep: a handle to the trace event parser context > - * @rec: the record to parse > - * > - * This returns the preempt count from a record. > - */ > -int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec) > -{ > - return parse_common_pc(tep, rec->data); > -} > - > -/** > - * tep_data_flags - parse the latency flags from the record > - * @tep: a handle to the trace event parser context > - * @rec: the record to parse > - * > - * This returns the latency flags from a record. > - * > - * Use trace_flag_type enum for the flags (see event-parse.h). > - */ > -int tep_data_flags(struct tep_handle *tep, struct tep_record *rec) > -{ > - return parse_common_flags(tep, rec->data); > -} > - > -/** > - * tep_data_comm_from_pid - return the command line from PID > - * @tep: a handle to the trace event parser context > - * @pid: the PID of the task to search for > - * > - * This returns a pointer to the command line that has the given > - * @pid. > - */ > -const char *tep_data_comm_from_pid(struct tep_handle *tep, int pid) > -{ > - const char *comm; > - > - comm = find_cmdline(tep, pid); > - return comm; > -} > - > -static struct tep_cmdline * > -pid_from_cmdlist(struct tep_handle *tep, const char *comm, struct tep_cmdline *next) > -{ > - struct cmdline_list *cmdlist = (struct cmdline_list *)next; > - > - if (cmdlist) > - cmdlist = cmdlist->next; > - else > - cmdlist = tep->cmdlist; > - > - while (cmdlist && strcmp(cmdlist->comm, comm) != 0) > - cmdlist = cmdlist->next; > - > - return (struct tep_cmdline *)cmdlist; > -} > - > -/** > - * tep_data_pid_from_comm - return the pid from a given comm > - * @tep: a handle to the trace event parser context > - * @comm: the cmdline to find the pid from > - * @next: the cmdline structure to find the next comm > - * > - * This returns the cmdline structure that holds a pid for a given > - * comm, or NULL if none found. As there may be more than one pid for > - * a given comm, the result of this call can be passed back into > - * a recurring call in the @next parameter, and then it will find the > - * next pid. > - * Also, it does a linear search, so it may be slow. > - */ > -struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *tep, const char *comm, > - struct tep_cmdline *next) > -{ > - struct tep_cmdline *cmdline; > - > - /* > - * If the cmdlines have not been converted yet, then use > - * the list. > - */ > - if (!tep->cmdlines) > - return pid_from_cmdlist(tep, comm, next); > - > - if (next) { > - /* > - * The next pointer could have been still from > - * a previous call before cmdlines were created > - */ > - if (next < tep->cmdlines || > - next >= tep->cmdlines + tep->cmdline_count) > - next = NULL; > - else > - cmdline = next++; > - } > - > - if (!next) > - cmdline = tep->cmdlines; > - > - while (cmdline < tep->cmdlines + tep->cmdline_count) { > - if (strcmp(cmdline->comm, comm) == 0) > - return cmdline; > - cmdline++; > - } > - return NULL; > -} > - > -/** > - * tep_cmdline_pid - return the pid associated to a given cmdline > - * @tep: a handle to the trace event parser context > - * @cmdline: The cmdline structure to get the pid from > - * > - * Returns the pid for a give cmdline. If @cmdline is NULL, then > - * -1 is returned. > - */ > -int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline) > -{ > - struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline; > - > - if (!cmdline) > - return -1; > - > - /* > - * If cmdlines have not been created yet, or cmdline is > - * not part of the array, then treat it as a cmdlist instead. > - */ > - if (!tep->cmdlines || > - cmdline < tep->cmdlines || > - cmdline >= tep->cmdlines + tep->cmdline_count) > - return cmdlist->pid; > - > - return cmdline->pid; > -} > - > -/* > - * This parses the raw @data using the given @event information and > - * writes the print format into the trace_seq. > - */ > -static void print_event_info(struct trace_seq *s, char *format, bool raw, > - struct tep_event *event, struct tep_record *record) > -{ > - int print_pretty = 1; > - > - if (raw || (event->flags & TEP_EVENT_FL_PRINTRAW)) > - tep_print_fields(s, record->data, record->size, event); > - else { > - > - if (event->handler && !(event->flags & TEP_EVENT_FL_NOHANDLE)) > - print_pretty = event->handler(s, record, event, > - event->context); > - > - if (print_pretty) > - pretty_print(s, record->data, record->size, event); > - } > - > - trace_seq_terminate(s); > -} > - > -/** > - * tep_find_event_by_record - return the event from a given record > - * @tep: a handle to the trace event parser context > - * @record: The record to get the event from > - * > - * Returns the associated event for a given record, or NULL if non is > - * is found. > - */ > -struct tep_event * > -tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record) > -{ > - int type; > - > - if (record->size < 0) { > - do_warning("ug! negative record size %d", record->size); > - return NULL; > - } > - > - type = trace_parse_common_type(tep, record->data); > - > - return tep_find_event(tep, type); > -} > - > -/* > - * Writes the timestamp of the record into @s. Time divisor and precision can be > - * specified as part of printf @format string. Example: > - * "%3.1000d" - divide the time by 1000 and print the first 3 digits > - * before the dot. Thus, the timestamp "123456000" will be printed as > - * "123.456" > - */ > -static void print_event_time(struct tep_handle *tep, struct trace_seq *s, > - char *format, struct tep_event *event, > - struct tep_record *record) > -{ > - unsigned long long time; > - char *divstr; > - int prec = 0, pr; > - int div = 0; > - int p10 = 1; > - > - if (isdigit(*(format + 1))) > - prec = atoi(format + 1); > - divstr = strchr(format, '.'); > - if (divstr && isdigit(*(divstr + 1))) > - div = atoi(divstr + 1); > - time = record->ts; > - if (div) { > - time += div / 2; > - time /= div; > - } > - pr = prec; > - while (pr--) > - p10 *= 10; > - > - if (p10 > 1 && p10 < time) > - trace_seq_printf(s, "%5llu.%0*llu", time / p10, prec, time % p10); > - else > - trace_seq_printf(s, "%12llu", time); > -} > - > -struct print_event_type { > - enum { > - EVENT_TYPE_INT = 1, > - EVENT_TYPE_STRING, > - EVENT_TYPE_UNKNOWN, > - } type; > - char format[32]; > -}; > - > -static void print_string(struct tep_handle *tep, struct trace_seq *s, > - struct tep_record *record, struct tep_event *event, > - const char *arg, struct print_event_type *type) > -{ > - const char *comm; > - int pid; > - > - if (strncmp(arg, TEP_PRINT_LATENCY, strlen(TEP_PRINT_LATENCY)) == 0) { > - data_latency_format(tep, s, type->format, record); > - } else if (strncmp(arg, TEP_PRINT_COMM, strlen(TEP_PRINT_COMM)) == 0) { > - pid = parse_common_pid(tep, record->data); > - comm = find_cmdline(tep, pid); > - trace_seq_printf(s, type->format, comm); > - } else if (strncmp(arg, TEP_PRINT_INFO_RAW, strlen(TEP_PRINT_INFO_RAW)) == 0) { > - print_event_info(s, type->format, true, event, record); > - } else if (strncmp(arg, TEP_PRINT_INFO, strlen(TEP_PRINT_INFO)) == 0) { > - print_event_info(s, type->format, false, event, record); > - } else if (strncmp(arg, TEP_PRINT_NAME, strlen(TEP_PRINT_NAME)) == 0) { > - trace_seq_printf(s, type->format, event->name); > - } else { > - trace_seq_printf(s, "[UNKNOWN TEP TYPE %s]", arg); > - } > - > -} > - > -static void print_int(struct tep_handle *tep, struct trace_seq *s, > - struct tep_record *record, struct tep_event *event, > - int arg, struct print_event_type *type) > -{ > - int param; > - > - switch (arg) { > - case TEP_PRINT_CPU: > - param = record->cpu; > - break; > - case TEP_PRINT_PID: > - param = parse_common_pid(tep, record->data); > - break; > - case TEP_PRINT_TIME: > - return print_event_time(tep, s, type->format, event, record); > - default: > - return; > - } > - trace_seq_printf(s, type->format, param); > -} > - > -static int tep_print_event_param_type(char *format, > - struct print_event_type *type) > -{ > - char *str = format + 1; > - int i = 1; > - > - type->type = EVENT_TYPE_UNKNOWN; > - while (*str) { > - switch (*str) { > - case 'd': > - case 'u': > - case 'i': > - case 'x': > - case 'X': > - case 'o': > - type->type = EVENT_TYPE_INT; > - break; > - case 's': > - type->type = EVENT_TYPE_STRING; > - break; > - } > - str++; > - i++; > - if (type->type != EVENT_TYPE_UNKNOWN) > - break; > - } > - memset(type->format, 0, 32); > - memcpy(type->format, format, i < 32 ? i : 31); > - return i; > -} > - > -/** > - * tep_print_event - Write various event information > - * @tep: a handle to the trace event parser context > - * @s: the trace_seq to write to > - * @record: The record to get the event from > - * @format: a printf format string. Supported event fileds: > - * TEP_PRINT_PID, "%d" - event PID > - * TEP_PRINT_CPU, "%d" - event CPU > - * TEP_PRINT_COMM, "%s" - event command string > - * TEP_PRINT_NAME, "%s" - event name > - * TEP_PRINT_LATENCY, "%s" - event latency > - * TEP_PRINT_TIME, %d - event time stamp. A divisor and precision > - * can be specified as part of this format string: > - * "%precision.divisord". Example: > - * "%3.1000d" - divide the time by 1000 and print the first > - * 3 digits before the dot. Thus, the time stamp > - * "123456000" will be printed as "123.456" > - * TEP_PRINT_INFO, "%s" - event information. If any width is specified in > - * the format string, the event information will be printed > - * in raw format. > - * Writes the specified event information into @s. > - */ > -void tep_print_event(struct tep_handle *tep, struct trace_seq *s, > - struct tep_record *record, const char *fmt, ...) > -{ > - struct print_event_type type; > - char *format = strdup(fmt); > - char *current = format; > - char *str = format; > - int offset; > - va_list args; > - struct tep_event *event; > - > - if (!format) > - return; > - > - event = tep_find_event_by_record(tep, record); > - va_start(args, fmt); > - while (*current) { > - current = strchr(str, '%'); > - if (!current) { > - trace_seq_puts(s, str); > - break; > - } > - memset(&type, 0, sizeof(type)); > - offset = tep_print_event_param_type(current, &type); > - *current = '\0'; > - trace_seq_puts(s, str); > - current += offset; > - switch (type.type) { > - case EVENT_TYPE_STRING: > - print_string(tep, s, record, event, > - va_arg(args, char*), &type); > - break; > - case EVENT_TYPE_INT: > - print_int(tep, s, record, event, > - va_arg(args, int), &type); > - break; > - case EVENT_TYPE_UNKNOWN: > - default: > - trace_seq_printf(s, "[UNKNOWN TYPE]"); > - break; > - } > - str = current; > - > - } > - va_end(args); > - free(format); > -} > - > -static int events_id_cmp(const void *a, const void *b) > -{ > - struct tep_event * const * ea = a; > - struct tep_event * const * eb = b; > - > - if ((*ea)->id < (*eb)->id) > - return -1; > - > - if ((*ea)->id > (*eb)->id) > - return 1; > - > - return 0; > -} > - > -static int events_name_cmp(const void *a, const void *b) > -{ > - struct tep_event * const * ea = a; > - struct tep_event * const * eb = b; > - int res; > - > - res = strcmp((*ea)->name, (*eb)->name); > - if (res) > - return res; > - > - res = strcmp((*ea)->system, (*eb)->system); > - if (res) > - return res; > - > - return events_id_cmp(a, b); > -} > - > -static int events_system_cmp(const void *a, const void *b) > -{ > - struct tep_event * const * ea = a; > - struct tep_event * const * eb = b; > - int res; > - > - res = strcmp((*ea)->system, (*eb)->system); > - if (res) > - return res; > - > - res = strcmp((*ea)->name, (*eb)->name); > - if (res) > - return res; > - > - return events_id_cmp(a, b); > -} > - > -static struct tep_event **list_events_copy(struct tep_handle *tep) > -{ > - struct tep_event **events; > - > - if (!tep) > - return NULL; > - > - events = malloc(sizeof(*events) * (tep->nr_events + 1)); > - if (!events) > - return NULL; > - > - memcpy(events, tep->events, sizeof(*events) * tep->nr_events); > - events[tep->nr_events] = NULL; > - return events; > -} > - > -static void list_events_sort(struct tep_event **events, int nr_events, > - enum tep_event_sort_type sort_type) > -{ > - int (*sort)(const void *a, const void *b); > - > - switch (sort_type) { > - case TEP_EVENT_SORT_ID: > - sort = events_id_cmp; > - break; > - case TEP_EVENT_SORT_NAME: > - sort = events_name_cmp; > - break; > - case TEP_EVENT_SORT_SYSTEM: > - sort = events_system_cmp; > - break; > - default: > - sort = NULL; > - } > - > - if (sort) > - qsort(events, nr_events, sizeof(*events), sort); > -} > - > -/** > - * tep_list_events - Get events, sorted by given criteria. > - * @tep: a handle to the tep context > - * @sort_type: desired sort order of the events in the array > - * > - * Returns an array of pointers to all events, sorted by the given > - * @sort_type criteria. The last element of the array is NULL. The returned > - * memory must not be freed, it is managed by the library. > - * The function is not thread safe. > - */ > -struct tep_event **tep_list_events(struct tep_handle *tep, > - enum tep_event_sort_type sort_type) > -{ > - struct tep_event **events; > - > - if (!tep) > - return NULL; > - > - events = tep->sort_events; > - if (events && tep->last_type == sort_type) > - return events; > - > - if (!events) { > - events = list_events_copy(tep); > - if (!events) > - return NULL; > - > - tep->sort_events = events; > - > - /* the internal events are sorted by id */ > - if (sort_type == TEP_EVENT_SORT_ID) { > - tep->last_type = sort_type; > - return events; > - } > - } > - > - list_events_sort(events, tep->nr_events, sort_type); > - tep->last_type = sort_type; > - > - return events; > -} > - > - > -/** > - * tep_list_events_copy - Thread safe version of tep_list_events() > - * @tep: a handle to the tep context > - * @sort_type: desired sort order of the events in the array > - * > - * Returns an array of pointers to all events, sorted by the given > - * @sort_type criteria. The last element of the array is NULL. The returned > - * array is newly allocated inside the function and must be freed by the caller > - */ > -struct tep_event **tep_list_events_copy(struct tep_handle *tep, > - enum tep_event_sort_type sort_type) > -{ > - struct tep_event **events; > - > - if (!tep) > - return NULL; > - > - events = list_events_copy(tep); > - if (!events) > - return NULL; > - > - /* the internal events are sorted by id */ > - if (sort_type == TEP_EVENT_SORT_ID) > - return events; > - > - list_events_sort(events, tep->nr_events, sort_type); > - > - return events; > -} > - > -static struct tep_format_field ** > -get_event_fields(const char *type, const char *name, > - int count, struct tep_format_field *list) > -{ > - struct tep_format_field **fields; > - struct tep_format_field *field; > - int i = 0; > - > - fields = malloc(sizeof(*fields) * (count + 1)); > - if (!fields) > - return NULL; > - > - for (field = list; field; field = field->next) { > - fields[i++] = field; > - if (i == count + 1) { > - do_warning("event %s has more %s fields than specified", > - name, type); > - i--; > - break; > - } > - } > - > - if (i != count) > - do_warning("event %s has less %s fields than specified", > - name, type); > - > - fields[i] = NULL; > - > - return fields; > -} > - > -/** > - * tep_event_common_fields - return a list of common fields for an event > - * @event: the event to return the common fields of. > - * > - * Returns an allocated array of fields. The last item in the array is NULL. > - * The array must be freed with free(). > - */ > -struct tep_format_field **tep_event_common_fields(struct tep_event *event) > -{ > - return get_event_fields("common", event->name, > - event->format.nr_common, > - event->format.common_fields); > -} > - > -/** > - * tep_event_fields - return a list of event specific fields for an event > - * @event: the event to return the fields of. > - * > - * Returns an allocated array of fields. The last item in the array is NULL. > - * The array must be freed with free(). > - */ > -struct tep_format_field **tep_event_fields(struct tep_event *event) > -{ > - return get_event_fields("event", event->name, > - event->format.nr_fields, > - event->format.fields); > -} > - > -static void print_fields(struct trace_seq *s, struct tep_print_flag_sym *field) > -{ > - trace_seq_printf(s, "{ %s, %s }", field->value, field->str); > - if (field->next) { > - trace_seq_puts(s, ", "); > - print_fields(s, field->next); > - } > -} > - > -/* for debugging */ > -static void print_args(struct tep_print_arg *args) > -{ > - int print_paren = 1; > - struct trace_seq s; > - > - switch (args->type) { > - case TEP_PRINT_NULL: > - printf("null"); > - break; > - case TEP_PRINT_ATOM: > - printf("%s", args->atom.atom); > - break; > - case TEP_PRINT_FIELD: > - printf("REC->%s", args->field.name); > - break; > - case TEP_PRINT_FLAGS: > - printf("__print_flags("); > - print_args(args->flags.field); > - printf(", %s, ", args->flags.delim); > - trace_seq_init(&s); > - print_fields(&s, args->flags.flags); > - trace_seq_do_printf(&s); > - trace_seq_destroy(&s); > - printf(")"); > - break; > - case TEP_PRINT_SYMBOL: > - printf("__print_symbolic("); > - print_args(args->symbol.field); > - printf(", "); > - trace_seq_init(&s); > - print_fields(&s, args->symbol.symbols); > - trace_seq_do_printf(&s); > - trace_seq_destroy(&s); > - printf(")"); > - break; > - case TEP_PRINT_HEX: > - printf("__print_hex("); > - print_args(args->hex.field); > - printf(", "); > - print_args(args->hex.size); > - printf(")"); > - break; > - case TEP_PRINT_HEX_STR: > - printf("__print_hex_str("); > - print_args(args->hex.field); > - printf(", "); > - print_args(args->hex.size); > - printf(")"); > - break; > - case TEP_PRINT_INT_ARRAY: > - printf("__print_array("); > - print_args(args->int_array.field); > - printf(", "); > - print_args(args->int_array.count); > - printf(", "); > - print_args(args->int_array.el_size); > - printf(")"); > - break; > - case TEP_PRINT_STRING: > - case TEP_PRINT_BSTRING: > - printf("__get_str(%s)", args->string.string); > - break; > - case TEP_PRINT_BITMASK: > - printf("__get_bitmask(%s)", args->bitmask.bitmask); > - break; > - case TEP_PRINT_TYPE: > - printf("(%s)", args->typecast.type); > - print_args(args->typecast.item); > - break; > - case TEP_PRINT_OP: > - if (strcmp(args->op.op, ":") == 0) > - print_paren = 0; > - if (print_paren) > - printf("("); > - print_args(args->op.left); > - printf(" %s ", args->op.op); > - print_args(args->op.right); > - if (print_paren) > - printf(")"); > - break; > - default: > - /* we should warn... */ > - return; > - } > - if (args->next) { > - printf("\n"); > - print_args(args->next); > - } > -} > - > -static void parse_header_field(const char *field, > - int *offset, int *size, int mandatory) > -{ > - unsigned long long save_input_buf_ptr; > - unsigned long long save_input_buf_siz; > - char *token; > - int type; > - > - save_input_buf_ptr = input_buf_ptr; > - save_input_buf_siz = input_buf_siz; > - > - if (read_expected(TEP_EVENT_ITEM, "field") < 0) > - return; > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - return; > - > - /* type */ > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto fail; > - free_token(token); > - > - /* > - * If this is not a mandatory field, then test it first. > - */ > - if (mandatory) { > - if (read_expected(TEP_EVENT_ITEM, field) < 0) > - return; > - } else { > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto fail; > - if (strcmp(token, field) != 0) > - goto discard; > - free_token(token); > - } > - > - if (read_expected(TEP_EVENT_OP, ";") < 0) > - return; > - if (read_expected(TEP_EVENT_ITEM, "offset") < 0) > - return; > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - return; > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto fail; > - *offset = atoi(token); > - free_token(token); > - if (read_expected(TEP_EVENT_OP, ";") < 0) > - return; > - if (read_expected(TEP_EVENT_ITEM, "size") < 0) > - return; > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - return; > - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) > - goto fail; > - *size = atoi(token); > - free_token(token); > - if (read_expected(TEP_EVENT_OP, ";") < 0) > - return; > - type = read_token(&token); > - if (type != TEP_EVENT_NEWLINE) { > - /* newer versions of the kernel have a "signed" type */ > - if (type != TEP_EVENT_ITEM) > - goto fail; > - > - if (strcmp(token, "signed") != 0) > - goto fail; > - > - free_token(token); > - > - if (read_expected(TEP_EVENT_OP, ":") < 0) > - return; > - > - if (read_expect_type(TEP_EVENT_ITEM, &token)) > - goto fail; > - > - free_token(token); > - if (read_expected(TEP_EVENT_OP, ";") < 0) > - return; > - > - if (read_expect_type(TEP_EVENT_NEWLINE, &token)) > - goto fail; > - } > - fail: > - free_token(token); > - return; > - > - discard: > - input_buf_ptr = save_input_buf_ptr; > - input_buf_siz = save_input_buf_siz; > - *offset = 0; > - *size = 0; > - free_token(token); > -} > - > -/** > - * tep_parse_header_page - parse the data stored in the header page > - * @tep: a handle to the trace event parser context > - * @buf: the buffer storing the header page format string > - * @size: the size of @buf > - * @long_size: the long size to use if there is no header > - * > - * This parses the header page format for information on the > - * ring buffer used. The @buf should be copied from > - * > - * /sys/kernel/debug/tracing/events/header_page > - */ > -int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size, > - int long_size) > -{ > - int ignore; > - > - if (!size) { > - /* > - * Old kernels did not have header page info. > - * Sorry but we just use what we find here in user space. > - */ > - tep->header_page_ts_size = sizeof(long long); > - tep->header_page_size_size = long_size; > - tep->header_page_data_offset = sizeof(long long) + long_size; > - tep->old_format = 1; > - return -1; > - } > - init_input_buf(buf, size); > - > - parse_header_field("timestamp", &tep->header_page_ts_offset, > - &tep->header_page_ts_size, 1); > - parse_header_field("commit", &tep->header_page_size_offset, > - &tep->header_page_size_size, 1); > - parse_header_field("overwrite", &tep->header_page_overwrite, > - &ignore, 0); > - parse_header_field("data", &tep->header_page_data_offset, > - &tep->header_page_data_size, 1); > - > - return 0; > -} > - > -static int event_matches(struct tep_event *event, > - int id, const char *sys_name, > - const char *event_name) > -{ > - if (id >= 0 && id != event->id) > - return 0; > - > - if (event_name && (strcmp(event_name, event->name) != 0)) > - return 0; > - > - if (sys_name && (strcmp(sys_name, event->system) != 0)) > - return 0; > - > - return 1; > -} > - > -static void free_handler(struct event_handler *handle) > -{ > - free((void *)handle->sys_name); > - free((void *)handle->event_name); > - free(handle); > -} > - > -static int find_event_handle(struct tep_handle *tep, struct tep_event *event) > -{ > - struct event_handler *handle, **next; > - > - for (next = &tep->handlers; *next; > - next = &(*next)->next) { > - handle = *next; > - if (event_matches(event, handle->id, > - handle->sys_name, > - handle->event_name)) > - break; > - } > - > - if (!(*next)) > - return 0; > - > - pr_stat("overriding event (%d) %s:%s with new print handler", > - event->id, event->system, event->name); > - > - event->handler = handle->func; > - event->context = handle->context; > - > - *next = handle->next; > - free_handler(handle); > - > - return 1; > -} > - > -/** > - * parse_format - parse the event format > - * @buf: the buffer storing the event format string > - * @size: the size of @buf > - * @sys: the system the event belongs to > - * > - * This parses the event format and creates an event structure > - * to quickly parse raw data for a given event. > - * > - * These files currently come from: > - * > - * /sys/kernel/debug/tracing/events/.../.../format > - */ > -static enum tep_errno parse_format(struct tep_event **eventp, > - struct tep_handle *tep, const char *buf, > - unsigned long size, const char *sys) > -{ > - struct tep_event *event; > - int ret; > - > - init_input_buf(buf, size); > - > - *eventp = event = alloc_event(); > - if (!event) > - return TEP_ERRNO__MEM_ALLOC_FAILED; > - > - event->name = event_read_name(); > - if (!event->name) { > - /* Bad event? */ > - ret = TEP_ERRNO__MEM_ALLOC_FAILED; > - goto event_alloc_failed; > - } > - > - if (strcmp(sys, "ftrace") == 0) { > - event->flags |= TEP_EVENT_FL_ISFTRACE; > - > - if (strcmp(event->name, "bprint") == 0) > - event->flags |= TEP_EVENT_FL_ISBPRINT; > - } > - > - event->id = event_read_id(); > - if (event->id < 0) { > - ret = TEP_ERRNO__READ_ID_FAILED; > - /* > - * This isn't an allocation error actually. > - * But as the ID is critical, just bail out. > - */ > - goto event_alloc_failed; > - } > - > - event->system = strdup(sys); > - if (!event->system) { > - ret = TEP_ERRNO__MEM_ALLOC_FAILED; > - goto event_alloc_failed; > - } > - > - /* Add tep to event so that it can be referenced */ > - event->tep = tep; > - > - ret = event_read_format(event); > - if (ret < 0) { > - ret = TEP_ERRNO__READ_FORMAT_FAILED; > - goto event_parse_failed; > - } > - > - /* > - * If the event has an override, don't print warnings if the event > - * print format fails to parse. > - */ > - if (tep && find_event_handle(tep, event)) > - show_warning = 0; > - > - ret = event_read_print(event); > - show_warning = 1; > - > - if (ret < 0) { > - ret = TEP_ERRNO__READ_PRINT_FAILED; > - goto event_parse_failed; > - } > - > - if (!ret && (event->flags & TEP_EVENT_FL_ISFTRACE)) { > - struct tep_format_field *field; > - struct tep_print_arg *arg, **list; > - > - /* old ftrace had no args */ > - list = &event->print_fmt.args; > - for (field = event->format.fields; field; field = field->next) { > - arg = alloc_arg(); > - if (!arg) { > - event->flags |= TEP_EVENT_FL_FAILED; > - return TEP_ERRNO__OLD_FTRACE_ARG_FAILED; > - } > - arg->type = TEP_PRINT_FIELD; > - arg->field.name = strdup(field->name); > - if (!arg->field.name) { > - event->flags |= TEP_EVENT_FL_FAILED; > - free_arg(arg); > - return TEP_ERRNO__OLD_FTRACE_ARG_FAILED; > - } > - arg->field.field = field; > - *list = arg; > - list = &arg->next; > - } > - } > - > - if (!(event->flags & TEP_EVENT_FL_ISBPRINT)) > - event->print_fmt.print_cache = parse_args(event, > - event->print_fmt.format, > - event->print_fmt.args); > - > - return 0; > - > - event_parse_failed: > - event->flags |= TEP_EVENT_FL_FAILED; > - return ret; > - > - event_alloc_failed: > - free(event->system); > - free(event->name); > - free(event); > - *eventp = NULL; > - return ret; > -} > - > -static enum tep_errno > -__parse_event(struct tep_handle *tep, > - struct tep_event **eventp, > - const char *buf, unsigned long size, > - const char *sys) > -{ > - int ret = parse_format(eventp, tep, buf, size, sys); > - struct tep_event *event = *eventp; > - > - if (event == NULL) > - return ret; > - > - if (tep && add_event(tep, event)) { > - ret = TEP_ERRNO__MEM_ALLOC_FAILED; > - goto event_add_failed; > - } > - > -#define PRINT_ARGS 0 > - if (PRINT_ARGS && event->print_fmt.args) > - print_args(event->print_fmt.args); > - > - return 0; > - > -event_add_failed: > - free_tep_event(event); > - return ret; > -} > - > -/** > - * tep_parse_format - parse the event format > - * @tep: a handle to the trace event parser context > - * @eventp: returned format > - * @buf: the buffer storing the event format string > - * @size: the size of @buf > - * @sys: the system the event belongs to > - * > - * This parses the event format and creates an event structure > - * to quickly parse raw data for a given event. > - * > - * These files currently come from: > - * > - * /sys/kernel/debug/tracing/events/.../.../format > - */ > -enum tep_errno tep_parse_format(struct tep_handle *tep, > - struct tep_event **eventp, > - const char *buf, > - unsigned long size, const char *sys) > -{ > - return __parse_event(tep, eventp, buf, size, sys); > -} > - > -/** > - * tep_parse_event - parse the event format > - * @tep: a handle to the trace event parser context > - * @buf: the buffer storing the event format string > - * @size: the size of @buf > - * @sys: the system the event belongs to > - * > - * This parses the event format and creates an event structure > - * to quickly parse raw data for a given event. > - * > - * These files currently come from: > - * > - * /sys/kernel/debug/tracing/events/.../.../format > - */ > -enum tep_errno tep_parse_event(struct tep_handle *tep, const char *buf, > - unsigned long size, const char *sys) > -{ > - struct tep_event *event = NULL; > - return __parse_event(tep, &event, buf, size, sys); > -} > - > -int get_field_val(struct trace_seq *s, struct tep_format_field *field, > - const char *name, struct tep_record *record, > - unsigned long long *val, int err) > -{ > - if (!field) { > - if (err) > - trace_seq_printf(s, "", name); > - return -1; > - } > - > - if (tep_read_number_field(field, record->data, val)) { > - if (err) > - trace_seq_printf(s, " %s=INVALID", name); > - return -1; > - } > - > - return 0; > -} > - > -/** > - * tep_get_field_raw - return the raw pointer into the data field > - * @s: The seq to print to on error > - * @event: the event that the field is for > - * @name: The name of the field > - * @record: The record with the field name. > - * @len: place to store the field length. > - * @err: print default error if failed. > - * > - * Returns a pointer into record->data of the field and places > - * the length of the field in @len. > - * > - * On failure, it returns NULL. > - */ > -void *tep_get_field_raw(struct trace_seq *s, struct tep_event *event, > - const char *name, struct tep_record *record, > - int *len, int err) > -{ > - struct tep_format_field *field; > - void *data = record->data; > - unsigned offset; > - int dummy; > - > - if (!event) > - return NULL; > - > - field = tep_find_field(event, name); > - > - if (!field) { > - if (err) > - trace_seq_printf(s, "", name); > - return NULL; > - } > - > - /* Allow @len to be NULL */ > - if (!len) > - len = &dummy; > - > - offset = field->offset; > - if (field->flags & TEP_FIELD_IS_DYNAMIC) { > - offset = tep_read_number(event->tep, > - data + offset, field->size); > - *len = offset >> 16; > - offset &= 0xffff; > - if (field->flags & TEP_FIELD_IS_RELATIVE) > - offset += field->offset + field->size; > - } else > - *len = field->size; > - > - return data + offset; > -} > - > -/** > - * tep_get_field_val - find a field and return its value > - * @s: The seq to print to on error > - * @event: the event that the field is for > - * @name: The name of the field > - * @record: The record with the field name. > - * @val: place to store the value of the field. > - * @err: print default error if failed. > - * > - * Returns 0 on success -1 on field not found. > - */ > -int tep_get_field_val(struct trace_seq *s, struct tep_event *event, > - const char *name, struct tep_record *record, > - unsigned long long *val, int err) > -{ > - struct tep_format_field *field; > - > - if (!event) > - return -1; > - > - field = tep_find_field(event, name); > - > - return get_field_val(s, field, name, record, val, err); > -} > - > -/** > - * tep_get_common_field_val - find a common field and return its value > - * @s: The seq to print to on error > - * @event: the event that the field is for > - * @name: The name of the field > - * @record: The record with the field name. > - * @val: place to store the value of the field. > - * @err: print default error if failed. > - * > - * Returns 0 on success -1 on field not found. > - */ > -int tep_get_common_field_val(struct trace_seq *s, struct tep_event *event, > - const char *name, struct tep_record *record, > - unsigned long long *val, int err) > -{ > - struct tep_format_field *field; > - > - if (!event) > - return -1; > - > - field = tep_find_common_field(event, name); > - > - return get_field_val(s, field, name, record, val, err); > -} > - > -/** > - * tep_get_any_field_val - find a any field and return its value > - * @s: The seq to print to on error > - * @event: the event that the field is for > - * @name: The name of the field > - * @record: The record with the field name. > - * @val: place to store the value of the field. > - * @err: print default error if failed. > - * > - * Returns 0 on success -1 on field not found. > - */ > -int tep_get_any_field_val(struct trace_seq *s, struct tep_event *event, > - const char *name, struct tep_record *record, > - unsigned long long *val, int err) > -{ > - struct tep_format_field *field; > - > - if (!event) > - return -1; > - > - field = tep_find_any_field(event, name); > - > - return get_field_val(s, field, name, record, val, err); > -} > - > -/** > - * tep_print_num_field - print a field and a format > - * @s: The seq to print to > - * @fmt: The printf format to print the field with. > - * @event: the event that the field is for > - * @name: The name of the field > - * @record: The record with the field name. > - * @err: print default error if failed. > - * > - * Returns positive value on success, negative in case of an error, > - * or 0 if buffer is full. > - */ > -int tep_print_num_field(struct trace_seq *s, const char *fmt, > - struct tep_event *event, const char *name, > - struct tep_record *record, int err) > -{ > - struct tep_format_field *field = tep_find_field(event, name); > - unsigned long long val; > - > - if (!field) > - goto failed; > - > - if (tep_read_number_field(field, record->data, &val)) > - goto failed; > - > - return trace_seq_printf(s, fmt, val); > - > - failed: > - if (err) > - trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name); > - return -1; > -} > - > -/** > - * tep_print_func_field - print a field and a format for function pointers > - * @s: The seq to print to > - * @fmt: The printf format to print the field with. > - * @event: the event that the field is for > - * @name: The name of the field > - * @record: The record with the field name. > - * @err: print default error if failed. > - * > - * Returns positive value on success, negative in case of an error, > - * or 0 if buffer is full. > - */ > -int tep_print_func_field(struct trace_seq *s, const char *fmt, > - struct tep_event *event, const char *name, > - struct tep_record *record, int err) > -{ > - struct tep_format_field *field = tep_find_field(event, name); > - struct tep_handle *tep = event->tep; > - unsigned long long val; > - struct func_map *func; > - char tmp[128]; > - > - if (!field) > - goto failed; > - > - if (tep_read_number_field(field, record->data, &val)) > - goto failed; > - > - func = find_func(tep, val); > - > - if (func) > - snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val); > - else > - sprintf(tmp, "0x%08llx", val); > - > - return trace_seq_printf(s, fmt, tmp); > - > - failed: > - if (err) > - trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name); > - return -1; > -} > - > -static void free_func_handle(struct tep_function_handler *func) > -{ > - struct func_params *params; > - > - free(func->name); > - > - while (func->params) { > - params = func->params; > - func->params = params->next; > - free(params); > - } > - > - free(func); > -} > - > -/** > - * tep_register_print_function - register a helper function > - * @tep: a handle to the trace event parser context > - * @func: the function to process the helper function > - * @ret_type: the return type of the helper function > - * @name: the name of the helper function > - * @parameters: A list of enum tep_func_arg_type > - * > - * Some events may have helper functions in the print format arguments. > - * This allows a plugin to dynamically create a way to process one > - * of these functions. > - * > - * The @parameters is a variable list of tep_func_arg_type enums that > - * must end with TEP_FUNC_ARG_VOID. > - */ > -int tep_register_print_function(struct tep_handle *tep, > - tep_func_handler func, > - enum tep_func_arg_type ret_type, > - char *name, ...) > -{ > - struct tep_function_handler *func_handle; > - struct func_params **next_param; > - struct func_params *param; > - enum tep_func_arg_type type; > - va_list ap; > - int ret; > - > - func_handle = find_func_handler(tep, name); > - if (func_handle) { > - /* > - * This is most like caused by the users own > - * plugins updating the function. This overrides the > - * system defaults. > - */ > - pr_stat("override of function helper '%s'", name); > - remove_func_handler(tep, name); > - } > - > - func_handle = calloc(1, sizeof(*func_handle)); > - if (!func_handle) { > - do_warning("Failed to allocate function handler"); > - return TEP_ERRNO__MEM_ALLOC_FAILED; > - } > - > - func_handle->ret_type = ret_type; > - func_handle->name = strdup(name); > - func_handle->func = func; > - if (!func_handle->name) { > - do_warning("Failed to allocate function name"); > - free(func_handle); > - return TEP_ERRNO__MEM_ALLOC_FAILED; > - } > - > - next_param = &(func_handle->params); > - va_start(ap, name); > - for (;;) { > - type = va_arg(ap, enum tep_func_arg_type); > - if (type == TEP_FUNC_ARG_VOID) > - break; > - > - if (type >= TEP_FUNC_ARG_MAX_TYPES) { > - do_warning("Invalid argument type %d", type); > - ret = TEP_ERRNO__INVALID_ARG_TYPE; > - goto out_free; > - } > - > - param = malloc(sizeof(*param)); > - if (!param) { > - do_warning("Failed to allocate function param"); > - ret = TEP_ERRNO__MEM_ALLOC_FAILED; > - goto out_free; > - } > - param->type = type; > - param->next = NULL; > - > - *next_param = param; > - next_param = &(param->next); > - > - func_handle->nr_args++; > - } > - va_end(ap); > - > - func_handle->next = tep->func_handlers; > - tep->func_handlers = func_handle; > - > - return 0; > - out_free: > - va_end(ap); > - free_func_handle(func_handle); > - return ret; > -} > - > -/** > - * tep_unregister_print_function - unregister a helper function > - * @tep: a handle to the trace event parser context > - * @func: the function to process the helper function > - * @name: the name of the helper function > - * > - * This function removes existing print handler for function @name. > - * > - * Returns 0 if the handler was removed successully, -1 otherwise. > - */ > -int tep_unregister_print_function(struct tep_handle *tep, > - tep_func_handler func, char *name) > -{ > - struct tep_function_handler *func_handle; > - > - func_handle = find_func_handler(tep, name); > - if (func_handle && func_handle->func == func) { > - remove_func_handler(tep, name); > - return 0; > - } > - return -1; > -} > - > -static struct tep_event *search_event(struct tep_handle *tep, int id, > - const char *sys_name, > - const char *event_name) > -{ > - struct tep_event *event; > - > - if (id >= 0) { > - /* search by id */ > - event = tep_find_event(tep, id); > - if (!event) > - return NULL; > - if (event_name && (strcmp(event_name, event->name) != 0)) > - return NULL; > - if (sys_name && (strcmp(sys_name, event->system) != 0)) > - return NULL; > - } else { > - event = tep_find_event_by_name(tep, sys_name, event_name); > - if (!event) > - return NULL; > - } > - return event; > -} > - > -/** > - * tep_register_event_handler - register a way to parse an event > - * @tep: a handle to the trace event parser context > - * @id: the id of the event to register > - * @sys_name: the system name the event belongs to > - * @event_name: the name of the event > - * @func: the function to call to parse the event information > - * @context: the data to be passed to @func > - * > - * This function allows a developer to override the parsing of > - * a given event. If for some reason the default print format > - * is not sufficient, this function will register a function > - * for an event to be used to parse the data instead. > - * > - * If @id is >= 0, then it is used to find the event. > - * else @sys_name and @event_name are used. > - * > - * Returns: > - * TEP_REGISTER_SUCCESS_OVERWRITE if an existing handler is overwritten > - * TEP_REGISTER_SUCCESS if a new handler is registered successfully > - * negative TEP_ERRNO_... in case of an error > - * > - */ > -int tep_register_event_handler(struct tep_handle *tep, int id, > - const char *sys_name, const char *event_name, > - tep_event_handler_func func, void *context) > -{ > - struct tep_event *event; > - struct event_handler *handle; > - > - event = search_event(tep, id, sys_name, event_name); > - if (event == NULL) > - goto not_found; > - > - pr_stat("overriding event (%d) %s:%s with new print handler", > - event->id, event->system, event->name); > - > - event->handler = func; > - event->context = context; > - return TEP_REGISTER_SUCCESS_OVERWRITE; > - > - not_found: > - /* Save for later use. */ > - handle = calloc(1, sizeof(*handle)); > - if (!handle) { > - do_warning("Failed to allocate event handler"); > - return TEP_ERRNO__MEM_ALLOC_FAILED; > - } > - > - handle->id = id; > - if (event_name) > - handle->event_name = strdup(event_name); > - if (sys_name) > - handle->sys_name = strdup(sys_name); > - > - if ((event_name && !handle->event_name) || > - (sys_name && !handle->sys_name)) { > - do_warning("Failed to allocate event/sys name"); > - free((void *)handle->event_name); > - free((void *)handle->sys_name); > - free(handle); > - return TEP_ERRNO__MEM_ALLOC_FAILED; > - } > - > - handle->func = func; > - handle->next = tep->handlers; > - tep->handlers = handle; > - handle->context = context; > - > - return TEP_REGISTER_SUCCESS; > -} > - > -static int handle_matches(struct event_handler *handler, int id, > - const char *sys_name, const char *event_name, > - tep_event_handler_func func, void *context) > -{ > - if (id >= 0 && id != handler->id) > - return 0; > - > - if (event_name && (strcmp(event_name, handler->event_name) != 0)) > - return 0; > - > - if (sys_name && (strcmp(sys_name, handler->sys_name) != 0)) > - return 0; > - > - if (func != handler->func || context != handler->context) > - return 0; > - > - return 1; > -} > - > -/** > - * tep_unregister_event_handler - unregister an existing event handler > - * @tep: a handle to the trace event parser context > - * @id: the id of the event to unregister > - * @sys_name: the system name the handler belongs to > - * @event_name: the name of the event handler > - * @func: the function to call to parse the event information > - * @context: the data to be passed to @func > - * > - * This function removes existing event handler (parser). > - * > - * If @id is >= 0, then it is used to find the event. > - * else @sys_name and @event_name are used. > - * > - * Returns 0 if handler was removed successfully, -1 if event was not found. > - */ > -int tep_unregister_event_handler(struct tep_handle *tep, int id, > - const char *sys_name, const char *event_name, > - tep_event_handler_func func, void *context) > -{ > - struct tep_event *event; > - struct event_handler *handle; > - struct event_handler **next; > - > - event = search_event(tep, id, sys_name, event_name); > - if (event == NULL) > - goto not_found; > - > - if (event->handler == func && event->context == context) { > - pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.", > - event->id, event->system, event->name); > - > - event->handler = NULL; > - event->context = NULL; > - return 0; > - } > - > -not_found: > - for (next = &tep->handlers; *next; next = &(*next)->next) { > - handle = *next; > - if (handle_matches(handle, id, sys_name, event_name, > - func, context)) > - break; > - } > - > - if (!(*next)) > - return -1; > - > - *next = handle->next; > - free_handler(handle); > - > - return 0; > -} > - > -/** > - * tep_alloc - create a tep handle > - */ > -struct tep_handle *tep_alloc(void) > -{ > - struct tep_handle *tep = calloc(1, sizeof(*tep)); > - > - if (tep) { > - tep->ref_count = 1; > - tep->host_bigendian = tep_is_bigendian(); > - } > - > - return tep; > -} > - > -void tep_ref(struct tep_handle *tep) > -{ > - tep->ref_count++; > -} > - > -int tep_get_ref(struct tep_handle *tep) > -{ > - if (tep) > - return tep->ref_count; > - return 0; > -} > - > -__hidden void free_tep_format_field(struct tep_format_field *field) > -{ > - free(field->type); > - if (field->alias != field->name) > - free(field->alias); > - free(field->name); > - free(field); > -} > - > -static void free_format_fields(struct tep_format_field *field) > -{ > - struct tep_format_field *next; > - > - while (field) { > - next = field->next; > - free_tep_format_field(field); > - field = next; > - } > -} > - > -static void free_formats(struct tep_format *format) > -{ > - free_format_fields(format->common_fields); > - free_format_fields(format->fields); > -} > - > -__hidden void free_tep_event(struct tep_event *event) > -{ > - free(event->name); > - free(event->system); > - > - free_formats(&event->format); > - > - free(event->print_fmt.format); > - free_args(event->print_fmt.args); > - free_parse_args(event->print_fmt.print_cache); > - free(event); > -} > - > -/** > - * tep_free - free a tep handle > - * @tep: the tep handle to free > - */ > -void tep_free(struct tep_handle *tep) > -{ > - struct cmdline_list *cmdlist, *cmdnext; > - struct func_list *funclist, *funcnext; > - struct printk_list *printklist, *printknext; > - struct tep_function_handler *func_handler; > - struct event_handler *handle; > - int i; > - > - if (!tep) > - return; > - > - cmdlist = tep->cmdlist; > - funclist = tep->funclist; > - printklist = tep->printklist; > - > - tep->ref_count--; > - if (tep->ref_count) > - return; > - > - if (tep->cmdlines) { > - for (i = 0; i < tep->cmdline_count; i++) > - free(tep->cmdlines[i].comm); > - free(tep->cmdlines); > - } > - > - while (cmdlist) { > - cmdnext = cmdlist->next; > - free(cmdlist->comm); > - free(cmdlist); > - cmdlist = cmdnext; > - } > - > - if (tep->func_map) { > - for (i = 0; i < (int)tep->func_count; i++) { > - free(tep->func_map[i].func); > - free(tep->func_map[i].mod); > - } > - free(tep->func_map); > - } > - > - while (funclist) { > - funcnext = funclist->next; > - free(funclist->func); > - free(funclist->mod); > - free(funclist); > - funclist = funcnext; > - } > - > - while (tep->func_handlers) { > - func_handler = tep->func_handlers; > - tep->func_handlers = func_handler->next; > - free_func_handle(func_handler); > - } > - > - if (tep->printk_map) { > - for (i = 0; i < (int)tep->printk_count; i++) > - free(tep->printk_map[i].printk); > - free(tep->printk_map); > - } > - > - while (printklist) { > - printknext = printklist->next; > - free(printklist->printk); > - free(printklist); > - printklist = printknext; > - } > - > - for (i = 0; i < tep->nr_events; i++) > - free_tep_event(tep->events[i]); > - > - while (tep->handlers) { > - handle = tep->handlers; > - tep->handlers = handle->next; > - free_handler(handle); > - } > - > - free(tep->events); > - free(tep->sort_events); > - free(tep->func_resolver); > - free_tep_plugin_paths(tep); > - > - free(tep); > -} > - > -void tep_unref(struct tep_handle *tep) > -{ > - tep_free(tep); > -} > diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h > deleted file mode 100644 > index 41d4f9f6a843..000000000000 > --- a/tools/lib/traceevent/event-parse.h > +++ /dev/null > @@ -1,750 +0,0 @@ > -/* SPDX-License-Identifier: LGPL-2.1 */ > -/* > - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt > - * > - */ > -#ifndef _PARSE_EVENTS_H > -#define _PARSE_EVENTS_H > - > -#include > -#include > -#include > -#include > -#include > - > -#include "trace-seq.h" > - > -#ifndef __maybe_unused > -#define __maybe_unused __attribute__((unused)) > -#endif > - > -#ifndef DEBUG_RECORD > -#define DEBUG_RECORD 0 > -#endif > - > -struct tep_record { > - unsigned long long ts; > - unsigned long long offset; > - long long missed_events; /* buffer dropped events before */ > - int record_size; /* size of binary record */ > - int size; /* size of data */ > - void *data; > - int cpu; > - int ref_count; > - int locked; /* Do not free, even if ref_count is zero */ > - void *priv; > -#if DEBUG_RECORD > - struct tep_record *prev; > - struct tep_record *next; > - long alloc_addr; > -#endif > -}; > - > -/* ----------------------- tep ----------------------- */ > - > -struct tep_handle; > -struct tep_event; > - > -typedef int (*tep_event_handler_func)(struct trace_seq *s, > - struct tep_record *record, > - struct tep_event *event, > - void *context); > - > -typedef int (*tep_plugin_load_func)(struct tep_handle *tep); > -typedef int (*tep_plugin_unload_func)(struct tep_handle *tep); > - > -struct tep_plugin_option { > - struct tep_plugin_option *next; > - void *handle; > - char *file; > - char *name; > - char *plugin_alias; > - char *description; > - const char *value; > - void *priv; > - int set; > -}; > - > -/* > - * Plugin hooks that can be called: > - * > - * TEP_PLUGIN_LOADER: (required) > - * The function name to initialized the plugin. > - * > - * int TEP_PLUGIN_LOADER(struct tep_handle *tep) > - * > - * TEP_PLUGIN_UNLOADER: (optional) > - * The function called just before unloading > - * > - * int TEP_PLUGIN_UNLOADER(struct tep_handle *tep) > - * > - * TEP_PLUGIN_OPTIONS: (optional) > - * Plugin options that can be set before loading > - * > - * struct tep_plugin_option TEP_PLUGIN_OPTIONS[] = { > - * { > - * .name = "option-name", > - * .plugin_alias = "override-file-name", (optional) > - * .description = "description of option to show users", > - * }, > - * { > - * .name = NULL, > - * }, > - * }; > - * > - * Array must end with .name = NULL; > - * > - * > - * .plugin_alias is used to give a shorter name to access > - * the vairable. Useful if a plugin handles more than one event. > - * > - * If .value is not set, then it is considered a boolean and only > - * .set will be processed. If .value is defined, then it is considered > - * a string option and .set will be ignored. > - * > - * TEP_PLUGIN_ALIAS: (optional) > - * The name to use for finding options (uses filename if not defined) > - */ > -#define TEP_PLUGIN_LOADER tep_plugin_loader > -#define TEP_PLUGIN_UNLOADER tep_plugin_unloader > -#define TEP_PLUGIN_OPTIONS tep_plugin_options > -#define TEP_PLUGIN_ALIAS tep_plugin_alias > -#define _MAKE_STR(x) #x > -#define MAKE_STR(x) _MAKE_STR(x) > -#define TEP_PLUGIN_LOADER_NAME MAKE_STR(TEP_PLUGIN_LOADER) > -#define TEP_PLUGIN_UNLOADER_NAME MAKE_STR(TEP_PLUGIN_UNLOADER) > -#define TEP_PLUGIN_OPTIONS_NAME MAKE_STR(TEP_PLUGIN_OPTIONS) > -#define TEP_PLUGIN_ALIAS_NAME MAKE_STR(TEP_PLUGIN_ALIAS) > - > -enum tep_format_flags { > - TEP_FIELD_IS_ARRAY = 1, > - TEP_FIELD_IS_POINTER = 2, > - TEP_FIELD_IS_SIGNED = 4, > - TEP_FIELD_IS_STRING = 8, > - TEP_FIELD_IS_DYNAMIC = 16, > - TEP_FIELD_IS_LONG = 32, > - TEP_FIELD_IS_FLAG = 64, > - TEP_FIELD_IS_SYMBOLIC = 128, > - TEP_FIELD_IS_RELATIVE = 256, > -}; > - > -struct tep_format_field { > - struct tep_format_field *next; > - struct tep_event *event; > - char *type; > - char *name; > - char *alias; > - int offset; > - int size; > - unsigned int arraylen; > - unsigned int elementsize; > - unsigned long flags; > -}; > - > -struct tep_format { > - int nr_common; > - int nr_fields; > - struct tep_format_field *common_fields; > - struct tep_format_field *fields; > -}; > - > -struct tep_print_arg_atom { > - char *atom; > -}; > - > -struct tep_print_arg_string { > - char *string; > - struct tep_format_field *field; > -}; > - > -struct tep_print_arg_bitmask { > - char *bitmask; > - struct tep_format_field *field; > -}; > - > -struct tep_print_arg_field { > - char *name; > - struct tep_format_field *field; > -}; > - > -struct tep_print_flag_sym { > - struct tep_print_flag_sym *next; > - char *value; > - char *str; > -}; > - > -struct tep_print_arg_typecast { > - char *type; > - struct tep_print_arg *item; > -}; > - > -struct tep_print_arg_flags { > - struct tep_print_arg *field; > - char *delim; > - struct tep_print_flag_sym *flags; > -}; > - > -struct tep_print_arg_symbol { > - struct tep_print_arg *field; > - struct tep_print_flag_sym *symbols; > -}; > - > -struct tep_print_arg_hex { > - struct tep_print_arg *field; > - struct tep_print_arg *size; > -}; > - > -struct tep_print_arg_int_array { > - struct tep_print_arg *field; > - struct tep_print_arg *count; > - struct tep_print_arg *el_size; > -}; > - > -struct tep_print_arg_dynarray { > - struct tep_format_field *field; > - struct tep_print_arg *index; > -}; > - > -struct tep_print_arg; > - > -struct tep_print_arg_op { > - char *op; > - int prio; > - struct tep_print_arg *left; > - struct tep_print_arg *right; > -}; > - > -struct tep_function_handler; > - > -struct tep_print_arg_func { > - struct tep_function_handler *func; > - struct tep_print_arg *args; > -}; > - > -enum tep_print_arg_type { > - TEP_PRINT_NULL, > - TEP_PRINT_ATOM, > - TEP_PRINT_FIELD, > - TEP_PRINT_FLAGS, > - TEP_PRINT_SYMBOL, > - TEP_PRINT_HEX, > - TEP_PRINT_INT_ARRAY, > - TEP_PRINT_TYPE, > - TEP_PRINT_STRING, > - TEP_PRINT_BSTRING, > - TEP_PRINT_DYNAMIC_ARRAY, > - TEP_PRINT_OP, > - TEP_PRINT_FUNC, > - TEP_PRINT_BITMASK, > - TEP_PRINT_DYNAMIC_ARRAY_LEN, > - TEP_PRINT_HEX_STR, > -}; > - > -struct tep_print_arg { > - struct tep_print_arg *next; > - enum tep_print_arg_type type; > - union { > - struct tep_print_arg_atom atom; > - struct tep_print_arg_field field; > - struct tep_print_arg_typecast typecast; > - struct tep_print_arg_flags flags; > - struct tep_print_arg_symbol symbol; > - struct tep_print_arg_hex hex; > - struct tep_print_arg_int_array int_array; > - struct tep_print_arg_func func; > - struct tep_print_arg_string string; > - struct tep_print_arg_bitmask bitmask; > - struct tep_print_arg_op op; > - struct tep_print_arg_dynarray dynarray; > - }; > -}; > - > -struct tep_print_parse; > - > -struct tep_print_fmt { > - char *format; > - struct tep_print_arg *args; > - struct tep_print_parse *print_cache; > -}; > - > -struct tep_event { > - struct tep_handle *tep; > - char *name; > - int id; > - int flags; > - struct tep_format format; > - struct tep_print_fmt print_fmt; > - char *system; > - tep_event_handler_func handler; > - void *context; > -}; > - > -enum { > - TEP_EVENT_FL_ISFTRACE = 0x01, > - TEP_EVENT_FL_ISPRINT = 0x02, > - TEP_EVENT_FL_ISBPRINT = 0x04, > - TEP_EVENT_FL_ISFUNCENT = 0x10, > - TEP_EVENT_FL_ISFUNCRET = 0x20, > - TEP_EVENT_FL_NOHANDLE = 0x40, > - TEP_EVENT_FL_PRINTRAW = 0x80, > - > - TEP_EVENT_FL_FAILED = 0x80000000 > -}; > - > -enum tep_event_sort_type { > - TEP_EVENT_SORT_ID, > - TEP_EVENT_SORT_NAME, > - TEP_EVENT_SORT_SYSTEM, > -}; > - > -enum tep_event_type { > - TEP_EVENT_ERROR, > - TEP_EVENT_NONE, > - TEP_EVENT_SPACE, > - TEP_EVENT_NEWLINE, > - TEP_EVENT_OP, > - TEP_EVENT_DELIM, > - TEP_EVENT_ITEM, > - TEP_EVENT_DQUOTE, > - TEP_EVENT_SQUOTE, > -}; > - > -typedef unsigned long long (*tep_func_handler)(struct trace_seq *s, > - unsigned long long *args); > - > -enum tep_func_arg_type { > - TEP_FUNC_ARG_VOID, > - TEP_FUNC_ARG_INT, > - TEP_FUNC_ARG_LONG, > - TEP_FUNC_ARG_STRING, > - TEP_FUNC_ARG_PTR, > - TEP_FUNC_ARG_MAX_TYPES > -}; > - > -enum tep_flag { > - TEP_NSEC_OUTPUT = 1, /* output in NSECS */ > - TEP_DISABLE_SYS_PLUGINS = 1 << 1, > - TEP_DISABLE_PLUGINS = 1 << 2, > -}; > - > -#define TEP_ERRORS \ > - _PE(MEM_ALLOC_FAILED, "failed to allocate memory"), \ > - _PE(PARSE_EVENT_FAILED, "failed to parse event"), \ > - _PE(READ_ID_FAILED, "failed to read event id"), \ > - _PE(READ_FORMAT_FAILED, "failed to read event format"), \ > - _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \ > - _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\ > - _PE(INVALID_ARG_TYPE, "invalid argument type"), \ > - _PE(INVALID_EXP_TYPE, "invalid expression type"), \ > - _PE(INVALID_OP_TYPE, "invalid operator type"), \ > - _PE(INVALID_EVENT_NAME, "invalid event name"), \ > - _PE(EVENT_NOT_FOUND, "no event found"), \ > - _PE(SYNTAX_ERROR, "syntax error"), \ > - _PE(ILLEGAL_RVALUE, "illegal rvalue"), \ > - _PE(ILLEGAL_LVALUE, "illegal lvalue for string comparison"), \ > - _PE(INVALID_REGEX, "regex did not compute"), \ > - _PE(ILLEGAL_STRING_CMP, "illegal comparison for string"), \ > - _PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer"), \ > - _PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \ > - _PE(REPARENT_FAILED, "failed to reparent filter OP"), \ > - _PE(BAD_FILTER_ARG, "bad arg in filter tree"), \ > - _PE(UNEXPECTED_TYPE, "unexpected type (not a value)"), \ > - _PE(ILLEGAL_TOKEN, "illegal token"), \ > - _PE(INVALID_PAREN, "open parenthesis cannot come here"), \ > - _PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \ > - _PE(UNKNOWN_TOKEN, "unknown token"), \ > - _PE(FILTER_NOT_FOUND, "no filter found"), \ > - _PE(NOT_A_NUMBER, "must have number field"), \ > - _PE(NO_FILTER, "no filters exists"), \ > - _PE(FILTER_MISS, "record does not match to filter") > - > -#undef _PE > -#define _PE(__code, __str) TEP_ERRNO__ ## __code > -enum tep_errno { > - TEP_ERRNO__SUCCESS = 0, > - TEP_ERRNO__FILTER_MATCH = TEP_ERRNO__SUCCESS, > - > - /* > - * Choose an arbitrary negative big number not to clash with standard > - * errno since SUS requires the errno has distinct positive values. > - * See 'Issue 6' in the link below. > - * > - * https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html > - */ > - __TEP_ERRNO__START = -100000, > - > - TEP_ERRORS, > - > - __TEP_ERRNO__END, > -}; > -#undef _PE > - > -struct tep_plugin_list; > - > -#define INVALID_PLUGIN_LIST_OPTION ((char **)((unsigned long)-1)) > - > -enum tep_plugin_load_priority { > - TEP_PLUGIN_FIRST, > - TEP_PLUGIN_LAST, > -}; > - > -int tep_add_plugin_path(struct tep_handle *tep, char *path, > - enum tep_plugin_load_priority prio); > -struct tep_plugin_list *tep_load_plugins(struct tep_handle *tep); > -void tep_unload_plugins(struct tep_plugin_list *plugin_list, > - struct tep_handle *tep); > -void tep_load_plugins_hook(struct tep_handle *tep, const char *suffix, > - void (*load_plugin)(struct tep_handle *tep, > - const char *path, > - const char *name, > - void *data), > - void *data); > -char **tep_plugin_list_options(void); > -void tep_plugin_free_options_list(char **list); > -int tep_plugin_add_options(const char *name, > - struct tep_plugin_option *options); > -int tep_plugin_add_option(const char *name, const char *val); > -void tep_plugin_remove_options(struct tep_plugin_option *options); > -void tep_plugin_print_options(struct trace_seq *s); > -void tep_print_plugins(struct trace_seq *s, > - const char *prefix, const char *suffix, > - const struct tep_plugin_list *list); > - > -/* tep_handle */ > -typedef char *(tep_func_resolver_t)(void *priv, > - unsigned long long *addrp, char **modp); > -void tep_set_flag(struct tep_handle *tep, int flag); > -void tep_clear_flag(struct tep_handle *tep, enum tep_flag flag); > -bool tep_test_flag(struct tep_handle *tep, enum tep_flag flags); > - > -static inline int tep_is_bigendian(void) > -{ > - unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 }; > - unsigned int val; > - > - memcpy(&val, str, 4); > - return val == 0x01020304; > -} > - > -/* taken from kernel/trace/trace.h */ > -enum trace_flag_type { > - TRACE_FLAG_IRQS_OFF = 0x01, > - TRACE_FLAG_IRQS_NOSUPPORT = 0x02, > - TRACE_FLAG_NEED_RESCHED = 0x04, > - TRACE_FLAG_HARDIRQ = 0x08, > - TRACE_FLAG_SOFTIRQ = 0x10, > -}; > - > -int tep_set_function_resolver(struct tep_handle *tep, > - tep_func_resolver_t *func, void *priv); > -void tep_reset_function_resolver(struct tep_handle *tep); > -int tep_register_comm(struct tep_handle *tep, const char *comm, int pid); > -int tep_override_comm(struct tep_handle *tep, const char *comm, int pid); > -int tep_register_function(struct tep_handle *tep, char *name, > - unsigned long long addr, char *mod); > -int tep_register_print_string(struct tep_handle *tep, const char *fmt, > - unsigned long long addr); > -bool tep_is_pid_registered(struct tep_handle *tep, int pid); > - > -struct tep_event *tep_get_event(struct tep_handle *tep, int index); > - > -#define TEP_PRINT_INFO "INFO" > -#define TEP_PRINT_INFO_RAW "INFO_RAW" > -#define TEP_PRINT_COMM "COMM" > -#define TEP_PRINT_LATENCY "LATENCY" > -#define TEP_PRINT_NAME "NAME" > -#define TEP_PRINT_PID 1U > -#define TEP_PRINT_TIME 2U > -#define TEP_PRINT_CPU 3U > - > -void tep_print_event(struct tep_handle *tep, struct trace_seq *s, > - struct tep_record *record, const char *fmt, ...) > - __attribute__ ((format (printf, 4, 5))); > - > -int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size, > - int long_size); > - > -enum tep_errno tep_parse_event(struct tep_handle *tep, const char *buf, > - unsigned long size, const char *sys); > -enum tep_errno tep_parse_format(struct tep_handle *tep, > - struct tep_event **eventp, > - const char *buf, > - unsigned long size, const char *sys); > - > -void *tep_get_field_raw(struct trace_seq *s, struct tep_event *event, > - const char *name, struct tep_record *record, > - int *len, int err); > - > -int tep_get_field_val(struct trace_seq *s, struct tep_event *event, > - const char *name, struct tep_record *record, > - unsigned long long *val, int err); > -int tep_get_common_field_val(struct trace_seq *s, struct tep_event *event, > - const char *name, struct tep_record *record, > - unsigned long long *val, int err); > -int tep_get_any_field_val(struct trace_seq *s, struct tep_event *event, > - const char *name, struct tep_record *record, > - unsigned long long *val, int err); > - > -int tep_print_num_field(struct trace_seq *s, const char *fmt, > - struct tep_event *event, const char *name, > - struct tep_record *record, int err); > - > -int tep_print_func_field(struct trace_seq *s, const char *fmt, > - struct tep_event *event, const char *name, > - struct tep_record *record, int err); > - > -enum tep_reg_handler { > - TEP_REGISTER_SUCCESS = 0, > - TEP_REGISTER_SUCCESS_OVERWRITE, > -}; > - > -int tep_register_event_handler(struct tep_handle *tep, int id, > - const char *sys_name, const char *event_name, > - tep_event_handler_func func, void *context); > -int tep_unregister_event_handler(struct tep_handle *tep, int id, > - const char *sys_name, const char *event_name, > - tep_event_handler_func func, void *context); > -int tep_register_print_function(struct tep_handle *tep, > - tep_func_handler func, > - enum tep_func_arg_type ret_type, > - char *name, ...); > -int tep_unregister_print_function(struct tep_handle *tep, > - tep_func_handler func, char *name); > - > -struct tep_format_field *tep_find_common_field(struct tep_event *event, const char *name); > -struct tep_format_field *tep_find_field(struct tep_event *event, const char *name); > -struct tep_format_field *tep_find_any_field(struct tep_event *event, const char *name); > - > -const char *tep_find_function(struct tep_handle *tep, unsigned long long addr); > -unsigned long long > -tep_find_function_address(struct tep_handle *tep, unsigned long long addr); > -unsigned long long tep_read_number(struct tep_handle *tep, const void *ptr, int size); > -int tep_read_number_field(struct tep_format_field *field, const void *data, > - unsigned long long *value); > - > -struct tep_event *tep_get_first_event(struct tep_handle *tep); > -int tep_get_events_count(struct tep_handle *tep); > -struct tep_event *tep_find_event(struct tep_handle *tep, int id); > - > -struct tep_event * > -tep_find_event_by_name(struct tep_handle *tep, const char *sys, const char *name); > -struct tep_event * > -tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record); > - > -int tep_data_type(struct tep_handle *tep, struct tep_record *rec); > -int tep_data_pid(struct tep_handle *tep, struct tep_record *rec); > -int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec); > -int tep_data_flags(struct tep_handle *tep, struct tep_record *rec); > -const char *tep_data_comm_from_pid(struct tep_handle *tep, int pid); > -struct tep_cmdline; > -struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *tep, const char *comm, > - 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_fields(struct trace_seq *s, void *data, > - int size __maybe_unused, struct tep_event *event); > -int tep_strerror(struct tep_handle *tep, enum tep_errno errnum, > - char *buf, size_t buflen); > - > -struct tep_event **tep_list_events(struct tep_handle *tep, enum tep_event_sort_type); > -struct tep_event **tep_list_events_copy(struct tep_handle *tep, > - enum tep_event_sort_type); > -struct tep_format_field **tep_event_common_fields(struct tep_event *event); > -struct tep_format_field **tep_event_fields(struct tep_event *event); > - > -enum tep_endian { > - TEP_LITTLE_ENDIAN = 0, > - TEP_BIG_ENDIAN > -}; > -int tep_get_cpus(struct tep_handle *tep); > -void tep_set_cpus(struct tep_handle *tep, int cpus); > -int tep_get_long_size(struct tep_handle *tep); > -void tep_set_long_size(struct tep_handle *tep, int long_size); > -int tep_get_page_size(struct tep_handle *tep); > -void tep_set_page_size(struct tep_handle *tep, int _page_size); > -bool tep_is_file_bigendian(struct tep_handle *tep); > -void tep_set_file_bigendian(struct tep_handle *tep, enum tep_endian endian); > -bool tep_is_local_bigendian(struct tep_handle *tep); > -void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian); > -int tep_get_header_page_size(struct tep_handle *tep); > -int tep_get_header_timestamp_size(struct tep_handle *tep); > -bool tep_is_old_format(struct tep_handle *tep); > -void tep_set_test_filters(struct tep_handle *tep, int test_filters); > - > -struct tep_handle *tep_alloc(void); > -void tep_free(struct tep_handle *tep); > -void tep_ref(struct tep_handle *tep); > -void tep_unref(struct tep_handle *tep); > -int tep_get_ref(struct tep_handle *tep); > - > -/* for debugging */ > -void tep_print_funcs(struct tep_handle *tep); > -void tep_print_printk(struct tep_handle *tep); > - > -/* ----------------------- filtering ----------------------- */ > - > -enum tep_filter_boolean_type { > - TEP_FILTER_FALSE, > - TEP_FILTER_TRUE, > -}; > - > -enum tep_filter_op_type { > - TEP_FILTER_OP_AND = 1, > - TEP_FILTER_OP_OR, > - TEP_FILTER_OP_NOT, > -}; > - > -enum tep_filter_cmp_type { > - TEP_FILTER_CMP_NONE, > - TEP_FILTER_CMP_EQ, > - TEP_FILTER_CMP_NE, > - TEP_FILTER_CMP_GT, > - TEP_FILTER_CMP_LT, > - TEP_FILTER_CMP_GE, > - TEP_FILTER_CMP_LE, > - TEP_FILTER_CMP_MATCH, > - TEP_FILTER_CMP_NOT_MATCH, > - TEP_FILTER_CMP_REGEX, > - TEP_FILTER_CMP_NOT_REGEX, > -}; > - > -enum tep_filter_exp_type { > - TEP_FILTER_EXP_NONE, > - TEP_FILTER_EXP_ADD, > - TEP_FILTER_EXP_SUB, > - TEP_FILTER_EXP_MUL, > - TEP_FILTER_EXP_DIV, > - TEP_FILTER_EXP_MOD, > - TEP_FILTER_EXP_RSHIFT, > - TEP_FILTER_EXP_LSHIFT, > - TEP_FILTER_EXP_AND, > - TEP_FILTER_EXP_OR, > - TEP_FILTER_EXP_XOR, > - TEP_FILTER_EXP_NOT, > -}; > - > -enum tep_filter_arg_type { > - TEP_FILTER_ARG_NONE, > - TEP_FILTER_ARG_BOOLEAN, > - TEP_FILTER_ARG_VALUE, > - TEP_FILTER_ARG_FIELD, > - TEP_FILTER_ARG_EXP, > - TEP_FILTER_ARG_OP, > - TEP_FILTER_ARG_NUM, > - TEP_FILTER_ARG_STR, > -}; > - > -enum tep_filter_value_type { > - TEP_FILTER_NUMBER, > - TEP_FILTER_STRING, > - TEP_FILTER_CHAR > -}; > - > -struct tep_filter_arg; > - > -struct tep_filter_arg_boolean { > - enum tep_filter_boolean_type value; > -}; > - > -struct tep_filter_arg_field { > - struct tep_format_field *field; > -}; > - > -struct tep_filter_arg_value { > - enum tep_filter_value_type type; > - union { > - char *str; > - unsigned long long val; > - }; > -}; > - > -struct tep_filter_arg_op { > - enum tep_filter_op_type type; > - struct tep_filter_arg *left; > - struct tep_filter_arg *right; > -}; > - > -struct tep_filter_arg_exp { > - enum tep_filter_exp_type type; > - struct tep_filter_arg *left; > - struct tep_filter_arg *right; > -}; > - > -struct tep_filter_arg_num { > - enum tep_filter_cmp_type type; > - struct tep_filter_arg *left; > - struct tep_filter_arg *right; > -}; > - > -struct tep_filter_arg_str { > - enum tep_filter_cmp_type type; > - struct tep_format_field *field; > - char *val; > - char *buffer; > - regex_t reg; > -}; > - > -struct tep_filter_arg { > - enum tep_filter_arg_type type; > - union { > - struct tep_filter_arg_boolean boolean; > - struct tep_filter_arg_field field; > - struct tep_filter_arg_value value; > - struct tep_filter_arg_op op; > - struct tep_filter_arg_exp exp; > - struct tep_filter_arg_num num; > - struct tep_filter_arg_str str; > - }; > -}; > - > -struct tep_filter_type { > - int event_id; > - struct tep_event *event; > - struct tep_filter_arg *filter; > -}; > - > -#define TEP_FILTER_ERROR_BUFSZ 1024 > - > -struct tep_event_filter { > - struct tep_handle *tep; > - int filters; > - struct tep_filter_type *event_filters; > - char error_buffer[TEP_FILTER_ERROR_BUFSZ]; > -}; > - > -struct tep_event_filter *tep_filter_alloc(struct tep_handle *tep); > - > -/* for backward compatibility */ > -#define FILTER_NONE TEP_ERRNO__NO_FILTER > -#define FILTER_NOEXIST TEP_ERRNO__FILTER_NOT_FOUND > -#define FILTER_MISS TEP_ERRNO__FILTER_MISS > -#define FILTER_MATCH TEP_ERRNO__FILTER_MATCH > - > -enum tep_errno tep_filter_add_filter_str(struct tep_event_filter *filter, > - const char *filter_str); > - > -enum tep_errno tep_filter_match(struct tep_event_filter *filter, > - struct tep_record *record); > - > -int tep_filter_strerror(struct tep_event_filter *filter, enum tep_errno err, > - char *buf, size_t buflen); > - > -int tep_event_filtered(struct tep_event_filter *filter, > - int event_id); > - > -void tep_filter_reset(struct tep_event_filter *filter); > - > -void tep_filter_free(struct tep_event_filter *filter); > - > -char *tep_filter_make_string(struct tep_event_filter *filter, int event_id); > - > -int tep_filter_remove_event(struct tep_event_filter *filter, > - int event_id); > - > -int tep_filter_copy(struct tep_event_filter *dest, struct tep_event_filter *source); > - > -int tep_filter_compare(struct tep_event_filter *filter1, struct tep_event_filter *filter2); > - > -#endif /* _PARSE_EVENTS_H */ > diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c > deleted file mode 100644 > index e7f93d5fe4fd..000000000000 > --- a/tools/lib/traceevent/event-plugin.c > +++ /dev/null > @@ -1,711 +0,0 @@ > -// SPDX-License-Identifier: LGPL-2.1 > -/* > - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt > - * > - */ > - > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include "event-parse.h" > -#include "event-parse-local.h" > -#include "event-utils.h" > -#include "trace-seq.h" > - > -#define LOCAL_PLUGIN_DIR ".local/lib/traceevent/plugins/" > - > -static struct registered_plugin_options { > - struct registered_plugin_options *next; > - struct tep_plugin_option *options; > -} *registered_options; > - > -static struct trace_plugin_options { > - struct trace_plugin_options *next; > - char *plugin; > - char *option; > - char *value; > -} *trace_plugin_options; > - > -struct tep_plugin_list { > - struct tep_plugin_list *next; > - char *name; > - void *handle; > -}; > - > -struct tep_plugins_dir { > - struct tep_plugins_dir *next; > - char *path; > - enum tep_plugin_load_priority prio; > -}; > - > -static void lower_case(char *str) > -{ > - if (!str) > - return; > - for (; *str; str++) > - *str = tolower(*str); > -} > - > -static int update_option_value(struct tep_plugin_option *op, const char *val) > -{ > - char *op_val; > - > - if (!val) { > - /* toggle, only if option is boolean */ > - if (op->value) > - /* Warn? */ > - return 0; > - op->set ^= 1; > - return 0; > - } > - > - /* > - * If the option has a value then it takes a string > - * otherwise the option is a boolean. > - */ > - if (op->value) { > - op->value = val; > - return 0; > - } > - > - /* Option is boolean, must be either "1", "0", "true" or "false" */ > - > - op_val = strdup(val); > - if (!op_val) > - return -1; > - lower_case(op_val); > - > - if (strcmp(val, "1") == 0 || strcmp(val, "true") == 0) > - op->set = 1; > - else if (strcmp(val, "0") == 0 || strcmp(val, "false") == 0) > - op->set = 0; > - free(op_val); > - > - return 0; > -} > - > -/** > - * tep_plugin_list_options - get list of plugin options > - * > - * Returns an array of char strings that list the currently registered > - * plugin options in the format of :