diff options
author | Jiri Olsa <jolsa@redhat.com> | 2014-01-07 07:47:29 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-02-18 07:34:49 -0500 |
commit | c9b951c4d12f0b2e9a07dd459c554bc05628d092 (patch) | |
tree | caa1bbe8ea8ccf5490589bf366215218068f0a4f /tools/perf/util/unwind-libunwind.c | |
parent | 9ff125d132001c02d32a193a9423be0690526e11 (diff) |
perf callchain: Separate perf_reg_value function in perf_regs object
Making perf_reg_value function global (formely reg_value), because it's
going to be used globaly across all code providing the dwarf post unwind
feature.
Changing its prototype to be generic:
-int reg_value(unw_word_t *valp, struct regs_dump *regs, int id)
+int perf_reg_value(u64 *valp, struct regs_dump *regs, int id);
Changing the valp type from libunwind specific 'unw_word_t' to u64.
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Jean Pihet <jean.pihet@linaro.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1389098853-14466-13-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/unwind-libunwind.c')
-rw-r--r-- | tools/perf/util/unwind-libunwind.c | 38 |
1 files changed, 12 insertions, 26 deletions
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 79dbfbbeb5ed..bd5768d74f01 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c | |||
@@ -390,30 +390,13 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr, | |||
390 | return !(size == sizeof(*data)); | 390 | return !(size == sizeof(*data)); |
391 | } | 391 | } |
392 | 392 | ||
393 | static int reg_value(unw_word_t *valp, struct regs_dump *regs, int id) | ||
394 | { | ||
395 | int i, idx = 0; | ||
396 | u64 mask = regs->mask; | ||
397 | |||
398 | if (!(mask & (1 << id))) | ||
399 | return -EINVAL; | ||
400 | |||
401 | for (i = 0; i < id; i++) { | ||
402 | if (mask & (1 << i)) | ||
403 | idx++; | ||
404 | } | ||
405 | |||
406 | *valp = regs->regs[idx]; | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | static int access_mem(unw_addr_space_t __maybe_unused as, | 393 | static int access_mem(unw_addr_space_t __maybe_unused as, |
411 | unw_word_t addr, unw_word_t *valp, | 394 | unw_word_t addr, unw_word_t *valp, |
412 | int __write, void *arg) | 395 | int __write, void *arg) |
413 | { | 396 | { |
414 | struct unwind_info *ui = arg; | 397 | struct unwind_info *ui = arg; |
415 | struct stack_dump *stack = &ui->sample->user_stack; | 398 | struct stack_dump *stack = &ui->sample->user_stack; |
416 | unw_word_t start, end; | 399 | u64 start, end; |
417 | int offset; | 400 | int offset; |
418 | int ret; | 401 | int ret; |
419 | 402 | ||
@@ -423,7 +406,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as, | |||
423 | return 0; | 406 | return 0; |
424 | } | 407 | } |
425 | 408 | ||
426 | ret = reg_value(&start, &ui->sample->user_regs, PERF_REG_SP); | 409 | ret = perf_reg_value(&start, &ui->sample->user_regs, PERF_REG_SP); |
427 | if (ret) | 410 | if (ret) |
428 | return ret; | 411 | return ret; |
429 | 412 | ||
@@ -436,8 +419,9 @@ static int access_mem(unw_addr_space_t __maybe_unused as, | |||
436 | if (addr < start || addr + sizeof(unw_word_t) >= end) { | 419 | if (addr < start || addr + sizeof(unw_word_t) >= end) { |
437 | ret = access_dso_mem(ui, addr, valp); | 420 | ret = access_dso_mem(ui, addr, valp); |
438 | if (ret) { | 421 | if (ret) { |
439 | pr_debug("unwind: access_mem %p not inside range %p-%p\n", | 422 | pr_debug("unwind: access_mem %p not inside range" |
440 | (void *)addr, (void *)start, (void *)end); | 423 | " 0x%" PRIx64 "-0x%" PRIx64 "\n", |
424 | (void *) addr, start, end); | ||
441 | *valp = 0; | 425 | *valp = 0; |
442 | return ret; | 426 | return ret; |
443 | } | 427 | } |
@@ -446,8 +430,8 @@ static int access_mem(unw_addr_space_t __maybe_unused as, | |||
446 | 430 | ||
447 | offset = addr - start; | 431 | offset = addr - start; |
448 | *valp = *(unw_word_t *)&stack->data[offset]; | 432 | *valp = *(unw_word_t *)&stack->data[offset]; |
449 | pr_debug("unwind: access_mem addr %p, val %lx, offset %d\n", | 433 | pr_debug("unwind: access_mem addr %p val %lx, offset %d\n", |
450 | (void *)addr, (unsigned long)*valp, offset); | 434 | (void *) addr, (unsigned long)*valp, offset); |
451 | return 0; | 435 | return 0; |
452 | } | 436 | } |
453 | 437 | ||
@@ -457,6 +441,7 @@ static int access_reg(unw_addr_space_t __maybe_unused as, | |||
457 | { | 441 | { |
458 | struct unwind_info *ui = arg; | 442 | struct unwind_info *ui = arg; |
459 | int id, ret; | 443 | int id, ret; |
444 | u64 val; | ||
460 | 445 | ||
461 | /* Don't support write, I suspect we don't need it. */ | 446 | /* Don't support write, I suspect we don't need it. */ |
462 | if (__write) { | 447 | if (__write) { |
@@ -473,12 +458,13 @@ static int access_reg(unw_addr_space_t __maybe_unused as, | |||
473 | if (id < 0) | 458 | if (id < 0) |
474 | return -EINVAL; | 459 | return -EINVAL; |
475 | 460 | ||
476 | ret = reg_value(valp, &ui->sample->user_regs, id); | 461 | ret = perf_reg_value(&val, &ui->sample->user_regs, id); |
477 | if (ret) { | 462 | if (ret) { |
478 | pr_err("unwind: can't read reg %d\n", regnum); | 463 | pr_err("unwind: can't read reg %d\n", regnum); |
479 | return ret; | 464 | return ret; |
480 | } | 465 | } |
481 | 466 | ||
467 | *valp = (unw_word_t) val; | ||
482 | pr_debug("unwind: reg %d, val %lx\n", regnum, (unsigned long)*valp); | 468 | pr_debug("unwind: reg %d, val %lx\n", regnum, (unsigned long)*valp); |
483 | return 0; | 469 | return 0; |
484 | } | 470 | } |
@@ -572,7 +558,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, | |||
572 | struct machine *machine, struct thread *thread, | 558 | struct machine *machine, struct thread *thread, |
573 | struct perf_sample *data, int max_stack) | 559 | struct perf_sample *data, int max_stack) |
574 | { | 560 | { |
575 | unw_word_t ip; | 561 | u64 ip; |
576 | struct unwind_info ui = { | 562 | struct unwind_info ui = { |
577 | .sample = data, | 563 | .sample = data, |
578 | .thread = thread, | 564 | .thread = thread, |
@@ -583,7 +569,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, | |||
583 | if (!data->user_regs.regs) | 569 | if (!data->user_regs.regs) |
584 | return -EINVAL; | 570 | return -EINVAL; |
585 | 571 | ||
586 | ret = reg_value(&ip, &data->user_regs, PERF_REG_IP); | 572 | ret = perf_reg_value(&ip, &data->user_regs, PERF_REG_IP); |
587 | if (ret) | 573 | if (ret) |
588 | return ret; | 574 | return ret; |
589 | 575 | ||