summaryrefslogtreecommitdiff
path: root/tools/perf/util/annotate.c
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2024-03-18 22:51:08 -0700
committerArnaldo Carvalho de Melo <acme@redhat.com>2024-03-21 10:41:29 -0300
commitcbaf89a8c5b467f99dd930f24a698f3fa338b012 (patch)
tree7f52c1bf428b323b33ca5f1640852d7e7e0af5e5 /tools/perf/util/annotate.c
parentbdc80ace07106a62b51d1752869df29dbd65ad2c (diff)
downloadlinux-cbaf89a8c5b467f99dd930f24a698f3fa338b012.tar.gz
linux-cbaf89a8c5b467f99dd930f24a698f3fa338b012.tar.bz2
linux-cbaf89a8c5b467f99dd930f24a698f3fa338b012.zip
perf annotate: Parse x86 segment register location
Add a segment field in the struct annotated_insn_loc and save it for the segment based addressing like %gs:0x28. For simplicity it now handles %gs register only. 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: Linus Torvalds <torvalds@linux-foundation.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: https://lore.kernel.org/r/20240319055115.4063940-17-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r--tools/perf/util/annotate.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index abb641aa8ec0..3aa3a3b987ad 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -94,6 +94,7 @@ struct arch {
char skip_functions_char;
char register_char;
char memory_ref_char;
+ char imm_char;
} objdump;
};
@@ -211,6 +212,7 @@ static struct arch architectures[] = {
.comment_char = '#',
.register_char = '%',
.memory_ref_char = '(',
+ .imm_char = '$',
},
},
{
@@ -3585,6 +3587,12 @@ static int extract_reg_offset(struct arch *arch, const char *str,
* %gs:0x18(%rbx). In that case it should skip the part.
*/
if (*str == arch->objdump.register_char) {
+ if (arch__is(arch, "x86")) {
+ /* FIXME: Handle other segment registers */
+ if (!strncmp(str, "%gs:", 4))
+ op_loc->segment = INSN_SEG_X86_GS;
+ }
+
while (*str && !isdigit(*str) &&
*str != arch->objdump.memory_ref_char)
str++;
@@ -3681,12 +3689,32 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl,
op_loc->multi_regs = multi_regs;
extract_reg_offset(arch, insn_str, op_loc);
} else {
- char *s = strdup(insn_str);
+ char *s, *p = NULL;
+
+ if (arch__is(arch, "x86")) {
+ /* FIXME: Handle other segment registers */
+ if (!strncmp(insn_str, "%gs:", 4)) {
+ op_loc->segment = INSN_SEG_X86_GS;
+ op_loc->offset = strtol(insn_str + 4,
+ &p, 0);
+ if (p && p != insn_str + 4)
+ op_loc->imm = true;
+ continue;
+ }
+ }
+
+ s = strdup(insn_str);
+ if (s == NULL)
+ return -1;
- if (s) {
+ if (*s == arch->objdump.register_char)
op_loc->reg1 = get_dwarf_regnum(s, 0);
- free(s);
+ else if (*s == arch->objdump.imm_char) {
+ op_loc->offset = strtol(s + 1, &p, 0);
+ if (p && p != s + 1)
+ op_loc->imm = true;
}
+ free(s);
}
}
@@ -3881,7 +3909,7 @@ retry:
.op = op_loc,
};
- if (!op_loc->mem_ref)
+ if (!op_loc->mem_ref && op_loc->segment == INSN_SEG_NONE)
continue;
/* Recalculate IP because of LOCK prefix or insn fusion */