contrib/plugins/uftrace: implement x64 support
It's trivial to implement x64 support, as it's the same stack layout as aarch64. Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Message-ID: <20250902075042.223990-8-pierrick.bouvier@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-ID: <20250922093711.2768983-24-alex.bennee@linaro.org>
This commit is contained in:
parent
7278747595
commit
b860d96f00
1 changed files with 86 additions and 0 deletions
|
|
@ -82,6 +82,21 @@ typedef struct {
|
|||
struct qemu_plugin_register *reg_scr_el3;
|
||||
} Aarch64Cpu;
|
||||
|
||||
typedef enum {
|
||||
X64_RING0,
|
||||
X64_RING1,
|
||||
X64_RING2,
|
||||
X64_RING3,
|
||||
X64_REAL_MODE,
|
||||
X64_PRIVILEGE_LEVEL_MAX,
|
||||
} X64PrivilegeLevel;
|
||||
|
||||
typedef struct {
|
||||
struct qemu_plugin_register *reg_rbp;
|
||||
struct qemu_plugin_register *reg_cs;
|
||||
struct qemu_plugin_register *reg_cr0;
|
||||
} X64Cpu;
|
||||
|
||||
typedef struct {
|
||||
uint64_t timestamp;
|
||||
uint64_t data;
|
||||
|
|
@ -570,6 +585,75 @@ static CpuOps aarch64_ops = {
|
|||
.does_insn_modify_frame_pointer = aarch64_does_insn_modify_frame_pointer,
|
||||
};
|
||||
|
||||
static uint8_t x64_num_privilege_levels(void)
|
||||
{
|
||||
return X64_PRIVILEGE_LEVEL_MAX;
|
||||
}
|
||||
|
||||
static const char *x64_get_privilege_level_name(uint8_t pl)
|
||||
{
|
||||
switch (pl) {
|
||||
case X64_RING0: return "Ring0";
|
||||
case X64_RING1: return "Ring1";
|
||||
case X64_RING2: return "Ring2";
|
||||
case X64_RING3: return "Ring3";
|
||||
case X64_REAL_MODE: return "RealMode";
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t x64_get_privilege_level(Cpu *cpu_)
|
||||
{
|
||||
X64Cpu *cpu = cpu_->arch;
|
||||
uint64_t cr0 = cpu_read_register64(cpu_, cpu->reg_cr0);
|
||||
uint64_t protected_mode = (cr0 >> 0) & 0b1;
|
||||
if (!protected_mode) {
|
||||
return X64_REAL_MODE;
|
||||
}
|
||||
uint32_t cs = cpu_read_register32(cpu_, cpu->reg_cs);
|
||||
uint32_t ring_level = (cs >> 0) & 0b11;
|
||||
return ring_level;
|
||||
}
|
||||
|
||||
static uint64_t x64_get_frame_pointer(Cpu *cpu_)
|
||||
{
|
||||
X64Cpu *cpu = cpu_->arch;
|
||||
return cpu_read_register64(cpu_, cpu->reg_rbp);
|
||||
}
|
||||
|
||||
static void x64_init(Cpu *cpu_)
|
||||
{
|
||||
X64Cpu *cpu = g_new0(X64Cpu, 1);
|
||||
cpu_->arch = cpu;
|
||||
cpu->reg_rbp = plugin_find_register("rbp");
|
||||
g_assert(cpu->reg_rbp);
|
||||
cpu->reg_cs = plugin_find_register("cs");
|
||||
g_assert(cpu->reg_cs);
|
||||
cpu->reg_cr0 = plugin_find_register("cr0");
|
||||
g_assert(cpu->reg_cr0);
|
||||
}
|
||||
|
||||
static void x64_end(Cpu *cpu)
|
||||
{
|
||||
g_free(cpu->arch);
|
||||
}
|
||||
|
||||
static bool x64_does_insn_modify_frame_pointer(const char *disas)
|
||||
{
|
||||
return strstr(disas, "rbp");
|
||||
}
|
||||
|
||||
static CpuOps x64_ops = {
|
||||
.init = x64_init,
|
||||
.end = x64_end,
|
||||
.get_frame_pointer = x64_get_frame_pointer,
|
||||
.get_privilege_level = x64_get_privilege_level,
|
||||
.num_privilege_levels = x64_num_privilege_levels,
|
||||
.get_privilege_level_name = x64_get_privilege_level_name,
|
||||
.does_insn_modify_frame_pointer = x64_does_insn_modify_frame_pointer,
|
||||
};
|
||||
|
||||
static void track_privilege_change(unsigned int cpu_index, void *udata)
|
||||
{
|
||||
Cpu *cpu = qemu_plugin_scoreboard_find(score, cpu_index);
|
||||
|
|
@ -777,6 +861,8 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
|
|||
|
||||
if (!strcmp(info->target_name, "aarch64")) {
|
||||
arch_ops = aarch64_ops;
|
||||
} else if (!strcmp(info->target_name, "x86_64")) {
|
||||
arch_ops = x64_ops;
|
||||
} else {
|
||||
fprintf(stderr, "plugin uftrace: %s target is not supported\n",
|
||||
info->target_name);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue