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.


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