summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2024-04-25 03:51:56 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2024-04-27 04:07:21 +0300
commitf35847de2a65137e011e559f38a3de5902a5463f (patch)
treee6b6bce71a7540576f8aee5937b87e13ad2021a6
parent47557db99a5decba2192303ed34ec1add5177b51 (diff)
downloadlinux-f35847de2a65137e011e559f38a3de5902a5463f.tar.xz
perf annotate: Fallback disassemble to objdump when capstone fails
I found some cases that capstone failed to disassemble. Probably my capstone is an old version but anyway there's a chance it can fail. And then it silently stopped in the middle. In my case, it didn't understand "RDPKRU" instruction. Let's check if the capstone disassemble reached the end of the function and fallback to objdump if not. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: https://lore.kernel.org/r/20240425005157.1104789-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/disasm.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c
index 92937809be85..412101f2cf2a 100644
--- a/tools/perf/util/disasm.c
+++ b/tools/perf/util/disasm.c
@@ -1542,6 +1542,20 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
offset += insn[i].size;
}
+ /* It failed in the middle: probably due to unknown instructions */
+ if (offset != len) {
+ struct list_head *list = &notes->src->source;
+
+ /* Discard all lines and fallback to objdump */
+ while (!list_empty(list)) {
+ dl = list_first_entry(list, struct disasm_line, al.node);
+
+ list_del_init(&dl->al.node);
+ disasm_line__free(dl);
+ }
+ count = -1;
+ }
+
out:
if (needs_cs_close)
cs_close(&handle);