diff options
| -rw-r--r-- | tools/perf/builtin-test.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/event.h | 2 | ||||
| -rw-r--r-- | tools/perf/util/evsel.c | 54 | ||||
| -rw-r--r-- | tools/perf/util/session.h | 3 |
4 files changed, 47 insertions, 14 deletions
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 55f4c76f2821..efe696f936e2 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
| @@ -561,7 +561,7 @@ static int test__basic_mmap(void) | |||
| 561 | } | 561 | } |
| 562 | 562 | ||
| 563 | err = perf_event__parse_sample(event, attr.sample_type, sample_size, | 563 | err = perf_event__parse_sample(event, attr.sample_type, sample_size, |
| 564 | false, &sample); | 564 | false, &sample, false); |
| 565 | if (err) { | 565 | if (err) { |
| 566 | pr_err("Can't parse sample, err = %d\n", err); | 566 | pr_err("Can't parse sample, err = %d\n", err); |
| 567 | goto out_munmap; | 567 | goto out_munmap; |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 1d7f66488a88..357a85b85248 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
| @@ -186,6 +186,6 @@ const char *perf_event__name(unsigned int id); | |||
| 186 | 186 | ||
| 187 | int perf_event__parse_sample(const union perf_event *event, u64 type, | 187 | int perf_event__parse_sample(const union perf_event *event, u64 type, |
| 188 | int sample_size, bool sample_id_all, | 188 | int sample_size, bool sample_id_all, |
| 189 | struct perf_sample *sample); | 189 | struct perf_sample *sample, bool swapped); |
| 190 | 190 | ||
| 191 | #endif /* __PERF_RECORD_H */ | 191 | #endif /* __PERF_RECORD_H */ |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index a03a36b7908a..c5748c52318f 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | * Released under the GPL v2. (and only v2, not any later version) | 7 | * Released under the GPL v2. (and only v2, not any later version) |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <byteswap.h> | ||
| 11 | #include "asm/bug.h" | ||
| 10 | #include "evsel.h" | 12 | #include "evsel.h" |
| 11 | #include "evlist.h" | 13 | #include "evlist.h" |
| 12 | #include "util.h" | 14 | #include "util.h" |
| @@ -342,10 +344,20 @@ static bool sample_overlap(const union perf_event *event, | |||
| 342 | 344 | ||
| 343 | int perf_event__parse_sample(const union perf_event *event, u64 type, | 345 | int perf_event__parse_sample(const union perf_event *event, u64 type, |
| 344 | int sample_size, bool sample_id_all, | 346 | int sample_size, bool sample_id_all, |
| 345 | struct perf_sample *data) | 347 | struct perf_sample *data, bool swapped) |
| 346 | { | 348 | { |
| 347 | const u64 *array; | 349 | const u64 *array; |
| 348 | 350 | ||
| 351 | /* | ||
| 352 | * used for cross-endian analysis. See git commit 65014ab3 | ||
| 353 | * for why this goofiness is needed. | ||
| 354 | */ | ||
| 355 | union { | ||
| 356 | u64 val64; | ||
| 357 | u32 val32[2]; | ||
| 358 | } u; | ||
| 359 | |||
| 360 | |||
| 349 | data->cpu = data->pid = data->tid = -1; | 361 | data->cpu = data->pid = data->tid = -1; |
| 350 | data->stream_id = data->id = data->time = -1ULL; | 362 | data->stream_id = data->id = data->time = -1ULL; |
| 351 | 363 | ||
| @@ -366,9 +378,16 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, | |||
| 366 | } | 378 | } |
| 367 | 379 | ||
| 368 | if (type & PERF_SAMPLE_TID) { | 380 | if (type & PERF_SAMPLE_TID) { |
| 369 | u32 *p = (u32 *)array; | 381 | u.val64 = *array; |
| 370 | data->pid = p[0]; | 382 | if (swapped) { |
| 371 | data->tid = p[1]; | 383 | /* undo swap of u64, then swap on individual u32s */ |
| 384 | u.val64 = bswap_64(u.val64); | ||
| 385 | u.val32[0] = bswap_32(u.val32[0]); | ||
| 386 | u.val32[1] = bswap_32(u.val32[1]); | ||
| 387 | } | ||
| 388 | |||
| 389 | data->pid = u.val32[0]; | ||
| 390 | data->tid = u.val32[1]; | ||
| 372 | array++; | 391 | array++; |
| 373 | } | 392 | } |
| 374 | 393 | ||
| @@ -395,8 +414,15 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, | |||
| 395 | } | 414 | } |
| 396 | 415 | ||
| 397 | if (type & PERF_SAMPLE_CPU) { | 416 | if (type & PERF_SAMPLE_CPU) { |
| 398 | u32 *p = (u32 *)array; | 417 | |
| 399 | data->cpu = *p; | 418 | u.val64 = *array; |
| 419 | if (swapped) { | ||
| 420 | /* undo swap of u64, then swap on individual u32s */ | ||
| 421 | u.val64 = bswap_64(u.val64); | ||
| 422 | u.val32[0] = bswap_32(u.val32[0]); | ||
| 423 | } | ||
| 424 | |||
| 425 | data->cpu = u.val32[0]; | ||
| 400 | array++; | 426 | array++; |
| 401 | } | 427 | } |
| 402 | 428 | ||
| @@ -423,18 +449,24 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, | |||
| 423 | } | 449 | } |
| 424 | 450 | ||
| 425 | if (type & PERF_SAMPLE_RAW) { | 451 | if (type & PERF_SAMPLE_RAW) { |
| 426 | u32 *p = (u32 *)array; | 452 | u.val64 = *array; |
| 453 | if (WARN_ONCE(swapped, | ||
| 454 | "Endianness of raw data not corrected!\n")) { | ||
| 455 | /* undo swap of u64, then swap on individual u32s */ | ||
| 456 | u.val64 = bswap_64(u.val64); | ||
| 457 | u.val32[0] = bswap_32(u.val32[0]); | ||
| 458 | u.val32[1] = bswap_32(u.val32[1]); | ||
| 459 | } | ||
| 427 | 460 | ||
| 428 | if (sample_overlap(event, array, sizeof(u32))) | 461 | if (sample_overlap(event, array, sizeof(u32))) |
| 429 | return -EFAULT; | 462 | return -EFAULT; |
| 430 | 463 | ||
| 431 | data->raw_size = *p; | 464 | data->raw_size = u.val32[0]; |
| 432 | p++; | ||
| 433 | 465 | ||
| 434 | if (sample_overlap(event, p, data->raw_size)) | 466 | if (sample_overlap(event, &u.val32[1], data->raw_size)) |
| 435 | return -EFAULT; | 467 | return -EFAULT; |
| 436 | 468 | ||
| 437 | data->raw_data = p; | 469 | data->raw_data = &u.val32[1]; |
| 438 | } | 470 | } |
| 439 | 471 | ||
| 440 | return 0; | 472 | return 0; |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 170601e67d6b..974d0cbee5e9 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -162,7 +162,8 @@ static inline int perf_session__parse_sample(struct perf_session *session, | |||
| 162 | { | 162 | { |
| 163 | return perf_event__parse_sample(event, session->sample_type, | 163 | return perf_event__parse_sample(event, session->sample_type, |
| 164 | session->sample_size, | 164 | session->sample_size, |
| 165 | session->sample_id_all, sample); | 165 | session->sample_id_all, sample, |
| 166 | session->header.needs_swap); | ||
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | 169 | struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, |
