X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdbserver%2Fremote-utils.cc;h=db9b2a66f3cbd6f4d4237dea5b05b2f200c19e4a;hb=0d02e70b197c786f26175b9a73f94e01d14abdab;hp=1c211e2572096eae4df94a37e22f54672f87f981;hpb=442131c1bec1a2ff0b3a5e5d1d91a116ce869dee;p=binutils-gdb.git diff --git a/gdbserver/remote-utils.cc b/gdbserver/remote-utils.cc index 1c211e25720..db9b2a66f3c 100644 --- a/gdbserver/remote-utils.cc +++ b/gdbserver/remote-utils.cc @@ -1,5 +1,5 @@ /* Remote utility routines for the remote server for GDB. - Copyright (C) 1986-2020 Free Software Foundation, Inc. + Copyright (C) 1986-2022 Free Software Foundation, Inc. This file is part of GDB. @@ -68,22 +68,12 @@ #include #endif -#if __QNX__ -#include -#endif /* __QNX__ */ - #ifndef HAVE_SOCKLEN_T typedef int socklen_t; #endif #ifndef IN_PROCESS_AGENT -#if USE_WIN32API -# define INVALID_DESCRIPTOR INVALID_SOCKET -#else -# define INVALID_DESCRIPTOR -1 -#endif - /* Extra value for readchar_callback. */ enum { /* The callback is currently not scheduled. */ @@ -108,10 +98,14 @@ struct sym_cache static int remote_is_stdio = 0; -static gdb_fildes_t remote_desc = INVALID_DESCRIPTOR; -static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR; +static int remote_desc = -1; +static int listen_desc = -1; #ifdef USE_WIN32API +/* gnulib wraps these as macros, undo them. */ +# undef read +# undef write + # define read(fd, buf, len) recv (fd, (char *) buf, len, 0) # define write(fd, buf, len) send (fd, (char *) buf, len, 0) #endif @@ -119,7 +113,7 @@ static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR; int gdb_connected (void) { - return remote_desc != INVALID_DESCRIPTOR; + return remote_desc != -1; } /* Return true if the remote connection is over stdio. */ @@ -144,14 +138,13 @@ enable_async_notification (int fd) #endif } -static int +static void handle_accept_event (int err, gdb_client_data client_data) { struct sockaddr_storage sockaddr; socklen_t len = sizeof (sockaddr); - if (debug_threads) - debug_printf ("handling possible accept event\n"); + threads_debug_printf ("handling possible accept event"); remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &len); if (remote_desc == -1) @@ -204,7 +197,7 @@ handle_accept_event (int err, gdb_client_data client_data) enable_async_notification (remote_desc); /* Register the event loop handler. */ - add_file_handler (remote_desc, handle_serial_event, NULL); + add_file_handler (remote_desc, handle_serial_event, NULL, "remote-net"); /* We have a new GDB connection now. If we were disconnected tracing, there's a window where the target could report a stop @@ -213,8 +206,6 @@ handle_accept_event (int err, gdb_client_data client_data) until GDB as selected all-stop/non-stop, and has queried the threads' status ('?'). */ target_async (0); - - return 0; } /* Prepare for a later connection to a remote debugger. @@ -343,7 +334,7 @@ remote_open (const char *name) enable_async_notification (remote_desc); /* Register the event loop handler. */ - add_file_handler (remote_desc, handle_serial_event, NULL); + add_file_handler (remote_desc, handle_serial_event, NULL, "remote-stdio"); } #ifndef USE_WIN32API else if (port_str == NULL) @@ -384,7 +375,8 @@ remote_open (const char *name) enable_async_notification (remote_desc); /* Register the event loop handler. */ - add_file_handler (remote_desc, handle_serial_event, NULL); + add_file_handler (remote_desc, handle_serial_event, NULL, + "remote-device"); } #endif /* USE_WIN32API */ else @@ -410,7 +402,8 @@ remote_open (const char *name) fflush (stderr); /* Register the event loop handler. */ - add_file_handler (listen_desc, handle_accept_event, NULL); + add_file_handler (listen_desc, handle_accept_event, NULL, + "remote-listen"); } } @@ -427,7 +420,7 @@ remote_close (void) if (! remote_connection_is_stdio ()) close (remote_desc); #endif - remote_desc = INVALID_DESCRIPTOR; + remote_desc = -1; reset_readchar (); } @@ -587,7 +580,7 @@ read_ptid (const char *buf, const char **obuf) if (obuf) *obuf = pp; - return ptid_t (pid, tid, 0); + return ptid_t (pid, tid); } /* No multi-process. Just a tid. */ @@ -600,7 +593,7 @@ read_ptid (const char *buf, const char **obuf) if (obuf) *obuf = pp; - return ptid_t (pid, tid, 0); + return ptid_t (pid, tid); } /* Write COUNT bytes in BUF to the client. @@ -677,22 +670,15 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif) if (cs.noack_mode || is_notif) { /* Don't expect an ack then. */ - if (remote_debug) - { - if (is_notif) - debug_printf ("putpkt (\"%s\"); [notif]\n", buf2); - else - debug_printf ("putpkt (\"%s\"); [noack mode]\n", buf2); - debug_flush (); - } + if (is_notif) + remote_debug_printf ("putpkt (\"%s\"); [notif]", buf2); + else + remote_debug_printf ("putpkt (\"%s\"); [noack mode]", buf2); + break; } - if (remote_debug) - { - debug_printf ("putpkt (\"%s\"); [looking for ack]\n", buf2); - debug_flush (); - } + remote_debug_printf ("putpkt (\"%s\"); [looking for ack]", buf2); cc = readchar (); @@ -702,11 +688,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif) return -1; } - if (remote_debug) - { - debug_printf ("[received '%c' (0x%x)]\n", cc, cc); - debug_flush (); - } + remote_debug_printf ("[received '%c' (0x%x)]", cc, cc); /* Check for an input interrupt while we're here. */ if (cc == '\003' && current_thread != NULL) @@ -790,7 +772,7 @@ check_remote_input_interrupt_request (void) /* This function may be called before establishing communications, therefore we need to validate the remote descriptor. */ - if (remote_desc == INVALID_DESCRIPTOR) + if (remote_desc == -1) return; input_interrupt (0); @@ -812,28 +794,6 @@ block_unblock_async_io (int block) #endif } -#ifdef __QNX__ -static void -nto_comctrl (int enable) -{ - struct sigevent event; - - if (enable) - { - event.sigev_notify = SIGEV_SIGNAL_THREAD; - event.sigev_signo = SIGIO; - event.sigev_code = 0; - event.sigev_value.sival_ptr = NULL; - event.sigev_priority = -1; - ionotify (remote_desc, _NOTIFY_ACTION_POLLARM, _NOTIFY_COND_INPUT, - &event); - } - else - ionotify (remote_desc, _NOTIFY_ACTION_POLL, _NOTIFY_COND_INPUT, NULL); -} -#endif /* __QNX__ */ - - /* Current state of asynchronous I/O. */ static int async_io_enabled; @@ -847,9 +807,6 @@ enable_async_io (void) block_unblock_async_io (0); async_io_enabled = 1; -#ifdef __QNX__ - nto_comctrl (1); -#endif /* __QNX__ */ } /* Disable asynchronous I/O. */ @@ -862,10 +819,6 @@ disable_async_io (void) block_unblock_async_io (1); async_io_enabled = 0; -#ifdef __QNX__ - nto_comctrl (0); -#endif /* __QNX__ */ - } void @@ -904,8 +857,7 @@ readchar (void) { if (readchar_bufcnt == 0) { - if (remote_debug) - debug_printf ("readchar: Got EOF\n"); + remote_debug_printf ("readchar: Got EOF"); } else perror ("readchar"); @@ -930,27 +882,21 @@ reset_readchar (void) readchar_bufcnt = 0; if (readchar_callback != NOT_SCHEDULED) { - delete_callback_event (readchar_callback); + delete_timer (readchar_callback); readchar_callback = NOT_SCHEDULED; } } /* Process remaining data in readchar_buf. */ -static int +static void process_remaining (void *context) { - int res; - /* This is a one-shot event. */ readchar_callback = NOT_SCHEDULED; if (readchar_bufcnt > 0) - res = handle_serial_event (0, NULL); - else - res = 0; - - return res; + handle_serial_event (0, NULL); } /* If there is still data in the buffer, queue another event to process it, @@ -960,7 +906,7 @@ static void reschedule (void) { if (readchar_bufcnt > 0 && readchar_callback == NOT_SCHEDULED) - readchar_callback = append_callback_event (process_remaining, NULL); + readchar_callback = create_timer (0, process_remaining, NULL); } /* Read a packet from the remote machine, with error checking, @@ -992,11 +938,8 @@ getpkt (char *buf) if (c == '$') break; - if (remote_debug) - { - debug_printf ("[getpkt: discarding char '%c']\n", c); - debug_flush (); - } + + remote_debug_printf ("[getpkt: discarding char '%c']", c); if (c < 0) return -1; @@ -1039,29 +982,15 @@ getpkt (char *buf) if (!cs.noack_mode) { - if (remote_debug) - { - debug_printf ("getpkt (\"%s\"); [sending ack] \n", buf); - debug_flush (); - } + remote_debug_printf ("getpkt (\"%s\"); [sending ack]", buf); if (write_prim ("+", 1) != 1) return -1; - if (remote_debug) - { - debug_printf ("[sent ack]\n"); - debug_flush (); - } + remote_debug_printf ("[sent ack]"); } else - { - if (remote_debug) - { - debug_printf ("getpkt (\"%s\"); [no ack sent] \n", buf); - debug_flush (); - } - } + remote_debug_printf ("getpkt (\"%s\"); [no ack sent]", buf); /* The readchar above may have already read a '\003' out of the socket and moved it to the local buffer. For example, when GDB sends @@ -1122,15 +1051,13 @@ outreg (struct regcache *regcache, int regno, char *buf) } void -prepare_resume_reply (char *buf, ptid_t ptid, - struct target_waitstatus *status) +prepare_resume_reply (char *buf, ptid_t ptid, const target_waitstatus &status) { client_state &cs = get_client_state (); - if (debug_threads) - debug_printf ("Writing resume reply for %s:%d\n", - target_pid_to_str (ptid), status->kind); + threads_debug_printf ("Writing resume reply for %s:%d", + target_pid_to_str (ptid).c_str (), status.kind ()); - switch (status->kind) + switch (status.kind ()) { case TARGET_WAITKIND_STOPPED: case TARGET_WAITKIND_FORKED: @@ -1141,31 +1068,31 @@ prepare_resume_reply (char *buf, ptid_t ptid, case TARGET_WAITKIND_SYSCALL_ENTRY: case TARGET_WAITKIND_SYSCALL_RETURN: { - struct thread_info *saved_thread; const char **regp; struct regcache *regcache; + char *buf_start = buf; - if ((status->kind == TARGET_WAITKIND_FORKED && cs.report_fork_events) - || (status->kind == TARGET_WAITKIND_VFORKED + if ((status.kind () == TARGET_WAITKIND_FORKED && cs.report_fork_events) + || (status.kind () == TARGET_WAITKIND_VFORKED && cs.report_vfork_events)) { enum gdb_signal signal = GDB_SIGNAL_TRAP; - const char *event = (status->kind == TARGET_WAITKIND_FORKED + const char *event = (status.kind () == TARGET_WAITKIND_FORKED ? "fork" : "vfork"); sprintf (buf, "T%02x%s:", signal, event); buf += strlen (buf); - buf = write_ptid (buf, status->value.related_pid); + buf = write_ptid (buf, status.child_ptid ()); strcat (buf, ";"); } - else if (status->kind == TARGET_WAITKIND_VFORK_DONE + else if (status.kind () == TARGET_WAITKIND_VFORK_DONE && cs.report_vfork_events) { enum gdb_signal signal = GDB_SIGNAL_TRAP; sprintf (buf, "T%02xvforkdone:;", signal); } - else if (status->kind == TARGET_WAITKIND_EXECD && cs.report_exec_events) + else if (status.kind () == TARGET_WAITKIND_EXECD && cs.report_exec_events) { enum gdb_signal signal = GDB_SIGNAL_TRAP; const char *event = "exec"; @@ -1175,34 +1102,32 @@ prepare_resume_reply (char *buf, ptid_t ptid, buf += strlen (buf); /* Encode pathname to hexified format. */ - bin2hex ((const gdb_byte *) status->value.execd_pathname, + bin2hex ((const gdb_byte *) status.execd_pathname (), hexified_pathname, - strlen (status->value.execd_pathname)); + strlen (status.execd_pathname ())); sprintf (buf, "%s;", hexified_pathname); - xfree (status->value.execd_pathname); - status->value.execd_pathname = NULL; buf += strlen (buf); } - else if (status->kind == TARGET_WAITKIND_THREAD_CREATED + else if (status.kind () == TARGET_WAITKIND_THREAD_CREATED && cs.report_thread_events) { enum gdb_signal signal = GDB_SIGNAL_TRAP; sprintf (buf, "T%02xcreate:;", signal); } - else if (status->kind == TARGET_WAITKIND_SYSCALL_ENTRY - || status->kind == TARGET_WAITKIND_SYSCALL_RETURN) + else if (status.kind () == TARGET_WAITKIND_SYSCALL_ENTRY + || status.kind () == TARGET_WAITKIND_SYSCALL_RETURN) { enum gdb_signal signal = GDB_SIGNAL_TRAP; - const char *event = (status->kind == TARGET_WAITKIND_SYSCALL_ENTRY + const char *event = (status.kind () == TARGET_WAITKIND_SYSCALL_ENTRY ? "syscall_entry" : "syscall_return"); sprintf (buf, "T%02x%s:%x;", signal, event, - status->value.syscall_number); + status.syscall_number ()); } else - sprintf (buf, "T%02x", status->value.sig); + sprintf (buf, "T%02x", status.sig ()); if (disable_packet_T) { @@ -1216,17 +1141,17 @@ prepare_resume_reply (char *buf, ptid_t ptid, An 'S' stop packet always looks like 'Sxx', so all we do here is convert the buffer from a T packet to an S packet and the avoid adding any extra content by breaking out. */ - gdb_assert (*buf == 'T'); - gdb_assert (isxdigit (*(buf + 1))); - gdb_assert (isxdigit (*(buf + 2))); - *buf = 'S'; - *(buf + 3) = '\0'; + gdb_assert (buf_start[0] == 'T'); + gdb_assert (isxdigit (buf_start[1])); + gdb_assert (isxdigit (buf_start[2])); + buf_start[0] = 'S'; + buf_start[3] = '\0'; break; } buf += strlen (buf); - saved_thread = current_thread; + scoped_restore_current_thread restore_thread; switch_to_thread (the_target, ptid); @@ -1311,32 +1236,30 @@ prepare_resume_reply (char *buf, ptid_t ptid, } } - if (dlls_changed) + if (current_process ()->dlls_changed) { strcpy (buf, "library:;"); buf += strlen (buf); - dlls_changed = 0; + current_process ()->dlls_changed = false; } - - current_thread = saved_thread; } break; case TARGET_WAITKIND_EXITED: if (cs.multi_process) sprintf (buf, "W%x;process:%x", - status->value.integer, ptid.pid ()); + status.exit_status (), ptid.pid ()); else - sprintf (buf, "W%02x", status->value.integer); + sprintf (buf, "W%02x", status.exit_status ()); break; case TARGET_WAITKIND_SIGNALLED: if (cs.multi_process) sprintf (buf, "X%x;process:%x", - status->value.sig, ptid.pid ()); + status.sig (), ptid.pid ()); else - sprintf (buf, "X%02x", status->value.sig); + sprintf (buf, "X%02x", status.sig ()); break; case TARGET_WAITKIND_THREAD_EXITED: - sprintf (buf, "w%x;", status->value.integer); + sprintf (buf, "w%x;", status.exit_status ()); buf += strlen (buf); buf = write_ptid (buf, ptid); break; @@ -1349,10 +1272,13 @@ prepare_resume_reply (char *buf, ptid_t ptid, } } -void -decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr) +/* See remote-utils.h. */ + +const char * +decode_m_packet_params (const char *from, CORE_ADDR *mem_addr_ptr, + unsigned int *len_ptr, const char end_marker) { - int i = 0, j = 0; + int i = 0; char ch; *mem_addr_ptr = *len_ptr = 0; @@ -1362,39 +1288,32 @@ decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr) *mem_addr_ptr |= fromhex (ch) & 0x0f; } - for (j = 0; j < 4; j++) + while ((ch = from[i++]) != end_marker) { - if ((ch = from[i++]) == 0) - break; *len_ptr = *len_ptr << 4; *len_ptr |= fromhex (ch) & 0x0f; } + + return from + i; } void -decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr, - unsigned char **to_p) +decode_m_packet (const char *from, CORE_ADDR *mem_addr_ptr, + unsigned int *len_ptr) { - 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; - } + decode_m_packet_params (from, mem_addr_ptr, len_ptr, '\0'); +} - while ((ch = from[i++]) != ':') - { - *len_ptr = *len_ptr << 4; - *len_ptr |= fromhex (ch) & 0x0f; - } +void +decode_M_packet (const char *from, CORE_ADDR *mem_addr_ptr, + unsigned int *len_ptr, unsigned char **to_p) +{ + from = decode_m_packet_params (from, mem_addr_ptr, len_ptr, ':'); if (*to_p == NULL) *to_p = (unsigned char *) xmalloc (*len_ptr); - hex2bin (&from[i++], *to_p, *len_ptr); + hex2bin (from, *to_p, *len_ptr); } int