Пример #1
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();
}
Пример #2
0
static void gdb_vmm_wr_sysreg(uint8_t *data, size_t len)
{
   raw64_t  *reg, value;
   size_t   size;

   if(!__gdb_setup_reg_op(data, len, &reg, &size, &value, 1, 1))
   {
      debug(GDBSTUB_CMD, "write sysreg failed\n");
      return;
   }

   if(reg == (raw64_t*)&__cr0 && __resolve_cr0_wr((cr0_reg_t*)&value) == VM_FAIL)
      goto __err;
   else if(reg == (raw64_t*)&__cr3 && __resolve_cr3_wr((cr3_reg_t*)&value) == VM_FAIL)
      goto __err;
   else if(reg == (raw64_t*)&__cr4 && __resolve_cr4_wr((cr4_reg_t*)&value) == VM_FAIL)
      goto __err;
   else
      reg->raw = value.raw;

   gdb_ok();
   return;

__err:
   debug(GDBSTUB_CMD, "invalid wr to control register\n");
   gdb_err_inv();
}
Пример #3
0
static void gdb_vmm_npg_set_pte(uint8_t *data, size_t len)
{
   uint64_t     args[2];
   loc_t        addr;
   npg_pte64_t  npte, *opte;

   if(!__gdb_vmm_parse_args(data, len, args, 2))
   {
      gdb_nak();
      return;
   }

   addr.raw = args[0];
   opte = _npg_get_pte(addr.linear);
   if(!opte)
   {
      debug(GDBSTUB_CMD, "no npg pte for 0x%x\n", addr.raw);
      gdb_err_mem();
      return;
   }

   npte.raw = args[1];
   opte->raw = npte.raw;
   npg_invlpg(addr.linear);
   gdb_ok();
}
Пример #4
0
static void gdb_cmd_kill()
{
   debug(GDBSTUB_CMD, "gdb kill\n");
   gdb_reset();
   gdb_ok();
   return;
}
Пример #5
0
static void gdb_vmm_clear_idt_event(uint8_t __unused__ *data, size_t __unused__ len)
{
   if(__injecting_event())
      __clear_event_injection();

   gdb_ok();
}
Пример #6
0
static void gdb_cmd_detach()
{
   debug(GDBSTUB_CMD, "gdb detach\n");
   gdb_reset();
   gdb_ok();
   gdb_wait_ack();
   return;
}
Пример #7
0
/* gdb_q():
 * Query.  Not sure what this is for, but according to Gatliff's
 * article, just do it...
 */
int
gdb_q(char *line)
{
	line++;

	if (strncmp(line,"Offsets",7) == 0)
		return(gdb_response("Text=0;Data=0;Bss=0"));
	else
		return(gdb_ok());
}
Пример #8
0
static void gdb_vmm_keep_active_cr3(uint8_t __unused__ *data, size_t __unused__ len)
{
   if(ctrl_cr3_enabled())
   {
      ctrl_set_cr3_keep(1);
      gdb_ok();
      return;
   }

   gdb_err_inv();
}
Пример #9
0
static void gdb_vmm_set_active_cr3(uint8_t *data, size_t len)
{
   cr3_reg_t val;

   if(!gdb_get_number(data, len, (uint64_t*)&val.raw, 0))
   {
      gdb_nak();
      return;
   }

   ctrl_active_cr3_enable(val);
   gdb_ok();
}
Пример #10
0
static void gdb_vmm_npg_unmap(uint8_t *data, size_t len)
{
   uint64_t args[2];

   if(!__gdb_vmm_parse_args(data, len, args, 2))
   {
      gdb_nak();
      return;
   }

   npg_unmap((offset_t)args[0], (offset_t)args[1]);
   gdb_ok();
}
Пример #11
0
static void gdb_vmm_wr_cr_rd_mask(uint8_t *data, size_t len)
{
   raw64_t val;

   if(!gdb_get_number(data, len, (uint64_t*)&val.raw, 0))
   {
      gdb_nak();
      return;
   }

   ctrl_usr_set_cr_rd(val.wlow);
   gdb_ok();
}
Пример #12
0
static void gdb_vmm_set_affinity(uint8_t *data, size_t len)
{
   raw64_t val;

   if(!gdb_get_number(data, len, (uint64_t*)&val.raw, 0))
   {
      gdb_nak();
      return;
   }

   ctrl_set_affinity(val.blow);
   gdb_ok();
   debug(GDBSTUB_CMD, "set affinity to %d\n", val.blow);
}
Пример #13
0
static void gdb_vmm_wr_excp_mask(uint8_t *data, size_t len)
{
   raw64_t val;

   if(!gdb_get_number(data, len, (uint64_t*)&val.raw, 0))
   {
      gdb_nak();
      return;
   }

   info->vmm.ctrl.usr.excp = val.low;
   __update_exception_mask();
   gdb_ok();
}
Пример #14
0
static void gdb_vmm_wr_cr_wr_mask(uint8_t *data, size_t len)
{
   raw64_t val;

   if(!gdb_get_number(data, len, (uint64_t*)&val.raw, 0))
   {
      gdb_nak();
      return;
   }

   debug(GDBSTUB_CMD, "write cr mask 0x%x\n", val.wlow);

   ctrl_usr_set_cr_wr(val.wlow);
   gdb_ok();
}
Пример #15
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;
   }
}
Пример #16
0
static void gdb_cmd_wr_reg(uint8_t *data, size_t len)
{
   raw64_t  *reg, value;
   size_t   size;

   if(!__gdb_setup_reg_op(data, len, &reg, &size, &value, 1, 0))
      return;

   switch(size)
   {
   case 2: reg->wlow = value.wlow; break;
   case 4: reg->low  = value.low;  break;
   case 8: reg->raw  = value.raw;  break;
   }

   gdb_ok();
}
Пример #17
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();
}
Пример #18
0
static int __gdb_vmm_mem_rw_parse(uint8_t *data, size_t len,
				  loc_t *addr, size_t *sz)
{
   uint64_t args[2];

   if(!__gdb_vmm_parse_args(data, len, args, 2))
   {
      gdb_nak();
      return 0;
   }

   addr->raw = args[0];
   *sz = (size_t)args[1];

   gdb_ok();
   gdb_wait_ack();
   return 1;
}
Пример #19
0
/* gdb_M():
 * GDB memory write command...
 * Incoming command format is...
 *
 *		MADDR,LEN:DATA#CC
 *
 * where:
 *	'M'		is the "memory read" request
 *	'ADDR'	is the address from which the data is to be read
 *	'LEN'	is the number of bytes to be read
 *	'DATA'	is the ascii data
 *
 * STATUS: This function has been tested with m68k-elf-gdb (xtools)
 * and appears to work ok.
 */
int
gdb_M(char *line)
{
	int		len, i;
	char	*lp;
	uchar	*addr, buf[3];
	
	addr = (uchar *)strtol(line+1,&lp,16);
	len = (int)strtol(lp+1,&lp,16);
	lp++;

	buf[2] = 0;
	for(i=0;i<len;i++) {
		buf[0] = *lp++;
		buf[1] = *lp++;
		*addr++ = (uchar)strtol((char *)buf,0,16);
	}
	gdb_ok();
	return(0);
}
Пример #20
0
/* gdb_P():
 * Store to a register.
 */
int
gdb_P(char *line)
{
	char *lp;
	int rnum;
	ulong rval;

	line++;
	rnum = strtol(line,&lp,16);
	if (rnum >= REGTBL_SIZE) {
		gdb_err(GDBERR_RNUMOOR);	
		return(-1);
	}
	lp++;
	rval = strtol(lp,0,16);
	self_ecl(rval);
	putreg(gdb_regtbl[rnum],rval);

	gdb_ok();
	return(0);
}
Пример #21
0
/* gdb_m():
 * GDB memory read command...
 * Incoming command format is...
 *
 *		mADDR,LEN#CC
 *
 * where:
 *	'm'		is the "memory read" request
 *	'ADDR'	is the address from which the data is to be read
 *	'LEN'	is the number of bytes to be read
 *
 */
int
gdb_m(char *line)
{
	int		len, i;
	char 	*lp;
	uchar	*addr, *resp, buf[128];
	
	addr = (uchar *)strtol(line+1,&lp,16);
	len = (int)strtol(lp+1,0,16);
	if (len) {
		if (len*2 >= sizeof(buf)) {
			gdb_err(GDBERR_NOSPACE);
		}
		else {
			resp = buf;
			for(i=0;i<len;i++,addr++)
				resp += sprintf((char *)resp,"%02x",*addr);
			gdb_response((char *)buf);
		}
	}
	else
		gdb_ok();
	return(0);
}
Пример #22
0
/* gdb_X():
 * Similar to gdb_M() except that the data is in binary.
 * The characters '$', '#' and 0x7d are escaped using 0x7d.
 */
int
gdb_X(char *line)
{
	int		len, i;
	char	*lp;
	uchar	*addr;
	
	addr = (uchar *)strtol(line+1,&lp,16);
	len = (int)strtol(lp+1,&lp,16);
	lp++;

	for(i=0;i<len;i++) {
		if ((*lp == 0x7d) && 
			((*(lp+1) == 0x03) || (*(lp+1) == 0x04) || (*(lp+1) == 0x5d))) {
			*addr++ = *(lp+1) | 0x20;
			lp += 2;
		}
		else
			*addr++ = *lp++;
	}

	gdb_ok();
	return(0);
}
Пример #23
0
/* gdb_cmd():
 *	First function called out of the monitor's command interpreter.  It
 *	does a basic syntax verification and then passes parameters to the
 *	appropriate handler above.
 *	Incoming syntax is
 *
 *		$ CMD # CSUM (of CMD)
 *
 *	where:
 *		$		is the ascii '$' character (0x24)
 *		#		is the ascii '#' character (0x23)
 *		CMD		is some command line consisting of a command and arguments
 *		CSUM	is the checksum of the characters in CMD
 *
 *	for example:
 *		
 *		$m4015bc,2#5a
 *
 *	Returns...
 *		 0 if command is not processed;
 *		 1 if command is processed;
 *		-1 if command is processed but has an error;
 *
 *	If this code detects an error, then send an error code back to GDB.
 *	According to the article, there are no defined error codes in GDB so
 *	we will use the following...
 *		1 	indicates a missing '#' at the end of the incoming cmd string.
 *		2 	indicates a bad checksum calculation.
 *		3 	indicates some command processing error.
 *		4 	indicates bad 'X' command parsing.
 */
int
gdb_cmd(uchar *line)
{
	char 	*comma, *colon, *cp, *bp, buf[32];
	int		len, clen, err, i;
	uchar	mycsum, incsum;

	gdbContinueFptr = (void(*)())0;

	/* If the command is 'X', then we have to treat it "special" because
	 * it contains binary data...
	 */
	if (line[1] == 'X') {
		comma = strchr((char *)line,',');
		colon = strchr((char *)line,':');
		if ((comma) && (colon)) {
			bp = buf;
			cp = (char *)line;
			while(cp <= colon)
				*bp++ = *cp++;
			*bp = 0;
			gdbTrace("GDB_CMD: '%s'\n",buf);
		}
		else {
			gdbTrace("GDB_CMD: 'X'\n");
			gdb_err(GDBERR_BADXFMT);	/* Unexpected 'X' command format */
		}
	}
	else if (line[0] == 0x03) {
		gdbTrace("GDB_CTRLC\n");
		gdb_sig(2);
		return(1);
	}
	else {
		gdbTrace("GDB_CMD: '%s'\n",line);
		len = strlen((char *)line);

		if (line[len-3] != '#') {
			gdb_err(GDBERR_NOHASH);		/* Missing ending '#' */
			return(-1);
		}

		clen = len - 3;
		mycsum = 0;
		for(i=1;i<clen;i++)
			mycsum += line[i];

		incsum = (uchar)strtol((char *)line+len-2,(char **)0,16);
		if (mycsum != incsum) {
			gdb_err(GDBERR_BADCSUM);	/* Checksum failure */
			return(-1);
		}
	}

	err = 0;
	line++;
	switch(*line) {
		case 'm':		/* Memory read */
			err = gdb_m((char *)line);
			break;
		case 'M':		/* Memory write (Ascii-coded-hex) */
			err = gdb_M((char *)line);
			break;
		case 'X':		/* Memory write (Binary) */
			err = gdb_X((char *)line);
			break;
		case 's':		/* Step */
			gdb_response("S05");
			break;
		case 'c':		/* Continue */
			gdb_c((char *)line);
			break;
		case '?':		/* Last signal */
			gdb_response("S05");
			break;
		case 'g':		/* get all registers */
			gdb_g((char *)line);
			break;
		case 'q':		/* Query */
			gdb_q((char *)line);
			break;
		case 'P':		/* PRR=HHHHHHHH... reg*/
			gdb_P((char *)line);
			break;
		case 'H':		/* Thread */
			gdb_ok();
			break;
		case 'k':		/* Quit */
			gdb_ok();
			break;
		default:		/* Unknown... return empty response. */
			gdb_response("");
			break;
	}
	if (err) {
		gdb_err(GDBERR_GENERR);			/* Command processing error */
	}
	return(1);
}
Пример #24
0
static void gdb_vmm_set_lbr(uint8_t __unused__ *data, size_t __unused__ len)
{
   __enable_lbr();
   gdb_ok();
}
Пример #25
0
static void gdb_vmm_del_lbr(uint8_t __unused__ *data, size_t __unused__ len)
{
   __disable_lbr();
   gdb_ok();
}
Пример #26
0
static void gdb_vmm_del_active_cr3(uint8_t __unused__ *data, size_t __unused__ len)
{
   ctrl_active_cr3_disable();
   gdb_ok();
}