return machine;
 }
 
+/*
+ * A common case for KVM test programs is that the test program acts as the
+ * hypervisor, creating, running and destroying the virtual machine, and
+ * providing the guest object code from its own object code. In this case,
+ * the VM is not running an OS, but only the functions loaded into it by the
+ * hypervisor test program, and conveniently, loaded at the same virtual
+ * addresses.
+ *
+ * Normally to resolve addresses, MMAP events are needed to map addresses
+ * back to the object code and debug symbols for that object code.
+ *
+ * Currently, there is no way to get such mapping information from guests
+ * but, in the scenario described above, the guest has the same mappings
+ * as the hypervisor, so support for that scenario can be achieved.
+ *
+ * To support that, copy the host thread's maps to the guest thread's maps.
+ * Note, we do not discover the guest until we encounter a guest event,
+ * which works well because it is not until then that we know that the host
+ * thread's maps have been set up.
+ *
+ * This function returns the guest thread. Apart from keeping the data
+ * structures sane, using a thread belonging to the guest machine, instead
+ * of the host thread, allows it to have its own comm (refer
+ * thread__set_guest_comm()).
+ */
+static struct thread *findnew_guest_code(struct machine *machine,
+                                        struct machine *host_machine,
+                                        pid_t pid)
+{
+       struct thread *host_thread;
+       struct thread *thread;
+       int err;
+
+       if (!machine)
+               return NULL;
+
+       thread = machine__findnew_thread(machine, -1, pid);
+       if (!thread)
+               return NULL;
+
+       /* Assume maps are set up if there are any */
+       if (thread->maps->nr_maps)
+               return thread;
+
+       host_thread = machine__find_thread(host_machine, -1, pid);
+       if (!host_thread)
+               goto out_err;
+
+       thread__set_guest_comm(thread, pid);
+
+       /*
+        * Guest code can be found in hypervisor process at the same address
+        * so copy host maps.
+        */
+       err = maps__clone(thread, host_thread->maps);
+       thread__put(host_thread);
+       if (err)
+               goto out_err;
+
+       return thread;
+
+out_err:
+       thread__zput(thread);
+       return NULL;
+}
+
+struct thread *machines__findnew_guest_code(struct machines *machines, pid_t pid)
+{
+       struct machine *host_machine = machines__find(machines, HOST_KERNEL_ID);
+       struct machine *machine = machines__findnew(machines, pid);
+
+       return findnew_guest_code(machine, host_machine, pid);
+}
+
+struct thread *machine__findnew_guest_code(struct machine *machine, pid_t pid)
+{
+       struct machines *machines = machine->machines;
+       struct machine *host_machine;
+
+       if (!machines)
+               return NULL;
+
+       host_machine = machines__find(machines, HOST_KERNEL_ID);
+
+       return findnew_guest_code(machine, host_machine, pid);
+}
+
 void machines__process_guests(struct machines *machines,
                              machine__process_t process, void *data)
 {
 
 struct machine *machines__find(struct machines *machines, pid_t pid);
 struct machine *machines__findnew(struct machines *machines, pid_t pid);
 struct machine *machines__find_guest(struct machines *machines, pid_t pid);
+struct thread *machines__findnew_guest_code(struct machines *machines, pid_t pid);
+struct thread *machine__findnew_guest_code(struct machine *machine, pid_t pid);
 
 void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size);
 void machines__set_comm_exec(struct machines *machines, bool comm_exec);