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
364 {
"domain",
'm',
"DOMAIN",0,
"The Xen domain ID or name.",-4 },
365 {
"kernel-filename",
'K',
"FILE",0,
366 "Override xenstore kernel filepath for guest.",-4 },
367 {
"no-clear-hw-debug-regs",
'H',NULL,0,
368 "Don't clear hardware debug registers at target attach.",-4 },
370 "Clear mem caches on each debug exception.",-4 },
373 "Clear mem caches on each debug exception.",-4 },
375 #ifdef ENABLE_XENACCESS
377 "Clear mem caches on each debug exception.",-4 },
380 "Max size (bytes) of the mmap cache (default 128MB).",-4 },
381 {
"no-hvm-setcontext",
'V',NULL,0,
382 "Don't use HVM-specific libxc get/set context functions to access"
383 "virtual CPU info.",-4 },
384 {
"configfile",
'c',
"FILE",0,
"The Xen config file.",-4 },
385 {
"replaydir",
'r',
"DIR",0,
"The XenTT replay directory.",-4 },
386 {
"no-use-multiplexer",
'M',NULL,0,
"Do not spawn/attach to the Xen multiplexer server",-4 },
387 {
"dominfo-timeout",
'T',
"MICROSECONDS",0,
"If libxc gets a \"NULL\" dominfo status, the number of microseconds we should keep retrying",-4 },
388 {
"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 },
421 #ifdef ENABLE_XENACCESS
438 av = calloc(ac + 1,
sizeof(
char *));
441 av[j++] = strdup(
"-m");
442 av[j++] = strdup(xspec->
domain);
445 av[j++] = strdup(
"-K");
449 av[j++] = strdup(
"--no-clear-hw-debug-regs");
452 av[j++] = strdup(
"--no-hvm-setcontext");
455 av[j++] = strdup(
"--clear-mem-caches-each-exception");
459 av[j++] = strdup(
"--use-libvmi");
461 #ifdef ENABLE_XENACCESS
463 av[j++] = strdup(
"--use-xenaccess");
466 av[j++] = strdup(
"--memcache-mmap-size");
472 av[j++] = strdup(
"-c");
476 av[j++] = strdup(
"-r");
480 av[j++] = strdup(
"--no-use-multiplexer");
483 av[j++] = strdup(
"-T");
489 av[j++] = strdup(
"--hypervisor-ignores-userspace-exceptions");
505 struct argp_option *opti;
508 if (key == ARGP_KEY_INIT)
510 else if (!state->input)
511 return ARGP_ERR_UNKNOWN;
524 if (key == opti->key) {
537 verror(
"cannot mix arguments for Xen target (%c) with non-Xen"
545 xspec = calloc(1,
sizeof(*xspec));
549 verror(
"cannot mix arguments for Xen target with non-Xen target!\n");
563 return ARGP_ERR_UNKNOWN;
566 case ARGP_KEY_NO_ARGS:
569 case ARGP_KEY_SUCCESS:
576 xspec->domain = strdup(arg);
579 xspec->kernel_filename = strdup(arg);
582 xspec->no_hw_debug_reg_clear = 1;
585 xspec->no_hvm_setcontext = 1;
588 xspec->config_file = strdup(arg);
591 xspec->clear_mem_caches_each_exception = 1;
595 xspec->use_libvmi = 1;
598 #ifdef ENABLE_XENACCESSS
600 xspec->use_xenaccess = 1;
604 xspec->memcache_mmap_size = atoi(arg);
607 xspec->replay_dir = strdup(arg);
610 xspec->no_use_multiplexer = 1;
613 xspec->dominfo_timeout = atoi(arg);
616 xspec->hypervisor_ignores_userspace_exceptions = 1;
619 return ARGP_ERR_UNKNOWN;
636 return xen_vm_attach(spec,evloop);
642 xspec = calloc(1,
sizeof(*xspec));
671 struct xs_handle *xsh = NULL;
672 xs_transaction_t xth = XBT_NULL;
675 char **domains = NULL;
683 if (geteuid() != 0) {
684 verror(
"must be root!\n");
694 if (!(xstate = (
struct xen_vm_state *)malloc(
sizeof(*xstate)))) {
698 memset(xstate,0,
sizeof(*xstate));
702 if (!(buf = malloc(PATH_MAX))) {
703 verror(
"could not allocate tmp path buffer: %s\n",strerror(errno));
707 if (!(xsh = xs_domain_open())) {
708 verror(
"could not open xenstore!\n");
712 xstate->evloop_fd = -1;
716 xstate->id = (domid_t)strtol(
domain,&tmp,10);
717 if (errno == ERANGE) {
718 verror(
"bad domain id: %s\n",strerror(errno));
721 else if (errno == EINVAL || tmp ==
domain)
731 domains = xs_directory(xsh,xth,
"/local/domain",&size);
732 for (i = 0; i < size; ++i) {
734 snprintf(buf,PATH_MAX,
"/local/domain/%s/name",domains[i]);
735 tmp = xs_read(xsh,xth,buf,NULL);
737 if (tmp && strcmp(
domain,tmp) == 0) {
740 xstate->id = (domid_t)strtol(domains[i],NULL,10);
748 verror(
"matching domain name for %s; but bad"
749 " domain id %s: %s\n",
750 tmp,domains[i],strerror(errno));
759 xstate->name = strdup(tmp);
783 snprintf(buf,PATH_MAX,
"/local/domain/%d/name",xstate->id);
784 xstate->name = xs_read(xsh,xth,buf,NULL);
786 vwarn(
"could not read name for dom %d; may cause problems!\n",
791 snprintf(buf,PATH_MAX,
"/local/domain/%d/vm",xstate->id);
792 xstate->vmpath = xs_read(xsh,xth,buf,NULL);
794 vwarn(
"could not read vmpath for dom %d; may cause problems!\n",
797 snprintf(buf,PATH_MAX,
"%s/image/ostype",xstate->vmpath);
798 xstate->ostype = xs_read(xsh,xth,buf,NULL);
799 if (!xstate->ostype) {
800 vwarn(
"could not read ostype for dom %d; may cause problems!\n",
805 else if (strcmp(xstate->ostype,
"hvm") == 0) {
812 strdup(xstate->ostype));
817 snprintf(buf,PATH_MAX,
"%s/image/kernel",xstate->vmpath);
818 xstate->kernel_filename = xs_read(xsh,xth,buf,NULL);
819 if (!xstate->kernel_filename)
820 vwarn(
"could not read kernel for dom %d; may cause problems!\n",
823 g_hash_table_insert(
target->
config,strdup(
"OS_KERNEL_FILENAME"),
824 strdup(xstate->kernel_filename));
830 "using kernel filename %s (overrides %s from xenstore)\n",
831 xspec->
kernel_filename,xstate->kernel_filename ? xstate->kernel_filename :
"''");
833 if (xstate->kernel_filename)
834 free(xstate->kernel_filename);
838 g_hash_table_remove(
target->
config,
"OS_KERNEL_FILENAME");
839 g_hash_table_insert(
target->
config,strdup(
"OS_KERNEL_FILENAME"),
840 strdup(xstate->kernel_filename));
844 xs_daemon_close(xsh);
855 && xstate->kernel_filename
856 && (strstr(xstate->kernel_filename,
"inux")
857 || strstr(xstate->kernel_filename,
"inuz"))) {
860 "autoinitialized the os_linux_generic personality!\n");
863 verror(
"failed to autoinitialize the os_linux_generic personality!\n");
868 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 #ifdef XC_HAVE_CONTEXT_ANY
1544 memcpy(&context_any.c,context,
sizeof(*context));
1546 xstate->
dominfo.max_vcpu_id,&context_any);
1549 xstate->
dominfo.max_vcpu_id,context);
1552 verror(
"could not set vcpu context for dom %d\n",xstate->
id);
1559 if (__xen_vm_vcpu_to_hvm_cpu_context(context,xstate->hvm_cpu)) {
1560 verror(
"Could not translate software vcpu info to HVM vcpu info!\n");
1564 if (xc_domain_hvm_setcontext(
xc_handle,xstate->
id,
1565 xstate->hvm_context_buf,
1566 xstate->hvm_context_bufsiz)) {
1567 verror(
"Could not store HVM context buf!\n");
1572 verror(
"HVM unsupported on 32-bit platform!\n");
1581 static struct target_thread *__xen_vm_load_current_thread(
struct target *target,
1596 if (globalonly && !force
1603 else if (!globalonly && !force
1608 verror(
"target not paused; cannot load current task!\n");
1619 if (xen_vm_load_dominfo(target)) {
1620 verror(
"could not load dominfo!\n");
1631 if (__xen_vm_cpu_getcontext(target,>state->context) < 0) {
1632 verror(
"could not get vcpu context for %d\n",xstate->
id);
1649 ipval = gtstate->context.user_regs.rip;
1651 ipval = gtstate->context.user_regs.eip;
1654 cpl = 0x3 & gtstate->context.user_regs.cs;
1658 if (__xen_vm_in_userspace(target,cpl,ipval))
1680 gtstate->context.kernel_sp);
1701 "cpl = %d,tidctxt = %d)\n",ipval,pgd,cpl,
1729 vwarn(
"personality set current thread context to %d; global thread"
1730 " context is %d; forcing current to global!\n",
1741 tthread->
state = tstate = \
1744 memcpy(&tstate->context,>state->context,
sizeof(gtstate->context));
1759 gtstate->context.debugreg[0],gtstate->context.debugreg[1],
1760 gtstate->context.debugreg[2],gtstate->context.debugreg[3],
1761 gtstate->context.debugreg[6],gtstate->context.debugreg[7]);
1772 vwarn(
"error loading current thread; trying to use default thread\n");
1778 static struct target_thread *xen_vm_load_current_thread(
struct target *target,
1780 return __xen_vm_load_current_thread(target,force,0);
1794 tid_t xen_vm_gettid(
struct target *target) {
1800 tthread = xen_vm_load_current_thread(target,0);
1802 verror(
"could not load current thread to get TID!\n");
1806 return tthread->
tid;
1809 void xen_vm_free_thread_state(
struct target *target,
void *
state) {
1813 static int xen_vm_snprintf(
struct target *target,
char *buf,
int bufsiz) {
1817 return snprintf(buf,bufsiz,
"domain(%s)",xspec->
domain);
1820 static int xen_vm_init(
struct target *target) {
1828 vwarn(
"auto-enabling SEMI_STRICT bpmode on Xen target.\n");
1833 g_hash_table_insert(target->
config,
1834 strdup(
"OS_EMULATE_USERSPACE_EXCEPTIONS"),
1856 xstate->
dominfo.shutdown_reason = 0;
1857 xstate->
dominfo.max_vcpu_id = 0;
1858 xstate->
dominfo.shared_info_frame = 0;
1877 #ifdef XENCTRL_HAS_XC_INTERFACE
1884 #ifdef XENCTRL_HAS_XC_INTERFACE
1885 *xc_handle = xc_interface_open(NULL,NULL,0);
1887 *xc_handle = xc_interface_open();
1890 verror(
"failed to open xc interface: %s\n",strerror(errno));
1896 #ifdef XENCTRL_HAS_XC_INTERFACE
1897 *xce_handle = xc_evtchn_open(NULL,0);
1899 *xce_handle = xc_evtchn_open();
1902 verror(
"failed to open event channel: %s\n",strerror(errno));
1910 #ifdef XENCTRL_HAS_XC_INTERFACE
1917 xc_interface_close(*xc_handle);
1922 xc_evtchn_close(*xce_handle);
1929 #ifdef XENCTRL_HAS_XC_INTERFACE
1935 if (dbg_port && *dbg_port == -1) {
1936 *dbg_port = xc_evtchn_bind_virq(xce_handle,VIRQ_DEBUGGER);
1942 if ((int32_t)*dbg_port < 0) {
1943 verror(
"failed to bind debug virq port: %s",strerror(errno));
1951 #ifdef XENCTRL_HAS_XC_INTERFACE
1957 if (dbg_port && *dbg_port != -1) {
1958 if (xc_evtchn_unbind(xce_handle,(evtchn_port_t)*dbg_port)) {
1959 verror(
"failed to unbind debug virq port\n");
1971 struct sockaddr_un sun,sun_client;
1974 int spath_len,cpath_len;
1980 if (cfd && *cfd != -1)
1987 if (stat(
"/var/run",&sbuf) == 0
1988 && S_ISDIR(sbuf.st_mode) && access(
"/var/run",W_OK) == 0) {
1990 spath = malloc(spath_len);
1993 else if ((tmpdir = getenv(
"TMPDIR"))
1994 && stat(tmpdir,&sbuf) == 0 && access(tmpdir,W_OK) == 0) {
1996 spath = malloc(spath_len);
1999 else if (stat(
"/tmp",&sbuf) == 0
2000 && S_ISDIR(sbuf.st_mode) && access(
"/tmp",W_OK) == 0) {
2002 spath = malloc(spath_len);
2007 spath = malloc(spath_len);
2012 spath = strdup(path);
2014 memset(&sun,0,
sizeof(sun));
2015 sun.sun_family = AF_UNIX;
2026 cpath_len = strlen(spath) + 1
2029 *cpath = malloc(cpath_len);
2033 if (open(*cpath,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR) < 0) {
2035 "could not open client VMP socket file %s: %s\n",
2036 *cpath,strerror(errno));
2043 if (cpath[0] ==
'\0' && (tmpdir = getenv(
"TMPDIR"))) {
2044 cpath_len = strlen(tmpdir) + 1
2047 *cpath = malloc(cpath_len);
2051 if (open(*cpath,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR) < 0) {
2053 "could not open client VMP socket file %s: %s\n",
2054 *cpath,strerror(errno));
2061 if (cpath[0] ==
'\0') {
2062 cpath_len = strlen(
"/tmp") + 1
2065 *cpath = malloc(cpath_len);
2069 if (open(*cpath,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR) < 0) {
2071 "could not open client VMP socket file %s: %s\n",
2072 *cpath,strerror(errno));
2079 if (cpath[0] ==
'\0') {
2080 cpath_len = strlen(
".") + 1
2083 *cpath = malloc(cpath_len);
2087 if (open(*cpath,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR) < 0) {
2089 "could not open client VMP socket file %s: %s\n",
2090 *cpath,strerror(errno));
2098 verror(
"could not open a client VMP socket file; aborting!\n");
2102 memset(&sun_client,0,
sizeof(sun_client));
2103 sun_client.sun_family = AF_UNIX;
2106 *cfd = socket(AF_UNIX,SOCK_STREAM,0);
2108 verror(
"socket(): %s\n",strerror(errno));
2111 len = offsetof(
struct sockaddr_un,sun_path) + strlen(sun_client.sun_path);
2112 if (bind(*cfd,&sun_client,len) < 0) {
2113 verror(
"bind(%s): %s\n",sun_client.sun_path,strerror(errno));
2116 if (fchmod(*cfd,S_IRUSR | S_IWUSR) < 0) {
2117 verror(
"chmod(%s): %s\n",sun_client.sun_path,strerror(errno));
2121 len = offsetof(
struct sockaddr_un,sun_path) + strlen(sun.sun_path);
2122 if (connect(*cfd,&sun,len) < 0) {
2123 verror(
"connect(%s): %s\n",sun.sun_path,strerror(errno));
2142 if (cfd && *cfd != -1) {
2145 if (cpath && *cpath) {
2174 if (dbg_port > -1) {
2175 verror(
"cannot connect for multiple domains without multiplexer!\n");
2186 verror(
"could not launch Xen VIRQ_DEBUGGER multiplexer!\n");
2193 for (i = 0; i < 5; ++i) {
2203 verror(
"could not connect to launched Xen VIRQ_DEBUGGER multiplexer!\n");
2216 if (dbg_port != -1) {
2228 if (dbg_port != -1) {
2239 XC_EVTCHN_PORT_T port = -1;
2244 if (dbg_port != -1) {
2246 port = xc_evtchn_pending(xce_handle);
2251 retval = xc_evtchn_unmask(xce_handle, port);
2253 verror(
"failed to unmask event channel\n");
2257 if (port != dbg_port) {
2272 if (errno == EINTR) {
2281 else if (rc !=
sizeof(resp)) {
2294 static int xen_vm_attach_internal(
struct target *target) {
2296 struct xen_domctl domctl;
2303 domctl.cmd = XEN_DOMCTL_setdebugging;
2304 domctl.domain = xstate->
id;
2305 domctl.u.setdebugging.enable =
true;
2325 if (xc_domctl(xc_handle,&domctl)) {
2326 verror(
"could not enable debugging of dom %d!\n",xstate->
id);
2332 if (xen_vm_load_dominfo(target)) {
2333 verror(
"could not load dominfo for dom %d\n",xstate->
id);
2337 if (xen_vm_pause(target,0)) {
2338 verror(
"could not pause target before attaching; letting user handle!\n");
2346 verror(
"could not attach memops!\n");
2364 if (!(tthread = __xen_vm_load_cached_thread(target,
TID_GLOBAL))) {
2382 xtstate->context.debugreg[0] = 0;
2383 xtstate->context.debugreg[1] = 0;
2384 xtstate->context.debugreg[2] = 0;
2385 xtstate->context.debugreg[3] = 0;
2386 xtstate->context.debugreg[6] = 0;
2387 xtstate->context.debugreg[7] = 0;
2405 xtstate->context.debugreg[0] = 0;
2406 xtstate->context.debugreg[1] = 0;
2407 xtstate->context.debugreg[2] = 0;
2408 xtstate->context.debugreg[3] = 0;
2409 xtstate->context.debugreg[6] = 0;
2410 xtstate->context.debugreg[7] = 0;
2419 static int xen_vm_detach(
struct target *target,
int stay_paused) {
2421 struct xen_domctl domctl;
2423 domctl.cmd = XEN_DOMCTL_setdebugging;
2424 domctl.domain = xstate->
id;
2425 domctl.u.setdebugging.enable =
false;
2446 verror(
"failed to fini memops; continuing anyway!\n");
2454 if (xc_domctl(xc_handle,&domctl)) {
2455 verror(
"could not disable debugging of dom %d!\n",xstate->
id);
2460 __xen_vm_resume(target,1);
2470 verror(
"failed to unbind debug virq port\n");
2473 verror(
"failed to close xc interfaces\n");
2481 static int xen_vm_fini(
struct target *target) {
2498 static int xen_vm_kill(
struct target *target,
int sig) {
2510 static int xen_vm_loadspaces(
struct target *target) {
2532 static int xen_vm_loadregions(
struct target *target,
struct addrspace *space) {
2535 char *kernel_filename;
2538 (
char *)g_hash_table_lookup(target->
config,
"OS_KERNEL_FILENAME");
2568 static int xen_vm_loaddebugfiles(
struct target *target,
2589 if (!region->
name || strlen(region->
name) == 0)
2627 if (!target->
arch) {
2643 static int xen_vm_postloadinit(
struct target *target) {
2665 char *start = (
char *)g_hash_table_lookup(target->
config,
2666 "OS_KERNEL_START_ADDR");
2670 char *hpage = (
char *)g_hash_table_lookup(target->
config,
2671 "OS_KERNEL_HYPERCALL_PAGE");
2678 static int xen_vm_postopened(
struct target *target) {
2684 static int xen_vm_set_active_probing(
struct target *target,
2692 xen_vm_build_default_overlay_spec(
struct target *target,
tid_t tid) {
2696 static struct target *
2697 xen_vm_instantiate_overlay(
struct target *target,
2701 struct target *overlay;
2734 verror(
"could not load group_leader for thread %d; BUG?!\n",tthread->
tid);
2737 else if (leader != tthread) {
2739 "using group_leader %d instead of user-supplied overlay thread %d\n",
2740 leader->
tid,tthread->
tid);
2753 xen_vm_lookup_overlay_thread_by_id(
struct target *target,
int id) {
2756 retval = xen_vm_load_thread(target,
id,0);
2765 "found overlay thread %d\n",
id);
2769 verror(
"tid %d matched %d, but is a kernel thread!\n",retval->
tid,
id);
2776 xen_vm_lookup_overlay_thread_by_name(
struct target *target,
char *
name) {
2781 GHashTableIter iter;
2783 if ((rc = xen_vm_load_available_threads(target,0)))
2784 vwarn(
"could not load %d threads; continuing anyway!\n",-rc);
2786 g_hash_table_iter_init(&iter,target->
threads);
2787 while (g_hash_table_iter_next(&iter,NULL,(gpointer)&tthread)) {
2791 if (!tthread->name) {
2792 vwarn(
"tid %d does not have a name; continuing!\n",
2797 slen = strlen(tthread->name);
2799 "checking task with name '%*s' against '%s'\n",
2800 slen,tthread->name,name);
2801 if (strncmp(name,tthread->name,slen) == 0) {
2809 verror(
"tid %d matched '%s', but is a kernel thread!\n",
2816 "found overlay thread %"PRIiTID"\n",retval->
tid);
2833 if (nltid == -1 || cltid == -1)
2852 if (xen_vm_load_dominfo(target)) {
2853 verror(
"could not load dominfo for dom %d\n",xstate->
id);
2865 else if (xstate->
dominfo.shutdown)
2875 static int xen_vm_pause(
struct target *target,
int nowait) {
2877 struct timeval check_tv = { 0,0};
2883 if (xen_vm_load_dominfo(target))
2884 vwarn(
"could not load dominfo for dom %d, trying to pause anyway!\n",xstate->
id);
2892 else if (xc_domain_pause(xc_handle,xstate->
id)) {
2893 verror(
"could not pause dom %d!\n",xstate->
id);
2907 if (xen_vm_load_dominfo(target))
2908 vwarn(
"could not reload dominfo for dom %d after pause!\n",xstate->
id);
2925 xen_vm_poll(target,&check_tv,&outcome,&pstatus);
2930 static int xen_vm_flush_current_thread(
struct target *target) {
2938 verror(
"current thread not loaded!\n");
2951 "dom %d tid %"PRIiTID" not valid (%d) or not dirty (%d)\n",
2963 verror(
"could not convert regcache to vcpu context(dom %d tid %"PRIiTID
")\n",
2972 if (__xen_vm_cpu_setcontext(target,&tstate->
context) < 0) {
2973 verror(
"could not set vcpu context (dom %d tid %"PRIiTID
")\n",
2979 #if __WORDSIZE == 32
2981 "eflags (vcpu context): 0x%"PRIxADDR"\n",
2982 tstate->
context.user_regs.eflags);
2985 "rflags (vcpu context): 0x%"PRIxADDR"\n",
2986 tstate->
context.user_regs.rflags);
2998 tstate->
dr[0],tstate->
dr[1],tstate->
dr[2],tstate->
dr[3],
2999 tstate->
dr[6],tstate->
dr[7]);
3028 static int xen_vm_flush_global_thread(
struct target *target,
3034 vcpu_guest_context_t *ctxp;
3039 verror(
"BUG: no global thread loaded!!!\n");
3044 current_thread = NULL;
3055 "dom %d tid %"PRIiTID
" not valid (%d) or not dirty (%d)\n",
3066 verror(
"could not convert regcache to vcpu context"
3067 " (dom %d tid %"PRIiTID
") ctxt %d\n",
3075 if (!current_thread) {
3079 xstate->
id,gthread->
tid);
3088 verror(
"could not convert regcache to vcpu context"
3089 " (dom %d tid %"PRIiTID
") ctxt %d\n",
3107 ctxp->debugreg[6] = 0;
3112 for (i = 0; i < 4; ++i) {
3113 if (gtstate->
context.debugreg[i] == 0)
3118 ctxp->debugreg[i] = gtstate->
context.debugreg[i];
3120 ctxp->debugreg[7] &= ~(0x3 << (i * 2));
3121 ctxp->debugreg[7] |= ((0x3 << (i * 2)) & gtstate->
context.debugreg[7]);
3123 ctxp->debugreg[7] &= ~(0x3 << (16 + (i * 4)));
3124 ctxp->debugreg[7] |= ((0x3 << (16 + (i * 4))) & gtstate->
context.debugreg[7]);
3126 ctxp->debugreg[7] &= ~(0x3 << (18 + (i * 4)));
3127 ctxp->debugreg[7] |= ((0x3 << (18 + (i * 4))) & gtstate->
context.debugreg[7]);
3135 if (!current_thread) {
3137 "EIP is 0x%"PRIxREGVAL" before flush (dom %d tid %"PRIiTID
")\n",
3139 xstate->
id,gthread->
tid);
3143 "EIP is 0x%"PRIxREGVAL" (in thread %"PRIiTID
") before flush (dom %d tid %"PRIiTID
")\n",
3145 gtstate->
context.user_regs.rip,
3147 gtstate->
context.user_regs.eip,
3149 current_thread->
tid,
3150 xstate->
id,gthread->
tid);
3156 if (__xen_vm_cpu_setcontext(target,ctxp) < 0) {
3157 verror(
"could not set vcpu context (dom %d tid %"PRIiTID
")\n",
3158 xstate->
id,gthread->
tid);
3166 if (!current_thread)
3175 "debug registers (setting MERGED!!! vcpu context): 0x%"PRIxADDR",0x%"PRIxADDR
3177 ctxp->debugreg[0],ctxp->debugreg[1],
3178 ctxp->debugreg[2],ctxp->debugreg[3],
3179 ctxp->debugreg[6],ctxp->debugreg[7]);
3181 if (!current_thread)
3185 gtstate->
dr[0],gtstate->
dr[1],gtstate->
dr[2],gtstate->
dr[3],
3186 gtstate->
dr[6],gtstate->
dr[7]);
3191 static int xen_vm_pause_thread(
struct target *target,
tid_t tid,
int nowait) {
3192 verror(
"cannot pause individual threads in guests!\n");
3197 static int xen_vm_flush_thread(
struct target *target,
tid_t tid) {
3209 return xen_vm_flush_current_thread(target);
3225 "current thread not loaded to compare with"
3226 " tid %"PRIiTID
"; exiting, user-mode EIP, or BUG?\n",
3231 "current thread not valid to compare with"
3232 " tid %"PRIiTID
"; exiting, user-mode EIP, or BUG?\n",
3241 return xen_vm_flush_current_thread(target);
3249 verror(
"cannot flush unknown thread %"PRIiTID
"; you forgot to load?\n",
3256 return xen_vm_flush_current_thread(target);
3260 "dom %d tid %"PRIiTID
" not valid (%d) or not dirty (%d)\n",
3277 static int xen_vm_flush_all_threads(
struct target *target) {
3279 GHashTableIter iter;
3283 g_hash_table_iter_init(&iter,target->
threads);
3284 while (g_hash_table_iter_next(&iter,NULL,(gpointer)&tthread)) {
3289 rc = xen_vm_flush_thread(target,tthread->tid);
3291 verror(
"could not flush thread %"PRIiTID
"\n",tthread->tid);
3312 rc = xen_vm_flush_current_thread(target);
3314 verror(
"could not flush current thread %"PRIiTID
"\n",
3342 rc = xen_vm_flush_global_thread(target,current_thread);
3351 static int __value_get_append_tid(
struct target *target,
struct value *
value,
3359 verror(
"could not load pid in task; BUG?\n");
3363 array_list_append(list,(
void *)(uintptr_t)
v_i32(v));
3369 static struct array_list *xen_vm_list_available_tids(
struct target *target) {
3375 static int xen_vm_load_all_threads(
struct target *target,
int force) {
3383 for (i = 0; i < array_list_len(cthreads); ++i) {
3384 tthread = (
struct target_thread *)array_list_item(cthreads,i);
3387 "tid %"PRIiTID
" (%p)\n",tthread->
tid,tthread);
3389 if (!xen_vm_load_thread(target,tthread->
tid,force)) {
3391 verror(
"could not load thread %"PRIiTID
"\n",tthread->
tid);
3405 static int xen_vm_load_available_threads(
struct target *target,
int force) {
3413 if (!__xen_vm_load_current_thread(target,force,1)) {
3414 verror(
"could not load current thread!\n");
3422 static int xen_vm_thread_snprintf(
struct target *target,
3424 char *buf,
int bufsiz,
3425 int detail,
char *sep,
char *kvsep) {
3431 buf,bufsiz,detail,sep,kvsep,0);
3437 (rc >= bufsiz) ? NULL : buf + rc,
3438 (rc >= bufsiz) ? 0 : bufsiz - rc,
3441 verror(
"could not snprintf personality info for thread %d!\n",
3454 static int xen_vm_thread_snprintf(
struct target_thread *tthread,
3455 char *buf,
int bufsiz,
3456 int detail,
char *sep,
char *kvsep) {
3458 struct cpu_user_regs *r;
3463 goto personality_out;
3467 goto personality_out;
3469 r = &tstate->
context.user_regs;
3476 rc += snprintf((rc >= bufsiz) ? NULL : buf + rc,
3477 (rc >= bufsiz) ? 0 :bufsiz - rc,
3478 "%s" "ip%s%"RF "%s" "bp%s%"RF "%s" "sp%s%"RF "%s"
3479 "flags%s%"RF "%s" "ax%s%"RF "%s" "bx%s%"RF "%s"
3480 "cx%s%"RF "%s" "dx%s%"RF "%s" "di%s%"RF "%s"
3481 "si%s%"RF "%s" "cs%s%d" "%s" "ss%s%d" "%s"
3482 "ds%s%d" "%s" "es%s%d" "%s"
3483 "fs%s%d" "%s" "gs%s%d",
3484 #
if __WORDSIZE == 64
3485 sep,kvsep,r->rip,sep,kvsep,r->rbp,sep,kvsep,r->rsp,sep,
3486 kvsep,r->eflags,sep,kvsep,r->rax,sep,kvsep,r->rbx,sep,
3487 kvsep,r->rcx,sep,kvsep,r->rdx,sep,kvsep,r->rdi,sep,
3488 kvsep,r->rsi,sep,kvsep,r->cs,sep,kvsep,r->ss,sep,
3489 kvsep,r->ds,sep,kvsep,r->es,sep,
3490 kvsep,r->fs,sep,kvsep,r->gs
3492 sep,kvsep,r->eip,sep,kvsep,r->ebp,sep,kvsep,r->esp,sep,
3493 kvsep,r->eflags,sep,kvsep,r->eax,sep,kvsep,r->ebx,sep,
3494 kvsep,r->ecx,sep,kvsep,r->edx,sep,kvsep,r->edi,sep,
3495 kvsep,r->esi,sep,kvsep,r->cs,sep,kvsep,r->ss,sep,
3496 kvsep,r->ds,sep,kvsep,r->es,sep,
3497 kvsep,r->fs,sep,kvsep,r->gs
3501 rc += snprintf((rc >= bufsiz) ? NULL : buf + rc,
3502 (rc >= bufsiz) ? 0 :bufsiz - rc,
3503 "%s" "dr0%s%"DRF "%s" "dr1%s%"DRF
3504 "%s" "dr2%s%"DRF "%s" "dr3%s%"DRF
3505 "%s" "dr6%s%"DRF "%s" "dr7%s%"DRF,
3506 sep,kvsep,tstate->
dr[0],sep,kvsep,tstate->
dr[1],
3507 sep,kvsep,tstate->
dr[1],sep,kvsep,tstate->
dr[2],
3508 sep,kvsep,tstate->
dr[6],sep,kvsep,tstate->
dr[7]);
3511 nrc = target_personality_thread_snprintf(tthread,
3512 (rc >= bufsiz) ? NULL : buf + rc,
3513 (rc >= bufsiz) ? 0 : bufsiz - rc,
3516 verror(
"could not snprintf personality info for thread %d!\n",
3525 static int xen_vm_invalidate_thread(
struct target *target,
3539 static int __xen_vm_resume(
struct target *target,
int detaching) {
3545 if (xen_vm_load_dominfo(target))
3546 vwarn(
"could not load dominfo for dom %d, trying to pause anyway!\n",xstate->
id);
3548 if (!xstate->
dominfo.paused) {
3549 vwarn(
"dom %d not paused; not invalidating and resuming; bug?\n",
3572 rc = xc_domain_unpause(xc_handle,xstate->
id);
3579 static int xen_vm_resume(
struct target *target) {
3580 return __xen_vm_resume(target,0);
3592 int *again,
void *priv) {
3599 tid_t overlay_leader_tid;
3606 ADDR bogus_sstep_probepoint_addr;
3607 struct target *overlay;
3616 if (xen_vm_load_dominfo(target)) {
3617 verror(
"could not load dominfo; returning to user!\n");
3625 "ignoring \"exception\" in our running VM %d; not for us\n",
3633 "new debug event (brctr = %"PRIu64
", tsc = %"PRIx64
")\n",
3645 if (!__xen_vm_load_current_thread(target,0,1)) {
3646 verror(
"could not load global thread!\n");
3657 verror(
"could not read CPL while checking debug event: %s\n",
3663 verror(
"could not read EIP while checking debug event: %s\n",
3685 xen_vm_load_current_thread(target,0);
3687 if (__xen_vm_in_userspace(target,cpl,ipval)) {
3691 verror(
"could not load current userspace thread at 0x%"PRIxADDR"!\n",
3699 target->current_thread->state;
3703 "user-mode debug event at EIP 0x%"PRIxADDR" in tid %"PRIiTID
";"
3704 " will try to handle it if it is single step!\n",
3715 verror(
"could not read current thread!\n");
3745 "dbgreg[6]=0x%"DRF", eflags=0x%"RF"\n",
3746 tid, ipval, xtstate->
context.debugreg[6],
3747 xtstate->
context.user_regs.eflags);
3750 if (xtstate->
context.debugreg[6] & 0x4000
3770 "emulating debug memmod at ss for tid %"PRIiTID
3792 || (__xen_vm_in_userspace(target,cpl,ipval)
3798 if (__xen_vm_in_userspace(target,cpl,ipval)) {
3800 "single step event in overlay tid %"PRIiTID
3801 " (tgid %"PRIiTID
"); notifying overlay\n",
3805 xtstate->
context.debugreg[6] = 0;
3844 "single step event in overlay tid %"PRIiTID
3845 " (tgid %"PRIiTID
") INTO KERNEL (at 0x%"PRIxADDR")"
3846 " notifying overlay\n",
3850 xtstate->
context.debugreg[6] = 0;
3864 sstep_thread = NULL;
3870 handle_inferred_sstep:
3871 if (!tthread->
tpc) {
3872 if (sstep_thread && __xen_vm_in_userspace(target,cpl,ipval)) {
3873 vwarn(
"single step event (status reg and eflags) into"
3874 " userspace; trying to handle in sstep thread"
3875 " %"PRIiTID
"!\n",sstep_thread->tid);
3876 goto handle_sstep_thread;
3882 xtstate->
context.debugreg[6] = 0;
3893 gtstate->
context.debugreg[6] = 0;
3915 xtstate->
context.debugreg[6] = 0;
3927 gtstate->
context.debugreg[6] = 0;
3934 else if (sstep_thread) {
3936 "thread %"PRIiTID
" single stepped can_context_switch"
3937 " instr; trying to handle exception in old thread!\n",
3940 handle_sstep_thread:
3942 sstep_thread->tpc->probepoint);
3945 xtstate->
context.debugreg[6] = 0;
3951 else if (__xen_vm_in_userspace(target,cpl,ipval)) {
3953 "; debug status reg 0x%"DRF"; eflags 0x%"RF
3954 "; skipping handling!\n",
3955 ipval,xtstate->
context.debugreg[6],
3956 xtstate->
context.user_regs.eflags);
3963 xtstate->
context.debugreg[6] = 0;
3990 if (xtstate->
context.debugreg[6] & 15) {
3991 if (xtstate->
context.debugreg[6] & 0x1)
3993 else if (xtstate->
context.debugreg[6] & 0x2)
3995 else if (xtstate->
context.debugreg[6] & 0x4)
3997 else if (xtstate->
context.debugreg[6] & 0x8)
4019 verror(
"DR6 said hw dbg reg %d at 0x%"DRF" was hit;"
4020 " but EIP 0x%"PRIxADDR" in tid %"PRIiTID
" does not"
4021 " match! ignoring hw dbg status; continuing"
4023 dreg,xtstate->
context.debugreg[dreg],ipval,
4038 gtstate->
context.debugreg[6] = 0;
4045 if (__xen_vm_in_userspace(target,cpl,ipval)) {
4046 vwarn(
"user-mode debug event (hw dbg reg)"
4047 " at 0x%"PRIxADDR"; debug status reg 0x%"DRF"; eflags"
4048 " 0x%"RF"; trying to handle in global thread!\n",
4049 ipval,xtstate->
context.debugreg[6],
4050 xtstate->
context.user_regs.eflags);
4058 ipval = xtstate->
context.debugreg[dreg];
4061 "found hw break (status) in dreg %d on 0x%"PRIxADDR"\n",
4064 else if (__xen_vm_in_userspace(target,cpl,ipval)) {
4069 overlay_leader_tid =
4074 "found yet-unknown thread %d with"
4075 " overlay leader %d; will notify!\n",
4076 tthread->
tid,overlay_leader_tid);
4085 "user-mode debug event in overlay tid %"PRIiTID
4086 " (tgid %"PRIiTID
") (not single step, not hw dbg reg)"
4087 " at 0x%"PRIxADDR"; debug status reg 0x%"DRF"; eflags"
4088 " 0x%"RF"; passing to overlay!\n",
4091 xtstate->
context.user_regs.eflags);
4105 if (xtstate->
context.debugreg[6] & 0x4000) {
4108 "single step debug event in overlay\n");
4110 else if (bogus_sstep_thread
4114 "inferred single step debug event in overlay\n");
4119 xtstate->
context.debugreg[6] = 0;
4142 rc = xen_vm_addr_v2p(target,
TID_GLOBAL,tmp_ipval,&paddr);
4150 "emulating debug memmod at bp for tid %"PRIiTID
4152 tid,pmmod->addr,tmp_ipval);
4157 verror(
"could not emulate debug memmod for"
4158 " tid %"PRIiTID
" at paddr 0x%"PRIxADDR"\n",
4164 xtstate->
context.debugreg[6] = 0;
4167 gtstate->
context.debugreg[6] = 0;
4170 "cleared status debug reg 6\n");
4176 verror(
"user-mode debug event (not single step, not"
4177 " hw dbg reg) at 0x%"PRIxADDR"; debug status reg"
4178 " 0x%"DRF"; eflags 0x%"RF"; skipping handling!\n",
4179 tmp_ipval,xtstate->
context.debugreg[6],
4180 xtstate->
context.user_regs.eflags);
4187 "dreg status was 0x%"PRIxREGVAL"; trying eip method\n",
4190 if (xtstate->
dr[0] == ipval)
4192 else if (xtstate->
dr[1] == ipval)
4194 else if (xtstate->
dr[2] == ipval)
4196 else if (xtstate->
dr[3] == ipval)
4201 "found hw break (eip) in dreg %d on 0x%"PRIxADDR"\n",
4204 if (xtstate != gtstate) {
4209 if (gtstate->
dr[0] == ipval)
4211 else if (gtstate->
dr[1] == ipval)
4213 else if (gtstate->
dr[2] == ipval)
4215 else if (gtstate->
dr[3] == ipval)
4220 "found hw break (eip) in GLOBAL dreg %d on 0x%"PRIxADDR"\n",
4224 "did NOT find hw break (eip) on 0x%"PRIxADDR
4225 " (neither global nor per-thread!)\n",
4230 "did NOT find hw break (eip) on 0x%"PRIxADDR"\n",
4244 "found hw break in thread %"PRIiTID
"\n",
4253 verror(
"could not find probepoint for hw dbg reg %d"
4254 " in current or global threads!\n",dreg);
4259 "found hw break in global thread!\n");
4271 gtstate->
context.debugreg[6] = 0;
4289 xtstate->
context.debugreg[6] & 0x4000);
4292 xtstate->
context.debugreg[6] = 0;
4303 xtstate->
context.debugreg[6] & 0x4000);
4306 xtstate->
context.debugreg[6] = 0;
4317 "thread-inferred single step for dom %d (TF set, but not"
4318 " dreg status!) at 0x%"PRIxADDR" (stepped %lu bytes"
4319 " from probepoint)!\n",
4321 sstep_thread = tthread;
4322 goto handle_inferred_sstep;
4325 && bogus_sstep_thread
4326 && bogus_sstep_thread->tpc
4327 && bogus_sstep_thread->tpc->probepoint) {
4328 bogus_sstep_probepoint_addr =
4337 "inferred single step for dom %d (TF set, but not"
4338 " dreg status!) at 0x%"PRIxADDR" (stepped %d bytes"
4339 " from probepoint)!\n",
4340 xstate->
id,ipval,ipval - bogus_sstep_probepoint_addr);
4341 sstep_thread = bogus_sstep_thread;
4342 goto handle_inferred_sstep;
4346 vwarn(
"phantom single step for dom %d (no breakpoint"
4347 " set either!); letting user handle fault at"
4352 vwarn(
"could not find hardware bp and not sstep'ing;"
4353 " letting user handle fault at 0x%"PRIxADDR"!\n",
4392 struct target *target = (
struct target *)state;
4405 if (vmid != 0 && vmid != xstate->
id)
4409 retval = xen_vm_handle_exception(target,0,&again,NULL);
4420 __xen_vm_resume(target,0);
4429 verror(
"no evloop attached!\n");
4436 verror(
"event channel not initialized\n");
4444 "added evloop readfd %d event channel\n",xstate->
evloop_fd);
4474 verror(
"event channel not initialized\n");
4485 ret = select(fd+1,&inset,NULL,NULL,&tv);
4489 if (!FD_ISSET(fd, &inset))
4493 verror(
"failed to unmask event channel\n");
4498 if (vmid != 0 && vmid != xstate->
id)
4502 retval = xen_vm_handle_exception(target,0,&again,NULL);
4515 if (xen_vm_load_dominfo(target)) {
4516 vwarn(
"could not load dominfo for dom %d, trying to unpause anyway!\n",
4518 __xen_vm_resume(target,0);
4520 else if (xstate->
dominfo.paused) {
4521 __xen_vm_resume(target,0);
4528 static target_status_t xen_vm_poll(
struct target *target,
struct timeval *tv,
4541 verror(
"event channel not initialized\n");
4554 ret = select(fd+1,&inset,NULL,NULL,tv);
4561 if (!FD_ISSET(fd, &inset)) {
4568 verror(
"failed to unmask event channel\n");
4575 if (vmid != 0 && vmid != xstate->
id) {
4582 retval = xen_vm_handle_exception(target,0,&again,NULL);
4589 static unsigned char *xen_vm_read(
struct target *target,
ADDR addr,
4590 unsigned long target_length,
4591 unsigned char *buf) {
4595 static unsigned long xen_vm_write(
struct target *target,
ADDR addr,
4596 unsigned long length,
unsigned char *buf) {
4609 static int __xen_vm_pgd(
struct target *target,
tid_t tid,uint64_t *pgd) {
4613 REGVAL cr0 = 0,cr4 = 0,msr_efer = 0,cpuid_edx = 0;
4618 tthread = __xen_vm_load_current_thread(target,0,1);
4620 verror(
"could not load global thread!\n");
4632 "tid %"PRIiTID
" pgd (phys) = 0x%"PRIx64
" (cached)\n",tid,*pgd);
4637 if (xtstate->
context.vm_assist & (1 << VMASST_TYPE_pae_extended_cr3)) {
4638 *pgd = ((uint64_t)xen_cr3_to_pfn(xtstate->
context.ctrlreg[3])) \
4656 cr0 = xtstate->
context.ctrlreg[0];
4657 cr4 = xtstate->
context.ctrlreg[4];
4658 if (xstate->
hvm && xstate->hvm_cpu)
4659 msr_efer = xstate->hvm_cpu->msr_efer;
4665 verror(
"could not determine v2p_flags! pgd walks might fail;"
4666 " assuming 64-bit long mode and paging!\n");
4670 verror(
"could not determine v2p_flags! pgd walks might fail;"
4671 " assuming 32-bit mode and PAE (and auto-PSE)!\n");
4691 tthread = xen_vm_load_thread(target,tid,0);
4693 verror(
"could not load tid %"PRIiTID
"!\n",tid);
4699 tthread->
state = xtstate;
4709 "tid %"PRIiTID
" pgd (phys) = 0x%"PRIx64
" (cached)\n",tid,*pgd);
4731 verror(
"could not get phys pgd for tid %"PRIiTID
": %s!\n",
4732 tid,strerror(errno));
4740 "tid %"PRIiTID
" pgd (phys) = 0x%"PRIx64
"\n",tid,*pgd);
4745 static int xen_vm_addr_v2p(
struct target *target,
tid_t tid,
4752 if (__xen_vm_pgd(target,tid,&pgd)) {
4753 verror(
"could not read pgd for tid %"PRIiTID
"!\n",tid);
4765 static unsigned char *xen_vm_read_phys(
struct target *target,
ADDR paddr,
4766 unsigned long length,
unsigned char *buf) {
4779 static unsigned long xen_vm_write_phys(
struct target *target,
ADDR paddr,
4780 unsigned long length,
unsigned char *buf) {
4794 unsigned long length,
unsigned char *buf) {
4805 if (__xen_vm_pgd(target,tid,&pgd)) {
4806 verror(
"could not read pgd for tid %"PRIiTID
"!\n",tid);
4810 return xstate->
memops->
read_tid(target,tid,pgd,vaddr,length,buf);
4814 unsigned long length,
unsigned char *buf) {
4825 if (__xen_vm_pgd(target,tid,&pgd)) {
4826 verror(
"could not read pgd for tid %"PRIiTID
"!\n",tid);
4846 offsetof(
struct vcpu_guest_context,user_regs.rax),
4847 offsetof(
struct vcpu_guest_context,user_regs.rdx),
4848 offsetof(
struct vcpu_guest_context,user_regs.rcx),
4849 offsetof(
struct vcpu_guest_context,user_regs.rbx),
4850 offsetof(
struct vcpu_guest_context,user_regs.rsi),
4851 offsetof(
struct vcpu_guest_context,user_regs.rdi),
4852 offsetof(
struct vcpu_guest_context,user_regs.rbp),
4853 offsetof(
struct vcpu_guest_context,user_regs.rsp),
4854 offsetof(
struct vcpu_guest_context,user_regs.r8),
4855 offsetof(
struct vcpu_guest_context,user_regs.r9),
4856 offsetof(
struct vcpu_guest_context,user_regs.r10),
4857 offsetof(
struct vcpu_guest_context,user_regs.r11),
4858 offsetof(
struct vcpu_guest_context,user_regs.r12),
4859 offsetof(
struct vcpu_guest_context,user_regs.r13),
4860 offsetof(
struct vcpu_guest_context,user_regs.r14),
4861 offsetof(
struct vcpu_guest_context,user_regs.r15),
4862 offsetof(
struct vcpu_guest_context,user_regs.rip),
4863 -1, -1, -1, -1, -1, -1, -1, -1,
4864 -1, -1, -1, -1, -1, -1, -1, -1,
4865 -1, -1, -1, -1, -1, -1, -1, -1,
4866 -1, -1, -1, -1, -1, -1, -1, -1,
4867 offsetof(
struct vcpu_guest_context,user_regs.rflags),
4868 offsetof(
struct vcpu_guest_context,user_regs.es),
4869 offsetof(
struct vcpu_guest_context,user_regs.cs),
4870 offsetof(
struct vcpu_guest_context,user_regs.ss),
4871 offsetof(
struct vcpu_guest_context,user_regs.ds),
4872 offsetof(
struct vcpu_guest_context,user_regs.fs),
4873 offsetof(
struct vcpu_guest_context,user_regs.gs),
4876 offsetof(
struct vcpu_guest_context,fs_base),
4877 offsetof(
struct vcpu_guest_context,gs_base_kernel),
4878 offsetof(
struct vcpu_guest_context,gs_base_kernel),
4879 offsetof(
struct vcpu_guest_context,gs_base_user),
4880 -1, -1, -1, -1, -1, -1,
4882 offsetof(
struct vcpu_guest_context,ctrlreg[0]),
4883 offsetof(
struct vcpu_guest_context,ctrlreg[1]),
4884 offsetof(
struct vcpu_guest_context,ctrlreg[2]),
4885 offsetof(
struct vcpu_guest_context,ctrlreg[3]),
4886 offsetof(
struct vcpu_guest_context,ctrlreg[4]),
4888 offsetof(
struct vcpu_guest_context,debugreg[0]),
4889 offsetof(
struct vcpu_guest_context,debugreg[1]),
4890 offsetof(
struct vcpu_guest_context,debugreg[2]),
4891 offsetof(
struct vcpu_guest_context,debugreg[3]),
4893 offsetof(
struct vcpu_guest_context,debugreg[6]),
4894 offsetof(
struct vcpu_guest_context,debugreg[7]),
4899 offsetof(
struct vcpu_guest_context,user_regs.eax),
4900 offsetof(
struct vcpu_guest_context,user_regs.ecx),
4901 offsetof(
struct vcpu_guest_context,user_regs.edx),
4902 offsetof(
struct vcpu_guest_context,user_regs.ebx),
4903 offsetof(
struct vcpu_guest_context,user_regs.esp),
4904 offsetof(
struct vcpu_guest_context,user_regs.ebp),
4905 offsetof(
struct vcpu_guest_context,user_regs.esi),
4906 offsetof(
struct vcpu_guest_context,user_regs.edi),
4907 offsetof(
struct vcpu_guest_context,user_regs.eip),
4908 offsetof(
struct vcpu_guest_context,user_regs.eflags),
4909 -1, -1, -1, -1, -1, -1, -1, -1,
4911 -1, -1, -1, -1, -1, -1, -1, -1,
4912 -1, -1, -1, -1, -1, -1, -1, -1,
4915 offsetof(
struct vcpu_guest_context,user_regs.es),
4916 offsetof(
struct vcpu_guest_context,user_regs.cs),
4917 offsetof(
struct vcpu_guest_context,user_regs.ss),
4918 offsetof(
struct vcpu_guest_context,user_regs.ds),
4919 offsetof(
struct vcpu_guest_context,user_regs.fs),
4920 offsetof(
struct vcpu_guest_context,user_regs.gs),
4921 offsetof(
struct vcpu_guest_context,ctrlreg[0]),
4922 offsetof(
struct vcpu_guest_context,ctrlreg[1]),
4923 offsetof(
struct vcpu_guest_context,ctrlreg[2]),
4924 offsetof(
struct vcpu_guest_context,ctrlreg[3]),
4925 offsetof(
struct vcpu_guest_context,ctrlreg[4]),
4926 offsetof(
struct vcpu_guest_context,debugreg[0]),
4927 offsetof(
struct vcpu_guest_context,debugreg[1]),
4928 offsetof(
struct vcpu_guest_context,debugreg[2]),
4929 offsetof(
struct vcpu_guest_context,debugreg[3]),
4931 offsetof(
struct vcpu_guest_context,debugreg[6]),
4932 offsetof(
struct vcpu_guest_context,debugreg[7]),
4940 struct vcpu_guest_context *context,
4949 tthread->
tid,tctxt);
4955 if (arch_wordsize(target->
arch) == 8 || __WORDSIZE == 64) {
4957 offset = dreg_to_offset64[i];
4962 regval = (
REGVAL)*(uint64_t *)(((
char *)context) + offset);
4964 regval = (
REGVAL)*(uint16_t *)(((
char *)context) + offset);
4968 vwarn(
"could not set reg %d thid %d tctxt %d\n",
4969 i,tthread->
tid,tctxt);
4975 else if (arch_wordsize(target->
arch) == 4) {
4977 offset = dreg_to_offset32[i];
4981 regval = (
REGVAL)*(uint32_t *)(((
char *)context) + offset);
4985 vwarn(
"could not set reg %d thid %d tctxt %d\n",
4986 i,tthread->
tid,tctxt);
4994 "translated %d vcpu regs to thid %d tctxt %d regcache\n",
4995 count,tthread->
tid,tctxt);
5004 struct vcpu_guest_context *context;
5008 vwarn(
"unsupported reg %d!\n",reg);
5013 context = (
struct vcpu_guest_context *)priv;
5014 offset = dreg_to_offset64[reg];
5017 vwarn(
"unsupported reg %d!\n",reg);
5023 "tid %d thid %d tctxt %d regcache->vcpu %d 0x%"PRIxREGVAL"\n",
5024 target->
id,tthread->
tid,tctxt,reg,regval);
5027 *(uint64_t *)(((
char *)context) + offset) =
5030 *(uint16_t *)(((
char *)context) + offset) =
5039 REG reg,
void *rawval,
int rawlen,
5045 vwarn(
"unsupported reg %d!\n",reg);
5051 offset = dreg_to_offset64[reg];
5054 vwarn(
"unsupported reg %d!\n",reg);
5059 vwarn(
"tid %d thid %d tctxt %d regcache->vcpu %d"
5060 " -- unsupported rawval len %d\n",
5061 target->
id,tthread->
tid,tctxt,reg,rawlen);
5070 struct vcpu_guest_context *context;
5074 vwarn(
"unsupported reg %d!\n",reg);
5079 context = (
struct vcpu_guest_context *)priv;
5080 offset = dreg_to_offset32[reg];
5083 vwarn(
"unsupported reg %d!\n",reg);
5089 "tid %d thid %d tctxt %d regcache->vcpu %d 0x%"PRIxREGVAL"\n",
5090 target->
id,tthread->
tid,tctxt,reg,regval);
5092 *(uint32_t *)(((
char *)context) + offset) = (uint32_t)regval;
5100 REG reg,
void *rawval,
int rawlen,
5106 vwarn(
"unsupported reg %d!\n",reg);
5112 offset = dreg_to_offset32[reg];
5115 vwarn(
"unsupported reg %d!\n",reg);
5120 vwarn(
"tid %d thid %d tctxt %d regcache->vcpu %d"
5121 " -- unsupported rawval len %d\n",
5122 target->
id,tthread->
tid,tctxt,reg,rawlen);
5130 struct vcpu_guest_context *context) {
5132 tthread->
tid,tctxt);
5138 if (arch_wordsize(target->
arch) == 8 || __WORDSIZE == 64) {
5144 else if (arch_wordsize(target->
arch) == 4) {
5157 static REG xen_vm_get_unused_debug_reg(
struct target *target,
tid_t tid) {
5163 verror(
"currently must use TID_GLOBAL for hardware probepoints!\n");
5167 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5170 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5175 if (!xtstate->
dr[0]) { retval = 0; }
5176 else if (!xtstate->
dr[1]) { retval = 1; }
5177 else if (!xtstate->
dr[2]) { retval = 2; }
5178 else if (!xtstate->
dr[3]) { retval = 3; }
5209 static int xen_vm_set_hw_breakpoint(
struct target *target,
tid_t tid,
5214 if (reg < 0 || reg > 3) {
5219 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5222 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5227 if (xtstate->
context.debugreg[reg] != 0) {
5228 vwarn(
"debug reg %"PRIiREG" already has an address, overwriting (0x%lx)!\n",
5229 reg,xtstate->
context.debugreg[reg]);
5235 xtstate->
dr[reg] = (
unsigned long)addr;
5241 xtstate->
dr[7] |= (1 << (reg * 2));
5242 xtstate->
dr[7] &= ~(1 << (reg * 2 + 1));
5244 xtstate->
dr[7] &= ~(3 << (16 + (reg * 4)));
5247 xtstate->
context.debugreg[reg] = xtstate->
dr[reg];
5248 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5249 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5253 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5257 if (xstate->
dominfo.ttd_replay_flag) {
5258 int ret = xc_ttd_vmi_add_probe(xc_handle,xstate->
id,addr);
5262 xstate->
id,addr,ret);
5266 "registered probe in replay domain [dom%d:%"PRIxADDR"]\n",
5274 static int xen_vm_set_hw_watchpoint(
struct target *target,
tid_t tid,
5281 if (reg < 0 || reg > 3) {
5286 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5289 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5294 if (xtstate->
context.debugreg[reg] != 0) {
5295 vwarn(
"debug reg %"PRIiREG" already has an address, overwriting (0x%lx)!\n",
5296 reg,xtstate->
context.debugreg[reg]);
5302 xtstate->
dr[reg] = addr;
5308 xtstate->
dr[7] |= (1 << (reg * 2));
5309 xtstate->
dr[7] &= ~(1 << (reg * 2 + 1));
5311 xtstate->
dr[7] &= ~(3 << (16 + (reg * 4)));
5312 xtstate->
dr[7] |= (whence << (16 + (reg * 4)));
5314 xtstate->
dr[7] &= ~(3 << (18 + (reg * 4)));
5315 xtstate->
dr[7] |= (watchsize << (18 + (reg * 4)));
5319 xtstate->
dr[6],xtstate->
dr[7],whence,watchsize);
5322 xtstate->
context.debugreg[reg] = xtstate->
dr[reg];
5323 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5324 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5328 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5332 if (xstate->
dominfo.ttd_replay_flag) {
5333 int ret = xc_ttd_vmi_add_probe(xc_handle,xstate->
id,addr);
5337 xstate->
id,addr,ret);
5341 "registered probe in replay domain [dom%d:%"PRIxADDR"]\n",
5349 static int xen_vm_unset_hw_breakpoint(
struct target *target,
tid_t tid,
REG reg) {
5350 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5356 if (reg < 0 || reg > 3) {
5361 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5364 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5369 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5370 addr = xtstate->
dr[reg];
5374 xtstate->
dr[reg] = 0;
5380 xtstate->
dr[7] &= ~(3 << (reg * 2));
5383 xtstate->
context.debugreg[reg] = xtstate->
dr[reg];
5384 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5385 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5389 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5393 if (xstate->
dominfo.ttd_replay_flag) {
5394 int ret = xc_ttd_vmi_remove_probe(xc_handle,xstate->
id,addr);
5398 xstate->
id,addr,ret);
5402 "unregistered probe in replay domain [dom%d:%"PRIxADDR"]\n",
5410 static int xen_vm_unset_hw_watchpoint(
struct target *target,
tid_t tid,
REG reg) {
5412 return xen_vm_unset_hw_breakpoint(target,tid,reg);
5419 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5422 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5427 xtstate->
context.debugreg[7] = 0;
5438 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5441 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5446 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5457 if (dreg < 0 || dreg > 3) {
5462 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5465 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5474 xtstate->
dr[7] &= ~(3 << (dreg * 2));
5477 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5478 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5482 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5486 if (xstate->
dominfo.ttd_replay_flag) {
5487 int ret = xc_ttd_vmi_remove_probe(xc_handle,xstate->
id,xtstate->
dr[dreg]);
5490 verror(
"failed to unregister probe [dom%d:%lx (%d)\n",
5491 xstate->
id,xtstate->
dr[dreg],ret);
5495 "unregistered probe in replay domain [dom%d:%lx]\n",
5496 xstate->
id,xtstate->
dr[dreg]);
5507 if (dreg < 0 || dreg > 3) {
5512 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5515 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5524 xtstate->
dr[7] |= (1 << (dreg * 2));
5525 xtstate->
dr[7] &= ~(1 << (dreg * 2 + 1));
5528 xtstate->
context.debugreg[6] = xtstate->
dr[6];
5529 xtstate->
context.debugreg[7] = xtstate->
dr[7];
5533 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5537 if (xstate->
dominfo.ttd_replay_flag) {
5538 int ret = xc_ttd_vmi_add_probe(xc_handle,xstate->
id,xtstate->
dr[dreg]);
5541 verror(
"failed to register probe [dom%d:%lx (%d)\n",
5542 xstate->
id,xtstate->
dr[dreg],ret);
5546 "registered probe in replay domain [dom%d:%lx]\n",
5547 xstate->
id,xtstate->
dr[dreg]);
5556 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5559 char *msg =
"unregister";
5565 if (!xstate->
dominfo.ttd_replay_flag)
5570 ret = xc_ttd_vmi_add_probe(xc_handle,xstate->
id,addr);
5573 ret = xc_ttd_vmi_remove_probe(xc_handle,xstate->
id,addr);
5578 msg,xstate->
id,addr,ret);
5582 "%sed probe in replay domain [dom%d:%"PRIxADDR"]\n",
5583 msg,xstate->
id,addr);
5589 struct target *overlay) {
5595 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5598 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5627 #ifdef XC_HAVE_DOMAIN_DEBUG_CONTROL
5628 if (xc_domain_debug_control(xc_handle,xstate->
id,
5629 XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON,
5630 xstate->
dominfo.max_vcpu_id)) {
5631 vwarn(
"xc_domain_debug_control failed! falling back to eflags!\n");
5637 vwarn(
"xc_domain_debug_control does not exist; falling back to eflags!\n");
5646 verror(
"BUG: overlay process driver should call"
5647 " target_os_thread_singlestep()!\n");
5653 #if __WORDSIZE == 32
5683 struct target *overlay) {
5689 if (!(tthread = __xen_vm_load_cached_thread(target,tid))) {
5692 verror(
"could not load cached thread %"PRIiTID
"\n",tid);
5704 #ifdef XC_HAVE_DOMAIN_DEBUG_CONTROL
5705 if (xc_domain_debug_control(xc_handle,xstate->
id,
5706 XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF,
5707 xstate->
dominfo.max_vcpu_id)) {
5708 vwarn(
"xc_domain_debug_control failed! falling back to eflags!\n");
5714 vwarn(
"xc_domain_debug_control does not exist; falling back to eflags!\n");
5723 verror(
"BUG: overlay process driver should call"
5724 " target_os_thread_singlestep_end()!\n");
5745 unsigned char buf[2];
5755 else if (buf[0] == 0xcc || buf[0] == 0xcd || buf[1] == 0xce)
5766 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5769 if (xstate->
dominfo.ttd_guest) {
5772 else if (!(gthread = __xen_vm_load_current_thread(target,0,1))) {
5773 verror(
"could not load global thread!\n");
5779 return gtstate->
context.ttd_perf.tsc;
5783 if (xstate->
vcpuinfo.time.version & 0x1)
5784 vwarn(
"tsc update in progress; tsc may be wrong?!\n");
5786 return xstate->
vcpuinfo.time.tsc_timestamp;
5787 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5797 if (xstate->
vcpuinfo.time.version & 0x1)
5798 vwarn(
"tsc update in progress; time may be wrong?!\n");
5800 return xstate->
vcpuinfo.time.system_time;
5808 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5811 if (xstate->
dominfo.ttd_guest) {
5814 else if (!(gthread = __xen_vm_load_current_thread(target,0,1))) {
5815 verror(
"could not load global thread!\n");
5821 return gtstate->
context.ttd_perf.brctr;
5825 if (xstate->
vcpuinfo.time.version & 0x1)
5826 vwarn(
"time (subbing for counter) update in progress; time/counter"
5827 " may be wrong?!\n");
5829 return xstate->
vcpuinfo.time.system_time;
5830 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5839 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5845 if (!xstate->
dominfo.ttd_replay_flag)
5848 return xc_ttd_set_bts_on(xc_handle,xstate->
id);
5858 #ifdef CONFIG_DETERMINISTIC_TIMETRAVEL
5864 if (!xstate->
dominfo.ttd_replay_flag)
5867 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
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
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)
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)
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)