|
@@ -1465,6 +1465,98 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
|
|
|
+ u64 sample_regs_user, u64 read_format)
|
|
|
+{
|
|
|
+ size_t sz, result = sizeof(struct sample_event);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_IDENTIFIER)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_IP)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_TID)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_TIME)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_ADDR)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_ID)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_STREAM_ID)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_CPU)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_PERIOD)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_READ) {
|
|
|
+ result += sizeof(u64);
|
|
|
+ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
|
|
|
+ result += sizeof(u64);
|
|
|
+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
|
|
|
+ result += sizeof(u64);
|
|
|
+ /* 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);
|
|
|
+ result += sz;
|
|
|
+ } else {
|
|
|
+ result += sizeof(u64);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_CALLCHAIN) {
|
|
|
+ sz = (sample->callchain->nr + 1) * sizeof(u64);
|
|
|
+ result += sz;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_RAW) {
|
|
|
+ result += sizeof(u32);
|
|
|
+ result += sample->raw_size;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_BRANCH_STACK) {
|
|
|
+ sz = sample->branch_stack->nr * sizeof(struct branch_entry);
|
|
|
+ sz += sizeof(u64);
|
|
|
+ result += sz;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_REGS_USER) {
|
|
|
+ if (sample->user_regs.abi) {
|
|
|
+ result += sizeof(u64);
|
|
|
+ sz = hweight_long(sample_regs_user) * sizeof(u64);
|
|
|
+ result += sz;
|
|
|
+ } else {
|
|
|
+ result += sizeof(u64);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_STACK_USER) {
|
|
|
+ sz = sample->user_stack.size;
|
|
|
+ result += sizeof(u64);
|
|
|
+ if (sz) {
|
|
|
+ result += sz;
|
|
|
+ result += sizeof(u64);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_WEIGHT)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ if (type & PERF_SAMPLE_DATA_SRC)
|
|
|
+ result += sizeof(u64);
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
int perf_event__synthesize_sample(union perf_event *event, u64 type,
|
|
|
u64 sample_regs_user, u64 read_format,
|
|
|
const struct perf_sample *sample,
|