2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
19 #include <palacios/vmm.h>
20 #include <palacios/vmm_symmod.h>
21 #include <palacios/vmm_symbiotic.h>
22 #include <palacios/vm_guest.h>
24 static struct hashtable * master_mod_table = NULL;
27 * This is a place holder to ensure that the _v3_modules section gets created
29 static struct {} null_mod __attribute__((__used__)) \
30 __attribute__((unused, __section__ ("_v3_modules"), \
31 aligned(sizeof(addr_t))));
33 static uint_t mod_hash_fn(addr_t key) {
34 char * name = (char *)key;
35 return v3_hash_buffer((uchar_t *)name, strlen(name));
38 static int mod_eq_fn(addr_t key1, addr_t key2) {
39 char * name1 = (char *)key1;
40 char * name2 = (char *)key2;
42 return (strcmp(name1, name2) == 0);
47 int V3_init_symmod() {
48 extern struct v3_sym_module __start__v3_modules[];
49 extern struct v3_sym_module __stop__v3_modules[];
50 struct v3_sym_module * tmp_mod = __start__v3_modules;
53 if (tmp_mod == __stop__v3_modules) {
54 PrintDebug("No Symbiotic modules found\n");
58 master_mod_table = v3_create_htable(0, mod_hash_fn, mod_eq_fn);
60 while (tmp_mod != __stop__v3_modules) {
62 if (v3_htable_search(master_mod_table, (addr_t)(tmp_mod->name))) {
63 PrintError("Multiple instances of Module (%s)\n", tmp_mod->name);
67 PrintDebug("Registering Symbiotic Module (%s)\n", tmp_mod->name);
69 if (v3_htable_insert(master_mod_table,
70 (addr_t)(tmp_mod->name),
71 (addr_t)(tmp_mod)) == 0) {
72 PrintError("Could not insert module %s to master list\n", tmp_mod->name);
75 tmp_mod = &(__start__v3_modules[++i]);
81 /* ***************** */
82 /* Linkage functions */
83 /* ***************** */
86 /* Data structure containing symbols exported via the symbiotic interface */
87 struct v3_symbol_def32 {
90 } __attribute__((packed));
96 struct list_head sym_node;
101 #include <palacios/vm_guest_mem.h>
103 static int symbol_hcall_handler(struct guest_info * core, hcall_id_t hcall_id, void * priv_data) {
104 struct v3_symmod_state * symmod_state = &(core->vm_info->sym_vm_state.symmod_state);
105 addr_t sym_start_gva = core->vm_regs.rbx;
106 uint32_t sym_size = core->vm_regs.rcx;
110 PrintError("Received SYMMOD symbol tables addr=%p, size=%d\n", (void *)sym_start_gva, sym_size);
112 for (i = 0; i < sym_size; i++) {
113 char * sym_name = NULL;
114 struct v3_symbol_def32 * tmp_symbol = NULL;
115 struct v3_symbol * new_symbol = NULL;
116 addr_t sym_gva = sym_start_gva + (sizeof(struct v3_symbol_def32) * i);
119 if (guest_va_to_host_va(core, sym_gva, (addr_t *)&(tmp_symbol)) == -1) {
120 PrintError("Could not locate symbiotic symbol definition\n");
124 if (guest_va_to_host_va(core, tmp_symbol->name_gva, (addr_t *)&(sym_name)) == -1) {
125 PrintError("Could not locate symbiotic symbol name\n");
129 PrintError("Symbiotic Symbol (%s) at %p\n", sym_name, (void *)(addr_t)tmp_symbol->value);
131 new_symbol = (struct v3_symbol *)V3_Malloc(sizeof(struct v3_symbol));
133 strncpy(new_symbol->name, sym_name, 256);
134 new_symbol->linkage = tmp_symbol->value;
136 list_add(&(new_symbol->sym_node), &(symmod_state->v3_sym_list));
143 int v3_init_symmod_vm(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
144 struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
145 struct v3_symspy_global_page * sym_page = v3_sym_get_symspy_vm(vm);
147 sym_page->symmod_enabled = 1;
149 v3_register_hypercall(vm, SYMMOD_SYMS_HCALL, symbol_hcall_handler, NULL);
151 INIT_LIST_HEAD(&(symmod_state->v3_sym_list));
153 V3_Print("Symmod initialized\n");
160 int v3_set_symmod_loader(struct v3_vm_info * vm, struct v3_symmod_loader_ops * ops, void * priv_data) {
161 struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
163 symmod_state->loader_ops = ops;
164 symmod_state->loader_data = priv_data;
173 int v3_load_sym_module(struct v3_vm_info * vm, char * mod_name) {
174 struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
175 struct v3_sym_module * mod = (struct v3_sym_module *)v3_htable_search(master_mod_table, (addr_t)mod_name);
178 PrintError("Could not find module %s\n", mod_name);
182 PrintDebug("Loading Module (%s)\n", mod_name);
184 return symmod_state->loader_ops->load_module(vm, mod, symmod_state->loader_data);
190 struct v3_sym_module * v3_get_sym_module(struct v3_vm_info * vm, char * name) {
191 struct v3_sym_module * mod = (struct v3_sym_module *)v3_htable_search(master_mod_table, (addr_t)name);
194 PrintError("Could not find module %s\n", name);