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

📄 kgdb.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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);/* 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. */static unsigned char *bin2mem(unsigned char *mem, unsigned char *buf, int count);/* Await the sequence $<data>#<checksum> and store <data> in the array buffer   returned. */static void getpacket(char *buffer);/* Send $<data>#<checksum> from the <data> in the array buffer. */static void putpacket(char *buffer);/* Build and send a response packet in order to inform the host the   stub is stopped. */static void stub_is_stopped(int sigval);/* All expected commands are sent from remote.c. Send a response according   to the description in remote.c. Not static since it needs to be reached   from assembler code. */void handle_exception(int sigval);/* Performs a complete re-start from scratch. ETRAX specific. */static void kill_restart(void);/******************** Prototypes for global functions. ***********************//* The string str is prepended with the GDB printout token and sent. */void putDebugString(const unsigned char *str, int len);/* A static breakpoint to be used at startup. */void breakpoint(void);/* Avoid warning as the internal_stack is not used in the C-code. */#define USEDVAR(name)    { if (name) { ; } }#define USEDFUN(name) { void (*pf)(void) = (void *)name; USEDVAR(pf) }/********************************** Packet I/O ******************************//* BUFMAX defines the maximum number of characters in   inbound/outbound buffers *//* FIXME: How do we know it's enough? */#define BUFMAX 512/* Run-length encoding maximum length. Send 64 at most. */#define RUNLENMAX 64/* Definition of all valid hexadecimal characters */static const char hexchars[] = "0123456789abcdef";/* The inbound/outbound buffers used in packet I/O */static char input_buffer[BUFMAX];static char output_buffer[BUFMAX];/* Error and warning messages. */enum error_type{	SUCCESS, E01, E02, E03, E04, E05, E06,};static char *error_message[] ={	"",	"E01 Set current or general thread - H[c,g] - internal error.",	"E02 Change register content - P - cannot change read-only register.",	"E03 Thread is not alive.", /* T, not used. */	"E04 The command is not supported - [s,C,S,!,R,d,r] - internal error.",	"E05 Change register content - P - the register is not implemented..",	"E06 Change memory content - M - internal error.",};/********************************** Breakpoint *******************************//* Use an internal stack in the breakpoint and interrupt response routines.   FIXME: How do we know the size of this stack is enough?   Global so it can be reached from assembler code. */#define INTERNAL_STACK_SIZE 1024char internal_stack[INTERNAL_STACK_SIZE];/* Due to the breakpoint return pointer, a state variable is needed to keep   track of whether it is a static (compiled) or dynamic (gdb-invoked)   breakpoint to be handled. A static breakpoint uses the content of register   ERP as it is whereas a dynamic breakpoint requires subtraction with 2   in order to execute the instruction. The first breakpoint is static; all   following are assumed to be dynamic. */static int dynamic_bp = 0;/********************************* String library ****************************//* Single-step over library functions creates trap loops. *//* Copy char s2[] to s1[]. */static char*gdb_cris_strcpy(char *s1, const char *s2){	char *s = s1;	for (s = s1; (*s++ = *s2++) != '\0'; )		;	return s1;}/* Find length of s[]. */static intgdb_cris_strlen(const char *s){	const char *sc;	for (sc = s; *sc != '\0'; sc++)		;	return (sc - s);}/* Find first occurrence of c in s[n]. */static void*gdb_cris_memchr(const void *s, int c, int n){	const unsigned char uc = c;	const unsigned char *su;	for (su = s; 0 < n; ++su, --n)		if (*su == uc)			return (void *)su;	return NULL;}/******************************* Standard library ****************************//* Single-step over library functions creates trap loops. *//* Convert string to long. */static intgdb_cris_strtol(const char *s, char **endptr, int base){	char *s1;	char *sd;	int x = 0;	for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1)		x = x * base + (sd - hexchars);        if (endptr) {                /* Unconverted suffix is stored in endptr unless endptr is NULL. */                *endptr = s1;        }	return x;}/********************************* Register image ****************************//* Write a value to a specified register in the register image of the current   thread. Returns status code SUCCESS, E02 or E05. */static intwrite_register(int regno, char *val){	int status = SUCCESS;        if (regno >= R0 && regno <= ACR) {		/* Consecutive 32-bit registers. */		hex2mem((unsigned char *)&reg.r0 + (regno - R0) * sizeof(unsigned int),			val, sizeof(unsigned int));	} else if (regno == BZ || regno == VR || regno == WZ || regno == DZ) {		/* Read-only registers. */		status = E02;	} else if (regno == PID) {		/* 32-bit register. (Even though we already checked SRS and WZ, we cannot		   combine this with the EXS - SPC write since SRS and WZ have different size.) */		hex2mem((unsigned char *)&reg.pid, val, sizeof(unsigned int));	} else if (regno == SRS) {		/* 8-bit register. */		hex2mem((unsigned char *)&reg.srs, val, sizeof(unsigned char));	} else if (regno >= EXS && regno <= SPC) {		/* Consecutive 32-bit registers. */		hex2mem((unsigned char *)&reg.exs + (regno - EXS) * sizeof(unsigned int),			 val, sizeof(unsigned int));       } else if (regno == PC) {               /* Pseudo-register. Treat as read-only. */               status = E02;       } else if (regno >= S0 && regno <= S15) {               /* 32-bit registers. */               hex2mem((unsigned char *)&sreg.s0_0 + (reg.srs * 16 * sizeof(unsigned int)) + (regno - S0) * sizeof(unsigned int), val, sizeof(unsigned int));	} else {		/* Non-existing register. */		status = E05;	}	return status;}/* Read a value from a specified register in the register image. Returns the   value in the register or -1 for non-implemented registers. */static intread_register(char regno, unsigned int *valptr){	int status = SUCCESS;	/* We read the zero registers from the register struct (instead of just returning 0)	   to catch errors. */	if (regno >= R0 && regno <= ACR) {		/* Consecutive 32-bit registers. */		*valptr = *(unsigned int *)((char *)&reg.r0 + (regno - R0) * sizeof(unsigned int));	} else if (regno == BZ || regno == VR) {		/* Consecutive 8-bit registers. */		*valptr = (unsigned int)(*(unsigned char *)                                         ((char *)&reg.bz + (regno - BZ) * sizeof(char)));	} else if (regno == PID) {		/* 32-bit register. */		*valptr =  *(unsigned int *)((char *)&reg.pid);	} else if (regno == SRS) {		/* 8-bit register. */		*valptr = (unsigned int)(*(unsigned char *)((char *)&reg.srs));	} else if (regno == WZ) {		/* 16-bit register. */		*valptr = (unsigned int)(*(unsigned short *)(char *)&reg.wz);	} else if (regno >= EXS && regno <= PC) {		/* Consecutive 32-bit registers. */		*valptr = *(unsigned int *)((char *)&reg.exs + (regno - EXS) * sizeof(unsigned int));	} else if (regno >= S0 && regno <= S15) {		/* Consecutive 32-bit registers, located elsewhere. */		*valptr = *(unsigned int *)((char *)&sreg.s0_0 + (reg.srs * 16 * sizeof(unsigned int)) + (regno - S0) * sizeof(unsigned int));	} else {		/* Non-existing register. */		status = E05;	}	return status;}/********************************** Packet I/O ******************************//* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte,   represented by int x. */static inline charhighhex(int x){	return hexchars[(x >> 4) & 0xf];}/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte,   represented by int x. */static inline charlowhex(int x){	return hexchars[x & 0xf];}/* Returns the integer equivalent of a hexadecimal character. */static inthex(char ch){	if ((ch >= 'a') && (ch <= 'f'))		return (ch - 'a' + 10);	if ((ch >= '0') && (ch <= '9'))		return (ch - '0');	if ((ch >= 'A') && (ch <= 'F'))		return (ch - 'A' + 10);	return -1;}/* Convert the memory, pointed to by mem into hexadecimal representation.   Put the result in buf, and return a pointer to the last character   in buf (null). */static char *mem2hex(char *buf, unsigned char *mem, int count){	int i;	int ch;        if (mem == NULL) {		/* Invalid address, caught by 'm' packet handler. */                for (i = 0; i < count; i++) {                        *buf++ = '0';                        *buf++ = '0';                }        } else {                /* Valid mem address. */		for (i = 0; i < count; i++) {			ch = *mem++;			*buf++ = highhex (ch);			*buf++ = lowhex (ch);		}        }        /* Terminate properly. */	*buf = '\0';	return buf;}/* Same as mem2hex, but puts it in network byte order. */static char *mem2hex_nbo(char *buf, unsigned char *mem, int count){	int i;	int ch;	mem += count - 1;	for (i = 0; i < count; i++) {		ch = *mem--;		*buf++ = highhex (ch);		*buf++ = lowhex (ch);        }        /* 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;		}		if (count >= BUFMAX)			continue;		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. */

⌨️ 快捷键说明

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