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.


Resource control extensions to host OS interface
[palacios.releases.git] / palacios / src / palacios / vmm_quix86.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) 2012,  Alexander Kudryavtsev <alexk@ispras.ru>
11  * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
12  * All rights reserved.
13  *
14  * Author: Alexander Kudryavtsev <alexk@ispras.ru>
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
20 #include <palacios/vmm.h>
21 #include <palacios/vm_guest.h>
22 #include <palacios/vmm_mem_hook.h>
23 #include <palacios/vmm_emulator.h>
24 #include <palacios/vm_guest_mem.h>
25 #include <palacios/vmm_hashtable.h>
26 #include <palacios/vmm_decoder.h>
27
28 #include <quix86/quix86.h>
29
30 #ifdef V3_CONFIG_TM_FUNC
31 #include <extensions/trans_mem.h>
32 #endif
33
34 #ifdef V3_CONFIG_DEBUG_TM_FUNC
35 #define PrintTMDebug(...) V3_Print(__VA_ARGS__)
36 #else
37 #define PrintTMDebug(...)
38 #endif
39
40 #ifndef V3_CONFIG_DEBUG_DECODER
41 #undef PrintDebug
42 #define PrintDebug(fmt, args...)
43 #endif
44
45 #define GPR_REGISTER     0
46 #define SEGMENT_REGISTER 1
47 #define CTRL_REGISTER    2
48 #define DEBUG_REGISTER   3
49
50 // QUIX86 does not have to be initialised or deinitialised.
51 int v3_init_decoder(struct guest_info * core) {
52     return 0;
53 }
54 int v3_deinit_decoder(struct guest_info * core) {
55     return 0;
56 }
57
58 static int get_opcode(qx86_insn *inst, struct guest_info *core);
59 static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg,
60                  addr_t * v3_reg, uint_t * reg_len);
61
62 static int callback(void *data, int rindex, int subreg, unsigned char *value) {
63     void* reg_addr = 0;
64     uint_t reg_size;
65
66     struct guest_info *info = (struct guest_info*)data;
67     int v3_reg_type = qx86_register_to_v3_reg(info,
68         rindex,
69         (addr_t*)&reg_addr, &reg_size);
70
71     if(v3_reg_type == -1) {
72         PrintError(info->vm_info, info, "Callback failed to get register index %d\n", rindex);
73         return 0;
74     }
75
76     *(uint64_t*)value = 0;
77     switch(subreg) {
78     case QX86_SUBREG_BASE:
79         *(uint64_t*)value = ((struct v3_segment*)reg_addr)->base;
80         break;
81     case QX86_SUBREG_LIMIT:
82         *(uint32_t*)value = ((struct v3_segment*)reg_addr)->limit;
83         break;
84     case QX86_SUBREG_FLAGS:
85         PrintError(info->vm_info, info, "Callback doesn't know how to give flags.\n");
86         return 0;
87     case QX86_SUBREG_NONE: {
88         switch(qx86_rinfo(rindex)->size) {
89         case 1: *(uint8_t* )value = *(uint8_t* )reg_addr; break;
90         case 2: *(uint16_t*)value = *(uint16_t*)reg_addr; break;
91         case 4: *(uint32_t*)value = *(uint32_t*)reg_addr; break;
92         case 8: *(uint64_t*)value = *(uint64_t*)reg_addr; break;
93         }
94         break;
95     }
96     }
97
98     return 1;
99 }
100
101 static inline int qx86_op_to_v3_op(struct guest_info *info, qx86_insn *qx86_insn,
102         int op_num, struct x86_operand * v3_op) {
103     int status = 0;
104     qx86_operand *qx86_op = &qx86_insn->operands[op_num];
105     if (qx86_op->ot == QX86_OPERAND_TYPE_REGISTER) {
106         int v3_reg_type = qx86_register_to_v3_reg(info,
107                 qx86_op->u.r.rindex,
108                 &(v3_op->operand), &(v3_op->size));
109
110         if (v3_reg_type == -1) {
111             PrintError(info->vm_info, info, "Operand %d is an Unhandled Operand: %s\n", op_num,
112                     qx86_rinfo(qx86_op->u.r.rindex)->name);
113             v3_op->type = INVALID_OPERAND;
114             return -1;
115         } else if (v3_reg_type == SEGMENT_REGISTER) {
116             struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
117             v3_op->operand = (addr_t)&(seg_reg->selector);
118         }
119         v3_op->type = REG_OPERAND;
120
121     } else if(qx86_op->ot == QX86_OPERAND_TYPE_MEMORY) {
122         PrintDebug(info->vm_info, info, "Memory operand (%d)\n", op_num);
123         if((status = qx86_calculate_linear_address(qx86_insn, op_num,
124                 (qx86_uint64*)&v3_op->operand)) != QX86_SUCCESS) {
125             PrintError(info->vm_info, info, "Could not get memory operand %d: "
126                     "qx86_calculate_linear_address() returns %d\n", op_num, status);
127             return -1;
128         }
129         v3_op->type = MEM_OPERAND;
130         v3_op->size = qx86_op->size;
131
132     } else if(qx86_op->ot == QX86_OPERAND_TYPE_IMMEDIATE) {
133         v3_op->size = qx86_op->u.i.valueSize;
134
135         if (v3_op->size > 4) {
136             PrintError(info->vm_info, info, "Unhandled 64 bit immediates\n");
137             return -1;
138         }
139         v3_op->operand = (addr_t)*(uint64_t*)qx86_op->u.i.value;
140         v3_op->type = IMM_OPERAND;
141
142     } else {
143         PrintError(info->vm_info, info, "Unhandled Operand %d Type %d\n", op_num, qx86_op->ot);
144         return -1;
145     }
146
147     if (qx86_op->attributes & QX86_OPERAND_ATTRIBUTE_READ) {
148         v3_op->read = 1;
149     }
150     if (qx86_op->attributes & QX86_OPERAND_ATTRIBUTE_WRITTEN) {
151         v3_op->write = 1;
152     }
153     return 0;
154 }
155
156 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
157     int proc_mode;
158     qx86_insn qx86_inst;
159     uint8_t inst_buf[QX86_INSN_SIZE_MAX];
160
161     memset(instr, 0, sizeof(struct x86_instr));
162     memset(&qx86_inst, 0, sizeof(qx86_inst));
163
164 #ifdef V3_CONFIG_TM_FUNC
165     if (v3_tm_decode_rtm_instrs(info, instr_ptr, instr) == -1) {
166         return -1;
167     }
168 #endif
169
170
171     v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
172
173     switch(v3_get_vm_cpu_mode(info)) {
174     case REAL: case LONG_16_COMPAT:
175         proc_mode = QX86_SIZE_16; break;
176     case PROTECTED: case PROTECTED_PAE: case LONG_32_COMPAT:
177         proc_mode = QX86_SIZE_32; break;
178     case LONG:
179         proc_mode = QX86_SIZE_64; break;
180     default:
181         PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
182         return -1;
183     }
184
185     int left_in_page = 0x1000 - (instr_ptr & 0xfff);
186     if(left_in_page < QX86_INSN_SIZE_MAX) {
187         addr_t instr_ptr2;
188         int status = 0;
189
190         if (info->mem_mode == PHYSICAL_MEM) {
191             status = v3_gpa_to_hva(info, get_addr_linear(info,
192                     (info->rip & ~0xfffULL) + 0x1000, &(info->segments.cs)), &instr_ptr2);
193         } else {
194             status = v3_gva_to_hva(info, get_addr_linear(info,
195                     (info->rip & ~0xfffULL) + 0x1000, &(info->segments.cs)), &instr_ptr2);
196         }
197         if (status == -1) {
198             PrintError(info->vm_info, info, "Could not translate Instruction Address at second stage "
199                     "translation (%p)\n", (void *)(addr_t)info->rip);
200             return -1;
201         }
202
203         if(((instr_ptr & ~0xfffUL) + 0x1000) != instr_ptr2) {
204             PrintError(info->vm_info, info, "Note: physical page non-contiguous\n");
205             memcpy(inst_buf, (const void*)instr_ptr, left_in_page);
206             memcpy(inst_buf + left_in_page, (const void*)instr_ptr2,
207                     QX86_INSN_SIZE_MAX - left_in_page);
208             instr_ptr = (addr_t)inst_buf;
209         } // in other case, address space is contiguous and everything is OK
210     }
211
212     qx86_inst.callback = callback;
213     qx86_inst.data = info;
214
215     int status = qx86_decode(&qx86_inst, proc_mode,
216             (const void*)instr_ptr, QX86_INSN_SIZE_MAX);
217     if(status != QX86_SUCCESS) {
218         PrintError(info->vm_info, info, "qx86_decode() returned %d\n", status);
219         return -1;
220     }
221
222     instr->instr_length = qx86_inst.rawSize;
223
224     // 441 - dump memory for quix86 debugging
225     if ((instr->op_type = get_opcode(&qx86_inst,info)) == V3_INVALID_OP) {
226         PrintError(info->vm_info, info, "++==++ QX86 DECODE ++==++, guest RIP: %llx\n", info->rip);
227         v3_dump_mem((void *)instr_ptr, 15);
228         PrintError(info->vm_info, info, "Could not get opcode. (mnemonic=%s)\n",
229                 qx86_minfo(qx86_inst.mnemonic)->name);
230         return -1;
231     }
232     if ((instr->op_type = get_opcode(&qx86_inst, info)) == V3_INVALID_OP) {
233         PrintError(info->vm_info, info, "Could not get opcode. (mnemonic=%s)\n",
234                 qx86_minfo(qx86_inst.mnemonic)->name);
235         return -1;
236     }
237
238     if(instr->op_type == V3_OP_MOVS || instr->op_type == V3_OP_STOS) {
239         instr->is_str_op = 1;
240         if (instr->prefixes.rep == 1) {
241             uint64_t a_mask = (~0ULL >>
242                 (64 - QX86_SIZE_OCTETS(qx86_inst.attributes.addressSize) * 8));
243
244             instr->str_op_length = info->vm_regs.rcx & a_mask;
245         } else {
246             instr->str_op_length = 1;
247         }
248     } else {
249         instr->is_str_op = 0;
250         instr->str_op_length = 0;
251     }
252
253     instr->num_operands = qx86_inst.operandCount;
254
255     // set first operand
256     if (instr->num_operands >= 1) {
257         if (qx86_op_to_v3_op(info, &qx86_inst, 0, &instr->dst_operand) != 0)
258             return -1;
259     }
260
261     // set second operand
262     if (instr->num_operands >= 2) {
263         if (qx86_op_to_v3_op(info, &qx86_inst, 1, &instr->src_operand) != 0)
264             return -1;
265     }
266
267     // set third operand
268     if (instr->num_operands >= 3) {
269         if (qx86_op_to_v3_op(info, &qx86_inst, 2, &instr->third_operand) != 0)
270             return -1;
271     }
272
273 #ifdef V3_CONFIG_DEBUG_DECODER
274     qx86_print_options_intel opt;
275     char buf[128];
276     int buf_sz = 128;
277     if(qx86_print_intel(&qx86_inst, &opt, buf, &buf_sz) != QX86_SUCCESS) {
278         PrintDebug(info->vm_info, info, "Print failed!\n");
279     } else {
280         PrintDebug(info->vm_info, info, "Instruction (%p): %s\n", (void*)info->rip, buf);
281     }
282     PrintDebug(info->vm_info, info, "Operands: dst %p src %p 3rd %p\n", (void*)instr->dst_operand.operand,
283             (void*)instr->src_operand.operand, (void*)instr->third_operand.operand);
284 #endif
285     return 0;
286 }
287
288 static int get_opcode(qx86_insn *inst, struct guest_info *core) {
289     switch (inst->mnemonic) {
290 #define IS_CR(op) inst->operands[op].ot == QX86_OPERAND_TYPE_REGISTER && \
291     qx86_rinfo(inst->operands[op].u.r.rindex)->rclass == QX86_RCLASS_CREG
292
293     /* MOV cases */
294     case QX86_MNEMONIC_MOV: {
295         if(inst->operands[0].ot == QX86_OPERAND_TYPE_MEMORY
296                 || inst->operands[1].ot == QX86_OPERAND_TYPE_MEMORY)
297             return V3_OP_MOV;
298         if(IS_CR(0))
299             return V3_OP_MOV2CR;
300         if(IS_CR(1))
301             return V3_OP_MOVCR2;
302         // 441 - mov reg reg is also ok
303         if(inst->operands[0].ot == QX86_OPERAND_TYPE_REGISTER
304                 || inst->operands[1].ot == QX86_OPERAND_TYPE_REGISTER)
305             return V3_OP_MOV;
306
307         PrintError(core->vm_info, core, "Bad operand types for MOV: %d %d\n", inst->operands[0].ot,
308                 inst->operands[1].ot);
309         return V3_INVALID_OP;
310     }
311
312     /* Control Instructions */
313     case QX86_MNEMONIC_SMSW:
314         return V3_OP_SMSW;
315
316     case QX86_MNEMONIC_LMSW:
317         return V3_OP_LMSW;
318
319     case QX86_MNEMONIC_CLTS:
320         return V3_OP_CLTS;
321
322     case QX86_MNEMONIC_INVLPG:
323         return V3_OP_INVLPG;
324
325     /* Data Instructions */
326     case QX86_MNEMONIC_ADC:
327         return V3_OP_ADC;
328
329     case QX86_MNEMONIC_ADD:
330         return V3_OP_ADD;
331
332     case QX86_MNEMONIC_AND:
333         return V3_OP_AND;
334
335     case QX86_MNEMONIC_SUB:
336         return V3_OP_SUB;
337
338
339     case QX86_MNEMONIC_MOVZX:
340         return V3_OP_MOVZX;
341
342     case QX86_MNEMONIC_MOVSX:
343         return V3_OP_MOVSX;
344
345
346     case QX86_MNEMONIC_DEC:
347         return V3_OP_DEC;
348
349     case QX86_MNEMONIC_INC:
350         return V3_OP_INC;
351
352     case QX86_MNEMONIC_OR:
353         return V3_OP_OR;
354
355     case QX86_MNEMONIC_XOR:
356         return V3_OP_XOR;
357
358     case QX86_MNEMONIC_NEG:
359         return V3_OP_NEG;
360
361     case QX86_MNEMONIC_NOT:
362         return V3_OP_NOT;
363
364     case QX86_MNEMONIC_XCHG:
365         return V3_OP_XCHG;
366
367     case QX86_MNEMONIC_SETB:
368         return V3_OP_SETB;
369
370     case QX86_MNEMONIC_SETBE:
371         return V3_OP_SETBE;
372
373     case QX86_MNEMONIC_SETL:
374         return V3_OP_SETL;
375
376     case QX86_MNEMONIC_SETLE:
377         return V3_OP_SETLE;
378
379     case QX86_MNEMONIC_SETAE:
380         return V3_OP_SETNB;
381
382     case QX86_MNEMONIC_SETA:
383         return V3_OP_SETNBE;
384
385     case QX86_MNEMONIC_SETGE:
386         return V3_OP_SETNL;
387
388     case QX86_MNEMONIC_SETG:
389         return V3_OP_SETNLE;
390
391     case QX86_MNEMONIC_SETNO:
392         return V3_OP_SETNO;
393
394     case QX86_MNEMONIC_SETNP:
395         return V3_OP_SETNP;
396
397     case QX86_MNEMONIC_SETNS:
398         return V3_OP_SETNS;
399
400     case QX86_MNEMONIC_SETNZ:
401         return V3_OP_SETNZ;
402
403     case QX86_MNEMONIC_SETO:
404         return V3_OP_SETO;
405
406     case QX86_MNEMONIC_SETP:
407         return V3_OP_SETP;
408
409     case QX86_MNEMONIC_SETS:
410         return V3_OP_SETS;
411
412     case QX86_MNEMONIC_SETZ:
413         return V3_OP_SETZ;
414
415     case QX86_MNEMONIC_MOVSB:
416     case QX86_MNEMONIC_MOVSW:
417     case QX86_MNEMONIC_MOVSD:
418     case QX86_MNEMONIC_MOVSQ:
419         return V3_OP_MOVS;
420
421     case QX86_MNEMONIC_STOSB:
422     case QX86_MNEMONIC_STOSW:
423     case QX86_MNEMONIC_STOSD:
424     case QX86_MNEMONIC_STOSQ:
425         return V3_OP_STOS;
426
427     /* 441-tm: add in CMP, POP, JLE, CALL cases */
428     case QX86_MNEMONIC_CMP:
429         return V3_OP_CMP;
430
431     case QX86_MNEMONIC_POP:
432         return V3_OP_POP;
433
434     case QX86_MNEMONIC_JLE:
435         return V3_OP_JLE;
436
437     case QX86_MNEMONIC_CALL:
438         return V3_OP_CALL;
439
440     case QX86_MNEMONIC_TEST:
441         return V3_OP_TEST;
442
443     case QX86_MNEMONIC_PUSH:
444         return V3_OP_PUSH;
445
446     case QX86_MNEMONIC_JAE:
447         return V3_OP_JAE;
448
449     case QX86_MNEMONIC_JMP:
450         return V3_OP_JMP;
451
452     case QX86_MNEMONIC_JNZ:
453         return V3_OP_JNZ;
454
455     case QX86_MNEMONIC_JZ:
456         return V3_OP_JZ;
457
458     case QX86_MNEMONIC_RET:
459         return V3_OP_RET;
460
461     case QX86_MNEMONIC_IMUL:
462         return V3_OP_IMUL;
463
464     case QX86_MNEMONIC_LEA:
465         return V3_OP_LEA;
466
467     case QX86_MNEMONIC_JL:
468         return V3_OP_JL;
469
470     case QX86_MNEMONIC_CMOVZ:
471         return V3_OP_CMOVZ;
472
473     case QX86_MNEMONIC_MOVSXD:
474         return V3_OP_MOVSXD;
475
476     case QX86_MNEMONIC_JNS:
477         return V3_OP_JNS;
478
479     case QX86_MNEMONIC_CMOVS:
480         return V3_OP_CMOVS;
481
482     case QX86_MNEMONIC_SHL:
483         return V3_OP_SHL;
484
485     case QX86_MNEMONIC_INT:
486         return V3_OP_INT;
487
488     default:
489         return V3_INVALID_OP;
490     }
491 }
492
493 static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg,
494                  addr_t * v3_reg, uint_t * reg_len) {
495     PrintDebug(info->vm_info, info, "qx86 Register: %s\n", qx86_rinfo(qx86_reg)->name);
496
497     switch (qx86_reg) {
498     case QX86_REGISTER_INVALID:
499         *v3_reg = 0;
500         *reg_len = 0;
501         return -1;
502
503     case QX86_REGISTER_RAX:
504         *v3_reg = (addr_t)&(info->vm_regs.rax);
505         *reg_len = 8;
506         return GPR_REGISTER;
507     case QX86_REGISTER_EAX:
508         *v3_reg = (addr_t)&(info->vm_regs.rax);
509         *reg_len = 4;
510         return GPR_REGISTER;
511     case QX86_REGISTER_AX:
512         *v3_reg = (addr_t)&(info->vm_regs.rax);
513         *reg_len = 2;
514         return GPR_REGISTER;
515     case QX86_REGISTER_AH:
516         *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
517         *reg_len = 1;
518         return GPR_REGISTER;
519     case QX86_REGISTER_AL:
520         *v3_reg = (addr_t)&(info->vm_regs.rax);
521         *reg_len = 1;
522         return GPR_REGISTER;
523
524     case QX86_REGISTER_RCX:
525         *v3_reg = (addr_t)&(info->vm_regs.rcx);
526         *reg_len = 8;
527         return GPR_REGISTER;
528     case QX86_REGISTER_ECX:
529         *v3_reg = (addr_t)&(info->vm_regs.rcx);
530         *reg_len = 4;
531         return GPR_REGISTER;
532     case QX86_REGISTER_CX:
533         *v3_reg = (addr_t)&(info->vm_regs.rcx);
534         *reg_len = 2;
535         return GPR_REGISTER;
536     case QX86_REGISTER_CH:
537         *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
538         *reg_len = 1;
539         return GPR_REGISTER;
540     case QX86_REGISTER_CL:
541         *v3_reg = (addr_t)&(info->vm_regs.rcx);
542         *reg_len = 1;
543         return GPR_REGISTER;
544
545     case QX86_REGISTER_RDX:
546         *v3_reg = (addr_t)&(info->vm_regs.rdx);
547         *reg_len = 8;
548         return GPR_REGISTER;
549     case QX86_REGISTER_EDX:
550         *v3_reg = (addr_t)&(info->vm_regs.rdx);
551         *reg_len = 4;
552         return GPR_REGISTER;
553     case QX86_REGISTER_DX:
554         *v3_reg = (addr_t)&(info->vm_regs.rdx);
555         *reg_len = 2;
556         return GPR_REGISTER;
557     case QX86_REGISTER_DH:
558         *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
559         *reg_len = 1;
560         return GPR_REGISTER;
561     case QX86_REGISTER_DL:
562         *v3_reg = (addr_t)&(info->vm_regs.rdx);
563         *reg_len = 1;
564         return GPR_REGISTER;
565
566     case QX86_REGISTER_RBX:
567         *v3_reg = (addr_t)&(info->vm_regs.rbx);
568         *reg_len = 8;
569         return GPR_REGISTER;
570     case QX86_REGISTER_EBX:
571         *v3_reg = (addr_t)&(info->vm_regs.rbx);
572         *reg_len = 4;
573         return GPR_REGISTER;
574     case QX86_REGISTER_BX:
575         *v3_reg = (addr_t)&(info->vm_regs.rbx);
576         *reg_len = 2;
577         return GPR_REGISTER;
578     case QX86_REGISTER_BH:
579         *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
580         *reg_len = 1;
581         return GPR_REGISTER;
582     case QX86_REGISTER_BL:
583         *v3_reg = (addr_t)&(info->vm_regs.rbx);
584         *reg_len = 1;
585         return GPR_REGISTER;
586
587
588     case QX86_REGISTER_RSP:
589         *v3_reg = (addr_t)&(info->vm_regs.rsp);
590         *reg_len = 8;
591         return GPR_REGISTER;
592     case QX86_REGISTER_ESP:
593         *v3_reg = (addr_t)&(info->vm_regs.rsp);
594         *reg_len = 4;
595         return GPR_REGISTER;
596     case QX86_REGISTER_SP:
597         *v3_reg = (addr_t)&(info->vm_regs.rsp);
598         *reg_len = 2;
599         return GPR_REGISTER;
600     case QX86_REGISTER_SPL:
601         *v3_reg = (addr_t)&(info->vm_regs.rsp);
602         *reg_len = 1;
603         return GPR_REGISTER;
604
605     case QX86_REGISTER_RBP:
606         *v3_reg = (addr_t)&(info->vm_regs.rbp);
607         *reg_len = 8;
608         return GPR_REGISTER;
609     case QX86_REGISTER_EBP:
610         *v3_reg = (addr_t)&(info->vm_regs.rbp);
611         *reg_len = 4;
612         return GPR_REGISTER;
613     case QX86_REGISTER_BP:
614         *v3_reg = (addr_t)&(info->vm_regs.rbp);
615         *reg_len = 2;
616         return GPR_REGISTER;
617     case QX86_REGISTER_BPL:
618         *v3_reg = (addr_t)&(info->vm_regs.rbp);
619         *reg_len = 1;
620         return GPR_REGISTER;
621
622
623
624     case QX86_REGISTER_RSI:
625         *v3_reg = (addr_t)&(info->vm_regs.rsi);
626         *reg_len = 8;
627         return GPR_REGISTER;
628     case QX86_REGISTER_ESI:
629         *v3_reg = (addr_t)&(info->vm_regs.rsi);
630         *reg_len = 4;
631         return GPR_REGISTER;
632     case QX86_REGISTER_SI:
633         *v3_reg = (addr_t)&(info->vm_regs.rsi);
634         *reg_len = 2;
635         return GPR_REGISTER;
636     case QX86_REGISTER_SIL:
637         *v3_reg = (addr_t)&(info->vm_regs.rsi);
638         *reg_len = 1;
639         return GPR_REGISTER;
640
641
642     case QX86_REGISTER_RDI:
643         *v3_reg = (addr_t)&(info->vm_regs.rdi);
644         *reg_len = 8;
645         return GPR_REGISTER;
646     case QX86_REGISTER_EDI:
647         *v3_reg = (addr_t)&(info->vm_regs.rdi);
648         *reg_len = 4;
649         return GPR_REGISTER;
650     case QX86_REGISTER_DI:
651         *v3_reg = (addr_t)&(info->vm_regs.rdi);
652         *reg_len = 2;
653         return GPR_REGISTER;
654     case QX86_REGISTER_DIL:
655         *v3_reg = (addr_t)&(info->vm_regs.rdi);
656         *reg_len = 1;
657         return GPR_REGISTER;
658
659
660
661
662
663     case QX86_REGISTER_R8:
664         *v3_reg = (addr_t)&(info->vm_regs.r8);
665         *reg_len = 8;
666         return GPR_REGISTER;
667     case QX86_REGISTER_R8D:
668         *v3_reg = (addr_t)&(info->vm_regs.r8);
669         *reg_len = 4;
670         return GPR_REGISTER;
671     case QX86_REGISTER_R8W:
672         *v3_reg = (addr_t)&(info->vm_regs.r8);
673         *reg_len = 2;
674         return GPR_REGISTER;
675     case QX86_REGISTER_R8B:
676         *v3_reg = (addr_t)&(info->vm_regs.r8);
677         *reg_len = 1;
678         return GPR_REGISTER;
679
680     case QX86_REGISTER_R9:
681         *v3_reg = (addr_t)&(info->vm_regs.r9);
682         *reg_len = 8;
683         return GPR_REGISTER;
684     case QX86_REGISTER_R9D:
685         *v3_reg = (addr_t)&(info->vm_regs.r9);
686         *reg_len = 4;
687         return GPR_REGISTER;
688     case QX86_REGISTER_R9W:
689         *v3_reg = (addr_t)&(info->vm_regs.r9);
690         *reg_len = 2;
691         return GPR_REGISTER;
692     case QX86_REGISTER_R9B:
693         *v3_reg = (addr_t)&(info->vm_regs.r9);
694         *reg_len = 1;
695         return GPR_REGISTER;
696
697     case QX86_REGISTER_R10:
698         *v3_reg = (addr_t)&(info->vm_regs.r10);
699         *reg_len = 8;
700         return GPR_REGISTER;
701     case QX86_REGISTER_R10D:
702         *v3_reg = (addr_t)&(info->vm_regs.r10);
703         *reg_len = 4;
704         return GPR_REGISTER;
705     case QX86_REGISTER_R10W:
706         *v3_reg = (addr_t)&(info->vm_regs.r10);
707         *reg_len = 2;
708         return GPR_REGISTER;
709     case QX86_REGISTER_R10B:
710         *v3_reg = (addr_t)&(info->vm_regs.r10);
711         *reg_len = 1;
712         return GPR_REGISTER;
713
714     case QX86_REGISTER_R11:
715         *v3_reg = (addr_t)&(info->vm_regs.r11);
716         *reg_len = 8;
717         return GPR_REGISTER;
718     case QX86_REGISTER_R11D:
719         *v3_reg = (addr_t)&(info->vm_regs.r11);
720         *reg_len = 4;
721         return GPR_REGISTER;
722     case QX86_REGISTER_R11W:
723         *v3_reg = (addr_t)&(info->vm_regs.r11);
724         *reg_len = 2;
725         return GPR_REGISTER;
726     case QX86_REGISTER_R11B:
727         *v3_reg = (addr_t)&(info->vm_regs.r11);
728         *reg_len = 1;
729         return GPR_REGISTER;
730
731     case QX86_REGISTER_R12:
732         *v3_reg = (addr_t)&(info->vm_regs.r12);
733         *reg_len = 8;
734         return GPR_REGISTER;
735     case QX86_REGISTER_R12D:
736         *v3_reg = (addr_t)&(info->vm_regs.r12);
737         *reg_len = 4;
738         return GPR_REGISTER;
739     case QX86_REGISTER_R12W:
740         *v3_reg = (addr_t)&(info->vm_regs.r12);
741         *reg_len = 2;
742         return GPR_REGISTER;
743     case QX86_REGISTER_R12B:
744         *v3_reg = (addr_t)&(info->vm_regs.r12);
745         *reg_len = 1;
746         return GPR_REGISTER;
747
748     case QX86_REGISTER_R13:
749         *v3_reg = (addr_t)&(info->vm_regs.r13);
750         *reg_len = 8;
751         return GPR_REGISTER;
752     case QX86_REGISTER_R13D:
753         *v3_reg = (addr_t)&(info->vm_regs.r13);
754         *reg_len = 4;
755         return GPR_REGISTER;
756     case QX86_REGISTER_R13W:
757         *v3_reg = (addr_t)&(info->vm_regs.r13);
758         *reg_len = 2;
759         return GPR_REGISTER;
760     case QX86_REGISTER_R13B:
761         *v3_reg = (addr_t)&(info->vm_regs.r13);
762         *reg_len = 1;
763         return GPR_REGISTER;
764
765     case QX86_REGISTER_R14:
766         *v3_reg = (addr_t)&(info->vm_regs.r14);
767         *reg_len = 8;
768         return GPR_REGISTER;
769     case QX86_REGISTER_R14D:
770         *v3_reg = (addr_t)&(info->vm_regs.r14);
771         *reg_len = 4;
772         return GPR_REGISTER;
773     case QX86_REGISTER_R14W:
774         *v3_reg = (addr_t)&(info->vm_regs.r14);
775         *reg_len = 2;
776         return GPR_REGISTER;
777     case QX86_REGISTER_R14B:
778         *v3_reg = (addr_t)&(info->vm_regs.r14);
779         *reg_len = 1;
780         return GPR_REGISTER;
781
782     case QX86_REGISTER_R15:
783         *v3_reg = (addr_t)&(info->vm_regs.r15);
784         *reg_len = 8;
785         return GPR_REGISTER;
786     case QX86_REGISTER_R15D:
787         *v3_reg = (addr_t)&(info->vm_regs.r15);
788         *reg_len = 4;
789         return GPR_REGISTER;
790     case QX86_REGISTER_R15W:
791         *v3_reg = (addr_t)&(info->vm_regs.r15);
792         *reg_len = 2;
793         return GPR_REGISTER;
794     case QX86_REGISTER_R15B:
795         *v3_reg = (addr_t)&(info->vm_regs.r15);
796         *reg_len = 1;
797         return GPR_REGISTER;
798
799
800     case QX86_REGISTER_RIP:
801         *v3_reg = (addr_t)&(info->rip);
802         *reg_len = 8;
803         return CTRL_REGISTER;
804     case QX86_REGISTER_EIP:
805         *v3_reg = (addr_t)&(info->rip);
806         *reg_len = 4;
807         return CTRL_REGISTER;
808     case QX86_REGISTER_IP:
809         *v3_reg = (addr_t)&(info->rip);
810         *reg_len = 2;
811         return CTRL_REGISTER;
812
813     case QX86_REGISTER_FLAGS:
814         *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
815         *reg_len = 2;
816         return CTRL_REGISTER;
817     case QX86_REGISTER_EFLAGS:
818         *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
819         *reg_len = 4;
820         return CTRL_REGISTER;
821     case QX86_REGISTER_RFLAGS:
822         *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
823         *reg_len = 8;
824         return CTRL_REGISTER;
825
826     case QX86_REGISTER_CR0:
827         *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
828         *reg_len = 4;
829         return CTRL_REGISTER;
830     case QX86_REGISTER_CR2:
831         *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
832         *reg_len = 4;
833         return CTRL_REGISTER;
834     case QX86_REGISTER_CR3:
835         *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
836         *reg_len = 4;
837         return CTRL_REGISTER;
838     case QX86_REGISTER_CR4:
839         *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
840         *reg_len = 4;
841         return CTRL_REGISTER;
842     case QX86_REGISTER_CR8:
843         *v3_reg = (addr_t)&(info->ctrl_regs.apic_tpr);
844         *reg_len = 4;
845         return CTRL_REGISTER;
846
847     case QX86_REGISTER_CR1:
848     case QX86_REGISTER_CR5:
849     case QX86_REGISTER_CR6:
850     case QX86_REGISTER_CR7:
851     case QX86_REGISTER_CR9:
852     case QX86_REGISTER_CR10:
853     case QX86_REGISTER_CR11:
854     case QX86_REGISTER_CR12:
855     case QX86_REGISTER_CR13:
856     case QX86_REGISTER_CR14:
857     case QX86_REGISTER_CR15:
858         return -1;
859
860
861     case QX86_REGISTER_CS:
862         *v3_reg = (addr_t)&(info->segments.cs);
863         *reg_len = 8;
864         return SEGMENT_REGISTER;
865     case QX86_REGISTER_DS:
866         *v3_reg = (addr_t)&(info->segments.ds);
867         *reg_len = 8;
868         return SEGMENT_REGISTER;
869     case QX86_REGISTER_ES:
870         *v3_reg = (addr_t)&(info->segments.es);
871         *reg_len = 8;
872         return SEGMENT_REGISTER;
873     case QX86_REGISTER_SS:
874         *v3_reg = (addr_t)&(info->segments.ss);
875         *reg_len = 8;
876         return SEGMENT_REGISTER;
877     case QX86_REGISTER_FS:
878         *v3_reg = (addr_t)&(info->segments.fs);
879         *reg_len = 8;
880         return SEGMENT_REGISTER;
881     case QX86_REGISTER_GS:
882         *v3_reg = (addr_t)&(info->segments.gs);
883         *reg_len = 8;
884         return SEGMENT_REGISTER;
885
886
887     case QX86_REGISTER_DR0:
888     case QX86_REGISTER_DR1:
889     case QX86_REGISTER_DR2:
890     case QX86_REGISTER_DR3:
891     case QX86_REGISTER_DR4:
892     case QX86_REGISTER_DR5:
893     case QX86_REGISTER_DR6:
894     case QX86_REGISTER_DR7:
895     case QX86_REGISTER_DR8:
896     case QX86_REGISTER_DR9:
897     case QX86_REGISTER_DR10:
898     case QX86_REGISTER_DR11:
899     case QX86_REGISTER_DR12:
900     case QX86_REGISTER_DR13:
901     case QX86_REGISTER_DR14:
902     case QX86_REGISTER_DR15:
903         return -1;
904
905
906     case QX86_REGISTER_XMM0:
907     case QX86_REGISTER_XMM1:
908     case QX86_REGISTER_XMM2:
909     case QX86_REGISTER_XMM3:
910     case QX86_REGISTER_XMM4:
911     case QX86_REGISTER_XMM5:
912     case QX86_REGISTER_XMM6:
913     case QX86_REGISTER_XMM7:
914     case QX86_REGISTER_XMM8:
915     case QX86_REGISTER_XMM9:
916     case QX86_REGISTER_XMM10:
917     case QX86_REGISTER_XMM11:
918     case QX86_REGISTER_XMM12:
919     case QX86_REGISTER_XMM13:
920     case QX86_REGISTER_XMM14:
921     case QX86_REGISTER_XMM15:
922
923     case QX86_REGISTER_YMM0:
924     case QX86_REGISTER_YMM1:
925     case QX86_REGISTER_YMM2:
926     case QX86_REGISTER_YMM3:
927     case QX86_REGISTER_YMM4:
928     case QX86_REGISTER_YMM5:
929     case QX86_REGISTER_YMM6:
930     case QX86_REGISTER_YMM7:
931     case QX86_REGISTER_YMM8:
932     case QX86_REGISTER_YMM9:
933     case QX86_REGISTER_YMM10:
934     case QX86_REGISTER_YMM11:
935     case QX86_REGISTER_YMM12:
936     case QX86_REGISTER_YMM13:
937     case QX86_REGISTER_YMM14:
938     case QX86_REGISTER_YMM15:
939
940     case QX86_REGISTER_MMX0:
941     case QX86_REGISTER_MMX1:
942     case QX86_REGISTER_MMX2:
943     case QX86_REGISTER_MMX3:
944     case QX86_REGISTER_MMX4:
945     case QX86_REGISTER_MMX5:
946     case QX86_REGISTER_MMX6:
947     case QX86_REGISTER_MMX7:
948
949     case QX86_REGISTER_ST0:
950     case QX86_REGISTER_ST1:
951     case QX86_REGISTER_ST2:
952     case QX86_REGISTER_ST3:
953     case QX86_REGISTER_ST4:
954     case QX86_REGISTER_ST5:
955     case QX86_REGISTER_ST6:
956     case QX86_REGISTER_ST7:
957         return -1;
958
959     }
960
961
962     return 0;
963 }