static void enhanced_gdb_listing_cmd(char *arg, int from_tty, int cmdNbr,
				     void (*cmd)(char*, int))
{
    if (from_tty && isatty(STDOUT_FILENO) && gdb_get_int("$__prevcmd__") == cmdNbr) {
    	if (!macsbug_screen) {
    	    if (!(arg && *arg))
    	    	gdb_printf(CURSOR_UP CLEAR_LINE, 2);
    	} else if (macsbug_screen && arg && *arg)
    	    gdb_printf("\n");
    }

    if (macsbug_screen)
    	cmd(arg, from_tty);			/* just do cmd if we have screen	*/
    else {
    	GDB_FILE *redirect_stdout, *prev_stdout;

	redirect_stdout = gdb_open_output(stdout, listing_filter, &prev_stdout);
	prev_stdout = gdb_redirect_output(redirect_stdout);

	cmd(arg, from_tty);			/* filter output with listing_filter()	*/

	gdb_close_output(redirect_stdout);
    }

    gdb_set_int("$__lastcmd__", cmdNbr);
}
Exemple #2
0
static int run_final_status(struct gdb_data *data)
{
	address_t regs[DEVICE_NUM_REGS];
	int i;

	if (device_getregs(regs) < 0)
		return gdb_send(data, "E00");

	gdb_packet_start(data);
	gdb_printf(data, "T05");
	for (i = 0; i < 16; i++) {
		address_t value = regs[i];
		int j;

		/* NOTE: this only gives GDB the lower 16 bits of each
		 *       register. It complains if we give the full data.
		 */
		gdb_printf(data, "%02x:", i);
		for (j = 0; j < 2; j++) {
			gdb_printf(data, "%02x", value & 0xff);
			value >>= 8;
		}
		gdb_printf(data, ";");
	}
	gdb_packet_end(data);

	return gdb_flush_ack(data);
}
Exemple #3
0
static void send_message(char *message, int len) {
    if (len == 0) {
        len = strlen(message);
    }
    unsigned char checksum = compute_checksum(message, len);
    gdb_printf(GDB_RESPONSE_START "$%s#%02X", message, checksum);
    gdb_printf(GDB_RESPONSE_END);
}
Exemple #4
0
static int gdb_send_supported(struct gdb_data *data)
{
	gdb_packet_start(data);
	gdb_printf(data, "PacketSize=%x", GDB_MAX_XFER * 2);
	gdb_packet_end(data);
	return gdb_flush_ack(data);
}
Exemple #5
0
static int read_memory(struct gdb_data *data, char *text)
{
	char *length_text = strchr(text, ',');
	address_t length, addr;
	uint8_t buf[GDB_MAX_XFER];
	int i;

	if (!length_text) {
		printc_err("gdb: malformed memory read request\n");
		return gdb_send(data, "E00");
	}

	*(length_text++) = 0;

	length = strtoul(length_text, NULL, 16);
	addr = strtoul(text, NULL, 16);

	if (length > sizeof(buf))
		length = sizeof(buf);

	printc("Reading %4d bytes from 0x%04x\n", length, addr);

	if (device_readmem(addr, buf, length) < 0)
		return gdb_send(data, "E00");

	gdb_packet_start(data);
	for (i = 0; i < length; i++)
		gdb_printf(data, "%02x", buf[i]);
	gdb_packet_end(data);

	return gdb_flush_ack(data);
}
static void new_breakpoint(GDB_ADDRESS address, int enabled)
{
    int i;

    if (!enabled)				/* can this ever happen?		*/
    	return;

    i = find_breakpt(address);   		/* find the breakpoint			*/
    if (i >= 0)					/* if already recorded...		*/
    	return;					/* ...don't record duplicates		*/

    if (++bkpt_tbl_index >= bkpt_tbl_sz) {	/* add it to the bkpt_tbl		*/
        bkpt_tbl_sz += BKPT_DELTA;
	bkpt_tbl = gdb_realloc(bkpt_tbl, bkpt_tbl_sz * sizeof(GDB_ADDRESS));
    }
    bkpt_tbl[bkpt_tbl_index] = address;

    qsort(bkpt_tbl, bkpt_tbl_index+1, 		/* always keep table sorted		*/
          sizeof(GDB_ADDRESS), qsort_compar_bkpt);

    fix_pc_area_if_necessary(address);

    if (0)
	for (i = 0; i <= bkpt_tbl_index; ++i)
	    gdb_printf("after add: %2d. 0x%.8llX\n", i+1, (long long)bkpt_tbl[i]);
}
Exemple #7
0
static int monitor_command(struct gdb_data *data, char *buf)
{
	char cmd[128];
	int len = 0;
	int i;
	struct monitor_buf mbuf;

	while (len + 1 < sizeof(cmd) && *buf && buf[1]) {
		if (len + 1 >= sizeof(cmd))
			break;

		cmd[len++] = (hexval(buf[0]) << 4) | hexval(buf[1]);
		buf += 2;
	}
	cmd[len] = 0;

	printc("Monitor command received: %s\n", cmd);

	mbuf.len = 0;
	mbuf.trunc = 0;
	capture_start(monitor_capture, &mbuf);
	process_command(cmd);
	capture_end();

	if (!mbuf.len)
		return gdb_send(data, "OK");

	gdb_packet_start(data);
	for (i = 0; i < mbuf.len; i++)
		gdb_printf(data, "%02x", mbuf.buf[i]);
	gdb_packet_end(data);

	return gdb_flush_ack(data);
}
static void exit_handler(void)
{
    if (log_stream) {				/* close log file if it's open...	*/
	gdb_printf("Closing log\n");
	fclose(log_stream);
	log_stream = NULL;
    }

    position_cursor_for_shell_input();
}
static void set_arch(char *theSetting, Gdb_Set_Type type, void *value, int show, int confirm)
{
    static int len = sizeof(DEFAULT_TARGET_ARCH) + 1;

    if (new_arch && *new_arch)
    	if (strcmp(new_arch, "32") == 0) {
    	    target_arch = force_arch = 4;
	    need_CurApName = 1;
	    if (macsbug_screen && strcmp(prev_arch, new_arch) != 0)
		refresh(NULL, 0);
    	    else
    	    	define_macsbug_screen_positions(pc_area_lines, cmd_area_lines);
    	    strcpy(prev_arch, new_arch);
    	    gdb_printf("Display architecture always assumes 32-bit.\n");
    	} else if (strcmp(new_arch, "64") == 0) {
    	    target_arch = force_arch = 8;
    	   need_CurApName = 1;
	    if (macsbug_screen && strcmp(prev_arch, new_arch) != 0)
		refresh(NULL, 0);
    	    else
    	    	define_macsbug_screen_positions(pc_area_lines, cmd_area_lines);
    	    strcpy(prev_arch, new_arch);
    	    gdb_printf("Display architecture always assumes 64-bit.\n");
    	} else {
    	    new_arch = (char *)gdb_realloc(new_arch, strlen(prev_arch) + 1);
    	    strcpy(new_arch, prev_arch);
    	    gdb_error("invalid value - 32, or 64, or no value (for default) is expected");
    	}
    else {
    	new_arch = new_arch ? (char *)gdb_realloc(new_arch, len) : (char *)gdb_malloc(len);
    	force_arch  = 0;
    	target_arch = gdb_target_arch();
    	strcpy(new_arch,  DEFAULT_TARGET_ARCH);
	need_CurApName = 1;
	if (macsbug_screen && strcmp(prev_arch, new_arch) != 0)
	    refresh(NULL, 0);
	else
	    define_macsbug_screen_positions(pc_area_lines, cmd_area_lines);
	strcpy(prev_arch, new_arch);

    	gdb_printf("Display architecture is set according to inferior.\n");
    }
}
static void show_the_command(char *cmd, char *arg, int from_tty)
{
    if (arg && from_tty && macsbug_screen) {
    	gdb_printf("%s %s\n", cmd, arg);
	gdb_fflush(gdb_current_stdout);
    	gdb_define_raw_input_handler(my_raw_input_handler);
    	gdb_control_prompt_position(my_prompt_position_function);
    	gdb_set_raw_input_prompt_handler(my_raw_input_prompt_setter);
    }

    control_level = reading_raw = 1;
    gdb_set_int("$__lastcmd__", -1);
}
Exemple #11
0
/*
 * gdb_write_membytes:
 * Write bytes from the gdb client command buffer to our memory
 */
void
gdb_write_membytes(CPU_REGISTERS *ctx) {
    int 		addr;
	int			length;
    char		*ptr;
	char		*p;
	size_t		actual;
	size_t		valid;
	void		*trans;

    if(parse2hexnum(&inbuf[1],&addr,&length)) {
		ptr = strchr(inbuf,':') + 1; /* point 1 past the colon */
#ifdef DEBUG_GDB
		kprintf("Writemem: addr = %x\n", addr);
#endif
		p = ptr;
		for( ;; ) {
			trans = gdb_mapping_add(addr, length, PROT_READ|PROT_WRITE, &valid);
			if(trans == NULL) break;
			actual = min(valid, length);
			hex2mem(p, trans, actual);
			CPU_CACHE_FLUSH(trans, addr, actual);
			gdb_mapping_del(trans, valid);
			p += actual * 2;
			addr += actual;
			length -= actual;
			if(length == 0) break;
		}
		if((p == ptr) && (trans == NULL)) {
			strcpy(outbuf,"E03");
			if(gdb_debug) gdb_printf("bus error");
		}
    } else {
		strcpy(outbuf,"E02");
		if(gdb_debug) gdb_printf("malformed write memory command: %s",inbuf);
    } 
}
Exemple #12
0
/*
 * gdb_read_membytes:
 * Read bytes from our memory and return to gdb client
 */
void
gdb_read_membytes(CPU_REGISTERS *ctx) {
    int 		addr;
	int 		length;
	size_t		actual;
	char		*p;
	size_t		valid;
	void		*trans;

    if(parse2hexnum(&inbuf[1],&addr,&length)) {
#ifdef DEBUG_GDB
		kprintf("Readmem: addr = %x, ", addr);
		kprintf("data = %x\n", safe_read(addr));
#endif
		p = outbuf;
		for( ;; ) {
			trans = gdb_mapping_add(addr, length, PROT_READ, &valid);
			if(trans == NULL) break;
			if(valid == 0) break;
			actual = min(valid, length);
			mem2hex(trans, p, actual);
			gdb_mapping_del(trans, valid);
			p += actual * 2;
			addr += actual;
			length -= actual;
			if(length == 0) break;
		}
		if(p == outbuf && valid == 0) {
			strcpy(outbuf,"E03");
			if(gdb_debug) gdb_printf("bus error");
		}
    } else {
		strcpy(outbuf,"E01");
		if(gdb_debug) gdb_printf("malformed read memory command: %s", inbuf);
    }     
}
static void delete_breakpoint(GDB_ADDRESS address, int enabled)
{
    int i, j;

    i = find_breakpt(address);			/* find the breakpoint			*/
    if (i >= 0) {				/* if found, delete it...		*/
	 j = i++;				/* ...do it by moving all the items	*/
	 while (i <= bkpt_tbl_index)		/*    one entry lower in the bkpt_tbl	*/
	     bkpt_tbl[j++] = bkpt_tbl[i++];	/*    starting with 1 beyond the one 	*/
	 --bkpt_tbl_index;			/*    that was found			*/
    }

    fix_pc_area_if_necessary(address);

    if (0)
	for (i = 0; i <= bkpt_tbl_index; ++i)
	    gdb_printf("after delete: %2d. 0x%llX\n", i+1, (long long)bkpt_tbl[i]);
}
static void changed_breakpoint(GDB_ADDRESS address, int enabled)
{
    int i;

    i = find_breakpt(address);			/* find the breakpoint			*/
    if (i < 0) {				/* if not found...			*/
    	if (enabled)				/* ...if being enabled...		*/
    	    new_breakpoint(address, 1);		/* ...just recreate it in bkpt_tbl	*/
	return;
    }

    if (!enabled)				/* if found and being disabled...	*/
    	delete_breakpoint(address, 0);		/* ...delete it				*/

    if (0)
	for (i = 0; i <= bkpt_tbl_index; ++i)
	    gdb_printf("after change: %2d. 0x%llX\n", i+1, (long long)bkpt_tbl[i]);
}
Exemple #15
0
static int handle_gdb(void) {
    // Acknowledge packet
    gdb_printf(GDB_RESPONSE_START GDB_ACK GDB_RESPONSE_END "\n");
    // Get command and checksum
    int command_length = buf.checksum_index-1;
    char *command_ptr = &buf.data[COMMAND_START];
    char command[GETCHAR_BUFSIZ + 1] = {0};
    strncpy(command, command_ptr, command_length);
    char *checksum = &buf.data[buf.checksum_index + 1];
    // Calculate checksum of data
    if (DEBUG_PRINT) printf("command: %s\n", command);
    unsigned char computed_checksum = compute_checksum(command, command_length);
    unsigned char received_checksum = (unsigned char) strtol(checksum, NULL, HEX_STRING);
    if (computed_checksum != received_checksum) {
        if (DEBUG_PRINT) printf("Checksum error, computed %x, received %x received_checksum\n",
               computed_checksum, received_checksum);
    }
    // Parse the command
    handle_command(command);
    return 0;
}
Exemple #16
0
/*
 * gdb_show_exception_info:
 * Print out some information on the exception taken
 */
void
gdb_show_exception_info(ulong_t signal, CPU_REGISTERS *ctx) {
    gdb_printf("signal=%d, eip=%x\n", signal, ctx->eip);
}
Exemple #17
0
/*
 * This function does all command procesing for interfacing to gdb.
 */
static boolean
do_gdb_interface(struct kdebug_entry *entry, CPU_REGISTERS *ctx, ulong_t signal) {
    int    length;

struct kdebug_info		*kinfo;
const struct kdebug_private	*kprivate;
THREAD *thread;

    /* 
     * Indicate that we've gone back to debug mode
     */
    for (length = 0; length < 4; length++) dbg_putc('|');
	if(protocol == 0) {
		// generic GDB 4.16 wants the response to the continue/step
		// command sent before it transmits anything else.
		ksprintf(outbuf,"S%02xk", (unsigned)signal);
		putpacket();
	}

	while(getpacket()) {
		connected = TRUE;

		outbuf[0] = 0;

#ifdef DEBUG_GDB
kprintf("Processing packet '%s'\n", inbuf);		
#endif
        switch(inbuf[0]) {

		/* Tell the gdb client our signal number */
		case '?' :
			if(gdb_test_reloc_sem()) {
				paddr_t					base;
				char					*str = SYSPAGE_ENTRY(strings)->data;
				struct asinfo_entry		*as = SYSPAGE_ENTRY(asinfo);
		
				while(strcmp(&str[as->name], "imagefs") != 0) {
					++as;
				}
				base = gdb_image_base(as->start);
				gdb_clear_reloc_sem();
				ksprintf(outbuf,"N%02x%P;%P;%P",
					(unsigned)signal, base, base, (paddr_t)(base + as->end - as->start + 1));
			} else {
				ksprintf(outbuf,"S%02xk", (unsigned)signal);
			}
	
			for(length=1;outbuf[length];length++) {
				if((outbuf[length] >= 'A') && 
					(outbuf[length] <='Z'))
					outbuf[length]=outbuf[length]+('a'-'A');
			}
			if(gdb_debug) gdb_printf("%s", outbuf);
	
			break;
	
		/* toggle debug flag */
		case 'd' :
			gdb_debug = !(gdb_debug);
			break; 
		
		/* return the value of the CPU registers */
		case 'g' :
/* temp solution, need to add an offset item in kdebug_private for fpu data	*/
			if((kinfo = private->kdebug_info)== NULL || (kprivate = kinfo->kdbg_private) == NULL ||
				(thread = ((void **)kprivate->actives)[0]) == NULL) {
				gdb_get_cpuregs(ctx,NULL);
			} else {
				gdb_get_cpuregs(ctx,thread->fpudata);
			}
			break;
	
		/* set the value of the CPU registers - return OK */
		case 'G' : 
/* temp solution, need to add an offset item in kdebug_private for fpu data	*/
			if((kinfo = private->kdebug_info)== NULL || (kprivate = kinfo->kdbg_private) == NULL ||
				(thread = ((void **)kprivate->actives)[0]) == NULL) {
				gdb_set_cpuregs(ctx,NULL);
			} else {
				gdb_set_cpuregs(ctx,thread->fpudata);
			}
			strcpy(outbuf,"OK");
			break;

		/* get target information */
		case 'i':
			gdb_get_info();
			break;
		  
		/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
		case 'm' : 
			gdb_read_membytes(ctx);
			break;
		  
		/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
		case 'M' : 
			gdb_write_membytes(ctx);
			break;
		 
		/* cAA..AA    Continue at address AA..AA(optional) */
		case 'c' : 
			gdb_proc_continue(ctx, 0);	/* continue the process */
			return(TRUE);
	
		/* sAA..AA   Step one instruction from AA..AA(optional) */
		case 's' : 
			gdb_proc_continue(ctx, 1);	/* step one instruction */
			return(TRUE);

		/* q???? Generic query */	

		case 'q': 
			if(memcmp(&inbuf[1], "Rcmd,", 5) == 0) {
				// remote command
				char	*p;

				p = &inbuf[6];
				hex2mem(p, scratch, strlen(p));
				#define MEM_CMD	"mem "
				if(memcmp(scratch, MEM_CMD, sizeof(MEM_CMD)-1) == 0) {
					monitor_mem(&scratch[sizeof(MEM_CMD)-1]);
				}
			}
			break;

		/* k		Kill program */
		case 'k' :
			putpacket(); /*ACK the packet early (since we're going bye-bye) */
			gdb_prep_reboot();
			SYSPAGE_ENTRY(callout)->reboot(_syspage_ptr, 0);
			break;

		/* D		Detach from host */
		case 'D' :
			connected = FALSE;
			return(FALSE);
			  
		} /* switch */ 
static void help_command(char *arg, int from_tty)
{
    gdb_help_command(arg, from_tty);
    if (!arg)
    	gdb_printf("\nType \"help mb-notes\" or just \"mb-notes\" to get additional info about MacsBug.\n");
}
/*------------------------------------------*
 | macsbug_set - handle MacsBug SET options |
 *------------------------------------------*

 Common routine used by both mset() and all macsbug options that accept settings of the
 form:

   [m]set setting [on | off | now | show]

 The parameters to this function are:

   cmd		      "set" | "mset" | "dx"
   arg		      "" | on | off | now | show
   value	      pointer to int switch to be set according to option
   meaning            string to prefix "is [still] {en|dis}abled" messages
   confirm	      1 if SET/SHOW is entered from terminal and SET confirm on
   additional_stuff   NULL or function to call to do additional stuff when state changes
   		      The prototype for this function is:
   		      	additiona_stuff(int state, int confirm);

 As a standard gdb SET command the setting's arguments are handled as a arbitrary string
 to allow us to handle the case when no options are specified.  I'd like to use the enum
 form but that requires a argument.
*/
static void macsbug_set(char *cmd, char **arg, int *value, char *meaning, int confirm,
			void (*additional_stuff)(int state, int confirm))
{
    int  argc, err = 0;
    char *argv[4], tmpCmdLine[1024];

    static char *options[] = {"ON", "OFF", "NOW", "SHOW", NULL};

    gdb_setup_argv(safe_strcpy(tmpCmdLine, *arg), cmd, &argc, argv, 3);

    if (argc == 1) {
	if (*value) {
	    *value = 0;
	    if (additional_stuff)
	    	additional_stuff(0, confirm);
	    if (confirm)
	    	gdb_printf("%s is disabled.\n", meaning);
	} else {
	    *value = 1;
	    if (additional_stuff)
	    	additional_stuff(1, confirm);
	    if (confirm)
	    	gdb_printf("%s is enabled.\n", meaning);
	}
    } else if (argc == 2) {
	switch (gdb_keyword(argv[1], options)) {
	    case 0: /* on   */
		if (*value) {
		    if (confirm)
		    	gdb_printf("%s is still enabled.\n", meaning);
		} else {
		    *value = 1;
		    if (additional_stuff)
		    	additional_stuff(1, confirm);
		    if (confirm)
		    	gdb_printf("%s is enabled.\n", meaning);
		}
		break;
	    case 1: /* off  */
		if (*value) {
		    *value = 0;
		    if (additional_stuff)
		    	additional_stuff(0, confirm);
		    if (confirm)
		    	gdb_printf("%s is disabled.\n", meaning);
		} else if (confirm)
		    gdb_printf("%s is still disabled.\n", meaning);
		break;
	    case 2: /* now  */
	    case 3: /* show */
		if (*value)
		    gdb_printf("%s is still enabled.\n", meaning);
		else
		    gdb_printf("%s is still disabled.\n", meaning);
		break;
	    default:
		err = 1;
	}
    } else
	err = 1;

    gdb_set_int("$__lastcmd__", 40);

    if (*value)
    	if (*arg)
	    *arg = strcpy((char *)gdb_realloc(*arg, 3), "on");
	else
	    *arg = strcpy((char *)gdb_malloc(3), "on");
    else if (*arg)
	*arg = strcpy((char *)gdb_realloc(*arg, 4), "off");
    else
	*arg = strcpy((char *)gdb_malloc(4), "off");

    if (err)
    	gdb_error("\"on\", \"off\", \"now\", or \"show\" expected.");
}
Exemple #20
0
/* 
 * scan for the sequence $<data>#<checksum>
 */
boolean
getpacket() {
    unsigned char checksum;
    unsigned char xmitcsum;
    int  i;
    int  count;
    int ch;
	int cs1;
	int cs2;
	int	(*init_getc)(void);
  
 	init_getc = connected ? dbg_getc : dbg_getc_connect_check;
    for( ;; ) {
try_again:
		/* wait around for the start character, ignore all other characters */
		do {
			ch = init_getc();
			if(ch == -1) return(FALSE);
		} while(ch != '$');

try_again2:		
		checksum = 0;
		count = 0;
		cs1 = cs2 = 0;
		
		/* now, read until a # or end of buffer is found */
		for( ;; ) {
			if(count >= BUFMAX) goto try_again;
			ch = dbg_getc();
			if(ch == -1) return(FALSE);
			if(ch == '#') break;
			if(ch == '$') goto try_again2;
			checksum = checksum + ch;
			scratch[count++] = ch;
		}
		/* collect the checksum */
		cs1 = dbg_getc();
		if(cs1 == -1) return(FALSE);
		cs2 = dbg_getc();
		if(cs2 == -1) return(FALSE);

		scratch[count] = 0;
		gdb_expand(scratch, inbuf);
		
		xmitcsum = (chartohex(cs1) << 4) + chartohex(cs2);
		if(checksum == xmitcsum) break;
		if(gdb_debug) {
			gdb_printf("bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
			   checksum,xmitcsum,inbuf);
		}
		dbg_putc('-');  /* failed checksum */ 
    } 
	dbg_putc('+');  /* successful transfer */
	/* if a sequence char is present, reply the sequence ID */
	if(inbuf[2] == ':') {
		dbg_putc(inbuf[0]);
		dbg_putc(inbuf[1]);
		/* remove sequence chars from buffer */
		i = 3;
		for( ;; ) {
			inbuf[i-3] = inbuf[i];
			if(inbuf[i] == '\0') break;
			++i;
		}
	} 
    return(TRUE);
}