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.


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