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

📄 gdb-jtag-arm.c

📁 GDB Remote Stub Backend for debugging an embedded ARM system via JTAG common hardware debug interfac
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (C) 2004 Lars Kristian Klauske * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. *//* GDB remote server */#include <stdlib.h>#include <stdio.h>#include "jtag.h"#include "debug.h"#include "memory.h"#include "ice.h"#include "lpec.h"/* network functions */#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/poll.h>#define GDB_ANSWER_OK	"OK"#define GDB_ANSWER_S05	"S05"	/* breakpoint happened */#define GDB_ANSWER_W07	"W07"	/* breakpoint happened */#define GDB_ANSWER_W02	"W02"	/* interrupt occured */#define GDB_ANSWER_S03	"S03"	/* interrupt occured */#define GDB_ANSWER_W00	"W00"	/* process stopped */#define GDB_ANSWER_S17	"S17"	/* process stopped */#define GDB_ANSWER_E01	"E01"	/* error */#define GDB_ANSWER_E02	"E02"	/* error */unsigned long SW_BP_PATTERN = 0xe7ffdefe;/* implemented GDB commands:D				detachg				read registersG<XX...>			write registersm<addr>,<length>		read memoryM<addr>,<length>:<XX...>	write memoryc<addr>				continues<addr>				step*/int client_socket;long buffersize=10000;int last_running=1;#define sw_bp_max 99unsigned long sw_bp_addr[sw_bp_max+1];unsigned long sw_bp_memdata[sw_bp_max+1];void execute_command(long length, char *cmd);void gdb_write_memory(unsigned long addr, unsigned long length, char *buffer);void gdb_step(void);char HexByte_to_Value(char input) {    // is it a number?    if ( (input>=0x30) && (input<=0x39) )	return (input-0x30);        // or is it a lowercase    if ( (input>=0x61) && (input<=0x66) )	return (input-0x57);        // or is it an uppercase    if ( (input>=0x41) && (input<=0x46) )	return (input-0x37);        return 0;}int Calculate_Checksum(long length, char *input) {    int ret=0;    //int i;        for (; length>0; length--) {	ret += input[length-1];	ret = ret & 0xff;    }        return ret;}unsigned long HexString_to_Long (char *input) {    #define longsize 8    unsigned long ret;    ret = strtoul(input,NULL,16);    //printf("Converting: %s  - Result: %8.8x\n",input, ret);    return ret;}/*unsigned long HexString_to_ULong (char *input) {    #define longsize 8    unsigned long ret;    ret = strtoul(input,NULL,16);    printf("Converting: %s  - Result: %8.8x\n",input, ret);    return ret;    }*/void answer_gdb(long length, char *text) {    int checksum=Calculate_Checksum(length, text);    char cs_string[5];    sprintf (cs_string, "%02.2x", checksum);        if ((text[0]=='+') || (text[0]=='-')) {	//printf ("Sending: %c\n",text[0]);	write(client_socket, text, 1);    } else {	printf ("Sending: $%s#%02.2x\n", text, checksum);	write(client_socket,"$",1);	if (length) write(client_socket,text,length);	write(client_socket,"#",1);	write(client_socket,cs_string,2);    }    // fflush(&new_socket);    return;}     	void do_gdb(void) {    int socket_desc;    struct sockaddr_in address;    int addrlen;    //int new_socket;        struct pollfd ufds = { 0, POLLIN+POLLPRI, 0 };    char buffer[buffersize];    long bufferfill=0;    char byte;    int state=0;    int checksum;    for (checksum=0; checksum<=sw_bp_max; checksum++) {	sw_bp_memdata[checksum]=SW_BP_PATTERN;	sw_bp_addr[checksum]=0;    }    /* create the master socket and check it worked */    if ((socket_desc=socket(AF_INET,SOCK_STREAM,0))==0)    {	/* if socket failed then display error and exit */	perror("Create socket");	exit(EXIT_FAILURE);    }    /* type of socket created */    address.sin_family = AF_INET;    address.sin_addr.s_addr = INADDR_ANY;    /* use port 8888 */    address.sin_port = htons(8888);    /* bind the socket to port 8888 */    if (bind(socket_desc,(struct sockaddr *)&address,sizeof(address))<0)    {	/* if bind failed then display error message and exit */	perror("bind");	exit(EXIT_FAILURE);    }    /* accept connection, wait if no connection pending */    addrlen=sizeof(address);    listen(socket_desc,1) ;    printf("Listening for Connection...\n");    client_socket=accept(socket_desc,(struct sockaddr *)&address,&addrlen);    /* inform user of socket number - used in send and receive commands */    printf("Client socket is %d\n",client_socket);    state=0;    ufds.fd=client_socket;    /* stopping target for gdb */    debug_stop();    ice_set_software_breakpoint(0, SW_BP_PATTERN);    lpec_init();    last_running=0;//    while ( read(client_socket, &byte, 1) == 1  ) {    while (client_socket) {	if (poll( &ufds, 1, 0 ) > 0) {	    read(client_socket, &byte, 1);	    	    printf("%c",byte);	    fflush(stdout);	    	    switch (state) {		case 0:		    if (byte == '$') {			bufferfill=0;			state = 1;		    }		    break;		case 1:		    if (byte != '#') {			if (bufferfill < buffersize-1) {			    buffer[bufferfill]=byte;			    			    /*if (bufferfill==0) {			      switch (buffer[0]) {			      case 'M':			      state=0;			      execute_command(bufferfill, buffer);			      break;			      default:			      break;			      }			      }*/			    bufferfill++;			    			} else {			    bufferfill=0;			    printf ("Error! Buffer overflow while reading from Socket.\n");			    answer_gdb(1,"-");			    state=0;			}		    } else {			buffer[bufferfill]='\0';			state=2;		    }		    break;		case 2:		    checksum=HexByte_to_Value(byte);		    checksum*=16;		    state=3;		    break;		case 3:		    checksum += HexByte_to_Value(byte);		    printf ("\nCommand: %s", buffer);		    printf (" - Checksum IN:%02.2x, CA:%02.2x\n",checksum,Calculate_Checksum(bufferfill, buffer));		    if (checksum == Calculate_Checksum(bufferfill, buffer)) {			answer_gdb(1,"+");			//printf("Answered: Checksum Ok\n");			//printf("Doing Work: %s\n", buffer);			execute_command(bufferfill, buffer);		    } else {			answer_gdb(1,"-");			printf("Answered: Checksum Mismatch\n");		    }		    state=0;		    break;		default:		    break;		    	    }	    	    fflush(stdout);	    	} else {  // invoming Event is not invoked by GDB	    if (last_running) {		printf(".");		if (ice_halted()) {		    debug_save_regs();		    answer_gdb(3, "S05");		    last_running=0;	       		}	    }	    	}        }    /* shutdown master socket properly */    close(socket_desc);            return;        }void execute_command(long length, char *cmd) {    int retsize=0;    //char *MemoryAdressString;    //char *MemoryLengthString;    long MemoryAddress;    long MemoryLength;    char *MemoryData;    unsigned long *MemoryLongData;    long MemoryDataLength=0;    long MemoryTemp=0;    long MemoryFirstValue=0;    long MemoryBlah=0;    char MemoryTempString[10];    int tempI=0;    long tempL=0;    switch (cmd[0]) {	case 'H':	// set thread	    answer_gdb(2,"OK");	    printf("(set thread)\n");	    break;	case 'g':	// read registers	    retsize = gdb_read_registers(buffersize, cmd);	    answer_gdb(retsize,cmd);	    printf("(read registers)\n");	    break;	case 'G':	// write registers	    //answer_gdb(0,"\0");	    retsize=gdb_write_registers(cmd);	    answer_gdb(2,"OK");	    printf("(write registers)\n");	    break;	    	case 'P':	// write a particular register	    answer_gdb(0,"\0");	    printf("(write a particular register)\n");	    break;	    	case 'm':	// read memory	    for (tempL=1; ((tempL<=8) && (cmd[tempL]!=',')); tempL++);	    cmd[tempL]='\0';	    MemoryAddress=HexString_to_Long(cmd+1);	    MemoryLength=HexString_to_Long(cmd+tempL+1);	    MemoryLength = MemoryLength >> 2; // read full 32bit only	    // printf("Reading %8.8x Longs from %8.8x\n",MemoryLength,MemoryAddress); 	    MemoryLongData = malloc(sizeof(long)*MemoryLength);	    MemoryData = malloc(sizeof(long)*(MemoryLength+1)*2);	    memory_read(MemoryAddress, MemoryLongData, MemoryLength);	    for (tempL=0; tempL<MemoryLength; tempL++) {		MemoryTemp=tempL*sizeof(long)*2;		sprintf( MemoryData+MemoryTemp, "%8.8x", MemoryLongData[tempL]);		}	    	    answer_gdb(MemoryLength*2*sizeof(long), MemoryData);	    printf("(read memory)\n");	    	    free(MemoryLongData);	    free(MemoryData);	    break;	case 'M':	// write memory  	    cmd ++;	    /* read address */	    for (tempL=0; ((tempL<8) && (cmd[tempL]!=',')); tempL++);	    cmd[tempL]='\0';	    MemoryAddress=HexString_to_Long(cmd);	    cmd += tempL+1;	    /* read length */	    for (tempL=0; ((tempL<8) && (cmd[tempL]!=':')); tempL++);	    cmd[tempL]='\0';	    MemoryLength=HexString_to_Long(cmd);	    cmd += tempL+1;	    gdb_write_memory(MemoryAddress, MemoryLength, cmd);	    answer_gdb(2,"OK");	    printf("(write memory)\n");	    break;	    	case 'X':	// write memory, binary data	    answer_gdb(0,"\0");	    printf("(write memory, binary data)\n");	    break;	    	case 'z':	// delete breakpoint	    printf("(delete breakpoint)\n");	    retsize = gdb_remove_breakpoint(buffersize, cmd+1);	    if (retsize) {		answer_gdb(0, "\0");	    } else {		answer_gdb(2, "OK");	    }	    break;	case 'Z':	// set breakpoint	    printf("(set breakpoint)\n");	    retsize = gdb_insert_breakpoint(buffersize, cmd+1);	    if (retsize) {		answer_gdb(0, "\0");	    } else {		answer_gdb(2, "OK");	    }	    break;

⌨️ 快捷键说明

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