aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/evsel.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r--tools/perf/util/evsel.c57
1 files changed, 46 insertions, 11 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index a03a36b7908a..e389815078d3 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
343int perf_event__parse_sample(const union perf_event *event, u64 type, 345int 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,27 @@ 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 const u64 *pdata;
453
454 u.val64 = *array;
455 if (WARN_ONCE(swapped,
456 "Endianness of raw data not corrected!\n")) {
457 /* undo swap of u64, then swap on individual u32s */
458 u.val64 = bswap_64(u.val64);
459 u.val32[0] = bswap_32(u.val32[0]);
460 u.val32[1] = bswap_32(u.val32[1]);
461 }
427 462
428 if (sample_overlap(event, array, sizeof(u32))) 463 if (sample_overlap(event, array, sizeof(u32)))
429 return -EFAULT; 464 return -EFAULT;
430 465
431 data->raw_size = *p; 466 data->raw_size = u.val32[0];
432 p++; 467 pdata = (void *) array + sizeof(u32);
433 468
434 if (sample_overlap(event, p, data->raw_size)) 469 if (sample_overlap(event, pdata, data->raw_size))
435 return -EFAULT; 470 return -EFAULT;
436 471
437 data->raw_data = p; 472 data->raw_data = (void *) pdata;
438 } 473 }
439 474
440 return 0; 475 return 0;