From: Ian Rogers <irogers@google.com>
To: Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
John Fastabend <john.fastabend@gmail.com>,
Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jiri Olsa <jolsa@kernel.org>,
Emil Tsalapatis <emil@etsalapatis.com>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
James Clark <james.clark@linaro.org>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Mike Leach <mike.leach@arm.com>, Leo Yan <leo.yan@arm.com>,
John Garry <john.g.garry@oracle.com>,
Will Deacon <will@kernel.org>, Thomas Gleixner <tglx@kernel.org>,
Dapeng Mi <dapeng1.mi@linux.intel.com>,
Ravi Bangoria <ravi.bangoria@amd.com>,
Swapnil Sapkal <swapnil.sapkal@amd.com>,
Thomas Falcon <thomas.falcon@intel.com>,
Thomas Richter <tmricht@linux.ibm.com>,
Dmitrii Dolgov <9erthalion6@gmail.com>,
Eric Biggers <ebiggers@kernel.org>, Zecheng Li <zli94@ncsu.edu>,
Gabriel Marin <gmx@google.com>,
Tengda Wu <wutengda@huaweicloud.com>,
Derek Foreman <derek.foreman@collabora.com>,
Tanushree Shah <tshah@linux.ibm.com>,
Ankur Arora <ankur.a.arora@oracle.com>,
Aaron Tomlin <atomlin@atomlin.com>, tanze <tanze@kylinos.cn>,
Rui Qi <qirui.001@bytedance.com>,
Howard Chu <howardchu95@gmail.com>, Chuck Lever <cel@kernel.org>,
Shimin Guo <shimin.guo@skydio.com>,
Alessio Podda <aleph.pi.gh@gmail.com>,
linux-kernel@vger.kernel.org, bpf@vger.kernel.org,
linux-perf-users@vger.kernel.org, coresight@lists.linaro.org,
linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH v1 6/8] perf inject: Extend perf inject to support bid_offset conversion
Date: Fri, 7 Aug 2026 00:18:16 -0700 [thread overview]
Message-ID: <20260807071818.718751-7-irogers@google.com> (raw)
In-Reply-To: <20260807071818.718751-1-irogers@google.com>
This adds the --sample-buildids option to perf inject, allowing it to
drop MMAP events and rewrite samples to use build IDs and offsets
instead of virtual addresses.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/builtin-inject.c | 14 +-
tools/perf/util/Build | 1 +
tools/perf/util/inject_bid_offset.c | 504 ++++++++++++++++++++++++++++
tools/perf/util/inject_bid_offset.h | 21 ++
4 files changed, 539 insertions(+), 1 deletion(-)
create mode 100644 tools/perf/util/inject_bid_offset.c
create mode 100644 tools/perf/util/inject_bid_offset.h
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 6aa9e3eea438..8f8d5267a37e 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -9,6 +9,7 @@
#include "builtin.h"
#include "util/aslr.h"
+#include "util/inject_bid_offset.h"
#include "util/color.h"
#include "util/dso.h"
#include "util/vdso.h"
@@ -112,6 +113,7 @@ enum build_id_rewrite_style {
BID_RWS__INJECT_HEADER_ALL,
BID_RWS__MMAP2_BUILDID_ALL,
BID_RWS__MMAP2_BUILDID_LAZY,
+ BID_RWS__SAMPLE_BUILDID,
};
struct perf_inject {
@@ -371,7 +373,7 @@ static s64 perf_event__repipe_auxtrace(const struct perf_tool *tool,
return event->auxtrace.size;
}
-static int perf_event__repipe(const struct perf_tool *tool,
+int perf_event__repipe(const struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample __maybe_unused,
struct machine *machine __maybe_unused)
@@ -2687,6 +2689,7 @@ int cmd_inject(int argc, const char **argv)
bool build_id_all = false;
bool mmap2_build_ids = false;
bool mmap2_build_id_all = false;
+ bool build_id_sample = false;
struct option options[] = {
OPT_BOOLEAN('b', "build-ids", &build_ids,
@@ -2695,8 +2698,11 @@ int cmd_inject(int argc, const char **argv)
"Inject build-ids of all DSOs into the output stream"),
OPT_BOOLEAN('B', "mmap2-buildids", &mmap2_build_ids,
"Drop unused mmap events, make others mmap2 with build IDs"),
+
OPT_BOOLEAN(0, "mmap2-buildid-all", &mmap2_build_id_all,
"Rewrite all mmap events as mmap2 events with build IDs"),
+ OPT_BOOLEAN('S', "sample-buildids", &build_id_sample,
+ "Drop all mmap events and rewrite samples to use build ID + offset"),
OPT_STRING(0, "known-build-ids", &known_build_ids,
"buildid path [,buildid path...]",
"build-ids to use for given paths"),
@@ -2815,8 +2821,11 @@ int cmd_inject(int argc, const char **argv)
inject.build_id_style = BID_RWS__MMAP2_BUILDID_ALL;
if (build_ids)
inject.build_id_style = BID_RWS__INJECT_HEADER_LAZY;
+
if (build_id_all)
inject.build_id_style = BID_RWS__INJECT_HEADER_ALL;
+ if (build_id_sample)
+ inject.build_id_style = BID_RWS__SAMPLE_BUILDID;
data.path = inject.input_name;
@@ -2880,8 +2889,11 @@ int cmd_inject(int argc, const char **argv)
if (IS_ERR(inject.session)) {
ret = PTR_ERR(inject.session);
+
if (inject.aslr)
aslr_tool__delete(tool);
+ if (inject.build_id_style == BID_RWS__SAMPLE_BUILDID)
+ inject_bid_offset_tool__delete(tool);
goto out_close_output;
}
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 330311cac550..cefbf2ef3fac 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -7,6 +7,7 @@ perf-util-y += addr2line.o
perf-util-y += addr_location.o
perf-util-y += annotate.o
perf-util-y += aslr.o
+perf-util-y += inject_bid_offset.o
perf-util-y += blake2s.o
perf-util-y += block-info.o
perf-util-y += block-range.o
diff --git a/tools/perf/util/inject_bid_offset.c b/tools/perf/util/inject_bid_offset.c
new file mode 100644
index 000000000000..f7b5fb05fac7
--- /dev/null
+++ b/tools/perf/util/inject_bid_offset.c
@@ -0,0 +1,504 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "inject_bid_offset.h"
+
+#include <stdlib.h>
+
+#include <linux/compiler.h>
+#include <linux/string.h>
+#include <linux/zalloc.h>
+
+#include "addr_location.h"
+#include "debug.h"
+#include "dso.h"
+#include "event.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "machine.h"
+#include "map.h"
+#include "session.h"
+#include "synthetic-events.h"
+#include "thread.h"
+#include "tool.h"
+
+struct inject_bid_offset_tool {
+ struct delegate_tool tool;
+ char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8);
+};
+
+int perf_event__rewrite_attr_for_build_id_offset(struct perf_event_attr *attr)
+{
+ if (attr->sample_type & (PERF_SAMPLE_BUILD_ID_OFFSET |
+ PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET)) {
+ /*
+ * Expect to add build ID information from virtual address, if
+ * it is already present then things would be confused so fail.
+ */
+ return -1;
+ }
+ if (attr->sample_type & PERF_SAMPLE_IP) {
+ attr->sample_type &= ~PERF_SAMPLE_IP;
+ attr->sample_type |= PERF_SAMPLE_BUILD_ID_OFFSET;
+ }
+ if (attr->sample_type & PERF_SAMPLE_CALLCHAIN) {
+ attr->sample_type &= ~PERF_SAMPLE_CALLCHAIN;
+ attr->sample_type |= PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET;
+ }
+ return 0;
+}
+
+int perf_event__rewrite_attr_for_sample_ip(struct perf_event_attr *attr)
+{
+ if (attr->sample_type & (PERF_SAMPLE_IP | PERF_SAMPLE_CALLCHAIN)) {
+ /*
+ * Expect to remove build ID information for virtual address, if
+ * it is already present then things would be confused so fail.
+ */
+ return -1;
+ }
+ if (attr->sample_type & PERF_SAMPLE_BUILD_ID_OFFSET) {
+ attr->sample_type &= ~PERF_SAMPLE_BUILD_ID_OFFSET;
+ attr->sample_type |= PERF_SAMPLE_IP;
+ }
+ if (attr->sample_type & PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET) {
+ attr->sample_type &= ~PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET;
+ attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
+ }
+ return 0;
+}
+
+static void perf_event__inject_sample_buildid_array(struct thread *thread,
+ u64 ip, u8 cpumode,
+ __u64 *array)
+{
+ struct perf_build_id bid = { .size = 0 };
+ u64 offset = ip;
+ struct addr_location al;
+ struct dso *dso;
+ const struct build_id *dso_bid;
+
+ struct perf_sample ps = { .ip = ip, .cpumode = cpumode };
+
+ addr_location__init(&al);
+
+ if (!thread)
+ goto write_bid;
+
+ if (!thread__find_map(thread, &ps, &al))
+ goto write_bid;
+
+ dso = al.map ? dso__get(map__dso(al.map)) : NULL;
+ if (!dso)
+ goto write_bid;
+ dso_bid = dso__bid(dso);
+ if (!dso_bid) {
+ dso__put(dso);
+ goto write_bid;
+ }
+
+ bid.size = dso_bid->size;
+ if (bid.size > sizeof(bid.data))
+ bid.size = sizeof(bid.data);
+ memcpy(bid.data, &dso_bid->data, bid.size);
+ offset = map__dso_map_ip(al.map, offset);
+ dso__put(dso);
+
+write_bid:
+ compiletime_assert(sizeof(struct perf_build_id) == 3 * sizeof(u64),
+ "Unexpected perf_build_id size");
+ memcpy(&array[0], &bid, 3 * sizeof(u64));
+ array[3] = offset;
+ addr_location__exit(&al);
+}
+
+static void mark_dso_hit(const struct perf_tool *tool,
+ struct perf_sample *sample, struct machine *machine,
+ struct thread *thread, u64 ip, u8 cpumode)
+{
+ struct addr_location al;
+ struct dso *dso;
+
+ struct perf_sample ps = { .ip = ip, .cpumode = cpumode };
+
+ addr_location__init(&al);
+
+ if (thread__find_map(thread, &ps, &al)) {
+ dso = al.map ? dso__get(map__dso(al.map)) : NULL;
+ if (dso) {
+ if (!dso__hit(dso)) {
+ const struct build_id *bid = dso__bid(dso);
+
+ dso__set_hit(dso);
+ if (bid) {
+ perf_event__synthesize_build_id(
+ tool, sample, machine,
+ perf_event__repipe,
+ dso__kernel(dso) ?
+ PERF_RECORD_MISC_KERNEL :
+ PERF_RECORD_MISC_USER,
+ bid, dso->long_name);
+ }
+ }
+ dso__put(dso);
+ }
+ }
+ addr_location__exit(&al);
+}
+
+static int inject_bid_offset_tool__sample(const struct perf_tool *tool,
+ union perf_event *event,
+ struct perf_sample *sample,
+ struct machine *machine)
+{
+ struct delegate_tool *dt =
+ container_of(tool, struct delegate_tool, tool);
+ struct inject_bid_offset_tool *ibo =
+ container_of(dt, struct inject_bid_offset_tool, tool);
+ union perf_event *ev;
+ struct evsel *evsel = sample->evsel;
+ __u64 i = 0, j = 0;
+ __u64 *in_array, *out_array;
+ __u64 sample_type = evsel->core.attr.sample_type;
+ const __u64 max_i = event->header.size / sizeof(__u64);
+ struct thread *thread;
+ u16 max_size = event->header.size;
+
+ if ((sample_type & (PERF_SAMPLE_IP | PERF_SAMPLE_CALLCHAIN)) == 0)
+ return ibo->tool.delegate->sample(ibo->tool.delegate, event,
+ sample, machine);
+
+ if (symbol_conf.guest_code && !machine__is_host(machine))
+ thread = machine__findnew_guest_code(machine, sample->pid);
+ else
+ thread = machine__findnew_thread(machine, sample->pid,
+ sample->tid);
+
+ if (sample_type & PERF_SAMPLE_IP)
+ max_size += sizeof(struct perf_build_id) + sizeof(u64) -
+ sizeof(u64);
+
+ if (sample_type & PERF_SAMPLE_CALLCHAIN) {
+ max_size +=
+ sample->callchain->nr * (sizeof(struct perf_build_id) +
+ sizeof(u64) - sizeof(u64));
+ }
+
+ if (max_size > PERF_SAMPLE_MAX_SIZE) {
+ pr_debug("Insufficient space to copy event\n");
+ thread__put(thread);
+ return -E2BIG;
+ }
+
+ ev = (union perf_event *)ibo->event_copy;
+ ev->sample.header =
+ (struct perf_event_header){ .type = event->header.type,
+ .misc = event->header.misc,
+ .size = max_size };
+
+ in_array = &event->sample.array[0];
+ out_array = &ev->sample.array[0];
+
+ if (sample_type & PERF_SAMPLE_IDENTIFIER) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_IP) {
+ i++;
+ if (evsel && thread)
+ mark_dso_hit(ibo->tool.delegate, sample, machine,
+ thread, sample->ip, sample->cpumode);
+ }
+ if (sample_type & PERF_SAMPLE_TID) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_TIME) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_ADDR) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_ID) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_STREAM_ID) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_CPU) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_PERIOD) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_READ) {
+ if ((evsel->core.attr.read_format & PERF_FORMAT_GROUP) == 0) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (evsel->core.attr.read_format &
+ PERF_FORMAT_TOTAL_TIME_ENABLED)
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (evsel->core.attr.read_format &
+ PERF_FORMAT_TOTAL_TIME_RUNNING)
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (evsel->core.attr.read_format & PERF_FORMAT_ID)
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (evsel->core.attr.read_format & PERF_FORMAT_LOST)
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ } else {
+ u64 nr;
+
+ if (i > max_i)
+ goto err;
+ nr = out_array[j++] = in_array[i++];
+ if (evsel->core.attr.read_format &
+ PERF_FORMAT_TOTAL_TIME_ENABLED)
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (evsel->core.attr.read_format &
+ PERF_FORMAT_TOTAL_TIME_RUNNING)
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ for (u64 cntr = 0; cntr < nr; cntr++) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (evsel->core.attr.read_format &
+ PERF_FORMAT_ID)
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (evsel->core.attr.read_format &
+ PERF_FORMAT_LOST)
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ }
+ }
+ if (sample_type & PERF_SAMPLE_CALLCHAIN) {
+ i++;
+ if (evsel && thread) {
+ for (u64 x = 0; x < sample->callchain->nr; x++)
+ mark_dso_hit(ibo->tool.delegate, sample,
+ machine, thread,
+ sample->callchain->ips[x],
+ sample->cpumode);
+ }
+ i += sample->callchain->nr;
+ }
+ if (sample_type & PERF_SAMPLE_RAW) {
+ size_t bytes = sizeof(u32) + sample->raw_size;
+
+ if ((i + (bytes / sizeof(u64))) > max_i)
+ goto err;
+ memcpy(&out_array[j], &in_array[i], bytes);
+ i += bytes / sizeof(u64);
+ j += bytes / sizeof(u64);
+ }
+ if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (sample_type & PERF_SAMPLE_BRANCH_HW_INDEX) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (i + (sample->branch_stack->nr * 3) > max_i)
+ goto err;
+ memcpy(&out_array[j], &in_array[i],
+ sample->branch_stack->nr * 3 * sizeof(u64));
+ i += sample->branch_stack->nr * 3;
+ j += sample->branch_stack->nr * 3;
+ if (sample_type & PERF_SAMPLE_BRANCH_COUNTERS) {
+ if (i + sample->branch_stack->nr > max_i)
+ goto err;
+ memcpy(&out_array[j], &in_array[i],
+ sample->branch_stack->nr * sizeof(u64));
+ i += sample->branch_stack->nr;
+ j += sample->branch_stack->nr;
+ }
+ }
+ if (sample_type & PERF_SAMPLE_REGS_USER) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (sample->user_regs->abi != PERF_SAMPLE_REGS_ABI_NONE) {
+ u64 nr = hweight64(evsel->core.attr.sample_regs_user);
+
+ if (i + nr > max_i)
+ goto err;
+ memcpy(&out_array[j], &in_array[i], nr * sizeof(u64));
+ i += nr;
+ j += nr;
+ }
+ }
+ if (sample_type & PERF_SAMPLE_STACK_USER) {
+ u64 size;
+
+ if (i > max_i)
+ goto err;
+ size = out_array[j++] = in_array[i++];
+ if (size > 0) {
+ memcpy(&out_array[j], &in_array[i], size);
+ i += size / sizeof(u64);
+ j += size / sizeof(u64);
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ }
+ if (sample_type & PERF_SAMPLE_WEIGHT_TYPE) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_DATA_SRC) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_TRANSACTION) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_REGS_INTR) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ if (sample->intr_regs->abi != PERF_SAMPLE_REGS_ABI_NONE) {
+ u64 nr = hweight64(evsel->core.attr.sample_regs_intr);
+
+ if (i + nr > max_i)
+ goto err;
+ memcpy(&out_array[j], &in_array[i], nr * sizeof(u64));
+ i += nr;
+ j += nr;
+ }
+ }
+ if (sample_type & PERF_SAMPLE_PHYS_ADDR) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_CGROUP) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_DATA_PAGE_SIZE) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_CODE_PAGE_SIZE) {
+ if (i > max_i)
+ goto err;
+ out_array[j++] = in_array[i++];
+ }
+ if (sample_type & PERF_SAMPLE_AUX) {
+ u64 size;
+
+ if (i > max_i)
+ goto err;
+ size = out_array[j++] = in_array[i++];
+ if (i + (size / sizeof(u64)) > max_i)
+ goto err;
+ memcpy(&out_array[j], &in_array[i], size);
+ i += size / sizeof(u64);
+ j += size / sizeof(u64);
+ }
+
+ if (sample_type & PERF_SAMPLE_IP) {
+ perf_event__inject_sample_buildid_array(
+ thread, sample->ip, sample->cpumode, &out_array[j]);
+ j += 4;
+ }
+ if (sample_type & PERF_SAMPLE_CALLCHAIN) {
+ out_array[j++] = sample->callchain->nr;
+ for (u64 x = 0; x < sample->callchain->nr; x++) {
+ perf_event__inject_sample_buildid_array(
+ thread, sample->callchain->ips[x],
+ sample->cpumode, &out_array[j]);
+ j += 4;
+ }
+ }
+
+ thread__put(thread);
+
+ return ibo->tool.delegate->sample(ibo->tool.delegate, ev, sample,
+ machine);
+
+err:
+ thread__put(thread);
+ return -EFAULT;
+}
+
+static int
+inject_bid_offset_tool__mmap(const struct perf_tool *tool __maybe_unused,
+ union perf_event *event,
+ struct perf_sample *sample,
+ struct machine *machine)
+{
+ perf_event__process_mmap(tool, event, sample, machine);
+ return 0; // Drop mmap events from output stream
+}
+static int
+inject_bid_offset_tool__mmap2(const struct perf_tool *tool __maybe_unused,
+ union perf_event *event,
+ struct perf_sample *sample,
+ struct machine *machine)
+{
+ perf_event__process_mmap2(tool, event, sample, machine);
+ return 0; // Drop mmap2 events from output stream
+}
+
+struct perf_tool *inject_bid_offset_tool__new(struct perf_tool *delegate)
+{
+ struct inject_bid_offset_tool *ibo = zalloc(sizeof(*ibo));
+
+ if (!ibo)
+ return NULL;
+
+ delegate_tool__init(&ibo->tool, delegate);
+ ibo->tool.tool.sample = inject_bid_offset_tool__sample;
+ ibo->tool.tool.mmap = inject_bid_offset_tool__mmap;
+ ibo->tool.tool.mmap2 = inject_bid_offset_tool__mmap2;
+
+ return &ibo->tool.tool;
+}
+
+void inject_bid_offset_tool__delete(struct perf_tool *tool)
+{
+ struct delegate_tool *dt;
+
+ if (!tool)
+ return;
+ dt = container_of(tool, struct delegate_tool, tool);
+ free(container_of(dt, struct inject_bid_offset_tool, tool));
+}
diff --git a/tools/perf/util/inject_bid_offset.h b/tools/perf/util/inject_bid_offset.h
new file mode 100644
index 000000000000..e4cfea255f6b
--- /dev/null
+++ b/tools/perf/util/inject_bid_offset.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PERF_INJECT_BID_OFFSET_H
+#define __PERF_INJECT_BID_OFFSET_H
+
+#include <linux/perf_event.h>
+
+struct perf_tool;
+struct evlist;
+
+int perf_event__rewrite_attr_for_build_id_offset(struct perf_event_attr *attr);
+int perf_event__rewrite_attr_for_sample_ip(struct perf_event_attr *attr);
+union perf_event;
+struct perf_sample;
+struct machine;
+
+int perf_event__repipe(const struct perf_tool *tool, union perf_event *event,
+ struct perf_sample *sample, struct machine *machine);
+struct perf_tool *inject_bid_offset_tool__new(struct perf_tool *delegate);
+void inject_bid_offset_tool__delete(struct perf_tool *tool);
+
+#endif /* __PERF_INJECT_BID_OFFSET_H */
--
2.55.0.679.g6767b8d81c-goog
next prev parent reply other threads:[~2026-08-07 7:18 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 7:18 [RFC PATCH v1 0/8] perf/core, perf/tools: Add PERF_SAMPLE_BUILD_ID_OFFSET support Ian Rogers
2026-08-07 7:18 ` [RFC PATCH v1 1/8] perf event: Factor build_id out into its own top-level struct Ian Rogers
2026-08-07 7:33 ` sashiko-bot
2026-08-07 7:18 ` [RFC PATCH v1 2/8] perf/core: Add BUILD_ID_OFFSET to UAPI Ian Rogers
2026-08-07 7:42 ` sashiko-bot
2026-08-07 7:18 ` [RFC PATCH v1 3/8] perf/core: Implement BUILD_ID_OFFSET sample type Ian Rogers
2026-08-07 7:54 ` sashiko-bot
2026-08-07 7:18 ` [RFC PATCH v1 4/8] perf: Refactor thread map and symbol APIs to take perf_sample Ian Rogers
2026-08-07 8:20 ` sashiko-bot
2026-08-07 7:18 ` [RFC PATCH v1 5/8] perf tools: Internal support for BUILD_ID_OFFSET Ian Rogers
2026-08-07 8:41 ` sashiko-bot
2026-08-07 7:18 ` Ian Rogers [this message]
2026-08-07 9:18 ` [RFC PATCH v1 6/8] perf inject: Extend perf inject to support bid_offset conversion sashiko-bot
2026-08-07 7:18 ` [RFC PATCH v1 7/8] perf record: Add --buildid-offset option Ian Rogers
2026-08-07 9:47 ` sashiko-bot
2026-08-07 7:18 ` [RFC PATCH v1 8/8] perf tests: Add build_id_offset test coverage Ian Rogers
2026-08-07 9:58 ` sashiko-bot
2026-08-07 11:18 ` [RFC PATCH v1 0/8] perf/core, perf/tools: Add PERF_SAMPLE_BUILD_ID_OFFSET support Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260807071818.718751-7-irogers@google.com \
--to=irogers@google.com \
--cc=9erthalion6@gmail.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=aleph.pi.gh@gmail.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=andrii@kernel.org \
--cc=ankur.a.arora@oracle.com \
--cc=ast@kernel.org \
--cc=atomlin@atomlin.com \
--cc=bpf@vger.kernel.org \
--cc=cel@kernel.org \
--cc=coresight@lists.linaro.org \
--cc=daniel@iogearbox.net \
--cc=dapeng1.mi@linux.intel.com \
--cc=derek.foreman@collabora.com \
--cc=ebiggers@kernel.org \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=gmx@google.com \
--cc=howardchu95@gmail.com \
--cc=james.clark@linaro.org \
--cc=john.fastabend@gmail.com \
--cc=john.g.garry@oracle.com \
--cc=jolsa@kernel.org \
--cc=leo.yan@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=mhiramat@kernel.org \
--cc=mike.leach@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=qirui.001@bytedance.com \
--cc=ravi.bangoria@amd.com \
--cc=rostedt@goodmis.org \
--cc=shimin.guo@skydio.com \
--cc=song@kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=swapnil.sapkal@amd.com \
--cc=tanze@kylinos.cn \
--cc=tglx@kernel.org \
--cc=thomas.falcon@intel.com \
--cc=tmricht@linux.ibm.com \
--cc=tshah@linux.ibm.com \
--cc=will@kernel.org \
--cc=wutengda@huaweicloud.com \
--cc=yonghong.song@linux.dev \
--cc=zli94@ncsu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox