📄 remote-utils.c
字号:
sigset_t sigio_set; sigemptyset (&sigio_set); sigaddset (&sigio_set, SIGIO); sigprocmask (SIG_UNBLOCK, &sigio_set, NULL);}/* Asynchronous I/O support. SIGIO must be enabled when waiting, in order to accept Control-C from the client, and must be disabled when talking to the client. *//* Current state of asynchronous I/O. */static int async_io_enabled;/* Enable asynchronous I/O. */voidenable_async_io (void){ if (async_io_enabled) return; signal (SIGIO, input_interrupt); async_io_enabled = 1;}/* Disable asynchronous I/O. */voiddisable_async_io (void){ if (!async_io_enabled) return; signal (SIGIO, SIG_IGN); async_io_enabled = 0;}/* Returns next char from remote GDB. -1 if error. */static intreadchar (void){ 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) { fprintf (stderr, "[getpkt: discarding char '%c']\n", c); fflush (stderr); } 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) { fprintf (stderr, "getpkt (\"%s\"); [sending ack] \n", buf); fflush (stderr); } write (remote_desc, "+", 1); if (remote_debug) { fprintf (stderr, "[sent ack]\n"); fflush (stderr); } return bp - buf;}voidwrite_ok (char *buf){ buf[0] = 'O'; buf[1] = 'K'; buf[2] = '\0';}voidwrite_enn (char *buf){ /* Some day, we should define the meanings of the error codes... */ buf[0] = 'E'; buf[1] = '0'; buf[2] = '1'; 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){ if ((regno >> 12) != 0) *buf++ = tohex ((regno >> 12) & 0xf); if ((regno >> 8) != 0) *buf++ = tohex ((regno >> 8) & 0xf); *buf++ = tohex ((regno >> 4) & 0xf); *buf++ = tohex (regno & 0xf); *buf++ = ':'; collect_register_as_string (regno, buf); buf += 2 * register_size (regno); *buf++ = ';'; return buf;}voidnew_thread_notify (int id){ char own_buf[256]; /* The `n' response is not yet part of the remote protocol. Do nothing. */ if (1) return; if (server_waiting == 0) return; sprintf (own_buf, "n%x", id); disable_async_io (); putpkt (own_buf); enable_async_io ();}voiddead_thread_notify (int id){ char own_buf[256]; /* The `x' response is not yet part of the remote protocol. Do nothing. */ if (1) return; sprintf (own_buf, "x%x", id); disable_async_io (); putpkt (own_buf); enable_async_io ();}voidprepare_resume_reply (char *buf, char status, unsigned char signo){ int nib, sig; *buf++ = status; sig = (int)target_signal_from_host (signo); nib = ((sig & 0xf0) >> 4); *buf++ = tohex (nib); nib = sig & 0x0f; *buf++ = tohex (nib); if (status == 'T') { const char **regp = gdbserver_expedite_regs; while (*regp) { buf = outreg (find_regno (*regp), buf); regp ++; } /* Formerly, if the debugger had not used any thread features we would not burden it with a thread status response. This was for the benefit of GDB 4.13 and older. However, in recent GDB versions the check (``if (cont_thread != 0)'') does not have the desired effect because of sillyness in the way that the remote protocol handles specifying a thread. Since thread support relies on qSymbol support anyway, assume GDB can handle threads. */ if (using_threads) { /* FIXME right place to set this? */ thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id; if (debug_threads) fprintf (stderr, "Writing resume reply for %d\n\n", thread_from_wait); /* This if (1) ought to be unnecessary. But remote_wait in GDB will claim this event belongs to inferior_ptid if we do not specify a thread, and there's no way for gdbserver to know what inferior_ptid is. */ if (1 || old_thread_from_wait != thread_from_wait) { general_thread = thread_from_wait; sprintf (buf, "thread:%x;", thread_from_wait); buf += strlen (buf); old_thread_from_wait = thread_from_wait; } } } /* For W and X, we're done. */ *buf++ = 0;}voiddecode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr){ int i = 0, j = 0; char ch; *mem_addr_ptr = *len_ptr = 0; while ((ch = from[i++]) != ',') { *mem_addr_ptr = *mem_addr_ptr << 4; *mem_addr_ptr |= fromhex (ch) & 0x0f; } for (j = 0; j < 4; j++) { if ((ch = from[i++]) == 0) break; *len_ptr = *len_ptr << 4; *len_ptr |= fromhex (ch) & 0x0f; }}voiddecode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr, char *to){ int i = 0; char ch; *mem_addr_ptr = *len_ptr = 0; while ((ch = from[i++]) != ',') { *mem_addr_ptr = *mem_addr_ptr << 4; *mem_addr_ptr |= fromhex (ch) & 0x0f; } while ((ch = from[i++]) != ':') { *len_ptr = *len_ptr << 4; *len_ptr |= fromhex (ch) & 0x0f; } convert_ascii_to_int (&from[i++], to, *len_ptr);}/* Ask GDB for the address of NAME, and return it in ADDRP if found. Returns 1 if the symbol is found, 0 if it is not, -1 on error. */intlook_up_one_symbol (const char *name, CORE_ADDR *addrp){ char own_buf[266], *p, *q; int len; struct sym_cache *sym; /* Check the cache first. */ for (sym = symbol_cache; sym; sym = sym->next) if (strcmp (name, sym->name) == 0) { *addrp = sym->addr; return 1; } /* Send the request. */ strcpy (own_buf, "qSymbol:"); hexify (own_buf + strlen ("qSymbol:"), name, strlen (name)); if (putpkt (own_buf) < 0) return -1; /* FIXME: Eventually add buffer overflow checking (to getpkt?) */ len = getpkt (own_buf); if (len < 0) return -1; if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0) { /* Malformed response. */ if (remote_debug) { fprintf (stderr, "Malformed response to qSymbol, ignoring.\n"); fflush (stderr); } return -1; } p = own_buf + strlen ("qSymbol:"); q = p; while (*q && *q != ':') q++; /* Make sure we found a value for the symbol. */ if (p == q || *q == '\0') return 0; decode_address (addrp, p, q - p); /* Save the symbol in our cache. */ sym = malloc (sizeof (*sym)); sym->name = strdup (name); sym->addr = *addrp; sym->next = symbol_cache; symbol_cache = sym; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -