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.


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