Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1488212 > unrolled thread
| Started by | Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> |
|---|---|
| First post | 2016-09-21 18:00 +0200 |
| Last post | 2016-09-22 17:00 +0200 |
| Articles | 6 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v7 0/6] perf annotate: Cross arch support + few fixes Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> - 2016-09-21 18:00 +0200
[PATCH v7 2/6] perf annotate: Add support for powerpc Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> - 2016-09-21 18:00 +0200
[PATCH v7 1/6] perf annotate: Add cross arch annotate support Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> - 2016-09-21 18:00 +0200
Re: [PATCH v7 0/6] perf annotate: Cross arch support + few fixes Kim Phillips <kim.phillips@arm.com> - 2016-09-21 21:40 +0200
Re: [PATCH v7 0/6] perf annotate: Cross arch support + few fixes Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> - 2016-09-22 07:20 +0200
Re: [PATCH v7 0/6] perf annotate: Cross arch support + few fixes Kim Phillips <kim.phillips@arm.com> - 2016-09-22 17:00 +0200
| From | Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-09-21 18:00 +0200 |
| Subject | [PATCH v7 0/6] perf annotate: Cross arch support + few fixes |
| Message-ID | <sjS6d-2q3-3@gated-at.bofh.it> |
Currently Perf annotate support code navigation (branches and calls)
only when run on the same architecture where perf.data was recorded.
But, for example, record on powerpc server and annotate on client's
x86 desktop is not supported.
This patchset adds supports for that.
Example:
Record on powerpc:
$ ./perf record -a
Report -> Annotate on x86:
$ ./perf report -i perf.data.powerpc --vmlinux vmlinux.powerpc
Changes in v7:
- Using string for normalized arch names instread of macros.(i.e.
removed patch 1/7 of v6)
- In patch 1/6, make norm_arch as global var instead of passing them
to each parser.
- In patch 1/6 and 6/6, little bit change in initializing instruction
list.
- patch 4/7 of v6 is already accepted. Removed that in v7.
- Address other review comments.
- Added more examples in patch descriptions.
v6 link:
https://lkml.org/lkml/2016/8/19/411
Kim, I don't have arm test machine. Can you please help me to test
this on arm.
Kim Phillips (1):
perf annotate: cross arch annotate support fixes for ARM
Naveen N. Rao (1):
perf annotate: Add support for powerpc
Ravi Bangoria (4):
perf annotate: Add cross arch annotate support
perf annotate: Show raw form for jump instruction with indirect target
perf annotate: Support jump instruction with target as second operand
perf annotate: Fix jump target outside of function address range
tools/perf/builtin-top.c | 2 +-
tools/perf/ui/browsers/annotate.c | 8 +-
tools/perf/ui/gtk/annotate.c | 2 +-
tools/perf/util/annotate.c | 259 ++++++++++++++++++++++++++++++++------
tools/perf/util/annotate.h | 8 +-
5 files changed, 232 insertions(+), 47 deletions(-)
--
2.5.5
[toc] | [next] | [standalone]
| From | Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-09-21 18:00 +0200 |
| Subject | [PATCH v7 2/6] perf annotate: Add support for powerpc |
| Message-ID | <sjS6e-2q3-13@gated-at.bofh.it> |
| In reply to | #1488212 |
From: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
Current perf can disassemble annotated function but it does not have
parsing logic for powerpc instructions. So all navigation options are
not available for powerpc.
Apart from that, Powerpc has long list of branch instructions and
hardcoding them in table appears to be error-prone. So, add function
to find instruction instead of creating table. This function dynamically
create table (list of 'struct ins'), and instead of creating object
every time, first check if list already contain object for that
instruction.
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
---
Changes in v7:
- Little bit change in initializing instruction list.
tools/perf/util/annotate.c | 112 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 816aa2c..5aa72d9 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -531,6 +531,11 @@ static struct ins instructions_arm[] = {
{ .name = "retq", .ops = &ret_ops, },
};
+struct instructions_powerpc {
+ struct ins *ins;
+ struct list_head list;
+};
+
static int ins__key_cmp(const void *name, const void *insp)
{
const struct ins *ins = insp;
@@ -546,6 +551,111 @@ static int ins__cmp(const void *a, const void *b)
return strcmp(ia->name, ib->name);
}
+static struct ins *list_add__ins_powerpc(struct instructions_powerpc *head,
+ const char *name, struct ins_ops *ops)
+{
+ struct instructions_powerpc *ins_powerpc;
+ struct ins *ins;
+
+ ins = zalloc(sizeof(struct ins));
+ if (!ins)
+ return NULL;
+
+ ins_powerpc = zalloc(sizeof(struct instructions_powerpc));
+ if (!ins_powerpc)
+ goto out_free_ins;
+
+ ins->name = strdup(name);
+ if (!ins->name)
+ goto out_free_ins_power;
+
+ ins->ops = ops;
+ ins_powerpc->ins = ins;
+ list_add_tail(&(ins_powerpc->list), &(head->list));
+
+ return ins;
+
+out_free_ins_power:
+ zfree(&ins_powerpc);
+out_free_ins:
+ zfree(&ins);
+ return NULL;
+}
+
+static struct ins *list_search__ins_powerpc(struct instructions_powerpc *head,
+ const char *name)
+{
+ struct instructions_powerpc *pos;
+
+ list_for_each_entry(pos, &head->list, list) {
+ if (!strcmp(pos->ins->name, name))
+ return pos->ins;
+ }
+ return NULL;
+}
+
+static struct ins *ins__find_powerpc(const char *name)
+{
+ int i;
+ struct ins *ins;
+ struct ins_ops *ops;
+ static struct instructions_powerpc head = {
+ .list = LIST_HEAD_INIT(head.list),
+ };
+
+ /*
+ * - Interested only if instruction starts with 'b'.
+ * - Few start with 'b', but aren't branch instructions.
+ */
+ if (name[0] != 'b' ||
+ !strncmp(name, "bcd", 3) ||
+ !strncmp(name, "brinc", 5) ||
+ !strncmp(name, "bper", 4))
+ return NULL;
+
+ /*
+ * Return if we already have object of 'struct ins' for this instruction
+ */
+ ins = list_search__ins_powerpc(&head, name);
+ if (ins)
+ return ins;
+
+ ops = &jump_ops;
+
+ i = strlen(name) - 1;
+ if (i < 0)
+ return NULL;
+
+ /* ignore optional hints at the end of the instructions */
+ if (name[i] == '+' || name[i] == '-')
+ i--;
+
+ if (name[i] == 'l' || (name[i] == 'a' && name[i-1] == 'l')) {
+ /*
+ * if the instruction ends up with 'l' or 'la', then
+ * those are considered 'calls' since they update LR.
+ * ... except for 'bnl' which is branch if not less than
+ * and the absolute form of the same.
+ */
+ if (strcmp(name, "bnl") && strcmp(name, "bnl+") &&
+ strcmp(name, "bnl-") && strcmp(name, "bnla") &&
+ strcmp(name, "bnla+") && strcmp(name, "bnla-"))
+ ops = &call_ops;
+ }
+ if (name[i] == 'r' && name[i-1] == 'l')
+ /*
+ * instructions ending with 'lr' are considered to be
+ * return instructions
+ */
+ ops = &ret_ops;
+
+ /*
+ * Add instruction to list so next time no need to
+ * allocate memory for it.
+ */
+ return list_add__ins_powerpc(&head, name, ops);
+}
+
static void ins__sort(struct ins *instructions, int nmemb)
{
qsort(instructions, nmemb, sizeof(struct ins), ins__cmp);
@@ -581,6 +691,8 @@ static struct ins *ins__find(const char *name)
} else if (!strcmp(norm_arch, "arm")) {
instructions = instructions_arm;
nmemb = ARRAY_SIZE(instructions_arm);
+ } else if (!strcmp(norm_arch, "powerpc")) {
+ return ins__find_powerpc(name);
} else {
pr_err("perf annotate not supported by %s arch\n", norm_arch);
return NULL;
--
2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-09-21 18:00 +0200 |
| Subject | [PATCH v7 1/6] perf annotate: Add cross arch annotate support |
| Message-ID | <sjS6e-2q3-23@gated-at.bofh.it> |
| In reply to | #1488212 |
Change current data structures and function to enable cross arch
annotate.
Current perf implementation does not support cross arch annotate.
To make it truly cross arch, instruction table of all arch should
be present in perf binary. And use appropriate table based on arch
where perf.data was recorded.
Record on arm:
$ ./perf record -a
Report -> Annotate on x86:
$ ./perf report -i perf.data.arm --vmlinux vmlinux.arm
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
---
Changes in v7:
- Make norm_arch as global var instead of passing them to each parser.
- Address other review comments.
tools/perf/builtin-top.c | 2 +-
tools/perf/ui/browsers/annotate.c | 3 +-
tools/perf/ui/gtk/annotate.c | 2 +-
tools/perf/util/annotate.c | 151 ++++++++++++++++++++++++++++++++------
tools/perf/util/annotate.h | 3 +-
5 files changed, 134 insertions(+), 27 deletions(-)
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 4007857..41ecdd6 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -129,7 +129,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
return err;
}
- err = symbol__disassemble(sym, map, 0);
+ err = symbol__disassemble(sym, map, 0, NULL);
if (err == 0) {
out_assign:
top->sym_filter_entry = he;
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 4c18271..214a14a 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -1050,7 +1050,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
(nr_pcnt - 1);
}
- err = symbol__disassemble(sym, map, sizeof_bdl);
+ err = symbol__disassemble(sym, map, sizeof_bdl,
+ perf_evsel__env_arch(evsel));
if (err) {
char msg[BUFSIZ];
symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c
index 42d3199..c127aba 100644
--- a/tools/perf/ui/gtk/annotate.c
+++ b/tools/perf/ui/gtk/annotate.c
@@ -167,7 +167,7 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
if (map->dso->annotate_warned)
return -1;
- err = symbol__disassemble(sym, map, 0);
+ err = symbol__disassemble(sym, map, 0, perf_evsel__env_arch(evsel));
if (err) {
char msg[BUFSIZ];
symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index aeb5a44..816aa2c 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -21,10 +21,13 @@
#include <regex.h>
#include <pthread.h>
#include <linux/bitops.h>
+#include <sys/utsname.h>
+#include "../arch/common.h"
const char *disassembler_style;
const char *objdump_path;
static regex_t file_lineno;
+static char *norm_arch;
static struct ins *ins__find(const char *name);
static int disasm_line__parse(char *line, char **namep, char **rawp);
@@ -66,10 +69,8 @@ static int call__parse(struct ins_operands *ops, struct map *map)
name++;
-#ifdef __arm__
- if (strchr(name, '+'))
+ if (!strcmp(norm_arch, "arm") && strchr(name, '+'))
return -1;
-#endif
tok = strchr(name, '>');
if (tok == NULL)
@@ -252,16 +253,12 @@ static int mov__parse(struct ins_operands *ops, struct map *map __maybe_unused)
return -1;
target = ++s;
-#ifdef __arm__
+
comment = strchr(s, ';');
-#else
- comment = strchr(s, '#');
-#endif
+ if (comment == NULL)
+ comment = strchr(s, '#');
- if (comment != NULL)
- s = comment - 1;
- else
- s = strchr(s, '\0') - 1;
+ s = (comment != NULL) ? comment - 1 : strchr(s, '\0') - 1;
while (s > target && isspace(s[0]))
--s;
@@ -364,14 +361,92 @@ bool ins__is_ret(const struct ins *ins)
return ins->ops == &ret_ops;
}
-static struct ins instructions[] = {
+static struct ins instructions_x86[] = {
{ .name = "add", .ops = &mov_ops, },
{ .name = "addl", .ops = &mov_ops, },
{ .name = "addq", .ops = &mov_ops, },
{ .name = "addw", .ops = &mov_ops, },
{ .name = "and", .ops = &mov_ops, },
-#ifdef __arm__
- { .name = "b", .ops = &jump_ops, }, // might also be a call
+ { .name = "bts", .ops = &mov_ops, },
+ { .name = "call", .ops = &call_ops, },
+ { .name = "callq", .ops = &call_ops, },
+ { .name = "cmp", .ops = &mov_ops, },
+ { .name = "cmpb", .ops = &mov_ops, },
+ { .name = "cmpl", .ops = &mov_ops, },
+ { .name = "cmpq", .ops = &mov_ops, },
+ { .name = "cmpw", .ops = &mov_ops, },
+ { .name = "cmpxch", .ops = &mov_ops, },
+ { .name = "dec", .ops = &dec_ops, },
+ { .name = "decl", .ops = &dec_ops, },
+ { .name = "imul", .ops = &mov_ops, },
+ { .name = "inc", .ops = &dec_ops, },
+ { .name = "incl", .ops = &dec_ops, },
+ { .name = "ja", .ops = &jump_ops, },
+ { .name = "jae", .ops = &jump_ops, },
+ { .name = "jb", .ops = &jump_ops, },
+ { .name = "jbe", .ops = &jump_ops, },
+ { .name = "jc", .ops = &jump_ops, },
+ { .name = "jcxz", .ops = &jump_ops, },
+ { .name = "je", .ops = &jump_ops, },
+ { .name = "jecxz", .ops = &jump_ops, },
+ { .name = "jg", .ops = &jump_ops, },
+ { .name = "jge", .ops = &jump_ops, },
+ { .name = "jl", .ops = &jump_ops, },
+ { .name = "jle", .ops = &jump_ops, },
+ { .name = "jmp", .ops = &jump_ops, },
+ { .name = "jmpq", .ops = &jump_ops, },
+ { .name = "jna", .ops = &jump_ops, },
+ { .name = "jnae", .ops = &jump_ops, },
+ { .name = "jnb", .ops = &jump_ops, },
+ { .name = "jnbe", .ops = &jump_ops, },
+ { .name = "jnc", .ops = &jump_ops, },
+ { .name = "jne", .ops = &jump_ops, },
+ { .name = "jng", .ops = &jump_ops, },
+ { .name = "jnge", .ops = &jump_ops, },
+ { .name = "jnl", .ops = &jump_ops, },
+ { .name = "jnle", .ops = &jump_ops, },
+ { .name = "jno", .ops = &jump_ops, },
+ { .name = "jnp", .ops = &jump_ops, },
+ { .name = "jns", .ops = &jump_ops, },
+ { .name = "jnz", .ops = &jump_ops, },
+ { .name = "jo", .ops = &jump_ops, },
+ { .name = "jp", .ops = &jump_ops, },
+ { .name = "jpe", .ops = &jump_ops, },
+ { .name = "jpo", .ops = &jump_ops, },
+ { .name = "jrcxz", .ops = &jump_ops, },
+ { .name = "js", .ops = &jump_ops, },
+ { .name = "jz", .ops = &jump_ops, },
+ { .name = "lea", .ops = &mov_ops, },
+ { .name = "lock", .ops = &lock_ops, },
+ { .name = "mov", .ops = &mov_ops, },
+ { .name = "movb", .ops = &mov_ops, },
+ { .name = "movdqa", .ops = &mov_ops, },
+ { .name = "movl", .ops = &mov_ops, },
+ { .name = "movq", .ops = &mov_ops, },
+ { .name = "movslq", .ops = &mov_ops, },
+ { .name = "movzbl", .ops = &mov_ops, },
+ { .name = "movzwl", .ops = &mov_ops, },
+ { .name = "nop", .ops = &nop_ops, },
+ { .name = "nopl", .ops = &nop_ops, },
+ { .name = "nopw", .ops = &nop_ops, },
+ { .name = "or", .ops = &mov_ops, },
+ { .name = "orl", .ops = &mov_ops, },
+ { .name = "test", .ops = &mov_ops, },
+ { .name = "testb", .ops = &mov_ops, },
+ { .name = "testl", .ops = &mov_ops, },
+ { .name = "xadd", .ops = &mov_ops, },
+ { .name = "xbeginl", .ops = &jump_ops, },
+ { .name = "xbeginq", .ops = &jump_ops, },
+ { .name = "retq", .ops = &ret_ops, },
+};
+
+static struct ins instructions_arm[] = {
+ { .name = "add", .ops = &mov_ops, },
+ { .name = "addl", .ops = &mov_ops, },
+ { .name = "addq", .ops = &mov_ops, },
+ { .name = "addw", .ops = &mov_ops, },
+ { .name = "and", .ops = &mov_ops, },
+ { .name = "b", .ops = &jump_ops, }, /* might also be a call */
{ .name = "bcc", .ops = &jump_ops, },
{ .name = "bcs", .ops = &jump_ops, },
{ .name = "beq", .ops = &jump_ops, },
@@ -383,7 +458,6 @@ static struct ins instructions[] = {
{ .name = "blt", .ops = &jump_ops, },
{ .name = "blx", .ops = &call_ops, },
{ .name = "bne", .ops = &jump_ops, },
-#endif
{ .name = "bts", .ops = &mov_ops, },
{ .name = "call", .ops = &call_ops, },
{ .name = "callq", .ops = &call_ops, },
@@ -472,24 +546,48 @@ static int ins__cmp(const void *a, const void *b)
return strcmp(ia->name, ib->name);
}
-static void ins__sort(void)
+static void ins__sort(struct ins *instructions, int nmemb)
{
- const int nmemb = ARRAY_SIZE(instructions);
-
qsort(instructions, nmemb, sizeof(struct ins), ins__cmp);
}
+static const char *annotate__norm_arch(char *arch)
+{
+ struct utsname uts;
+
+ if (!arch) { /* Assume we are annotating locally. */
+ if (uname(&uts) < 0)
+ return NULL;
+ arch = uts.machine;
+ }
+ return normalize_arch(arch);
+}
+
static struct ins *ins__find(const char *name)
{
- const int nmemb = ARRAY_SIZE(instructions);
static bool sorted;
+ struct ins *instructions;
+ int nmemb;
if (!sorted) {
- ins__sort();
+ ins__sort(instructions_x86, ARRAY_SIZE(instructions_x86));
+ ins__sort(instructions_arm, ARRAY_SIZE(instructions_arm));
sorted = true;
}
- return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__key_cmp);
+ if (!strcmp(norm_arch, "x86")) {
+ instructions = instructions_x86;
+ nmemb = ARRAY_SIZE(instructions_x86);
+ } else if (!strcmp(norm_arch, "arm")) {
+ instructions = instructions_arm;
+ nmemb = ARRAY_SIZE(instructions_arm);
+ } else {
+ pr_err("perf annotate not supported by %s arch\n", norm_arch);
+ return NULL;
+ }
+
+ return bsearch(name, instructions, nmemb, sizeof(struct ins),
+ ins__key_cmp);
}
int symbol__alloc_hist(struct symbol *sym)
@@ -1280,7 +1378,8 @@ fallback:
return 0;
}
-int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
+int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize,
+ char *arch)
{
struct dso *dso = map->dso;
char command[PATH_MAX * 2];
@@ -1297,6 +1396,12 @@ int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
if (err)
return err;
+ norm_arch = (char *) annotate__norm_arch(arch);
+ if (!norm_arch) {
+ pr_err("Can not annotate. Could not determine architecture.");
+ return -1;
+ }
+
pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
symfs_filename, sym->name, map->unmap_ip(map, sym->start),
map->unmap_ip(map, sym->end));
@@ -1793,7 +1898,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
struct rb_root source_line = RB_ROOT;
u64 len;
- if (symbol__disassemble(sym, map, 0) < 0)
+ if (symbol__disassemble(sym, map, 0, perf_evsel__env_arch(evsel)) < 0)
return -1;
len = symbol__size(sym);
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 5bbcec1..4400269 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -156,7 +156,8 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
int symbol__alloc_hist(struct symbol *sym);
void symbol__annotate_zero_histograms(struct symbol *sym);
-int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize);
+int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize,
+ char *arch);
enum symbol_disassemble_errno {
SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0,
--
2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Kim Phillips <kim.phillips@arm.com> |
|---|---|
| Date | 2016-09-21 21:40 +0200 |
| Message-ID | <sjVx8-4Eu-41@gated-at.bofh.it> |
| In reply to | #1488212 |
On Wed, 21 Sep 2016 21:17:50 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > Kim, I don't have arm test machine. Can you please help me to test > this on arm. This works for me: hitting return on return instructions yields "Invalid jump offset", but I'll get that later. Thanks, Kim
[toc] | [prev] | [next] | [standalone]
| From | Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-09-22 07:20 +0200 |
| Message-ID | <sk4Ap-2ay-3@gated-at.bofh.it> |
| In reply to | #1488355 |
On Thursday 22 September 2016 01:04 AM, Kim Phillips wrote: > On Wed, 21 Sep 2016 21:17:50 +0530 > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > >> Kim, I don't have arm test machine. Can you please help me to test >> this on arm. > This works for me: hitting return on return instructions yields > "Invalid jump offset", but I'll get that later. Thanks Kim. Hmm.. so, ins__find_arm does not contain logic for return instructions. Navigation with return instruction is working fine for x86 and powerpc. -Ravi > Thanks, > > Kim >
[toc] | [prev] | [next] | [standalone]
| From | Kim Phillips <kim.phillips@arm.com> |
|---|---|
| Date | 2016-09-22 17:00 +0200 |
| Message-ID | <skdDH-7GI-5@gated-at.bofh.it> |
| In reply to | #1488536 |
On Thu, 22 Sep 2016 10:48:13 +0530 Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > On Thursday 22 September 2016 01:04 AM, Kim Phillips wrote: > > On Wed, 21 Sep 2016 21:17:50 +0530 > > Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> wrote: > > > >> Kim, I don't have arm test machine. Can you please help me to test > >> this on arm. > > This works for me: hitting return on return instructions yields > > "Invalid jump offset", but I'll get that later. > > Thanks Kim. > > Hmm.. so, ins__find_arm does not contain logic for return instructions. Navigation > with return instruction is working fine for x86 and powerpc. Right, for ARM, in order to match return instructions, 'lr' must be found to be the operand of the branch instruction, which is not contained in the 'name' variable passed to ins__find(). I don't want this to inhibit acceptance of this series, however: I plan on addressing it afterwards, unless, of course, it is perceived as a problem somehow (compatibility-wise, it is not because it is an error at the moment). Thanks, Kim
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web