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

📄 kgdb.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* The number of characters used for a 64 bit thread identifier. */#define HEXCHARS_IN_THREAD_ID 16/* 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 */#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 remcomInBuffer[BUFMAX];static char remcomOutBuffer[BUFMAX];/* Error and warning messages. */enum error_type{	SUCCESS, E01, E02, E03, E04, E05, E06, E07};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.",	"E07 Change register content - P - the register is not stored on the stack"};/********************************* Register image ****************************//* Use the order of registers as defined in "AXIS ETRAX CRIS Programmer's   Reference", p. 1-1, with the additional register definitions of the   ETRAX 100LX in cris-opc.h.   There are 16 general 32-bit registers, R0-R15, where R14 is the stack   pointer, SP, and R15 is the program counter, PC.   There are 16 special registers, P0-P15, where three of the unimplemented   registers, P0, P4 and P8, are reserved as zero-registers. A read from   any of these registers returns zero and a write has no effect. */enum register_name{	R0,  R1,   R2,  R3,	R4,  R5,   R6,  R7,	R8,  R9,   R10, R11,	R12, R13,  SP,  PC,	P0,  VR,   P2,  P3,	P4,  CCR,  P6,  MOF,	P8,  IBR,  IRP, SRP,	BAR, DCCR, BRP, USP};/* The register sizes of the registers in register_name. An unimplemented register   is designated by size 0 in this array. */static int register_size[] ={	4, 4, 4, 4,	4, 4, 4, 4,	4, 4, 4, 4,	4, 4, 4, 4,	1, 1, 0, 0,	2, 2, 0, 4,	4, 4, 4, 4,	4, 4, 4, 4};/* Contains the register image of the executing thread in the assembler   part of the code in order to avoid horrible addressing modes. */static registers reg;/* FIXME: Should this be used? Delete otherwise. *//* Contains the assumed consistency state of the register image. Uses the   enum error_type for state information. */static int consistency_status = SUCCESS;/********************************** Handle exceptions ************************//* The variable reg contains the register image associated with the   current_thread_c variable. It is a complete register image created at   entry. The reg_g contains a register image of a task where the general   registers are taken from the stack and all special registers are taken   from the executing task. It is associated with current_thread_g and used   in order to provide access mainly for 'g', 'G' and 'P'.*//* Need two task id pointers in order to handle Hct and Hgt commands. */static int current_thread_c = 0;static int current_thread_g = 0;/* Need two register images in order to handle Hct and Hgt commands. The   variable reg_g is in addition to reg above. */static registers reg_g;/********************************** Breakpoint *******************************//* Use an internal stack in the breakpoint and interrupt response routines */#define INTERNAL_STACK_SIZE 1024static char 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   BRP as it is whereas a dynamic breakpoint requires subtraction with 2   in order to execute the instruction. The first breakpoint is static. */static unsigned char is_dyn_brkp = 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;}intdouble_this(int x){        return 2 * x;}/********************************* Register image ****************************//* Copy the content of a register image into another. The size n is   the size of the register image. Due to struct assignment generation of   memcpy in libc. */static voidcopy_registers (registers *dptr, registers *sptr, int n){	unsigned char *dreg;	unsigned char *sreg;		for (dreg = (unsigned char*)dptr, sreg = (unsigned char*)sptr; n > 0; n--)		*dreg++ = *sreg++;}#ifdef PROCESS_SUPPORT/* Copy the stored registers from the stack. Put the register contents   of thread thread_id in the struct reg. */static voidcopy_registers_from_stack (int thread_id, registers *regptr){	int j;	stack_registers *s = (stack_registers *)stack_list[thread_id];	unsigned int *d = (unsigned int *)regptr;		for (j = 13; j >= 0; j--)		*d++ = s->r[j];	regptr->sp = (unsigned int)stack_list[thread_id];	regptr->pc = s->pc;	regptr->dccr = s->dccr;	regptr->srp = s->srp;}/* Copy the registers to the stack. Put the register contents of thread   thread_id from struct reg to the stack. */static voidcopy_registers_to_stack (int thread_id, registers *regptr){	int i;	stack_registers *d = (stack_registers *)stack_list[thread_id];	unsigned int *s = (unsigned int *)regptr;		for (i = 0; i < 14; i++) {		d->r[i] = *s++;	}	d->pc = regptr->pc;	d->dccr = regptr->dccr;	d->srp = regptr->srp;}#endif/* 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;	registers *current_reg = &reg;        if (regno >= R0 && regno <= PC) {		/* 32-bit register with simple offset. */		hex2mem ((unsigned char *)current_reg + regno * sizeof(unsigned int),			 val, sizeof(unsigned int));	}        else if (regno == P0 || regno == VR || regno == P4 || regno == P8) {		/* Do not support read-only registers. */		status = E02;	}        else if (regno == CCR) {		/* 16 bit register with complex offset. (P4 is read-only, P6 is not implemented,                    and P7 (MOF) is 32 bits in ETRAX 100LX. */		hex2mem ((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short),			 val, sizeof(unsigned short));	}	else if (regno >= MOF && regno <= USP) {		/* 32 bit register with complex offset.  (P8 has been taken care of.) */		hex2mem ((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int),			 val, sizeof(unsigned int));	}         else {		/* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */		status = E05;	}	return status;}#ifdef PROCESS_SUPPORT/* Write a value to a specified register in the stack of a thread other   than the current thread. Returns status code SUCCESS or E07. */static intwrite_stack_register (int thread_id, int regno, char *valptr){	int status = SUCCESS;	stack_registers *d = (stack_registers *)stack_list[thread_id];	unsigned int val;		hex2mem ((unsigned char *)&val, valptr, sizeof(unsigned int));	if (regno >= R0 && regno < SP) {		d->r[regno] = val;	}	else if (regno == SP) {		stack_list[thread_id] = val;	}	else if (regno == PC) {		d->pc = val;	}	else if (regno == SRP) {		d->srp = val;	}	else if (regno == DCCR) {		d->dccr = val;	}	else {		/* Do not support registers in the current thread. */		status = E07;	}	return status;}#endif/* Read a value from a specified register in the register image. Returns the   value in the register or -1 for non-implemented registers.   Should check consistency_status after a call which may be E05 after changes   in the implementation. */static intread_register (char regno, unsigned int *valptr){	registers *current_reg = &reg;	if (regno >= R0 && regno <= PC) {		/* 32-bit register with simple offset. */		*valptr = *(unsigned int *)((char *)current_reg + regno * sizeof(unsigned int));                return SUCCESS;	}	else if (regno == P0 || regno == VR) {		/* 8 bit register with complex offset. */		*valptr = (unsigned int)(*(unsigned char *)                                         ((char *)&(current_reg->p0) + (regno-P0) * sizeof(char)));                return SUCCESS;	}	else if (regno == P4 || regno == CCR) {		/* 16 bit register with complex offset. */		*valptr = (unsigned int)(*(unsigned short *)                                         ((char *)&(current_reg->p4) + (regno-P4) * sizeof(unsigned short)));                return SUCCESS;	}	else if (regno >= MOF && regno <= USP) {		/* 32 bit register with complex offset. */		*valptr = *(unsigned int *)((char *)&(current_reg->p8)                                            + (regno-P8) * sizeof(unsigned int));                return SUCCESS;	}	else {		/* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */		consistency_status = E05;		return E05;	}}/********************************** 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 int do_printk = 0;static char *mem2hex(char *buf, unsigned char *mem, int count){	int i;	int ch;                if (mem == NULL) {                /* Bogus read from m0. FIXME: What constitutes a valid address? */                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);                }        }        

⌨️ 快捷键说明

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