Example #1
0
static void gdb_vmm_wr_all_sysregs(uint8_t *data, size_t len)
{
   debug(GDBSTUB_CMD, "need to implement write all system registers\n");
   data = data;
   len  = len;
   gdb_unsupported();
}
Example #2
0
static void gdb_cmd_rm_brk(uint8_t *data, size_t len)
{
   uint64_t type;
   size_t   size;
   offset_t addr;
   int      rc;

   if(!__gdb_setup_brk_op(data, len, &type, &size, &addr))
      return;

   switch(type)
   {
   case GDB_BRK_TYPE_MEM:
      rc = dbg_soft_del(addr);
      break;
   case GDB_BRK_TYPE_HRD_X:
   case GDB_BRK_TYPE_HRD_W:
   case GDB_BRK_TYPE_HRD_RW:
      rc = dbg_hard_brk_del(addr, type-1, size-1);
      break;
   default:
      gdb_unsupported();
      return;
   }

   if(rc == DBG_BRK_OK)
   {
      gdb_ok();
      return;
   }

   gdb_err_mem();
}
Example #3
0
static void gdb_cmd_wr_mem(uint8_t *data, size_t len)
{
   offset_t addr;
   loc_t    bytes;
   size_t   size, lbytes, can, i;
   uint8_t  store[128];

   if(!__gdb_setup_mem_op(data, len, &addr, &size, &bytes))
      return;

   debug(GDBSTUB_CMD, "write mem: addr 0x%X size %D\n", addr, size);

   lbytes = (size_t)data + len - bytes.linear;
   if(lbytes/2 != size)
   {
      debug(GDBSTUB_CMD, "gdb cmd_wr_mem missing bytes\n");
      gdb_unsupported();
   }

   while(size)
   {
      can = min(size, sizeof(store));

      for(i=0 ; i<can ; i++, bytes.u16++)
      {
	 if(!__hex_to_uint8(bytes.u8, &store[i]))
	 {
	    debug(GDBSTUB_CMD, "gdb cmd_wr_mem invalid byte\n");
	    gdb_unsupported();
	 }
      }

      if(!gdb_mem_write(addr, store, can))
      {
	 debug(GDBSTUB_CMD, "access failure\n");
	 gdb_err_mem();
	 return;
      }

      addr += can;
      size -= can;
   }

   gdb_ok();
}
Example #4
0
static size_t gdb_consume_packet(uint8_t *data, size_t len)
{
   size_t done;

   debug(GDBSTUB_PKT, "consume (%D): [", len);
#ifdef CONFIG_GDBSTUB_PKT_DBG
   debug_write(data, len);
   debug_write((uint8_t*)"]\n", 2);
#endif

   while(len)
   {
      switch(*data)
      {
      case GDB_ACK_BYTE:
	 if(!gdb_enabled())
	 {
	    debug(GDBSTUB_PKT, "gdb connect\n");
	    gdb_enable();
	 }
	 done = 1;
	 break;

      case GDB_PKT_BYTE:
	 done = gdb_parse_packet(data, len);
	 if(!done)
	    goto __end;
	 break;

      case GDB_INT_BYTE:
	 done = 1;
	 debug(GDBSTUB_PKT, "interrupt sequence requested\n");
	 gdb_interrupt_sequence();
	 break;

      case GDB_NAK_BYTE:
	 done = 1;
	 gdb_ack();
	 break;

      default:
	 done = 1;
	 debug(GDBSTUB_PKT, "gdb_stub unsupported '\\x%x' (sz %D)\n", *data, len);
	 gdb_unsupported();
	 break;
      }

      len -= done;
      data += done;
   }

__end:
   return len;
}
Example #5
0
/*
** Command packets
*/
static void gdb_cmd_query(uint8_t *data, size_t len)
{
   uint8_t qry = *data;

   data++; len--;

   switch(qry)
   {
   case GDB_QUERY_THREAD: gdb_query_thread(); return;
   }

   debug(GDBSTUB_CMD, "query unsupported\n");
   gdb_unsupported();
   return;
}
Example #6
0
static void gdb_cmd_thread(uint8_t *data)
{
   switch(*data)
   {
   case 'g':
   case 'c':
      /* ignore thread-id */
      debug(GDBSTUB_CMD, "gdb ok for thread\n");
      gdb_ok();
      break;
   default :
      debug(GDBSTUB_CMD, "thread unsupported\n");
      gdb_unsupported();
      break;
   }
}
Example #7
0
void gdb_cmd_vmm(uint8_t *data, size_t len)
{
   uint8_t idx = *data - 0x80;

   data++; len--;

   if(idx <= sizeof(gdb_vmm_handlers)/sizeof(gdb_vmm_hdl_t))
   {
      debug(GDBSTUB_CMD, "gdb_vmm handler call %d\n", idx);
      gdb_vmm_handlers[idx](data, len);
      return;
   }

   debug(GDBSTUB_CMD, "vmm cmd unsupported\n");
   gdb_unsupported();
}
Example #8
0
void gdb_process_packet(uint8_t *data, size_t len)
{
   uint8_t cmd = *data;

   data++; len--;

   debug(GDBSTUB_CMD, "parsing cmd %c\n", cmd);

   switch(cmd)
   {
   case GDB_CMD_R_MEM:
      return gdb_cmd_rd_mem(data, len);
   case GDB_CMD_W_MEM:
      return gdb_cmd_wr_mem(data, len);
   case GDB_CMD_R_REG:
      return gdb_cmd_rd_reg(data, len);
   case GDB_CMD_W_REG:
      return gdb_cmd_wr_reg(data, len);
   case GDB_CMD_S_BRK:
      return gdb_cmd_st_brk(data, len);
   case GDB_CMD_R_BRK:
      return gdb_cmd_rm_brk(data, len);
   case GDB_CMD_R_GPR:
      return gdb_cmd_rd_gpr();
   case GDB_CMD_W_GPR:
      return gdb_cmd_wr_gpr(data, len);
   case GDB_CMD_CONT:
      return gdb_cmd_cont(data, len);
   case GDB_CMD_STEP:
      return gdb_cmd_step(data, len);
   case GDB_CMD_THREAD:
      return gdb_cmd_thread(data);
   case GDB_CMD_STOP_REASON:
      return gdb_cmd_stop_reason();
   case GDB_CMD_VMM:
      return gdb_cmd_vmm(data, len);
   case GDB_CMD_QUERY:
      return gdb_cmd_query(data, len);
   case GDB_CMD_KILL:
      return gdb_cmd_kill();
   case GDB_CMD_DETACH:
      return gdb_cmd_detach();
   }

   debug(GDBSTUB_CMD, "cmd unsupported\n");
   gdb_unsupported();
}
Example #9
0
static void gdb_cmd_rd_mem(uint8_t *data, size_t len)
{
   offset_t addr;
   size_t   size, need, i;
   uint8_t  store[128];

   if(!__gdb_setup_mem_op(data, len, &addr, &size, 0))
      return;

   debug(GDBSTUB_CMD, "read mem: addr 0x%X size %D\n", addr, size);

   if(size > ((GDB_ANSWER_SZ - GDB_ACKPKT_SZ)/2))
   {
      debug(GDBSTUB_CMD, "gdb buffer too small for cmd_rd_mem\n");
      gdb_unsupported();
   }

   while(size)
   {
      need = min(size, sizeof(store));

      if(!gdb_mem_read(addr, store, need))
      {
	 debug(GDBSTUB_CMD, "access failure\n");
	 gdb_err_mem();
	 return;
      }

      for(i=0 ; i<need ; i++)
	 gdb_add_byte(store[i]);

      addr += need;
      size -= need;
   }

   gdb_send_packet();
}
Example #10
0
void gdb_send_packet()
{
   uint8_t *pkt;
   size_t  sz;

   if(!gdb_acked())
   {
      debug(GDBSTUB_PKT, "adding ACK byte\n");
      pkt = &gdb_answer[0];
      sz = gdb_buffer.sz + GDB_ACKPKT_SZ;
   }
   else
   {
      debug(GDBSTUB_PKT, "already ACKed\n");
      pkt = &gdb_answer[1];
      gdb_set_ack(0);
      sz = gdb_buffer.sz + GDB_PKT_SZ;
   }

   if(gdb_buffer.sz > (GDB_ANSWER_SZ - GDB_ACKPKT_SZ))
   {
      debug(GDBSTUB_PKT, "can not send pkt with 0x%X bytes\n", gdb_buffer.sz);
      gdb_unsupported();
      return;
   }

   gdb_answer[gdb_buffer.sz + 2] = GDB_END_BYTE;
   gdb_checksum(gdb_buffer.data.u8, gdb_buffer.sz, &gdb_answer[gdb_buffer.sz+3]);
   gdb_io_write(pkt, sz);

   debug(GDBSTUB_PKT, "gdb sent (%D): [", sz);
#ifdef CONFIG_GDBSTUB_PKT_DBG
   debug_write(pkt, sz);
   debug_write((uint8_t*)"]\n", 2);
#endif
}
Example #11
0
static void gdb_cmd_wr_gpr(uint8_t __unused__ *data, size_t __unused__ len)
{
   debug(GDBSTUB_CMD, "need to implement write all general purpose registers");
   gdb_unsupported();
}
Example #12
0
int __gdb_setup_reg(uint64_t idx, raw64_t **reg,
		    size_t *size, uint8_t sys,
		    uint8_t
#ifdef CONFIG_ARCH_AMD
		    __unused__
#endif
		    wr)
{
   loc_t    loc;
   offset_t *cache;

   if(sys)
   {
      debug(GDBSTUB_PKT, "reg_sys_op\n");
      *size = sizeof(uint64_t);
      if(idx >= 22)
	 goto __fail;

      cache = (offset_t*)info->vm.cpu.insn_cache;
      goto __sys;
   }

   if(cpu_addr_sz() == 64)
   {
      *size = sizeof(uint64_t);
      if(idx < 16)
	 goto __gpr;
      else if(idx < 24)
	 idx -= 8;
      else
	 goto __fail;
   }
   else
   {
      /* XXX: gdb seems to wait for 32 bits regs at least */
      *size = sizeof(uint32_t);

      if(idx < 8)
	 goto __gpr;
      else if(idx >= 16)
	 goto __fail;
   }

   switch(idx)
   {
   case  8: loc.u64 = &__rip.raw;        __cond_access(wr,__rip);         goto __win;
   case  9: loc.u64 = &__rflags.raw;     __cond_access(wr,__rflags);      goto __win;

   case 10: loc.u16 = &__cs.selector.raw;__cond_access(wr,__cs.selector); goto __win16;
   case 11: loc.u16 = &__ss.selector.raw;__cond_access(wr,__ss.selector); goto __win16;
   case 12: loc.u16 = &__ds.selector.raw;__cond_access(wr,__ds.selector); goto __win16;
   case 13: loc.u16 = &__es.selector.raw;__cond_access(wr,__es.selector); goto __win16;
   case 14: loc.u16 = &__fs.selector.raw;__cond_access(wr,__fs.selector); goto __win16;
   case 15: loc.u16 = &__gs.selector.raw;__cond_access(wr,__gs.selector); goto __win16;
   }

__sys:
   switch(idx)
   {
   case  0: loc.u64 = &__cr0.raw; __cond_access(wr,__cr0); goto __win;
   case  1: loc.u64 = &__cr2.raw; __cond_access(wr,__cr2); goto __win;
   case  2: loc.u64 = &__cr3.raw; __cond_access(wr,__cr3); goto __win;
   case  3: loc.u64 = &__cr4.raw; __cond_access(wr,__cr4); goto __win;

   case  4: *cache = get_dr0(); loc.addr = (void*)cache; goto __win;
   case  5: *cache = get_dr1(); loc.addr = (void*)cache; goto __win;
   case  6: *cache = get_dr2(); loc.addr = (void*)cache; goto __win;
   case  7: *cache = get_dr3(); loc.addr = (void*)cache; goto __win;

   case  8: loc.u64 = &__dr6.raw;       __cond_access(wr,__dr6);       goto __win;
   case  9: loc.u64 = &__dr7.raw;       __cond_access(wr,__dr7);       goto __win;
   case 10: loc.u64 = &__dbgctl.raw;    __cond_access(wr,__dbgctl);    goto __win;
   case 11: loc.u64 = &__efer.raw;      /*__cond_access(wr,__efer);*/  goto __win;
   case 12: loc.u64 = &__cs.base.raw;   __cond_access(wr,__cs.base);   goto __win;
   case 13: loc.u64 = &__ss.base.raw;   __cond_access(wr,__ss.base);   goto __win;
   case 14: loc.u64 = &__ds.base.raw;   __cond_access(wr,__ds.base);   goto __win;
   case 15: loc.u64 = &__es.base.raw;   __cond_access(wr,__es.base);   goto __win;
   case 16: loc.u64 = &__fs.base.raw;   __cond_access(wr,__fs.base);   goto __win;
   case 17: loc.u64 = &__gs.base.raw;   __cond_access(wr,__gs.base);   goto __win;
   case 18: loc.u64 = &__gdtr.base.raw; __cond_access(wr,__gdtr.base); goto __win;
   case 19: loc.u64 = &__idtr.base.raw; __cond_access(wr,__idtr.base); goto __win;
   case 20: loc.u64 = &__ldtr.base.raw; __cond_access(wr,__ldtr.base); goto __win;
   case 21: loc.u64 = &__tr.base.raw;   __cond_access(wr,__tr.base);   goto __win;
   }

__gpr:
   loc.u64 = &info->vm.cpu.gpr->raw[GPR64_RAX - idx].raw;
   goto __win;

__win16:
   *size = sizeof(uint16_t);

__win:
   debug(GDBSTUB_PKT, "reg_op win on %d\n", idx);
   *reg = (raw64_t*)loc.u64;
   return 1;

__fail:
   debug(GDBSTUB_PKT, "reg_op failed on %d\n", idx);
   gdb_unsupported();
   return 0;
}