@@ -49,6 +49,7 @@
#include "qemu/guest-random.h"
#include "gdbstub/user.h"
#include "exec/page-vary.h"
+#include "exec/watchpoint.h"
#include "host-os.h"
#include "target_arch_cpu.h"
@@ -215,7 +216,7 @@ bool qemu_cpu_is_self(CPUState *cpu)
}
/* Assumes contents are already zeroed. */
-static void init_task_state(TaskState *ts)
+void init_task_state(TaskState *ts)
{
ts->sigaltstack_used = (struct target_sigaltstack) {
.ss_sp = 0,
@@ -224,6 +225,34 @@ static void init_task_state(TaskState *ts)
};
}
+static const char *cpu_type;
+
+CPUArchState *cpu_copy(CPUArchState *env)
+{
+ CPUState *cpu = env_cpu(env);
+ CPUState *new_cpu = cpu_create(cpu_type);
+ CPUArchState *new_env = cpu_env(new_cpu);
+ CPUBreakpoint *bp;
+
+ /* Reset non arch specific state */
+ cpu_reset(new_cpu);
+
+ new_cpu->tcg_cflags = cpu->tcg_cflags;
+ memcpy(new_env, env, sizeof(CPUArchState));
+
+ /*
+ * Clone all break/watchpoints.
+ * Note: Once we support ptrace with hw-debug register access, make sure
+ * BP_CPU break/watchpoints are handled correctly on clone.
+ */
+ QTAILQ_INIT(&new_cpu->breakpoints);
+ QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
+ cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
+ }
+
+ return new_env;
+}
+
static QemuPluginList plugins = QTAILQ_HEAD_INITIALIZER(plugins);
void gemu_log(const char *fmt, ...)
@@ -256,7 +285,6 @@ int main(int argc, char **argv)
{
const char *filename;
const char *cpu_model;
- const char *cpu_type;
const char *log_file = NULL;
const char *log_mask = NULL;
const char *seed_optarg = NULL;
@@ -122,6 +122,7 @@ struct TaskState {
struct target_sigaltstack sigaltstack_used;
} __attribute__((aligned(16)));
+void init_task_state(TaskState *ts);
void stop_all_tasks(void);
extern const char *interp_prefix;
extern const char *qemu_uname_release;