26 #include <sys/types.h>
30 #include <sys/socket.h>
32 #if !defined(UNIX_PATH_MAX)
33 #define UNIX_PATH_MAX (size_t)sizeof(((struct sockaddr_un *) 0)->sun_path)
65 #ifdef ENABLE_XENACCESS
83 static int xen_vm_snprintf(
struct target *
target,
char *buf,
int bufsiz);
85 static int xen_vm_attach_internal(
struct target *
target);
86 static int xen_vm_detach(
struct target *
target,
int stay_paused);
95 static int xen_vm_set_active_probing(
struct target *
target,
100 int *again,
void *priv);
110 xen_vm_lookup_overlay_thread_by_id(
struct target *
target,
int id);
118 static int xen_vm_pause(
struct target *
target,
int nowait);
119 static int __xen_vm_resume(
struct target *
target,
int detaching);
127 unsigned long length,
unsigned char *buf);
129 unsigned long length,
unsigned char *buf);
140 unsigned long length,
unsigned char *buf);
142 unsigned long length,
unsigned char *buf);
151 static int xen_vm_load_all_threads(
struct target *
target,
int force);
152 static int xen_vm_load_available_threads(
struct target *
target,
int force);
155 static int xen_vm_flush_current_thread(
struct target *
target);
156 static int xen_vm_flush_all_threads(
struct target *
target);
157 static int xen_vm_invalidate_thread(
struct target *
target,
159 static int xen_vm_thread_snprintf(
struct target *
target,
161 char *buf,
int bufsiz,
162 int detail,
char *sep,
char *key_val_sep);
187 struct target *overlay);
189 struct target *overlay);
203 struct vcpu_guest_context *context,
209 struct vcpu_guest_context *context);
212 struct probe *trigger,
216 struct probe *trigger,
220 struct probe *trigger,
254 static int xc_refcnt = 0;
256 #ifdef XENCTRL_HAS_XC_INTERFACE
258 static xc_interface *xce_handle = NULL;
259 #define XC_IF_INVALID (NULL)
262 static int xce_handle = -1;
263 #define XC_IF_INVALID (-1)
267 #if !defined(XC_EVTCHN_PORT_T)
268 #error "XC_EVTCHN_PORT_T undefined!"
270 static XC_EVTCHN_PORT_T dbg_port = -1;
280 .attach = xen_vm_attach_internal,
281 .detach = xen_vm_detach,
283 .loadspaces = xen_vm_loadspaces,
284 .loadregions = xen_vm_loadregions,
285 .loaddebugfiles = xen_vm_loaddebugfiles,
286 .postloadinit = xen_vm_postloadinit,
287 .postopened = xen_vm_postopened,
288 .set_active_probing = xen_vm_set_active_probing,
290 .handle_exception = xen_vm_handle_exception,
293 .handle_interrupted_step = NULL,
295 .build_default_overlay_spec = xen_vm_build_default_overlay_spec,
296 .instantiate_overlay = xen_vm_instantiate_overlay,
297 .lookup_overlay_thread_by_id = xen_vm_lookup_overlay_thread_by_id,
298 .lookup_overlay_thread_by_name = xen_vm_lookup_overlay_thread_by_name,
302 .status = xen_vm_status,
303 .pause = xen_vm_pause,
304 .resume = xen_vm_resume,
305 .monitor = xen_vm_monitor,
308 .write = xen_vm_write,
309 .addr_v2p = xen_vm_addr_v2p,
310 .read_phys = xen_vm_read_phys,
311 .write_phys = xen_vm_write_phys,
313 .gettid = xen_vm_gettid,
314 .free_thread_state = xen_vm_free_thread_state,
315 .list_available_tids = xen_vm_list_available_tids,
316 .load_available_threads = xen_vm_load_available_threads,
317 .load_thread = xen_vm_load_thread,
318 .load_current_thread = xen_vm_load_current_thread,
319 .load_all_threads = xen_vm_load_all_threads,
320 .pause_thread = xen_vm_pause_thread,
321 .flush_thread = xen_vm_flush_thread,
322 .flush_current_thread = xen_vm_flush_current_thread,
323 .flush_all_threads = xen_vm_flush_all_threads,
324 .invalidate_thread = xen_vm_invalidate_thread,
325 .thread_snprintf = xen_vm_thread_snprintf,
336 .get_unused_debug_reg = xen_vm_get_unused_debug_reg,
337 .set_hw_breakpoint = xen_vm_set_hw_breakpoint,
338 .set_hw_watchpoint = xen_vm_set_hw_watchpoint,
339 .unset_hw_breakpoint = xen_vm_unset_hw_breakpoint,
340 .unset_hw_watchpoint = xen_vm_unset_hw_watchpoint,
356 #define XV_ARGP_USE_XENACCESS 0x550001
357 #define XV_ARGP_USE_LIBVMI 0x550002
358 #define XV_ARGP_CLEAR_MEM_CACHES 0x550003
359 #define XV_ARGP_MEMCACHE_MMAP_SIZE 0x550004
360 #define XV_ARGP_HIUE 0x550005
361 #define XV_ARGP_REPLAYDIR 0x550006
365 {
"domain",
'm',
"DOMAIN",0,
"The Xen domain ID or name.",-4 },
366 {
"kernel-filename",
'K',
"FILE",0,
367 "Override xenstore kernel filepath for guest.",-4 },
368 {
"no-clear-hw-debug-regs",
'H',NULL,0,
369 "Don't clear hardware debug registers at target attach.",-4 },
371 "Clear mem caches on each debug exception.",-4 },
374 "Clear mem caches on each debug exception.",-4 },
376 #ifdef ENABLE_XENACCESS
378 "Clear mem caches on each debug exception.",-4 },
381 "Max size (bytes) of the mmap cache (default 128MB).",-4 },
382 {
"no-hvm-setcontext",
'V',NULL,0,
383 "Don't use HVM-specific libxc get/set context functions to access"
384 "virtual CPU info.",-4 },
385 {
"configfile",
'c',
"FILE",0,
"The Xen config file.",-4 },
387 {
"no-use-multiplexer",
'M',NULL,0,
"Do not spawn/attach to the Xen multiplexer server",-4 },
388 {
"dominfo-timeout",
'T',
"MICROSECONDS",0,
"If libxc gets a \"NULL\" dominfo status, the number of microseconds we should keep retrying",-4 },
389 {
"hypervisor-ignores-userspace-exceptions",
XV_ARGP_HIUE,NULL,0,
"If your Xen hypervisor is not a Utah-patched version, make sure to supply this flag!",-4 },
422 #ifdef ENABLE_XENACCESS
439 av =
calloc(ac + 1,
sizeof(
char *));
442 av[j++] = strdup(
"-m");
443 av[j++] = strdup(xspec->
domain);
446 av[j++] = strdup(
"-K");
450 av[j++] = strdup(
"--no-clear-hw-debug-regs");
453 av[j++] = strdup(
"--no-hvm-setcontext");
456 av[j++] = strdup(
"--clear-mem-caches-each-exception");
460 av[j++] = strdup(
"--use-libvmi");
462 #ifdef ENABLE_XENACCESS
464 av[j++] = strdup(
"--use-xenaccess");
467 av[j++] = strdup(
"--memcache-mmap-size");
473 av[j++] = strdup(
"-c");
477 av[j++] = strdup(
"--replaydir");
481 av[j++] = strdup(
"--no-use-multiplexer");
484 av[j++] = strdup(
"-T");
490 av[j++] = strdup(
"--hypervisor-ignores-userspace-exceptions");
506 struct argp_option *opti;
509 if (key == ARGP_KEY_INIT)
511 else if (!state->input)
512 return ARGP_ERR_UNKNOWN;
525 if (key == opti->key) {
538 verror(
"cannot mix arguments for Xen target (%c) with non-Xen"
546 xspec =
calloc(1,
sizeof(*xspec));
550 verror(
"cannot mix arguments for Xen target with non-Xen target!\n");
564 return ARGP_ERR_UNKNOWN;
567 case ARGP_KEY_NO_ARGS:
570 case ARGP_KEY_SUCCESS:
577 xspec->domain = strdup(arg);
580 xspec->kernel_filename = strdup(arg);
583 xspec->no_hw_debug_reg_clear = 1;
586 xspec->no_hvm_setcontext = 1;
589 xspec->config_file = strdup(arg);
592 xspec->clear_mem_caches_each_exception = 1;
596 xspec->use_libvmi = 1;
599 #ifdef ENABLE_XENACCESSS
601 xspec->use_xenaccess = 1;
605 xspec->memcache_mmap_size = atoi(arg);
608 xspec->replay_dir = strdup(arg);
611 xspec->no_use_multiplexer = 1;
614 xspec->dominfo_timeout = atoi(arg);
617 xspec->hypervisor_ignores_userspace_exceptions = 1;
620 return ARGP_ERR_UNKNOWN;
637 return xen_vm_attach(spec,evloop);
643 xspec =
calloc(1,
sizeof(*xspec));
672 struct xs_handle *xsh = NULL;
673 xs_transaction_t xth = XBT_NULL;
676 char **domains = NULL;
684 if (geteuid() != 0) {
685 verror(
"must be root!\n");
699 memset(xstate,0,
sizeof(*xstate));
703 if (!(buf =
malloc(PATH_MAX))) {
704 verror(
"could not allocate tmp path buffer: %s\n",strerror(errno));
708 if (!(xsh = xs_domain_open())) {
709 verror(
"could not open xenstore!\n");
713 xstate->evloop_fd = -1;
717 xstate->id = (domid_t)strtol(
domain,&tmp,10);
718 if (errno == ERANGE) {
719 verror(
"bad domain id: %s\n",strerror(errno));
722 else if (errno == EINVAL || tmp ==
domain)
732 domains = xs_directory(xsh,xth,
"/local/domain",&size);
733 for (
i = 0;
i < size; ++
i) {
735 snprintf(buf,PATH_MAX,
"/local/domain/%s/name",domains[
i]);
736 tmp = xs_read(xsh,xth,buf,NULL);
738 if (tmp && strcmp(
domain,tmp) == 0) {
741 xstate->id = (domid_t)strtol(domains[
i],NULL,10);
749 verror(
"matching domain name for %s; but bad"
750 " domain id %s: %s\n",
751 tmp,domains[i],strerror(errno));
760 xstate->name = strdup(tmp);
784 snprintf(buf,PATH_MAX,
"/local/domain/%d/name",xstate->id);
785 xstate->name = xs_read(xsh,xth,buf,NULL);
787 vwarn(
"could not read name for dom %d; may cause problems!\n",
792 snprintf(buf,PATH_MAX,
"/local/domain/%d/vm",xstate->id);
793 xstate->vmpath = xs_read(xsh,xth,buf,NULL);
795 vwarn(
"could not read vmpath for dom %d; may cause problems!\n",
798 snprintf(buf,PATH_MAX,
"%s/image/ostype",xstate->vmpath);
799 xstate->ostype = xs_read(xsh,xth,buf,NULL);
800 if (!xstate->ostype) {
801 vwarn(
"could not read ostype for dom %d; may cause problems!\n",
806 else if (strcmp(xstate->ostype,
"hvm") == 0) {
813 strdup(xstate->ostype));
818 snprintf(buf,PATH_MAX,
"%s/image/kernel",xstate->vmpath);
819 xstate->kernel_filename = xs_read(xsh,xth,buf,NULL);
820 if (!xstate->kernel_filename)
821 vwarn(
"could not read kernel for dom %d; may cause problems!\n",
824 g_hash_table_insert(
target->
config,strdup(
"OS_KERNEL_FILENAME"),
825 strdup(xstate->kernel_filename));
831 "using kernel filename %s (overrides %s from xenstore)\n",
832 xspec->
kernel_filename,xstate->kernel_filename ? xstate->kernel_filename :
"''");
834 if (xstate->kernel_filename)
835 free(xstate->kernel_filename);
839 g_hash_table_remove(
target->
config,
"OS_KERNEL_FILENAME");
840 g_hash_table_insert(
target->
config,strdup(
"OS_KERNEL_FILENAME"),
841 strdup(xstate->kernel_filename));
845 xs_daemon_close(xsh);
856 && xstate->kernel_filename
857 && (strstr(xstate->kernel_filename,
"inux")
858 || strstr(xstate->kernel_filename,
"inuz"))) {
861 "autoinitialized the os_linux_generic personality!\n");
864 verror(
"failed to autoinitialize the os_linux_generic personality!\n");
869 vwarn(
"cannot initialize a personality!\n");
880 xstate->memops = NULL;
885 #ifdef ENABLE_XENACCESS
887 xstate->memops = &xen_vm_mem_ops_xenaccess;
892 if (xstate->memops->init) {
893 if (xstate->memops->init(
target)) {
894 verror(
"failed to init memops!\n");
902 if (evloop && xstate->evloop_fd < 0) {
915 for (i = 0; i < size; ++
i) {
920 if (xstate->vmpath) {
921 free(xstate->vmpath);
922 xstate->vmpath = NULL;
924 if (xstate->ostype) {
925 free(xstate->ostype);
926 xstate->ostype = NULL;
933 xs_daemon_close(xsh);
958 struct timeval itv = { 0,0 };
963 "load dominfo; current dominfo is invalid\n");
967 verror(
"could not get dominfo for %d\n",xstate->
id);
978 && (total - waited) > 0) {
982 itv.tv_usec = (interval > (total - waited)) \
983 ? (total - waited) : interval;
985 rc = select(0,NULL,NULL,NULL,&itv);
987 if (errno != EINTR) {
988 verror(
"select(dominfo retry): %s\n",strerror(errno));
1000 waited += (interval - itv.tv_usec);
1003 "waited %d of %d total microseconds to retry dominfo...\n",
1008 verror(
"could not get dominfo for %d\n",xstate->
id);
1020 xstate->
dominfo.shared_info_frame);
1022 verror(
"could not mmap shared_info frame 0x%lx!\n",
1023 xstate->
dominfo.shared_info_frame);
1044 "did not need to load dominfo; current dominfo is valid\n");
1050 static struct target_thread *__xen_vm_load_cached_thread(
struct target *target,
1059 return xen_vm_load_thread(target,tid,0);
1064 static int __xen_vm_in_userspace(
struct target *target,
int cpl,
REGVAL ipval) {
1088 static int __xen_get_cpl_thread(
struct target *target,
1102 verror(
"could not read CS register to find CPL!\n");
1109 static int __xen_get_cpl(
struct target *target,
tid_t tid) {
1112 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
1119 return __xen_get_cpl_thread(target,tthread);
1122 static struct target_thread *xen_vm_load_thread(
struct target *target,
1123 tid_t tid,
int force) {
1142 xen_vm_load_current_thread(target,force);
1153 if (!xen_vm_load_current_thread(target,force)) {
1154 vwarn(
"could not load current thread to compare with"
1165 return xen_vm_load_current_thread(target,force);
1196 static int __xen_vm_hvm_cpu_to_vcpu_context(HVM_SAVE_TYPE(CPU) *hvm,
1197 vcpu_guest_context_t *svm) {
1198 assert(
sizeof(svm->fpu_ctxt.x) ==
sizeof(hvm->fpu_regs));
1200 memcpy(svm->fpu_ctxt.x,hvm->fpu_regs,
sizeof(svm->fpu_ctxt.x));
1202 svm->user_regs.rax = hvm->rax;
1203 svm->user_regs.rbx = hvm->rbx;
1204 svm->user_regs.rcx = hvm->rcx;
1205 svm->user_regs.rdx = hvm->rdx;
1206 svm->user_regs.rbp = hvm->rbp;
1207 svm->user_regs.rsi = hvm->rsi;
1208 svm->user_regs.rdi = hvm->rdi;
1209 svm->user_regs.rsp = hvm->rsp;
1210 svm->user_regs.r8 = hvm->r8;
1211 svm->user_regs.r9 = hvm->r9;
1212 svm->user_regs.r10 = hvm->r10;
1213 svm->user_regs.r11 = hvm->r11;
1214 svm->user_regs.r12 = hvm->r12;
1215 svm->user_regs.r13 = hvm->r13;
1216 svm->user_regs.r14 = hvm->r14;
1217 svm->user_regs.r15 = hvm->r15;
1219 svm->user_regs.rip = hvm->rip;
1220 svm->user_regs.rflags = hvm->rflags;
1222 svm->user_regs.error_code = hvm->error_code;
1227 svm->gs_base_kernel = hvm->gs_base;
1229 svm->gs_base_kernel = hvm->shadow_gs;
1235 svm->ctrlreg[0] = hvm->cr0;
1236 svm->ctrlreg[2] = hvm->cr2;
1237 svm->ctrlreg[3] = hvm->cr3;
1238 svm->ctrlreg[4] = hvm->cr4;
1240 svm->debugreg[0] = hvm->dr0;
1241 svm->debugreg[1] = hvm->dr1;
1242 svm->debugreg[2] = hvm->dr2;
1243 svm->debugreg[3] = hvm->dr3;
1244 svm->debugreg[6] = hvm->dr6;
1245 svm->debugreg[7] = hvm->dr7;
1252 static int __xen_vm_vcpu_to_hvm_cpu_context(vcpu_guest_context_t *svm,
1253 HVM_SAVE_TYPE(CPU) *hvm) {
1254 assert(
sizeof(svm->fpu_ctxt.x) ==
sizeof(hvm->fpu_regs));
1256 memcpy(hvm->fpu_regs,svm->fpu_ctxt.x,
sizeof(hvm->fpu_regs));
1258 if (hvm->rax != svm->user_regs.rax) {
1260 svm->user_regs.rax,hvm->rax);
1261 hvm->rax = svm->user_regs.rax;
1263 if (hvm->rbx != svm->user_regs.rbx) {
1265 svm->user_regs.rbx,hvm->rbx);
1266 hvm->rbx = svm->user_regs.rbx;
1268 if (hvm->rcx != svm->user_regs.rcx) {
1270 svm->user_regs.rcx,hvm->rcx);
1271 hvm->rcx = svm->user_regs.rcx;
1273 if (hvm->rdx != svm->user_regs.rdx) {
1275 svm->user_regs.rdx,hvm->rdx);
1276 hvm->rdx = svm->user_regs.rdx;
1278 if (hvm->rbp != svm->user_regs.rbp) {
1280 svm->user_regs.rbp,hvm->rbp);
1281 hvm->rbp = svm->user_regs.rbp;
1283 if (hvm->rsi != svm->user_regs.rsi) {
1285 svm->user_regs.rsi,hvm->rsi);
1286 hvm->rsi = svm->user_regs.rsi;
1288 if (hvm->rdi != svm->user_regs.rdi) {
1290 svm->user_regs.rdi,hvm->rdi);
1291 hvm->rdi = svm->user_regs.rdi;
1293 if (hvm->rsp != svm->user_regs.rsp) {
1295 svm->user_regs.rsp,hvm->rsp);
1296 hvm->rsp = svm->user_regs.rsp;
1298 if (hvm->r8 != svm->user_regs.r8) {
1300 svm->user_regs.r8,hvm->r8);
1301 hvm->r8 = svm->user_regs.r8;
1303 if (hvm->r9 != svm->user_regs.r9) {
1305 svm->user_regs.r9,hvm->r9);
1306 hvm->r9 = svm->user_regs.r9;
1308 if (hvm->r10 != svm->user_regs.r10) {
1310 svm->user_regs.r10,hvm->r10);
1311 hvm->r10 = svm->user_regs.r10;
1313 if (hvm->r11 != svm->user_regs.r11) {
1315 svm->user_regs.r11,hvm->r11);
1316 hvm->r11 = svm->user_regs.r11;
1318 if (hvm->r12 != svm->user_regs.r12) {
1320 svm->user_regs.r12,hvm->r12);
1321 hvm->r12 = svm->user_regs.r12;
1323 if (hvm->r13 != svm->user_regs.r13) {
1325 svm->user_regs.r13,hvm->r13);
1326 hvm->r13 = svm->user_regs.r13;
1328 if (hvm->r14 != svm->user_regs.r14) {
1330 svm->user_regs.r14,hvm->r14);
1331 hvm->r14 = svm->user_regs.r14;
1333 if (hvm->r15 != svm->user_regs.r15) {
1335 svm->user_regs.r15,hvm->r15);
1336 hvm->r15 = svm->user_regs.r15;
1339 if (hvm->rip != svm->user_regs.rip) {
1341 svm->user_regs.rip,hvm->rip);
1342 hvm->rip = svm->user_regs.rip;
1344 if (hvm->rflags != svm->user_regs.rflags) {
1346 svm->user_regs.rflags,hvm->rflags);
1347 hvm->rflags = svm->user_regs.rflags;
1350 if (hvm->error_code != svm->user_regs.error_code) {
1352 svm->user_regs.error_code,hvm->error_code);
1353 hvm->error_code = svm->user_regs.error_code;
1362 if (hvm->cr0 != svm->ctrlreg[0]) {
1364 svm->ctrlreg[0],hvm->cr0);
1365 hvm->cr0 = svm->ctrlreg[0];
1367 if (hvm->cr2 != svm->ctrlreg[2]) {
1369 svm->ctrlreg[2],hvm->cr2);
1370 hvm->cr2 = svm->ctrlreg[2];
1372 if (hvm->cr3 != svm->ctrlreg[3]) {
1374 svm->ctrlreg[3],hvm->cr3);
1375 hvm->cr3 = svm->ctrlreg[3];
1377 if (hvm->cr4 != svm->ctrlreg[4]) {
1379 svm->ctrlreg[4],hvm->cr4);
1380 hvm->cr4 = svm->ctrlreg[4];
1383 if (hvm->dr0 != svm->debugreg[0]) {
1385 svm->debugreg[0],hvm->dr0);
1386 hvm->dr0 = svm->debugreg[0];
1388 if (hvm->dr1 != svm->debugreg[1]) {
1390 svm->debugreg[1],hvm->dr1);
1391 hvm->dr1 = svm->debugreg[1];
1393 if (hvm->dr2 != svm->debugreg[2]) {
1395 svm->debugreg[2],hvm->dr2);
1396 hvm->dr2 = svm->debugreg[2];
1398 if (hvm->dr3 != svm->debugreg[3]) {
1400 svm->debugreg[3],hvm->dr3);
1401 hvm->dr3 = svm->debugreg[3];
1403 if (hvm->dr6 != svm->debugreg[6]) {
1405 svm->debugreg[6],hvm->dr6);
1406 hvm->dr6 = svm->debugreg[6];
1408 if (hvm->dr7 != svm->debugreg[7]) {
1410 svm->debugreg[7],hvm->dr7);
1411 hvm->dr7 = svm->debugreg[7];
1438 static int __xen_vm_cpu_getcontext(
struct target *target,
1439 vcpu_guest_context_t *context) {
1444 uint32_t offset = 0;
1445 struct hvm_save_descriptor *sdesc = NULL;
1447 #ifdef XC_HAVE_CONTEXT_ANY
1448 vcpu_guest_context_any_t context_any;
1453 #ifdef XC_HAVE_CONTEXT_ANY
1455 xstate->
dominfo.max_vcpu_id,&context_any);
1458 xstate->
dominfo.max_vcpu_id,context);
1461 verror(
"could not get vcpu context for %d\n",xstate->
id);
1464 #ifdef XC_HAVE_CONTEXT_ANY
1466 memcpy(context,&context_any.c,
sizeof(*context));
1471 if ((size = xc_domain_hvm_getcontext(
xc_handle,xstate->
id,0,0)) <= 0) {
1472 verror(
"Could not get HVM context buf size!\n");
1477 if (
unlikely(!xstate->hvm_context_buf)) {
1478 xstate->hvm_context_bufsiz = size;
1479 xstate->hvm_context_buf =
malloc(size);
1481 else if (size >= xstate->hvm_context_bufsiz) {
1482 free(xstate->hvm_context_buf);
1483 xstate->hvm_context_bufsiz = size;
1484 xstate->hvm_context_buf =
malloc(size);
1487 xstate->hvm_cpu = NULL;
1489 if (xc_domain_hvm_getcontext(
xc_handle,xstate->
id,xstate->hvm_context_buf,
1490 xstate->hvm_context_bufsiz) < 0) {
1491 verror(
"Could not load HVM context buf!\n");
1496 while (offset < size) {
1497 sdesc = (
struct hvm_save_descriptor *) \
1498 (xstate->hvm_context_buf + offset);
1500 offset +=
sizeof(*sdesc);
1502 if (sdesc->typecode == HVM_SAVE_CODE(CPU)
1503 && sdesc->instance == xstate->
dominfo.max_vcpu_id) {
1504 xstate->hvm_cpu = (HVM_SAVE_TYPE(CPU) *) \
1505 (xstate->hvm_context_buf + offset);
1509 offset += sdesc->length;
1512 if (!xstate->hvm_cpu) {
1513 verror(
"Could not find HVM context for VCPU %d!\n",
1518 if (__xen_vm_hvm_cpu_to_vcpu_context(xstate->hvm_cpu,context)) {
1519 verror(
"Could not translate HVM vcpu info to software vcpu info!\n");
1524 verror(
"HVM unsupported on 32-bit platform!\n");
1533 static int __xen_vm_cpu_setcontext(
struct target *target,
1534 vcpu_guest_context_t *context) {
1537 #ifdef XC_HAVE_CONTEXT_ANY
1538 vcpu_guest_context_any_t context_any;
1543 verror(
"target %s not writeable!\n",target->
name);
1549 #ifdef XC_HAVE_CONTEXT_ANY
1550 memcpy(&context_any.c,context,
sizeof(*context));
1552 xstate->
dominfo.max_vcpu_id,&context_any);
1555 xstate->
dominfo.max_vcpu_id,context);
1558 verror(
"could not set vcpu context for dom %d\n",xstate->
id);
1565 if (__xen_vm_vcpu_to_hvm_cpu_context(context,xstate->hvm_cpu)) {
1566 verror(
"Could not translate software vcpu info to HVM vcpu info!\n");
1570 if (xc_domain_hvm_setcontext(
xc_handle,xstate->
id,
1571 xstate->hvm_context_buf,
1572 xstate->hvm_context_bufsiz)) {
1573 verror(
"Could not store HVM context buf!\n");
1578 verror(
"HVM unsupported on 32-bit platform!\n");
1587 static struct target_thread *__xen_vm_load_current_thread(
struct target *target,
1602 if (globalonly && !force
1609 else if (!globalonly && !force
1614 verror(
"target not paused; cannot load current task!\n");
1625 if (xen_vm_load_dominfo(target)) {
1626 verror(
"could not load dominfo!\n");
1637 if (__xen_vm_cpu_getcontext(target,>state->context) < 0) {
1638 verror(
"could not get vcpu context for %d\n",xstate->
id);
1655 ipval = gtstate->context.user_regs.rip;
1657 ipval = gtstate->context.user_regs.eip;
1660 cpl = 0x3 & gtstate->context.user_regs.cs;
1664 if (__xen_vm_in_userspace(target,cpl,ipval))
1686 gtstate->context.kernel_sp);
1707 "cpl = %d,tidctxt = %d)\n",ipval,pgd,cpl,
1735 vwarn(
"personality set current thread context to %d; global thread"
1736 " context is %d; forcing current to global!\n",
1747 tthread->
state = tstate = \
1750 memcpy(&tstate->context,>state->context,
sizeof(gtstate->context));
1765 gtstate->context.debugreg[0],gtstate->context.debugreg[1],
1766 gtstate->context.debugreg[2],gtstate->context.debugreg[3],
1767 gtstate->context.debugreg[6],gtstate->context.debugreg[7]);
1778 vwarn(
"error loading current thread; trying to use default thread\n");
1784 static struct target_thread *xen_vm_load_current_thread(
struct target *target,
1786 return __xen_vm_load_current_thread(target,force,0);
1800 tid_t xen_vm_gettid(
struct target *target) {
1806 tthread = xen_vm_load_current_thread(target,0);
1808 verror(
"could not load current thread to get TID!\n");
1812 return tthread->
tid;
1815 void xen_vm_free_thread_state(
struct target *target,
void *
state) {
1819 static int xen_vm_snprintf(
struct target *target,
char *buf,
int bufsiz) {
1823 return snprintf(buf,bufsiz,
"domain(%s)",xspec->
domain);
1826 static int xen_vm_init(
struct target *target) {
1834 vwarn(
"auto-enabling SEMI_STRICT bpmode on Xen target.\n");
1839 g_hash_table_insert(target->
config,
1840 strdup(
"OS_EMULATE_USERSPACE_EXCEPTIONS"),
1862 xstate->
dominfo.shutdown_reason = 0;
1863 xstate->
dominfo.max_vcpu_id = 0;
1864 xstate->
dominfo.shared_info_frame = 0;
1883 #ifdef XENCTRL_HAS_XC_INTERFACE
1890 #ifdef XENCTRL_HAS_XC_INTERFACE
1891 *xc_handle = xc_interface_open(NULL,NULL,0);
1893 *xc_handle = xc_interface_open();
1896 verror(
"failed to open xc interface: %s\n",strerror(errno));
1902 #ifdef XENCTRL_HAS_XC_INTERFACE
1903 *xce_handle = xc_evtchn_open(NULL,0);
1905 *xce_handle = xc_evtchn_open();
1908 verror(
"failed to open event channel: %s\n",strerror(errno));
1916 #ifdef XENCTRL_HAS_XC_INTERFACE
1923 xc_interface_close(*xc_handle);
1928 xc_evtchn_close(*xce_handle);
1935 #ifdef XENCTRL_HAS_XC_INTERFACE
1941 if (dbg_port && *dbg_port == -1) {
1942 *dbg_port = xc_evtchn_bind_virq(xce_handle,VIRQ_DEBUGGER);
1948 if ((int32_t)*dbg_port < 0) {
1949 verror(
"failed to bind debug virq port: %s",strerror(errno));
1957 #ifdef XENCTRL_HAS_XC_INTERFACE
1963 if (dbg_port && *dbg_port != -1) {
1964 if (xc_evtchn_unbind(xce_handle,(evtchn_port_t)*dbg_port)) {
1965 verror(
"failed to unbind debug virq port\n");
1977 struct sockaddr_un sun,sun_client;
1980 int spath_len,cpath_len;
1986 if (cfd && *cfd != -1)
1993 if (stat(
"/var/run",&sbuf) == 0
1994 && S_ISDIR(sbuf.st_mode) && access(
"/var/run",W_OK) == 0) {
1996 spath =
malloc(spath_len);
1999 else if ((tmpdir = getenv(
"TMPDIR"))
2000 && stat(tmpdir,&sbuf) == 0 && access(tmpdir,W_OK) == 0) {
2002 spath =
malloc(spath_len);
2005 else if (stat(
"/tmp",&sbuf) == 0
2006 && S_ISDIR(sbuf.st_mode) && access(
"/tmp",W_OK) == 0) {
2008 spath =
malloc(spath_len);
2013 spath =
malloc(spath_len);
2018 spath = strdup(path);
2020 memset(&sun,0,
sizeof(sun));
2021 sun.sun_family = AF_UNIX;
2032 cpath_len = strlen(spath) + 1
2035 *cpath =
malloc(cpath_len);
2039 if (open(*cpath,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR) < 0) {
2041 "could not open client VMP socket file %s: %s\n",
2042 *cpath,strerror(errno));
2049 if (cpath[0] ==
'\0' && (tmpdir = getenv(
"TMPDIR"))) {
2050 cpath_len = strlen(tmpdir) + 1
2053 *cpath =
malloc(cpath_len);
2057 if (open(*cpath,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR) < 0) {
2059 "could not open client VMP socket file %s: %s\n",
2060 *cpath,strerror(errno));
2067 if (cpath[0] ==
'\0') {
2068 cpath_len = strlen(
"/tmp") + 1
2071 *cpath =
malloc(cpath_len);
2075 if (open(*cpath,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR) < 0) {
2077 "could not open client VMP socket file %s: %s\n",
2078 *cpath,strerror(errno));
2085 if (cpath[0] ==
'\0') {
2086 cpath_len = strlen(
".") + 1
2089 *cpath =
malloc(cpath_len);
2093 if (open(*cpath,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR) < 0) {
2095 "could not open client VMP socket file %s: %s\n",
2096 *cpath,strerror(errno));
2104 verror(
"could not open a client VMP socket file; aborting!\n");
2108 memset(&sun_client,0,
sizeof(sun_client));
2109 sun_client.sun_family = AF_UNIX;
2112 *cfd = socket(AF_UNIX,SOCK_STREAM,0);
2114 verror(
"socket(): %s\n",strerror(errno));
2117 len = offsetof(
struct sockaddr_un,sun_path) + strlen(sun_client.sun_path);
2118 if (bind(*cfd,&sun_client,len) < 0) {
2119 verror(
"bind(%s): %s\n",sun_client.sun_path,strerror(errno));
2122 if (fchmod(*cfd,S_IRUSR | S_IWUSR) < 0) {
2123 verror(
"chmod(%s): %s\n",sun_client.sun_path,strerror(errno));
2127 len = offsetof(
struct sockaddr_un,sun_path) + strlen(sun.sun_path);
2128 if (connect(*cfd,&sun,len) < 0) {
2129 verror(
"connect(%s): %s\n",sun.sun_path,strerror(errno));
2148 if (cfd && *cfd != -1) {
2151 if (cpath && *cpath) {
2180 if (dbg_port > -1) {
2181 verror(
"cannot connect for multiple domains without multiplexer!\n");
2192 verror(
"could not launch Xen VIRQ_DEBUGGER multiplexer!\n");
2199 for (i = 0; i < 5; ++
i) {
2209 verror(
"could not connect to launched Xen VIRQ_DEBUGGER multiplexer!\n");
2222 if (dbg_port != -1) {
2234 if (dbg_port != -1) {
2245 XC_EVTCHN_PORT_T port = -1;
2250 if (dbg_port != -1) {
2252 port = xc_evtchn_pending(xce_handle);
2257 retval = xc_evtchn_unmask(xce_handle, port);
2259 verror(
"failed to unmask event channel\n");
2263 if (port != dbg_port) {
2278 if (errno == EINTR) {
2287 else if (rc !=
sizeof(resp)) {
2300 static int xen_vm_attach_internal(
struct target *target) {
2302 struct xen_domctl domctl;
2309 domctl.cmd = XEN_DOMCTL_setdebugging;
2310 domctl.domain = xstate->
id;
2311 domctl.u.setdebugging.enable =
true;
2331 if (xc_domctl(xc_handle,&domctl)) {
2332 verror(
"could not enable debugging of dom %d!\n",xstate->
id);
2338 if (xen_vm_load_dominfo(target)) {
2339 verror(
"could not load dominfo for dom %d\n",xstate->
id);
2343 if (xen_vm_pause(target,0)) {
2344 verror(
"could not pause target before attaching; letting user handle!\n");
2352 verror(
"could not attach memops!\n");
2370 if (!(tthread = __xen_vm_load_cached_thread(target,
TID_GLOBAL))) {
2388 xtstate->context.debugreg[0] = 0;
2389 xtstate->context.debugreg[1] = 0;
2390 xtstate->context.debugreg[2] = 0;
2391 xtstate->context.debugreg[3] = 0;
2392 xtstate->context.debugreg[6] = 0;
2393 xtstate->context.debugreg[7] = 0;
2411 xtstate->context.debugreg[0] = 0;
2412 xtstate->context.debugreg[1] = 0;
2413 xtstate->context.debugreg[2] = 0;
2414 xtstate->context.debugreg[3] = 0;
2415 xtstate->context.debugreg[6] = 0;
2416 xtstate->context.debugreg[7] = 0;
2425 static int xen_vm_detach(
struct target *target,
int stay_paused) {
2427 struct xen_domctl domctl;
2429 domctl.cmd = XEN_DOMCTL_setdebugging;
2430 domctl.domain = xstate->
id;
2431 domctl.u.setdebugging.enable =
false;
2452 verror(
"failed to fini memops; continuing anyway!\n");
2460 if (xc_domctl(xc_handle,&domctl)) {
2461 verror(
"could not disable debugging of dom %d!\n",xstate->
id);
2466 __xen_vm_resume(target,1);
2476 verror(
"failed to unbind debug virq port\n");
2479 verror(
"failed to close xc interfaces\n");
2487 static int xen_vm_fini(
struct target *target) {
2504 static int xen_vm_kill(
struct target *target,
int sig) {
2516 static int xen_vm_loadspaces(
struct target *target) {
2538 static int xen_vm_loadregions(
struct target *target,
struct addrspace *space) {
2541 char *kernel_filename;
2544 (
char *)g_hash_table_lookup(target->
config,
"OS_KERNEL_FILENAME");
2574 static int xen_vm_loaddebugfiles(
struct target *target,
2595 if (!region->
name || strlen(region->
name) == 0)
2633 if (!target->
arch) {
2649 static int xen_vm_postloadinit(
struct target *target) {
2671 char *start = (
char *)g_hash_table_lookup(target->
config,
2672 "OS_KERNEL_START_ADDR");
2676 char *hpage = (
char *)g_hash_table_lookup(target->
config,
2677 "OS_KERNEL_HYPERCALL_PAGE");
2684 static int xen_vm_postopened(
struct target *target) {
2690 static int xen_vm_set_active_probing(
struct target *target,
2698 xen_vm_build_default_overlay_spec(
struct target *target,
tid_t tid) {
2702 static struct target *
2703 xen_vm_instantiate_overlay(
struct target *target,
2707 struct target *overlay;
2740 verror(
"could not load group_leader for thread %d; BUG?!\n",tthread->
tid);
2743 else if (leader != tthread) {
2745 "using group_leader %d instead of user-supplied overlay thread %d\n",
2746 leader->
tid,tthread->
tid);
2759 xen_vm_lookup_overlay_thread_by_id(
struct target *target,
int id) {
2762 retval = xen_vm_load_thread(target,
id,0);
2771 "found overlay thread %d\n",
id);
2775 verror(
"tid %d matched %d, but is a kernel thread!\n",retval->
tid,
id);
2782 xen_vm_lookup_overlay_thread_by_name(
struct target *target,
char *
name) {
2787 GHashTableIter iter;
2789 if ((rc = xen_vm_load_available_threads(target,0)))
2790 vwarn(
"could not load %d threads; continuing anyway!\n",-rc);
2792 g_hash_table_iter_init(&iter,target->
threads);
2793 while (g_hash_table_iter_next(&iter,NULL,(gpointer)&tthread)) {
2797 if (!tthread->name) {
2798 vwarn(
"tid %d does not have a name; continuing!\n",
2803 slen = strlen(tthread->name);
2805 "checking task with name '%*s' against '%s'\n",
2806 slen,tthread->name,name);
2807 if (strncmp(name,tthread->name,slen) == 0) {
2815 verror(
"tid %d matched '%s', but is a kernel thread!\n",
2822 "found overlay thread %"PRIiTID"\n",retval->
tid);
2839 if (nltid == -1 || cltid == -1)
2858 if (xen_vm_load_dominfo(target)) {
2859 verror(
"could not load dominfo for dom %d\n",xstate->
id);
2871 else if (xstate->
dominfo.shutdown)
2881 static int xen_vm_pause(
struct target *target,
int nowait) {
2883 struct timeval check_tv = { 0,0};
2889 if (xen_vm_load_dominfo(target))
2890 vwarn(
"could not load dominfo for dom %d, trying to pause anyway!\n",xstate->
id);
2898 else if (xc_domain_pause(xc_handle,xstate->
id)) {
2899 verror(
"could not pause dom %d!\n",xstate->
id);
2913 if (xen_vm_load_dominfo(target))
2914 vwarn(
"could not reload dominfo for dom %d after pause!\n",xstate->
id);
2931 xen_vm_poll(target,&check_tv,&outcome,&pstatus);
2936 static int xen_vm_flush_current_thread(
struct target *target) {
2944 verror(
"current thread not loaded!\n");
2957 "dom %d tid %"PRIiTID" not valid (%d) or not dirty (%d)\n",
2968 verror(
"target %s not writeable!\n",target->
name);
2975 verror(
"could not convert regcache to vcpu context(dom %d tid %"PRIiTID
")\n",
2984 if (__xen_vm_cpu_setcontext(target,&tstate->
context) < 0) {
2985 verror(
"could not set vcpu context (dom %d tid %"PRIiTID
")\n",
2991 #if __WORDSIZE == 32
2993 "eflags (vcpu context): 0x%"PRIxADDR"\n",
2994 tstate->
context.user_regs.eflags);
2997 "rflags (vcpu context): 0x%"PRIxADDR"\n",
2998 tstate->
context.user_regs.rflags);
3010 tstate->
dr[0],tstate->
dr[1],tstate->
dr[2],tstate->
dr[3],
3011 tstate->
dr[6],tstate->
dr[7]);
3040 static int xen_vm_flush_global_thread(
struct target *target,
3046 vcpu_guest_context_t *ctxp;
3051 verror(
"BUG: no global thread loaded!!!\n");
3056 current_thread = NULL;
3067 "dom %d tid %"PRIiTID
" not valid (%d) or not dirty (%d)\n",
3078 verror(
"could not convert regcache to vcpu context"
3079 " (dom %d tid %"PRIiTID
") ctxt %d\n",
3087 if (!current_thread) {
3091 xstate->
id,gthread->
tid);
3100 verror(
"could not convert regcache to vcpu context"
3101 " (dom %d tid %"PRIiTID
") ctxt %d\n",
3119 ctxp->debugreg[6] = 0;
3124 for (i = 0; i < 4; ++
i) {
3125 if (gtstate->
context.debugreg[i] == 0)
3130 ctxp->debugreg[
i] = gtstate->
context.debugreg[
i];
3132 ctxp->debugreg[7] &= ~(0x3 << (i * 2));
3133 ctxp->debugreg[7] |= ((0x3 << (i * 2)) & gtstate->
context.debugreg[7]);
3135 ctxp->debugreg[7] &= ~(0x3 << (16 + (i * 4)));
3136 ctxp->debugreg[7] |= ((0x3 << (16 + (i * 4))) & gtstate->
context.debugreg[7]);
3138 ctxp->debugreg[7] &= ~(0x3 << (18 + (i * 4)));
3139 ctxp->debugreg[7] |= ((0x3 << (18 + (i * 4))) & gtstate->
context.debugreg[7]);
3147 if (!current_thread) {
3149 "EIP is 0x%"PRIxREGVAL" before flush (dom %d tid %"PRIiTID
")\n",
3151 xstate->
id,gthread->
tid);
3155 "EIP is 0x%"PRIxREGVAL" (in thread %"PRIiTID
") before flush (dom %d tid %"PRIiTID
")\n",
3157 gtstate->
context.user_regs.rip,
3159 gtstate->
context.user_regs.eip,
3161 current_thread->
tid,
3162 xstate->
id,gthread->
tid);
3166 verror(
"target %s not writeable!\n",target->
name);
3174 if (__xen_vm_cpu_setcontext(target,ctxp) < 0) {
3175 verror(
"could not set vcpu context (dom %d tid %"PRIiTID
")\n",
3176 xstate->
id,gthread->
tid);
3184 if (!current_thread)
3193 "debug registers (setting MERGED!!! vcpu context): 0x%"PRIxADDR",0x%"PRIxADDR
3195 ctxp->debugreg[0],ctxp->debugreg[1],
3196 ctxp->debugreg[2],ctxp->debugreg[3],
3197 ctxp->debugreg[6],ctxp->debugreg[7]);
3199 if (!current_thread)
3203 gtstate->
dr[0],gtstate->
dr[1],gtstate->
dr[2],gtstate->
dr[3],
3204 gtstate->
dr[6],gtstate->
dr[7]);
3209 static int xen_vm_pause_thread(
struct target *target,
tid_t tid,
int nowait) {
3210 verror(
"cannot pause individual threads in guests!\n");
3215 static int xen_vm_flush_thread(
struct target *target,
tid_t tid) {
3227 return xen_vm_flush_current_thread(target);
3243 "current thread not loaded to compare with"
3244 " tid %"PRIiTID
"; exiting, user-mode EIP, or BUG?\n",
3249 "current thread not valid to compare with"
3250 " tid %"PRIiTID
"; exiting, user-mode EIP, or BUG?\n",
3259 return xen_vm_flush_current_thread(target);
3267 verror(
"cannot flush unknown thread %"PRIiTID
"; you forgot to load?\n",
3274 return xen_vm_flush_current_thread(target);
3278 "dom %d tid %"PRIiTID
" not valid (%d) or not dirty (%d)\n",
3295 static int xen_vm_flush_all_threads(
struct target *target) {
3297 GHashTableIter iter;
3301 g_hash_table_iter_init(&iter,target->
threads);
3302 while (g_hash_table_iter_next(&iter,NULL,(gpointer)&tthread)) {
3307 rc = xen_vm_flush_thread(target,tthread->tid);
3309 verror(
"could not flush thread %"PRIiTID
"\n",tthread->tid);
3330 rc = xen_vm_flush_current_thread(target);
3332 verror(
"could not flush current thread %"PRIiTID
"\n",
3360 rc = xen_vm_flush_global_thread(target,current_thread);
3369 static int __value_get_append_tid(
struct target *target,
struct value *
value,
3377 verror(
"could not load pid in task; BUG?\n");
3381 array_list_append(list,(
void *)(uintptr_t)
v_i32(v));
3387 static struct array_list *xen_vm_list_available_tids(
struct target *target) {
3393 static int xen_vm_load_all_threads(
struct target *target,
int force) {
3401 for (i = 0; i < array_list_len(cthreads); ++
i) {
3402 tthread = (
struct target_thread *)array_list_item(cthreads,i);
3405 "tid %"PRIiTID
" (%p)\n",tthread->
tid,tthread);
3407 if (!xen_vm_load_thread(target,tthread->
tid,force)) {
3409 verror(
"could not load thread %"PRIiTID
"\n",tthread->
tid);
3423 static int xen_vm_load_available_threads(
struct target *target,
int force) {
3431 if (!__xen_vm_load_current_thread(target,force,1)) {
3432 verror(
"could not load current thread!\n");
3440 static int xen_vm_thread_snprintf(
struct target *target,
3442 char *buf,
int bufsiz,
3443 int detail,
char *sep,
char *kvsep) {
3449 buf,bufsiz,detail,sep,kvsep,0);
3455 (rc >= bufsiz) ? NULL : buf + rc,
3456 (rc >= bufsiz) ? 0 : bufsiz - rc,
3459 verror(
"could not snprintf personality info for thread %d!\n",
3472 static int xen_vm_thread_snprintf(
struct target_thread *tthread,
3473 char *buf,
int bufsiz,
3474 int detail,
char *sep,
char *kvsep) {
3476 struct cpu_user_regs *r;
3481 goto personality_out;
3485 goto personality_out;
3487 r = &tstate->
context.user_regs;
3494 rc += snprintf((rc >= bufsiz) ? NULL : buf + rc,
3495 (rc >= bufsiz) ? 0 :bufsiz - rc,
3496 "%s" "ip%s%"RF "%s" "bp%s%"RF "%s" "sp%s%"RF "%s"
3497 "flags%s%"RF "%s" "ax%s%"RF "%s" "bx%s%"RF "%s"
3498 "cx%s%"RF "%s" "dx%s%"RF "%s" "di%s%"RF "%s"
3499 "si%s%"RF "%s" "cs%s%d" "%s" "ss%s%d" "%s"
3500 "ds%s%d" "%s" "es%s%d" "%s"
3501 "fs%s%d" "%s" "gs%s%d",
3502 #
if __WORDSIZE == 64
3503 sep,kvsep,r->rip,sep,kvsep,r->rbp,sep,kvsep,r->rsp,sep,
3504 kvsep,r->eflags,sep,kvsep,r->rax,sep,kvsep,r->rbx,sep,
3505 kvsep,r->rcx,sep,kvsep,r->rdx,sep,kvsep,r->rdi,sep,
3506 kvsep,r->rsi,sep,kvsep,r->cs,sep,kvsep,r->ss,sep,
3507 kvsep,r->ds,sep,kvsep,r->es,sep,
3508 kvsep,r->fs,sep,kvsep,r->gs
3510 sep,kvsep,r->eip,sep,kvsep,r->ebp,sep,kvsep,r->esp,sep,
3511 kvsep,r->eflags,sep,kvsep,r->eax,sep,kvsep,r->ebx,sep,
3512 kvsep,r->ecx,sep,kvsep,r->edx,sep,kvsep,r->edi,sep,
3513 kvsep,r->esi,sep,kvsep,r->cs,sep,kvsep,r->ss,sep,
3514 kvsep,r->ds,sep,kvsep,r->es,sep,
3515 kvsep,r->fs,sep,kvsep,r->gs
3519 rc += snprintf((rc >= bufsiz) ? NULL : buf + rc,
3520 (rc >= bufsiz) ? 0 :bufsiz - rc,
3521 "%s" "dr0%s%"DRF "%s" "dr1%s%"DRF
3522 "%s" "dr2%s%"DRF "%s" "dr3%s%"DRF
3523 "%s" "dr6%s%"DRF "%s" "dr7%s%"DRF,
3524 sep,kvsep,tstate->
dr[0],sep,kvsep,tstate->
dr[1],
3525 sep,kvsep,tstate->
dr[1],sep,kvsep,tstate->
dr[2],
3526 sep,kvsep,tstate->
dr[6],sep,kvsep,tstate->
dr[7]);
3529 nrc = target_personality_thread_snprintf(tthread,
3530 (rc >= bufsiz) ? NULL : buf + rc,
3531 (rc >= bufsiz) ? 0 : bufsiz - rc,
3534 verror(
"could not snprintf personality info for thread %d!\n",
3543 static int xen_vm_invalidate_thread(
struct target *target,
3557 static int __xen_vm_resume(
struct target *target,
int detaching) {
3563 if (xen_vm_load_dominfo(target))
3564 vwarn(
"could not load dominfo for dom %d, trying to pause anyway!\n",xstate->
id);
3566 if (!xstate->
dominfo.paused) {
3567 vwarn(
"dom %d not paused; not invalidating and resuming; bug?\n",
3590 rc = xc_domain_unpause(xc_handle,xstate->
id);
3597 static int xen_vm_resume(
struct target *target) {
3598 return __xen_vm_resume(target,0);
3610 int *again,
void *priv) {
3617 tid_t overlay_leader_tid;
3624 ADDR bogus_sstep_probepoint_addr;
3625 struct target *overlay;
3634 if (xen_vm_load_dominfo(target)) {
3635 verror(
"could not load dominfo; returning to user!\n");
3643 "ignoring \"exception\" in our running VM %d; not for us\n",
3651 "new debug event (brctr = %"PRIu64
", tsc = %"PRIx64
")\n",
3663 if (!__xen_vm_load_current_thread(target,0,1)) {
3664 verror(
"could not load global thread!\n");
3675 verror(
"could not read CPL while checking debug event: %s\n",
3681 verror(
"could not read EIP while checking debug event: %s\n",
3703 xen_vm_load_current_thread(target,0);
3705 if (__xen_vm_in_userspace(target,cpl,ipval)) {
3709 verror(
"could not load current userspace thread at 0x%"PRIxADDR"!\n",
3717 target->current_thread->state;
3721 "user-mode debug event at EIP 0x%"PRIxADDR" in tid %"PRIiTID
";"
3722 " will try to handle it if it is single step!\n",
3733 verror(
"could not read current thread!\n");
3763 "dbgreg[6]=0x%"DRF", eflags=0x%"RF"\n",
3764 tid, ipval, xtstate->
context.debugreg[6],
3765 xtstate->
context.user_regs.eflags);
3768 if (xtstate->
context.debugreg[6] & 0x4000
3788 "emulating debug memmod at ss for tid %"PRIiTID
3810 || (__xen_vm_in_userspace(target,cpl,ipval)
3816 if (__xen_vm_in_userspace(target,cpl,ipval)) {
3818 "single step event in overlay tid %"PRIiTID
3819 " (tgid %"PRIiTID
"); notifying overlay\n",
3823 xtstate->
context.debugreg[6] = 0;
3862 "single step event in overlay tid %"PRIiTID
3863 " (tgid %"PRIiTID
") INTO KERNEL (at 0x%"PRIxADDR")"
3864 " notifying overlay\n",
3868 xtstate->
context.debugreg[6] = 0;
3882 sstep_thread = NULL;
3888 handle_inferred_sstep:
3889 if (!tthread->
tpc) {
3890 if (sstep_thread && __xen_vm_in_userspace(target,cpl,ipval)) {
3891 vwarn(
"single step event (status reg and eflags) into"
3892 " userspace; trying to handle in sstep thread"
3893 " %"PRIiTID
"!\n",sstep_thread->tid);
3894 goto handle_sstep_thread;
3900 xtstate->
context.debugreg[6] = 0;
3911 gtstate->
context.debugreg[6] = 0;
3933 xtstate->
context.debugreg[6] = 0;
3945 gtstate->
context.debugreg[6] = 0;
3952 else if (sstep_thread) {
3954 "thread %"PRIiTID
" single stepped can_context_switch"
3955 " instr; trying to handle exception in old thread!\n",
3958 handle_sstep_thread:
3960 sstep_thread->tpc->probepoint);
3963 xtstate->
context.debugreg[6] = 0;
3969 else if (__xen_vm_in_userspace(target,cpl,ipval)) {
3971 "; debug status reg 0x%"DRF"; eflags 0x%"RF
3972 "; skipping handling!\n",
3973 ipval,xtstate->
context.debugreg[6],
3974 xtstate->
context.user_regs.eflags);
3981 xtstate->
context.debugreg[6] = 0;
4008 if (xtstate->
context.debugreg[6] & 15) {
4009 if (xtstate->
context.debugreg[6] & 0x1)
4011 else if (xtstate->
context.debugreg[6] & 0x2)
4013 else if (xtstate->
context.debugreg[6] & 0x4)
4015 else if (xtstate->
context.debugreg[6] & 0x8)
4037 verror(
"DR6 said hw dbg reg %d at 0x%"DRF" was hit;"
4038 " but EIP 0x%"PRIxADDR" in tid %"PRIiTID
" does not"
4039 " match! ignoring hw dbg status; continuing"
4041 dreg,xtstate->
context.debugreg[dreg],ipval,
4056 gtstate->
context.debugreg[6] = 0;
4063 if (__xen_vm_in_userspace(target,cpl,ipval)) {
4064 vwarn(
"user-mode debug event (hw dbg reg)"
4065 " at 0x%"PRIxADDR"; debug status reg 0x%"DRF"; eflags"
4066 " 0x%"RF"; trying to handle in global thread!\n",
4067 ipval,xtstate->
context.debugreg[6],
4068 xtstate->
context.user_regs.eflags);
4076 ipval = xtstate->
context.debugreg[dreg];
4079 "found hw break (status) in dreg %d on 0x%"PRIxADDR"\n",
4082 else if (__xen_vm_in_userspace(target,cpl,ipval)) {
4087 overlay_leader_tid =
4092 "found yet-unknown thread %d with"
4093 " overlay leader %d; will notify!\n",
4094 tthread->
tid,overlay_leader_tid);
4103 "user-mode debug event in overlay tid %"PRIiTID
4104 " (tgid %"PRIiTID
") (not single step, not hw dbg reg)"
4105 " at 0x%"PRIxADDR"; debug status reg 0x%"DRF"; eflags"
4106 " 0x%"RF"; passing to overlay!\n",
4109 xtstate->
context.user_regs.eflags);
4123 if (xtstate->
context.debugreg[6] & 0x4000) {
4126 "single step debug event in overlay\n");
4128 else if (bogus_sstep_thread
4132 "inferred single step debug event in overlay\n");
4137 xtstate->
context.debugreg[6] = 0;
4160 rc = xen_vm_addr_v2p(target,
TID_GLOBAL,tmp_ipval,&paddr);
4168 "emulating debug memmod at bp for tid %"PRIiTID
4170 tid,pmmod->addr,tmp_ipval);
4175 verror(
"could not emulate debug memmod for"
4176 " tid %"PRIiTID
" at paddr 0x%"PRIxADDR"\n",
4182 xtstate->
context.debugreg[6] = 0;
4185 gtstate->
context.debugreg[6] = 0;
4188 "cleared status debug reg 6\n");
4194 verror(
"user-mode debug event (not single step, not"
4195 " hw dbg reg) at 0x%"PRIxADDR"; debug status reg"
4196 " 0x%"DRF"; eflags 0x%"RF"; skipping handling!\n",
4197 tmp_ipval,xtstate->
context.debugreg[6],
4198 xtstate->
context.user_regs.eflags);
4205 "dreg status was 0x%"PRIxREGVAL"; trying eip method\n",
4208 if (xtstate->
dr[0] == ipval)
4210 else if (xtstate->
dr[1] == ipval)
4212 else if (xtstate->
dr[2] == ipval)
4214 else if (xtstate->
dr[3] == ipval)
4219 "found hw break (eip) in dreg %d on 0x%"PRIxADDR"\n",
4222 if (xtstate != gtstate) {
4227 if (gtstate->
dr[0] == ipval)
4229 else if (gtstate->
dr[1] == ipval)
4231 else if (gtstate->
dr[2] == ipval)
4233 else if (gtstate->
dr[3] == ipval)
4238 "found hw break (eip) in GLOBAL dreg %d on 0x%"PRIxADDR"\n",
4242 "did NOT find hw break (eip) on 0x%"PRIxADDR
4243 " (neither global nor per-thread!)\n",
4248 "did NOT find hw break (eip) on 0x%"PRIxADDR"\n",
4262 "found hw break in thread %"PRIiTID
"\n",
4271 verror(
"could not find probepoint for hw dbg reg %d"
4272 " in current or global threads!\n",dreg);
4277 "found hw break in global thread!\n");
4289 gtstate->
context.debugreg[6] = 0;
4307 xtstate->
context.debugreg[6] & 0x4000);
4310 xtstate->
context.debugreg[6] = 0;
4321 xtstate->
context.debugreg[6] & 0x4000);
4324 xtstate->
context.debugreg[6] = 0;
4335 "thread-inferred single step for dom %d (TF set, but not"
4336 " dreg status!) at 0x%"PRIxADDR" (stepped %lu bytes"
4337 " from probepoint)!\n",
4339 sstep_thread = tthread;
4340 goto handle_inferred_sstep;
4343 && bogus_sstep_thread
4344 && bogus_sstep_thread->tpc
4345 && bogus_sstep_thread->tpc->probepoint) {
4346 bogus_sstep_probepoint_addr =
4355 "inferred single step for dom %d (TF set, but not"
4356 " dreg status!) at 0x%"PRIxADDR" (stepped %d bytes"
4357 " from probepoint)!\n",
4358 xstate->
id,ipval,ipval - bogus_sstep_probepoint_addr);
4359 sstep_thread = bogus_sstep_thread;
4360 goto handle_inferred_sstep;
4364 vwarn(
"phantom single step for dom %d (no breakpoint"
4365 " set either!); letting user handle fault at"
4370 vwarn(
"could not find hardware bp and not sstep'ing;"
4371 " letting user handle fault at 0x%"PRIxADDR"!\n",
4410 struct target *target = (
struct target *)state;
4423 if (vmid != 0 && vmid != xstate->
id)
4427 retval = xen_vm_handle_exception(target,0,&again,NULL);
4438 __xen_vm_resume(target,0);
4447 verror(
"no evloop attached!\n");
4454 verror(
"event channel not initialized\n");
4462 "added evloop readfd %d event channel\n",xstate->
evloop_fd);
4492 verror(
"event channel not initialized\n");
4503 ret = select(fd+1,&inset,NULL,NULL,&tv);
4507 if (!FD_ISSET(fd, &inset))
4511 verror(
"failed to unmask event channel\n");
4516 if (vmid != 0 && vmid != xstate->
id)
4520 retval = xen_vm_handle_exception(target,0,&again,NULL);
4533 if (xen_vm_load_dominfo(target)) {
4534 vwarn(
"could not load dominfo for dom %d, trying to unpause anyway!\n",
4536 __xen_vm_resume(target,0);
4538 else if (xstate->
dominfo.paused) {
4539 __xen_vm_resume(target,0);
4546 static target_status_t xen_vm_poll(
struct target *target,
struct timeval *tv,
4559 verror(
"event channel not initialized\n");
4572 ret = select(fd+1,&inset,NULL,NULL,tv);
4579 if (!FD_ISSET(fd, &inset)) {
4586 verror(
"failed to unmask event channel\n");
4593 if (vmid != 0 && vmid != xstate->
id) {
4600 retval = xen_vm_handle_exception(target,0,&again,NULL);
4607 static unsigned char *xen_vm_read(
struct target *target,
ADDR addr,
4608 unsigned long target_length,
4609 unsigned char *buf) {
4613 static unsigned long xen_vm_write(
struct target *target,
ADDR addr,
4614 unsigned long length,
unsigned char *buf) {
4616 verror(
"target %s not writeable!\n",target->
name);
4633 static int __xen_vm_pgd(
struct target *target,
tid_t tid,uint64_t *pgd) {
4637 REGVAL cr0 = 0,cr4 = 0,msr_efer = 0,cpuid_edx = 0;
4642 tthread = __xen_vm_load_current_thread(target,0,1);
4644 verror(
"could not load global thread!\n");
4656 "tid %"PRIiTID
" pgd (phys) = 0x%"PRIx64
" (cached)\n",tid,*pgd);
4661 if (xtstate->
context.vm_assist & (1 << VMASST_TYPE_pae_extended_cr3)) {
4662 *pgd = ((uint64_t)xen_cr3_to_pfn(xtstate->
context.ctrlreg[3])) \
4680 cr0 = xtstate->
context.ctrlreg[0];
4681 cr4 = xtstate->
context.ctrlreg[4];
4682 if (xstate->
hvm && xstate->hvm_cpu)
4683 msr_efer = xstate->hvm_cpu->msr_efer;
4689 verror(
"could not determine v2p_flags! pgd walks might fail;"
4690 " assuming 64-bit long mode and paging!\n");
4694 verror(
"could not determine v2p_flags! pgd walks might fail;"
4695 " assuming 32-bit mode and PAE (and auto-PSE)!\n");
4715 tthread = xen_vm_load_thread(target,tid,0);
4717 verror(
"could not load tid %"PRIiTID
"!\n",tid);
4723 tthread->
state = xtstate;
4733 "tid %"PRIiTID
" pgd (phys) = 0x%"PRIx64
" (cached)\n",tid,*pgd);
4755 verror(
"could not get phys pgd for tid %"PRIiTID
": %s!\n",
4756 tid,strerror(errno));
4764 "tid %"PRIiTID
" pgd (phys) = 0x%"PRIx64
"\n",tid,*pgd);
4769 static int xen_vm_addr_v2p(
struct target *target,
tid_t tid,
4776 if (__xen_vm_pgd(target,tid,&pgd)) {
4777 verror(
"could not read pgd for tid %"PRIiTID
"!\n",tid);
4789 static unsigned char *xen_vm_read_phys(
struct target *target,
ADDR paddr,
4790 unsigned long length,
unsigned char *buf) {
4803 static unsigned long xen_vm_write_phys(
struct target *target,
ADDR paddr,
4804 unsigned long length,
unsigned char *buf) {
4815 verror(
"target %s not writeable!\n",target->
name);
4824 unsigned long length,
unsigned char *buf) {
4835 if (__xen_vm_pgd(target,tid,&pgd)) {
4836 verror(
"could not read pgd for tid %"PRIiTID
"!\n",tid);
4840 return xstate->
memops->
read_tid(target,tid,pgd,vaddr,length,buf);
4844 unsigned long length,
unsigned char *buf) {
4855 if (__xen_vm_pgd(target,tid,&pgd)) {
4856 verror(
"could not read pgd for tid %"PRIiTID
"!\n",tid);
4861 verror(
"target %s not writeable!\n",target->
name);
4882 offsetof(
struct vcpu_guest_context,user_regs.rax),
4883 offsetof(
struct vcpu_guest_context,user_regs.rdx),
4884 offsetof(
struct vcpu_guest_context,user_regs.rcx),
4885 offsetof(
struct vcpu_guest_context,user_regs.rbx),
4886 offsetof(
struct vcpu_guest_context,user_regs.rsi),
4887 offsetof(
struct vcpu_guest_context,user_regs.rdi),
4888 offsetof(
struct vcpu_guest_context,user_regs.rbp),
4889 offsetof(
struct vcpu_guest_context,user_regs.rsp),
4890 offsetof(
struct vcpu_guest_context,user_regs.r8),
4891 offsetof(
struct vcpu_guest_context,user_regs.r9),
4892 offsetof(
struct vcpu_guest_context,user_regs.r10),
4893 offsetof(
struct vcpu_guest_context,user_regs.r11),
4894 offsetof(
struct vcpu_guest_context,user_regs.r12),
4895 offsetof(
struct vcpu_guest_context,user_regs.r13),
4896 offsetof(
struct vcpu_guest_context,user_regs.r14),
4897 offsetof(
struct vcpu_guest_context,user_regs.r15),
4898 offsetof(
struct vcpu_guest_context,user_regs.rip),
4899 -1, -1, -1, -1, -1, -1, -1, -1,
4900 -1, -1, -1, -1, -1, -1, -1, -1,
4901 -1, -1, -1, -1, -1, -1, -1, -1,
4902 -1, -1, -1, -1, -1, -1, -1, -1,
4903 offsetof(
struct vcpu_guest_context,user_regs.rflags),
4904 offsetof(
struct vcpu_guest_context,user_regs.es),
4905 offsetof(
struct vcpu_guest_context,user_regs.cs),
4906 offsetof(
struct vcpu_guest_context,user_regs.ss),
4907 offsetof(
struct vcpu_guest_context,user_regs.ds),
4908 offsetof(
struct vcpu_guest_context,user_regs.fs),
4909 offsetof(
struct vcpu_guest_context,user_regs.gs),
4912 offsetof(
struct vcpu_guest_context,fs_base),
4913 offsetof(
struct vcpu_guest_context,gs_base_kernel),
4914 offsetof(
struct vcpu_guest_context,gs_base_kernel),
4915 offsetof(
struct vcpu_guest_context,gs_base_user),
4916 -1, -1, -1, -1, -1, -1,
4918 offsetof(
struct vcpu_guest_context,ctrlreg[0]),
4919 offsetof(
struct vcpu_guest_context,ctrlreg[1]),
4920 offsetof(
struct vcpu_guest_context,ctrlreg[2]),
4921 offsetof(
struct vcpu_guest_context,ctrlreg[3]),
4922 offsetof(
struct vcpu_guest_context,ctrlreg[4]),
4924 offsetof(
struct vcpu_guest_context,debugreg[0]),
4925 offsetof(
struct vcpu_guest_context,debugreg[1]),
4926 offsetof(
struct vcpu_guest_context,debugreg[2]),
4927 offsetof(
struct vcpu_guest_context,debugreg[3]),
4929 offsetof(
struct vcpu_guest_context,debugreg[6]),
4930 offsetof(
struct vcpu_guest_context,debugreg[7]),
4935 offsetof(
struct vcpu_guest_context,user_regs.eax),
4936 offsetof(
struct vcpu_guest_context,user_regs.ecx),
4937 offsetof(
struct vcpu_guest_context,user_regs.edx),
4938 offsetof(
struct vcpu_guest_context,user_regs.ebx),
4939 offsetof(
struct vcpu_guest_context,user_regs.esp),
4940 offsetof(
struct vcpu_guest_context,user_regs.ebp),
4941 offsetof(
struct vcpu_guest_context,user_regs.esi),
4942 offsetof(
struct vcpu_guest_context,user_regs.edi),
4943 offsetof(
struct vcpu_guest_context,user_regs.eip),
4944 offsetof(
struct vcpu_guest_context,user_regs.eflags),
4945 -1, -1, -1, -1, -1, -1, -1, -1,
4947 -1, -1, -1, -1, -1, -1, -1, -1,
4948 -1, -1, -1, -1, -1, -1, -1, -1,
4951 offsetof(
struct vcpu_guest_context,user_regs.es),
4952 offsetof(
struct vcpu_guest_context,user_regs.cs),
4953 offsetof(
struct vcpu_guest_context,user_regs.ss),
4954 offsetof(
struct vcpu_guest_context,user_regs.ds),
4955 offsetof(
struct vcpu_guest_context,user_regs.fs),
4956 offsetof(
struct vcpu_guest_context,user_regs.gs),
4957 offsetof(
struct vcpu_guest_context,ctrlreg[0]),
4958 offsetof(
struct vcpu_guest_context,ctrlreg[1]),
4959 offsetof(
struct vcpu_guest_context,ctrlreg[2]),
4960 offsetof(
struct vcpu_guest_context,ctrlreg[3]),
4961 offsetof(
struct vcpu_guest_context,ctrlreg[4]),
4962 offsetof(
struct vcpu_guest_context,debugreg[0]),
4963 offsetof(
struct vcpu_guest_context,debugreg[1]),
4964 offsetof(
struct vcpu_guest_context,debugreg[2]),
4965 offsetof(
struct vcpu_guest_context,debugreg[3]),
4967 offsetof(
struct vcpu_guest_context,debugreg[6]),
4968 offsetof(
struct vcpu_guest_context,debugreg[7]),
4976 struct vcpu_guest_context *context,
4985 tthread->
tid,tctxt);
4991 if (arch_wordsize(target->
arch) == 8 || __WORDSIZE == 64) {
4993 offset = dreg_to_offset64[
i];
4998 regval = (
REGVAL)*(uint64_t *)(((
char *)context) + offset);
5000 regval = (
REGVAL)*(uint16_t *)(((
char *)context) + offset);
5004 vwarn(
"could not set reg %d thid %d tctxt %d\n",
5005 i,tthread->
tid,tctxt);
5011 else if (arch_wordsize(target->
arch) == 4) {
5013 offset = dreg_to_offset32[
i];
5017 regval = (
REGVAL)*(uint32_t *)(((
char *)context) + offset);
5021 vwarn(
"could not set reg %d thid %d tctxt %d\n",
5022 i,tthread->
tid,tctxt);
5030 "translated %d vcpu regs to thid %d tctxt %d regcache\n",
5031 count,tthread->
tid,tctxt);
5040 struct vcpu_guest_context *context;
5044 vwarn(
"unsupported reg %d!\n",reg);
5049 context = (
struct vcpu_guest_context *)priv;
5050 offset = dreg_to_offset64[reg];
5053 vwarn(
"unsupported reg %d!\n",reg);
5059 "tid %d thid %d tctxt %d regcache->vcpu %d 0x%"PRIxREGVAL"\n",
5060 target->
id,tthread->
tid,tctxt,reg,regval);
5063 *(uint64_t *)(((
char *)context) + offset) =
5066 *(uint16_t *)(((
char *)context) + offset) =
5075 REG reg,
void *rawval,
int rawlen,
5081 vwarn(
"unsupported reg %d!\n",reg);
5087 offset = dreg_to_offset64[reg];
5090 vwarn(
"unsupported reg %d!\n",reg);
5095 vwarn(
"tid %d thid %d tctxt %d regcache->vcpu %d"
5096 " -- unsupported rawval len %d\n",
5097 target->
id,tthread->
tid,tctxt,reg,rawlen);
5106 struct vcpu_guest_context *context;
5110 vwarn(
"unsupported reg %d!\n",reg);
5115 context = (
struct vcpu_guest_context *)priv;
5116 offset = dreg_to_offset32[reg];
5119 vwarn(
"unsupported reg %d!\n",reg);
5125 "tid %d thid %d tctxt %d regcache->vcpu %d 0x%"PRIxREGVAL"\n",
5126 target->
id,tthread->
tid,tctxt,reg,regval);
5128 *(uint32_t *)(((
char *)context) + offset) = (uint32_t)regval;
5136 REG reg,
void *rawval,
int rawlen,
5142 vwarn(
"unsupported reg %d!\n",reg);
5148 offset = dreg_to_offset32[reg];
5151 vwarn(
"unsupported reg %d!\n",reg);
5156 vwarn(
"tid %d thid %d tctxt %d regcache->vcpu %d"
5157 " -- unsupported rawval len %d\n",
5158 target->
id,tthread->
tid,tctxt,reg,rawlen);
5166 struct vcpu_guest_context *context) {
5168 tthread->
tid,tctxt);
5174 if (arch_wordsize(target->
arch) == 8 || __WORDSIZE == 64) {
5180 else if (arch_wordsize(target->
arch) == 4) {
5193 static REG xen_vm_get_unused_debug_reg(
struct target *target,
tid_t tid) {
5199 verror(
"currently must use TID_GLOBAL for hardware probepoints!\n");
5203 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5206 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5211 if (!xtstate->
dr[0]) { retval = 0; }
5212 else if (!xtstate->
dr[1]) { retval = 1; }
5213 else if (!xtstate->
dr[2]) { retval = 2; }
5214 else if (!xtstate->
dr[3]) { retval = 3; }
5245 static int xen_vm_set_hw_breakpoint(
struct target *target,
tid_t tid,
5250 if (reg < 0 || reg > 3) {
5256 verror(
"target %s not writeable!\n",target->
name);
5261 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5264 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5269 if (xtstate->
context.debugreg[reg] != 0) {
5270 vwarn(
"debug reg %"PRIiREG" already has an address, overwriting (0x%lx)!\n",
5271 reg,xtstate->
context.debugreg[reg]);
5277 xtstate->
dr[reg] = (
unsigned long)addr;
5283 xtstate->
dr[7] |= (1 << (reg * 2));
5284 xtstate->
dr[7] &= ~(1 << (reg * 2 + 1));
5286 xtstate->
dr[7] &= ~(3 << (16 + (reg * 4)));
5289 xtstate->
context.debugreg[reg] = xtstate->
dr[reg];
5290 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5291 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5295 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5299 if (xstate->
dominfo.ttd_replay_flag) {
5300 int ret = xc_ttd_vmi_add_probe(xc_handle,xstate->
id,addr);
5304 xstate->
id,addr,ret);
5308 "registered probe in replay domain [dom%d:%"PRIxADDR"]\n",
5316 static int xen_vm_set_hw_watchpoint(
struct target *target,
tid_t tid,
5323 if (reg < 0 || reg > 3) {
5329 verror(
"target %s not writeable!\n",target->
name);
5334 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5337 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5342 if (xtstate->
context.debugreg[reg] != 0) {
5343 vwarn(
"debug reg %"PRIiREG" already has an address, overwriting (0x%lx)!\n",
5344 reg,xtstate->
context.debugreg[reg]);
5350 xtstate->
dr[reg] = addr;
5356 xtstate->
dr[7] |= (1 << (reg * 2));
5357 xtstate->
dr[7] &= ~(1 << (reg * 2 + 1));
5359 xtstate->
dr[7] &= ~(3 << (16 + (reg * 4)));
5360 xtstate->
dr[7] |= (whence << (16 + (reg * 4)));
5362 xtstate->
dr[7] &= ~(3 << (18 + (reg * 4)));
5363 xtstate->
dr[7] |= (watchsize << (18 + (reg * 4)));
5367 xtstate->
dr[6],xtstate->
dr[7],whence,watchsize);
5370 xtstate->
context.debugreg[reg] = xtstate->
dr[reg];
5371 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5372 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5376 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5380 if (xstate->
dominfo.ttd_replay_flag) {
5381 int ret = xc_ttd_vmi_add_probe(xc_handle,xstate->
id,addr);
5385 xstate->
id,addr,ret);
5389 "registered probe in replay domain [dom%d:%"PRIxADDR"]\n",
5397 static int xen_vm_unset_hw_breakpoint(
struct target *target,
tid_t tid,
REG reg) {
5398 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5404 if (reg < 0 || reg > 3) {
5410 verror(
"target %s not writeable!\n",target->
name);
5415 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5418 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5423 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5424 addr = xtstate->
dr[reg];
5428 xtstate->
dr[reg] = 0;
5434 xtstate->
dr[7] &= ~(3 << (reg * 2));
5437 xtstate->
context.debugreg[reg] = xtstate->
dr[reg];
5438 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5439 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5443 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5447 if (xstate->
dominfo.ttd_replay_flag) {
5448 int ret = xc_ttd_vmi_remove_probe(xc_handle,xstate->
id,addr);
5452 xstate->
id,addr,ret);
5456 "unregistered probe in replay domain [dom%d:%"PRIxADDR"]\n",
5464 static int xen_vm_unset_hw_watchpoint(
struct target *target,
tid_t tid,
REG reg) {
5466 return xen_vm_unset_hw_breakpoint(target,tid,reg);
5474 verror(
"target %s not writeable!\n",target->
name);
5479 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5482 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5487 xtstate->
context.debugreg[7] = 0;
5499 verror(
"target %s not writeable!\n",target->
name);
5504 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5507 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5512 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5523 if (dreg < 0 || dreg > 3) {
5529 verror(
"target %s not writeable!\n",target->
name);
5534 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5537 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5546 xtstate->
dr[7] &= ~(3 << (dreg * 2));
5549 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5550 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5554 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5558 if (xstate->
dominfo.ttd_replay_flag) {
5559 int ret = xc_ttd_vmi_remove_probe(xc_handle,xstate->
id,xtstate->
dr[dreg]);
5562 verror(
"failed to unregister probe [dom%d:%lx (%d)\n",
5563 xstate->
id,xtstate->
dr[dreg],ret);
5567 "unregistered probe in replay domain [dom%d:%lx]\n",
5568 xstate->
id,xtstate->
dr[dreg]);
5579 if (dreg < 0 || dreg > 3) {
5585 verror(
"target %s not writeable!\n",target->
name);
5590 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5593 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5602 xtstate->
dr[7] |= (1 << (dreg * 2));
5603 xtstate->
dr[7] &= ~(1 << (dreg * 2 + 1));
5606 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5607 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5611 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5615 if (xstate->
dominfo.ttd_replay_flag) {
5616 int ret = xc_ttd_vmi_add_probe(xc_handle,xstate->
id,xtstate->
dr[dreg]);
5619 verror(
"failed to register probe [dom%d:%lx (%d)\n",
5620 xstate->
id,xtstate->
dr[dreg],ret);
5624 "registered probe in replay domain [dom%d:%lx]\n",
5625 xstate->
id,xtstate->
dr[dreg]);
5634 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5637 char *msg =
"unregister";
5643 if (!xstate->
dominfo.ttd_replay_flag)
5648 ret = xc_ttd_vmi_add_probe(xc_handle,xstate->
id,addr);
5651 ret = xc_ttd_vmi_remove_probe(xc_handle,xstate->
id,addr);
5656 msg,xstate->
id,addr,ret);
5660 "%sed probe in replay domain [dom%d:%"PRIxADDR"]\n",
5661 msg,xstate->
id,addr);
5667 struct target *overlay) {
5673 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5676 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5705 #ifdef XC_HAVE_DOMAIN_DEBUG_CONTROL
5706 if (xc_domain_debug_control(xc_handle,xstate->
id,
5707 XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON,
5708 xstate->
dominfo.max_vcpu_id)) {
5709 vwarn(
"xc_domain_debug_control failed! falling back to eflags!\n");
5715 vwarn(
"xc_domain_debug_control does not exist; falling back to eflags!\n");
5724 verror(
"BUG: overlay process driver should call"
5725 " target_os_thread_singlestep()!\n");
5732 verror(
"target %s not writeable!\n",target->
name);
5737 #if __WORDSIZE == 32
5767 struct target *overlay) {
5773 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5776 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5788 #ifdef XC_HAVE_DOMAIN_DEBUG_CONTROL
5789 if (xc_domain_debug_control(xc_handle,xstate->
id,
5790 XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF,
5791 xstate->
dominfo.max_vcpu_id)) {
5792 vwarn(
"xc_domain_debug_control failed! falling back to eflags!\n");
5798 vwarn(
"xc_domain_debug_control does not exist; falling back to eflags!\n");
5807 verror(
"BUG: overlay process driver should call"
5808 " target_os_thread_singlestep_end()!\n");
5815 verror(
"target %s not writeable!\n",target->
name);
5835 unsigned char buf[2];
5845 else if (buf[0] == 0xcc || buf[0] == 0xcd || buf[1] == 0xce)
5856 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5859 if (xstate->
dominfo.ttd_guest) {
5862 else if (!(gthread = __xen_vm_load_current_thread(target,0,1))) {
5863 verror(
"could not load global thread!\n");
5869 return gtstate->
context.ttd_perf.tsc;
5873 if (xstate->
vcpuinfo.time.version & 0x1)
5874 vwarn(
"tsc update in progress; tsc may be wrong?!\n");
5876 return xstate->
vcpuinfo.time.tsc_timestamp;
5877 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5887 if (xstate->
vcpuinfo.time.version & 0x1)
5888 vwarn(
"tsc update in progress; time may be wrong?!\n");
5890 return xstate->
vcpuinfo.time.system_time;
5898 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5901 if (xstate->
dominfo.ttd_guest) {
5904 else if (!(gthread = __xen_vm_load_current_thread(target,0,1))) {
5905 verror(
"could not load global thread!\n");
5911 return gtstate->
context.ttd_perf.brctr;
5915 if (xstate->
vcpuinfo.time.version & 0x1)
5916 vwarn(
"time (subbing for counter) update in progress; time/counter"
5917 " may be wrong?!\n");
5919 return xstate->
vcpuinfo.time.system_time;
5920 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5929 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5935 if (!xstate->
dominfo.ttd_replay_flag)
5938 return xc_ttd_set_bts_on(xc_handle,xstate->
id);
5948 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5954 if (!xstate->
dominfo.ttd_replay_flag)
5957 return xc_ttd_set_bts_off(xc_handle,xstate->
id);
#define TARGET_XV_VMP_SOCKET_FILENAME
int target_flush_all_threads(struct target *target)
int xen_vm_virq_or_vmp_read(struct target *target, int *vmid)
REGVAL target_regcache_readreg_tidctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg)
#define vwarnopt(level, area, flags, format,...)
shared_info_t * live_shinfo
int target_arch_x86_v2p_flags_snprintf(struct target *target, arch_x86_v2p_flags_t flags, char *buf, unsigned int bufsiz)
#define SAFE_PERSONALITY_OP_WARN(op, outvar, expoutval, target,...)
int __xen_vm_thread_regcache_to_vcpu_64_raw_h(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg, void *rawval, int rawlen, void *priv)
int xen_vm_virq_attach(int xce_handle, XC_EVTCHN_PORT_T *dbg_port)
target_status_t target_get_status(struct target *target)
unsigned int use_xenaccess
int evloop_unset_fd(struct evloop *evloop, int fd, int fdtype)
int xen_vm_instr_can_switch_context(struct target *target, ADDR addr)
#define SAFE_PERSONALITY_OP_WARN_NORET(op, outvar, expoutval, target,...)
struct debugfile * debugfile_from_file(char *filename, char *root_prefix, struct array_list *debugfile_load_opts_list)
int xen_vm_disable_hw_breakpoint(struct target *target, tid_t tid, REG dreg)
unsigned char *(* read_phys)(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
int xen_vm_virq_or_vmp_attach_or_launch(struct target *target)
result_t probepoint_ss_handler(struct target *target, struct target_thread *tthread, struct probepoint *probepoint)
int xen_vm_virq_or_vmp_get_fd(struct target *target)
struct memregion * region
uint64_t xen_vm_get_time(struct target *target)
int target_regcache_copy_all(struct target_thread *sthread, thread_ctxt_t stidctxt, struct target_thread *dthread, thread_ctxt_t dtidctxt)
GHashTable * soft_probepoints
static uint64_t unsigned int i
error_t xen_vm_argp_parse_opt(int key, char *arg, struct argp_state *state)
struct target_personality_ops * personality_ops
struct target * sstep_thread_overlay
struct target_thread * sstep_thread
GHashTable * target_regcache_copy_registers(struct target *target, tid_t tid)
int xen_vm_notify_sw_breakpoint(struct target *target, ADDR addr, int notification)
int target_os_thread_is_user(struct target *target, tid_t tid)
target_debug_bp_handler_t handle_break
#define SAFE_PERSONALITY_OP(op, outvar, defoutval, target,...)
struct target_thread * base_thread
struct target_thread * global_thread
int xen_vm_disable_feature(struct target *target, int feature)
struct target * target_create(char *type, struct target_spec *spec)
int target_regcache_writereg_tidctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg, REGVAL value)
#define TARGET_XV_VMP_SOCKET_CLIENT_FILE_FORMAT_EXTRA
int target_associate_debugfile(struct target *target, struct memregion *region, struct debugfile *debugfile)
int xen_vm_detach_overlay_thread(struct target *base, struct target *overlay, tid_t tid)
#define verror(format,...)
int(* fini)(struct target *target)
unsigned char * target_read_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
tid_t target_os_thread_get_leader(struct target *target, tid_t tid)
#define XV_ARGP_MEMCACHE_MMAP_SIZE
unsigned char * xen_vm_read_pid(struct target *target, tid_t tid, ADDR vaddr, unsigned long length, unsigned char *buf)
uint64_t xen_vm_get_counter(struct target *target)
int __xen_vm_thread_regcache_to_vcpu_32_reg_h(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg, REGVAL regval, void *priv)
int xen_vm_evloop_handler(int readfd, int fdtype, void *state)
struct memregion * memregion_create(struct addrspace *space, region_type_t type, char *name)
int target_personality_attach(struct target *target, char *personality, char *personality_lib)
#define vwarn(format,...)
unsigned int clear_mem_caches_each_exception
REGVAL target_read_reg(struct target *target, tid_t tid, REG reg)
unsigned int no_hvm_setcontext
result_t probepoint_bp_handler(struct target *target, struct target_thread *tthread, struct probepoint *probepoint, int was_stepping)
struct xen_vm_mem_ops xen_vm_mem_ops_builtin
int target_regcache_foreach_dirty(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, target_regcache_regval_handler_t regh, target_regcache_rawval_handler_t rawh, void *priv)
int xen_vm_detach_evloop(struct target *target)
struct memrange * memrange_create(struct memregion *region, ADDR start, ADDR end, OFFSET offset, unsigned int prot_flags)
struct xen_vm_spec * xen_vm_build_spec(void)
int target_os_thread_get_pgd_phys(struct target *target, tid_t tid, ADDR *pgdp)
unsigned int no_hw_debug_reg_clear
struct target_thread * current_thread
struct target_memmod * target_memmod_lookup(struct target *target, tid_t tid, ADDR addr, int is_phys)
int __xen_vm_thread_regcache_to_vcpu_32_raw_h(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg, void *rawval, int rawlen, void *priv)
int xen_vm_singlestep_end(struct target *target, tid_t tid, struct target *overlay)
unsigned int no_use_multiplexer
struct target_location_ctxt * global_tlctxt
int xen_vm_vmp_attach(char *path, int *cfd, char **cpath)
uint64_t xen_vm_get_tsc(struct target *target)
int target_arch_x86_v2p_get_flags(struct target *target, REGVAL cr0, REGVAL cr4, REGVAL msr_efer, REGVAL cpuid_edx, arch_x86_v2p_flags_t *flags)
unsigned int hvm_monitor_trap_flag_set
int(* handle_exception_ours)(struct target *target)
void value_free(struct value *value)
#define TARGET_XV_VMP_BIN_PATH
struct target_location_ctxt * target_global_tlctxt(struct target *target)
struct target_spec * spec
struct value * target_load_value_member(struct target *target, struct target_location_ctxt *tlctxt, struct value *old_value, const char *member, const char *delim, load_flags_t flags)
#define THREAD_CTXT_KERNEL
struct xen_vm_mem_ops xen_vm_mem_ops_libvmi
struct target_memmod * emulating_debug_mmod
int target_regcache_snprintf(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, char *buf, int bufsiz, int detail, char *sep, char *kvsep, int flags)
target_type_t target_type
#define TARGET_XV_VMP_SOCKET_CLIENT_FILE_FORMAT
int(* addr_v2p)(struct target *target, tid_t tid, ADDR pgd, ADDR vaddr, ADDR *paddr)
#define vdebug(devel, areas, flags, format,...)
int evloop_set_fd(struct evloop *evloop, int fd, int fdtype, evloop_handler_t handler, void *state)
struct thread_probepoint_context * tpc
unsigned char *(* read_tid)(struct target *target, tid_t tid, ADDR pgd, ADDR addr, unsigned long target_length, unsigned char *buf)
struct target * xen_vm_instantiate(struct target_spec *spec, struct evloop *evloop)
#define EVLOOP_HRET_ERROR
int target_regcache_init_reg_tidctxt(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg, REGVAL regval)
struct memregion * region
struct xen_vm_mem_ops * memops
#define ARCH_X86_64_REG_COUNT
void * calloc(size_t nmemb, size_t size)
unsigned int hypervisor_ignores_userspace_exceptions
int unlink(const char *pathname)
struct array_list * debugfile_load_opts_list
int __xen_vm_thread_regcache_to_vcpu(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, struct vcpu_guest_context *context)
#define ARCH_X86_REG_COUNT
unsigned int thread_ctxt_t
void target_thread_set_status(struct target_thread *tthread, thread_status_t status)
vcpu_guest_context_t context
int xen_vm_enable_feature(struct target *target, int feature, void *arg)
int xen_vm_attach_evloop(struct target *target, struct evloop *evloop)
uint32_t needmonitorinterrupt
#define EVLOOP_HRET_SUCCESS
target_status_t target_status(struct target *target)
int target_invalidate_all_threads(struct target *target)
char * xen_vm_vmp_client_path
struct target_spec * target_build_spec(target_type_t type, target_mode_t mode)
struct target_ops xen_vm_ops
int(* attach)(struct target *target)
struct binfile * binfile_pointing
int xen_vm_singlestep(struct target *target, tid_t tid, int isbp, struct target *overlay)
#define XV_ARGP_USE_XENACCESS
int(* handle_pause)(struct target *target)
int xen_vm_virq_detach(int xce_handle, XC_EVTCHN_PORT_T *dbg_port)
struct target_location_ctxt * target_location_ctxt_create(struct target *target, tid_t tid, struct memregion *region)
int target_finalize(struct target *target)
unsigned int breakpoint_instrs_len
GHashTable * hard_probepoints
unsigned long int memcache_mmap_size
int xen_vm_disable_hw_breakpoints(struct target *target, tid_t tid)
struct target * target_lookup_overlay(struct target *target, tid_t tid)
REGVAL target_read_reg_ctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg)
target_status_t target_notify_overlay(struct target *overlay, target_exception_flags_t flags, tid_t tid, ADDR ipval, int *again)
int xen_vm_enable_hw_breakpoint(struct target *target, tid_t tid, REG dreg)
arch_x86_v2p_flags_t v2p_flags
int32_t v_i32(struct value *v)
int xen_vm_enable_hw_breakpoints(struct target *target, tid_t tid)
int __xen_vm_vcpu_to_thread_regcache(struct target *target, struct vcpu_guest_context *context, struct target_thread *tthread, thread_ctxt_t tctxt)
int binfile_get_root_scope_sizes(struct binfile *binfile, int *named, int *duplicated, int *anon, int *numscopes)
REGVAL target_regcache_readreg(struct target *target, tid_t tid, REG reg)
int(* snprintf)(struct target *target, char *buf, int bufsiz)
unsigned long(* write_tid)(struct target *target, tid_t tid, ADDR pgd, ADDR addr, unsigned long length, unsigned char *buf)
struct target_spec * spec
int xen_vm_vmp_detach(int *cfd, char **cpath)
#define EVLOOP_HRET_BADERROR
int xen_vm_xc_detach(int *xc_handle, int *xce_handle)
unsigned long(* write_phys)(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
uint32_t nodisablehwbponss
result_t target_os_emulate_ss_handler(struct target *target, tid_t tid, thread_ctxt_t tidctxt, struct target_memmod *mmod)
int xen_vm_attach_overlay_thread(struct target *base, struct target *overlay, tid_t newtid)
void * malloc(size_t size)
char * debugfile_root_prefix
unsigned int max_thread_ctxt
struct target_thread * target_lookup_thread(struct target *target, tid_t tid)
void target_set_status(struct target *target, target_status_t status)
int __xen_vm_thread_regcache_to_vcpu_64_reg_h(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg, REGVAL regval, void *priv)
target_debug_handler_t handle_step
#define XV_ARGP_USE_LIBVMI
void xen_vm_free_spec(struct xen_vm_spec *xspec)
int vdebug_is_on(int level, log_areas_t areas, log_flags_t flags)
#define XV_ARGP_CLEAR_MEM_CACHES
struct target_thread * target_create_thread(struct target *target, tid_t tid, void *tstate, void *tpstate)
struct array_list * target_list_threads(struct target *target)
int target_regcache_writereg(struct target *target, tid_t tid, REG reg, REGVAL value)
result_t target_os_emulate_bp_handler(struct target *target, tid_t tid, thread_ctxt_t tidctxt, struct target_memmod *mmod)
struct argp_option xen_vm_argp_opts[]
int xen_vm_xc_attach(int *xc_handle, int *xce_handle)
unsigned long xen_vm_write_pid(struct target *target, tid_t tid, ADDR vaddr, unsigned long length, unsigned char *buf)
int xen_vm_spec_to_argv(struct target_spec *spec, int *argc, char ***argv)
#define XV_ARGP_REPLAYDIR
struct probepoint * probepoint
struct addrspace * addrspace_create(struct target *target, char *name, ADDR tag)
char * xen_vm_argp_header
int xen_vm_virq_or_vmp_detach(struct target *target)