From nobody Fri Sep 19 02:34:17 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BD44C4321E for ; Wed, 30 Nov 2022 06:30:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234113AbiK3GaD (ORCPT ); Wed, 30 Nov 2022 01:30:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46106 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234091AbiK3G3z (ORCPT ); Wed, 30 Nov 2022 01:29:55 -0500 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 986CC2AE17 for ; Tue, 29 Nov 2022 22:29:54 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id e185-20020a2569c2000000b006f28dd5da75so13920404ybc.19 for ; Tue, 29 Nov 2022 22:29:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=HZL18oOsNtp1Oe4BxfidvSOrYVVlN8hR4hEUrcdG9nU=; b=FMNA5Chj3DF5Qdu3T6hVsMlCz/3WveDed7pxt8kIBvy248lpr+zle/NeOz8oXOfs7G QzFUKWde6+oAcJNib3oRIUdSTXRUj1MtKsp766xkur5Dq9aq7J7VqE37bfUze29Rmhls mPSd4gW6vBhRteSIBUiSBF2Y3q3MeXJeK3gQ68ttOZ91G4VZfEKKVpZ+AYLZumpOqG8x NCMZUzM+N7HRDbW3aRPqDWpqOKispvPQVcsgHnUews4wSteZ2r3u30byQ1bLSdxfdKti D0Nz/YFcX8OD89x+W8paiyLLRzYaOYiAmSRhCXU1GPKhgPURjhVOcTfeXlMZc/jv7zaT iZog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HZL18oOsNtp1Oe4BxfidvSOrYVVlN8hR4hEUrcdG9nU=; b=By/XGbKl2efPnseXcQ93zinjbUwhYPEJmXtZ+dCb9QZdo6OD+7hsAd2hkKQqcJcFm6 44ZSB2MA7D1Fe//tTaO5s5tzuABFmem6rXp4GYN0vRsnWJeTHggLBfVFEBYLpHjdwPA4 0YXQv85Uvn5BSxB1Th0iELjnKka9ltZKdASZRC112WLLL5j5pRPTrkWCIQf/3zH3GLsS TdmCj3W5CZT49QHhuewfUFdVhz79HoNKtXlLsv2GKJzZCZO5PesN79RsCAy5HGA59QL3 l5JWkZQAoeFSOFomcq6Uk9Fwx47J/raqIiMTM2LWS6LpPHIrWCQBemnM9s5fH6LjIA9O atCQ== X-Gm-Message-State: ANoB5pmfx6CXUvdETB9DmlBgWMRVmHGZQtVvJUGpPjUVEBc3qUmWD4c2 QPdQu3G4oOoycLAsysucMVWyWl3VAmv9 X-Google-Smtp-Source: AA0mqf7GPpvxyQJHXBNtjO3h5bKWOEMpMgrvNsR3Fbh9z2AshF3dX8pyxaW9njJ/GiASZaOR5nuno1ZNdkRT X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:788c:ccf4:3670:3362]) (user=irogers job=sendgmr) by 2002:a81:38d5:0:b0:3d2:8530:f69a with SMTP id f204-20020a8138d5000000b003d28530f69amr3905457ywa.357.1669789793849; Tue, 29 Nov 2022 22:29:53 -0800 (PST) Date: Tue, 29 Nov 2022 22:29:32 -0800 In-Reply-To: <20221130062935.2219247-1-irogers@google.com> Message-Id: <20221130062935.2219247-2-irogers@google.com> Mime-Version: 1.0 References: <20221130062935.2219247-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog Subject: [PATCH v2 1/4] perf util: Make header guard consistent with tool From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , 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 Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Remove git reference by changing GIT_COMPAT_UTIL_H to __PERF_UTIL_H. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim --- tools/perf/util/util.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index c1f2d423a9ec..63cdab0e5314 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef GIT_COMPAT_UTIL_H -#define GIT_COMPAT_UTIL_H +#ifndef __PERF_UTIL_H +#define __PERF_UTIL_H =20 #define _BSD_SOURCE 1 /* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ @@ -94,4 +94,4 @@ int do_realloc_array_as_needed(void **arr, size_t *arr_sz= , size_t x, 0; \ }) =20 -#endif /* GIT_COMPAT_UTIL_H */ +#endif /* __PERF_UTIL_H */ --=20 2.38.1.584.g0f3c55d4c2-goog From nobody Fri Sep 19 02:34:17 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9E20C47088 for ; Wed, 30 Nov 2022 06:30:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234140AbiK3GaP (ORCPT ); Wed, 30 Nov 2022 01:30:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46322 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234119AbiK3GaF (ORCPT ); Wed, 30 Nov 2022 01:30:05 -0500 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F512391DE for ; Tue, 29 Nov 2022 22:30:02 -0800 (PST) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-3d2994e2d7dso25014787b3.9 for ; Tue, 29 Nov 2022 22:30:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Lha3Kd4WHFBCvvAfaMAOkc1TPFOurCRe2KIXhb9Lg+s=; b=tbYWTlkoh3HC2/boHCOqE4z2jFROYutDeVXnfVOM/WaEQ5V0AiMbkUWKqaHYr6SxPj RgDTxtorxl6kfuoCRbUFrZw9hsijqLjhV4mVEBK8Z735bpm/HNvl1SIGdlIyOlcDuz7e I2Ljg0BFulbygmqyKrZxqdDa8oELnS75fw5Gmmy+Aei0AKbmPtfhRCY0tM/OL0Xx4Q9c 8p+KMxNFnCMCbU7V+rTX24i0zUfXKhsZRiSHkZXpQuLQbMsgwDqGZu+mA27srobQamV2 HRsjvI7ylALkNuvVnG8UVvVdVdXrDZaVzteDqFgiKjTsQA2G6u2R6NA2Ka8Gls/FIPI0 PFgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Lha3Kd4WHFBCvvAfaMAOkc1TPFOurCRe2KIXhb9Lg+s=; b=u/kCghncnRvKE7L3eXu1iON16RK8TZ9nDyb7kL41AqF3dpZuEF1hauOollo0OKSDqD L1lSaUdAi53WL3WqD5WK8xxZBzD8ctFOaJrR21kaUinCVECz+l+s49hMMgK6fO9sDknb 8+Gy34myFMVH/DIQUdY8OBYt+p4Hhv9RnmygpCoHKE065kLsKkdZavXq87/5L1xKf21y VG2C7etRhls/zEhFSh4Wvg47bY3yAxi9v7zUIGNqxkzlMIaZGMCI5Hb7hUke/5QHULjQ 5v87KyLaJBSKYQLQD8m7NtpifUfz1ZYG/NqwaE3t+bMN4+X0pvcC1eSjd5iURJUDvZhY 3CyQ== X-Gm-Message-State: ANoB5pl6QpGCNbk+zy7kl7oMdFEoH0mrNl/8NISEfk0P6iTRWxoERT4c nAFK5IeqcpBqF8MquE900lgthxv0BtKK X-Google-Smtp-Source: AA0mqf5QbZ0WaudvfB0LFXVWYxcBY4hUbCSZVBwOtqtrh6E3uwvyJrfCLcf8gh2ubZUYVb/po0pu4m8pJjOs X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:788c:ccf4:3670:3362]) (user=irogers job=sendgmr) by 2002:a25:c5d4:0:b0:6cc:7860:8452 with SMTP id v203-20020a25c5d4000000b006cc78608452mr55001151ybe.51.1669789801589; Tue, 29 Nov 2022 22:30:01 -0800 (PST) Date: Tue, 29 Nov 2022 22:29:33 -0800 In-Reply-To: <20221130062935.2219247-1-irogers@google.com> Message-Id: <20221130062935.2219247-3-irogers@google.com> Mime-Version: 1.0 References: <20221130062935.2219247-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog Subject: [PATCH v2 2/4] perf util: Add host_is_bigendian to util.h From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , 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 Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Avoid libtraceevent dependency for tep_is_bigendian or trace-event.h dependency for bigendian. Add a new host_is_bigendian to util.h, using the compiler defined __BYTE_ORDER__ when available. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim --- tools/perf/tests/code-reading.c | 4 ++-- tools/perf/tests/sample-parsing.c | 4 ++-- tools/perf/util/evsel.c | 5 +---- tools/perf/util/trace-event-info.c | 14 +++----------- tools/perf/util/trace-event-read.c | 3 ++- tools/perf/util/trace-event.h | 2 -- tools/perf/util/util.h | 19 +++++++++++++++++++ 7 files changed, 29 insertions(+), 22 deletions(-) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index 95feb6ef34a0..cb8cd09938d5 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -16,7 +16,6 @@ #include "dso.h" #include "env.h" #include "parse-events.h" -#include "trace-event.h" #include "evlist.h" #include "evsel.h" #include "thread_map.h" @@ -28,6 +27,7 @@ #include "util/mmap.h" #include "util/string2.h" #include "util/synthetic-events.h" +#include "util/util.h" #include "thread.h" =20 #include "tests.h" @@ -79,7 +79,7 @@ static size_t read_objdump_chunk(const char **line, unsig= ned char **buf, * see disassemble_bytes() at binutils/objdump.c for details * how objdump chooses display endian) */ - if (bytes_read > 1 && !bigendian()) { + if (bytes_read > 1 && !host_is_bigendian()) { unsigned char *chunk_end =3D chunk_start + bytes_read - 1; unsigned char tmp; =20 diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-pa= rsing.c index 20930dd48ee0..927c7f0cc4cc 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -13,7 +13,7 @@ #include "evsel.h" #include "debug.h" #include "util/synthetic-events.h" -#include "util/trace-event.h" +#include "util/util.h" =20 #include "tests.h" =20 @@ -117,7 +117,7 @@ static bool samples_same(const struct perf_sample *s1, COMP(branch_stack->hw_idx); for (i =3D 0; i < s1->branch_stack->nr; i++) { if (needs_swap) - return ((tep_is_bigendian()) ? + return ((host_is_bigendian()) ? (FLAG(s2).value =3D=3D BS_EXPECTED_BE) : (FLAG(s2).value =3D=3D BS_EXPECTED_LE)); else diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 45f4f08399ae..0f617359a82f 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2320,11 +2320,8 @@ u64 evsel__bitfield_swap_branch_flags(u64 value) * as it has variable bit-field sizes. Instead the * macro takes the bit-field position/size, * swaps it based on the host endianness. - * - * tep_is_bigendian() is used here instead of - * bigendian() to avoid python test fails. */ - if (tep_is_bigendian()) { + if (host_is_bigendian()) { new_val =3D bitfield_swap(value, 0, 1); new_val |=3D bitfield_swap(value, 1, 1); new_val |=3D bitfield_swap(value, 2, 1); diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-eve= nt-info.c index 892c323b4ac9..c24b3a15e319 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -26,6 +26,7 @@ #include #include "evsel.h" #include "debug.h" +#include "util.h" =20 #define VERSION "0.6" #define MAX_EVENT_LENGTH 512 @@ -38,15 +39,6 @@ struct tracepoint_path { struct tracepoint_path *next; }; =20 -int bigendian(void) -{ - unsigned char str[] =3D { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0}; - unsigned int *ptr; - - ptr =3D (unsigned int *)(void *)str; - return *ptr =3D=3D 0x01020304; -} - /* unfortunately, you can not stat debugfs or proc files for size */ static int record_file(const char *file, ssize_t hdr_sz) { @@ -79,7 +71,7 @@ static int record_file(const char *file, ssize_t hdr_sz) =20 /* ugh, handle big-endian hdr_size =3D=3D 4 */ sizep =3D (char*)&size; - if (bigendian()) + if (host_is_bigendian()) sizep +=3D sizeof(u64) - hdr_sz; =20 if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) { @@ -564,7 +556,7 @@ static int tracing_data_header(void) return -1; =20 /* save endian */ - if (bigendian()) + if (host_is_bigendian()) buf[0] =3D 1; else buf[0] =3D 0; diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-eve= nt-read.c index 8a01af783310..43146a4ce2fb 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -17,6 +17,7 @@ =20 #include "trace-event.h" #include "debug.h" +#include "util.h" =20 static int input_fd; =20 @@ -414,7 +415,7 @@ ssize_t trace_report(int fd, struct trace_event *tevent= , bool __repipe) return -1; } file_bigendian =3D buf[0]; - host_bigendian =3D bigendian(); + host_bigendian =3D host_is_bigendian() ? 1 : 0; =20 if (trace_event__init(tevent)) { pr_debug("trace_event__init failed"); diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 640981105788..8f39f5bcb2c2 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -27,8 +27,6 @@ trace_event__tp_format(const char *sys, const char *name); =20 struct tep_event *trace_event__tp_format_id(int id); =20 -int bigendian(void); - void event_format__fprintf(struct tep_event *event, int cpu, void *data, int size, FILE *fp); =20 diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 63cdab0e5314..87d418cb6792 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -94,4 +94,23 @@ int do_realloc_array_as_needed(void **arr, size_t *arr_s= z, size_t x, 0; \ }) =20 +static inline bool host_is_bigendian(void) +{ +#ifdef __BYTE_ORDER__ +#if __BYTE_ORDER__ =3D=3D __ORDER_LITTLE_ENDIAN__ + return false; +#elif __BYTE_ORDER__ =3D=3D __ORDER_BIG_ENDIAN__ + return true; +#else +#error "Unrecognized __BYTE_ORDER__" +#endif +#else + unsigned char str[] =3D { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0}; + unsigned int *ptr; + + ptr =3D (unsigned int *)(void *)str; + return *ptr =3D=3D 0x01020304; +#endif +} + #endif /* __PERF_UTIL_H */ --=20 2.38.1.584.g0f3c55d4c2-goog From nobody Fri Sep 19 02:34:17 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B1897C4321E for ; Wed, 30 Nov 2022 06:30:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234163AbiK3Gar (ORCPT ); Wed, 30 Nov 2022 01:30:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234222AbiK3GaV (ORCPT ); Wed, 30 Nov 2022 01:30:21 -0500 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D1F94AF09 for ; Tue, 29 Nov 2022 22:30:10 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id e202-20020a2550d3000000b006f9d739c724so2325422ybb.6 for ; Tue, 29 Nov 2022 22:30:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Pkdk0kIUlIrAuZX9PiioTs4KInAvPi3/A2o1BBwh9vM=; b=DtPeUfGftboOK2SJDS/3/cG2ZapTWYU5qgOvSuDBi0fx5rpMStx95lqCQcx732q+RK 4Rl7McPmUA0bTrfeKFqowQxt9hlUqQlpZI7Xygzmhbz8e930spA03RbVrvaqqh+I9RT+ 5Faue23GJX9A16xjhmrtn69TUiAuTA9+NtjsXebZaQk3OU7hWyfSl4tEvCwgJvD2CRXg 3/y5phjpyr8Hta/y2szaAgsEF/HGY01fLhwrMRqxznbznLpSGcbgix84v+SC6pArTfR/ gPThE+JeulU10ID6XkQqVBlwmkp0OtfxTJt/cWKL8vn0rF/acLb1ADls4k0V3vi0aF95 J0Sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Pkdk0kIUlIrAuZX9PiioTs4KInAvPi3/A2o1BBwh9vM=; b=T/dxtOn3hvcgf/VC/zCDI5XDA53t1LbFFPSYqGxwRUYbwO3oEfKsEFA2uGVgi8GsPG H+rt7ui2RkJM1mmzqzI1XKgJ8RJqjipGeMx55LUwoALKnn6J2tBet/hd0stJ18/OLGvH +X81QHhYjrCfzhZKDZsozpfGPNJZpWjSUB16pZHowKiFPVqMeZ9NwccMWF46m8jG5+mS FxXx77RtfUe2/qKx/5KYYH0QPSPyNv6eQTgM4Sd1UzZgEjVj19vnpHrAcvOOwJy2BFLM 1MlHpXl5XgHtAeaP0D5tg/NtFp72REt8Kk6MPuVinbx7Kbdeo8SohR2iWPjhZXHQ3uJL U1VA== X-Gm-Message-State: ANoB5pkRYj+hF+CA3mA9STG44GdDjz3pu6FuzylxnVtMQgyMsF1mODvZ QaKX/wbTsNvdyekYV0CZ53pKWCgOqggc X-Google-Smtp-Source: AA0mqf7o4gjq607cETjbQyt4HSXO/bCL4R5K29jCvS75B6ELWonGHjIXbbg9BMRCBz3bLdPPeNmXC8pm6SNc X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:788c:ccf4:3670:3362]) (user=irogers job=sendgmr) by 2002:a0d:d491:0:b0:3cc:5892:fd07 with SMTP id w139-20020a0dd491000000b003cc5892fd07mr9965948ywd.420.1669789809625; Tue, 29 Nov 2022 22:30:09 -0800 (PST) Date: Tue, 29 Nov 2022 22:29:34 -0800 In-Reply-To: <20221130062935.2219247-1-irogers@google.com> Message-Id: <20221130062935.2219247-4-irogers@google.com> Mime-Version: 1.0 References: <20221130062935.2219247-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog Subject: [PATCH v2 3/4] perf build: Use libtraceevent from the system From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , 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 Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Remove the LIBTRACEEVENT_DYNAMIC and LIBTRACEFS_DYNAMIC. If libtraceevent isn't installed or NO_LIBTRACEEVENT=3D1 is passed to the build, don't compile in libtraceevent and libtracefs support. This also disables CONFIG_TRACE that controls "perf trace". CONFIG_TRACEEVENT is used to control enablement in Build/Makefiles, HAVE_LIBTRACEEVENT is used in C code. Without HAVE_LIBTRACEEVENT tracepoints are disabled and as such the commands kmem, kwork, lock, sched and timechart are removed. The majority of commands continue to work including "perf test". Signed-off-by: Ian Rogers --- tools/perf/Build | 11 ++- tools/perf/Makefile.config | 37 +++---- tools/perf/Makefile.perf | 99 +------------------ tools/perf/arch/x86/util/Build | 2 +- tools/perf/arch/x86/util/intel-pt.c | 4 + tools/perf/builtin-annotate.c | 2 + tools/perf/builtin-inject.c | 8 ++ tools/perf/builtin-kmem.c | 1 + tools/perf/builtin-kvm.c | 12 +-- tools/perf/builtin-kwork.c | 1 + tools/perf/builtin-record.c | 2 + tools/perf/builtin-report.c | 9 +- tools/perf/builtin-script.c | 19 +++- tools/perf/builtin-timechart.c | 1 + tools/perf/builtin-trace.c | 5 +- tools/perf/builtin-version.c | 1 + tools/perf/perf.c | 24 +++-- .../perf/scripts/python/Perf-Trace-Util/Build | 2 +- tools/perf/tests/Build | 12 +-- tools/perf/tests/builtin-test.c | 6 ++ tools/perf/tests/parse-events.c | 20 ++++ tools/perf/util/Build | 10 +- tools/perf/util/data-convert-bt.c | 5 +- tools/perf/util/data-convert-json.c | 9 +- tools/perf/util/evlist.c | 6 +- tools/perf/util/evlist.h | 4 + tools/perf/util/evsel.c | 11 ++- tools/perf/util/evsel.h | 12 ++- tools/perf/util/evsel_fprintf.c | 7 +- tools/perf/util/header.c | 19 ++++ tools/perf/util/header.h | 2 + tools/perf/util/intel-pt.c | 7 +- tools/perf/util/parse-events.c | 15 +++ tools/perf/util/parse-events.h | 1 - tools/perf/util/python.c | 4 + tools/perf/util/scripting-engines/Build | 6 +- .../scripting-engines/trace-event-python.c | 1 + tools/perf/util/session.c | 2 + tools/perf/util/session.h | 2 + tools/perf/util/sort.c | 60 +++++++++-- tools/perf/util/synthetic-events.c | 6 ++ tools/perf/util/trace-event-parse.c | 2 + tools/perf/util/trace-event-read.c | 1 + tools/perf/util/trace-event-scripting.c | 1 + tools/perf/util/trace-event.c | 1 - tools/perf/util/trace-event.h | 11 ++- 46 files changed, 312 insertions(+), 171 deletions(-) diff --git a/tools/perf/Build b/tools/perf/Build index 496b096153bb..edafe3cb3d07 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -5,7 +5,6 @@ perf-y +=3D builtin-diff.o perf-y +=3D builtin-evlist.o perf-y +=3D builtin-ftrace.o perf-y +=3D builtin-help.o -perf-y +=3D builtin-sched.o perf-y +=3D builtin-buildid-list.o perf-y +=3D builtin-buildid-cache.o perf-y +=3D builtin-kallsyms.o @@ -13,11 +12,8 @@ perf-y +=3D builtin-list.o perf-y +=3D builtin-record.o perf-y +=3D builtin-report.o perf-y +=3D builtin-stat.o -perf-y +=3D builtin-timechart.o perf-y +=3D builtin-top.o perf-y +=3D builtin-script.o -perf-y +=3D builtin-kmem.o -perf-y +=3D builtin-lock.o perf-y +=3D builtin-kvm.o perf-y +=3D builtin-inject.o perf-y +=3D builtin-mem.o @@ -25,7 +21,12 @@ perf-y +=3D builtin-data.o perf-y +=3D builtin-version.o perf-y +=3D builtin-c2c.o perf-y +=3D builtin-daemon.o -perf-y +=3D builtin-kwork.o + +perf-$(CONFIG_TRACEEVENT) +=3D builtin-kmem.o +perf-$(CONFIG_TRACEEVENT) +=3D builtin-kwork.o +perf-$(CONFIG_TRACEEVENT) +=3D builtin-lock.o +perf-$(CONFIG_TRACEEVENT) +=3D builtin-sched.o +perf-$(CONFIG_TRACEEVENT) +=3D builtin-timechart.o =20 perf-$(CONFIG_TRACE) +=3D builtin-trace.o perf-$(CONFIG_LIBELF) +=3D builtin-probe.o diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 9cc3c48f3288..b34288cb1900 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -763,18 +763,20 @@ ifndef NO_LIBUNWIND EXTLIBS +=3D $(EXTLIBS_LIBUNWIND) endif =20 -ifeq ($(NO_SYSCALL_TABLE),0) - $(call detected,CONFIG_TRACE) -else - ifndef NO_LIBAUDIT - $(call feature_check,libaudit) - ifneq ($(feature-libaudit), 1) - msg :=3D $(warning No libaudit.h found, disables 'trace' tool, pleas= e install audit-libs-devel or libaudit-dev); - NO_LIBAUDIT :=3D 1 - else - CFLAGS +=3D -DHAVE_LIBAUDIT_SUPPORT - EXTLIBS +=3D -laudit - $(call detected,CONFIG_TRACE) +ifneq ($(NO_LIBTRACEEVENT),1) + ifeq ($(NO_SYSCALL_TABLE),0) + $(call detected,CONFIG_TRACE) + else + ifndef NO_LIBAUDIT + $(call feature_check,libaudit) + ifneq ($(feature-libaudit), 1) + msg :=3D $(warning No libaudit.h found, disables 'trace' tool, ple= ase install audit-libs-devel or libaudit-dev); + NO_LIBAUDIT :=3D 1 + else + CFLAGS +=3D -DHAVE_LIBAUDIT_SUPPORT + EXTLIBS +=3D -laudit + $(call detected,CONFIG_TRACE) + endif endif endif endif @@ -1182,9 +1184,11 @@ ifdef LIBPFM4 endif endif =20 -ifdef LIBTRACEEVENT_DYNAMIC +# libtraceevent is a recommended dependency picked up from the system. +ifneq ($(NO_LIBTRACEEVENT),1) $(call feature_check,libtraceevent) ifeq ($(feature-libtraceevent), 1) + CFLAGS +=3D -DHAVE_LIBTRACEEVENT EXTLIBS +=3D -ltraceevent LIBTRACEEVENT_VERSION :=3D $(shell $(PKG_CONFIG) --modversion libtrace= event) LIBTRACEEVENT_VERSION_1 :=3D $(word 1, $(subst ., ,$(LIBTRACEEVENT_VER= SION))) @@ -1192,12 +1196,11 @@ ifdef LIBTRACEEVENT_DYNAMIC LIBTRACEEVENT_VERSION_3 :=3D $(word 3, $(subst ., ,$(LIBTRACEEVENT_VER= SION))) LIBTRACEEVENT_VERSION_CPP :=3D $(shell expr $(LIBTRACEEVENT_VERSION_1)= \* 255 \* 255 + $(LIBTRACEEVENT_VERSION_2) \* 255 + $(LIBTRACEEVENT_VERSIO= N_3)) CFLAGS +=3D -DLIBTRACEEVENT_VERSION=3D$(LIBTRACEEVENT_VERSION_CPP) + $(call detected,CONFIG_TRACEEVENT) else - dummy :=3D $(error Error: No libtraceevent devel library found, please= install libtraceevent-devel); + dummy :=3D $(warning Warning: libtraceevent is missing limiting functi= onality, please install libtraceevent-dev) endif -endif =20 -ifdef LIBTRACEFS_DYNAMIC $(call feature_check,libtracefs) ifeq ($(feature-libtracefs), 1) EXTLIBS +=3D -ltracefs @@ -1207,8 +1210,6 @@ ifdef LIBTRACEFS_DYNAMIC LIBTRACEFS_VERSION_3 :=3D $(word 3, $(subst ., ,$(LIBTRACEFS_VERSION))) LIBTRACEFS_VERSION_CPP :=3D $(shell expr $(LIBTRACEFS_VERSION_1) \* 25= 5 \* 255 + $(LIBTRACEFS_VERSION_2) \* 255 + $(LIBTRACEFS_VERSION_3)) CFLAGS +=3D -DLIBTRACEFS_VERSION=3D$(LIBTRACEFS_VERSION_CPP) - else - dummy :=3D $(error Error: No libtracefs devel library found, please in= stall libtracefs-dev); endif endif =20 diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index f4cd946fe91a..f0e4daeef812 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -128,10 +128,6 @@ include ../scripts/utilities.mak # # Define BUILD_BPF_SKEL to enable BPF skeletons # -# Define LIBTRACEEVENT_DYNAMIC to enable libtraceevent dynamic linking -# -# Define LIBTRACEFS_DYNAMIC to enable libtracefs dynamic linking -# =20 # As per kernel Makefile, avoid funny character set dependencies unexport LC_ALL @@ -242,10 +238,6 @@ sub-make: fixdep else # force_fixdep =20 LIBAPI_DIR =3D $(srctree)/tools/lib/api/ -ifndef LIBTRACEEVENT_DYNAMIC -LIBTRACEEVENT_DIR =3D $(srctree)/tools/lib/traceevent/ -LIBTRACEEVENT_PLUGINS_DIR =3D $(LIBTRACEEVENT_DIR)/plugins -endif LIBBPF_DIR =3D $(srctree)/tools/lib/bpf/ LIBSUBCMD_DIR =3D $(srctree)/tools/lib/subcmd/ LIBSYMBOL_DIR =3D $(srctree)/tools/lib/symbol/ @@ -295,31 +287,6 @@ SCRIPT_SH +=3D perf-iostat.sh grep-libs =3D $(filter -l%,$(1)) strip-libs =3D $(filter-out -l%,$(1)) =20 -ifndef LIBTRACEEVENT_DYNAMIC -ifneq ($(OUTPUT),) - LIBTRACEEVENT_OUTPUT =3D $(abspath $(OUTPUT))/libtraceevent -else - LIBTRACEEVENT_OUTPUT =3D $(CURDIR)/libtraceevent -endif -LIBTRACEEVENT_PLUGINS_OUTPUT =3D $(LIBTRACEEVENT_OUTPUT)_plugins -LIBTRACEEVENT_DESTDIR =3D $(LIBTRACEEVENT_OUTPUT) -LIBTRACEEVENT_PLUGINS_DESTDIR =3D $(LIBTRACEEVENT_PLUGINS_OUTPUT) -LIBTRACEEVENT_INCLUDE =3D $(LIBTRACEEVENT_DESTDIR)/include -LIBTRACEEVENT =3D $(LIBTRACEEVENT_OUTPUT)/libtraceevent.a -export LIBTRACEEVENT -LIBTRACEEVENT_DYNAMIC_LIST =3D $(LIBTRACEEVENT_PLUGINS_OUTPUT)/libtraceeve= nt-dynamic-list -CFLAGS +=3D -I$(LIBTRACEEVENT_OUTPUT)/include -# -# The static build has no dynsym table, so this does not work for -# static build. Looks like linker starts to scream about that now -# (in Fedora 26) so we need to switch it off for static build. -DYNAMIC_LIST_LDFLAGS =3D -Xlinker --dynamic-list=3D$(LIBTRAC= EEVENT_DYNAMIC_LIST) -LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS =3D $(if $(findstring -static,$(LDFLAGS= )),,$(DYNAMIC_LIST_LDFLAGS)) -else -LIBTRACEEVENT_DYNAMIC_LIST =3D -LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS =3D -endif - ifneq ($(OUTPUT),) LIBAPI_OUTPUT =3D $(abspath $(OUTPUT))/libapi else @@ -381,11 +348,7 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP python-clean :=3D $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) = $(OUTPUT)python/perf*.so =20 PYTHON_EXT_SRCS :=3D $(shell grep -v ^\# util/python-ext-sources) -ifndef LIBTRACEEVENT_DYNAMIC -PYTHON_EXT_DEPS :=3D util/python-ext-sources util/setup.py $(LIBTRACEEVENT= ) $(LIBAPI) -else PYTHON_EXT_DEPS :=3D util/python-ext-sources util/setup.py $(LIBAPI) -endif =20 SCRIPTS =3D $(patsubst %.sh,%,$(SCRIPT_SH)) =20 @@ -430,9 +393,6 @@ ifndef NO_LIBBPF PERFLIBS +=3D $(LIBBPF) endif endif -ifndef LIBTRACEEVENT_DYNAMIC - PERFLIBS +=3D $(LIBTRACEEVENT) -endif =20 # We choose to avoid "if .. else if .. else .. endif endif" # because maintaining the nesting to match is a pain. If @@ -682,9 +642,9 @@ all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BI= NDINGS) $(OTHER_PROGRAMS) # Create python binding output directory if not already present _dummy :=3D $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python') =20 -$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEE= VENT_DYNAMIC_LIST) $(LIBPERF) +$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBPERF) $(QUIET_GEN)LDSHARED=3D"$(CC) -pthread -shared" \ - CFLAGS=3D'$(CFLAGS)' LDFLAGS=3D'$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC= _LIST_LDFLAGS)' \ + CFLAGS=3D'$(CFLAGS)' LDFLAGS=3D'$(LDFLAGS)' \ $(PYTHON_WORD) util/setup.py \ --quiet build_ext; \ cp $(PYTHON_EXTBUILD_LIB)perf*.so $(OUTPUT)python/ @@ -710,8 +670,8 @@ $(PERF_IN): prepare FORCE $(PMU_EVENTS_IN): FORCE prepare $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=3Dpmu-events obj= =3Dpmu-events =20 -$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYN= AMIC_LIST) - $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFL= AGS) \ +$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) \ $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@ =20 $(GTK_IN): FORCE prepare @@ -797,10 +757,6 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cm= ds.h archheaders $(drm_ioc $(LIBSYMBOL) \ bpf-skel =20 -ifndef LIBTRACEEVENT_DYNAMIC -prepare: $(LIBTRACEEVENT) -endif - $(OUTPUT)%.o: %.c prepare FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=3D$(build-dir) $@ =20 @@ -856,38 +812,6 @@ endif =20 $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) =20 -ifndef LIBTRACEEVENT_DYNAMIC -LIBTRACEEVENT_FLAGS +=3D plugin_dir=3D$(plugindir_SQ) 'EXTRA_CFLAGS=3D$(EX= TRA_CFLAGS)' 'LDFLAGS=3D$(filter-out -static,$(LDFLAGS))' - -$(LIBTRACEEVENT): FORCE | $(LIBTRACEEVENT_OUTPUT) - $(Q)$(MAKE) -C $(LIBTRACEEVENT_DIR) O=3D$(LIBTRACEEVENT_OUTPUT) \ - DESTDIR=3D$(LIBTRACEEVENT_DESTDIR) prefix=3D \ - $@ install_headers - -$(LIBTRACEEVENT)-clean: - $(call QUIET_CLEAN, libtraceevent) - $(Q)$(RM) -r -- $(LIBTRACEEVENT_OUTPUT) - -libtraceevent_plugins: FORCE | $(LIBTRACEEVENT_PLUGINS_OUTPUT) - $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=3D$(LIBTRACEEVENT_PLUGINS_O= UTPUT) \ - DESTDIR=3D$(LIBTRACEEVENT_PLUGINS_DESTDIR) prefix=3D \ - plugins - -libtraceevent_plugins-clean: - $(call QUIET_CLEAN, libtraceevent_plugins) - $(Q)$(RM) -r -- $(LIBTRACEEVENT_PLUGINS_OUTPUT) - -$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins - $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=3D$(LIBTRACEEVENT_PLUGINS_O= UTPUT) \ - DESTDIR=3D$(LIBTRACEEVENT_PLUGINS_DESTDIR) prefix=3D \ - $(LIBTRACEEVENT_FLAGS) $@ - -install-traceevent-plugins: libtraceevent_plugins - $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=3D$(LIBTRACEEVENT_PLUGINS_O= UTPUT) \ - DESTDIR=3D$(DESTDIR_SQ) prefix=3D \ - $(LIBTRACEEVENT_FLAGS) install -endif - $(LIBAPI): FORCE | $(LIBAPI_OUTPUT) $(Q)$(MAKE) -C $(LIBAPI_DIR) O=3D$(LIBAPI_OUTPUT) \ DESTDIR=3D$(LIBAPI_DESTDIR) prefix=3D \ @@ -1095,10 +1019,6 @@ install-tests: all install-gtk =20 install-bin: install-tools install-tests =20 -ifndef LIBTRACEEVENT_DYNAMIC -install-bin: install-traceevent-plugins -endif - install: install-bin try-install-man =20 install-python_ext: @@ -1124,11 +1044,6 @@ SKELETONS +=3D $(SKEL_OUT)/kwork_trace.skel.h $(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBS= UBCMD_OUTPUT) $(LIBSYMBOL_OUTPUT): $(Q)$(MKDIR) -p $@ =20 -ifndef LIBTRACEEVENT_DYNAMIC -$(LIBTRACEEVENT_OUTPUT) $(LIBTRACEEVENT_PLUGINS_OUTPUT): - $(Q)$(MKDIR) -p $@ -endif - ifdef BUILD_BPF_SKEL BPFTOOL :=3D $(SKEL_TMP_OUT)/bootstrap/bpftool BPF_INCLUDE :=3D -I$(SKEL_TMP_OUT)/.. -I$(LIBBPF_INCLUDE) @@ -1211,10 +1126,6 @@ clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)= -clean $(LIBSYMBOL)-clean $( $(call QUIET_CLEAN, Documentation) \ $(MAKE) -C $(DOC_DIR) O=3D$(OUTPUT) clean >/dev/null =20 -ifndef LIBTRACEEVENT_DYNAMIC -clean:: $(LIBTRACEEVENT)-clean libtraceevent_plugins-clean -endif - # # To provide FEATURE-DUMP into $(FEATURE_DUMP_COPY) # file if defined, with no further action. @@ -1232,6 +1143,6 @@ FORCE: .PHONY: all install clean config-clean strip install-gtk .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_sh= ell .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope FORCE prepare -.PHONY: libtraceevent_plugins archheaders +.PHONY: archheaders =20 endif # force_fixdep diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build index dbeb04cb336e..a92644f12eec 100644 --- a/tools/perf/arch/x86/util/Build +++ b/tools/perf/arch/x86/util/Build @@ -1,7 +1,7 @@ perf-y +=3D header.o perf-y +=3D tsc.o perf-y +=3D pmu.o -perf-y +=3D kvm-stat.o +perf-$(CONFIG_TRACEEVENT) +=3D kvm-stat.o perf-y +=3D perf_regs.o perf-y +=3D topdown.o perf-y +=3D machine.o diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util= /intel-pt.c index af102f471e9f..1e39a034cee9 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -418,6 +418,7 @@ static int intel_pt_info_fill(struct auxtrace_record *i= tr, return 0; } =20 +#ifdef HAVE_LIBTRACEEVENT static int intel_pt_track_switches(struct evlist *evlist) { const char *sched_switch =3D "sched:sched_switch"; @@ -439,6 +440,7 @@ static int intel_pt_track_switches(struct evlist *evlis= t) =20 return 0; } +#endif =20 static void intel_pt_valid_str(char *str, size_t len, u64 valid) { @@ -829,6 +831,7 @@ static int intel_pt_recording_options(struct auxtrace_r= ecord *itr, ptr->have_sched_switch =3D 2; } } else { +#ifdef HAVE_LIBTRACEEVENT err =3D intel_pt_track_switches(evlist); if (err =3D=3D -EPERM) pr_debug2("Unable to select sched:sched_switch\n"); @@ -836,6 +839,7 @@ static int intel_pt_recording_options(struct auxtrace_r= ecord *itr, return err; else ptr->have_sched_switch =3D 1; +#endif } } =20 diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 517d928c00e3..90458ca6933f 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -499,7 +499,9 @@ int cmd_annotate(int argc, const char **argv) .namespaces =3D perf_event__process_namespaces, .attr =3D perf_event__process_attr, .build_id =3D perf_event__process_build_id, +#ifdef HAVE_LIBTRACEEVENT .tracing_data =3D perf_event__process_tracing_data, +#endif .id_index =3D perf_event__process_id_index, .auxtrace_info =3D perf_event__process_auxtrace_info, .auxtrace =3D perf_event__process_auxtrace, diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index e254f18986f7..3f4e4dd5abf3 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -607,6 +607,7 @@ static int perf_event__repipe_exit(struct perf_tool *to= ol, return err; } =20 +#ifdef HAVE_LIBTRACEEVENT static int perf_event__repipe_tracing_data(struct perf_session *session, union perf_event *event) { @@ -614,6 +615,7 @@ static int perf_event__repipe_tracing_data(struct perf_= session *session, =20 return perf_event__process_tracing_data(session, event); } +#endif =20 static int dso__read_build_id(struct dso *dso) { @@ -807,6 +809,7 @@ static int perf_inject__sched_switch(struct perf_tool *= tool, return 0; } =20 +#ifdef HAVE_LIBTRACEEVENT static int perf_inject__sched_stat(struct perf_tool *tool, union perf_event *event __maybe_unused, struct perf_sample *sample, @@ -836,6 +839,7 @@ static int perf_inject__sched_stat(struct perf_tool *to= ol, build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine); return perf_event__repipe(tool, event_sw, &sample_sw, machine); } +#endif =20 static struct guest_vcpu *guest_session__vcpu(struct guest_session *gs, u3= 2 vcpu) { @@ -1961,7 +1965,9 @@ static int __cmd_inject(struct perf_inject *inject) inject->tool.mmap =3D perf_event__repipe_mmap; inject->tool.mmap2 =3D perf_event__repipe_mmap2; inject->tool.fork =3D perf_event__repipe_fork; +#ifdef HAVE_LIBTRACEEVENT inject->tool.tracing_data =3D perf_event__repipe_tracing_data; +#endif } =20 output_data_offset =3D perf_session__data_offset(session->evlist); @@ -1984,8 +1990,10 @@ static int __cmd_inject(struct perf_inject *inject) evsel->handler =3D perf_inject__sched_switch; } else if (!strcmp(name, "sched:sched_process_exit")) evsel->handler =3D perf_inject__sched_process_exit; +#ifdef HAVE_LIBTRACEEVENT else if (!strncmp(name, "sched:sched_stat_", 17)) evsel->handler =3D perf_inject__sched_stat; +#endif } } else if (inject->itrace_synth_opts.vm_time_correlation) { session->itrace_synth_opts =3D &inject->itrace_synth_opts; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index ebfab2ca1702..e20656c431a4 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -35,6 +35,7 @@ #include =20 #include +#include =20 static int kmem_slab; static int kmem_page; diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 7d9ec1bac1a2..641e739c717c 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -63,7 +63,7 @@ static const char *get_filename_for_perf_kvm(void) return filename; } =20 -#ifdef HAVE_KVM_STAT_SUPPORT +#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) =20 void exit_event_get_key(struct evsel *evsel, struct perf_sample *sample, @@ -654,7 +654,7 @@ static void print_result(struct perf_kvm_stat *kvm) pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events); } =20 -#ifdef HAVE_TIMERFD_SUPPORT +#if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) static int process_lost_event(struct perf_tool *tool, union perf_event *event __maybe_unused, struct perf_sample *sample __maybe_unused, @@ -742,7 +742,7 @@ static bool verify_vcpu(int vcpu) return true; } =20 -#ifdef HAVE_TIMERFD_SUPPORT +#if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) /* keeping the max events to a modest level to keep * the processing of samples per mmap smooth. */ @@ -1290,7 +1290,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc= , const char **argv) return kvm_events_report_vcpu(kvm); } =20 -#ifdef HAVE_TIMERFD_SUPPORT +#if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) static struct evlist *kvm_live_event_list(void) { struct evlist *evlist; @@ -1507,7 +1507,7 @@ static int kvm_cmd_stat(const char *file_name, int ar= gc, const char **argv) if (strlen(argv[1]) > 2 && strstarts("report", argv[1])) return kvm_events_report(&kvm, argc - 1 , argv + 1); =20 -#ifdef HAVE_TIMERFD_SUPPORT +#if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) if (!strncmp(argv[1], "live", 4)) return kvm_events_live(&kvm, argc - 1 , argv + 1); #endif @@ -1644,7 +1644,7 @@ int cmd_kvm(int argc, const char **argv) return cmd_top(argc, argv); else if (strlen(argv[0]) > 2 && strstarts("buildid-list", argv[0])) return __cmd_buildid_list(file_name, argc, argv); -#ifdef HAVE_KVM_STAT_SUPPORT +#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) else if (strlen(argv[0]) > 2 && strstarts("stat", argv[0])) return kvm_cmd_stat(file_name, argc, argv); #endif diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c index 4ffbf5908070..024a6a949829 100644 --- a/tools/perf/builtin-kwork.c +++ b/tools/perf/builtin-kwork.c @@ -23,6 +23,7 @@ =20 #include #include +#include =20 #include #include diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index bd462a3f2bbd..50ce5adab897 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1701,8 +1701,10 @@ static void record__init_features(struct record *rec) if (rec->no_buildid) perf_header__clear_feat(&session->header, HEADER_BUILD_ID); =20 +#ifdef HAVE_LIBTRACEEVENT if (!have_tracepoints(&rec->evlist->core.entries)) perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); +#endif =20 if (!rec->opts.branch_stack) perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index b6d77d3da64f..2ee2ecca208e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -67,6 +67,10 @@ #include #include =20 +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + struct report { struct perf_tool tool; struct perf_session *session; @@ -1199,7 +1203,9 @@ int cmd_report(int argc, const char **argv) .lost =3D perf_event__process_lost, .read =3D process_read_event, .attr =3D process_attr, +#ifdef HAVE_LIBTRACEEVENT .tracing_data =3D perf_event__process_tracing_data, +#endif .build_id =3D perf_event__process_build_id, .id_index =3D perf_event__process_id_index, .auxtrace_info =3D perf_event__process_auxtrace_info, @@ -1660,6 +1666,7 @@ int cmd_report(int argc, const char **argv) report.range_num); } =20 +#ifdef HAVE_LIBTRACEEVENT if (session->tevent.pevent && tep_set_function_resolver(session->tevent.pevent, machine__resolve_kernel_addr, @@ -1668,7 +1675,7 @@ int cmd_report(int argc, const char **argv) __func__); return -1; } - +#endif sort__setup_elide(stdout); =20 ret =3D __cmd_report(&report); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index d7ec8c1af293..88888fb885c8 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -62,6 +62,9 @@ #include "perf.h" =20 #include +#ifdef HAVE_LIBTRACEEVENT +#include +#endif =20 static char const *script_name; static char const *generate_script_lang; @@ -2154,12 +2157,12 @@ static void process_event(struct perf_script *scrip= t, perf_sample__fprintf_bts(sample, evsel, thread, al, addr_al, machine, fp= ); return; } - +#ifdef HAVE_LIBTRACEEVENT if (PRINT_FIELD(TRACE) && sample->raw_data) { event_format__fprintf(evsel->tp_format, sample->cpu, sample->raw_data, sample->raw_size, fp); } - +#endif if (attr->type =3D=3D PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH)) perf_sample__fprintf_synth(sample, evsel, fp); =20 @@ -2283,8 +2286,10 @@ static void process_stat_interval(u64 tstamp) =20 static void setup_scripting(void) { +#ifdef HAVE_LIBTRACEEVENT setup_perl_scripting(); setup_python_scripting(); +#endif } =20 static int flush_scripting(void) @@ -3784,7 +3789,9 @@ int cmd_script(int argc, const char **argv) .fork =3D perf_event__process_fork, .attr =3D process_attr, .event_update =3D perf_event__process_event_update, +#ifdef HAVE_LIBTRACEEVENT .tracing_data =3D perf_event__process_tracing_data, +#endif .feature =3D process_feature_event, .build_id =3D perf_event__process_build_id, .id_index =3D perf_event__process_id_index, @@ -4215,6 +4222,7 @@ int cmd_script(int argc, const char **argv) else symbol_conf.use_callchain =3D false; =20 +#ifdef HAVE_LIBTRACEEVENT if (session->tevent.pevent && tep_set_function_resolver(session->tevent.pevent, machine__resolve_kernel_addr, @@ -4223,7 +4231,7 @@ int cmd_script(int argc, const char **argv) err =3D -1; goto out_delete; } - +#endif if (generate_script_lang) { struct stat perf_stat; int input; @@ -4259,9 +4267,12 @@ int cmd_script(int argc, const char **argv) err =3D -ENOENT; goto out_delete; } - +#ifdef HAVE_LIBTRACEEVENT err =3D scripting_ops->generate_script(session->tevent.pevent, "perf-script"); +#else + err =3D scripting_ops->generate_script(NULL, "perf-script"); +#endif goto out_delete; } =20 diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index c36296bb7637..6c629e7d370a 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -38,6 +38,7 @@ #include "util/string2.h" #include "util/tracepoint.h" #include +#include =20 #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE FILE *open_memstream(char **ptr, size_t *sizeloc); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 543c379d2a57..6909cd9f48d1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -15,7 +15,6 @@ */ =20 #include "util/record.h" -#include #include #include #include "util/bpf_map.h" @@ -80,6 +79,10 @@ #include #include =20 +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + #ifndef O_CLOEXEC # define O_CLOEXEC 02000000 #endif diff --git a/tools/perf/builtin-version.c b/tools/perf/builtin-version.c index a71f491224da..a886929ec6e5 100644 --- a/tools/perf/builtin-version.c +++ b/tools/perf/builtin-version.c @@ -82,6 +82,7 @@ static void library_status(void) STATUS(HAVE_AIO_SUPPORT, aio); STATUS(HAVE_ZSTD_SUPPORT, zstd); STATUS(HAVE_LIBPFM, libpfm4); + STATUS(HAVE_LIBTRACEEVENT, libtraceevent); } =20 int cmd_version(int argc, const char **argv) diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 7af135dea1cd..82bbe0ca858b 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -70,20 +70,26 @@ static struct cmd_struct commands[] =3D { { "report", cmd_report, 0 }, { "bench", cmd_bench, 0 }, { "stat", cmd_stat, 0 }, +#ifdef HAVE_LIBTRACEEVENT { "timechart", cmd_timechart, 0 }, +#endif { "top", cmd_top, 0 }, { "annotate", cmd_annotate, 0 }, { "version", cmd_version, 0 }, { "script", cmd_script, 0 }, +#ifdef HAVE_LIBTRACEEVENT { "sched", cmd_sched, 0 }, +#endif #ifdef HAVE_LIBELF_SUPPORT { "probe", cmd_probe, 0 }, #endif +#ifdef HAVE_LIBTRACEEVENT { "kmem", cmd_kmem, 0 }, { "lock", cmd_lock, 0 }, +#endif { "kvm", cmd_kvm, 0 }, { "test", cmd_test, 0 }, -#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT) +#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defi= ned(HAVE_SYSCALL_TABLE_SUPPORT)) { "trace", cmd_trace, 0 }, #endif { "inject", cmd_inject, 0 }, @@ -91,7 +97,9 @@ static struct cmd_struct commands[] =3D { { "data", cmd_data, 0 }, { "ftrace", cmd_ftrace, 0 }, { "daemon", cmd_daemon, 0 }, +#ifdef HAVE_LIBTRACEEVENT { "kwork", cmd_kwork, 0 }, +#endif }; =20 struct pager_config { @@ -500,14 +508,18 @@ int main(int argc, const char **argv) argv[0] =3D cmd; } if (strstarts(cmd, "trace")) { -#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT) - setup_path(); - argv[0] =3D "trace"; - return cmd_trace(argc, argv); -#else +#ifndef HAVE_LIBTRACEEVENT + fprintf(stderr, + "trace command not available: missing libtraceevent devel package at bu= ild time.\n"); + goto out; +#elif !defined(HAVE_LIBAUDIT_SUPPORT) && !defined(HAVE_SYSCALL_TABLE_SUPPO= RT) fprintf(stderr, "trace command not available: missing audit-libs devel package at build= time.\n"); goto out; +#else + setup_path(); + argv[0] =3D "trace"; + return cmd_trace(argc, argv); #endif } /* Look for flags.. */ diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Build b/tools/perf/s= cripts/python/Perf-Trace-Util/Build index 7d0e33ce6aba..f65625a60704 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Build +++ b/tools/perf/scripts/python/Perf-Trace-Util/Build @@ -1,3 +1,3 @@ -perf-y +=3D Context.o +perf-$(CONFIG_TRACEEVENT) +=3D Context.o =20 CFLAGS_Context.o +=3D $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-str= ict-prototypes -Wno-unused-parameter -Wno-nested-externs diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 11b69023011b..34ebc009e05a 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -6,13 +6,13 @@ perf-y +=3D parse-events.o perf-y +=3D dso-data.o perf-y +=3D attr.o perf-y +=3D vmlinux-kallsyms.o -perf-y +=3D openat-syscall.o -perf-y +=3D openat-syscall-all-cpus.o -perf-y +=3D openat-syscall-tp-fields.o -perf-y +=3D mmap-basic.o +perf-$(CONFIG_TRACEEVENT) +=3D openat-syscall.o +perf-$(CONFIG_TRACEEVENT) +=3D openat-syscall-all-cpus.o +perf-$(CONFIG_TRACEEVENT) +=3D openat-syscall-tp-fields.o +perf-$(CONFIG_TRACEEVENT) +=3D mmap-basic.o perf-y +=3D perf-record.o perf-y +=3D evsel-roundtrip-name.o -perf-y +=3D evsel-tp-sched.o +perf-$(CONFIG_TRACEEVENT) +=3D evsel-tp-sched.o perf-y +=3D fdarray.o perf-y +=3D pmu.o perf-y +=3D pmu-events.o @@ -30,7 +30,7 @@ perf-y +=3D task-exit.o perf-y +=3D sw-clock.o perf-y +=3D mmap-thread-lookup.o perf-y +=3D thread-maps-share.o -perf-y +=3D switch-tracking.o +perf-$(CONFIG_TRACEEVENT) +=3D switch-tracking.o perf-y +=3D keep-tracking.o perf-y +=3D code-reading.o perf-y +=3D sample-parsing.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index 4c6ae59a4dfd..658449204ce5 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -38,9 +38,11 @@ struct test_suite *__weak arch_tests[] =3D { =20 static struct test_suite *generic_tests[] =3D { &suite__vmlinux_matches_kallsyms, +#ifdef HAVE_LIBTRACEEVENT &suite__openat_syscall_event, &suite__openat_syscall_event_on_all_cpus, &suite__basic_mmap, +#endif &suite__mem, &suite__parse_events, &suite__expr, @@ -51,8 +53,10 @@ static struct test_suite *generic_tests[] =3D { &suite__dso_data_cache, &suite__dso_data_reopen, &suite__perf_evsel__roundtrip_name_test, +#ifdef HAVE_LIBTRACEEVENT &suite__perf_evsel__tp_sched_test, &suite__syscall_openat_tp_fields, +#endif &suite__attr, &suite__hists_link, &suite__python_use, @@ -71,7 +75,9 @@ static struct test_suite *generic_tests[] =3D { &suite__thread_maps_share, &suite__hists_output, &suite__hists_cumulate, +#ifdef HAVE_LIBTRACEEVENT &suite__switch_tracking, +#endif &suite__fdarray__filter, &suite__fdarray__add, &suite__kmod_path__parse, diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-event= s.c index 3440dd2616b0..dcbfb93287e8 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -46,6 +46,7 @@ static bool kvm_s390_create_vm_valid(void) } #endif =20 +#ifdef HAVE_LIBTRACEEVENT static int test__checkevent_tracepoint(struct evlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); @@ -76,6 +77,7 @@ static int test__checkevent_tracepoint_multi(struct evlis= t *evlist) } return TEST_OK; } +#endif /* HAVE_LIBTRACEEVENT */ =20 static int test__checkevent_raw(struct evlist *evlist) { @@ -222,6 +224,7 @@ static int test__checkevent_breakpoint_rw(struct evlist= *evlist) return TEST_OK; } =20 +#ifdef HAVE_LIBTRACEEVENT static int test__checkevent_tracepoint_modifier(struct evlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); @@ -252,6 +255,7 @@ test__checkevent_tracepoint_multi_modifier(struct evlis= t *evlist) =20 return test__checkevent_tracepoint_multi(evlist); } +#endif /* HAVE_LIBTRACEEVENT */ =20 static int test__checkevent_raw_modifier(struct evlist *evlist) { @@ -453,6 +457,7 @@ static int test__checkevent_pmu(struct evlist *evlist) return TEST_OK; } =20 +#ifdef HAVE_LIBTRACEEVENT static int test__checkevent_list(struct evlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); @@ -491,6 +496,7 @@ static int test__checkevent_list(struct evlist *evlist) =20 return TEST_OK; } +#endif =20 static int test__checkevent_pmu_name(struct evlist *evlist) { @@ -762,6 +768,7 @@ static int test__group2(struct evlist *evlist) return TEST_OK; } =20 +#ifdef HAVE_LIBTRACEEVENT static int test__group3(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; @@ -853,6 +860,7 @@ static int test__group3(struct evlist *evlist __maybe_u= nused) =20 return TEST_OK; } +#endif =20 static int test__group4(struct evlist *evlist __maybe_unused) { @@ -1460,6 +1468,7 @@ static int test__sym_event_dc(struct evlist *evlist) return TEST_OK; } =20 +#ifdef HAVE_LIBTRACEEVENT static int count_tracepoints(void) { struct dirent *events_ent; @@ -1513,6 +1522,7 @@ static int test__all_tracepoints(struct evlist *evlis= t) =20 return test__checkevent_tracepoint_multi(evlist); } +#endif /* HAVE_LIBTRACEVENT */ =20 static int test__hybrid_hw_event_with_pmu(struct evlist *evlist) { @@ -1642,6 +1652,7 @@ struct evlist_test { }; =20 static const struct evlist_test test__events[] =3D { +#ifdef HAVE_LIBTRACEEVENT { .name =3D "syscalls:sys_enter_openat", .check =3D test__checkevent_tracepoint, @@ -1652,6 +1663,7 @@ static const struct evlist_test test__events[] =3D { .check =3D test__checkevent_tracepoint_multi, /* 1 */ }, +#endif { .name =3D "r1a", .check =3D test__checkevent_raw, @@ -1702,6 +1714,7 @@ static const struct evlist_test test__events[] =3D { .check =3D test__checkevent_breakpoint_w, /* 1 */ }, +#ifdef HAVE_LIBTRACEEVENT { .name =3D "syscalls:sys_enter_openat:k", .check =3D test__checkevent_tracepoint_modifier, @@ -1712,6 +1725,7 @@ static const struct evlist_test test__events[] =3D { .check =3D test__checkevent_tracepoint_multi_modifier, /* 3 */ }, +#endif { .name =3D "r1a:kp", .check =3D test__checkevent_raw_modifier, @@ -1757,11 +1771,13 @@ static const struct evlist_test test__events[] =3D { .check =3D test__checkevent_breakpoint_w_modifier, /* 2 */ }, +#ifdef HAVE_LIBTRACEEVENT { .name =3D "r1,syscalls:sys_enter_openat:k,1:1:hp", .check =3D test__checkevent_list, /* 3 */ }, +#endif { .name =3D "instructions:G", .check =3D test__checkevent_exclude_host_modifier, @@ -1792,11 +1808,13 @@ static const struct evlist_test test__events[] =3D { .check =3D test__group2, /* 9 */ }, +#ifdef HAVE_LIBTRACEEVENT { .name =3D "group1{syscalls:sys_enter_openat:H,cycles:kppp},group2{cycle= s,1:3}:G,instructions:u", .check =3D test__group3, /* 0 */ }, +#endif { .name =3D "{cycles:u,instructions:kp}:p", .check =3D test__group4, @@ -1807,11 +1825,13 @@ static const struct evlist_test test__events[] =3D { .check =3D test__group5, /* 2 */ }, +#ifdef HAVE_LIBTRACEEVENT { .name =3D "*:*", .check =3D test__all_tracepoints, /* 3 */ }, +#endif { .name =3D "{cycles,cache-misses:G}:H", .check =3D test__group_gh1, diff --git a/tools/perf/util/Build b/tools/perf/util/Build index ab37f588ee8b..612406311e27 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -69,17 +69,17 @@ perf-y +=3D namespaces.o perf-y +=3D comm.o perf-y +=3D thread.o perf-y +=3D thread_map.o -perf-y +=3D trace-event-parse.o perf-y +=3D parse-events-flex.o perf-y +=3D parse-events-bison.o perf-y +=3D pmu.o perf-y +=3D pmu-flex.o perf-y +=3D pmu-bison.o perf-y +=3D pmu-hybrid.o -perf-y +=3D trace-event-read.o -perf-y +=3D trace-event-info.o -perf-y +=3D trace-event-scripting.o -perf-y +=3D trace-event.o +perf-$(CONFIG_TRACEEVENT) +=3D trace-event-info.o +perf-$(CONFIG_TRACEEVENT) +=3D trace-event-scripting.o +perf-$(CONFIG_TRACEEVENT) +=3D trace-event.o +perf-$(CONFIG_TRACEEVENT) +=3D trace-event-parse.o +perf-$(CONFIG_TRACEEVENT) +=3D trace-event-read.o perf-y +=3D svghelper.o perf-y +=3D sort.o perf-y +=3D hist.o diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-conve= rt-bt.c index c65cdaf6975e..8031b586e813 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "asm/bug.h" #include "data-convert.h" #include "session.h" @@ -36,6 +35,10 @@ #include "clockid.h" #include "util/sample.h" =20 +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + #define pr_N(n, fmt, ...) \ eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__) =20 diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-con= vert-json.c index 57db59068cb6..ba9d93ce9463 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -27,6 +27,10 @@ #include "util/thread.h" #include "util/tool.h" =20 +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + struct convert_json { struct perf_tool tool; FILE *out; @@ -217,6 +221,7 @@ static int process_sample_event(struct perf_tool *tool, } output_json_format(out, false, 3, "]"); =20 +#ifdef HAVE_LIBTRACEEVENT if (sample->raw_data) { int i; struct tep_format_field **fields; @@ -236,7 +241,7 @@ static int process_sample_event(struct perf_tool *tool, free(fields); } } - +#endif output_json_format(out, false, 2, "}"); return 0; } @@ -313,7 +318,9 @@ int bt_convert__perf2json(const char *input_name, const= char *output_name, .exit =3D perf_event__process_exit, .fork =3D perf_event__process_fork, .lost =3D perf_event__process_lost, +#ifdef HAVE_LIBTRACEEVENT .tracing_data =3D perf_event__process_tracing_data, +#endif .build_id =3D perf_event__process_build_id, .id_index =3D perf_event__process_id_index, .auxtrace_info =3D perf_event__process_auxtrace_info, diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index fbf3192bced9..590d4e77effc 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -290,6 +290,7 @@ struct evsel *evlist__add_aux_dummy(struct evlist *evli= st, bool system_wide) return evsel; } =20 +#ifdef HAVE_LIBTRACEEVENT struct evsel *evlist__add_sched_switch(struct evlist *evlist, bool system_= wide) { struct evsel *evsel =3D evsel__newtp_idx("sched", "sched_switch", 0); @@ -305,7 +306,8 @@ struct evsel *evlist__add_sched_switch(struct evlist *e= vlist, bool system_wide) =20 evlist__add(evlist, evsel); return evsel; -}; +} +#endif =20 int evlist__add_attrs(struct evlist *evlist, struct perf_event_attr *attrs= , size_t nr_attrs) { @@ -376,6 +378,7 @@ struct evsel *evlist__find_tracepoint_by_name(struct ev= list *evlist, const char return NULL; } =20 +#ifdef HAVE_LIBTRACEEVENT int evlist__add_newtp(struct evlist *evlist, const char *sys, const char *= name, void *handler) { struct evsel *evsel =3D evsel__newtp(sys, name); @@ -387,6 +390,7 @@ int evlist__add_newtp(struct evlist *evlist, const char= *sys, const char *name, evlist__add(evlist, evsel); return 0; } +#endif =20 struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct= affinity *affinity) { diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 16734c6756b3..e5b84ead566c 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -127,7 +127,9 @@ static inline struct evsel *evlist__add_dummy_on_all_cp= us(struct evlist *evlist) { return evlist__add_aux_dummy(evlist, true); } +#ifdef HAVE_LIBTRACEEVENT struct evsel *evlist__add_sched_switch(struct evlist *evlist, bool system_= wide); +#endif =20 int evlist__add_sb_event(struct evlist *evlist, struct perf_event_attr *at= tr, evsel__sb_cb_t cb, void *data); @@ -135,7 +137,9 @@ void evlist__set_cb(struct evlist *evlist, evsel__sb_cb= _t cb, void *data); int evlist__start_sb_thread(struct evlist *evlist, struct target *target); void evlist__stop_sb_thread(struct evlist *evlist); =20 +#ifdef HAVE_LIBTRACEEVENT int evlist__add_newtp(struct evlist *evlist, const char *sys, const char *= name, void *handler); +#endif =20 int __evlist__set_tracepoints_handlers(struct evlist *evlist, const struct evsel_str_handler *assocs, diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0f617359a82f..ca911856c4b1 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -57,6 +56,10 @@ =20 #include =20 +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + struct perf_missing_features perf_missing_features; =20 static clockid_t clockid; @@ -439,7 +442,9 @@ struct evsel *evsel__clone(struct evsel *orig) goto out_err; } evsel->cgrp =3D cgroup__get(orig->cgrp); +#ifdef HAVE_LIBTRACEEVENT evsel->tp_format =3D orig->tp_format; +#endif evsel->handler =3D orig->handler; evsel->core.leader =3D orig->core.leader; =20 @@ -479,6 +484,7 @@ struct evsel *evsel__clone(struct evsel *orig) /* * Returns pointer with encoded error via interface. */ +#ifdef HAVE_LIBTRACEEVENT struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx) { struct evsel *evsel =3D zalloc(perf_evsel__object.size); @@ -516,6 +522,7 @@ struct evsel *evsel__newtp_idx(const char *sys, const c= har *name, int idx) out_err: return ERR_PTR(err); } +#endif =20 const char *const evsel__hw_names[PERF_COUNT_HW_MAX] =3D { "cycles", @@ -2758,6 +2765,7 @@ u16 evsel__id_hdr_size(struct evsel *evsel) return size; } =20 +#ifdef HAVE_LIBTRACEEVENT struct tep_format_field *evsel__field(struct evsel *evsel, const char *nam= e) { return tep_find_field(evsel->tp_format, name); @@ -2831,6 +2839,7 @@ u64 evsel__intval(struct evsel *evsel, struct perf_sa= mple *sample, const char *n =20 return field ? format_field__intval(field, sample, evsel->needs_swap) : 0; } +#endif =20 bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsi= ze) { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index f3485799ddf9..d572be41b960 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -72,7 +72,9 @@ struct evsel { char *name; char *group_name; const char *pmu_name; +#ifdef HAVE_LIBTRACEEVENT struct tep_event *tp_format; +#endif char *filter; unsigned long max_events; double scale; @@ -223,11 +225,14 @@ static inline struct evsel *evsel__new(struct perf_ev= ent_attr *attr) } =20 struct evsel *evsel__clone(struct evsel *orig); -struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx); =20 int copy_config_terms(struct list_head *dst, struct list_head *src); void free_config_terms(struct list_head *config_terms); =20 + +#ifdef HAVE_LIBTRACEEVENT +struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx); + /* * Returns pointer with encoded error via interface. */ @@ -235,10 +240,13 @@ static inline struct evsel *evsel__newtp(const char *= sys, const char *name) { return evsel__newtp_idx(sys, name, 0); } +#endif =20 struct evsel *evsel__new_cycles(bool precise, __u32 type, __u64 config); =20 +#ifdef HAVE_LIBTRACEEVENT struct tep_event *event_format__new(const char *sys, const char *name); +#endif =20 void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int id= x); void evsel__exit(struct evsel *evsel); @@ -323,6 +331,7 @@ bool evsel__precise_ip_fallback(struct evsel *evsel); =20 struct perf_sample; =20 +#ifdef HAVE_LIBTRACEEVENT void *evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const= char *name); u64 evsel__intval(struct evsel *evsel, struct perf_sample *sample, const c= har *name); =20 @@ -330,6 +339,7 @@ static inline char *evsel__strval(struct evsel *evsel, = struct perf_sample *sampl { return evsel__rawptr(evsel, sample, name); } +#endif =20 struct tep_format_field; =20 diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprint= f.c index 8c2ea8001329..bd22c4932d10 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "evsel.h" #include "util/evsel_fprintf.h" #include "util/event.h" @@ -13,6 +12,10 @@ #include "srcline.h" #include "dso.h" =20 +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...) { va_list args; @@ -74,6 +77,7 @@ int evsel__fprintf(struct evsel *evsel, struct perf_attr_= details *details, FILE term, (u64)evsel->core.attr.sample_freq); } =20 +#ifdef HAVE_LIBTRACEEVENT if (details->trace_fields) { struct tep_format_field *field; =20 @@ -96,6 +100,7 @@ int evsel__fprintf(struct evsel *evsel, struct perf_attr= _details *details, FILE field =3D field->next; } } +#endif out: fputc('\n', fp); return ++printed; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 98dfaf84bd13..85c7b27e0cb4 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,10 @@ #include #include =20 +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + /* * magic2 =3D "PERFILE2" * must be a numerical value to let the endianness @@ -298,6 +303,7 @@ static int do_read_bitmap(struct feat_fd *ff, unsigned = long **pset, u64 *psize) return 0; } =20 +#ifdef HAVE_LIBTRACEEVENT static int write_tracing_data(struct feat_fd *ff, struct evlist *evlist) { @@ -306,6 +312,7 @@ static int write_tracing_data(struct feat_fd *ff, =20 return read_tracing_data(ff->fd, &evlist->core.entries); } +#endif =20 static int write_build_id(struct feat_fd *ff, struct evlist *evlist __maybe_unused) @@ -2394,12 +2401,14 @@ FEAT_PROCESS_STR_FUN(arch, arch); FEAT_PROCESS_STR_FUN(cpudesc, cpu_desc); FEAT_PROCESS_STR_FUN(cpuid, cpuid); =20 +#ifdef HAVE_LIBTRACEEVENT static int process_tracing_data(struct feat_fd *ff, void *data) { ssize_t ret =3D trace_report(ff->fd, data, false); =20 return ret < 0 ? -1 : 0; } +#endif =20 static int process_build_id(struct feat_fd *ff, void *data __maybe_unused) { @@ -3366,7 +3375,9 @@ static int process_pmu_caps(struct feat_fd *ff, void = *data __maybe_unused) const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE]; =20 const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] =3D { +#ifdef HAVE_LIBTRACEEVENT FEAT_OPN(TRACING_DATA, tracing_data, false), +#endif FEAT_OPN(BUILD_ID, build_id, false), FEAT_OPR(HOSTNAME, hostname, false), FEAT_OPR(OSRELEASE, osrelease, false), @@ -4082,6 +4093,7 @@ static int read_attr(int fd, struct perf_header *ph, return ret <=3D 0 ? -1 : 0; } =20 +#ifdef HAVE_LIBTRACEEVENT static int evsel__prepare_tracepoint_event(struct evsel *evsel, struct tep= _handle *pevent) { struct tep_event *event; @@ -4125,6 +4137,7 @@ static int evlist__prepare_tracepoint_events(struct e= vlist *evlist, struct tep_h =20 return 0; } +#endif =20 int perf_session__read_header(struct perf_session *session, int repipe_fd) { @@ -4230,11 +4243,15 @@ int perf_session__read_header(struct perf_session *= session, int repipe_fd) lseek(fd, tmp, SEEK_SET); } =20 +#ifdef HAVE_LIBTRACEEVENT perf_header__process_sections(header, fd, &session->tevent, perf_file_section__process); =20 if (evlist__prepare_tracepoint_events(session->evlist, session->tevent.pe= vent)) goto out_delete_evlist; +#else + perf_header__process_sections(header, fd, NULL, perf_file_section__proces= s); +#endif =20 return 0; out_errno: @@ -4412,6 +4429,7 @@ int perf_event__process_event_update(struct perf_tool= *tool __maybe_unused, return 0; } =20 +#ifdef HAVE_LIBTRACEEVENT int perf_event__process_tracing_data(struct perf_session *session, union perf_event *event) { @@ -4459,6 +4477,7 @@ int perf_event__process_tracing_data(struct perf_sess= ion *session, =20 return size_read + padding; } +#endif =20 int perf_event__process_build_id(struct perf_session *session, union perf_event *event) diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 2d5e601ba60f..e3861ae62172 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -160,8 +160,10 @@ int perf_event__process_event_update(struct perf_tool = *tool, union perf_event *event, struct evlist **pevlist); size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp); +#ifdef HAVE_LIBTRACEEVENT int perf_event__process_tracing_data(struct perf_session *session, union perf_event *event); +#endif int perf_event__process_build_id(struct perf_session *session, union perf_event *event); bool is_perf_magic(u64 magic); diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index e3548ddef254..6d3921627e33 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -3142,6 +3142,7 @@ static int intel_pt_sync_switch(struct intel_pt *pt, = int cpu, pid_t tid, return 1; } =20 +#ifdef HAVE_LIBTRACEEVENT static int intel_pt_process_switch(struct intel_pt *pt, struct perf_sample *sample) { @@ -3165,6 +3166,7 @@ static int intel_pt_process_switch(struct intel_pt *p= t, =20 return machine__set_current_tid(pt->machine, cpu, -1, tid); } +#endif /* HAVE_LIBTRACEEVENT */ =20 static int intel_pt_context_switch_in(struct intel_pt *pt, struct perf_sample *sample) @@ -3433,9 +3435,12 @@ static int intel_pt_process_event(struct perf_sessio= n *session, return err; } =20 +#ifdef HAVE_LIBTRACEEVENT if (pt->switch_evsel && event->header.type =3D=3D PERF_RECORD_SAMPLE) err =3D intel_pt_process_switch(pt, sample); - else if (event->header.type =3D=3D PERF_RECORD_ITRACE_START) + else +#endif + if (event->header.type =3D=3D PERF_RECORD_ITRACE_START) err =3D intel_pt_process_itrace_start(pt, event, sample); else if (event->header.type =3D=3D PERF_RECORD_AUX_OUTPUT_HW_ID) err =3D intel_pt_process_aux_output_hw_id(pt, event, sample); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 6502cd679f57..21cce83462b3 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -445,6 +445,7 @@ int parse_events_add_cache(struct list_head *list, int = *idx, return ret; } =20 +#ifdef HAVE_LIBTRACEEVENT static void tracepoint_error(struct parse_events_error *e, int err, const char *sys, const char *name) { @@ -593,6 +594,7 @@ static int add_tracepoint_multi_sys(struct list_head *l= ist, int *idx, closedir(events_dir); return ret; } +#endif /* HAVE_LIBTRACEEVENT */ =20 #ifdef HAVE_LIBBPF_SUPPORT struct __add_bpf_event_param { @@ -1143,6 +1145,7 @@ static int config_term_pmu(struct perf_event_attr *at= tr, return config_term_common(attr, term, err); } =20 +#ifdef HAVE_LIBTRACEEVENT static int config_term_tracepoint(struct perf_event_attr *attr, struct parse_events_term *term, struct parse_events_error *err) @@ -1170,6 +1173,7 @@ static int config_term_tracepoint(struct perf_event_a= ttr *attr, =20 return 0; } +#endif =20 static int config_attr(struct perf_event_attr *attr, struct list_head *head, @@ -1325,6 +1329,7 @@ int parse_events_add_tracepoint(struct list_head *lis= t, int *idx, struct parse_events_error *err, struct list_head *head_config) { +#ifdef HAVE_LIBTRACEEVENT if (head_config) { struct perf_event_attr attr; =20 @@ -1339,6 +1344,16 @@ int parse_events_add_tracepoint(struct list_head *li= st, int *idx, else return add_tracepoint_event(list, idx, sys, event, err, head_config); +#else + (void)list; + (void)idx; + (void)sys; + (void)event; + (void)head_config; + parse_events_error__handle(err, 0, strdup("unsupported tracepoint"), + strdup("libtraceevent is necessary for tracepoint support")); + return -1; +#endif } =20 int parse_events_add_numeric(struct parse_events_state *parse_state, diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 07df7bb7b042..428e72eaafcc 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -18,7 +18,6 @@ struct parse_events_error; struct option; struct perf_pmu; =20 -bool have_tracepoints(struct list_head *evlist); bool is_event_supported(u8 type, u64 config); =20 const char *event_type(int type); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index b5941c74a0d6..728fe2f51759 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -417,6 +417,7 @@ static PyObject *pyrf_sample_event__repr(struct pyrf_ev= ent *pevent) return ret; } =20 +#ifdef HAVE_LIBTRACEEVENT static bool is_tracepoint(struct pyrf_event *pevent) { return pevent->evsel->core.attr.type =3D=3D PERF_TYPE_TRACEPOINT; @@ -486,14 +487,17 @@ get_tracepoint_field(struct pyrf_event *pevent, PyObj= ect *attr_name) =20 return tracepoint_field(pevent, field); } +#endif /* HAVE_LIBTRACEEVENT */ =20 static PyObject* pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name) { PyObject *obj =3D NULL; =20 +#ifdef HAVE_LIBTRACEEVENT if (is_tracepoint(pevent)) obj =3D get_tracepoint_field(pevent, attr_name); +#endif =20 return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name); } diff --git a/tools/perf/util/scripting-engines/Build b/tools/perf/util/scri= pting-engines/Build index 0f5ba28339cf..77544d2c447c 100644 --- a/tools/perf/util/scripting-engines/Build +++ b/tools/perf/util/scripting-engines/Build @@ -1,5 +1,7 @@ -perf-$(CONFIG_LIBPERL) +=3D trace-event-perl.o -perf-$(CONFIG_LIBPYTHON) +=3D trace-event-python.o +ifeq ($(CONFIG_TRACEEVENT),y) + perf-$(CONFIG_LIBPERL) +=3D trace-event-perl.o + perf-$(CONFIG_LIBPYTHON) +=3D trace-event-python.o +endif =20 CFLAGS_trace-event-perl.o +=3D $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -= Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-nested-externs= -Wno-undef -Wno-switch-default -Wno-bad-function-cast -Wno-declaration-aft= er-statement -Wno-switch-enum =20 diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools= /perf/util/scripting-engines/trace-event-python.c index 1cf65db8f861..5b7db76fc3ba 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -30,6 +30,7 @@ #include #include #include +#include =20 #include "../build-id.h" #include "../counts.h" diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0e1a3d6bacb9..c1aa5cb656a6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -314,7 +314,9 @@ void perf_session__delete(struct perf_session *session) evlist__delete(session->evlist); perf_data__close(session->data); } +#ifdef HAVE_LIBTRACEEVENT trace_event__cleanup(&session->tevent); +#endif free(session); } =20 diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index be5871ea558f..ee3715e8563b 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -33,7 +33,9 @@ struct perf_session { struct auxtrace *auxtrace; struct itrace_synth_opts *itrace_synth_opts; struct list_head auxtrace_index; +#ifdef HAVE_LIBTRACEEVENT struct trace_event tevent; +#endif struct perf_record_time_conv time_conv; bool repipe; bool one_mmap; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 2e7330867e2e..c7a97b33e134 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -22,7 +22,6 @@ #include "srcline.h" #include "strlist.h" #include "strbuf.h" -#include #include "mem-events.h" #include "annotate.h" #include "event.h" @@ -32,6 +31,10 @@ #include #include =20 +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + regex_t parent_regex; const char default_parent_pattern[] =3D "^sys_|^do_page_fault"; const char *parent_pattern =3D default_parent_pattern; @@ -743,6 +746,7 @@ struct sort_entry sort_time =3D { =20 /* --sort trace */ =20 +#ifdef HAVE_LIBTRACEEVENT static char *get_trace_output(struct hist_entry *he) { struct trace_seq seq; @@ -806,6 +810,7 @@ struct sort_entry sort_trace =3D { .se_snprintf =3D hist_entry__trace_snprintf, .se_width_idx =3D HISTC_TRACE, }; +#endif /* HAVE_LIBTRACEEVENT */ =20 /* sort keys for branch stacks */ =20 @@ -2022,7 +2027,9 @@ static struct sort_dimension common_sort_dimensions[]= =3D { DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight), DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight), DIM(SORT_TRANSACTION, "transaction", sort_transaction), +#ifdef HAVE_LIBTRACEEVENT DIM(SORT_TRACE, "trace", sort_trace), +#endif DIM(SORT_SYM_SIZE, "symbol_size", sort_sym_size), DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size), DIM(SORT_CGROUP, "cgroup", sort_cgroup), @@ -2206,7 +2213,14 @@ bool perf_hpp__is_ ## key ## _entry(struct perf_hpp_= fmt *fmt) \ return hse->se =3D=3D &sort_ ## key ; \ } =20 +#ifdef HAVE_LIBTRACEEVENT MK_SORT_ENTRY_CHK(trace) +#else +bool perf_hpp__is_trace_entry(struct perf_hpp_fmt *fmt __maybe_unused) +{ + return false; +} +#endif MK_SORT_ENTRY_CHK(srcline) MK_SORT_ENTRY_CHK(srcfile) MK_SORT_ENTRY_CHK(thread) @@ -2347,6 +2361,17 @@ static int __sort_dimension__add_hpp_output(struct s= ort_dimension *sd, return 0; } =20 +#ifndef HAVE_LIBTRACEEVENT +bool perf_hpp__is_dynamic_entry(struct perf_hpp_fmt *fmt __maybe_unused) +{ + return false; +} +bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt __maybe_unus= ed, + struct hists *hists __maybe_unused) +{ + return false; +} +#else struct hpp_dynamic_entry { struct perf_hpp_fmt hpp; struct evsel *evsel; @@ -2621,6 +2646,7 @@ __alloc_dynamic_entry(struct evsel *evsel, struct tep= _format_field *field, =20 return hde; } +#endif /* HAVE_LIBTRACEEVENT */ =20 struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hpp_fmt *fmt) { @@ -2633,6 +2659,7 @@ struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hp= p_fmt *fmt) new_hse =3D memdup(hse, sizeof(*hse)); if (new_hse) new_fmt =3D &new_hse->hpp; +#ifdef HAVE_LIBTRACEEVENT } else if (perf_hpp__is_dynamic_entry(fmt)) { struct hpp_dynamic_entry *hde, *new_hde; =20 @@ -2640,6 +2667,7 @@ struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hp= p_fmt *fmt) new_hde =3D memdup(hde, sizeof(*hde)); if (new_hde) new_fmt =3D &new_hde->hpp; +#endif } else { new_fmt =3D memdup(fmt, sizeof(*fmt)); } @@ -2719,6 +2747,7 @@ static struct evsel *find_evsel(struct evlist *evlist= , char *event_name) return evsel; } =20 +#ifdef HAVE_LIBTRACEEVENT static int __dynamic_dimension__add(struct evsel *evsel, struct tep_format_field *field, bool raw_trace, int level) @@ -2789,13 +2818,13 @@ static int add_all_matching_fields(struct evlist *e= vlist, } return ret; } +#endif /* HAVE_LIBTRACEEVENT */ =20 static int add_dynamic_entry(struct evlist *evlist, const char *tok, int level) { char *str, *event_name, *field_name, *opt_name; struct evsel *evsel; - struct tep_format_field *field; bool raw_trace =3D symbol_conf.raw_trace; int ret =3D 0; =20 @@ -2820,6 +2849,7 @@ static int add_dynamic_entry(struct evlist *evlist, c= onst char *tok, raw_trace =3D true; } =20 +#ifdef HAVE_LIBTRACEEVENT if (!strcmp(field_name, "trace_fields")) { ret =3D add_all_dynamic_fields(evlist, raw_trace, level); goto out; @@ -2829,6 +2859,7 @@ static int add_dynamic_entry(struct evlist *evlist, c= onst char *tok, ret =3D add_all_matching_fields(evlist, field_name, raw_trace, level); goto out; } +#endif =20 evsel =3D find_evsel(evlist, event_name); if (evsel =3D=3D NULL) { @@ -2843,10 +2874,12 @@ static int add_dynamic_entry(struct evlist *evlist,= const char *tok, goto out; } =20 +#ifdef HAVE_LIBTRACEEVENT if (!strcmp(field_name, "*")) { ret =3D add_evsel_fields(evsel, raw_trace, level); } else { - field =3D tep_find_any_field(evsel->tp_format, field_name); + struct tep_format_field *field =3D tep_find_any_field(evsel->tp_format, = field_name); + if (field =3D=3D NULL) { pr_debug("Cannot find event field for %s.%s\n", event_name, field_name); @@ -2855,6 +2888,10 @@ static int add_dynamic_entry(struct evlist *evlist, = const char *tok, =20 ret =3D __dynamic_dimension__add(evsel, field, raw_trace, level); } +#else + (void)level; + (void)raw_trace; +#endif /* HAVE_LIBTRACEEVENT */ =20 out: free(str); @@ -2955,11 +2992,11 @@ int sort_dimension__add(struct perf_hpp_list *list,= const char *tok, for (i =3D 0; i < ARRAY_SIZE(common_sort_dimensions); i++) { struct sort_dimension *sd =3D &common_sort_dimensions[i]; =20 - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; =20 for (j =3D 0; j < ARRAY_SIZE(dynamic_headers); j++) { - if (!strcmp(dynamic_headers[j], sd->name)) + if (sd->name && !strcmp(dynamic_headers[j], sd->name)) sort_dimension_add_dynamic_header(sd); } =20 @@ -3009,7 +3046,7 @@ int sort_dimension__add(struct perf_hpp_list *list, c= onst char *tok, for (i =3D 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) { struct sort_dimension *sd =3D &bstack_sort_dimensions[i]; =20 - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; =20 if (sort__mode !=3D SORT_MODE__BRANCH) @@ -3025,7 +3062,7 @@ int sort_dimension__add(struct perf_hpp_list *list, c= onst char *tok, for (i =3D 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) { struct sort_dimension *sd =3D &memory_sort_dimensions[i]; =20 - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; =20 if (sort__mode !=3D SORT_MODE__MEMORY) @@ -3339,7 +3376,7 @@ int output_field_add(struct perf_hpp_list *list, char= *tok) for (i =3D 0; i < ARRAY_SIZE(common_sort_dimensions); i++) { struct sort_dimension *sd =3D &common_sort_dimensions[i]; =20 - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; =20 return __sort_dimension__add_output(list, sd); @@ -3357,7 +3394,7 @@ int output_field_add(struct perf_hpp_list *list, char= *tok) for (i =3D 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) { struct sort_dimension *sd =3D &bstack_sort_dimensions[i]; =20 - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; =20 if (sort__mode !=3D SORT_MODE__BRANCH) @@ -3369,7 +3406,7 @@ int output_field_add(struct perf_hpp_list *list, char= *tok) for (i =3D 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) { struct sort_dimension *sd =3D &memory_sort_dimensions[i]; =20 - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; =20 if (sort__mode !=3D SORT_MODE__MEMORY) @@ -3508,6 +3545,9 @@ void reset_output_field(void) =20 static void add_key(struct strbuf *sb, const char *str, int *llen) { + if (!str) + return; + if (*llen >=3D 75) { strbuf_addstr(sb, "\n\t\t\t "); *llen =3D INDENT; diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index 0645795ff080..3ab6a92b1a6d 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -2157,6 +2157,7 @@ int perf_event__synthesize_attr(struct perf_tool *too= l, struct perf_event_attr * return err; } =20 +#ifdef HAVE_LIBTRACEEVENT int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, st= ruct evlist *evlist, perf_event__handler_t process) { @@ -2203,6 +2204,7 @@ int perf_event__synthesize_tracing_data(struct perf_t= ool *tool, int fd, struct e =20 return aligned_size; } +#endif =20 int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *po= s, u16 misc, perf_event__handler_t process, struct machine *machine) @@ -2355,6 +2357,7 @@ int perf_event__synthesize_for_pipe(struct perf_tool = *tool, } ret +=3D err; =20 +#ifdef HAVE_LIBTRACEEVENT if (have_tracepoints(&evlist->core.entries)) { int fd =3D perf_data__fd(data); =20 @@ -2374,6 +2377,9 @@ int perf_event__synthesize_for_pipe(struct perf_tool = *tool, } ret +=3D err; } +#else + (void)data; +#endif =20 return ret; } diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-ev= ent-parse.c index c9c83a40647c..2d3c2576bab7 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -11,6 +11,8 @@ #include "trace-event.h" =20 #include +#include +#include =20 static int get_common_field(struct scripting_context *context, int *offset, int *size, const char *type) diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-eve= nt-read.c index 43146a4ce2fb..1162c49b8082 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trac= e-event-scripting.c index 636a010d929b..56175c53f9af 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -9,6 +9,7 @@ #include #include #include +#include =20 #include "debug.h" #include "trace-event.h" diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c index b3ee651e3d91..8ad75b31e09b 100644 --- a/tools/perf/util/trace-event.c +++ b/tools/perf/util/trace-event.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 - #include #include #include diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 8f39f5bcb2c2..add6c5d9531c 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -2,9 +2,11 @@ #ifndef _PERF_UTIL_TRACE_EVENT_H #define _PERF_UTIL_TRACE_EVENT_H =20 -#include -#include "parse-events.h" +#include +#include +#include =20 +struct evlist; struct machine; struct perf_sample; union perf_event; @@ -18,6 +20,11 @@ struct trace_event { struct tep_plugin_list *plugin_list; }; =20 +typedef char *(tep_func_resolver_t)(void *priv, + unsigned long long *addrp, char **modp); + +bool have_tracepoints(struct list_head *evlist); + int trace_event__init(struct trace_event *t); void trace_event__cleanup(struct trace_event *t); int trace_event__register_resolver(struct machine *machine, --=20 2.38.1.584.g0f3c55d4c2-goog From nobody Fri Sep 19 02:34:17 2025 Return-Path: Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 165E5C433FE for ; Wed, 30 Nov 2022 06:30:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234374AbiK3Gam (ORCPT ); Wed, 30 Nov 2022 01:30:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234218AbiK3GaT (ORCPT ); Wed, 30 Nov 2022 01:30:19 -0500 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2FE4B654EA for ; Tue, 29 Nov 2022 22:30:18 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id e15-20020a5b0ccf000000b006ed1704b40cso15423997ybr.5 for ; Tue, 29 Nov 2022 22:30:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=t1pc0o3pP7TbZ36uCNhwDWRPbRkSvbVebEwh+7WxCbc=; b=atXjXT6+oAexD6nQIS1DsZfTPBXfL5MSliAy/E8sLtovr0hYfvMoSDMfpQTf2V0iZV p/zwry0yZ06YsaZJdJfIdhrFjt0vhYaOJmDiJN5fHw60QgEkpvNtDBDw1/mAPAyIQcAC We/OUtUTjYlFstYbS2os7ShMDS3u/ptYGvAXah8xKZvAM6MWSEq2umewivnwykZvXv6H 2j0Dolzvb8ONuE80uoavXOQ/8SHaHmf8o5mnFwh9qUGLbmzsJaS0AaqCy0GH7inWTAT9 NXdm2q/rZaLrPy05WXO1bwcXUClCcKZh8Q2qzdTL7/p6OKSNR9wp9sovLOtc+6uu8BAf T4Yg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=t1pc0o3pP7TbZ36uCNhwDWRPbRkSvbVebEwh+7WxCbc=; b=E5BH6P9iG3rtp0VlFEsTAi6/7HRLjG/mz7gRvz3T720WaGDRiswZ2TbCYaHNv6YEIq +HXn2oksGbXO+nHvs1Q0nSXDe4JpXSaKqyhoKd/dTSvWqRnzkl+t75nrUFP5GVqD+mDz oLRmvG+S5HNWGyMro0sOfUOkkObDFIYkz01LwGXM3sFfIaCfvV3regwPWC7ZC+lAzfUe mkUzSUNK+nWxnm+NaOPShn2yfrQyYylesVhY8afTIwIRz8vhAJqUy0vPqjr7yHGO1cPa FdV8c4RB6eI/6QE1xbm3ZNnZAZwh81wdGTuMN8GhdrDJwyO3KwD3GdVp+9ed7+HN9ZZX VNfw== X-Gm-Message-State: ANoB5pmq7vv8Bi/JaQeQCdPnjo69hb9PqAHOe6dzPkejwxAyU1XVWzqe 21Q9IpnlnTSEVDiaPpuyEt0OWZB7OsMu X-Google-Smtp-Source: AA0mqf7U5deAbGUEPBd+BqsFciE6RgD702yXgdSXH0snG2qLiQFrtK+ZRbPgT/Diq9K42etu7c3HFRwyu4MC X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:788c:ccf4:3670:3362]) (user=irogers job=sendgmr) by 2002:a5b:c4d:0:b0:6f8:775:78a6 with SMTP id d13-20020a5b0c4d000000b006f8077578a6mr9259234ybr.507.1669789817377; Tue, 29 Nov 2022 22:30:17 -0800 (PST) Date: Tue, 29 Nov 2022 22:29:35 -0800 In-Reply-To: <20221130062935.2219247-1-irogers@google.com> Message-Id: <20221130062935.2219247-5-irogers@google.com> Mime-Version: 1.0 References: <20221130062935.2219247-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog Subject: [PATCH v2 4/4] tools lib traceevent: Remove libtraceevent From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , 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 Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. 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-comman= ds.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-cpus.t= xt 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_e= ndian.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-filter= .txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-func_a= pis.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-func_f= ind.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_e= ndian.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-long_s= ize.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-page_s= ize.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-plugin= s.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-record= _parse.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-reg_ev= ent_handler.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-reg_pr= int_func.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-set_fl= ag.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-strerr= or.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-tseq.t= xt 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/.gitign= ore 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 +=3D event-parse.o -libtraceevent-y +=3D event-plugin.o -libtraceevent-y +=3D trace-seq.o -libtraceevent-y +=3D parse-filter.o -libtraceevent-y +=3D parse-utils.o -libtraceevent-y +=3D kbuffer-parse.o -libtraceevent-y +=3D tep_strerror.o -libtraceevent-y +=3D event-parse-api.o diff --git a/tools/lib/traceevent/Documentation/Makefile b/tools/lib/tracee= vent/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/Documenta= tion -# and modified for libtraceevent. - -MAN3_TXT=3D \ - $(wildcard libtraceevent-*.txt) \ - libtraceevent.txt - -MAN_TXT =3D $(MAN3_TXT) -_MAN_XML=3D$(patsubst %.txt,%.xml,$(MAN_TXT)) -_MAN_HTML=3D$(patsubst %.txt,%.html,$(MAN_TXT)) -_DOC_MAN3=3D$(patsubst %.txt,%.3,$(MAN3_TXT)) - -MAN_XML=3D$(addprefix $(OUTPUT),$(_MAN_XML)) -MAN_HTML=3D$(addprefix $(OUTPUT),$(_MAN_HTML)) -DOC_MAN3=3D$(addprefix $(OUTPUT),$(_DOC_MAN3)) - -# Make the path relative to DESTDIR, not prefix -ifndef DESTDIR -prefix?=3D$(HOME) -endif -bindir?=3D$(prefix)/bin -htmldir?=3D$(prefix)/share/doc/libtraceevent-doc -pdfdir?=3D$(prefix)/share/doc/libtraceevent-doc -mandir?=3D$(prefix)/share/man -man3dir=3D$(mandir)/man3 - -ASCIIDOC=3Dasciidoc -ASCIIDOC_EXTRA =3D --unsafe -f asciidoc.conf -ASCIIDOC_HTML =3D xhtml11 -MANPAGE_XSL =3D manpage-normal.xsl -XMLTO_EXTRA =3D -INSTALL?=3Dinstall -RM ?=3D rm -f - -ifdef USE_ASCIIDOCTOR -ASCIIDOC =3D asciidoctor -ASCIIDOC_EXTRA =3D -a compat-mode -ASCIIDOC_EXTRA +=3D -I. -rasciidoctor-extensions -ASCIIDOC_EXTRA +=3D -a mansource=3D"libtraceevent" -a manmanual=3D"libtrac= eevent Manual" -ASCIIDOC_HTML =3D xhtml5 -endif - -XMLTO=3Dxmlto - -_tmp_tool_path :=3D $(call get-executable,$(ASCIIDOC)) -ifeq ($(_tmp_tool_path),) - missing_tools =3D $(ASCIIDOC) -endif - -ifndef USE_ASCIIDOCTOR -_tmp_tool_path :=3D $(call get-executable,$(XMLTO)) -ifeq ($(_tmp_tool_path),) - missing_tools +=3D $(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 +=3D -a asciidoc7compatible -endif -ifdef DOCBOOK_XSL_172 -ASCIIDOC_EXTRA +=3D -a libtraceevent-asciidoc-no-roff -MANPAGE_XSL =3D 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 +=3D -a libtraceevent-asciidoc-no-roff - endif -endif -ifdef MAN_BOLD_LITERAL -XMLTO_EXTRA +=3D -m manpage-bold-literal.xsl -endif -ifdef DOCBOOK_SUPPRESS_SP -XMLTO_EXTRA +=3D -m manpage-suppress-sp.xsl -endif - -SHELL_PATH ?=3D $(SHELL) -# Shell quote; -SHELL_PATH_SQ =3D $(subst ','\'',$(SHELL_PATH)) - -DESTDIR ?=3D -DESTDIR_SQ =3D '$(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=3Dlibtraceevent&m=3D111558757202243&w= =3D2 -# -# Until that version is released you may have to apply the patch -# yourself - yes, all 6 characters of it! -# -QUIET_SUBDIR0 =3D +$(MAKE) -C # space to separate -C and subdir -QUIET_SUBDIR1 =3D - -ifneq ($(findstring $(MAKEFLAGS),w),w) -PRINT_DIR =3D --no-print-directory -else # "make -w" -NO_SUBDIR =3D : -endif - -ifneq ($(findstring $(MAKEFLAGS),s),s) -ifneq ($(V),1) - QUIET_ASCIIDOC =3D @echo ' ASCIIDOC '$@; - QUIET_XMLTO =3D @echo ' XMLTO '$@; - QUIET_SUBDIR0 =3D +@subdir=3D - QUIET_SUBDIR1 =3D ;$(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 =3D $(warning Please install $(missing_tools) to have the= man pages installed) -else - DO_INSTALL_MAN =3D do-install-man -endif - -CLEAN_FILES =3D \ - $(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=3D$(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=3D$(EVENT_PARSE_VERSION) -o $@= + $< && \ - mv $@+ $@ - -$(MAN_HTML): $(OUTPUT)%.html : %.txt - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ - $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage \ - $(ASCIIDOC_EXTRA) -aperf_version=3D$(EVENT_PARSE_VERSION) -o $@+ $< && \ - mv $@+ $@ diff --git a/tools/lib/traceevent/Documentation/asciidoc.conf b/tools/lib/t= raceevent/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.*?)\]=3D - -[attributes] -asterisk=3D* -plus=3D+ -caret=3D^ -startsb=3D[ -endsb=3D] -tilde=3D~ - -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 th= is. -# 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 scre= en -[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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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:[*]_pev= ent_, 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 p= ass:[*]_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 mappin= g. -If a command with the same _pid_ is already registered, an error is return= ed. -The _pid_ argument is the process ID, the _comm_ argument is the process n= ame, -_tep_ is the event context. The _comm_ is duplicated internally. - -The _tep_override_comm()_ function registers a _pid_ / process name mappin= g. -If a process with the same pid is already registered, the process name str= ing 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 eve= nt -context. - -The _tep_data_comm_from_pid()_ function returns the process name for a giv= en -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 searc= h for -the next pid. If _next_ is NULL, it will return the first pid associated w= ith -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 th= is -_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 _cm= dline_ - 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 =3D 1021; -struct tep_handle *tep =3D tep_alloc(); -... - ret =3D tep_register_comm(tep, "ls", ls_pid); - if (ret !=3D 0 && errno =3D=3D EEXIST) - ret =3D tep_override_comm(tep, "ls", ls_pid); - if (ret !=3D 0) { - /* Failed to register pid / command mapping */ - } -... - if (tep_is_pid_registered(tep, ls_pid) =3D=3D 0) { - /* Command mapping for ls_pid is not registered */ - } -... - const char *comm =3D tep_data_comm_from_pid(tep, ls_pid); - if (comm) { - /* Found process name for ls_pid */ - } -... - int pid; - struct cmdline *cmd =3D tep_data_pid_from_comm(tep, "ls", NULL); - while (cmd) { - pid =3D tep_cmdline_pid(tep, cmd); - /* Found pid for process "ls" */ - cmd =3D 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/to= ols/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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_get_cpus, tep_set_cpus - Get / set the number of CPUs, which have a tr= acing -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 trac= ing -data recorded. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep =3D 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.t= xt 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_read_number - Reads a number from raw data. - -SYNOPSIS --------- -[verse] --- -*#include * - -unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, cons= t void pass:[*]_ptr_, int _size_); --- - -DESCRIPTION ------------ -The _tep_read_number()_ function reads an integer from raw data, taking in= to -account the endianness of the raw data and the current host. The _tep_ arg= ument -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 =3D tep_alloc(); -... -void process_record(struct tep_record *record) -{ - int offset =3D 24; - int data =3D 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.tx= t 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 =3D tep_alloc(); -... -struct tep_event *event; - -event =3D tep_find_event(tep, 1857); -if (event =3D=3D NULL) { - /* There is no event with ID 1857 */ -} - -event =3D tep_find_event_by_name(tep, "kvm", "kvm_exit"); -if (event =3D=3D NULL) { - /* There is no kvm_exit event, from kvm system */ -} - -void event_from_record(struct tep_record *record) -{ - struct tep_event *event =3D tep_find_event_by_record(tep, record); - if (event =3D=3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 _in= dex_. -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 =3D tep_alloc(); -... -int i,count =3D tep_get_events_count(tep); -struct tep_event *event, *events =3D tep_get_first_event(tep); - -if (events =3D=3D NULL) { - /* There are no events */ -} else { - for (i =3D 0; i < count; i++) { - event =3D (events+i); - /* process events[i] */ - } - - /* Get the last event */ - event =3D 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.tx= t 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 event= s, -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 a= nd -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 free= d, -it is managed by the library. - -The _tep_list_events_copy()_ function returns an array of pointers to even= ts. -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 =3D tep_alloc(); -... -int i; -struct tep_event_format **events; - -i=3D0; -events =3D tep_list_events(tep, TEP_EVENT_SORT_ID); -if (events =3D=3D 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=3D0; -events =3D tep_list_events_copy(tep, TEP_EVENT_SORT_NAME); -if (events =3D=3D 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.t= xt 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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_seqpa= ss:[*]_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 =3D 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 functi= ons - 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.tx= t 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 p= ass:[*]_event_, const char pass:[*]_name_); -struct tep_format_field pass:[*]*tep_find_field*(struct tep_event_ormat pa= ss:[*]_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 _n= ame_ -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 =3D tep_find_event_by_name(tep, "timer", "hrtimer_start"); - - field =3D tep_find_common_field(event, "common_pid"); - if (field =3D=3D NULL) { - /* Cannot find "common_pid" field in the event */ - } else { - /* Get pid from the data record */ - pid =3D tep_read_number(tep, record->data + field->offset, - field->size); - } - - field =3D tep_find_field(event, "softexpires"); - if (field =3D=3D NULL) { - /* Cannot find "softexpires" event specific field in the event */ - } else { - /* Get softexpires parameter from the data record */ - softexpires =3D tep_read_number(tep, record->data + field->offset, - field->size); - } - - field =3D tep_find_any_field(event, "mode"); - if (field =3D=3D NULL) { - /* Cannot find "mode" field in the event */ - } else - { - /* Get mode parameter from the data record */ - mode =3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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:[*]_rec= ord_, unsigned long long pass:[*]_val_, int _err_); -int *tep_get_common_field_val*(struct trace_seq pass:[*]_s_, struct tep_ev= ent 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 pas= s:[*]_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 stor= ed 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 wo= rks -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 wi= th -_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 store= d 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 e= rror. - -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 retur= ned. - -EXAMPLE -------- -[source,c] --- -#include -#include -... -struct tep_handle *tep =3D tep_alloc(); -... -struct tep_event *event =3D 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 =3D tep_find_event_by_record(pevent, record); - if (event !=3D NULL) { - if (tep_get_common_field_val(NULL, event, "common_type", - record, &val, 0) =3D=3D 0) { - /* Got the value of common type field */ - } - if (tep_get_field_val(NULL, event, "pid", record, &val, 0) =3D=3D 0) { - /* Got the value of pid specific field */ - } - comm =3D tep_get_field_raw(NULL, event, "comm", record, &len, 0); - if (comm !=3D 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.t= xt 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_print_field, tep_print_fields, tep_print_num_field, tep_print_func_fie= ld - -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_, struc= t 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_ val= ue 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 f= ield -value according to the field's type: -[verse] --- -"field1_name=3Dfield1_value field2_name=3Dfield2_value ..." --- -It iterates all fields of the _event_, and calls _tep_print_field()_ for e= ach of -them. - -The _tep_print_num_field()_ function prints a numeric field with given for= mat -string. A search is performed in the _event_ for a field with _name_. If s= uch -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 f= ormat -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 ass= umed -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-z= ero, -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 =3D tep_alloc(); -... -struct trace_seq seq; -trace_seq_init(&seq); -struct tep_event *event =3D tep_find_event_by_name(tep, "timer", "hrtimer_= start"); -... -void process_record(struct tep_record *record) -{ - struct tep_format_field *field_pid =3D tep_find_common_field(event, "comm= on_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", re= cord, 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", r= ecord, 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 functi= ons - 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.tx= t 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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_ acc= ording -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 =3D tep_alloc(); -... -struct tep_event *event =3D 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 =3D tep_find_common_field(event, "comm= on_pid"); - - if (tep_read_number_field(field_pid, record->data, &pid) !=3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_event_common_fields, tep_event_fields - Get a list of fields for an ev= ent. - -SYNOPSIS --------- -[verse] --- -*#include * - -struct tep_format_field pass:[*]pass:[*]*tep_event_common_fields*(struct t= ep_event pass:[*]_event_); -struct tep_format_field pass:[*]pass:[*]*tep_event_fields*(struct tep_even= t pass:[*]_event_); --- - -DESCRIPTION ------------ -The _tep_event_common_fields()_ function returns an array of pointers to c= ommon -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 sp= ecific -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 =3D tep_alloc(); -... -int i; -struct tep_format_field **fields; -struct tep_event *event =3D tep_find_event_by_name(tep, "kvm", "kvm_exit"); -if (event !=3D NULL) { - fields =3D tep_event_common_fields(event); - if (fields !=3D NULL) { - i =3D 0; - while (fields[i]) { - /* - walk through the list of the common fields - of the kvm_exit event - */ - i++; - } - free(fields); - } - fields =3D tep_event_fields(event); - if (fields !=3D NULL) { - i =3D 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.t= xt 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_is_file_bigendian, tep_set_file_bigendian - Get / set the endianness o= f the -raw data being accessed by the tep handler. - -SYNOPSIS --------- -[verse] --- -*#include * - -enum *tep_endian* { - TEP_LITTLE_ENDIAN =3D 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_en= dian _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 be= ing -accessed by the tep handler. The _tep_ argument is trace event parser cont= ext. -[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 bige= ndian -format, false otherwise. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep =3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_filter_alloc, tep_filter_free, tep_filter_reset, tep_filter_make_strin= g, -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 _ev= ent_id_); -int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, in= t _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_e= vent_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:[*]_fil= ter_, int _event_id_); -int *tep_filter_strerror*(struct tep_event_filter pass:[*]_filter_, enum t= ep_errno _err_, char pass:[*]buf, size_t _buflen_); --- - -DESCRIPTION ------------ -Filters can be attached to traced events. They can be used to filter out v= arious -events when outputting them. Each event can be filtered based on its param= eters, -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_ ar= gument -is the trace event parser context. - -The _tep_filter_free()_ function frees an event filter and all resources t= hat it -had used. - -The _tep_filter_reset()_ function removes all rules from an event filter a= nd -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 w= ith -_event_id_. - -The _tep_filter_match()_ function tests if a _record_ matches given _filte= r_. - -The _tep_filter_copy()_ function copies a _source_ filter into a _dest_ fi= lter. - -The _tep_filter_compare()_ function compares two filers - _filter1_ and _f= ilter2_. - -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 e= vent -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 g= iven -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 re= sult: -[verse] --- -_pass:[TEP_ERRNO__FILTER_MATCH]_ - filter found for event, the record matc= hes. -_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 rul= es - 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 fr= eed -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 =3D tep_alloc(); -... -char errstr[200]; -int ret; - -struct tep_event_filter *filter =3D tep_filter_alloc(tep); -struct tep_event_filter *filter1 =3D tep_filter_alloc(tep); -ret =3D tep_filter_add_filter_str(filter, "sched/sched_wakeup:target_cpu= =3D=3D1"); -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) !=3D 0) { - /* Failed to copy filter in filter1 */ -} -... -if (tep_filter_compare(filter, filter1) !=3D 1) { - /* Both filters are different */ -} -... -void process_record(struct tep_handle *tep, struct tep_record *record) -{ - struct tep_event *event; - char *fstring; - - event =3D tep_find_event_by_record(tep, record); - - if (tep_event_filtered(filter, event->id) =3D=3D 1) { - /* The event has filter */ - fstring =3D tep_filter_make_string(filter, event->id); - if (fstring !=3D 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) =3D=3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_find_function, tep_find_function_address, tep_set_function_resolver, -tep_reset_function_resolver, tep_register_function, tep_register_print_str= ing - -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_, un= signed 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 cha= r pass:[*]_fmt_, unsigned long long _addr_); --- - -DESCRIPTION ------------ -Some tools may have already a way to resolve the kernel functions. These A= PIs -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 ke= rnel -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 alternat= ive -kernel functions resolver. The _tep_ argument is trace event parser contex= t. -The _priv_ argument is a custom context of the _func_ function. The functi= on -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 contai= ns the -given address _addr_. The _tep_ argument is the trace event parser context. - -The _tep_find_function_address()_ function returns the function start addr= ess, -by given address _addr_. The _addr_ does not have to be exact, it will sel= ect -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 t= racer -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 t= he -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 addr= ess -it was stored in the kernel. Some strings internal to the kernel with stat= ic -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. T= he -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, o= r -1 -in case of an error. - -The _tep_find_function()_ function returns the function name, or NULL in c= ase -it cannot be found. - -The _tep_find_function_address()_ function returns the function start addr= ess, -or 0 in case it cannot be found. - -The _tep_register_function()_ function returns 0 in case of success. In ca= se 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. I= n case -of an error -1 is returned, and errno is set to the appropriate error numb= er. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep =3D tep_alloc(); -... -char *my_resolve_kernel_addr(void *context, - unsigned long long *addrp, char **modp) -{ - struct db *function_database =3D context; - struct symbol *sym =3D sql_lookup(function_database, *addrp); - - if (!sym) - return NULL; - - *modp =3D 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) !=3D 0) { - /* failed to register my_resolve_kernel_addr */ - } - - /* These APIs use my_resolve_kernel_addr() to resolve the addr */ - fname =3D tep_find_function(tep, addr); - fstart =3D 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") !=3D 0) { - /* Failed to register kvm_exit address mapping */ - } -... - if (tep_register_print_string(tep, "print string", - (unsigned long long) 0x87654321, NULL) !=3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_find_function,tep_find_function_address - Find function name / start a= ddress. - -SYNOPSIS --------- -[verse] --- -*#include * - -const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, un= signed 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 gi= ven -address. The given address does not have to be exact, it will select the f= unction -that would contain it. - -The _tep_find_function()_ function returns the function name, which contai= ns the -given address _addr_. The _tep_ argument is the trace event parser context. - -The _tep_find_function_address()_ function returns the function start addr= ess, -by given address _addr_. The _addr_ does not have to be exact, it will sel= ect the -function that would contain it. The _tep_ argument is the trace event pars= er context. - -RETURN VALUE ------------- -The _tep_find_function()_ function returns the function name, or NULL in c= ase -it cannot be found. - -The _tep_find_function_address()_ function returns the function start addr= ess, -or 0 in case it cannot be found. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep =3D tep_alloc(); -... -void show_function( unsigned long long addr) -{ - const char *fname =3D tep_find_function(tep, addr); - unsigned long long fstart =3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_alloc, tep_free,tep_ref, tep_unref,tep_get_ref - Create, destroy, mana= ge -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 us= ed 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_ handle= r. -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 t= hat -it had used are cleaned up. - -The _tep_ref_get()_ functions gets the current references of the _tep_ han= dler. - -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 =3D tep_alloc(); -... -int ref =3D tep_get_ref(tep); -tep_ref(tep); -if ( (ref+1) !=3D 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.t= xt 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 v= alues -from user space context are used. - -The _tep_get_header_page_size()_ function returns the size of a long integ= er, -in kernel context. The _tep_ argument is trace event parser context. -This information is retrieved from tracefs events/header_page, "commit" fi= eld. - -The _tep_get_header_timestamp_size()_ function returns the size of timesta= mps, -in kernel context. The _tep_ argument is trace event parser context. This -information is retrieved from tracefs events/header_page, "timestamp" fiel= d. - -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 integ= er, -in bytes. - -The _tep_get_header_timestamp_size()_ function returns the size of timesta= mps, -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 i= s new, -or _tep_ is NULL, false is returned. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep =3D tep_alloc(); -... - int longsize; - int timesize; - bool old; - - longsize =3D tep_get_header_page_size(tep); - timesize =3D tep_get_header_timestamp_size(tep); - old =3D 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.t= xt 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 =3D 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_e= ndian _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 con= text. -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 otherwi= se. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep =3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_get_long_size, tep_set_long_size - Get / set the size of a long intege= r 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 t= he machine, -where the trace is generated. The _tep_ argument is trace event parser con= text. - -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 con= text. -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 t= he machine, -where the trace is generated, in bytes. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep =3D tep_alloc(); -... -tep_set_long_size(tep, 4); -... -int long_size =3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 byt= es. - -EXAMPLE -------- -[source,c] --- -#include -#include -... -struct tep_handle *tep =3D tep_alloc(); -... - int page_size =3D 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.t= xt 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 ch= ar 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 ev= ent -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 t= he -_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()_. Th= e 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 su= ccess, -or TEP_ERRNO__... in case of an error. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep =3D tep_alloc(); -... -char *buf; -int size; -struct tep_event *event =3D NULL; -buf =3D read_file("/sys/kernel/tracing/events/ftrace/print/format", &size); -if (tep_parse_event(tep, buf, size, "ftrace") !=3D 0) { - /* Failed to parse the ftrace print format */ -} - -if (tep_parse_format(tep, &event, buf, size, "ftrace") !=3D 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.tx= t 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 _b= uf_, -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 u= sed 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 =3D tep_alloc(); -... -char *buf; -int size; -buf =3D read_file("/sys/kernel/tracing/events/header_page", &size); -if (tep_parse_header_page(tep, buf, size, sizeof(unsigned long)) !=3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_load_plugins, tep_unload_plugins, tep_load_plugins_hook - Load / unloa= d 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_, st= ruct tep_handle pass:[*]_tep_); -void *tep_load_plugins_hook*(struct tep_handle pass:[*]_tep_, const char p= ass:[*]_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_F= IRST - - 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_L= AST --- -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 pl= ugins -and calls user specified _load_plugin()_ hook for each plugin file. Only f= iles -with given _suffix_ are considered to be plugins. The _data_ is a user spe= cified -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 pl= ugins, -or NULL in case no plugins are loaded. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep =3D tep_alloc(); -... -struct tep_plugin_list *plugins =3D tep_load_plugins(tep); -if (plugins =3D=3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 pas= s:[*]_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_r= ecord pass:[*]_rec_); -int *tep_data_flags*(struct tep_handle pass:[*]_tep_, struct tep_record pa= ss:[*]_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 pa= rser -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 par= ser -context. - -The _tep_data_preempt_count()_ function gets the preemption count from the -record _rec_. It reads the "common_preempt_count" field. The _tep_ argumen= t is -the trace event parser context. - -The _tep_data_flags()_ function gets the latency flags from the record _re= c_. -It reads the "common_flags" field. The _tep_ argument is the trace event p= arser -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 arc= hitecture. - _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 t= he -preemption count. - -The _tep_data_flags()_ function returns an integer, representing the laten= cy -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 =3D tep_alloc(); -... -void process_record(struct tep_record *record) -{ - int data; - - data =3D tep_data_type(tep, record); - if (data >=3D 0) { - /* Got the ID of the event */ - } - - data =3D tep_data_pid(tep, record); - if (data >=3D 0) { - /* Got the process ID */ - } - - data =3D tep_data_preempt_count(tep, record); - if (data >=3D 0) { - /* Got the preemption count */ - } - - data =3D tep_data_flags(tep, record); - if (data >=3D 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_han= dler.txt b/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handl= er.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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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_handl= er_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 pas= s:[*]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 >=3D 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 g= oing -to be called to parse the event information. The _context_ argument is a p= ointer -to the context data, which will be passed to the _func_. If a handler func= tion -for the same event is already registered, it will be overridden with the n= ew -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 develop= er -can register a function for an event to be used to parse the data instead. - -The _tep_unregister_event_handler()_ function unregisters the handler func= tion, -previously registered with _tep_register_event_handler()_. The _tep_ argum= ent -is the trace event parser context. The _id_, _sys_name_, _event_name_, _fu= nc_, -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 register= ed. - -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 remo= ved -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 =3D 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=3D"); - - if (tep_print_num_field(s, "0x%llx", event, "timer", record, 0) =3D=3D -1) - tep_print_num_field(s, "0x%llx", event, "hrtimer", record, 1); - - trace_seq_printf(s, " now=3D"); - - tep_print_num_field(s, "%llu", event, "now", record, 1); - - tep_print_func_field(s, " function=3D%s", event, "function", record, 0); - - return 0; -} -... - int ret; - - ret =3D tep_register_event_handler(tep, -1, "timer", "hrtimer_expire_entr= y", - 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 =3D tep_unregister_event_handler(tep, -1, "timer", "hrtimer_expire_en= try", - 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_fun= c.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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 p= ass:[*]s, unsigned long long pass:[*]args); - -int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_fun= c_handler _func_, enum tep_func_arg_type _ret_type_, char pass:[*]_name_, _= ..._); -int *tep_unregister_print_function*(struct tep_handle pass:[*]_tep_, tep_f= unc_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 _t= ep_ -argument is the trace event parser context. The _func_ argument is a poin= ter -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 th= e name -of the helper function, as seen in the print format arguments. The _..._ i= s 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, previ= ously -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_ argumen= t 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=3D%u, scanline=3D%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 =3D "yes"; - static const char *no =3D "no"; - - return x ? yes : no; -} --- -The user space event parser has no idea how to handle this _yesno()_ funct= ion. -The _tep_register_print_function()_ API can be used to register a user spa= ce -helper function, mapped to the kernel's _yesno()_: -[source,c] --- -#include -#include -... -struct tep_handle *tep =3D 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) !=3D 0) { - /* Failed to register yes_no_helper function */ - } - -/* - Now, when the event parser encounters this yesno() function, it will kn= ow - how to handle it. -*/ -... - if (tep_unregister_print_function(tep, yes_no_helper, "yesno") !=3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 mi= cro 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 =3D 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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -NAME ----- -tep_strerror - Returns a string describing regular errno and tep error num= ber. - -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 t= his -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 alw= ays -behaves as the POSIX version - the error string is copied in the user supp= lied -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 =3D tep_alloc(); -... -char buf[32]; -char *pool =3D calloc(1, 128); -if (tep =3D=3D 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/to= ols/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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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:[*]_f= mt_, _..._); -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 functio= ns -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 fre= es -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) <=3D 0) { - /* Failed to print in the trace sequence */ - } - va_end(ap); -} - -trace_seq_reset(&seq); - -char *str =3D " MAN page example"; -if (trace_seq_puts(&seq, str) !=3D strlen(str)) { - /* Failed to put str in the trace sequence */ -} -if (trace_seq_putc(&seq, ':') !=3D 1) { - /* Failed to put ':' in the trace sequence */ -} -if (trace_seq_printf(&seq, " trace sequence: %d", 1) <=3D 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 =3D 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/l= ib/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) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -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 _fla= g_); - bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag= s_); - 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 _errnu= m_, 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_even= t_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_hand= ler_func func, void pass:[*]_context_); - int *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const ch= ar pass:[*]_fmt_, unsigned long long _addr_); - int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_fu= nc_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_, s= truct 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:[*]_option= s_); - 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 pas= s:[*]_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 c= har 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 lon= g _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_eve= nt 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 pa= ss:[*]_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_e= vent 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_even= t pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_re= cord_, unsigned long long pass:[*]_val_, int _err_); - int *tep_read_number_field*(struct tep_format_field pass:[*]_field_, cons= t 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_, struc= t 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_, stru= ct 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 p= ass:[*]_event_, const char pass:[*]_name_); - struct tep_format_field pass:[*]*tep_find_any_field*(struct tep_event pas= s:[*]_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_, u= nsigned 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 _e= vent_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:[*]_fi= lter_, int _event_id_); - int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, i= nt _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_, struc= t tep_event_filter pass:[*]_filter2_); - -Parsing various data from the records: - int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pa= ss:[*]_rec_); - int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pas= s:[*]_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 p= ass:[*]_rec_); - -Command and task related APIs: - const char pass:[*]*tep_data_comm_from_pid*(struct tep_handle pass:[*]_te= p_, 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 pas= s:[*]_cmdline_); - -Endian related APIs: - int *tep_is_bigendian*(void); - unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, con= st 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_e= ndian _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:[*]_st= r_); - 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 eve= nts, -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 dir= ectory 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 functi= ons - 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/li= b/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 @@ - - - - - - - - - - diff --git a/tools/lib/traceevent/Documentation/manpage-base.xsl b/tools/li= b/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 @@ - - - - - - - - - - - - - - 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 @@ - - - - - - - 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 @@ - - - - - - -\ -. - - diff --git a/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl b/t= ools/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 @@ - - - - - - - - - - - - - - - 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 =3D 1 -EP_PATCHLEVEL =3D 1 -EP_EXTRAVERSION =3D 0 - -# file format version -FILE_VERSION =3D 6 - -MAKEFLAGS +=3D --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 ?=3D approach -# won't work as expected. -define allow-override - $(if $(or $(findstring environment,$(origin $(1))),\ - $(findstring command line,$(origin $(1)))),,\ - $(eval $(1) =3D $(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 =3D -std=3Dgnu99 -INSTALL =3D 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 ?=3D -DESTDIR_SQ =3D '$(subst ','\'',$(DESTDIR))' - -LP64 :=3D $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) -ifeq ($(LP64), 1) - libdir_relative_temp =3D lib64 -else - libdir_relative_temp =3D lib -endif - -libdir_relative ?=3D $(libdir_relative_temp) -prefix ?=3D /usr/local -libdir =3D $(prefix)/$(libdir_relative) -man_dir =3D $(prefix)/share/man -man_dir_SQ =3D '$(subst ','\'',$(man_dir))' -pkgconfig_dir ?=3D $(word 1,$(shell $(PKG_CONFIG) \ - --variable pc_path pkg-config | tr ":" " ")) -includedir_relative =3D traceevent -includedir =3D $(prefix)/include/$(includedir_relative) -includedir_SQ =3D '$(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 =3D $(V) -endif -ifndef VERBOSE - VERBOSE =3D 0 -endif - -ifeq ($(srctree),) -srctree :=3D $(patsubst %/,%,$(dir $(CURDIR))) -srctree :=3D $(patsubst %/,%,$(dir $(srctree))) -srctree :=3D $(patsubst %/,%,$(dir $(srctree))) -#$(info Determined 'srctree' to be $(srctree)) -endif - -export prefix libdir src obj - -# Shell quotes -libdir_SQ =3D $(subst ','\'',$(libdir)) -libdir_relative_SQ =3D $(subst ','\'',$(libdir_relative)) - -CONFIG_INCLUDES =3D=20 -CONFIG_LIBS =3D -CONFIG_FLAGS =3D - -VERSION =3D $(EP_VERSION) -PATCHLEVEL =3D $(EP_PATCHLEVEL) -EXTRAVERSION =3D $(EP_EXTRAVERSION) - -OBJ =3D $@ -N =3D - -EVENT_PARSE_VERSION =3D $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) - -LIB_TARGET =3D libtraceevent.a libtraceevent.so.$(EVENT_PARSE_VERSION) -LIB_INSTALL =3D libtraceevent.a libtraceevent.so* -LIB_INSTALL :=3D $(addprefix $(OUTPUT),$(LIB_INSTALL)) - -INCLUDES =3D -I. -I $(srctree)/tools/include $(CONFIG_INCLUDES) - -# Set compile option CFLAGS -ifdef EXTRA_CFLAGS - CFLAGS :=3D $(EXTRA_CFLAGS) -else - CFLAGS :=3D -g -Wall -endif - -# Append required CFLAGS -override CFLAGS +=3D -fPIC -override CFLAGS +=3D $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) -override CFLAGS +=3D $(udis86-flags) -D_GNU_SOURCE - -ifeq ($(VERBOSE),1) - Q =3D -else - Q =3D @ -endif - -# Disable command line variables (CFLAGS) override from top -# level Makefile (perf), otherwise build Makefile will get -# the same command line setup. -MAKEOVERRIDES=3D - -export srctree OUTPUT CC LD CFLAGS V -build :=3D -f $(srctree)/tools/build/Makefile.build dir=3D. obj - -TE_IN :=3D $(OUTPUT)libtraceevent-in.o -LIB_TARGET :=3D $(addprefix $(OUTPUT),$(LIB_TARGET)) - -CMD_TARGETS =3D $(LIB_TARGET) - -TARGETS =3D $(CMD_TARGETS) - -all: all_cmd plugins - -all_cmd: $(CMD_TARGETS) - -$(TE_IN): force - $(Q)$(MAKE) $(build)=3Dlibtraceevent - -$(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 =3D 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=3D+f --c-kinds=3D+px \ - --regex-c++=3D'/_PE\(([^,)]*).*/TEP_ERRNO__\1/' - -TAGS: force - $(RM) TAGS - find . -name '*.[ch]' | xargs etags \ - --regex=3D'/_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 =3D libtraceevent.pc -PKG_CONFIG_FILE :=3D $(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 +=3D doc -doc: - $(call descend,Documentation) - -PHONY +=3D doc-clean -doc-clean: - $(call descend,Documentation,clean) - -PHONY +=3D doc-install -doc-install: - $(call descend,Documentation,install) - -PHONY +=3D doc-uninstall -doc-uninstall: - $(call descend,Documentation,uninstall) - -PHONY +=3D 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 f= iles' - @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 +=3D plugins -plugins: - $(call descend,plugins) - -PHONY +=3D install_plugins -install_plugins: - $(call descend,plugins,install) - -PHONY +=3D 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 |=3D 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 &=3D ~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 =3D=3D tep->file_bigendian) - return data; - - swap =3D ((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 =3D=3D tep->file_bigendian) - return data; - - swap =3D ((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 =3D=3D tep->file_bigendian) - return data; - - swap =3D ((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 =3D 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 =3D 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 =3D _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 =3D=3D 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 =3D 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 =3D=3D 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 endia= n) -{ - if (tep) - tep->host_bigendian =3D 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 eve= nts or - * false if a new kernel is used. Old kernels did not have header page inf= o. - * 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 stri= ng - * instead of adding it. - */ -void tep_set_test_filters(struct tep_handle *tep, int test_filters) -{ - if (tep) - tep->test_filters =3D test_filters; -} diff --git a/tools/lib/traceevent/event-parse-local.h b/tools/lib/traceeven= t/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 d= ata); - -/* 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/even= t-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 =3D 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 =3D buf; - input_buf_siz =3D size; - input_buf_ptr =3D 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 =3D a; - const struct tep_cmdline *cb =3D 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 =3D a; - const struct tep_cmdline *cb =3D b; - const struct tep_cmdline *cb1 =3D cb + 1; - - if (ca->pid < cb->pid) - return -1; - - if (ca->pid > cb->pid) { - if (ca->pid <=3D 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 =3D tep->cmdlist; - struct cmdline_list *item; - struct tep_cmdline *cmdlines; - int i; - - cmdlines =3D malloc(sizeof(*cmdlines) * tep->cmdline_count); - if (!cmdlines) - return -1; - - i =3D 0; - while (cmdlist) { - cmdlines[i].pid =3D cmdlist->pid; - cmdlines[i].comm =3D cmdlist->comm; - i++; - item =3D cmdlist; - cmdlist =3D cmdlist->next; - free(item); - } - - qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp); - - tep->cmdlines =3D cmdlines; - tep->cmdlist =3D 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 =3D pid; - - comm =3D 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 =3D pid; - - comm =3D 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 =3D tep->cmdlines; - struct tep_cmdline *cmdline; - struct tep_cmdline key; - char *new_comm; - int cnt; - - if (!pid) - return 0; - - /* avoid duplicates */ - key.pid =3D pid; - - cmdline =3D bsearch(&key, tep->cmdlines, tep->cmdline_count, - sizeof(*tep->cmdlines), cmdline_cmp); - if (cmdline) { - if (!override) { - errno =3D EEXIST; - return -1; - } - new_comm =3D strdup(comm); - if (!new_comm) { - errno =3D ENOMEM; - return -1; - } - free(cmdline->comm); - cmdline->comm =3D new_comm; - - return 0; - } - - cmdlines =3D realloc(cmdlines, sizeof(*cmdlines) * (tep->cmdline_count + = 1)); - if (!cmdlines) { - errno =3D ENOMEM; - return -1; - } - tep->cmdlines =3D cmdlines; - - key.comm =3D strdup(comm); - if (!key.comm) { - errno =3D ENOMEM; - return -1; - } - - if (!tep->cmdline_count) { - /* no entries yet */ - tep->cmdlines[0] =3D key; - tep->cmdline_count++; - return 0; - } - - /* Now find where we want to store the new cmdline */ - cmdline =3D bsearch(&key, tep->cmdlines, tep->cmdline_count - 1, - sizeof(*tep->cmdlines), cmdline_slot_cmp); - - cnt =3D tep->cmdline_count; - if (cmdline) { - /* cmdline points to the one before the spot we want */ - cmdline++; - cnt -=3D 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++] =3D key; - return 0; - } - cmdline =3D &tep->cmdlines[0]; - } - memmove(cmdline + 1, cmdline, (cnt * sizeof(*cmdline))); - *cmdline =3D 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 =3D malloc(sizeof(*item)); - if (!item) - return -1; - - if (comm) - item->comm =3D strdup(comm); - else - item->comm =3D strdup("<...>"); - if (!item->comm) { - free(item); - return -1; - } - item->pid =3D pid; - item->next =3D tep->cmdlist; - - tep->cmdlist =3D 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 =3D 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 =3D a; - const struct func_map *fb =3D 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 =3D a; - const struct func_map *fb =3D b; - - if ((fa->addr =3D=3D 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 =3D malloc(sizeof(*func_map) * (tep->func_count + 1)); - if (!func_map) - return -1; - - funclist =3D tep->funclist; - - i =3D 0; - while (funclist) { - func_map[i].func =3D funclist->func; - func_map[i].addr =3D funclist->addr; - func_map[i].mod =3D funclist->mod; - i++; - item =3D funclist; - funclist =3D 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 =3D NULL; - func_map[tep->func_count].addr =3D 0; - func_map[tep->func_count].mod =3D NULL; - - tep->func_map =3D func_map; - tep->funclist =3D 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 =3D addr; - - func =3D 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 th= em to - * keep using it instead of duplicating all the entries inside tep->funcli= st. - */ -int tep_set_function_resolver(struct tep_handle *tep, - tep_func_resolver_t *func, void *priv) -{ - struct func_resolver *resolver =3D malloc(sizeof(*resolver)); - - if (resolver =3D=3D NULL) - return -1; - - resolver->func =3D func; - resolver->priv =3D priv; - - free(tep->func_resolver); - tep->func_resolver =3D 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 =3D 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 =3D &tep->func_resolver->map; - map->mod =3D NULL; - map->addr =3D addr; - map->func =3D tep->func_resolver->func(tep->func_resolver->priv, - &map->addr, &map->mod); - if (map->func =3D=3D 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 a= ddr) -{ - struct func_map *map; - - map =3D 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 =3D 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 =3D malloc(sizeof(*item)); - - if (!item) - return -1; - - item->next =3D tep->funclist; - item->func =3D strdup(func); - if (!item->func) - goto out_free; - - if (mod) { - item->mod =3D strdup(mod); - if (!item->mod) - goto out_free_func; - } else - item->mod =3D NULL; - item->addr =3D addr; - - tep->funclist =3D item; - tep->func_count++; - - return 0; - -out_free_func: - free(item->func); - item->func =3D NULL; -out_free: - free(item); - errno =3D 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 =3D 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 =3D a; - const struct printk_map *pb =3D 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 =3D malloc(sizeof(*printk_map) * (tep->printk_count + 1)); - if (!printk_map) - return -1; - - printklist =3D tep->printklist; - - i =3D 0; - while (printklist) { - printk_map[i].printk =3D printklist->printk; - printk_map[i].addr =3D printklist->addr; - i++; - item =3D printklist; - printklist =3D printklist->next; - free(item); - } - - qsort(printk_map, tep->printk_count, sizeof(*printk_map), printk_cmp); - - tep->printk_map =3D printk_map; - tep->printklist =3D 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 =3D addr; - - printk =3D 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 =3D malloc(sizeof(*item)); - char *p; - - if (!item) - return -1; - - item->next =3D tep->printklist; - item->addr =3D addr; - - /* Strip off quotes and '\n' from the end */ - if (fmt[0] =3D=3D '"') - fmt++; - item->printk =3D strdup(fmt); - if (!item->printk) - goto out_free; - - p =3D item->printk + strlen(item->printk) - 1; - if (*p =3D=3D '"') - *p =3D 0; - - p -=3D 2; - if (strcmp(p, "\\n") =3D=3D 0) - *p =3D 0; - - tep->printklist =3D item; - tep->printk_count++; - - return 0; - -out_free: - free(item); - errno =3D 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 =3D 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 =3D realloc(tep->events, sizeof(event) * - (tep->nr_events + 1)); - if (!events) - return -1; - - tep->events =3D events; - - for (i =3D 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] =3D event; - tep->nr_events++; - - event->tep =3D 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 =3D fsym->next; - free(fsym->value); - free(fsym->str); - free(fsym); - fsym =3D 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 =3D arg->func.args; - arg->func.args =3D 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 =3D=3D '\n') - return TEP_EVENT_NEWLINE; - if (isspace(ch)) - return TEP_EVENT_SPACE; - if (isalnum(ch) || ch =3D=3D '_') - return TEP_EVENT_ITEM; - if (ch =3D=3D '\'') - return TEP_EVENT_SQUOTE; - if (ch =3D=3D '"') - return TEP_EVENT_DQUOTE; - if (!isprint(ch)) - return TEP_EVENT_NONE; - if (ch =3D=3D '(' || ch =3D=3D ')' || ch =3D=3D ',') - return TEP_EVENT_DELIM; - - return TEP_EVENT_OP; -} - -static int __read_char(void) -{ - if (input_buf_ptr >=3D 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 >=3D input_buf_siz) - return -1; - - return input_buf[input_buf_ptr]; -} - -static int extend_token(char **tok, char *buf, int size) -{ - char *newtok =3D realloc(*tok, size); - - if (!newtok) { - free(*tok); - *tok =3D NULL; - return -1; - } - - if (!*tok) - strcpy(newtok, buf); - else - strcat(newtok, buf); - *tok =3D 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 =3D 0; - int tok_size =3D 0; - enum tep_event_type type; - - *tok =3D NULL; - - - ch =3D __read_char(); - if (ch < 0) - return TEP_EVENT_NONE; - - type =3D get_type(ch); - if (type =3D=3D TEP_EVENT_NONE) - return type; - - buf[i++] =3D 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 =3D peek_char(); - if (next_ch =3D=3D '>') { - buf[i++] =3D __read_char(); - break; - } - /* fall through */ - case '+': - case '|': - case '&': - case '>': - case '<': - last_ch =3D ch; - ch =3D peek_char(); - if (ch !=3D last_ch) - goto test_equal; - buf[i++] =3D __read_char(); - switch (last_ch) { - case '>': - case '<': - goto test_equal; - default: - break; - } - break; - case '!': - case '=3D': - goto test_equal; - default: /* what should we do instead? */ - break; - } - buf[i] =3D 0; - *tok =3D strdup(buf); - return type; - - test_equal: - ch =3D peek_char(); - if (ch =3D=3D '=3D') - buf[i++] =3D __read_char(); - goto out; - - case TEP_EVENT_DQUOTE: - case TEP_EVENT_SQUOTE: - /* don't keep quotes */ - i--; - quote_ch =3D ch; - last_ch =3D 0; - concat: - do { - if (i =3D=3D (BUFSIZ - 1)) { - buf[i] =3D 0; - tok_size +=3D BUFSIZ; - - if (extend_token(tok, buf, tok_size) < 0) - return TEP_EVENT_NONE; - i =3D 0; - } - last_ch =3D ch; - ch =3D __read_char(); - buf[i++] =3D ch; - /* the '\' '\' will cancel itself */ - if (ch =3D=3D '\\' && last_ch =3D=3D '\\') - last_ch =3D 0; - } while (ch !=3D quote_ch || last_ch =3D=3D '\\'); - /* remove the last quote */ - i--; - - /* - * For strings (double quotes) check the next token. - * If it is another string, concatinate the two. - */ - if (type =3D=3D TEP_EVENT_DQUOTE) { - unsigned long long save_input_buf_ptr =3D input_buf_ptr; - - do { - ch =3D __read_char(); - } while (isspace(ch)); - if (ch =3D=3D '"') - goto concat; - input_buf_ptr =3D save_input_buf_ptr; - } - - goto out; - - case TEP_EVENT_ERROR ... TEP_EVENT_SPACE: - case TEP_EVENT_ITEM: - default: - break; - } - - while (get_type(peek_char()) =3D=3D type) { - if (i =3D=3D (BUFSIZ - 1)) { - buf[i] =3D 0; - tok_size +=3D BUFSIZ; - - if (extend_token(tok, buf, tok_size) < 0) - return TEP_EVENT_NONE; - i =3D 0; - } - ch =3D __read_char(); - buf[i++] =3D ch; - } - - out: - buf[i] =3D 0; - if (extend_token(tok, buf, tok_size + i + 1) < 0) - return TEP_EVENT_NONE; - - if (type =3D=3D 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") =3D=3D 0) { - free(*tok); - *tok =3D NULL; - return force_token("\"%s\" ", tok); - } else if (strcmp(*tok, "STA_PR_FMT") =3D=3D 0) { - free(*tok); - *tok =3D NULL; - return force_token("\" sta:%pM\" ", tok); - } else if (strcmp(*tok, "VIF_PR_FMT") =3D=3D 0) { - free(*tok); - *tok =3D 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; -=09 - /* save off the current input pointers */ - save_input_buf =3D input_buf; - save_input_buf_ptr =3D input_buf_ptr; - save_input_buf_siz =3D input_buf_siz; - - init_input_buf(str, strlen(str)); - - type =3D __read_token(tok); - - /* reset back to original token */ - input_buf =3D save_input_buf; - input_buf_ptr =3D save_input_buf_ptr; - input_buf_siz =3D 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 =3D __read_token(tok); - if (type !=3D TEP_EVENT_SPACE) - return type; - - free_token(*tok); - } - - /* not reached */ - *tok =3D NULL; - return TEP_EVENT_NONE; -} - -/* no newline */ -static enum tep_event_type read_token_item(char **tok) -{ - enum tep_event_type type; - - for (;;) { - type =3D __read_token(tok); - if (type !=3D TEP_EVENT_SPACE && type !=3D TEP_EVENT_NEWLINE) - return type; - free_token(*tok); - *tok =3D NULL; - } - - /* not reached */ - *tok =3D NULL; - return TEP_EVENT_NONE; -} - -static int test_type(enum tep_event_type type, enum tep_event_type expect) -{ - if (type !=3D 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 !=3D expect) { - do_warning("Error: expected type %d but read %d", - expect, type); - return -1; - } - - if (strcmp(token, expect_tok) !=3D 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 =3D read_token(tok); - else - type =3D 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 =3D read_token(&token); - else - type =3D read_token_item(&token); - - ret =3D 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 =3D 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) =3D=3D 0) - return 1; - - return 0; -} - -static int field_is_relative_dynamic(struct tep_format_field *field) -{ - if (strncmp(field->type, "__rel_loc", 9) =3D=3D 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[] =3D { - { "u8", 1 }, - { "u16", 2 }, - { "u32", 4 }, - { "u64", 8 }, - { "s8", 1 }, - { "s16", 2 }, - { "s32", 4 }, - { "s64", 8 }, - { "char", 1 }, - { }, - }; - int i; - - for (i =3D 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 =3D realloc(*buf, strlen(*buf) + strlen(delim) + strlen(str) + 1); - if (!new_buf) - return -1; - strcat(new_buf, delim); - strcat(new_buf, str); - *buf =3D new_buf; - return 0; -} - -static int event_read_fields(struct tep_event *event, struct tep_format_fi= eld **fields) -{ - struct tep_format_field *field =3D NULL; - enum tep_event_type type; - char *token; - char *last_token; - char *delim =3D " "; - int count =3D 0; - int ret; - - do { - unsigned int size_dynamic =3D 0; - - type =3D read_token(&token); - if (type =3D=3D 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 =3D read_token(&token); - /* - * The ftrace fields may still use the "special" name. - * Just ignore it. - */ - if (event->flags & TEP_EVENT_FL_ISFTRACE && - type =3D=3D TEP_EVENT_ITEM && strcmp(token, "special") =3D=3D 0) { - free_token(token); - type =3D 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 =3D token; - - field =3D calloc(1, sizeof(*field)); - if (!field) - goto fail; - - field->event =3D event; - - /* read the rest of the type */ - for (;;) { - type =3D read_token(&token); - if (type =3D=3D TEP_EVENT_ITEM || - (type =3D=3D TEP_EVENT_OP && strcmp(token, "*") =3D=3D 0) || - /* - * Some of the ftrace fields are broken and have - * an illegal "." in them. - */ - (event->flags & TEP_EVENT_FL_ISFTRACE && - type =3D=3D TEP_EVENT_OP && strcmp(token, ".") =3D=3D 0)) { - - if (strcmp(token, "*") =3D=3D 0) - field->flags |=3D TEP_FIELD_IS_POINTER; - - if (field->type) { - ret =3D append(&field->type, delim, last_token); - free(last_token); - if (ret < 0) - goto fail; - } else - field->type =3D last_token; - last_token =3D token; - delim =3D " "; - continue; - } - - /* Handle __attribute__((user)) */ - if ((type =3D=3D TEP_EVENT_DELIM) && - strcmp("__attribute__", last_token) =3D=3D 0 && - token[0] =3D=3D '(') { - int depth =3D 1; - int ret; - - ret =3D append(&field->type, " ", last_token); - ret |=3D append(&field->type, "", "("); - if (ret < 0) - goto fail; - - delim =3D " "; - while ((type =3D read_token(&token)) !=3D TEP_EVENT_NONE) { - if (type =3D=3D TEP_EVENT_DELIM) { - if (token[0] =3D=3D '(') - depth++; - else if (token[0] =3D=3D ')') - depth--; - if (!depth) - break; - ret =3D append(&field->type, "", token); - delim =3D ""; - } else { - ret =3D append(&field->type, delim, token); - delim =3D " "; - } - if (ret < 0) - goto fail; - free(last_token); - last_token =3D token; - } - continue; - } - break; - } - - if (!field->type) { - do_warning_event(event, "%s: no type found", __func__); - goto fail; - } - field->name =3D field->alias =3D last_token; - - if (test_type(type, TEP_EVENT_OP)) - goto fail; - - if (strcmp(token, "[") =3D=3D 0) { - enum tep_event_type last_type =3D type; - char *brackets =3D token; - - field->flags |=3D TEP_FIELD_IS_ARRAY; - - type =3D read_token(&token); - - if (type =3D=3D TEP_EVENT_ITEM) - field->arraylen =3D strtoul(token, NULL, 0); - else - field->arraylen =3D 0; - - while (strcmp(token, "]") !=3D 0) { - const char *delim; - - if (last_type =3D=3D TEP_EVENT_ITEM && - type =3D=3D TEP_EVENT_ITEM) - delim =3D " "; - else - delim =3D ""; - - last_type =3D type; - - ret =3D append(&brackets, delim, token); - if (ret < 0) { - free(brackets); - goto fail; - } - /* We only care about the last token */ - field->arraylen =3D strtoul(token, NULL, 0); - free_token(token); - type =3D read_token(&token); - if (type =3D=3D TEP_EVENT_NONE) { - free(brackets); - do_warning_event(event, "failed to find token"); - goto fail; - } - } - - free_token(token); - - ret =3D append(&brackets, "", "]"); - if (ret < 0) { - free(brackets); - goto fail; - } - - /* add brackets to type */ - - type =3D read_token(&token); - /* - * If the next token is not an OP, then it is of - * the format: type [] item; - */ - if (type =3D=3D TEP_EVENT_ITEM) { - ret =3D append(&field->type, " ", field->name); - if (ret < 0) { - free(brackets); - goto fail; - } - ret =3D append(&field->type, "", brackets); - - size_dynamic =3D type_size(field->name); - free_token(field->name); - field->name =3D field->alias =3D token; - type =3D read_token(&token); - } else { - ret =3D append(&field->type, "", brackets); - if (ret < 0) { - free(brackets); - goto fail; - } - } - free(brackets); - } - - if (field_is_string(field)) - field->flags |=3D TEP_FIELD_IS_STRING; - if (field_is_dynamic(field)) - field->flags |=3D TEP_FIELD_IS_DYNAMIC; - if (field_is_relative_dynamic(field)) - field->flags |=3D TEP_FIELD_IS_DYNAMIC | TEP_FIELD_IS_RELATIVE; - if (field_is_long(field)) - field->flags |=3D 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 =3D 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 =3D strtoul(token, NULL, 0); - free_token(token); - - if (read_expected(TEP_EVENT_OP, ";") < 0) - goto fail_expect; - - type =3D read_token(&token); - if (type !=3D 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 |=3D 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 =3D field->size / field->arraylen; - else if (field->flags & TEP_FIELD_IS_DYNAMIC) - field->elementsize =3D size_dynamic; - else if (field->flags & TEP_FIELD_IS_STRING) - field->elementsize =3D 1; - else if (field->flags & TEP_FIELD_IS_LONG) - field->elementsize =3D event->tep ? - event->tep->long_size : - sizeof(long); - } else - field->elementsize =3D field->size; - - *fields =3D field; - fields =3D &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 =3D event_read_fields(event, &event->format.common_fields); - if (ret < 0) - return ret; - event->format.nr_common =3D ret; - - ret =3D event_read_fields(event, &event->format.fields); - if (ret < 0) - return ret; - event->format.nr_fields =3D 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 =3D read_token(&token); - *tok =3D 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 =3D process_arg(event, arg, tok); - - while (type =3D=3D TEP_EVENT_OP) { - type =3D process_op(event, arg, tok); - } - - return type; -} - -static enum tep_event_type -process_cond(struct tep_event *event, struct tep_print_arg *top, char **to= k) -{ - struct tep_print_arg *arg, *left, *right; - enum tep_event_type type; - char *token =3D NULL; - - arg =3D alloc_arg(); - left =3D alloc_arg(); - right =3D 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 =3D TEP_PRINT_OP; - arg->op.left =3D left; - arg->op.right =3D right; - - *tok =3D NULL; - type =3D process_arg(event, left, &token); - - again: - if (type =3D=3D TEP_EVENT_ERROR) - goto out_free; - - /* Handle other operations in the arguments */ - if (type =3D=3D TEP_EVENT_OP && strcmp(token, ":") !=3D 0) { - type =3D process_op(event, left, &token); - goto again; - } - - if (test_type_token(type, token, TEP_EVENT_OP, ":")) - goto out_free; - - arg->op.op =3D token; - - type =3D process_arg(event, right, &token); - - top->op.right =3D arg; - - *tok =3D token; - return type; - -out_free: - /* Top may point to itself */ - top->op.right =3D 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 **t= ok) -{ - struct tep_print_arg *arg; - enum tep_event_type type; - char *token =3D NULL; - - arg =3D 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 =3D NULL; - return TEP_EVENT_ERROR; - } - - *tok =3D NULL; - type =3D process_arg(event, arg, &token); - if (test_type_token(type, token, TEP_EVENT_OP, "]")) - goto out_free; - - top->op.right =3D arg; - - free_token(token); - type =3D read_token_item(&token); - *tok =3D 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; - /* '=3D=3D' and '!=3D' 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, "++") =3D=3D 0 || - strcmp(op, "--") =3D=3D 0) { - return 3; - } else if (strcmp(op, ">>") =3D=3D 0 || - strcmp(op, "<<") =3D=3D 0) { - return 8; - } else if (strcmp(op, ">=3D") =3D=3D 0 || - strcmp(op, "<=3D") =3D=3D 0) { - return 9; - } else if (strcmp(op, "=3D=3D") =3D=3D 0 || - strcmp(op, "!=3D") =3D=3D 0) { - return 10; - } else if (strcmp(op, "&&") =3D=3D 0) { - return 14; - } else if (strcmp(op, "||") =3D=3D 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 =3D=3D TEP_PRINT_NULL) - arg->op.prio =3D 0; - else - arg->op.prio =3D 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 =3D NULL; - enum tep_event_type type; - char *token; - - /* the op is passed in via tok */ - token =3D *tok; - - if (arg->type =3D=3D 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 =3D alloc_arg(); - if (!left) - goto out_warn_free; - - left->type =3D TEP_PRINT_NULL; - arg->op.left =3D left; - - right =3D alloc_arg(); - if (!right) - goto out_warn_free; - - arg->op.right =3D right; - - /* do not free the token, it belongs to an op */ - *tok =3D NULL; - type =3D process_arg(event, right, tok); - - } else if (strcmp(token, "?") =3D=3D 0) { - - left =3D alloc_arg(); - if (!left) - goto out_warn_free; - - /* copy the top arg to the left */ - *left =3D *arg; - - arg->type =3D TEP_PRINT_OP; - arg->op.op =3D token; - arg->op.left =3D left; - arg->op.prio =3D 0; - - /* it will set arg->op.right */ - type =3D process_cond(event, arg, tok); - - } else if (strcmp(token, ">>") =3D=3D 0 || - strcmp(token, "<<") =3D=3D 0 || - strcmp(token, "&") =3D=3D 0 || - strcmp(token, "|") =3D=3D 0 || - strcmp(token, "&&") =3D=3D 0 || - strcmp(token, "||") =3D=3D 0 || - strcmp(token, "-") =3D=3D 0 || - strcmp(token, "+") =3D=3D 0 || - strcmp(token, "*") =3D=3D 0 || - strcmp(token, "^") =3D=3D 0 || - strcmp(token, "/") =3D=3D 0 || - strcmp(token, "%") =3D=3D 0 || - strcmp(token, "<") =3D=3D 0 || - strcmp(token, ">") =3D=3D 0 || - strcmp(token, "<=3D") =3D=3D 0 || - strcmp(token, ">=3D") =3D=3D 0 || - strcmp(token, "=3D=3D") =3D=3D 0 || - strcmp(token, "!=3D") =3D=3D 0) { - - left =3D alloc_arg(); - if (!left) - goto out_warn_free; - - /* copy the top arg to the left */ - *left =3D *arg; - - arg->type =3D TEP_PRINT_OP; - arg->op.op =3D token; - arg->op.left =3D left; - arg->op.right =3D NULL; - - if (set_op_prio(arg) =3D=3D -1) { - event->flags |=3D TEP_EVENT_FL_FAILED; - /* arg->op.op (=3D token) will be freed at out_free */ - arg->op.op =3D NULL; - goto out_free; - } - - type =3D read_token_item(&token); - *tok =3D token; - - /* could just be a type pointer */ - if ((strcmp(arg->op.op, "*") =3D=3D 0) && - type =3D=3D TEP_EVENT_DELIM && (strcmp(token, ")") =3D=3D 0)) { - int ret; - - if (left->type !=3D TEP_PRINT_ATOM) { - do_warning_event(event, "bad pointer type"); - goto out_free; - } - ret =3D append(&left->atom.atom, " ", "*"); - if (ret < 0) - goto out_warn_free; - - free(arg->op.op); - *arg =3D *left; - free(left); - - return type; - } - - right =3D alloc_arg(); - if (!right) - goto out_warn_free; - - type =3D process_arg_token(event, right, tok, type); - if (type =3D=3D TEP_EVENT_ERROR) { - free_arg(right); - /* token was freed in process_arg_token() via *tok */ - token =3D NULL; - goto out_free; - } - - if (right->type =3D=3D 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 =3D right->op.left; - - tmp =3D *arg; - *arg =3D *right; - *right =3D tmp; - - arg->op.left =3D right; - } else { - arg->op.right =3D right; - } - - } else if (strcmp(token, "[") =3D=3D 0) { - - left =3D alloc_arg(); - if (!left) - goto out_warn_free; - - *left =3D *arg; - - arg->type =3D TEP_PRINT_OP; - arg->op.op =3D token; - arg->op.left =3D left; - - arg->op.prio =3D 0; - - /* it will set arg->op.right */ - type =3D process_array(event, arg, tok); - - } else { - do_warning_event(event, "unknown op '%s'", token); - event->flags |=3D TEP_EVENT_FL_FAILED; - /* the arg is now the left side */ - goto out_free; - } - - if (type =3D=3D TEP_EVENT_OP && strcmp(*tok, ":") !=3D 0) { - int prio; - - /* higher prios need to be closer to the root */ - prio =3D 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 =3D 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 =3D token; - - arg->type =3D TEP_PRINT_FIELD; - arg->field.name =3D field; - - if (is_flag_field) { - arg->field.field =3D tep_find_any_field(event, arg->field.name); - arg->field.field->flags |=3D TEP_FIELD_IS_FLAG; - is_flag_field =3D 0; - } else if (is_symbolic_field) { - arg->field.field =3D tep_find_any_field(event, arg->field.name); - arg->field.field->flags |=3D TEP_FIELD_IS_SYMBOLIC; - is_symbolic_field =3D 0; - } - - type =3D read_token(&token); - *tok =3D token; - - return type; - - out_free: - free_token(token); - out_err: - *tok =3D NULL; - return TEP_EVENT_ERROR; -} - -static int alloc_and_process_delim(struct tep_event *event, char *next_tok= en, - struct tep_print_arg **print_arg) -{ - struct tep_print_arg *field; - enum tep_event_type type; - char *token; - int ret =3D 0; - - field =3D alloc_arg(); - if (!field) { - do_warning_event(event, "%s: not enough memory!", __func__); - errno =3D ENOMEM; - return -1; - } - - type =3D process_arg(event, field, &token); - - if (test_type_token(type, token, TEP_EVENT_DELIM, next_token)) { - errno =3D EINVAL; - ret =3D -1; - free_arg(field); - goto out_free_token; - } - - *print_arg =3D 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 =3D 0; - char *ref; - int len; - - len =3D strlen(type); - - if (pointer) { - - if (type[len-1] !=3D '*') { - do_warning("pointer expected with non pointer type"); - return val; - } - - ref =3D malloc(len); - if (!ref) { - do_warning("%s: not enough memory!", __func__); - return val; - } - memcpy(ref, type, len); - - /* chop off the " *" */ - ref[len - 2] =3D 0; - - val =3D eval_type_str(val, ref, 0); - free(ref); - return val; - } - - /* check if this is a pointer */ - if (type[len - 1] =3D=3D '*') - return val; - - /* Try to figure out the arg size*/ - if (strncmp(type, "struct", 6) =3D=3D 0) - /* all bets off */ - return val; - - if (strcmp(type, "u8") =3D=3D 0) - return val & 0xff; - - if (strcmp(type, "u16") =3D=3D 0) - return val & 0xffff; - - if (strcmp(type, "u32") =3D=3D 0) - return val & 0xffffffff; - - if (strcmp(type, "u64") =3D=3D 0 || - strcmp(type, "s64") =3D=3D 0) - return val; - - if (strcmp(type, "s8") =3D=3D 0) - return (unsigned long long)(char)val & 0xff; - - if (strcmp(type, "s16") =3D=3D 0) - return (unsigned long long)(short)val & 0xffff; - - if (strcmp(type, "s32") =3D=3D 0) - return (unsigned long long)(int)val & 0xffffffff; - - if (strncmp(type, "unsigned ", 9) =3D=3D 0) { - sign =3D 0; - type +=3D 9; - } - - if (strcmp(type, "char") =3D=3D 0) { - if (sign) - return (unsigned long long)(char)val & 0xff; - else - return val & 0xff; - } - - if (strcmp(type, "short") =3D=3D 0) { - if (sign) - return (unsigned long long)(short)val & 0xffff; - else - return val & 0xffff; - } - - if (strcmp(type, "int") =3D=3D 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 !=3D 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 =3D 1; - - switch (arg->type) { - case TEP_PRINT_ATOM: - *val =3D strtoll(arg->atom.atom, NULL, 0); - break; - case TEP_PRINT_TYPE: - ret =3D arg_num_eval(arg->typecast.item, val); - if (!ret) - break; - *val =3D eval_type(*val, arg, 0); - break; - case TEP_PRINT_OP: - switch (arg->op.op[0]) { - case '|': - ret =3D arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret =3D arg_num_eval(arg->op.right, &right); - if (!ret) - break; - if (arg->op.op[1]) - *val =3D left || right; - else - *val =3D left | right; - break; - case '&': - ret =3D arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret =3D arg_num_eval(arg->op.right, &right); - if (!ret) - break; - if (arg->op.op[1]) - *val =3D left && right; - else - *val =3D left & right; - break; - case '<': - ret =3D arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret =3D arg_num_eval(arg->op.right, &right); - if (!ret) - break; - switch (arg->op.op[1]) { - case 0: - *val =3D left < right; - break; - case '<': - *val =3D left << right; - break; - case '=3D': - *val =3D left <=3D right; - break; - default: - do_warning("unknown op '%s'", arg->op.op); - ret =3D 0; - } - break; - case '>': - ret =3D arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret =3D arg_num_eval(arg->op.right, &right); - if (!ret) - break; - switch (arg->op.op[1]) { - case 0: - *val =3D left > right; - break; - case '>': - *val =3D left >> right; - break; - case '=3D': - *val =3D left >=3D right; - break; - default: - do_warning("unknown op '%s'", arg->op.op); - ret =3D 0; - } - break; - case '=3D': - ret =3D arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret =3D arg_num_eval(arg->op.right, &right); - if (!ret) - break; - - if (arg->op.op[1] !=3D '=3D') { - do_warning("unknown op '%s'", arg->op.op); - ret =3D 0; - } else - *val =3D left =3D=3D right; - break; - case '!': - ret =3D arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret =3D arg_num_eval(arg->op.right, &right); - if (!ret) - break; - - switch (arg->op.op[1]) { - case '=3D': - *val =3D left !=3D right; - break; - default: - do_warning("unknown op '%s'", arg->op.op); - ret =3D 0; - } - break; - case '-': - /* check for negative */ - if (arg->op.left->type =3D=3D TEP_PRINT_NULL) - left =3D 0; - else - ret =3D arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret =3D arg_num_eval(arg->op.right, &right); - if (!ret) - break; - *val =3D left - right; - break; - case '+': - if (arg->op.left->type =3D=3D TEP_PRINT_NULL) - left =3D 0; - else - ret =3D arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret =3D arg_num_eval(arg->op.right, &right); - if (!ret) - break; - *val =3D left + right; - break; - case '~': - ret =3D arg_num_eval(arg->op.right, &right); - if (!ret) - break; - *val =3D ~right; - break; - default: - do_warning("unknown op '%s'", arg->op.op); - ret =3D 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 =3D 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 =3D NULL; - struct tep_print_flag_sym *field; - char *token =3D *tok; - char *value; - - do { - free_token(token); - type =3D read_token_item(&token); - if (test_type_token(type, token, TEP_EVENT_OP, "{")) - break; - - arg =3D alloc_arg(); - if (!arg) - goto out_free; - - free_token(token); - type =3D process_arg(event, arg, &token); - - if (type =3D=3D TEP_EVENT_OP) - type =3D process_op(event, arg, &token); - - if (type =3D=3D TEP_EVENT_ERROR) - goto out_free; - - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto out_free; - - field =3D calloc(1, sizeof(*field)); - if (!field) - goto out_free; - - value =3D arg_eval(arg); - if (value =3D=3D NULL) - goto out_free_field; - field->value =3D strdup(value); - if (field->value =3D=3D NULL) - goto out_free_field; - - free_arg(arg); - arg =3D alloc_arg(); - if (!arg) - goto out_free; - - free_token(token); - type =3D process_arg(event, arg, &token); - if (test_type_token(type, token, TEP_EVENT_OP, "}")) - goto out_free_field; - - value =3D arg_eval(arg); - if (value =3D=3D NULL) - goto out_free_field; - field->str =3D strdup(value); - if (field->str =3D=3D NULL) - goto out_free_field; - free_arg(arg); - arg =3D NULL; - - *list =3D field; - list =3D &field->next; - - free_token(token); - type =3D read_token_item(&token); - } while (type =3D=3D TEP_EVENT_DELIM && strcmp(token, ",") =3D=3D 0); - - *tok =3D token; - return type; - -out_free_field: - free_flag_sym(field); -out_free: - free_arg(arg); - free_token(token); - *tok =3D NULL; - - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_flags(struct tep_event *event, struct tep_print_arg *arg, char **t= ok) -{ - struct tep_print_arg *field; - enum tep_event_type type; - char *token =3D NULL; - - memset(arg, 0, sizeof(*arg)); - arg->type =3D TEP_PRINT_FLAGS; - - field =3D alloc_arg(); - if (!field) { - do_warning_event(event, "%s: not enough memory!", __func__); - goto out_free; - } - - type =3D process_field_arg(event, field, &token); - - /* Handle operations in the first argument */ - while (type =3D=3D TEP_EVENT_OP) - type =3D process_op(event, field, &token); - - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto out_free_field; - free_token(token); - - arg->flags.field =3D field; - - type =3D read_token_item(&token); - if (event_item_type(type)) { - arg->flags.delim =3D token; - type =3D read_token_item(&token); - } - - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto out_free; - - type =3D process_fields(event, &arg->flags.flags, &token); - if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) - goto out_free; - - free_token(token); - type =3D read_token_item(tok); - return type; - -out_free_field: - free_arg(field); -out_free: - free_token(token); - *tok =3D 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 =3D NULL; - - memset(arg, 0, sizeof(*arg)); - arg->type =3D TEP_PRINT_SYMBOL; - - field =3D alloc_arg(); - if (!field) { - do_warning_event(event, "%s: not enough memory!", __func__); - goto out_free; - } - - type =3D process_field_arg(event, field, &token); - - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto out_free_field; - - arg->symbol.field =3D field; - - type =3D process_fields(event, &arg->symbol.symbols, &token); - if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) - goto out_free; - - free_token(token); - type =3D read_token_item(tok); - return type; - -out_free_field: - free_arg(field); -out_free: - free_token(token); - *tok =3D 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 =3D 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 =3D NULL; -out: - *tok =3D 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 =3D 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 =3D NULL; -free_field: - free_arg(arg->int_array.field); - arg->int_array.field =3D NULL; -out: - *tok =3D 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 =3D TEP_PRINT_DYNAMIC_ARRAY; - - /* - * The item within the parenthesis is another field that holds - * the index into where the array starts. - */ - type =3D read_token(&token); - *tok =3D token; - if (type !=3D TEP_EVENT_ITEM) - goto out_free; - - /* Find the field */ - - field =3D tep_find_field(event, token); - if (!field) - goto out_free; - - arg->dynarray.field =3D field; - arg->dynarray.index =3D 0; - - if (read_expected(TEP_EVENT_DELIM, ")") < 0) - goto out_free; - - free_token(token); - type =3D read_token_item(&token); - *tok =3D token; - if (type !=3D TEP_EVENT_OP || strcmp(token, "[") !=3D 0) - return type; - - free_token(token); - arg =3D alloc_arg(); - if (!arg) { - do_warning_event(event, "%s: not enough memory!", __func__); - *tok =3D NULL; - return TEP_EVENT_ERROR; - } - - type =3D process_arg(event, arg, &token); - if (type =3D=3D TEP_EVENT_ERROR) - goto out_free_arg; - - if (!test_type_token(type, token, TEP_EVENT_OP, "]")) - goto out_free_arg; - - free_token(token); - type =3D read_token_item(tok); - return type; - - out_free_arg: - free_arg(arg); - out_free: - free_token(token); - *tok =3D NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_dynamic_array_len(struct tep_event *event, struct tep_print_arg *a= rg, - 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 =3D TEP_PRINT_DYNAMIC_ARRAY_LEN; - - /* Find the field */ - field =3D tep_find_field(event, token); - if (!field) - goto out_free; - - arg->dynarray.field =3D field; - arg->dynarray.index =3D 0; - - if (read_expected(TEP_EVENT_DELIM, ")") < 0) - goto out_err; - - free_token(token); - type =3D read_token(&token); - *tok =3D token; - - return type; - - out_free: - free_token(token); - out_err: - *tok =3D NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_paren(struct tep_event *event, struct tep_print_arg *arg, char **t= ok) -{ - struct tep_print_arg *item_arg; - enum tep_event_type type; - char *token; - - type =3D process_arg(event, arg, &token); - - if (type =3D=3D TEP_EVENT_ERROR) - goto out_free; - - if (type =3D=3D TEP_EVENT_OP) - type =3D process_op(event, arg, &token); - - if (type =3D=3D TEP_EVENT_ERROR) - goto out_free; - - if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) - goto out_free; - - free_token(token); - type =3D 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 =3D=3D TEP_EVENT_DELIM && strcmp(token, "(") =3D=3D 0)) { - - /* make this a typecast and contine */ - - /* prevous must be an atom */ - if (arg->type !=3D TEP_PRINT_ATOM) { - do_warning_event(event, "previous needed to be TEP_PRINT_ATOM"); - goto out_free; - } - - item_arg =3D alloc_arg(); - if (!item_arg) { - do_warning_event(event, "%s: not enough memory!", - __func__); - goto out_free; - } - - arg->type =3D TEP_PRINT_TYPE; - arg->typecast.type =3D arg->atom.atom; - arg->typecast.item =3D item_arg; - type =3D process_arg_token(event, item_arg, &token, type); - - } - - *tok =3D token; - return type; - - out_free: - free_token(token); - *tok =3D 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 =3D TEP_PRINT_STRING; - arg->string.string =3D token; - arg->string.field =3D NULL; - - if (read_expected(TEP_EVENT_DELIM, ")") < 0) - goto out_err; - - type =3D read_token(&token); - *tok =3D token; - - return type; - - out_free: - free_token(token); - out_err: - *tok =3D NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_bitmask(struct tep_event *event __maybe_unused, struct tep_print_a= rg *arg, - char **tok) -{ - enum tep_event_type type; - char *token; - - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto out_free; - - arg->type =3D TEP_PRINT_BITMASK; - arg->bitmask.bitmask =3D token; - arg->bitmask.field =3D NULL; - - if (read_expected(TEP_EVENT_DELIM, ")") < 0) - goto out_err; - - type =3D read_token(&token); - *tok =3D token; - - return type; - - out_free: - free_token(token); - out_err: - *tok =3D 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 =3D tep->func_handlers; func; func =3D func->next) { - if (strcmp(func->name, func_name) =3D=3D 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 =3D &tep->func_handlers; - while ((func =3D *next)) { - if (strcmp(func->name, func_name) =3D=3D 0) { - *next =3D func->next; - free_func_handle(func); - break; - } - next =3D &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 =3D TEP_PRINT_FUNC; - arg->func.func =3D func; - - *tok =3D NULL; - - next_arg =3D &(arg->func.args); - for (i =3D 0; i < func->nr_args; i++) { - farg =3D alloc_arg(); - if (!farg) { - do_warning_event(event, "%s: not enough memory!", - __func__); - return TEP_EVENT_ERROR; - } - - type =3D process_arg(event, farg, &token); - if (i < (func->nr_args - 1)) { - if (type !=3D TEP_EVENT_DELIM || strcmp(token, ",") !=3D 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 !=3D TEP_EVENT_DELIM || strcmp(token, ")") !=3D 0) { - do_warning_event(event, - "Error: function '%s()' only expects %d arguments but event %s has mo= re", - func->name, func->nr_args, event->name); - goto err; - } - } - - *next_arg =3D farg; - next_arg =3D &(farg->next); - free_token(token); - } - - type =3D read_token(&token); - *tok =3D 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 =3D NULL; - - /* Handle __builtin_expect( cond, #) */ - type =3D process_arg(event, arg, &token); - - if (type !=3D TEP_EVENT_DELIM || token[0] !=3D ',') - 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 =3D read_token_item(tok); - return type; - -out_free: - free_token(token); - *tok =3D 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") =3D=3D 0) { - free_token(token); - is_flag_field =3D 1; - return process_flags(event, arg, tok); - } - if (strcmp(token, "__print_symbolic") =3D=3D 0) { - free_token(token); - is_symbolic_field =3D 1; - return process_symbols(event, arg, tok); - } - if (strcmp(token, "__print_hex") =3D=3D 0) { - free_token(token); - return process_hex(event, arg, tok); - } - if (strcmp(token, "__print_hex_str") =3D=3D 0) { - free_token(token); - return process_hex_str(event, arg, tok); - } - if (strcmp(token, "__print_array") =3D=3D 0) { - free_token(token); - return process_int_array(event, arg, tok); - } - if (strcmp(token, "__get_str") =3D=3D 0 || - strcmp(token, "__get_rel_str") =3D=3D 0) { - free_token(token); - return process_str(event, arg, tok); - } - if (strcmp(token, "__get_bitmask") =3D=3D 0 || - strcmp(token, "__get_rel_bitmask") =3D=3D 0) { - free_token(token); - return process_bitmask(event, arg, tok); - } - if (strcmp(token, "__get_dynamic_array") =3D=3D 0 || - strcmp(token, "__get_rel_dynamic_array") =3D=3D 0) { - free_token(token); - return process_dynamic_array(event, arg, tok); - } - if (strcmp(token, "__get_dynamic_array_len") =3D=3D 0 || - strcmp(token, "__get_rel_dynamic_array_len") =3D=3D 0) { - free_token(token); - return process_dynamic_array_len(event, arg, tok); - } - if (strcmp(token, "__builtin_expect") =3D=3D 0) { - free_token(token); - return process_builtin_expect(event, arg, tok); - } - - func =3D 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 =3D *tok; - - switch (type) { - case TEP_EVENT_ITEM: - if (strcmp(token, "REC") =3D=3D 0) { - free_token(token); - type =3D process_entry(event, arg, &token); - break; - } - atom =3D token; - /* test the next token */ - type =3D read_token_item(&token); - - /* - * If the next token is a parenthesis, then this - * is a function. - */ - if (type =3D=3D TEP_EVENT_DELIM && strcmp(token, "(") =3D=3D 0) { - free_token(token); - token =3D NULL; - /* this will free atom. */ - type =3D process_function(event, arg, atom, &token); - break; - } - /* atoms can be more than one token long */ - while (type =3D=3D TEP_EVENT_ITEM) { - int ret; - - ret =3D append(&atom, " ", token); - if (ret < 0) { - free(atom); - *tok =3D NULL; - free_token(token); - return TEP_EVENT_ERROR; - } - free_token(token); - type =3D read_token_item(&token); - } - - arg->type =3D TEP_PRINT_ATOM; - arg->atom.atom =3D atom; - break; - - case TEP_EVENT_DQUOTE: - case TEP_EVENT_SQUOTE: - arg->type =3D TEP_PRINT_ATOM; - arg->atom.atom =3D token; - type =3D read_token_item(&token); - break; - case TEP_EVENT_DELIM: - if (strcmp(token, "(") =3D=3D 0) { - free_token(token); - type =3D process_paren(event, arg, &token); - break; - } - case TEP_EVENT_OP: - /* handle single ops */ - arg->type =3D TEP_PRINT_OP; - arg->op.op =3D token; - arg->op.left =3D NULL; - type =3D process_op(event, arg, &token); - - /* On error, the op is freed */ - if (type =3D=3D TEP_EVENT_ERROR) - arg->op.op =3D 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 =3D token; - - return type; -} - -static int event_read_print_args(struct tep_event *event, struct tep_print= _arg **list) -{ - enum tep_event_type type =3D TEP_EVENT_ERROR; - struct tep_print_arg *arg; - char *token; - int args =3D 0; - - do { - if (type =3D=3D TEP_EVENT_NEWLINE) { - type =3D read_token_item(&token); - continue; - } - - arg =3D alloc_arg(); - if (!arg) { - do_warning_event(event, "%s: not enough memory!", - __func__); - return -1; - } - - type =3D process_arg(event, arg, &token); - - if (type =3D=3D TEP_EVENT_ERROR) { - free_token(token); - free_arg(arg); - return -1; - } - - *list =3D arg; - args++; - - if (type =3D=3D TEP_EVENT_OP) { - type =3D process_op(event, arg, &token); - free_token(token); - if (type =3D=3D TEP_EVENT_ERROR) { - *list =3D NULL; - free_arg(arg); - return -1; - } - list =3D &arg->next; - continue; - } - - if (type =3D=3D TEP_EVENT_DELIM && strcmp(token, ",") =3D=3D 0) { - free_token(token); - *list =3D arg; - list =3D &arg->next; - continue; - } - break; - } while (type !=3D TEP_EVENT_NONE); - - if (type !=3D TEP_EVENT_NONE && type !=3D 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 =3D token; - event->print_fmt.args =3D NULL; - - /* ok to have no arg */ - type =3D read_token_item(&token); - - if (type =3D=3D TEP_EVENT_NONE) - return 0; - - /* Handle concatenation of print lines */ - if (type =3D=3D 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 =3D NULL; - token =3D cat; - goto concat; - } - =20 - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto fail; - - free_token(token); - - ret =3D 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 =3D event->format.common_fields; - format; format =3D format->next) { - if (strcmp(format->name, name) =3D=3D 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 =3D event->format.fields; - format; format =3D format->next) { - if (strcmp(format->name, name) =3D=3D 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 =3D 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 =3D 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 =3D tep->events[0]; - field =3D tep_find_common_field(event, type); - if (!field) - return -1; - - *offset =3D field->offset; - *size =3D 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 =3D 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 =3D &key; - - /* Check cache first */ - if (tep->last_event && tep->last_event->id =3D=3D id) - return tep->last_event; - - key.id =3D id; - - eventptr =3D bsearch(&pkey, tep->events, tep->nr_events, - sizeof(*tep->events), events_id_cmp); - - if (eventptr) { - tep->last_event =3D *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 =3D NULL; - int i; - - if (tep->last_event && - strcmp(tep->last_event->name, name) =3D=3D 0 && - (!sys || strcmp(tep->last_event->system, sys) =3D=3D 0)) - return tep->last_event; - - for (i =3D 0; i < tep->nr_events; i++) { - event =3D tep->events[i]; - if (strcmp(event->name, name) =3D=3D 0) { - if (!sys) - break; - if (strcmp(event->system, sys) =3D=3D 0) - break; - } - } - if (i =3D=3D tep->nr_events) - event =3D NULL; - - tep->last_event =3D event; - return event; -} - -static unsigned long long -eval_num_arg(void *data, int size, struct tep_event *event, struct tep_pri= nt_arg *arg) -{ - struct tep_handle *tep =3D event->tep; - unsigned long long val =3D 0; - unsigned long long left, right; - struct tep_print_arg *typearg =3D 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 =3D tep_find_any_field(event, arg->field.name); - if (!arg->field.field) - goto out_warning_field; - =09 - } - /* must be a number */ - val =3D 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 =3D 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 =3D process_defined_func(&s, data, size, event, arg); - trace_seq_destroy(&s); - return val; - } - case TEP_PRINT_OP: - if (strcmp(arg->op.op, "[") =3D=3D 0) { - /* - * Arrays are special, since we don't want - * to read the arg as is. - */ - right =3D eval_num_arg(data, size, event, arg->op.right); - - /* handle typecasts */ - larg =3D arg->op.left; - while (larg->type =3D=3D TEP_PRINT_TYPE) { - if (!typearg) - typearg =3D larg; - larg =3D larg->typecast.item; - } - - /* Default to long size */ - field_size =3D tep->long_size; - - switch (larg->type) { - case TEP_PRINT_DYNAMIC_ARRAY: - offset =3D tep_read_number(tep, - data + larg->dynarray.field->offset, - larg->dynarray.field->size); - if (larg->dynarray.field->elementsize) - field_size =3D 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 &=3D 0xffff; - offset +=3D right; - break; - case TEP_PRINT_FIELD: - if (!larg->field.field) { - larg->field.field =3D - tep_find_any_field(event, larg->field.name); - if (!larg->field.field) { - arg =3D larg; - goto out_warning_field; - } - } - field_size =3D larg->field.field->elementsize; - offset =3D larg->field.field->offset + - right * larg->field.field->elementsize; - break; - default: - goto default_op; /* oops, all bets off */ - } - val =3D tep_read_number(tep, - data + offset, field_size); - if (typearg) - val =3D eval_type(val, typearg, 1); - break; - } else if (strcmp(arg->op.op, "?") =3D=3D 0) { - left =3D eval_num_arg(data, size, event, arg->op.left); - arg =3D arg->op.right; - if (left) - val =3D eval_num_arg(data, size, event, arg->op.left); - else - val =3D eval_num_arg(data, size, event, arg->op.right); - break; - } - default_op: - left =3D eval_num_arg(data, size, event, arg->op.left); - right =3D eval_num_arg(data, size, event, arg->op.right); - switch (arg->op.op[0]) { - case '!': - switch (arg->op.op[1]) { - case 0: - val =3D !right; - break; - case '=3D': - val =3D left !=3D right; - break; - default: - goto out_warning_op; - } - break; - case '~': - val =3D ~right; - break; - case '|': - if (arg->op.op[1]) - val =3D left || right; - else - val =3D left | right; - break; - case '&': - if (arg->op.op[1]) - val =3D left && right; - else - val =3D left & right; - break; - case '<': - switch (arg->op.op[1]) { - case 0: - val =3D left < right; - break; - case '<': - val =3D left << right; - break; - case '=3D': - val =3D left <=3D right; - break; - default: - goto out_warning_op; - } - break; - case '>': - switch (arg->op.op[1]) { - case 0: - val =3D left > right; - break; - case '>': - val =3D left >> right; - break; - case '=3D': - val =3D left >=3D right; - break; - default: - goto out_warning_op; - } - break; - case '=3D': - if (arg->op.op[1] !=3D '=3D') - goto out_warning_op; - - val =3D left =3D=3D right; - break; - case '-': - val =3D left - right; - break; - case '+': - val =3D left + right; - break; - case '/': - val =3D left / right; - break; - case '%': - val =3D left % right; - break; - case '*': - val =3D left * right; - break; - default: - goto out_warning_op; - } - break; - case TEP_PRINT_DYNAMIC_ARRAY_LEN: - offset =3D 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 =3D (unsigned long long)(offset >> 16); - break; - case TEP_PRINT_DYNAMIC_ARRAY: - /* Without [], we pass the address to the dynamic data */ - offset =3D 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 &=3D 0xffff; - val =3D (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[] =3D { - { "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 =3D 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) - if (strcmp(flags[i].name, flag) =3D=3D 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 >=3D 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 =3D size * 8; - int str_size =3D (nr_bits + 3) / 4; - int len =3D 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 +=3D (nr_bits - 1) / 32; - - str =3D malloc(str_size + 1); - if (!str) { - do_warning("%s: not enough memory!", __func__); - return; - } - str[str_size] =3D 0; - - /* Start out with -2 for the two chars per byte */ - for (i =3D str_size - 2; i >=3D 0; i -=3D 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 =3D size - (len + 1); - else - index =3D len; - - snprintf(buf, 3, "%02x", *((unsigned char *)data + index)); - memcpy(str + i, buf, 2); - len++; - if (!(len & 3) && i > 0) { - i--; - str[i] =3D ','; - } - } - - if (len_arg >=3D 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 =3D 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 =3D arg->field.field; - if (!field) { - field =3D tep_find_any_field(event, arg->field.name); - if (!field) { - str =3D arg->field.name; - goto out_warning_field; - } - arg->field.field =3D field; - } - /* Zero sized fields, mean the rest of the data */ - len =3D 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 =3D=3D 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 =3D (tep->long_size =3D=3D 8) ? - *(unsigned long long *)(data + field->offset) : - (unsigned long long)*(unsigned int *)(data + field->offset); - - /* Check if it matches a print format */ - printk =3D find_printk(tep, addr); - if (printk) - trace_seq_puts(s, printk->printk); - else - trace_seq_printf(s, "%llx", addr); - break; - } - str =3D malloc(len + 1); - if (!str) { - do_warning_event(event, "%s: not enough memory!", - __func__); - return; - } - memcpy(str, data + field->offset, len); - str[len] =3D 0; - print_str_to_seq(s, format, len_arg, str); - free(str); - break; - case TEP_PRINT_FLAGS: - val =3D eval_num_arg(data, size, event, arg->flags.field); - print =3D 0; - for (flag =3D arg->flags.flags; flag; flag =3D flag->next) { - fval =3D eval_flag(flag->value); - if (!val && fval < 0) { - print_str_to_seq(s, format, len_arg, flag->str); - break; - } - if (fval > 0 && (val & fval) =3D=3D fval) { - if (print && arg->flags.delim) - trace_seq_puts(s, arg->flags.delim); - print_str_to_seq(s, format, len_arg, flag->str); - print =3D 1; - val &=3D ~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 =3D eval_num_arg(data, size, event, arg->symbol.field); - for (flag =3D arg->symbol.symbols; flag; flag =3D flag->next) { - fval =3D eval_flag(flag->value); - if (val =3D=3D 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 =3D=3D TEP_PRINT_DYNAMIC_ARRAY) { - unsigned long offset; - offset =3D tep_read_number(tep, - data + arg->hex.field->dynarray.field->offset, - arg->hex.field->dynarray.field->size); - hex =3D data + (offset & 0xffff); - } else { - field =3D arg->hex.field->field.field; - if (!field) { - str =3D arg->hex.field->field.name; - field =3D tep_find_any_field(event, str); - if (!field) - goto out_warning_field; - arg->hex.field->field.field =3D field; - } - hex =3D data + field->offset; - } - len =3D eval_num_arg(data, size, event, arg->hex.size); - for (i =3D 0; i < len; i++) { - if (i && arg->type =3D=3D 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 =3D=3D TEP_PRINT_DYNAMIC_ARRAY) { - unsigned long offset; - struct tep_format_field *field =3D - arg->int_array.field->dynarray.field; - offset =3D tep_read_number(tep, - data + field->offset, - field->size); - num =3D data + (offset & 0xffff); - } else { - field =3D arg->int_array.field->field.field; - if (!field) { - str =3D arg->int_array.field->field.name; - field =3D tep_find_any_field(event, str); - if (!field) - goto out_warning_field; - arg->int_array.field->field.field =3D field; - } - num =3D data + field->offset; - } - len =3D eval_num_arg(data, size, event, arg->int_array.count); - el_size =3D eval_num_arg(data, size, event, - arg->int_array.el_size); - for (i =3D 0; i < len; i++) { - if (i) - trace_seq_putc(s, ' '); - - if (el_size =3D=3D 1) { - trace_seq_printf(s, "%u", *(uint8_t *)num); - } else if (el_size =3D=3D 2) { - trace_seq_printf(s, "%u", *(uint16_t *)num); - } else if (el_size =3D=3D 4) { - trace_seq_printf(s, "%u", *(uint32_t *)num); - } else if (el_size =3D=3D 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 =3D 1; - } - - num +=3D el_size; - } - break; - } - case TEP_PRINT_TYPE: - break; - case TEP_PRINT_STRING: { - int str_offset; - - if (!arg->string.field) - arg->string.field =3D tep_find_any_field(event, arg->string.string); - if (!arg->string.field) - break; - - str_offset =3D data2host4(tep, - *(unsigned int *)(data + arg->string.field->offset)); - str_offset &=3D 0xffff; - if (arg->string.field->flags & TEP_FIELD_IS_RELATIVE) - str_offset +=3D 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 =3D tep_find_any_field(event, arg->bitmask.bitmask); - if (!arg->bitmask.field) - break; - bitmask_offset =3D data2host4(tep, - *(unsigned int *)(data + arg->bitmask.field->offset)); - bitmask_size =3D bitmask_offset >> 16; - bitmask_offset &=3D 0xffff; - if (arg->bitmask.field->flags & TEP_FIELD_IS_RELATIVE) - bitmask_offset +=3D arg->bitmask.field->offset + arg->bitmask.field->si= ze; - 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] !=3D '?') - return; - val =3D 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 =3D 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 =3D NULL, *string; - int i; - - if (!func_handle->nr_args) { - ret =3D (*func_handle->func)(s, NULL); - goto out; - } - - farg =3D arg->func.args; - param =3D func_handle->params; - - ret =3D ULLONG_MAX; - args =3D malloc(sizeof(*args) * func_handle->nr_args); - if (!args) - goto out; - - for (i =3D 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] =3D 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 =3D malloc(sizeof(*string)); - if (!string) { - do_warning_event(event, "%s(%d): malloc str", - __func__, __LINE__); - goto out_free; - } - string->next =3D strings; - string->str =3D strdup(str.buffer); - if (!string->str) { - free(string); - do_warning_event(event, "%s(%d): malloc str", - __func__, __LINE__); - goto out_free; - } - args[i] =3D (uintptr_t)string->str; - strings =3D 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 =3D farg->next; - param =3D param->next; - } - - ret =3D (*func_handle->func)(s, args); -out_free: - free(args); - while (strings) { - string =3D strings; - strings =3D 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 =3D args->next; - - free_arg(args); - args =3D next; - } -} - -static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int s= ize, struct tep_event *event) -{ - struct tep_handle *tep =3D 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 =3D 0; - - field =3D tep->bprint_buf_field; - ip_field =3D tep->bprint_ip_field; - - if (!field) { - field =3D tep_find_field(event, "buf"); - if (!field) { - do_warning_event(event, "can't find buffer field for binary printk"); - return NULL; - } - ip_field =3D 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 =3D field; - tep->bprint_ip_field =3D ip_field; - } - - ip =3D tep_read_number(tep, data + ip_field->offset, ip_field->size); - - /* - * The first arg is the IP pointer. - */ - args =3D alloc_arg(); - if (!args) { - do_warning_event(event, "%s(%d): not enough memory!", - __func__, __LINE__); - return NULL; - } - arg =3D args; - arg->next =3D NULL; - next =3D &arg->next; - - arg->type =3D TEP_PRINT_ATOM; - =09 - if (asprintf(&arg->atom.atom, "%lld", ip) < 0) - goto out_free; - - /* skip the first "%ps: " */ - for (ptr =3D fmt + 5, bptr =3D data + field->offset; - bptr < data + size && *ptr; ptr++) { - int ls =3D 0; - - if (*ptr =3D=3D '%') { - process_again: - ptr++; - switch (*ptr) { - case '%': - break; - case 'l': - ls++; - goto process_again; - case 'L': - ls =3D 2; - goto process_again; - case '0' ... '9': - goto process_again; - case '.': - goto process_again; - case 'z': - case 'Z': - ls =3D 1; - goto process_again; - case 'p': - ls =3D 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] !=3D '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 =3D 4; - break; - case 1: - vsize =3D tep->long_size; - break; - case 2: - vsize =3D 8; - break; - default: - vsize =3D ls; /* ? */ - break; - } - /* fall through */ - case '*': - if (*ptr =3D=3D '*') - vsize =3D 4; - - /* the pointers are always 4 bytes aligned */ - bptr =3D (void *)(((unsigned long)bptr + 3) & - ~3); - val =3D tep_read_number(tep, bptr, vsize); - bptr +=3D vsize; - arg =3D alloc_arg(); - if (!arg) { - do_warning_event(event, "%s(%d): not enough memory!", - __func__, __LINE__); - goto out_free; - } - arg->next =3D NULL; - arg->type =3D TEP_PRINT_ATOM; - if (asprintf(&arg->atom.atom, "%lld", val) < 0) { - free(arg); - goto out_free; - } - *next =3D arg; - next =3D &arg->next; - /* - * The '*' case means that an arg is used as the length. - * We need to continue to figure out for what. - */ - if (*ptr =3D=3D '*') - goto process_again; - - break; - case 's': - process_string: - arg =3D alloc_arg(); - if (!arg) { - do_warning_event(event, "%s(%d): not enough memory!", - __func__, __LINE__); - goto out_free; - } - arg->next =3D NULL; - arg->type =3D TEP_PRINT_BSTRING; - arg->string.string =3D strdup(bptr); - if (!arg->string.string) - goto out_free; - bptr +=3D strlen(bptr) + 1; - *next =3D arg; - next =3D &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 =3D event->tep; - unsigned long long addr; - struct tep_format_field *field; - struct printk_map *printk; - char *format; - - field =3D tep->bprint_fmt_field; - - if (!field) { - field =3D 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 =3D field; - } - - addr =3D tep_read_number(tep, data + field->offset, field->size); - - printk =3D 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 =3D "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"; - bool reverse =3D false; - unsigned char *buf; - int ret =3D 0; - - if (arg->type =3D=3D TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return 0; - } - - if (arg->type !=3D TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", - arg->type); - return 0; - } - - if (format[0] =3D=3D 'm') { - fmt =3D "%.2x%.2x%.2x%.2x%.2x%.2x"; - } else if (format[0] =3D=3D 'M' && format[1] =3D=3D 'F') { - fmt =3D "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x"; - ret++; - } - if (format[1] =3D=3D 'R') { - reverse =3D true; - ret++; - } - - if (!arg->field.field) { - arg->field.field =3D - 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 !=3D 6) { - trace_seq_printf(s, "INVALIDMAC"); - return ret; - } - - buf =3D 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 =3D 0; - - *reverse =3D false; - - /* hnbl */ - switch (*ptr) { - case 'h': - if (tep->file_bigendian) - *reverse =3D false; - else - *reverse =3D true; - ret++; - break; - case 'l': - *reverse =3D true; - ret++; - break; - case 'n': - case 'b': - ret++; - /* fall through */ - default: - *reverse =3D false; - break; - } - - return ret; -} - -static void print_ip4_addr(struct trace_seq *s, char i, bool reverse, unsi= gned char *buf) -{ - const char *fmt; - - if (i =3D=3D 'i') - fmt =3D "%03d.%03d.%03d.%03d"; - else - fmt =3D "%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))) =3D=3D 0UL; -} - -static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr) -{ - return (addr->s6_addr32[2] | htonl(0x02000000)) =3D=3D htonl(0x02005EFE); -} - -static void print_ip6c_addr(struct trace_seq *s, unsigned char *addr) -{ - int i, j, range; - unsigned char zerolength[8]; - int longest =3D 1; - int colonpos =3D -1; - uint16_t word; - uint8_t hi, lo; - bool needcolon =3D false; - bool useIPv4; - struct in6_addr in6; - - memcpy(&in6, addr, sizeof(struct in6_addr)); - - useIPv4 =3D ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6); - - memset(zerolength, 0, sizeof(zerolength)); - - if (useIPv4) - range =3D 6; - else - range =3D 8; - - /* find position of longest 0 run */ - for (i =3D 0; i < range; i++) { - for (j =3D i; j < range; j++) { - if (in6.s6_addr16[j] !=3D 0) - break; - zerolength[i]++; - } - } - for (i =3D 0; i < range; i++) { - if (zerolength[i] > longest) { - longest =3D zerolength[i]; - colonpos =3D i; - } - } - if (longest =3D=3D 1) /* don't compress a single 0 */ - colonpos =3D -1; - - /* emit address */ - for (i =3D 0; i < range; i++) { - if (i =3D=3D colonpos) { - if (needcolon || i =3D=3D 0) - trace_seq_printf(s, ":"); - trace_seq_printf(s, ":"); - needcolon =3D false; - i +=3D longest - 1; - continue; - } - if (needcolon) { - trace_seq_printf(s, ":"); - needcolon =3D false; - } - /* hex u16 without leading 0s */ - word =3D ntohs(in6.s6_addr16[i]); - hi =3D word >> 8; - lo =3D word & 0xff; - if (hi) - trace_seq_printf(s, "%x%02x", hi, lo); - else - trace_seq_printf(s, "%x", lo); - - needcolon =3D 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 =3D 0; j < 16; j +=3D 2) { - trace_seq_printf(s, "%02x%02x", buf[j], buf[j+1]); - if (i =3D=3D '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 =3D false; - unsigned char *buf; - int ret; - - ret =3D parse_ip4_print_args(event->tep, ptr, &reverse); - - if (arg->type =3D=3D TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return ret; - } - - if (arg->type !=3D TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return ret; - } - - if (!arg->field.field) { - arg->field.field =3D - 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 =3D data + arg->field.field->offset; - - if (arg->field.field->size !=3D 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 =3D 0; - unsigned char *buf; - int rc =3D 0; - - /* pI6c */ - if (i =3D=3D 'I' && *ptr =3D=3D 'c') { - have_c =3D 1; - ptr++; - rc++; - } - - if (arg->type =3D=3D TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return rc; - } - - if (arg->type !=3D TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return rc; - } - - if (!arg->field.field) { - arg->field.field =3D - 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 =3D data + arg->field.field->offset; - - if (arg->field.field->size !=3D 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 =3D 0, have_p =3D 0; - unsigned char *buf; - struct sockaddr_storage *sa; - bool reverse =3D false; - int rc =3D 0; - int ret; - - /* pISpc */ - if (i =3D=3D 'I') { - if (*ptr =3D=3D 'p') { - have_p =3D 1; - ptr++; - rc++; - } - if (*ptr =3D=3D 'c') { - have_c =3D 1; - ptr++; - rc++; - } - } - ret =3D parse_ip4_print_args(event->tep, ptr, &reverse); - ptr +=3D ret; - rc +=3D ret; - - if (arg->type =3D=3D TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return rc; - } - - if (arg->type !=3D TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return rc; - } - - if (!arg->field.field) { - arg->field.field =3D - 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 =3D (struct sockaddr_storage *) (data + arg->field.field->offset); - - if (sa->ss_family =3D=3D AF_INET) { - struct sockaddr_in *sa4 =3D (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 =3D=3D AF_INET6) { - struct sockaddr_in6 *sa6 =3D (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 =3D (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 =3D *ptr; /* 'i' or 'I' */ - int rc =3D 1; - - /* IP version */ - ptr++; - - switch (*ptr) { - case '4': - rc +=3D print_ipv4_arg(s, ptr + 1, i, data, size, event, arg); - break; - case '6': - rc +=3D print_ipv6_arg(s, ptr + 1, i, data, size, event, arg); - break; - case 'S': - rc +=3D print_ipsa_arg(s, ptr + 1, i, data, size, event, arg); - break; - default: - return 0; - } - - return rc; -} - -static const int guid_index[16] =3D {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11,= 12, 13, 14, 15}; -static const int uuid_index[16] =3D {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 =3D uuid_index; - char *format =3D "%02x"; - int ret =3D 0; - char *buf; - int i; - - switch (*(ptr + 1)) { - case 'L': - format =3D "%02X"; - /* fall through */ - case 'l': - index =3D guid_index; - ret++; - break; - case 'B': - format =3D "%02X"; - /* fall through */ - case 'b': - ret++; - break; - } - - if (arg->type =3D=3D TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return ret; - } - - if (arg->type !=3D TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return ret; - } - - if (!arg->field.field) { - arg->field.field =3D - 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 !=3D 16) { - trace_seq_printf(s, "INVALIDUUID"); - return ret; - } - - buf =3D data + arg->field.field->offset; - - for (i =3D 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 =3D print_len; - char *delim =3D " "; - int ret =3D 0; - char *buf; - int i; - unsigned long offset; - int arr_len; - - switch (*(ptr + 1)) { - case 'C': - delim =3D ":"; - ret++; - break; - case 'D': - delim =3D "-"; - ret++; - break; - case 'N': - delim =3D ""; - ret++; - break; - } - - if (arg->type =3D=3D TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return ret; - } - - if (arg->type !=3D TEP_PRINT_DYNAMIC_ARRAY) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return ret; - } - - offset =3D tep_read_number(event->tep, - data + arg->dynarray.field->offset, - arg->dynarray.field->size); - arr_len =3D (unsigned long long)(offset >> 16); - buf =3D data + (offset & 0xffff); - - if (arr_len < plen) - plen =3D arr_len; - - if (plen < 1) - return ret; - - trace_seq_printf(s, "%02x", buf[0] & 0xff); - for (i =3D 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 =3D 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 =3D field->event->tep; - - if (field->flags & TEP_FIELD_IS_ARRAY) { - offset =3D field->offset; - len =3D field->size; - if (field->flags & TEP_FIELD_IS_DYNAMIC) { - val =3D tep_read_number(tep, data + offset, len); - offset =3D val; - len =3D offset >> 16; - offset &=3D 0xffff; - if (field->flags & TEP_FIELD_IS_RELATIVE) - offset +=3D 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 =3D 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 &=3D ~TEP_FIELD_IS_STRING; - } - } else { - val =3D 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 =3D event->format.fields; - while (field) { - trace_seq_printf(s, " %s=3D", field->name); - tep_print_field(s, data, field); - field =3D 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 =3D eval_num_arg(data, size, event, arg); - func =3D find_func(event->tep, val); - if (func) { - trace_seq_puts(s, func->func); - if (*format =3D=3D 'F' || *format =3D=3D 'S') - trace_seq_printf(s, "+0x%llx", val - func->addr); - } else { - if (event->tep->long_size =3D=3D 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 =3D 1; - - if (arg->type =3D=3D TEP_PRINT_BSTRING) { - trace_seq_puts(s, arg->string.string); - return 0; - } - while (*format) { - if (*format =3D=3D 'p') { - format++; - break; - } - format++; - } - - switch (*format) { - case 'F': - case 'f': - case 'S': - case 's': - ret +=3D print_function(s, format, data, size, event, arg); - break; - case 'M': - case 'm': - ret +=3D print_mac_arg(s, format, data, size, event, arg); - break; - case 'I': - case 'i': - ret +=3D print_ip_arg(s, format, data, size, event, arg); - break; - case 'U': - ret +=3D print_uuid_arg(s, format, data, size, event, arg); - break; - case 'h': - ret +=3D print_raw_buff_arg(s, format, data, size, event, arg, plen); - break; - default: - ret =3D 0; - val =3D 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 p= len, - void *data, int size, int ls, - struct tep_event *event, struct tep_print_arg *arg) -{ - unsigned long long val; - - val =3D eval_num_arg(data, size, event, arg); - - switch (ls) { - case -2: - if (plen >=3D 0) - trace_seq_printf(s, format, plen, (char)val); - else - trace_seq_printf(s, format, (char)val); - break; - case -1: - if (plen >=3D 0) - trace_seq_printf(s, format, plen, (short)val); - else - trace_seq_printf(s, format, (short)val); - break; - case 0: - if (plen >=3D 0) - trace_seq_printf(s, format, plen, (int)val); - else - trace_seq_printf(s, format, (int)val); - break; - case 1: - if (plen >=3D 0) - trace_seq_printf(s, format, plen, (long)val); - else - trace_seq_printf(s, format, (long)val); - break; - case 2: - if (plen >=3D 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 |=3D 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 =3D 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 =3D 2; - loop =3D 1; - switch (format[1]) { - case 'S': - /*[S][pfs]*/ - while (loop) { - switch (format[index]) { - case 'p': - case 'f': - case 's': - ret++; - index++; - break; - default: - loop =3D 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] =3D=3D '4') { - ret++; - break; - } - /* fall through */ - case '6': - /* [6S]c */ - if (format[index] =3D=3D '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 =3D arg; - arg =3D 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 =3D NULL; - - parg =3D calloc(1, sizeof(*parg)); - if (!parg) - goto error; - parg->format =3D strdup(format); - if (!parg->format) - goto error; - parg->type =3D type; - parg->arg =3D arg; - parg->len_as_arg =3D len_as_arg; - parg->ls =3D ls; - *parse =3D 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 =3D NULL; - char print_format[32]; - const char *start =3D format; - int ret =3D 0; - int ls =3D 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 =3D 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 |=3D TEP_EVENT_FL_FAILED; - goto out_failed; - } - if (len_arg) { - do_warning_event(event, "argument already matched"); - event->flags |=3D TEP_EVENT_FL_FAILED; - goto out_failed; - } - len_arg =3D *arg; - *arg =3D (*arg)->next; - break; - case 'p': - if (!*arg) { - do_warning_event(event, "no argument match"); - event->flags |=3D TEP_EVENT_FL_FAILED; - goto out_failed; - } - res =3D parse_arg_format_pointer(format + 1); - if (res > 0) { - format +=3D res; - ret +=3D res; - } - len =3D ((unsigned long)format + 1) - - (unsigned long)start; - /* should never happen */ - if (len > 31) { - do_warning_event(event, "bad format!"); - event->flags |=3D TEP_EVENT_FL_FAILED; - len =3D 31; - } - memcpy(print_format, start, len); - print_format[len] =3D 0; - - parse_arg_add(parse, print_format, - PRINT_FMT_ARG_POINTER, *arg, len_arg, ls); - *arg =3D (*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 |=3D TEP_EVENT_FL_FAILED; - goto out_failed; - } - - len =3D ((unsigned long)format + 1) - - (unsigned long)start; - - /* should never happen */ - if (len > 30) { - do_warning_event(event, "bad format!"); - event->flags |=3D TEP_EVENT_FL_FAILED; - len =3D 31; - } - memcpy(print_format, start, len); - print_format[len] =3D 0; - - if (event->tep->long_size =3D=3D 8 && ls =3D=3D 1 && - sizeof(long) !=3D 8) { - char *p; - - /* make %l into %ll */ - if (ls =3D=3D 1 && (p =3D strchr(print_format, 'l'))) - memmove(p+1, p, strlen(p)+1); - ls =3D 2; - } - if (ls < -2 || ls > 2) { - do_warning_event(event, "bad count (%d)", ls); - event->flags |=3D TEP_EVENT_FL_FAILED; - } - parse_arg_add(parse, print_format, - PRINT_FMT_ARG_DIGIT, *arg, len_arg, ls); - *arg =3D (*arg)->next; - ret++; - return ret; - case 's': - if (!*arg) { - do_warning_event(event, "no matching argument"); - event->flags |=3D TEP_EVENT_FL_FAILED; - goto out_failed; - } - - len =3D ((unsigned long)format + 1) - - (unsigned long)start; - - /* should never happen */ - if (len > 31) { - do_warning_event(event, "bad format!"); - event->flags |=3D TEP_EVENT_FL_FAILED; - len =3D 31; - } - - memcpy(print_format, start, len); - print_format[len] =3D 0; - - parse_arg_add(parse, print_format, - PRINT_FMT_ARG_STRING, *arg, len_arg, 0); - *arg =3D (*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 *fo= rmat) -{ - struct trace_seq s; - int ret =3D 0; - - trace_seq_init(&s); - for (; *format; format++) { - if (*format =3D=3D '\\') { - 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 =3D=3D '%') { - if (*(format + 1) =3D=3D '%') { - 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_a= rg *arg) -{ - struct tep_print_parse *parse_ret =3D NULL; - struct tep_print_parse **parse =3D NULL; - int ret; - int len; - - len =3D strlen(format); - while (*format) { - if (!parse_ret) - parse =3D &parse_ret; - if (*format =3D=3D '%' && *(format + 1) !=3D '%') - ret =3D parse_arg_format(parse, event, format, &arg); - else - ret =3D parse_arg_string(parse, format); - if (*parse) - parse =3D &((*parse)->next); - - len -=3D ret; - if (len > 0) - format +=3D 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 =3D 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 =3D parse->next; - } -} - -static void pretty_print(struct trace_seq *s, void *data, int size, struct= tep_event *event) -{ - struct tep_print_parse *parse =3D event->print_fmt.print_cache; - struct tep_print_arg *args =3D NULL; - char *bprint_fmt =3D 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 =3D get_bprint_format(data, size, event); - args =3D make_bprint_args(bprint_fmt, data, size, event); - parse =3D 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 =3D 1; - static int check_migrate_disable =3D 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 =3D 0; - int migrate_disable =3D 0; - int hardirq; - int softirq; - void *data =3D record->data; - - trace_seq_init(&sq); - lat_flags =3D parse_common_flags(tep, data); - pc =3D parse_common_pc(tep, data); - /* lock_depth may not always exist */ - if (lock_depth_exists) - lock_depth =3D parse_common_lock_depth(tep, data); - else if (check_lock_depth) { - lock_depth =3D parse_common_lock_depth(tep, data); - if (lock_depth < 0) - check_lock_depth =3D 0; - else - lock_depth_exists =3D 1; - } - - /* migrate_disable may not always exist */ - if (migrate_disable_exists) - migrate_disable =3D parse_common_migrate_disable(tep, data); - else if (check_migrate_disable) { - migrate_disable =3D parse_common_migrate_disable(tep, data); - if (migrate_disable < 0) - check_migrate_disable =3D 0; - else - migrate_disable_exists =3D 1; - } - - hardirq =3D lat_flags & TRACE_FLAG_HARDIRQ; - softirq =3D 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 =3D=3D TRACE_SEQ__MEM_ALLOC_FAILED) { - s->state =3D 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 =3D find_cmdline(tep, pid); - return comm; -} - -static struct tep_cmdline * -pid_from_cmdlist(struct tep_handle *tep, const char *comm, struct tep_cmdl= ine *next) -{ - struct cmdline_list *cmdlist =3D (struct cmdline_list *)next; - - if (cmdlist) - cmdlist =3D cmdlist->next; - else - cmdlist =3D tep->cmdlist; - - while (cmdlist && strcmp(cmdlist->comm, comm) !=3D 0) - cmdlist =3D 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 c= har *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 >=3D tep->cmdlines + tep->cmdline_count) - next =3D NULL; - else - cmdline =3D next++; - } - - if (!next) - cmdline =3D tep->cmdlines; - - while (cmdline < tep->cmdlines + tep->cmdline_count) { - if (strcmp(cmdline->comm, comm) =3D=3D 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 =3D (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 >=3D 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 =3D 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 =3D 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 =3D 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 =3D 0, pr; - int div =3D 0; - int p10 =3D 1; - - if (isdigit(*(format + 1))) - prec =3D atoi(format + 1); - divstr =3D strchr(format, '.'); - if (divstr && isdigit(*(divstr + 1))) - div =3D atoi(divstr + 1); - time =3D record->ts; - if (div) { - time +=3D div / 2; - time /=3D div; - } - pr =3D prec; - while (pr--) - p10 *=3D 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 =3D 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)) =3D=3D 0) { - data_latency_format(tep, s, type->format, record); - } else if (strncmp(arg, TEP_PRINT_COMM, strlen(TEP_PRINT_COMM)) =3D=3D 0)= { - pid =3D parse_common_pid(tep, record->data); - comm =3D find_cmdline(tep, pid); - trace_seq_printf(s, type->format, comm); - } else if (strncmp(arg, TEP_PRINT_INFO_RAW, strlen(TEP_PRINT_INFO_RAW)) = =3D=3D 0) { - print_event_info(s, type->format, true, event, record); - } else if (strncmp(arg, TEP_PRINT_INFO, strlen(TEP_PRINT_INFO)) =3D=3D 0)= { - print_event_info(s, type->format, false, event, record); - } else if (strncmp(arg, TEP_PRINT_NAME, strlen(TEP_PRINT_NAME)) =3D=3D 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 =3D record->cpu; - break; - case TEP_PRINT_PID: - param =3D 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 =3D format + 1; - int i =3D 1; - - type->type =3D EVENT_TYPE_UNKNOWN; - while (*str) { - switch (*str) { - case 'd': - case 'u': - case 'i': - case 'x': - case 'X': - case 'o': - type->type =3D EVENT_TYPE_INT; - break; - case 's': - type->type =3D EVENT_TYPE_STRING; - break; - } - str++; - i++; - if (type->type !=3D 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 =3D strdup(fmt); - char *current =3D format; - char *str =3D format; - int offset; - va_list args; - struct tep_event *event; - - if (!format) - return; - - event =3D tep_find_event_by_record(tep, record); - va_start(args, fmt); - while (*current) { - current =3D strchr(str, '%'); - if (!current) { - trace_seq_puts(s, str); - break; - } - memset(&type, 0, sizeof(type)); - offset =3D tep_print_event_param_type(current, &type); - *current =3D '\0'; - trace_seq_puts(s, str); - current +=3D 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 =3D current; - - } - va_end(args); - free(format); -} - -static int events_id_cmp(const void *a, const void *b) -{ - struct tep_event * const * ea =3D a; - struct tep_event * const * eb =3D 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 =3D a; - struct tep_event * const * eb =3D b; - int res; - - res =3D strcmp((*ea)->name, (*eb)->name); - if (res) - return res; - - res =3D 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 =3D a; - struct tep_event * const * eb =3D b; - int res; - - res =3D strcmp((*ea)->system, (*eb)->system); - if (res) - return res; - - res =3D 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 =3D malloc(sizeof(*events) * (tep->nr_events + 1)); - if (!events) - return NULL; - - memcpy(events, tep->events, sizeof(*events) * tep->nr_events); - events[tep->nr_events] =3D 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 =3D events_id_cmp; - break; - case TEP_EVENT_SORT_NAME: - sort =3D events_name_cmp; - break; - case TEP_EVENT_SORT_SYSTEM: - sort =3D events_system_cmp; - break; - default: - sort =3D 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 =3D tep->sort_events; - if (events && tep->last_type =3D=3D sort_type) - return events; - - if (!events) { - events =3D list_events_copy(tep); - if (!events) - return NULL; - - tep->sort_events =3D events; - - /* the internal events are sorted by id */ - if (sort_type =3D=3D TEP_EVENT_SORT_ID) { - tep->last_type =3D sort_type; - return events; - } - } - - list_events_sort(events, tep->nr_events, sort_type); - tep->last_type =3D 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 c= aller - */ -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 =3D list_events_copy(tep); - if (!events) - return NULL; - - /* the internal events are sorted by id */ - if (sort_type =3D=3D 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 =3D 0; - - fields =3D malloc(sizeof(*fields) * (count + 1)); - if (!fields) - return NULL; - - for (field =3D list; field; field =3D field->next) { - fields[i++] =3D field; - if (i =3D=3D count + 1) { - do_warning("event %s has more %s fields than specified", - name, type); - i--; - break; - } - } - - if (i !=3D count) - do_warning("event %s has less %s fields than specified", - name, type); - - fields[i] =3D 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 NUL= L. - * 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 NUL= L. - * 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 *f= ield) -{ - 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 =3D 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, ":") =3D=3D 0) - print_paren =3D 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 =3D input_buf_ptr; - save_input_buf_siz =3D 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) !=3D 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 =3D 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 =3D atoi(token); - free_token(token); - if (read_expected(TEP_EVENT_OP, ";") < 0) - return; - type =3D read_token(&token); - if (type !=3D TEP_EVENT_NEWLINE) { - /* newer versions of the kernel have a "signed" type */ - if (type !=3D TEP_EVENT_ITEM) - goto fail; - - if (strcmp(token, "signed") !=3D 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 =3D save_input_buf_ptr; - input_buf_siz =3D save_input_buf_siz; - *offset =3D 0; - *size =3D 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 =3D sizeof(long long); - tep->header_page_size_size =3D long_size; - tep->header_page_data_offset =3D sizeof(long long) + long_size; - tep->old_format =3D 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 >=3D 0 && id !=3D event->id) - return 0; - - if (event_name && (strcmp(event_name, event->name) !=3D 0)) - return 0; - - if (sys_name && (strcmp(sys_name, event->system) !=3D 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 *eve= nt) -{ - struct event_handler *handle, **next; - - for (next =3D &tep->handlers; *next; - next =3D &(*next)->next) { - handle =3D *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 =3D handle->func; - event->context =3D handle->context; - - *next =3D 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 =3D event =3D alloc_event(); - if (!event) - return TEP_ERRNO__MEM_ALLOC_FAILED; - - event->name =3D event_read_name(); - if (!event->name) { - /* Bad event? */ - ret =3D TEP_ERRNO__MEM_ALLOC_FAILED; - goto event_alloc_failed; - } - - if (strcmp(sys, "ftrace") =3D=3D 0) { - event->flags |=3D TEP_EVENT_FL_ISFTRACE; - - if (strcmp(event->name, "bprint") =3D=3D 0) - event->flags |=3D TEP_EVENT_FL_ISBPRINT; - } - =09 - event->id =3D event_read_id(); - if (event->id < 0) { - ret =3D 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 =3D strdup(sys); - if (!event->system) { - ret =3D TEP_ERRNO__MEM_ALLOC_FAILED; - goto event_alloc_failed; - } - - /* Add tep to event so that it can be referenced */ - event->tep =3D tep; - - ret =3D event_read_format(event); - if (ret < 0) { - ret =3D 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 =3D 0; - - ret =3D event_read_print(event); - show_warning =3D 1; - - if (ret < 0) { - ret =3D 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 =3D &event->print_fmt.args; - for (field =3D event->format.fields; field; field =3D field->next) { - arg =3D alloc_arg(); - if (!arg) { - event->flags |=3D TEP_EVENT_FL_FAILED; - return TEP_ERRNO__OLD_FTRACE_ARG_FAILED; - } - arg->type =3D TEP_PRINT_FIELD; - arg->field.name =3D strdup(field->name); - if (!arg->field.name) { - event->flags |=3D TEP_EVENT_FL_FAILED; - free_arg(arg); - return TEP_ERRNO__OLD_FTRACE_ARG_FAILED; - } - arg->field.field =3D field; - *list =3D arg; - list =3D &arg->next; - } - } - - if (!(event->flags & TEP_EVENT_FL_ISBPRINT)) - event->print_fmt.print_cache =3D parse_args(event, - event->print_fmt.format, - event->print_fmt.args); - - return 0; - - event_parse_failed: - event->flags |=3D TEP_EVENT_FL_FAILED; - return ret; - - event_alloc_failed: - free(event->system); - free(event->name); - free(event); - *eventp =3D 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 =3D parse_format(eventp, tep, buf, size, sys); - struct tep_event *event =3D *eventp; - - if (event =3D=3D NULL) - return ret; - - if (tep && add_event(tep, event)) { - ret =3D 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 =3D 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=3DINVALID", 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 =3D record->data; - unsigned offset; - int dummy; - - if (!event) - return NULL; - - field =3D tep_find_field(event, name); - - if (!field) { - if (err) - trace_seq_printf(s, "", name); - return NULL; - } - - /* Allow @len to be NULL */ - if (!len) - len =3D &dummy; - - offset =3D field->offset; - if (field->flags & TEP_FIELD_IS_DYNAMIC) { - offset =3D tep_read_number(event->tep, - data + offset, field->size); - *len =3D offset >> 16; - offset &=3D 0xffff; - if (field->flags & TEP_FIELD_IS_RELATIVE) - offset +=3D field->offset + field->size; - } else - *len =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D tep_find_field(event, name); - struct tep_handle *tep =3D 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 =3D 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 =3D func->params; - func->params =3D 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 =3D 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 =3D 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 =3D ret_type; - func_handle->name =3D strdup(name); - func_handle->func =3D func; - if (!func_handle->name) { - do_warning("Failed to allocate function name"); - free(func_handle); - return TEP_ERRNO__MEM_ALLOC_FAILED; - } - - next_param =3D &(func_handle->params); - va_start(ap, name); - for (;;) { - type =3D va_arg(ap, enum tep_func_arg_type); - if (type =3D=3D TEP_FUNC_ARG_VOID) - break; - - if (type >=3D TEP_FUNC_ARG_MAX_TYPES) { - do_warning("Invalid argument type %d", type); - ret =3D TEP_ERRNO__INVALID_ARG_TYPE; - goto out_free; - } - - param =3D malloc(sizeof(*param)); - if (!param) { - do_warning("Failed to allocate function param"); - ret =3D TEP_ERRNO__MEM_ALLOC_FAILED; - goto out_free; - } - param->type =3D type; - param->next =3D NULL; - - *next_param =3D param; - next_param =3D &(param->next); - - func_handle->nr_args++; - } - va_end(ap); - - func_handle->next =3D tep->func_handlers; - tep->func_handlers =3D 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 =3D find_func_handler(tep, name); - if (func_handle && func_handle->func =3D=3D 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 >=3D 0) { - /* search by id */ - event =3D tep_find_event(tep, id); - if (!event) - return NULL; - if (event_name && (strcmp(event_name, event->name) !=3D 0)) - return NULL; - if (sys_name && (strcmp(sys_name, event->system) !=3D 0)) - return NULL; - } else { - event =3D 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 >=3D 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 =3D search_event(tep, id, sys_name, event_name); - if (event =3D=3D NULL) - goto not_found; - - pr_stat("overriding event (%d) %s:%s with new print handler", - event->id, event->system, event->name); - - event->handler =3D func; - event->context =3D context; - return TEP_REGISTER_SUCCESS_OVERWRITE; - - not_found: - /* Save for later use. */ - handle =3D calloc(1, sizeof(*handle)); - if (!handle) { - do_warning("Failed to allocate event handler"); - return TEP_ERRNO__MEM_ALLOC_FAILED; - } - - handle->id =3D id; - if (event_name) - handle->event_name =3D strdup(event_name); - if (sys_name) - handle->sys_name =3D 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 =3D func; - handle->next =3D tep->handlers; - tep->handlers =3D handle; - handle->context =3D 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 >=3D 0 && id !=3D handler->id) - return 0; - - if (event_name && (strcmp(event_name, handler->event_name) !=3D 0)) - return 0; - - if (sys_name && (strcmp(sys_name, handler->sys_name) !=3D 0)) - return 0; - - if (func !=3D handler->func || context !=3D 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 >=3D 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 foun= d. - */ -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 =3D search_event(tep, id, sys_name, event_name); - if (event =3D=3D NULL) - goto not_found; - - if (event->handler =3D=3D func && event->context =3D=3D context) { - pr_stat("removing override handler for event (%d) %s:%s. Going back to d= efault handler.", - event->id, event->system, event->name); - - event->handler =3D NULL; - event->context =3D NULL; - return 0; - } - -not_found: - for (next =3D &tep->handlers; *next; next =3D &(*next)->next) { - handle =3D *next; - if (handle_matches(handle, id, sys_name, event_name, - func, context)) - break; - } - - if (!(*next)) - return -1; - - *next =3D handle->next; - free_handler(handle); - - return 0; -} - -/** - * tep_alloc - create a tep handle - */ -struct tep_handle *tep_alloc(void) -{ - struct tep_handle *tep =3D calloc(1, sizeof(*tep)); - - if (tep) { - tep->ref_count =3D 1; - tep->host_bigendian =3D 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 !=3D 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 =3D field->next; - free_tep_format_field(field); - field =3D 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 =3D tep->cmdlist; - funclist =3D tep->funclist; - printklist =3D tep->printklist; - - tep->ref_count--; - if (tep->ref_count) - return; - - if (tep->cmdlines) { - for (i =3D 0; i < tep->cmdline_count; i++) - free(tep->cmdlines[i].comm); - free(tep->cmdlines); - } - - while (cmdlist) { - cmdnext =3D cmdlist->next; - free(cmdlist->comm); - free(cmdlist); - cmdlist =3D cmdnext; - } - - if (tep->func_map) { - for (i =3D 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 =3D funclist->next; - free(funclist->func); - free(funclist->mod); - free(funclist); - funclist =3D funcnext; - } - - while (tep->func_handlers) { - func_handler =3D tep->func_handlers; - tep->func_handlers =3D func_handler->next; - free_func_handle(func_handler); - } - - if (tep->printk_map) { - for (i =3D 0; i < (int)tep->printk_count; i++) - free(tep->printk_map[i].printk); - free(tep->printk_map); - } - - while (printklist) { - printknext =3D printklist->next; - free(printklist->printk); - free(printklist); - printklist =3D printknext; - } - - for (i =3D 0; i < tep->nr_events; i++) - free_tep_event(tep->events[i]); - - while (tep->handlers) { - handle =3D tep->handlers; - tep->handlers =3D 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/even= t-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[] =3D { - * { - * .name =3D "option-name", - * .plugin_alias =3D "override-file-name", (optional) - * .description =3D "description of option to show users", - * }, - * { - * .name =3D NULL, - * }, - * }; - * - * Array must end with .name =3D 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 =3D 1, - TEP_FIELD_IS_POINTER =3D 2, - TEP_FIELD_IS_SIGNED =3D 4, - TEP_FIELD_IS_STRING =3D 8, - TEP_FIELD_IS_DYNAMIC =3D 16, - TEP_FIELD_IS_LONG =3D 32, - TEP_FIELD_IS_FLAG =3D 64, - TEP_FIELD_IS_SYMBOLIC =3D 128, - TEP_FIELD_IS_RELATIVE =3D 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 =3D 0x01, - TEP_EVENT_FL_ISPRINT =3D 0x02, - TEP_EVENT_FL_ISBPRINT =3D 0x04, - TEP_EVENT_FL_ISFUNCENT =3D 0x10, - TEP_EVENT_FL_ISFUNCRET =3D 0x20, - TEP_EVENT_FL_NOHANDLE =3D 0x40, - TEP_EVENT_FL_PRINTRAW =3D 0x80, - - TEP_EVENT_FL_FAILED =3D 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 =3D 1, /* output in NSECS */ - TEP_DISABLE_SYS_PLUGINS =3D 1 << 1, - TEP_DISABLE_PLUGINS =3D 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 =3D 0, - TEP_ERRNO__FILTER_MATCH =3D 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 =3D -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[] =3D { 0x1, 0x2, 0x3, 0x4 }; - unsigned int val; - - memcpy(&val, str, 4); - return val =3D=3D 0x01020304; -} - -/* taken from kernel/trace/trace.h */ -enum trace_flag_type { - TRACE_FLAG_IRQS_OFF =3D 0x01, - TRACE_FLAG_IRQS_NOSUPPORT =3D 0x02, - TRACE_FLAG_NEED_RESCHED =3D 0x04, - TRACE_FLAG_HARDIRQ =3D 0x08, - TRACE_FLAG_SOFTIRQ =3D 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 =3D 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, co= nst char *name); -struct tep_format_field *tep_find_field(struct tep_event *event, const cha= r *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 a= ddr); -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 c= har *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 =3D 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 endia= n); -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 =3D 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 er= r, - 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/eve= nt-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 =3D tolower(*str); -} - -static int update_option_value(struct tep_plugin_option *op, const char *v= al) -{ - char *op_val; - - if (!val) { - /* toggle, only if option is boolean */ - if (op->value) - /* Warn? */ - return 0; - op->set ^=3D 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 =3D val; - return 0; - } - - /* Option is boolean, must be either "1", "0", "true" or "false" */ - - op_val =3D strdup(val); - if (!op_val) - return -1; - lower_case(op_val); - - if (strcmp(val, "1") =3D=3D 0 || strcmp(val, "true") =3D=3D 0) - op->set =3D 1; - else if (strcmp(val, "0") =3D=3D 0 || strcmp(val, "false") =3D=3D 0) - op->set =3D 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 :