Пример #1
0
uint32_t GdbServer::Up (char *pbuf, uint32_t plen) {
  debug ("Up::%d:\"%s\"\n", plen, pbuf);
  lock.lock();
  size = plen;
continue_activity:
  switch (pbuf[0]) {
    case 0: {           // Ctrl - C
      debug ("GdbServer::Up Ctrl-C\n");
      target->halt_request ();
      last_activity = 's';
      break;
    }
      /* Implementation of these is mandatory! */
    case 'g': { /* 'g': Read general registers */
      if (!target_check ()) break;
      int rsize = target->get_regs_size();
      debug ("RSIZE = %d\n", rsize);
      uint8_t arm_regs [rsize];
      target->regs_read (arm_regs);
      /* Výstup po blocích délky max. 240 bytů byl vynucen větší déklou dat registrů
       * CortexM4F. Zdá se, že to funguje.
       */
      const int  chunk = 120;
      int block, start = 0;
      for (;;) {
        if (rsize > chunk) block = chunk; 
        else               block = rsize;
        char* tptr =  (char*) hexify (pbuf, (const unsigned char*) arm_regs + start, block);
        gdb_putpacket (tptr , block * 2);
        start += block;
        rsize -= block;
        if (!rsize) break;
      }
      break;
    }
    case 'm': { /* 'm addr,len': Read len bytes from addr */
      unsigned long addr, len;
      if (!target_check ()) break;
      sscanf ((char*)pbuf, "m%08lx,%08lx", &addr, &len);
      debug ("m packet: addr = %08lX, len = %08lX\n", addr, len);
      uint8_t mem[len];
      if ( ( (addr & 3) == 0) && ( (len & 3) == 0))
        target->mem_read_words ((uint32_t*) mem, addr, len);
      else
        target->mem_read_bytes (mem, addr, len);
      if (target->check_error ())
        gdb_putpacketz ("E01");
      else
        gdb_putpacket ((char*)hexify (pbuf, mem, len), len*2);
      break;
    }
    case 'G': { /* 'G XX': Write general registers */
      if (!target_check ()) break;
      int rsize = target->get_regs_size();
      uint8_t arm_regs [rsize];
      unhexify (arm_regs, (unsigned char*) &pbuf[1], rsize);
      target->regs_write (arm_regs);
      gdb_putpacketz ("OK");
      break;
    }
    case 'M': { /* 'M addr,len:XX': Write len bytes to addr */
      unsigned long addr, len;
      int hex;
      if (!target_check ()) break;
      sscanf ((char*)pbuf, "M%08lx,%08lx:%n", &addr, &len, &hex);
      debug ("M packet: addr = %08lX, len = %08lX\n", addr, len);
      uint8_t mem[len];
      unhexify (mem, (unsigned char*)pbuf + hex, len);
      if ( ( (addr & 3) == 0) && ( (len & 3) == 0))
        target->mem_write_words (addr, (const uint32_t*) mem, len);
      else
        target->mem_write_bytes (addr, mem, len);
      if (target->check_error ())
        gdb_putpacketz ("E01");
      else
        gdb_putpacketz ("OK");
      break;
    }
    
    case 's': /* 's [addr]': Single step [start at addr] */
      single_step = true;
      // Fall through to resume target
    case 'c': /* 'c [addr]': Continue [at addr] */
      if (!target) {
        gdb_putpacketz ("X1D");
        break;
      }
      target->halt_resume (single_step);
      single_step = false;
      // Fall through to wait for target halt
    case '?': { /* '?': Request reason for target halt */
      /* This packet isn't documented as being mandatory,
       * but GDB doesn't work without it. */

      if (!target) {
        /* Report "target exited" if no target */
        gdb_putpacketz ("W00");
        break;
      }
      if (!target->attached) {
        /* Report "target exited" if no target */
        gdb_putpacketz ("W00");
        break;
      }

      last_activity = pbuf[0];
      /* Wait for target halt */
      debug("? WAIT HALT\n");
      SetActive ();            // timto se prepne do mainloop, kde ceka na zastaveni
      break;
    }
    case 'F': { /* Semihosting call finished */
      int retcode, errcode, items;
      char c, *p;
      if (pbuf[1] == '-')
        p = (char*) &pbuf[2];
      else
        p = (char*) &pbuf[1];
      items = sscanf (p, "%x,%x,%c", &retcode, &errcode, &c);
      if (pbuf[1] == '-')
        retcode = -retcode;

      target->hostio_reply (retcode, errcode);

      /* if break is requested */
      if (items == 3 && c == 'C') {
        gdb_putpacketz ("T02");
        break;
      }

      pbuf[0] = last_activity;
      goto continue_activity;
    }

    /* Optional GDB packet support */
    case '!': /* Enable Extended GDB Protocol. */
      /* This doesn't do anything, we support the extended
       * protocol anyway, but GDB will never send us a 'R'
       * packet unless we answer 'OK' here.
       */
      gdb_putpacketz ("OK");
      break;

    case 0x04: // ???
      debug ("CASE 4 packet ???\n");
    case 'D': /* GDB 'detach' command. */
      if (target) {
        if (target->attached) {
          target->detach ();
          target->reset  ();
        }
      }
      gdb_putpacketz ("OK");
      break;

    case 'k': /* Kill the target */
      if (target) {
        target->detach ();
        target->reset  ();
      }
      break;

    case 'r': /* Reset the target system */
    case 'R': /* Restart the target program */
      if (target && target->attach()) {
        target->reset ();
        SetActive ();
      }
      break;

    case 'X': { /* 'X addr,len:XX': Write binary data to addr */
      unsigned long addr, len;
      int bin, icp;
      if (!target_check ()) break;
      sscanf ((char*)pbuf, "X%08lx,%08lx:%n", &addr, &len, &bin);
      // On Cortex-M0 word align param to write_words
      for (icp=0; icp<(int)len; icp++) pbuf[icp] = pbuf[icp + bin];
      
      debug ("X packet: addr = %08lX, len = %08lX\n", addr, len);
      if ( ( (addr & 3) == 0) && ( (len & 3) == 0))
        target->mem_write_words (addr, (const uint32_t*)  pbuf, len);
      else
        target->mem_write_bytes (addr, (unsigned char*) pbuf, len);
      if (target->check_error   ())
        gdb_putpacketz ("E01");
      else
        gdb_putpacketz ("OK");
      break;
    }

    case 'q': /* General query packet */
      handle_q_packet ((char*)pbuf, size);
      break;

    case 'v': /* General query packet */
      handle_v_packet ((char*)pbuf, size);
      break;

      /* These packet implement hardware break-/watchpoints */
    case 'Z': /* Z type,addr,len: Set breakpoint packet */
    case 'z': /* z type,addr,len: Clear breakpoint packet */
      if (!target_check ()) break;
      handle_z_packet ((char*)pbuf, size);
      break;

    default:  /* Packet not implemented */
      debug ("*** Unsupported packet: %s\n", pbuf);
      gdb_putpacketz ("");
  }
  lock.unlock();
  //return BaseLayer::Up (pbuf, plen);
  return plen;
}
Пример #2
0
void
gdb_main(void)
{
	int size;
	bool single_step = false;
	char last_activity = 0;

	DEBUG("Entring GDB protocol main loop\n");
	/* GDB protocol main loop */
	while(1) {
		SET_IDLE_STATE(1);
		size = gdb_getpacket(pbuf, BUF_SIZE);
		SET_IDLE_STATE(0);
	continue_activity:
		switch(pbuf[0]) {
		/* Implementation of these is mandatory! */
		case 'g': { /* 'g': Read general registers */
			ERROR_IF_NO_TARGET();
			uint8_t arm_regs[target_regs_size(cur_target)];
			target_regs_read(cur_target, arm_regs);
			gdb_putpacket(hexify(pbuf, arm_regs, sizeof(arm_regs)),
			              sizeof(arm_regs) * 2);
			break;
			}
		case 'm': {	/* 'm addr,len': Read len bytes from addr */
			uint32_t addr, len;
			ERROR_IF_NO_TARGET();
			sscanf(pbuf, "m%" SCNx32 ",%" SCNx32, &addr, &len);
			DEBUG("m packet: addr = %" PRIx32 ", len = %" PRIx32 "\n", addr, len);
			uint8_t mem[len];
			target_mem_read(cur_target, mem, addr, len);
			if(target_check_error(cur_target))
				gdb_putpacketz("E01");
			else
				gdb_putpacket(hexify(pbuf, mem, len), len*2);
			break;
			}
		case 'G': {	/* 'G XX': Write general registers */
			ERROR_IF_NO_TARGET();
			uint8_t arm_regs[target_regs_size(cur_target)];
			unhexify(arm_regs, &pbuf[1], sizeof(arm_regs));
			target_regs_write(cur_target, arm_regs);
			gdb_putpacketz("OK");
			break;
			}
		case 'M': { /* 'M addr,len:XX': Write len bytes to addr */
			uint32_t addr, len;
			int hex;
			ERROR_IF_NO_TARGET();
			sscanf(pbuf, "M%" SCNx32 ",%" SCNx32 ":%n", &addr, &len, &hex);
			DEBUG("M packet: addr = %" PRIx32 ", len = %" PRIx32 "\n", addr, len);
			uint8_t mem[len];
			unhexify(mem, pbuf + hex, len);
			target_mem_write(cur_target, addr, mem, len);
			if(target_check_error(cur_target))
				gdb_putpacketz("E01");
			else
				gdb_putpacketz("OK");
			break;
			}
		case 's':	/* 's [addr]': Single step [start at addr] */
			single_step = true;
			// Fall through to resume target
		case 'c':	/* 'c [addr]': Continue [at addr] */
			if(!cur_target) {
				gdb_putpacketz("X1D");
				break;
			}

			target_halt_resume(cur_target, single_step);
			SET_RUN_STATE(1);
			single_step = false;
			// Fall through to wait for target halt
		case '?': {	/* '?': Request reason for target halt */
			/* This packet isn't documented as being mandatory,
			 * but GDB doesn't work without it. */
			uint32_t watch_addr;
			int sig;

			if(!cur_target) {
				/* Report "target exited" if no target */
				gdb_putpacketz("W00");
				break;
			}

			last_activity = pbuf[0];
			/* Wait for target halt */
			while(!(sig = target_halt_wait(cur_target))) {
				unsigned char c = gdb_if_getchar_to(0);
				if((c == '\x03') || (c == '\x04')) {
					target_halt_request(cur_target);
					last_activity = 's';
				}
			}
			SET_RUN_STATE(0);

			/* Negative signal indicates we're in a syscall */
			if (sig < 0)
				break;

			/* Target disappeared */
			if (cur_target == NULL) {
				gdb_putpacket_f("X%02X", sig);
				break;
			}

			/* Report reason for halt */
			if(target_check_hw_wp(cur_target, &watch_addr)) {
				/* Watchpoint hit */
				gdb_putpacket_f("T%02Xwatch:%08X;", sig, watch_addr);
			} else {
				gdb_putpacket_f("T%02X", sig);
			}
			break;
			}
		case 'F': {	/* Semihosting call finished */
			int retcode, errcode, items;
			char c, *p;
			if (pbuf[1] == '-')
				p = &pbuf[2];
			else
				p = &pbuf[1];
			items = sscanf(p, "%x,%x,%c", &retcode, &errcode, &c);
			if (pbuf[1] == '-')
				retcode = -retcode;

			target_hostio_reply(cur_target, retcode, errcode);

			/* if break is requested */
			if (items == 3 && c == 'C') {
				gdb_putpacketz("T02");
				break;
			}

			pbuf[0] = last_activity;
			goto continue_activity;
		}

		/* Optional GDB packet support */
		case '!':	/* Enable Extended GDB Protocol. */
			/* This doesn't do anything, we support the extended
			 * protocol anyway, but GDB will never send us a 'R'
			 * packet unless we answer 'OK' here.
			 */
			gdb_putpacketz("OK");
			break;

		case 0x04:
		case 'D':	/* GDB 'detach' command. */
			if(cur_target)
				target_detach(cur_target);
			last_target = cur_target;
			cur_target = NULL;
			gdb_putpacketz("OK");
			break;

		case 'k':	/* Kill the target */
			if(cur_target) {
				target_reset(cur_target);
				target_detach(cur_target);
				last_target = cur_target;
				cur_target = NULL;
			}
			break;

		case 'r':	/* Reset the target system */
		case 'R':	/* Restart the target program */
			if(cur_target)
				target_reset(cur_target);
			else if(last_target) {
				cur_target = target_attach(last_target,
						gdb_target_destroy_callback);
				target_reset(cur_target);
			}
			break;

		case 'X': { /* 'X addr,len:XX': Write binary data to addr */
			uint32_t addr, len;
			int bin;
			ERROR_IF_NO_TARGET();
			sscanf(pbuf, "X%" SCNx32 ",%" SCNx32 ":%n", &addr, &len, &bin);
			DEBUG("X packet: addr = %" PRIx32 ", len = %" PRIx32 "\n", addr, len);
			target_mem_write(cur_target, addr, pbuf+bin, len);
			if(target_check_error(cur_target))
				gdb_putpacketz("E01");
			else
				gdb_putpacketz("OK");
			break;
			}

		case 'q':	/* General query packet */
			handle_q_packet(pbuf, size);
			break;

		case 'v':	/* General query packet */
			handle_v_packet(pbuf, size);
			break;

		/* These packet implement hardware break-/watchpoints */
		case 'Z':	/* Z type,addr,len: Set breakpoint packet */
		case 'z':	/* z type,addr,len: Clear breakpoint packet */
			ERROR_IF_NO_TARGET();
			handle_z_packet(pbuf, size);
			break;

		default: 	/* Packet not implemented */
			DEBUG("*** Unsupported packet: %s\n", pbuf);
			gdb_putpacketz("");
		}
	}
}
Пример #3
0
int gdb_main_loop(struct target_controller *tc, bool in_syscall)
{
	int size;
	bool single_step = false;

	/* GDB protocol main loop */
	while(1) {
		SET_IDLE_STATE(1);
		size = gdb_getpacket(pbuf, BUF_SIZE);
		SET_IDLE_STATE(0);
		switch(pbuf[0]) {
		/* Implementation of these is mandatory! */
		case 'g': { /* 'g': Read general registers */
			ERROR_IF_NO_TARGET();
			uint8_t arm_regs[target_regs_size(cur_target)];
			target_regs_read(cur_target, arm_regs);
			gdb_putpacket(hexify(pbuf, arm_regs, sizeof(arm_regs)),
			              sizeof(arm_regs) * 2);
			break;
			}
		case 'm': {	/* 'm addr,len': Read len bytes from addr */
			uint32_t addr, len;
			ERROR_IF_NO_TARGET();
			sscanf(pbuf, "m%" SCNx32 ",%" SCNx32, &addr, &len);
			if (len > sizeof(pbuf) / 2) {
				gdb_putpacketz("E02");
				break;
			}
			DEBUG("m packet: addr = %" PRIx32 ", len = %" PRIx32 "\n", addr, len);
			uint8_t mem[len];
			if (target_mem_read(cur_target, mem, addr, len))
				gdb_putpacketz("E01");
			else
				gdb_putpacket(hexify(pbuf, mem, len), len*2);
			break;
			}
		case 'G': {	/* 'G XX': Write general registers */
			ERROR_IF_NO_TARGET();
			uint8_t arm_regs[target_regs_size(cur_target)];
			unhexify(arm_regs, &pbuf[1], sizeof(arm_regs));
			target_regs_write(cur_target, arm_regs);
			gdb_putpacketz("OK");
			break;
			}
		case 'M': { /* 'M addr,len:XX': Write len bytes to addr */
			uint32_t addr, len;
			int hex;
			ERROR_IF_NO_TARGET();
			sscanf(pbuf, "M%" SCNx32 ",%" SCNx32 ":%n", &addr, &len, &hex);
			if (len > (unsigned)(size - hex) / 2) {
				gdb_putpacketz("E02");
				break;
			}
			DEBUG("M packet: addr = %" PRIx32 ", len = %" PRIx32 "\n", addr, len);
			uint8_t mem[len];
			unhexify(mem, pbuf + hex, len);
			if (target_mem_write(cur_target, addr, mem, len))
				gdb_putpacketz("E01");
			else
				gdb_putpacketz("OK");
			break;
			}
		case 's':	/* 's [addr]': Single step [start at addr] */
			single_step = true;
			/* fall through */
		case 'c':	/* 'c [addr]': Continue [at addr] */
			if(!cur_target) {
				gdb_putpacketz("X1D");
				break;
			}

			target_halt_resume(cur_target, single_step);
			SET_RUN_STATE(1);
			single_step = false;
			/* fall through */
		case '?': {	/* '?': Request reason for target halt */
			/* This packet isn't documented as being mandatory,
			 * but GDB doesn't work without it. */
			target_addr watch;
			enum target_halt_reason reason;

			if(!cur_target) {
				/* Report "target exited" if no target */
				gdb_putpacketz("W00");
				break;
			}

			/* Wait for target halt */
			while(!(reason = target_halt_poll(cur_target, &watch))) {
				unsigned char c = gdb_if_getchar_to(0);
				if((c == '\x03') || (c == '\x04')) {
					target_halt_request(cur_target);
				}
			}
			SET_RUN_STATE(0);

			/* Translate reason to GDB signal */
			switch (reason) {
			case TARGET_HALT_ERROR:
				gdb_putpacket_f("X%02X", GDB_SIGLOST);
				morse("TARGET LOST.", true);
				break;
			case TARGET_HALT_REQUEST:
				gdb_putpacket_f("T%02X", GDB_SIGINT);
				break;
			case TARGET_HALT_WATCHPOINT:
				gdb_putpacket_f("T%02Xwatch:%08X;", GDB_SIGTRAP, watch);
				break;
			case TARGET_HALT_FAULT:
				gdb_putpacket_f("T%02X", GDB_SIGSEGV);
				break;
			default:
				gdb_putpacket_f("T%02X", GDB_SIGTRAP);
			}
			break;
			}
		case 'F':	/* Semihosting call finished */
			if (in_syscall) {
				return hostio_reply(tc, pbuf, size);
			} else {
				DEBUG("*** F packet when not in syscall! '%s'\n", pbuf);
				gdb_putpacketz("");
			}
			break;

		/* Optional GDB packet support */
		case '!':	/* Enable Extended GDB Protocol. */
			/* This doesn't do anything, we support the extended
			 * protocol anyway, but GDB will never send us a 'R'
			 * packet unless we answer 'OK' here.
			 */
			gdb_putpacketz("OK");
			break;

		case 0x04:
		case 'D':	/* GDB 'detach' command. */
			if(cur_target)
				target_detach(cur_target);
			last_target = cur_target;
			cur_target = NULL;
			gdb_putpacketz("OK");
			break;

		case 'k':	/* Kill the target */
			if(cur_target) {
				target_reset(cur_target);
				target_detach(cur_target);
				last_target = cur_target;
				cur_target = NULL;
			}
			break;

		case 'r':	/* Reset the target system */
		case 'R':	/* Restart the target program */
			if(cur_target)
				target_reset(cur_target);
			else if(last_target) {
				cur_target = target_attach(last_target,
						           &gdb_controller);
				target_reset(cur_target);
			}
			break;

		case 'X': { /* 'X addr,len:XX': Write binary data to addr */
			uint32_t addr, len;
			int bin;
			ERROR_IF_NO_TARGET();
			sscanf(pbuf, "X%" SCNx32 ",%" SCNx32 ":%n", &addr, &len, &bin);
			if (len > (unsigned)(size - bin)) {
				gdb_putpacketz("E02");
				break;
			}
			DEBUG("X packet: addr = %" PRIx32 ", len = %" PRIx32 "\n", addr, len);
			if (target_mem_write(cur_target, addr, pbuf+bin, len))
				gdb_putpacketz("E01");
			else
				gdb_putpacketz("OK");
			break;
			}

		case 'q':	/* General query packet */
			handle_q_packet(pbuf, size);
			break;

		case 'v':	/* General query packet */
			handle_v_packet(pbuf, size);
			break;

		/* These packet implement hardware break-/watchpoints */
		case 'Z':	/* Z type,addr,len: Set breakpoint packet */
		case 'z':	/* z type,addr,len: Clear breakpoint packet */
			ERROR_IF_NO_TARGET();
			handle_z_packet(pbuf, size);
			break;

		default: 	/* Packet not implemented */
			DEBUG("*** Unsupported packet: %s\n", pbuf);
			gdb_putpacketz("");
		}
	}
}