⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remote.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	int unused_regno;{	int regno, len, rlen, ack;	u_char *cp, *ep;	regno = -1;	do {		outbuffer[0] = regno + 1;		ack = m_xchg(remote_cache_valid ?		    KGDB_REG_R|KGDB_DELTA : KGDB_REG_R,		    outbuffer, 1, inbuffer, &len);		cp = inbuffer;		ep = cp + len;		while (cp < ep) {			regno = *cp++;			rlen = REGISTER_RAW_SIZE(regno);			bcopy((caddr_t)cp,			    &reg_cache[REGISTER_BYTE(regno)], rlen);			cp += rlen;		}	} while (ack & KGDB_MORE);	remote_cache_valid = 1;	bcopy(reg_cache, registers, REGISTER_BYTES);}/* * Store the remote registers from the contents of the block REGS. *//* XXX Currently we just read all the registers, so we don't use regno.  *//* ARGSUSED */voidremote_store_registers(unused_regno)	int unused_regno;{	char *regs = registers;	u_char *cp, *ep;	int regno, off, rlen;	cp = outbuffer;	ep = cp + remote_fn.maxdata;	for (regno = 0; regno < NUM_REGS; ++regno) {		off = REGISTER_BYTE(regno);		rlen = REGISTER_RAW_SIZE(regno);		if (!remote_cache_valid ||		    bcmp(&regs[off], &reg_cache[off], rlen) != 0) {			if (cp + rlen + 1 >= ep) {				(void)m_xchg(KGDB_REG_W,				    outbuffer, cp - outbuffer,				    (u_char *)0, (int *)0);				cp = outbuffer;			}			*cp++ = regno;			bcopy(&regs[off], (caddr_t)cp, rlen);			cp += rlen;		}	}	if (cp != outbuffer)		(void)m_xchg(KGDB_REG_W, outbuffer, cp - outbuffer,		    (u_char *)0, (int *)0);	bcopy(regs, reg_cache, REGISTER_BYTES);}/* * XXX DOES THE NEW PROTOCOL NEED THIS? * Prepare to store registers.  Since we send them all, we have to * read out the ones we don't want to change first. */void remote_prepare_to_store (){	remote_fetch_registers(-1);}/* * Store a chunk of memory into the remote host. * 'remote_addr' is the address in the remote memory space. * 'cp' is the address of the buffer in our space, and 'len' is * the number of bytes.  Returns an errno status. */intremote_write(addr, cp, len)	CORE_ADDR addr;	u_char *cp;	int len;{	int cnt;	while (len > 0) {		/* XXX assumes sizeof(CORE_ADDR) is 4? */		cnt = min(len, remote_fn.maxdata - 4);		bcopy((caddr_t)&addr, (caddr_t)outbuffer, 4);		SWAP_TARGET_AND_HOST(outbuffer, 4);		bcopy((caddr_t)cp, (caddr_t)outbuffer + 4, cnt);		(void)m_xchg(KGDB_MEM_W, outbuffer, cnt + 4, inbuffer, &len);		if (inbuffer[0])			return (inbuffer[0]);		addr += cnt;		cp += cnt;		len -= cnt;	}	return 0;}/* * Read memory data directly from the remote machine. * 'addr' is the address in the remote memory space. * 'cp' is the address of the buffer in our space, and 'len' is * the number of bytes.  Returns an errno status. *//* XXX is this really needed? */static intremote_read(addr, cp, len)	CORE_ADDR addr;	u_char *cp;	int len;{	int cnt, inlen;	while (len > 0) {		cnt = min(len, remote_fn.maxdata);		outbuffer[0] = cnt;		bcopy((caddr_t)&addr, (caddr_t)&outbuffer[1], 4);		SWAP_TARGET_AND_HOST(&outbuffer[1], 4);		(void)m_xchg(KGDB_MEM_R, outbuffer, 5, inbuffer, &inlen);		if (inlen < 1)			error("remote_read(): remote protocol botch");		/* Return errno from remote side */		if (inbuffer[0])			return (inbuffer[0]);		--inlen;		if (inlen <= 0)			error("remote_read(): inlen too small (%d)", inlen);		if (inlen > cnt) {			printf(		"remote_read(): warning: asked for %d, got %d\n",			    cnt, inlen);			inlen = cnt;		}		bcopy((caddr_t)&inbuffer[1], (caddr_t)cp, inlen);		addr += inlen;		cp += inlen;		len -= inlen;	}	return (0);}static intremote_read_text(addr, cp, len, target)	CORE_ADDR addr;	char *cp;	int len;	struct target_ops *target;{	register int cc;	/*	 * Look down the target stack (we're on top) for the text file.	 * If it can transfer the whole chunk, let it.  Otherwise,	 * revert to the remote call.	 */	for (; target != 0; target = target->to_next) {		if (target->to_stratum != file_stratum)			continue;		cc = target->to_xfer_memory(addr, cp, len, 0, target);		if (cc == len)			return (0);	}			return (remote_read(addr, cp, len));}/* * Read or write LEN bytes from inferior memory at MEMADDR, transferring * to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is * nonzero.  Returns length of data written or read; 0 for error. *//* ARGSUSED */intremote_xfer_memory(addr, cp, len, should_write, target)	register CORE_ADDR addr;	register char *cp;	register int len;	int should_write;	struct target_ops *target;{	register int st;	if (should_write)		st = remote_write(addr, cp, len);	else {#ifdef NEED_TEXT_START_END		extern CORE_ADDR text_start, text_end;		st = (icache && addr >= text_start && addr + len <= text_end) ?			remote_read_text(addr, cp, len, target) :			remote_read(addr, cp, len);#else		st = remote_read(addr, cp, len);#endif	}	return ((st == 0) ? len : 0);}/* * Signal the remote machine.  The remote end might be idle or it might * already be in debug mode -- we need to handle both case.  Thus, we use * the framing character as the wakeup byte, and send a SIGNAL packet. * If the remote host is idle, the framing character will wake it up. * If it is in the kgdb stub, then we will get a SIGNAL reply. */static voidremote_signal(){	if (!remote_debugging)		printf("Remote agent not active.\n");	else {		remote_instub = 0;		m_send(KGDB_SIGNAL, (u_char *)0, 0);	}}static voidremote_signal_command(){	if (!remote_debugging)		error("Remote agent not active.\n");	remote_cache_valid = 0;	remote_signal();	restart_remote();}/* * Print a message for debugging. */static voidprint_msg(type, buf, len, dir)	int type;	u_char *buf;	int len;	int dir;{	int i;	char *s;	switch (KGDB_CMD(type)) {	case KGDB_MEM_R:	s = "memr"; break;	case KGDB_MEM_W:	s = "memw"; break;	case KGDB_REG_R:	s = "regr"; break;	case KGDB_REG_W:	s = "regw"; break;	case KGDB_CONT:		s = "cont"; break;	case KGDB_STEP:		s = "step"; break;	case KGDB_KILL:		s = "kill"; break;	case KGDB_SIGNAL:	s = "sig "; break;	case KGDB_EXEC:		s = "exec"; break;	default:		s = "unk "; break;	}	remote_debug("%c %c%c%c%c %s (%02x): ", dir,	    (type & KGDB_ACK) ? 'A' : '.',	    (type & KGDB_DELTA) ? 'D' : '.',	    (type & KGDB_MORE) ? 'M' : '.',	    (type & KGDB_SEQ) ? '-' : '+',	    s, type);	if (buf)		for (i = 0; i < len; ++i)			remote_debug("%02x", buf[i]);	remote_debug("\n");}static voidremote_debug_command(arg, from_tty)	char *arg;	int from_tty;{	char *name;	if (kiodebug != 0 && kiodebug != stderr)		(void)fclose(kiodebug);	if (arg == 0) {		kiodebug = 0;		printf("Remote debugging off.\n");		return;	}	if (arg[0] == '-') {		kiodebug = stderr;		name = "stderr";	} else {		kiodebug = fopen(arg, "w");		if (kiodebug == 0) {			printf("Cannot open '%s'.\n", arg);			return;		}		name = arg;	}	printf("Remote debugging output routed to %s.\n", name);}/* ARGSUSED */static voidremote_files_info(){	printf("Using %s for text references.\n",		icache? "local executable" : "remote");	printf("Protocol debugging is %s.\n", kiodebug? "on" : "off");	printf("%d spurious input messages.\n", remote_spurious);	printf("%d input errors; %d output errors; %d sequence errors.\n",	    remote_ierrs, remote_oerrs, remote_seqerrs);}/* VARARGS */static voidremote_debug(va_alist)	va_dcl{	register char *cp;	va_list ap;	va_start(ap);	cp = va_arg(ap, char *);	(void)vfprintf(kiodebug, cp, ap);	va_end(ap);	fflush(kiodebug);}/* Define the target subroutine names */struct target_ops remote_ops = {	"remote",			/* shortname */	"Remote serial target in gdb-specific protocol", /* longname */	"Debug a remote host, using a gdb-specific protocol.\n\Specify the target as an argument (e.g. /dev/ttya for a serial link).\n\Use \"detach\" or \"quit\" to end remote debugging gracefully, which\n\removes breakpoints from and resumes the remote kernel.\n\Use \"detach quiet\" to end remote debugging with no negotiation.\n\This latter method is desirable, for instance, when the remote kernel\n\has crashed and messages from gdb could wreak havoc.\n",	remote_open,		/* open */	remote_close,		/* close */	0,			/* attach */	remote_detach,		/* detach */	remote_resume,		/* resume */	remote_wait,		/* wait */	remote_fetch_registers,	/* fetch_registers */	remote_store_registers,	/* store_registers */	remote_prepare_to_store, /* prepare_to_store */	remote_xfer_memory,	/* xfer_memory */	remote_files_info,	/* files_info */	0,			/* insert_breakpoint */	0,			/* remove_breakpoint */	0,			/* terminal_init */	0,			/* terminal_inferior */	0,			/* terminal_ours_for_output */	0,			/* terminal_ours */	0,			/* terminal_info */	remote_kill,		/* kill */	0,			/* load */	0,			/* lookup_symbol */	0,			/* create_inferior */	0,			/* mourn_inferior */	0,			/* can_run */	0,			/* notice_signals */	process_stratum,	/* stratum */	0,			/* next */	1,			/* has_all_memory */	1,			/* has_memory */	1,			/* has_stack */	1,			/* has_registers */	1,			/* has_execution XXX can't start an inferior */	0,			/* sections */	0,			/* sections_end */	OPS_MAGIC,		/* magic */};void_initialize_remote (){	struct cmd_list_element *c;	extern struct cmd_list_element *setlist;	add_com("remote-signal", class_run, remote_signal_command,		"If remote debugging, send interrupt signal to remote.");	c = add_set_cmd ("remote-text-refs", class_support, var_boolean,			 (char *)&icache,"Set use of local executable for text segment references.\n\If on, all memory read/writes go to remote.\n\If off, text segment reads use the local executable.",		&setlist);	add_show_from_set (c, &showlist);	c = add_set_cmd ("remote-timeout", class_support, var_uinteger,			 (char *)&to_base,"Set remote timeout interval (in msec).  The gdb remote protocol\n\uses an exponential backoff retransmit timer that begins initialized\n\to this value (on each transmission).",		&setlist);	add_show_from_set (c, &showlist);	add_com("remote-debug", class_run, remote_debug_command,"With a file name argument, enables output of remote protocol debugging\n\messages to said file.  If file is `-', stderr is used.\n\With no argument, remote debugging is disabled.");#ifdef notdef	add_info("remote", remote_info,		 "Show current settings of remote debugging options.");#endif	add_target (&remote_ops);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -