mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 09:01:34 +00:00
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>
This commit is contained in:
parent
bdc80ace07
commit
cbaf89a8c5
@ -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 (s) {
|
||||
op_loc->reg1 = get_dwarf_regnum(s, 0);
|
||||
free(s);
|
||||
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 == arch->objdump.register_char)
|
||||
op_loc->reg1 = get_dwarf_regnum(s, 0);
|
||||
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 */
|
||||
|
@ -511,15 +511,19 @@ int annotate_check_args(void);
|
||||
* @reg1: First register in the operand
|
||||
* @reg2: Second register in the operand
|
||||
* @offset: Memory access offset in the operand
|
||||
* @segment: Segment selector register
|
||||
* @mem_ref: Whether the operand accesses memory
|
||||
* @multi_regs: Whether the second register is used
|
||||
* @imm: Whether the operand is an immediate value (in offset)
|
||||
*/
|
||||
struct annotated_op_loc {
|
||||
int reg1;
|
||||
int reg2;
|
||||
int offset;
|
||||
u8 segment;
|
||||
bool mem_ref;
|
||||
bool multi_regs;
|
||||
bool imm;
|
||||
};
|
||||
|
||||
enum annotated_insn_ops {
|
||||
@ -529,6 +533,17 @@ enum annotated_insn_ops {
|
||||
INSN_OP_MAX,
|
||||
};
|
||||
|
||||
enum annotated_x86_segment {
|
||||
INSN_SEG_NONE = 0,
|
||||
|
||||
INSN_SEG_X86_CS,
|
||||
INSN_SEG_X86_DS,
|
||||
INSN_SEG_X86_ES,
|
||||
INSN_SEG_X86_FS,
|
||||
INSN_SEG_X86_GS,
|
||||
INSN_SEG_X86_SS,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct annotated_insn_loc - Location info of instruction
|
||||
* @ops: Array of location info for source and target operands
|
||||
|
Loading…
Reference in New Issue
Block a user