📄 skyeye2gdb.c
字号:
/* debugger: Remote server for GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "skyeye2gdb.h"#include "skyeye_types.h"#include <setjmp.h>#include <stdio.h>#include <string.h>#include <sys/file.h>//koodailar remove it for mingw 2005.12.18--------------------------------------#ifndef __MINGW32__#include <netinet/in.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/tcp.h>#include <sys/ioctl.h>#endif//end --------------------------------------------------------------------------#include <signal.h>#include <fcntl.h>#undef DEBUG_RDI//#define DEBUG_RDI#ifdef DEBUG_RDI #define DBG_RDI(args...) printf(args)#else #define DBG_RDI(args...) #endiftypedef unsigned long CORE_ADDR;//int remote_debug = 1;int remote_debug = 0;static int remote_desc;jmp_buf toplevel;int extended_protocol;int general_thread;int cont_thread;unsigned char registers[REGISTER_BYTES];struct SkyEye_ICE skyeye_ice;/* Open a connection to a remote debugger. NAME is the filename used for communication. *///koodailar remove it for mingw-------------------------------------------------//actually i can include <winsock.h> and <winsock2.h>//but i am lazy ...#ifdef __MINGW32__void remote_open(char * name){}#elsevoidremote_open (char *name){ int save_fcntl_flags; char *port_str; int port; struct sockaddr_in sockaddr; int tmp; struct protoent *protoent; int tmp_desc; port_str = strchr (name, ':'); port = atoi (port_str + 1); tmp_desc = socket (PF_INET, SOCK_STREAM, 0); if (tmp_desc < 0) perror ("Can't open socket"); /* Allow rapid reuse of this port. */ tmp = 1; setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp)); sockaddr.sin_family = PF_INET; sockaddr.sin_port = htons (port); sockaddr.sin_addr.s_addr = INADDR_ANY; if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) || listen (tmp_desc, 1)) perror ("Can't bind address"); tmp = sizeof (sockaddr); remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp); if (remote_desc == -1) perror ("Accept failed"); /* Enable TCP keep alive process. */ tmp = 1; setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp)); /* Tell TCP not to delay small packets. This greatly speeds up interactive response. */ tmp = 1; setsockopt (remote_desc, 6 /* PROTO_TCP */ , TCP_NODELAY, (char *) &tmp, sizeof (tmp)); close (tmp_desc); /* No longer need this */ signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply exits when the remote side dies. */#if 0 //chy 20050729-------------------#if defined(F_SETFL) && defined (FASYNC) save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0); fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC); disable_async_io ();#endif /* FASYNC */#endif //chy 20050729------------------- fprintf (stderr, "Remote debugging using %s\n", name);}#endif//end koodailar ---------------------------------------------------------------voidremote_close (){ close (remote_desc);}/* Convert hex digit A to a number. */static intfromhex (int a){ if (a >= '0' && a <= '9') return a - '0'; else if (a >= 'a' && a <= 'f') return a - 'a' + 10; else perror ("Reply contains invalid hex digit");}/* Convert number NIB to a hex digit. */static inttohex (int nib){ if (nib < 10) return '0' + nib; else return 'a' + nib - 10;}/* Send a packet to the remote machine, with error checking. The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */intputpkt (char *buf){ int i; unsigned char csum = 0; char buf2[2000]; char buf3[1]; int cnt = strlen (buf); char *p; /* Copy the packet into buffer BUF2, encapsulating it and giving it a checksum. */ p = buf2; *p++ = '$'; for (i = 0; i < cnt; i++) { csum += buf[i]; *p++ = buf[i]; } *p++ = '#'; *p++ = tohex ((csum >> 4) & 0xf); *p++ = tohex (csum & 0xf); *p = '\0'; /* Send it over and over until we get a positive ack. */ do { int cc; if (write (remote_desc, buf2, p - buf2) != p - buf2) { perror ("putpkt(write)"); return -1; } if (remote_debug) DBG_RDI ("putpkt (\"%s\"); [looking for ack]\n", buf2); cc = read (remote_desc, buf3, 1); if (remote_debug) DBG_RDI ("[received '%c' (0x%x)]\n", buf3[0], buf3[0]); if (cc <= 0) { if (cc == 0) fprintf (stderr, "putpkt(read): Got EOF\n"); else perror ("putpkt(read)"); return -1; } } while (buf3[0] != '+'); return 1; /* Success! */}/* Come here when we get an input interrupt from the remote side. This interrupt should only be active while we are waiting for the child to do something. About the only thing that should come through is a ^C, which will cause us to send a SIGINT to the child. */static voidinput_interrupt (){ int cc; char c; cc = read (remote_desc, &c, 1); if (cc != 1 || c != '\003') { fprintf (stderr, "input_interrupt, cc = %d c = %d\n", cc, c); return; } DBG_RDI ("SkyEye debugger: input_interrupt: get a ctrl-c\n"); skyeye_exit (-1); //kill (inferior_pid, SIGINT);}voidenable_async_io (){//koodailar remove it for mingw 2005.12.18--------------------------------------#ifndef __MINGW32__ signal (SIGIO, input_interrupt);#endif//end -------------------------------------------------------------------------- }voiddisable_async_io (){//koodailar remove it for mingw 2005.12.18--------------------------------------#ifndef __MINGW32__ signal (SIGIO, SIG_IGN);#endif //end -------------------------------------------------------------------------- }/* Returns next char from remote GDB. -1 if error. */static intreadchar (){ static char buf[BUFSIZ]; static int bufcnt = 0; static char *bufp; if (bufcnt-- > 0) return *bufp++ & 0x7f; bufcnt = read (remote_desc, buf, sizeof (buf)); if (bufcnt <= 0) { if (bufcnt == 0) fprintf (stderr, "readchar: Got EOF\n"); else perror ("readchar"); return -1; } bufp = buf; bufcnt--; return *bufp++ & 0x7f;}/* Read a packet from the remote machine, with error checking, and store it in BUF. Returns length of packet, or negative if error. */intgetpkt (char *buf){ char *bp; unsigned char csum, c1, c2; int c; while (1) { csum = 0; while (1) { c = readchar (); if (c == '$') break; if (remote_debug) DBG_RDI ("[getpkt: discarding char '%c']\n", c); if (c < 0) return -1; } bp = buf; while (1) { c = readchar (); if (c < 0) return -1; if (c == '#') break; *bp++ = c; csum += c; } *bp = 0; c1 = fromhex (readchar ()); c2 = fromhex (readchar ()); if (csum == (c1 << 4) + c2) break; fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n", (c1 << 4) + c2, csum, buf); write (remote_desc, "-", 1); } if (remote_debug) DBG_RDI ("getpkt (\"%s\"); [sending ack] \n", buf); write (remote_desc, "+", 1); if (remote_debug) DBG_RDI ("[sent ack]\n"); return bp - buf;}voidwrite_ok (char *buf){ buf[0] = 'O'; buf[1] = 'K'; buf[2] = '\0';}voidwrite_enn (char *buf){ buf[0] = 'E'; buf[1] = 'N'; buf[2] = 'N'; buf[3] = '\0';}voidconvert_int_to_ascii (char *from, char *to, int n){ int nib; char ch; while (n--) { ch = *from++; nib = ((ch & 0xf0) >> 4) & 0x0f; *to++ = tohex (nib); nib = ch & 0x0f; *to++ = tohex (nib); } *to++ = 0;}voidconvert_ascii_to_int (char *from, char *to, int n){ int nib1, nib2; while (n--) { nib1 = fromhex (*from++); nib2 = fromhex (*from++); *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f); }}static char *outreg (int regno, char *buf){ extern unsigned char registers[]; int regsize = REGISTER_RAW_SIZE (regno); *buf++ = tohex (regno >> 4); *buf++ = tohex (regno & 0xf); *buf++ = ':'; convert_int_to_ascii (®isters[REGISTER_BYTE (regno)], buf, regsize); buf += 2 * regsize; *buf++ = ';'; return buf;}voidprepare_resume_reply (char *buf, char status, unsigned char signo){ int nib; *buf++ = status; /* FIXME! Should be converting this signal number (numbered according to the signal numbering of the system we are running on) to the signal numbers used by the gdb protocol (see enum target_signal in gdb/target.h). */ nib = ((signo & 0xf0) >> 4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -