When libVMI are using XEN, it creates a wrapper to “libxc” and “libxenstore” on driver/xen/xen.c
status_t
xen_init(
vmi_instance_t vmi,
uint32_t UNUSED(init_flags),
vmi_init_data_t *UNUSED(init_data))
{
if ( xen_get_instance(vmi) )
return VMI_SUCCESS;
xen_instance_t *xen = g_try_malloc0(sizeof(xen_instance_t));
if ( VMI_FAILURE == xen_get_version(xen) ) {
g_free(xen);
return VMI_FAILURE;
}
if ( VMI_FAILURE == create_libxc_wrapper(xen) ) {
dbprint(VMI_DEBUG_XEN, "Failed to find a suitable xenctrl.so!\n");
g_free(xen);
return VMI_FAILURE;
}
/* initialize other xen-specific values */
#ifdef HAVE_LIBXENSTORE
if ( VMI_FAILURE == create_libxs_wrapper(xen) ) {
dbprint(VMI_DEBUG_XEN, "Failed to find a suitable xenstore.so!\n");
xen->libxcw.xc_interface_close(xen->xchandle);
g_free(xen);
return VMI_FAILURE;
}
xen->domains = g_tree_new_full ((GCompareDataFunc)domains_compare, NULL, key_destroy_func, value_destroy_func);
#endif
vmi->driver.driver_data = (void *)xen;
return VMI_SUCCESS;
}The wrappers are created using dlsym() to resolve the function address inside .so module.
status_t create_libxc_wrapper(xen_instance_t *xen)
{
libxc_wrapper_t *wrapper = &xen->libxcw;
wrapper->handle = dlopen ("libxenctrl.so", RTLD_NOW | RTLD_GLOBAL);
if ( !wrapper->handle ) {
gchar *alternate = g_strdup_printf("libxenctrl.so.%u.%u", xen->major_version, xen->minor_version);
wrapper->handle = dlopen (alternate, RTLD_NOW | RTLD_GLOBAL);
g_free(alternate);
}
if ( !wrapper->handle ) {
gchar *alternate = g_strdup_printf("libxenctrl-%u.%u.so", xen->major_version, xen->minor_version);
wrapper->handle = dlopen (alternate, RTLD_NOW | RTLD_GLOBAL);
g_free(alternate);
}
if ( !wrapper->handle ) {
fprintf(stderr, "Failed to find a suitable libxenctrl.so at any of the standard paths!\n");
return VMI_FAILURE;
}
/* Basic */
wrapper->xc_interface_open = dlsym(wrapper->handle, "xc_interface_open");
wrapper->xc_interface_close = dlsym(wrapper->handle, "xc_interface_close");
wrapper->xc_version = dlsym(wrapper->handle, "xc_version");
wrapper->xc_map_foreign_pages = dlsym(wrapper->handle, "xc_map_foreign_pages");
wrapper->xc_map_foreign_range = dlsym(wrapper->handle, "xc_map_foreign_range");
wrapper->xc_domain_get_tsc_info = dlsym(wrapper->handle, "xc_domain_get_tsc_info");
wrapper->xc_vcpu_getcontext = dlsym(wrapper->handle, "xc_vcpu_getcontext");
wrapper->xc_vcpu_setcontext = dlsym(wrapper->handle, "xc_vcpu_setcontext");
wrapper->xc_domain_hvm_getcontext = dlsym(wrapper->handle, "xc_domain_hvm_getcontext");
wrapper->xc_domain_hvm_getcontext_partial = dlsym(wrapper->handle, "xc_domain_hvm_getcontext_partial");
wrapper->xc_domain_hvm_setcontext = dlsym(wrapper->handle, "xc_domain_hvm_setcontext");
wrapper->xc_domain_getinfo = dlsym(wrapper->handle, "xc_domain_getinfo");
wrapper->xc_domain_getinfolist = dlsym(wrapper->handle, "xc_domain_getinfolist");
wrapper->xc_domctl = dlsym(wrapper->handle, "xc_domctl");
wrapper->xc_domain_pause = dlsym(wrapper->handle, "xc_domain_pause");
wrapper->xc_domain_unpause = dlsym(wrapper->handle, "xc_domain_unpause");
wrapper->xc_domain_maximum_gpfn = dlsym(wrapper->handle, "xc_domain_maximum_gpfn");
wrapper->xc_domain_maximum_gpfn2 = dlsym(wrapper->handle, "xc_domain_maximum_gpfn");
wrapper->xc_map_foreign_batch = dlsym(wrapper->handle, "xc_map_foreign_batch");
wrapper->xc_domain_cacheflush = dlsym(wrapper->handle, "xc_domain_cacheflush");
/* Events */
wrapper->xc_vm_event_get_version = dlsym(wrapper->handle, "xc_vm_event_get_version");
wrapper->xc_domain_debug_control = dlsym(wrapper->handle, "xc_domain_debug_control");
wrapper->xc_domain_set_access_required = dlsym(wrapper->handle, "xc_domain_set_access_required");
wrapper->xc_domain_decrease_reservation_exact = dlsym(wrapper->handle, "xc_domain_decrease_reservation_exact");
wrapper->xc_hvm_inject_trap = dlsym(wrapper->handle, "xc_hvm_inject_trap");
wrapper->xc_domain_populate_physmap_exact = dlsym(wrapper->handle, "xc_domain_populate_physmap_exact");
wrapper->xc_evtchn_open = dlsym(wrapper->handle, "xc_evtchn_open");
wrapper->xc_evtchn_close = dlsym(wrapper->handle, "xc_evtchn_close");
wrapper->xc_evtchn_fd = dlsym(wrapper->handle, "xc_evtchn_fd");
wrapper->xc_evtchn_notify = dlsym(wrapper->handle, "xc_evtchn_notify");
wrapper->xc_evtchn_pending = dlsym(wrapper->handle, "xc_evtchn_pending");
wrapper->xc_evtchn_unmask = dlsym(wrapper->handle, "xc_evtchn_unmask");
wrapper->xc_evtchn_unbind = dlsym(wrapper->handle, "xc_evtchn_unbind");
wrapper->xc_evtchn_bind_interdomain = dlsym(wrapper->handle, "xc_evtchn_bind_interdomain");
wrapper->xc_set_mem_access = dlsym(wrapper->handle, "xc_set_mem_access");
wrapper->xc_get_mem_access = dlsym(wrapper->handle, "xc_get_mem_access");
wrapper->xc_mem_access_enable = dlsym(wrapper->handle, "xc_mem_access_enable");
wrapper->xc_mem_access_enable2 = dlsym(wrapper->handle, "xc_mem_access_enable");
wrapper->xc_mem_access_disable = dlsym(wrapper->handle, "xc_mem_access_disable");
wrapper->xc_mem_access_resume = dlsym(wrapper->handle, "xc_mem_access_resume");
wrapper->xc_monitor_enable = dlsym(wrapper->handle, "xc_monitor_enable");
wrapper->xc_monitor_disable = dlsym(wrapper->handle, "xc_monitor_disable");
wrapper->xc_monitor_resume = dlsym(wrapper->handle, "xc_monitor_resume");
wrapper->xc_monitor_get_capabilities = dlsym(wrapper->handle, "xc_monitor_get_capabilities");
wrapper->xc_monitor_write_ctrlreg = dlsym(wrapper->handle, "xc_monitor_write_ctrlreg");
wrapper->xc_monitor_write_ctrlreg2 = dlsym(wrapper->handle, "xc_monitor_write_ctrlreg");
wrapper->xc_monitor_mov_to_msr = dlsym(wrapper->handle, "xc_monitor_mov_to_msr");
wrapper->xc_monitor_mov_to_msr2 = dlsym(wrapper->handle, "xc_monitor_mov_to_msr");
wrapper->xc_monitor_singlestep = dlsym(wrapper->handle, "xc_monitor_singlestep");
wrapper->xc_monitor_software_breakpoint = dlsym(wrapper->handle, "xc_monitor_software_breakpoint");
wrapper->xc_monitor_guest_request = dlsym(wrapper->handle, "xc_monitor_guest_request");
wrapper->xc_monitor_guest_request2 = dlsym(wrapper->handle, "xc_monitor_guest_request");
wrapper->xc_monitor_privileged_call = dlsym(wrapper->handle, "xc_monitor_privileged_call");
wrapper->xc_monitor_descriptor_access = dlsym(wrapper->handle, "xc_monitor_descriptor_access");
wrapper->xc_monitor_emul_unimplemented = dlsym(wrapper->handle, "xc_monitor_emul_unimplemented");
wrapper->xc_altp2m_get_domain_state = dlsym ( wrapper->handle, "xc_altp2m_get_domain_state" );
wrapper->xc_altp2m_set_domain_state = dlsym ( wrapper->handle, "xc_altp2m_set_domain_state" );
wrapper->xc_altp2m_set_vcpu_enable_notify = dlsym ( wrapper->handle, "xc_altp2m_set_vcpu_enable_notify" );
wrapper->xc_altp2m_create_view = dlsym ( wrapper->handle, "xc_altp2m_create_view" );
wrapper->xc_altp2m_destroy_view = dlsym(wrapper->handle, "xc_altp2m_destroy_view");
wrapper->xc_altp2m_switch_to_view = dlsym ( wrapper->handle, "xc_altp2m_switch_to_view" );
wrapper->xc_altp2m_set_mem_access = dlsym ( wrapper->handle, "xc_altp2m_set_mem_access" );
wrapper->xc_altp2m_change_gfn = dlsym ( wrapper->handle, "xc_altp2m_change_gfn" );
wrapper->xc_monitor_debug_exceptions = dlsym(wrapper->handle, "xc_monitor_debug_exceptions");
wrapper->xc_monitor_cpuid = dlsym(wrapper->handle, "xc_monitor_cpuid");
wrapper->xc_hvm_param_get = dlsym(wrapper->handle, "xc_hvm_param_get");
wrapper->xc_hvm_param_set = dlsym(wrapper->handle, "xc_hvm_param_set");
wrapper->xc_get_hvm_param = dlsym(wrapper->handle, "xc_get_hvm_param");
wrapper->xc_set_hvm_param = dlsym(wrapper->handle, "xc_set_hvm_param");
if (VMI_FAILURE == sanity_check(xen)) {
// close libxenctrl handle
if (dlclose(wrapper->handle))
errprint("dlclose failed: %s", strerror(errno));
return VMI_FAILURE;
}
return VMI_SUCCESS;
}status_t create_libxs_wrapper(xen_instance_t *xen)
{
libxs_wrapper_t *wrapper = &xen->libxsw;
wrapper->handle = dlopen ("libxenstore.so", RTLD_NOW | RTLD_GLOBAL);
if ( !wrapper->handle ) {
fprintf(stderr, "Failed to find a suitable libxenstore.so at any of the standard paths!\n");
return VMI_FAILURE;
}
wrapper->xs_open = dlsym(wrapper->handle, "xs_open");
wrapper->xs_close = dlsym(wrapper->handle, "xs_close");
wrapper->xs_directory = dlsym(wrapper->handle, "xs_directory");
wrapper->xs_read = dlsym(wrapper->handle, "xs_read");
wrapper->xs_fileno = dlsym(wrapper->handle, "xs_fileno");
wrapper->xs_is_domain_introduced = dlsym(wrapper->handle, "xs_is_domain_introduced");
wrapper->xs_read_watch = dlsym(wrapper->handle, "xs_read_watch");
wrapper->xs_watch = dlsym(wrapper->handle, "xs_watch");
wrapper->xs_unwatch = dlsym(wrapper->handle, "xs_unwatch");
if (VMI_FAILURE == sanity_check(xen)) {
// closing libxenstore handle
if (dlclose(wrapper->handle))
errprint("dlclose failed: %s\n", strerror(errno));
return VMI_FAILURE;
}
return VMI_SUCCESS;
}