[PATCH V13 09/12] perf tools: expand perf_event__synthesize_sample()
Expand perf_event__synthesize_sample() to handle all sample format bits. Signed-off-by: Adrian Hunter --- tools/perf/builtin-inject.c | 4 +- tools/perf/util/event.h | 1 + tools/perf/util/evsel.c | 95 - 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ffacd46..9b336fd 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -301,7 +301,9 @@ found: sample_sw.period = sample->period; sample_sw.time = sample->time; perf_event__synthesize_sample(event_sw, evsel->attr.sample_type, - _sw, false); + evsel->attr.sample_regs_user, + evsel->attr.read_format, _sw, + false); build_id__mark_dso_hit(tool, event_sw, _sw, evsel, machine); return perf_event__repipe(tool, event_sw, _sw, machine); } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index f959801..1c80e13 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -230,6 +230,7 @@ int perf_event__preprocess_sample(const union perf_event *self, const char *perf_event__name(unsigned int id); int perf_event__synthesize_sample(union perf_event *event, u64 type, + u64 sample_regs_user, u64 read_format, const struct perf_sample *sample, bool swapped); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 1184188..7d62373 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1416,7 +1416,6 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, } if (type & PERF_SAMPLE_REGS_USER) { - /* First u64 tells us if we have any regs in sample. */ OVERFLOW_CHECK_u64(array); data->user_regs.abi = *array; array++; @@ -1467,11 +1466,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, } int perf_event__synthesize_sample(union perf_event *event, u64 type, + u64 sample_regs_user, u64 read_format, const struct perf_sample *sample, bool swapped) { u64 *array; - + size_t sz; /* * used for cross-endian analysis. See git commit 65014ab3 * for why this goofiness is needed. @@ -1544,6 +1544,97 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, array++; } + if (type & PERF_SAMPLE_READ) { + if (read_format & PERF_FORMAT_GROUP) + *array = sample->read.group.nr; + else + *array = sample->read.one.value; + array++; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { + *array = sample->read.time_enabled; + array++; + } + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { + *array = sample->read.time_running; + array++; + } + + /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ + if (read_format & PERF_FORMAT_GROUP) { + sz = sample->read.group.nr * +sizeof(struct sample_read_value); + memcpy(array, sample->read.group.values, sz); + array = (void *)array + sz; + } else { + *array = sample->read.one.id; + array++; + } + } + + if (type & PERF_SAMPLE_CALLCHAIN) { + sz = (sample->callchain->nr + 1) * sizeof(u64); + memcpy(array, sample->callchain, sz); + array = (void *)array + sz; + } + + if (type & PERF_SAMPLE_RAW) { + u.val32[0] = sample->raw_size; + if (WARN_ONCE(swapped, + "Endianness of raw data not corrected!\n")) { + /* +* Inverse of what is done in perf_evsel__parse_sample +*/ + u.val32[0] = bswap_32(u.val32[0]); + u.val32[1] = bswap_32(u.val32[1]); + u.val64 = bswap_64(u.val64); + } + *array = u.val64; + array = (void *)array + sizeof(u32); + + memcpy(array, sample->raw_data, sample->raw_size); + array = (void *)array + sample->raw_size; + } + + if (type & PERF_SAMPLE_BRANCH_STACK) { + sz = sample->branch_stack->nr * sizeof(struct branch_entry); + sz += sizeof(u64); +
[PATCH V13 09/12] perf tools: expand perf_event__synthesize_sample()
Expand perf_event__synthesize_sample() to handle all sample format bits. Signed-off-by: Adrian Hunter adrian.hun...@intel.com --- tools/perf/builtin-inject.c | 4 +- tools/perf/util/event.h | 1 + tools/perf/util/evsel.c | 95 - 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ffacd46..9b336fd 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -301,7 +301,9 @@ found: sample_sw.period = sample-period; sample_sw.time = sample-time; perf_event__synthesize_sample(event_sw, evsel-attr.sample_type, - sample_sw, false); + evsel-attr.sample_regs_user, + evsel-attr.read_format, sample_sw, + false); build_id__mark_dso_hit(tool, event_sw, sample_sw, evsel, machine); return perf_event__repipe(tool, event_sw, sample_sw, machine); } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index f959801..1c80e13 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -230,6 +230,7 @@ int perf_event__preprocess_sample(const union perf_event *self, const char *perf_event__name(unsigned int id); int perf_event__synthesize_sample(union perf_event *event, u64 type, + u64 sample_regs_user, u64 read_format, const struct perf_sample *sample, bool swapped); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 1184188..7d62373 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1416,7 +1416,6 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, } if (type PERF_SAMPLE_REGS_USER) { - /* First u64 tells us if we have any regs in sample. */ OVERFLOW_CHECK_u64(array); data-user_regs.abi = *array; array++; @@ -1467,11 +1466,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, } int perf_event__synthesize_sample(union perf_event *event, u64 type, + u64 sample_regs_user, u64 read_format, const struct perf_sample *sample, bool swapped) { u64 *array; - + size_t sz; /* * used for cross-endian analysis. See git commit 65014ab3 * for why this goofiness is needed. @@ -1544,6 +1544,97 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, array++; } + if (type PERF_SAMPLE_READ) { + if (read_format PERF_FORMAT_GROUP) + *array = sample-read.group.nr; + else + *array = sample-read.one.value; + array++; + + if (read_format PERF_FORMAT_TOTAL_TIME_ENABLED) { + *array = sample-read.time_enabled; + array++; + } + + if (read_format PERF_FORMAT_TOTAL_TIME_RUNNING) { + *array = sample-read.time_running; + array++; + } + + /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ + if (read_format PERF_FORMAT_GROUP) { + sz = sample-read.group.nr * +sizeof(struct sample_read_value); + memcpy(array, sample-read.group.values, sz); + array = (void *)array + sz; + } else { + *array = sample-read.one.id; + array++; + } + } + + if (type PERF_SAMPLE_CALLCHAIN) { + sz = (sample-callchain-nr + 1) * sizeof(u64); + memcpy(array, sample-callchain, sz); + array = (void *)array + sz; + } + + if (type PERF_SAMPLE_RAW) { + u.val32[0] = sample-raw_size; + if (WARN_ONCE(swapped, + Endianness of raw data not corrected!\n)) { + /* +* Inverse of what is done in perf_evsel__parse_sample +*/ + u.val32[0] = bswap_32(u.val32[0]); + u.val32[1] = bswap_32(u.val32[1]); + u.val64 = bswap_64(u.val64); + } + *array = u.val64; + array = (void *)array + sizeof(u32); + + memcpy(array, sample-raw_data, sample-raw_size); + array = (void *)array + sample-raw_size; + } + + if (type PERF_SAMPLE_BRANCH_STACK) { + sz = sample-branch_stack-nr * sizeof(struct branch_entry); + sz +=