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.


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