Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Cleanup and sanity-checking of use of strncpy/strcpy (Coverity static analysis)
[palacios.git] / palacios / src / palacios / vmm_symmod.c
1 /* 
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.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
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.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19 #include <palacios/vmm.h>
20 #include <palacios/vmm_symmod.h>
21 #include <palacios/vmm_symbiotic.h>
22 #include <palacios/vm_guest.h>
23 #include <palacios/vmm_list.h>
24
25 static struct hashtable * capsule_table = NULL;
26 static LIST_HEAD(capsule_list);
27
28
29 /* 
30  * This is a place holder to ensure that the _v3_modules section gets created by gcc
31  */
32 static struct {} null_mod  __attribute__((__used__))                    \
33     __attribute__((unused, __section__ ("_v3_capsules"),                \
34                    aligned(sizeof(addr_t))));
35
36 static uint_t mod_hash_fn(addr_t key) {
37     char * name = (char *)key;
38     return v3_hash_buffer((uchar_t *)name, strlen(name));
39 }
40
41 static int mod_eq_fn(addr_t key1, addr_t key2) {
42     char * name1 = (char *)key1;
43     char * name2 = (char *)key2;
44     
45     return (strcmp(name1, name2) == 0);
46 }
47
48
49 struct capsule_def {
50     char * name;
51     addr_t start_addr;
52     addr_t end_addr;
53     uint32_t flags; // see 'struct v3_symmod_flags'
54 } __attribute__((packed));
55
56
57
58 int V3_init_symmod() {
59     extern struct capsule_def __start__v3_capsules[];
60     extern struct capsule_def __stop__v3_capsules[];
61     struct capsule_def * tmp_def = __start__v3_capsules;
62     int i = 0;
63
64     if (tmp_def == __stop__v3_capsules) {
65         PrintDebug(VM_NONE, VCORE_NONE, "No Symbiotic capsules found\n");
66         return 0;
67     }
68
69     capsule_table = v3_create_htable(0, mod_hash_fn, mod_eq_fn);
70
71     while (tmp_def != __stop__v3_capsules) {
72         struct v3_sym_capsule * capsule = NULL;
73
74         if (v3_htable_search(capsule_table, (addr_t)(tmp_def->name))) {
75             PrintError(VM_NONE, VCORE_NONE, "Multiple instances of Module (%s)\n", tmp_def->name);
76             return -1;
77         }
78         
79
80         capsule = V3_Malloc(sizeof(struct v3_sym_capsule));
81
82         if (!capsule) {
83             PrintError(VM_NONE, VCORE_NONE, "Cannot allocate in initializing symmod\n");
84             return -1;
85         }
86
87
88         memset(capsule, 0, sizeof(struct v3_sym_capsule));
89
90         capsule->name = tmp_def->name;
91         capsule->start_addr = (void *)(tmp_def->start_addr);
92         capsule->size = tmp_def->end_addr - tmp_def->start_addr;
93         capsule->flags = tmp_def->flags;
94         
95         
96
97         if (capsule->type == V3_SYMMOD_MOD) {
98             // parse module
99             // capsule->capsule_data = v3_sym_module...
100             // capsule->guest_size = size of linked module
101         } else if (capsule->type == V3_SYMMOD_LNX) {
102             capsule->guest_size = capsule->size;
103             capsule->capsule_data = NULL;
104         } else {
105             V3_Free(capsule);
106             return -1;
107         }
108
109         PrintDebug(VM_NONE, VCORE_NONE, "Registering Symbiotic Module (%s)\n", tmp_def->name);
110
111         if (v3_htable_insert(capsule_table, 
112                              (addr_t)(tmp_def->name),
113                              (addr_t)(capsule)) == 0) {
114             PrintError(VM_NONE, VCORE_NONE, "Could not insert module %s to master list\n", tmp_def->name);
115             V3_Free(capsule);
116             return -1;
117         }
118
119         list_add(&(capsule->node), &capsule_list);
120
121         tmp_def = &(__start__v3_capsules[++i]);
122     }
123     
124     return 0;
125 }
126
127 int V3_deinit_symmod() {
128     v3_free_htable(capsule_table, 1, 0);    
129
130     return 0;
131 }
132
133 /* ***************** */
134 /* Linkage functions */
135 /* ***************** */
136
137
138 /* Data structure containing symbols exported via the symbiotic interface */
139 struct v3_symbol_def32 {
140     uint32_t name_gva;
141     uint32_t value;
142 } __attribute__((packed));
143
144 struct v3_symbol_def64 {
145     uint64_t name_gva;
146     uint64_t value;
147 } __attribute__((packed));
148
149
150
151 struct v3_symbol {
152     char name[256];
153     uint64_t linkage;
154
155     struct list_head sym_node;
156 };
157
158
159
160 #include <palacios/vm_guest_mem.h>
161
162 static int symbol_hcall_handler(struct guest_info * core, hcall_id_t hcall_id, void * priv_data) {
163     struct v3_symmod_state * symmod_state = &(core->vm_info->sym_vm_state.symmod_state);
164     addr_t sym_start_gva = core->vm_regs.rbx;
165     uint32_t sym_size = core->vm_regs.rcx;
166
167     int i = 0;
168
169     PrintError(core->vm_info, core, "Received SYMMOD symbol tables addr=%p, size=%d\n", (void *)sym_start_gva, sym_size);
170
171     for (i = 0; i < sym_size; i++) {
172         char * sym_name = NULL;
173         struct v3_symbol_def32 * tmp_symbol = NULL;
174         struct v3_symbol * new_symbol = NULL;
175         addr_t sym_gva = sym_start_gva + (sizeof(struct v3_symbol_def32) * i);
176
177
178         if (v3_gva_to_hva(core, sym_gva, (addr_t *)&(tmp_symbol)) == -1) {
179             PrintError(core->vm_info, core, "Could not locate symbiotic symbol definition\n");
180             continue;
181         }
182         
183         if (v3_gva_to_hva(core, tmp_symbol->name_gva, (addr_t *)&(sym_name)) == -1) {
184             PrintError(core->vm_info, core, "Could not locate symbiotic symbol name\n");
185             continue;
186         }
187         
188         PrintError(core->vm_info, core, "Symbiotic Symbol (%s) at %p\n", sym_name, (void *)(addr_t)tmp_symbol->value);
189         
190         new_symbol = (struct v3_symbol *)V3_Malloc(sizeof(struct v3_symbol));
191
192         if (!new_symbol) {
193             PrintError(core->vm_info, core, "Cannot allocate in symbiotic hcall handler\n");
194             return -1;
195         }
196
197         strncpy(new_symbol->name, sym_name, 256);
198         new_symbol->name[255] = 0;
199         new_symbol->linkage = tmp_symbol->value;
200
201         list_add(&(new_symbol->sym_node), &(symmod_state->v3_sym_list));
202     }
203
204     return 0;
205 }
206
207
208 int v3_init_symmod_vm(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
209     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
210     struct v3_symspy_global_page * sym_page = v3_sym_get_symspy_vm(vm);
211     struct v3_sym_capsule * tmp_capsule = NULL;
212
213     symmod_state->capsule_table = v3_create_htable(0, mod_hash_fn, mod_eq_fn);
214
215
216     // Add modules to local hash table, should be keyed to config
217     list_for_each_entry(tmp_capsule, &capsule_list, node) {
218         V3_Print(vm, VCORE_NONE, "Adding %s to local module table\n", tmp_capsule->name);
219         if (v3_htable_insert(symmod_state->capsule_table, 
220                              (addr_t)(tmp_capsule->name),
221                              (addr_t)(tmp_capsule)) == 0) {
222             PrintError(vm, VCORE_NONE, "Could not insert module %s to vm local list\n", tmp_capsule->name);
223             return -1;
224         }
225         symmod_state->num_avail_capsules++;
226     }
227
228     symmod_state->num_loaded_capsules = 0;
229     sym_page->symmod_enabled = 1;
230
231     v3_register_hypercall(vm, SYMMOD_SYMS_HCALL, symbol_hcall_handler, NULL);
232
233     INIT_LIST_HEAD(&(symmod_state->v3_sym_list));
234
235     V3_Print(vm, VCORE_NONE, "Symmod initialized\n");
236
237     return 0;
238 }
239
240 int v3_deinit_symmod_vm(struct v3_vm_info * vm) {
241     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
242     struct v3_symbol * sym = NULL;
243     struct v3_symbol * tmp_sym = NULL;
244
245     v3_remove_hypercall(vm, SYMMOD_SYMS_HCALL);
246
247     v3_free_htable(symmod_state->capsule_table, 0, 0);
248
249     list_for_each_entry_safe(sym, tmp_sym, &(symmod_state->v3_sym_list), sym_node) {
250         list_del(&(sym->sym_node));
251         V3_Free(sym);
252     }
253
254     return 0;
255 }
256
257
258 int v3_set_symmod_loader(struct v3_vm_info * vm, struct v3_symmod_loader_ops * ops, void * priv_data) {
259     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
260    
261     symmod_state->loader_ops = ops;
262     symmod_state->loader_data = priv_data;
263  
264     return 0;
265 }
266
267
268
269
270
271 int v3_load_sym_capsule(struct v3_vm_info * vm, char * name) {
272     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
273     struct v3_sym_capsule * capsule = (struct v3_sym_capsule *)v3_htable_search(capsule_table, (addr_t)name);
274
275     if (!capsule) {
276         PrintError(vm, VCORE_NONE, "Could not find capsule %s\n", name);
277         return -1;
278     }
279
280     PrintDebug(vm, VCORE_NONE, "Loading Capsule (%s)\n", name);
281
282     return symmod_state->loader_ops->load_capsule(vm, capsule, symmod_state->loader_data);
283 }
284
285
286
287 struct list_head * v3_get_sym_capsule_list() {
288     return &(capsule_list);
289 }
290
291
292 struct v3_sym_capsule * v3_get_sym_capsule(struct v3_vm_info * vm, char * name) {
293     struct v3_sym_capsule * mod = (struct v3_sym_capsule *)v3_htable_search(capsule_table, (addr_t)name);
294
295     if (!mod) {
296         PrintError(vm, VCORE_NONE, "Could not find module %s\n", name);
297         return NULL;
298     }
299
300     return mod;
301 }