📄 gdb.c
字号:
#include <stdio.h>#include <ctype.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <stdarg.h>/* Libraries for JTAG proxy server. */#include <sys/stat.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/select.h>#include <sys/poll.h>#include <fcntl.h>#include <netdb.h>#include <netinet/tcp.h>#include <inttypes.h>#include <errno.h>#include "gdb.h" /* partially copied from gdb/config/or1k */#include "jp2.h"/* connection to jp2 routines */int gdb_chain = -1;int gdb_read_reg(unsigned long adr, unsigned long *data) { switch (gdb_chain) { SC_RISC_DEBUG: return dbg_cpu_read32(adr, data) ? ERR_CRC : ERR_NONE; SC_REGISTER: return dbg_cpu_read_reg(adr, data) ? ERR_CRC : ERR_NONE; SC_WISHBONE: return dbg_wb_read32(adr, data) ? ERR_CRC : ERR_NONE; default: return JTAG_PROXY_INVALID_CHAIN; }}int gdb_write_reg(unsigned long adr, unsigned long data) { switch (gdb_chain) { SC_RISC_DEBUG: return dbg_cpu_write32(adr, data) ? ERR_CRC : ERR_NONE; SC_REGISTER: return dbg_cpu_write_reg(adr, data) ? ERR_CRC : ERR_NONE; SC_WISHBONE: return dbg_wb_write32(adr, data) ? ERR_CRC : ERR_NONE; default: return JTAG_PROXY_INVALID_CHAIN; }}int gdb_read_block(unsigned long adr, unsigned long *data, int len) { switch (gdb_chain) { SC_WISHBONE: return dbg_wb_read_block32(adr, data, len) ? ERR_CRC : ERR_NONE; default: return JTAG_PROXY_INVALID_CHAIN; }}int gdb_write_block(unsigned long adr, unsigned long *data, int len) { switch (gdb_chain) { SC_WISHBONE: return dbg_wb_write_block32(adr, data, len) ? ERR_CRC : ERR_NONE; default: return JTAG_PROXY_INVALID_CHAIN; }}int gdb_set_chain(int chain) { switch (gdb_chain) { SC_RISC_DEBUG: SC_REGISTER: SC_WISHBONE: gdb_chain = chain; return ERR_NONE; default: return JTAG_PROXY_INVALID_CHAIN; }}/************************ JTAG Server Routines ************************/unsigned int serverIP = 0;unsigned int serverPort = 0;unsigned int server_fd = 0;unsigned int gdb_fd = 0;static int gdb_read(void*, int);static int gdb_write(void*, int);static void ProtocolClean(int, int32_t);static int tcp_level = 0;/* Added by CZ 24/05/01 */int GetServerSocket(const char* name, const char* proto, int port) { struct servent *service; struct protoent *protocol; struct sockaddr_in sa; struct hostent *hp; int sockfd; char myname[256]; int flags; char sTemp[256]; /* First, get the protocol number of TCP */ if (!(protocol = getprotobyname(proto))) { sprintf(sTemp, "Unable to load protocol \"%s\"", proto); perror(sTemp); return 0; } tcp_level = protocol->p_proto; /* Save for later */ /* If we weren't passed a non standard port, get the port from the services directory. */ if (!port && (service = getservbyname(name, protocol->p_name))) port = ntohs(service->s_port); /* Create the socket using the TCP protocol */ if ((sockfd = socket(PF_INET, SOCK_STREAM, protocol->p_proto)) < 0) { perror("Unable to create socket"); return 0; } flags = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&flags, sizeof(int)) < 0) { sprintf(sTemp, "Can not set SO_REUSEADDR option on socket %d", sockfd); perror(sTemp); close(sockfd); return 0; } /* The server should also be non blocking. Get the current flags. */ if((flags = fcntl(sockfd, F_GETFL, 0)) < 0) { sprintf(sTemp, "Unable to get flags for socket %d", sockfd); perror(sTemp); close(sockfd); return 0; } /* Set the nonblocking flag */ if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) { sprintf(sTemp, "Unable to set flags for socket %d to value 0x%08x", sockfd, flags | O_NONBLOCK); perror(sTemp); close(sockfd); return 0; } /* Find out what our address is */ memset(&sa, 0, sizeof(struct sockaddr_in)); gethostname(myname, sizeof(myname)); if(!(hp = gethostbyname(myname))) { perror("Unable to read hostname"); close(sockfd); return 0; } /* Bind our socket to the appropriate address */ sa.sin_family = hp->h_addrtype; sa.sin_port = htons(port); if(bind(sockfd, (struct sockaddr*)&sa, sizeof(struct sockaddr_in)) < 0) { sprintf(sTemp, "Unable to bind socket %d to port %d", sockfd, port); perror(sTemp); close(sockfd); return 0; } serverIP = sa.sin_addr.s_addr; flags = sizeof(struct sockaddr_in); if(getsockname(sockfd, (struct sockaddr*)&sa, &flags) < 0) { sprintf(sTemp, "Unable to get socket information for socket %d", sockfd); perror(sTemp); close(sockfd); return 0; } serverPort = ntohs(sa.sin_port); /* Set the backlog to 1 connections */ if(listen(sockfd, 1) < 0) { sprintf(sTemp, "Unable to set backlog on socket %d to %d", sockfd, 1); perror(sTemp); close(sockfd); return 0; } return sockfd;}void HandleServerSocket(Boolean block) { struct pollfd fds[2]; int n; rebuild: n = 0; if(!server_fd && !gdb_fd) return; if(server_fd) { fds[n].fd = server_fd; fds[n].events = POLLIN; fds[n++].revents = 0; } if(gdb_fd) { fds[n].fd = gdb_fd; fds[n].events = POLLIN; fds[n++].revents = 0; } while(1) { switch(poll(fds, n, -1)) { case 0: case -1: if(errno == EINTR) continue; perror("poll"); server_fd = 0; return; default: /* Make sure to handle the gdb port first! */ if (gdb_fd && (fds[0].revents && !server_fd || fds[1].revents && server_fd)) { int revents = server_fd ? fds[1].revents : fds[0].revents; if (revents & POLLIN) GDBRequest(); else {/* Error Occurred */ fprintf(stderr, "Received flags 0x%08x on gdb socket. Shutting down.\n", revents); close(gdb_fd); gdb_fd = 0; } } if(fds[0].revents && server_fd) { if(fds[0].revents & POLLIN) { JTAGRequest(); goto rebuild; } else { /* Error Occurred */ fprintf(stderr, "Received flags 0x%08x on server. Shutting down.\n", fds[0].revents); close(server_fd); server_fd = 0; serverPort = 0; serverIP = 0; return; } } break; } /* End of switch statement */ } /* End of while statement */}void JTAGRequest() { struct sockaddr_in sa; struct sockaddr* addr = (struct sockaddr*)&sa; int n = sizeof(struct sockaddr_in); int fd = accept(server_fd, addr, &n); int on_off = 0; /* Turn off Nagel's algorithm on the socket */ int flags; char sTemp[256]; if(fd < 0) { /* This is valid, because a connection could have started, and then terminated due to a protocol error or user initiation before the accept could take place. */ if(errno != EWOULDBLOCK && errno != EAGAIN) { perror("accept"); close(server_fd); server_fd = 0; serverPort = 0; serverIP = 0; } return; } if(gdb_fd) { close(fd); return; } if((flags = fcntl(fd, F_GETFL,0)) < 0) { sprintf(sTemp, "Unable to get flags for gdb socket %d", fd); perror(sTemp); close(fd); return; } if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { sprintf(sTemp, "Unable to set flags for gdb socket %d to value 0x%08x", fd, flags | O_NONBLOCK); perror(sTemp); close(fd); return; } if(setsockopt(fd, tcp_level, TCP_NODELAY, &on_off, sizeof(int)) < 0) { sprintf(sTemp, "Unable to disable Nagel's algorithm for socket %d.\nsetsockopt", fd); perror(sTemp); close(fd); return; } gdb_fd = fd;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -