#include "qemu/osdep.h"
#include "qemu/plugin.h"
-#include "cpu.h"
+#include "qemu/log.h"
#include "tcg/tcg.h"
#include "exec/exec-all.h"
#include "exec/ram_addr.h"
#ifndef CONFIG_USER_ONLY
#include "qemu/plugin-memory.h"
#include "hw/boards.h"
+#else
+#include "qemu.h"
+#ifdef CONFIG_LINUX
+#include "loader.h"
+#endif
#endif
-#include "trace/mem.h"
/* Uninstall and Reset handlers */
return plugin_disas(cpu, insn->vaddr, insn->data->len);
}
+const char *qemu_plugin_insn_symbol(const struct qemu_plugin_insn *insn)
+{
+ const char *sym = lookup_symbol(insn->vaddr);
+ return sym[0] != 0 ? sym : NULL;
+}
+
/*
* The memory queries allow the plugin to query information about a
* memory access.
unsigned qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info)
{
- return info & TRACE_MEM_SZ_SHIFT_MASK;
+ MemOp op = get_memop(info);
+ return op & MO_SIZE;
}
bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info)
{
- return !!(info & TRACE_MEM_SE);
+ MemOp op = get_memop(info);
+ return op & MO_SIGN;
}
bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info)
{
- return !!(info & TRACE_MEM_BE);
+ MemOp op = get_memop(info);
+ return (op & MO_BSWAP) == MO_BE;
}
bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
{
- return !!(info & TRACE_MEM_ST);
+ return get_plugin_meminfo_rw(info) & QEMU_PLUGIN_MEM_W;
}
/*
{
#ifdef CONFIG_SOFTMMU
CPUState *cpu = current_cpu;
- unsigned int mmu_idx = info >> TRACE_MEM_MMU_SHIFT;
- hwaddr_info.is_store = info & TRACE_MEM_ST;
+ unsigned int mmu_idx = get_mmuidx(info);
+ enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info);
+ hwaddr_info.is_store = (rw & QEMU_PLUGIN_MEM_W) != 0;
+
+ assert(mmu_idx < NB_MMU_MODES);
if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx,
- info & TRACE_MEM_ST, &hwaddr_info)) {
+ hwaddr_info.is_store, &hwaddr_info)) {
error_report("invalid use of qemu_plugin_get_hwaddr");
return NULL;
}
if (!haddr->is_io) {
RAMBlock *block;
ram_addr_t offset;
- void *hostaddr = (void *) haddr->v.ram.hostaddr;
+ void *hostaddr = haddr->v.ram.hostaddr;
block = qemu_ram_block_from_host(hostaddr, false, &offset);
if (!block) {
- error_report("Bad ram pointer %"PRIx64"", haddr->v.ram.hostaddr);
+ error_report("Bad host ram pointer %p", haddr->v.ram.hostaddr);
abort();
}
return block->offset + offset + block->mr->addr;
} else {
MemoryRegionSection *mrs = haddr->v.io.section;
- return haddr->v.io.offset + mrs->mr->addr;
+ return mrs->offset_within_address_space + haddr->v.io.offset;
}
}
#endif
{
qemu_log_mask(CPU_LOG_PLUGIN, "%s", string);
}
+
+bool qemu_plugin_bool_parse(const char *name, const char *value, bool *ret)
+{
+ return name && value && qapi_bool_parse(name, value, ret, NULL);
+}
+
+/*
+ * Binary path, start and end locations
+ */
+const char *qemu_plugin_path_to_binary(void)
+{
+ char *path = NULL;
+#ifdef CONFIG_USER_ONLY
+ TaskState *ts = (TaskState *) current_cpu->opaque;
+ path = g_strdup(ts->bprm->filename);
+#endif
+ return path;
+}
+
+uint64_t qemu_plugin_start_code(void)
+{
+ uint64_t start = 0;
+#ifdef CONFIG_USER_ONLY
+ TaskState *ts = (TaskState *) current_cpu->opaque;
+ start = ts->info->start_code;
+#endif
+ return start;
+}
+
+uint64_t qemu_plugin_end_code(void)
+{
+ uint64_t end = 0;
+#ifdef CONFIG_USER_ONLY
+ TaskState *ts = (TaskState *) current_cpu->opaque;
+ end = ts->info->end_code;
+#endif
+ return end;
+}
+
+uint64_t qemu_plugin_entry_code(void)
+{
+ uint64_t entry = 0;
+#ifdef CONFIG_USER_ONLY
+ TaskState *ts = (TaskState *) current_cpu->opaque;
+ entry = ts->info->entry;
+#endif
+ return entry;
+}