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

📄 kgdb.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        /* Terminate properly. */	*buf = '\0';	return (buf);}/* Convert the array, in hexadecimal representation, pointed to by buf into   binary representation. Put the result in mem, and return a pointer to   the character after the last byte written. */static unsigned char*hex2mem (unsigned char *mem, char *buf, int count){	int i;	unsigned char ch;	for (i = 0; i < count; i++) {		ch = hex (*buf++) << 4;		ch = ch + hex (*buf++);		*mem++ = ch;	}	return (mem);}/* Put the content of the array, in binary representation, pointed to by buf   into memory pointed to by mem, and return a pointer to the character after   the last byte written.   Gdb will escape $, #, and the escape char (0x7d). */static unsigned char*bin2mem (unsigned char *mem, unsigned char *buf, int count){	int i;	unsigned char *next;	for (i = 0; i < count; i++) {		/* Check for any escaped characters. Be paranoid and		   only unescape chars that should be escaped. */		if (*buf == 0x7d) {			next = buf + 1;			if (*next == 0x3 || *next == 0x4 || *next == 0x5D) /* #, $, ESC */				{					buf++;					*buf += 0x20;				}		}		*mem++ = *buf++;	}	return (mem);}/* Await the sequence $<data>#<checksum> and store <data> in the array buffer   returned. */static voidgetpacket (char *buffer){	unsigned char checksum;	unsigned char xmitcsum;	int i;	int count;	char ch;	do {		while ((ch = getDebugChar ()) != '$')			/* Wait for the start character $ and ignore all other characters */;		checksum = 0;		xmitcsum = -1;		count = 0;		/* Read until a # or the end of the buffer is reached */		while (count < BUFMAX) {			ch = getDebugChar ();			if (ch == '#')				break;			checksum = checksum + ch;			buffer[count] = ch;			count = count + 1;		}		buffer[count] = '\0';				if (ch == '#') {			xmitcsum = hex (getDebugChar ()) << 4;			xmitcsum += hex (getDebugChar ());			if (checksum != xmitcsum) {				/* Wrong checksum */				putDebugChar ('-');			}			else {				/* Correct checksum */				putDebugChar ('+');				/* If sequence characters are received, reply with them */				if (buffer[2] == ':') {					putDebugChar (buffer[0]);					putDebugChar (buffer[1]);					/* Remove the sequence characters from the buffer */					count = gdb_cris_strlen (buffer);					for (i = 3; i <= count; i++)						buffer[i - 3] = buffer[i];				}			}		}	} while (checksum != xmitcsum);}/* Send $<data>#<checksum> from the <data> in the array buffer. */static voidputpacket(char *buffer){	int checksum;	int runlen;	int encode;		do {		char *src = buffer;		putDebugChar ('$');		checksum = 0;		while (*src) {			/* Do run length encoding */			putDebugChar (*src);			checksum += *src;			runlen = 0;			while (runlen < RUNLENMAX && *src == src[runlen]) {				runlen++;			}			if (runlen > 3) {				/* Got a useful amount */				putDebugChar ('*');				checksum += '*';				encode = runlen + ' ' - 4;				putDebugChar (encode);				checksum += encode;				src += runlen;			}			else {				src++;			}		}		putDebugChar ('#');		putDebugChar (highhex (checksum));		putDebugChar (lowhex (checksum));	} while(kgdb_started && (getDebugChar() != '+'));}/* The string str is prepended with the GDB printout token and sent. Required   in traditional implementations. */voidputDebugString (const unsigned char *str, int length){        remcomOutBuffer[0] = 'O';        mem2hex(&remcomOutBuffer[1], (unsigned char *)str, length);        putpacket(remcomOutBuffer);}/********************************** Handle exceptions ************************//* Build and send a response packet in order to inform the host the   stub is stopped. TAAn...:r...;n...:r...;n...:r...;                    AA = signal number                    n... = register number (hex)                    r... = register contents                    n... = `thread'                    r... = thread process ID.  This is a hex integer.                    n... = other string not starting with valid hex digit.                    gdb should ignore this n,r pair and go on to the next.                    This way we can extend the protocol. */static voidstub_is_stopped(int sigval){	char *ptr = remcomOutBuffer;	int regno;	unsigned int reg_cont;	int status;        	/* Send trap type (converted to signal) */	*ptr++ = 'T';		*ptr++ = highhex (sigval);	*ptr++ = lowhex (sigval);	/* Send register contents. We probably only need to send the	 * PC, frame pointer and stack pointer here. Other registers will be	 * explicitely asked for. But for now, send all. 	 */		for (regno = R0; regno <= USP; regno++) {		/* Store n...:r...; for the registers in the buffer. */                status = read_register (regno, &reg_cont);                		if (status == SUCCESS) {                                                *ptr++ = highhex (regno);                        *ptr++ = lowhex (regno);                        *ptr++ = ':';                        ptr = mem2hex(ptr, (unsigned char *)&reg_cont,                                      register_size[regno]);                        *ptr++ = ';';                }                	}#ifdef PROCESS_SUPPORT	/* Store the registers of the executing thread. Assume that both step,	   continue, and register content requests are with respect to this	   thread. The executing task is from the operating system scheduler. */	current_thread_c = executing_task;	current_thread_g = executing_task;	/* A struct assignment translates into a libc memcpy call. Avoid	   all libc functions in order to prevent recursive break points. */	copy_registers (&reg_g, &reg, sizeof(registers));	/* Store thread:r...; with the executing task TID. */	gdb_cris_strcpy (&remcomOutBuffer[pos], "thread:");	pos += gdb_cris_strlen ("thread:");	remcomOutBuffer[pos++] = highhex (executing_task);	remcomOutBuffer[pos++] = lowhex (executing_task);	gdb_cris_strcpy (&remcomOutBuffer[pos], ";");#endif	/* null-terminate and send it off */	*ptr = 0;	putpacket (remcomOutBuffer);}/* All expected commands are sent from remote.c. Send a response according   to the description in remote.c. */static voidhandle_exception (int sigval){	/* Avoid warning of not used. */	USEDFUN(handle_exception);	USEDVAR(internal_stack[0]);	/* Send response. */	stub_is_stopped (sigval);	for (;;) {		remcomOutBuffer[0] = '\0';		getpacket (remcomInBuffer);		switch (remcomInBuffer[0]) {			case 'g':				/* Read registers: g				   Success: Each byte of register data is described by two hex digits.				   Registers are in the internal order for GDB, and the bytes				   in a register  are in the same order the machine uses.				   Failure: void. */								{#ifdef PROCESS_SUPPORT					/* Use the special register content in the executing thread. */					copy_registers (&reg_g, &reg, sizeof(registers));					/* Replace the content available on the stack. */					if (current_thread_g != executing_task) {						copy_registers_from_stack (current_thread_g, &reg_g);					}					mem2hex ((unsigned char *)remcomOutBuffer, (unsigned char *)&reg_g, sizeof(registers));#else					mem2hex(remcomOutBuffer, (char *)&reg, sizeof(registers));#endif				}				break;							case 'G':				/* Write registers. GXX..XX				   Each byte of register data  is described by two hex digits.				   Success: OK				   Failure: void. */#ifdef PROCESS_SUPPORT				hex2mem ((unsigned char *)&reg_g, &remcomInBuffer[1], sizeof(registers));				if (current_thread_g == executing_task) {					copy_registers (&reg, &reg_g, sizeof(registers));				}				else {					copy_registers_to_stack(current_thread_g, &reg_g);				}#else				hex2mem((char *)&reg, &remcomInBuffer[1], sizeof(registers));#endif				gdb_cris_strcpy (remcomOutBuffer, "OK");				break;							case 'P':				/* Write register. Pn...=r...				   Write register n..., hex value without 0x, with value r...,				   which contains a hex value without 0x and two hex digits				   for each byte in the register (target byte order). P1f=11223344 means				   set register 31 to 44332211.				   Success: OK				   Failure: E02, E05 */				{					char *suffix;					int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);					int status;#ifdef PROCESS_SUPPORT					if (current_thread_g != executing_task)						status = write_stack_register (current_thread_g, regno, suffix+1);					else#endif						status = write_register (regno, suffix+1);					switch (status) {						case E02:							/* Do not support read-only registers. */							gdb_cris_strcpy (remcomOutBuffer, error_message[E02]);							break;						case E05:							/* Do not support non-existing registers. */							gdb_cris_strcpy (remcomOutBuffer, error_message[E05]);							break;						case E07:							/* Do not support non-existing registers on the stack. */							gdb_cris_strcpy (remcomOutBuffer, error_message[E07]);							break;						default:							/* Valid register number. */							gdb_cris_strcpy (remcomOutBuffer, "OK");							break;					}				}				break;							case 'm':				/* Read from memory. mAA..AA,LLLL				   AA..AA is the address and LLLL is the length.				   Success: XX..XX is the memory content.  Can be fewer bytes than				   requested if only part of the data may be read. m6000120a,6c means				   retrieve 108 byte from base address 6000120a.				   Failure: void. */				{                                        char *suffix;					unsigned char *addr = (unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],                                                                                               &suffix, 16);                                        int length = gdb_cris_strtol(suffix+1, 0, 16);                                                                                mem2hex(remcomOutBuffer, addr, length);                                }				break;							case 'X':				/* Write to memory. XAA..AA,LLLL:XX..XX				   AA..AA is the start address,  LLLL is the number of bytes, and				   XX..XX is the binary data.				   Success: OK				   Failure: void. */			case 'M':				/* Write to memory. MAA..AA,LLLL:XX..XX				   AA..AA is the start address,  LLLL is the number of bytes, and				   XX..XX is the hexadecimal data.				   Success: OK				   Failure: void. */				{					char *lenptr;					char *dataptr;					unsigned char *addr = (unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],										      &lenptr, 16);					int length = gdb_cris_strtol(lenptr+1, &dataptr, 16);					if (*lenptr == ',' && *dataptr == ':') {						if (remcomInBuffer[0] == 'M') {							hex2mem(addr, dataptr + 1, length);						}						else /* X */ {							bin2mem(addr, dataptr + 1, length);						}						gdb_cris_strcpy (remcomOutBuffer, "OK");					}					else {						gdb_cris_strcpy (remcomOutBuffer, error_message[E06]);					}				}				break;							case 'c':				/* Continue execution. cAA..AA				   AA..AA is the address where execution is resumed. If AA..AA is				   omitted, resume at the present address.				   Success: return to the executing thread.				   Failure: will never know. */				if (remcomInBuffer[1] != '\0') {					reg.pc = gdb_cris_strtol (&remcomInBuffer[1], 0, 16);				}				enableDebugIRQ();				return;							case 's':				/* Step. sAA..AA				   AA..AA is the address where execution is resumed. If AA..AA is				   omitted, resume at the present address. Success: return to the				   executing thread. Failure: will never know.				   				   Should never be invoked. The single-step is implemented on				   the host side. If ever invoked, it is an internal error E04. */				gdb_cris_strcpy (remcomOutBuffer, error_message[E04]);

⌨️ 快捷键说明

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