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

📄 kgdb.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
				putpacket (remcomOutBuffer);				return;							case '?':				/* The last signal which caused a stop. ?				   Success: SAA, where AA is the signal number.				   Failure: void. */				remcomOutBuffer[0] = 'S';				remcomOutBuffer[1] = highhex (sigval);				remcomOutBuffer[2] = lowhex (sigval);				remcomOutBuffer[3] = 0;				break;							case 'D':				/* Detach from host. D				   Success: OK, and return to the executing thread.				   Failure: will never know */				putpacket ("OK");				return;							case 'k':			case 'r':				/* kill request or reset request.				   Success: restart of target.				   Failure: will never know. */				kill_restart ();				break;							case 'C':			case 'S':			case '!':			case 'R':			case 'd':				/* Continue with signal sig. Csig;AA..AA				   Step with signal sig. Ssig;AA..AA				   Use the extended remote protocol. !				   Restart the target system. R0				   Toggle debug flag. d				   Search backwards. tAA:PP,MM				   Not supported: E04 */				gdb_cris_strcpy (remcomOutBuffer, error_message[E04]);				break;#ifdef PROCESS_SUPPORT			case 'T':				/* Thread alive. TXX				   Is thread XX alive?				   Success: OK, thread XX is alive.				   Failure: E03, thread XX is dead. */				{					int thread_id = (int)gdb_cris_strtol (&remcomInBuffer[1], 0, 16);					/* Cannot tell whether it is alive or not. */					if (thread_id >= 0 && thread_id < number_of_tasks)						gdb_cris_strcpy (remcomOutBuffer, "OK");				}				break;											case 'H':				/* Set thread for subsequent operations: Hct				   c = 'c' for thread used in step and continue;				   t can be -1 for all threads.				   c = 'g' for thread used in other  operations.				   t = 0 means pick any thread.				   Success: OK				   Failure: E01 */				{					int thread_id = gdb_cris_strtol (&remcomInBuffer[2], 0, 16);					if (remcomInBuffer[1] == 'c') {						/* c = 'c' for thread used in step and continue */						/* Do not change current_thread_c here. It would create a mess in						   the scheduler. */						gdb_cris_strcpy (remcomOutBuffer, "OK");					}					else if (remcomInBuffer[1] == 'g') {						/* c = 'g' for thread used in other  operations.						   t = 0 means pick any thread. Impossible since the scheduler does						   not allow that. */						if (thread_id >= 0 && thread_id < number_of_tasks) {							current_thread_g = thread_id;							gdb_cris_strcpy (remcomOutBuffer, "OK");						}						else {							/* Not expected - send an error message. */							gdb_cris_strcpy (remcomOutBuffer, error_message[E01]);						}					}					else {						/* Not expected - send an error message. */						gdb_cris_strcpy (remcomOutBuffer, error_message[E01]);					}				}				break;							case 'q':			case 'Q':				/* Query of general interest. qXXXX				   Set general value XXXX. QXXXX=yyyy */				{					int pos;					int nextpos;					int thread_id;										switch (remcomInBuffer[1]) {						case 'C':							/* Identify the remote current thread. */							gdb_cris_strcpy (&remcomOutBuffer[0], "QC");							remcomOutBuffer[2] = highhex (current_thread_c);							remcomOutBuffer[3] = lowhex (current_thread_c);							remcomOutBuffer[4] = '\0';							break;						case 'L':							gdb_cris_strcpy (&remcomOutBuffer[0], "QM");							/* Reply with number of threads. */							if (os_is_started()) {								remcomOutBuffer[2] = highhex (number_of_tasks);								remcomOutBuffer[3] = lowhex (number_of_tasks);							}							else {								remcomOutBuffer[2] = highhex (0);								remcomOutBuffer[3] = lowhex (1);							}							/* Done with the reply. */							remcomOutBuffer[4] = lowhex (1);							pos = 5;							/* Expects the argument thread id. */							for (; pos < (5 + HEXCHARS_IN_THREAD_ID); pos++)								remcomOutBuffer[pos] = remcomInBuffer[pos];							/* Reply with the thread identifiers. */							if (os_is_started()) {								/* Store the thread identifiers of all tasks. */								for (thread_id = 0; thread_id < number_of_tasks; thread_id++) {									nextpos = pos + HEXCHARS_IN_THREAD_ID - 1;									for (; pos < nextpos; pos ++)										remcomOutBuffer[pos] = lowhex (0);									remcomOutBuffer[pos++] = lowhex (thread_id);								}							}							else {								/* Store the thread identifier of the boot task. */								nextpos = pos + HEXCHARS_IN_THREAD_ID - 1;								for (; pos < nextpos; pos ++)									remcomOutBuffer[pos] = lowhex (0);								remcomOutBuffer[pos++] = lowhex (current_thread_c);							}							remcomOutBuffer[pos] = '\0';							break;						default:							/* Not supported: "" */							/* Request information about section offsets: qOffsets. */							remcomOutBuffer[0] = 0;							break;					}				}				break;#endif /* PROCESS_SUPPORT */							default:				/* The stub should ignore other request and send an empty				   response ($#<checksum>). This way we can extend the protocol and GDB				   can tell whether the stub it is talking to uses the old or the new. */				remcomOutBuffer[0] = 0;				break;		}		putpacket(remcomOutBuffer);	}}/* The jump is to the address 0x00000002. Performs a complete re-start   from scratch. */static voidkill_restart (){	__asm__ volatile ("jump 2");}/********************************** Breakpoint *******************************//* The hook for both a static (compiled) and a dynamic breakpoint set by GDB.   An internal stack is used by the stub. The register image of the caller is   stored in the structure register_image.   Interactive communication with the host is handled by handle_exception and   finally the register image is restored. */void kgdb_handle_breakpoint(void);asm ("  .global kgdb_handle_breakpointkgdb_handle_breakpoint:;;;; Response to the break-instruction;;;; Create a register image of the caller;;  move     $dccr,[reg+0x5E] ; Save the flags in DCCR before disable interrupts  di                        ; Disable interrupts  move.d   $r0,[reg]        ; Save R0  move.d   $r1,[reg+0x04]   ; Save R1  move.d   $r2,[reg+0x08]   ; Save R2  move.d   $r3,[reg+0x0C]   ; Save R3  move.d   $r4,[reg+0x10]   ; Save R4  move.d   $r5,[reg+0x14]   ; Save R5  move.d   $r6,[reg+0x18]   ; Save R6  move.d   $r7,[reg+0x1C]   ; Save R7  move.d   $r8,[reg+0x20]   ; Save R8  move.d   $r9,[reg+0x24]   ; Save R9  move.d   $r10,[reg+0x28]  ; Save R10  move.d   $r11,[reg+0x2C]  ; Save R11  move.d   $r12,[reg+0x30]  ; Save R12  move.d   $r13,[reg+0x34]  ; Save R13  move.d   $sp,[reg+0x38]   ; Save SP (R14);; Due to the old assembler-versions BRP might not be recognized  .word 0xE670              ; move brp,$r0  subq     2,$r0             ; Set to address of previous instruction.  move.d   $r0,[reg+0x3c]   ; Save the address in PC (R15)  clear.b  [reg+0x40]      ; Clear P0  move     $vr,[reg+0x41]   ; Save special register P1  clear.w  [reg+0x42]      ; Clear P4  move     $ccr,[reg+0x44]  ; Save special register CCR  move     $mof,[reg+0x46]  ; P7  clear.d  [reg+0x4A]      ; Clear P8  move     $ibr,[reg+0x4E]  ; P9,  move     $irp,[reg+0x52]  ; P10,  move     $srp,[reg+0x56]  ; P11,  move     $dtp0,[reg+0x5A] ; P12, register BAR, assembler might not know BAR                            ; P13, register DCCR already saved;; Due to the old assembler-versions BRP might not be recognized  .word 0xE670              ; move brp,r0;; Static (compiled) breakpoints must return to the next instruction in order;; to avoid infinite loops. Dynamic (gdb-invoked) must restore the instruction;; in order to execute it when execution is continued.  test.b   [is_dyn_brkp]    ; Is this a dynamic breakpoint?  beq      is_static         ; No, a static breakpoint  nop  subq     2,$r0              ; rerun the instruction the break replacedis_static:  moveq    1,$r1  move.b   $r1,[is_dyn_brkp] ; Set the state variable to dynamic breakpoint  move.d   $r0,[reg+0x62]    ; Save the return address in BRP  move     $usp,[reg+0x66]   ; USP;;;; Handle the communication;;  move.d   internal_stack+1020,$sp ; Use the internal stack which grows upward  moveq    5,$r10                   ; SIGTRAP  jsr      handle_exception       ; Interactive routine;;;; Return to the caller;;   move.d  [reg],$r0         ; Restore R0   move.d  [reg+0x04],$r1    ; Restore R1   move.d  [reg+0x08],$r2    ; Restore R2   move.d  [reg+0x0C],$r3    ; Restore R3   move.d  [reg+0x10],$r4    ; Restore R4   move.d  [reg+0x14],$r5    ; Restore R5   move.d  [reg+0x18],$r6    ; Restore R6   move.d  [reg+0x1C],$r7    ; Restore R7   move.d  [reg+0x20],$r8    ; Restore R8   move.d  [reg+0x24],$r9    ; Restore R9   move.d  [reg+0x28],$r10   ; Restore R10   move.d  [reg+0x2C],$r11   ; Restore R11   move.d  [reg+0x30],$r12   ; Restore R12   move.d  [reg+0x34],$r13   ; Restore R13;;;; FIXME: Which registers should be restored?;;   move.d  [reg+0x38],$sp    ; Restore SP (R14)   move    [reg+0x56],$srp   ; Restore the subroutine return pointer.   move    [reg+0x5E],$dccr  ; Restore DCCR   move    [reg+0x66],$usp   ; Restore USP   jump    [reg+0x62]       ; A jump to the content in register BRP works.   nop                       ;");/* The hook for an interrupt generated by GDB. An internal stack is used   by the stub. The register image of the caller is stored in the structure   register_image. Interactive communication with the host is handled by   handle_exception and finally the register image is restored. Due to the   old assembler which does not recognise the break instruction and the   breakpoint return pointer hex-code is used. */void kgdb_handle_serial(void);asm ("  .global kgdb_handle_serialkgdb_handle_serial:;;;; Response to a serial interrupt;;  move     $dccr,[reg+0x5E] ; Save the flags in DCCR  di                        ; Disable interrupts  move.d   $r0,[reg]        ; Save R0  move.d   $r1,[reg+0x04]   ; Save R1  move.d   $r2,[reg+0x08]   ; Save R2  move.d   $r3,[reg+0x0C]   ; Save R3  move.d   $r4,[reg+0x10]   ; Save R4  move.d   $r5,[reg+0x14]   ; Save R5  move.d   $r6,[reg+0x18]   ; Save R6  move.d   $r7,[reg+0x1C]   ; Save R7  move.d   $r8,[reg+0x20]   ; Save R8  move.d   $r9,[reg+0x24]   ; Save R9  move.d   $r10,[reg+0x28]  ; Save R10  move.d   $r11,[reg+0x2C]  ; Save R11  move.d   $r12,[reg+0x30]  ; Save R12  move.d   $r13,[reg+0x34]  ; Save R13  move.d   $sp,[reg+0x38]   ; Save SP (R14)  move     $irp,[reg+0x3c]  ; Save the address in PC (R15)  clear.b  [reg+0x40]      ; Clear P0  move     $vr,[reg+0x41]   ; Save special register P1,  clear.w  [reg+0x42]      ; Clear P4  move     $ccr,[reg+0x44]  ; Save special register CCR  move     $mof,[reg+0x46]  ; P7  clear.d  [reg+0x4A]      ; Clear P8  move     $ibr,[reg+0x4E]  ; P9,  move     $irp,[reg+0x52]  ; P10,  move     $srp,[reg+0x56]  ; P11,  move     $dtp0,[reg+0x5A] ; P12, register BAR, assembler might not know BAR                            ; P13, register DCCR already saved;; Due to the old assembler-versions BRP might not be recognized  .word 0xE670              ; move brp,r0  move.d   $r0,[reg+0x62]   ; Save the return address in BRP  move     $usp,[reg+0x66]  ; USP;; get the serial character (from debugport.c) and check if it is a ctrl-c  jsr getDebugChar  cmp.b 3, $r10  bne goback  nop;;;; Handle the communication;;  move.d   internal_stack+1020,$sp ; Use the internal stack  moveq    2,$r10                   ; SIGINT  jsr      handle_exception       ; Interactive routinegoback:;;;; Return to the caller;;   move.d  [reg],$r0         ; Restore R0   move.d  [reg+0x04],$r1    ; Restore R1   move.d  [reg+0x08],$r2    ; Restore R2   move.d  [reg+0x0C],$r3    ; Restore R3   move.d  [reg+0x10],$r4    ; Restore R4   move.d  [reg+0x14],$r5    ; Restore R5   move.d  [reg+0x18],$r6    ; Restore R6   move.d  [reg+0x1C],$r7    ; Restore R7   move.d  [reg+0x20],$r8    ; Restore R8   move.d  [reg+0x24],$r9    ; Restore R9   move.d  [reg+0x28],$r10   ; Restore R10   move.d  [reg+0x2C],$r11   ; Restore R11   move.d  [reg+0x30],$r12   ; Restore R12   move.d  [reg+0x34],$r13   ; Restore R13;;;; FIXME: Which registers should be restored?;;   move.d  [reg+0x38],$sp    ; Restore SP (R14)   move    [reg+0x56],$srp   ; Restore the subroutine return pointer.   move    [reg+0x5E],$dccr  ; Restore DCCR   move    [reg+0x66],$usp   ; Restore USP   reti                      ; Return from the interrupt routine   nop");/* Use this static breakpoint in the start-up only. */voidbreakpoint(void){	kgdb_started = 1;	is_dyn_brkp = 0;     /* This is a static, not a dynamic breakpoint. */	__asm__ volatile ("break 8"); /* Jump to handle_breakpoint. */}/* initialize kgdb. doesn't break into the debugger, but sets up irq and ports */voidkgdb_init(void){	/* could initialize debug port as well but it's done in head.S already... */        /* breakpoint handler is now set in irq.c */	set_int_vector(8, kgdb_handle_serial, 0);		enableDebugIRQ();}/****************************** End of file **********************************/

⌨️ 快捷键说明

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