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.


Release 1.0
[palacios.git] / misc / decoder_test / test.c
diff --git a/misc/decoder_test/test.c b/misc/decoder_test/test.c
new file mode 100644 (file)
index 0000000..f92238a
--- /dev/null
@@ -0,0 +1,194 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+#include "test.h"
+#include "vmm_xed.h"
+#include "vmm_decoder.h"
+#include "vm_guest.h"
+
+
+/* Disgusting mask hack...
+   I can't think right now, so we'll do it this way...
+*/
+static const ullong_t mask_1 = 0x00000000000000ffLL;
+static const ullong_t mask_2 = 0x000000000000ffffLL;
+static const ullong_t mask_4 = 0x00000000ffffffffLL;
+static const ullong_t mask_8 = 0xffffffffffffffffLL;
+
+
+#define MASK(val, length) ({                   \
+      ullong_t mask = 0x0LL;                   \
+      switch (length) {                                \
+      case 1:                                  \
+       mask = mask_1;                          \
+      case 2:                                  \
+       mask = mask_2;                          \
+      case 4:                                  \
+       mask = mask_4;                          \
+      case 8:                                  \
+       mask = mask_8;                          \
+      }                                                \
+      val & mask;})                            \
+
+static void init_guest_info(struct guest_info * info) {
+  memset(info, 0, sizeof(struct guest_info));
+  info->cpu_mode = PROTECTED;
+
+  info->vm_regs.rax = 0x01010101;
+  info->vm_regs.rbx = 0x02020202;
+  info->vm_regs.rcx = 0x03030303;
+  info->vm_regs.rdx = 0x04040404;
+
+  info->vm_regs.rdi = 0x05050505;
+  info->vm_regs.rsi = 0x06060606;
+  info->vm_regs.rsp = 0x07070707;
+  info->vm_regs.rbp = 0x08080808;
+
+  info->vm_regs.rdi = 0x05050505;
+  info->vm_regs.rsi = 0x06060606;
+  info->vm_regs.rsp = 0x07070707;
+  info->vm_regs.rbp = 0x08080808;
+
+
+  info->segments.ds.base = 0xf0f0f0f0;
+  info->segments.es.base = 0xe0e0e0e0;
+
+
+
+
+}
+static const char * mem = "MEMORY";
+static const char * reg = "REGISTER";
+static const char * imm = "IMMEDIATE";
+static const char * invalid = "INVALID";
+
+static const char * get_op_type_str(operand_type_t type) {
+  if (type == MEM_OPERAND) {
+    return mem;
+  } else if (type == REG_OPERAND) {
+    return reg;
+  } else if (type == IMM_OPERAND) {
+    return imm;
+  } else {
+    return invalid;
+  }
+}
+
+static int print_op(struct x86_operand *op) {
+  printf("\ttype=%s\n", get_op_type_str(op->type));
+
+  switch (op->type) {
+  case REG_OPERAND:
+    printf("\tsize=%d\n", op->size);
+    printf("\taddr=0x%x (val=%x)\n", op->operand, MASK(*(uint_t*)(op->operand), op->size));
+    return 0;
+  case MEM_OPERAND:
+    printf("\tsize=%d\n", op->size);
+    printf("\taddr=0x%x\n", op->operand);
+    return 0;
+
+  case IMM_OPERAND:
+    printf("\tsize=%d\n", op->size);
+    printf("\tval=0x%x\n", op->operand);
+    return 0;
+
+  default:
+    return -1;
+  }
+}
+
+int main(int argc, char ** argv) {
+  char * filename;
+  int fd;
+  struct stat file_state;
+  int ret;
+  char * file_buf;
+  int buf_offset = 0;
+  int file_size = 0;
+  char * instr_ptr = 0;
+  
+  struct guest_info * info = (struct guest_info *)malloc(sizeof(struct guest_info ));;
+
+  init_decoder();
+  init_guest_info(info);
+
+  if (argc == 1) {
+    printf("Error: Must give a binary file\n");
+    exit(-1);
+  }
+
+  filename = argv[1];
+  
+  ret = stat(filename, &file_state); 
+
+  if (ret == -1) {
+    printf("Could not stat file\n");
+    return -1;
+  }
+  file_size = file_state.st_size;
+
+  file_buf = malloc(file_size);
+
+  fd = open(filename, NULL);
+
+  if (fd == -1) {
+    printf("Could not open file\n");
+    return -1;
+  } else {
+    int total_read = 0;
+    int num_read = 0;
+    
+    while (total_read < file_size) {
+      num_read = read(fd, file_buf + total_read, file_size - total_read);
+      
+      if (num_read == 0) {
+       printf("end of file\n");
+       break;
+      }
+      if (num_read == -1) {
+       printf("Read error\n");
+       exit(-1);
+      }
+
+      total_read += num_read;
+    }
+
+  }
+
+  
+  instr_ptr = file_buf;
+
+  PrintV3CtrlRegs(info);
+  PrintV3GPRs(info);
+  PrintV3Segments(info);
+
+
+  while (buf_offset < file_size) {
+    struct x86_instr instr;
+
+    if (v3_decode(info, (addr_t)instr_ptr + buf_offset, &instr) == -1) {
+      printf("Unhandled instruction\n");
+      buf_offset += instr.instr_length;
+      continue;
+    }
+    printf("instr_length = %d, noperands=%d\n", instr.instr_length, instr.num_operands);
+
+    printf("Source:\n");
+    print_op(&(instr.src_operand));
+
+    printf("Dest:\n");
+    print_op(&(instr.dst_operand));
+
+
+    printf("\n\n");
+
+    buf_offset += instr.instr_length;
+  }
+
+  return 0;
+}