X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fremote.c;h=b60a89c6b20d425cb0a924476bd6273c96bc921d;hb=3dd5b83d5bd7977bb5b98c9ef9bd8345c0f26d80;hp=ad473cc2ce4a03b5ae44214a1924354ac96c4df7;hpb=eeae04df5210d8d569775a1088c084c1a9509545;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote.c b/gdb/remote.c index ad473cc2ce..b60a89c6b2 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -134,8 +134,6 @@ static int remote_is_async_p (void); static void remote_async (void (*callback) (enum inferior_event_type event_type, void *context), void *context); -static int remote_async_mask (int new_mask); - static void remote_detach (struct target_ops *ops, char *args, int from_tty); static void remote_interrupt (int signo); @@ -329,6 +327,10 @@ struct remote_state disconnected. */ int disconnected_tracing; + /* True if the stub reports support for enabling and disabling + tracepoints while a trace experiment is running. */ + int enable_disable_tracepoints; + /* Nonzero if the user has pressed Ctrl-C, but the target hasn't responded to that. */ int ctrlc_pending_p; @@ -535,24 +537,15 @@ compare_pnums (const void *lhs_, const void *rhs_) return 1; } -static void * -init_remote_state (struct gdbarch *gdbarch) +static int +map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs) { int regnum, num_remote_regs, offset; - struct remote_state *rs = get_remote_state_raw (); - struct remote_arch_state *rsa; struct packet_reg **remote_regs; - rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state); - - /* Use the architecture to build a regnum<->pnum table, which will be - 1:1 unless a feature set specifies otherwise. */ - rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, - gdbarch_num_regs (gdbarch), - struct packet_reg); for (regnum = 0; regnum < gdbarch_num_regs (gdbarch); regnum++) { - struct packet_reg *r = &rsa->regs[regnum]; + struct packet_reg *r = ®s[regnum]; if (register_size (gdbarch, regnum) == 0) /* Do not try to fetch zero-sized (placeholder) registers. */ @@ -568,12 +561,12 @@ init_remote_state (struct gdbarch *gdbarch) number. */ remote_regs = alloca (gdbarch_num_regs (gdbarch) - * sizeof (struct packet_reg *)); + * sizeof (struct packet_reg *)); for (num_remote_regs = 0, regnum = 0; regnum < gdbarch_num_regs (gdbarch); regnum++) - if (rsa->regs[regnum].pnum != -1) - remote_regs[num_remote_regs++] = &rsa->regs[regnum]; + if (regs[regnum].pnum != -1) + remote_regs[num_remote_regs++] = ®s[regnum]; qsort (remote_regs, num_remote_regs, sizeof (struct packet_reg *), compare_pnums); @@ -585,9 +578,55 @@ init_remote_state (struct gdbarch *gdbarch) offset += register_size (gdbarch, remote_regs[regnum]->regnum); } + return offset; +} + +/* Given the architecture described by GDBARCH, return the remote + protocol register's number and the register's offset in the g/G + packets of GDB register REGNUM, in PNUM and POFFSET respectively. + If the target does not have a mapping for REGNUM, return false, + otherwise, return true. */ + +int +remote_register_number_and_offset (struct gdbarch *gdbarch, int regnum, + int *pnum, int *poffset) +{ + int sizeof_g_packet; + struct packet_reg *regs; + struct cleanup *old_chain; + + gdb_assert (regnum < gdbarch_num_regs (gdbarch)); + + regs = xcalloc (gdbarch_num_regs (gdbarch), sizeof (struct packet_reg)); + old_chain = make_cleanup (xfree, regs); + + sizeof_g_packet = map_regcache_remote_table (gdbarch, regs); + + *pnum = regs[regnum].pnum; + *poffset = regs[regnum].offset; + + do_cleanups (old_chain); + + return *pnum != -1; +} + +static void * +init_remote_state (struct gdbarch *gdbarch) +{ + struct remote_state *rs = get_remote_state_raw (); + struct remote_arch_state *rsa; + + rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state); + + /* Use the architecture to build a regnum<->pnum table, which will be + 1:1 unless a feature set specifies otherwise. */ + rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, + gdbarch_num_regs (gdbarch), + struct packet_reg); + /* Record the maximum possible size of the g packet - it may turn out to be smaller. */ - rsa->sizeof_g_packet = offset; + rsa->sizeof_g_packet = map_regcache_remote_table (gdbarch, rsa->regs); /* Default maximum number of characters in a packet body. Many remote stubs have a hardwired buffer size of 400 bytes @@ -680,8 +719,6 @@ static struct target_ops remote_ops; static struct target_ops extended_remote_ops; -static int remote_async_mask_value = 1; - /* FIXME: cagney/1999-09-23: Even though getpkt was called with ``forever'' still use the normal timeout mechanism. This is currently used by the ASYNC code to guarentee that target reads @@ -1559,20 +1596,17 @@ static char *last_pass_packet; it can simply pass through to the inferior without reporting. */ static void -remote_pass_signals (void) +remote_pass_signals (int numsigs, unsigned char *pass_signals) { if (remote_protocol_packets[PACKET_QPassSignals].support != PACKET_DISABLE) { char *pass_packet, *p; - int numsigs = (int) TARGET_SIGNAL_LAST; int count = 0, i; gdb_assert (numsigs < 256); for (i = 0; i < numsigs; i++) { - if (signal_stop_state (i) == 0 - && signal_print_state (i) == 0 - && signal_pass_state (i) == 1) + if (pass_signals[i]) count++; } pass_packet = xmalloc (count * 3 + strlen ("QPassSignals:") + 1); @@ -1580,9 +1614,7 @@ remote_pass_signals (void) p = pass_packet + strlen (pass_packet); for (i = 0; i < numsigs; i++) { - if (signal_stop_state (i) == 0 - && signal_print_state (i) == 0 - && signal_pass_state (i) == 1) + if (pass_signals[i]) { if (i >= 16) *p++ = tohex (i >> 4); @@ -1612,14 +1644,6 @@ remote_pass_signals (void) } } -static void -remote_notice_signals (ptid_t ptid) -{ - /* Update the remote on signals to silently pass, if they've - changed. */ - remote_pass_signals (); -} - /* If PTID is MAGIC_NULL_PTID, don't set any thread. If PTID is MINUS_ONE_PTID, set the thread to -1, so the stub returns the thread. If GEN is set, set the general thread, if not, then set @@ -1876,7 +1900,7 @@ read_ptid (char *buf, char **obuf) /* Multi-process ptid. */ pp = unpack_varlen_hex (p + 1, &pid); if (*pp != '.') - error (_("invalid remote ptid: %s\n"), p); + error (_("invalid remote ptid: %s"), p); p = pp; pp = unpack_varlen_hex (p + 1, &tid); @@ -3097,19 +3121,6 @@ set_stop_requested_callback (struct thread_info *thread, void *data) return 0; } -/* Stub for catch_exception. */ - -struct start_remote_args -{ - int from_tty; - - /* The current target. */ - struct target_ops *target; - - /* Non-zero if this is an extended-remote target. */ - int extended_p; -}; - /* Send interrupt_sequence to remote target. */ static void send_interrupt_sequence (void) @@ -3130,21 +3141,20 @@ send_interrupt_sequence (void) } static void -remote_start_remote (struct ui_out *uiout, void *opaque) +remote_start_remote (int from_tty, struct target_ops *target, int extended_p) { - struct start_remote_args *args = opaque; struct remote_state *rs = get_remote_state (); struct packet_config *noack_config; char *wait_status = NULL; immediate_quit++; /* Allow user to interrupt it. */ - /* Ack any packet which the remote side has already sent. */ - serial_write (remote_desc, "+", 1); - if (interrupt_on_connect) send_interrupt_sequence (); + /* Ack any packet which the remote side has already sent. */ + serial_write (remote_desc, "+", 1); + /* The first packet we send to the target is the optional "supported packets" request. If the target can answer this, it will tell us which later probes to skip. */ @@ -3179,7 +3189,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque) rs->noack_mode = 1; } - if (args->extended_p) + if (extended_p) { /* Tell the remote that we are using the extended protocol. */ putpkt ("!"); @@ -3197,7 +3207,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque) /* On OSs where the list of libraries is global to all processes, we fetch them early. */ if (gdbarch_has_global_solist (target_gdbarch)) - solib_add (NULL, args->from_tty, args->target, auto_solib_add); + solib_add (NULL, from_tty, target, auto_solib_add); if (non_stop) { @@ -3215,7 +3225,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque) controlling. We default to adding them in the running state. The '?' query below will then tell us about which threads are stopped. */ - remote_threads_info (args->target); + remote_threads_info (target); } else if (rs->non_stop_aware) { @@ -3236,7 +3246,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque) { if (rs->buf[0] == 'W' || rs->buf[0] == 'X') { - if (!args->extended_p) + if (!extended_p) error (_("The target is not running (try extended-remote?)")); /* We're connected, but not running. Drop out before we @@ -3276,7 +3286,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque) how to do it some other way, try again. This is not supported for non-stop; it could be, but it is tricky if there are no stopped threads when we connect. */ - if (remote_read_description_p (args->target) + if (remote_read_description_p (target) && gdbarch_target_desc (target_gdbarch) == NULL) { target_clear_description (); @@ -3289,7 +3299,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque) rs->cached_wait_status = 1; immediate_quit--; - start_remote (args->from_tty); /* Initialize gdb process mechanisms. */ + start_remote (from_tty); /* Initialize gdb process mechanisms. */ } else { @@ -3331,7 +3341,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque) if (thread_count () == 0) { - if (!args->extended_p) + if (!extended_p) error (_("The target is not running (try extended-remote?)")); /* We're connected, but not running. Drop out before we @@ -3355,10 +3365,8 @@ remote_start_remote (struct ui_out *uiout, void *opaque) the stop reply queue. */ gdb_assert (wait_status == NULL); - /* Update the remote on signals to silently pass, or more - importantly, which to not ignore, in case a previous session - had set some different set of signals to be ignored. */ - remote_pass_signals (); + /* Report all signals during attach/startup. */ + remote_pass_signals (0, NULL); } /* If we connected to a live target, do some additional setup. */ @@ -3537,7 +3545,7 @@ remote_set_permissions (void) /* If the target didn't like the packet, warn the user. Do not try to undo the user's settings, that would just be maddening. */ if (strcmp (rs->buf, "OK") != 0) - warning ("Remote refused setting permissions with: %s", rs->buf); + warning (_("Remote refused setting permissions with: %s"), rs->buf); } /* This type describes each known response to the qSupported @@ -3681,6 +3689,16 @@ remote_disconnected_tracing_feature (const struct protocol_feature *feature, rs->disconnected_tracing = (support == PACKET_ENABLE); } +static void +remote_enable_disable_tracepoint_feature (const struct protocol_feature *feature, + enum packet_support support, + const char *value) +{ + struct remote_state *rs = get_remote_state (); + + rs->enable_disable_tracepoints = (support == PACKET_ENABLE); +} + static struct protocol_feature remote_protocol_features[] = { { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 }, { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet, @@ -3727,6 +3745,8 @@ static struct protocol_feature remote_protocol_features[] = { PACKET_TracepointSource }, { "QAllow", PACKET_DISABLE, remote_supported_packet, PACKET_QAllow }, + { "EnableDisableTracepoints", PACKET_DISABLE, + remote_enable_disable_tracepoint_feature, -1 }, }; static char *remote_support_xml; @@ -4060,14 +4080,12 @@ remote_open_1 (char *name, int from_tty, all the ``target ....'' commands to share a common callback function. See cli-dump.c. */ { - struct gdb_exception ex; - struct start_remote_args args; + volatile struct gdb_exception ex; - args.from_tty = from_tty; - args.target = target; - args.extended_p = extended_p; - - ex = catch_exception (uiout, remote_start_remote, &args, RETURN_MASK_ALL); + TRY_CATCH (ex, RETURN_MASK_ALL) + { + remote_start_remote (from_tty, target, extended_p); + } if (ex.reason < 0) { /* Pop the partially set up target - unless something else did @@ -4528,9 +4546,6 @@ remote_resume (struct target_ops *ops, last_sent_signal = siggnal; last_sent_step = step; - /* Update the inferior on signals to silently pass, if they've changed. */ - remote_pass_signals (); - /* The vCont packet doesn't need to specify threads via Hc. */ /* No reverse support (yet) for vCont. */ if (execution_direction != EXEC_REVERSE) @@ -4549,7 +4564,7 @@ remote_resume (struct target_ops *ops, { /* We don't pass signals to the target in reverse exec mode. */ if (info_verbose && siggnal != TARGET_SIGNAL_0) - warning (" - Can't pass signal %d to target in reverse: ignored.\n", + warning (_(" - Can't pass signal %d to target in reverse: ignored."), siggnal); if (step @@ -6210,7 +6225,7 @@ check_binary_download (CORE_ADDR addr) { if (remote_debug) fprintf_unfiltered (gdb_stdlog, - "binary downloading suppported by target\n"); + "binary downloading supported by target\n"); remote_protocol_packets[PACKET_X].support = PACKET_ENABLE; } break; @@ -9645,6 +9660,14 @@ remote_supports_static_tracepoints (void) return rs->static_tracepoints; } +static int +remote_supports_enable_disable_tracepoint (void) +{ + struct remote_state *rs = get_remote_state (); + + return rs->enable_disable_tracepoints; +} + static void remote_trace_init (void) { @@ -9915,6 +9938,38 @@ remote_download_trace_state_variable (struct trace_state_variable *tsv) error (_("Error on target while downloading trace state variable.")); } +static void +remote_enable_tracepoint (struct bp_location *location) +{ + struct remote_state *rs = get_remote_state (); + char addr_buf[40]; + + sprintf_vma (addr_buf, location->address); + sprintf (rs->buf, "QTEnable:%x:%s", location->owner->number, addr_buf); + putpkt (rs->buf); + remote_get_noisy_reply (&rs->buf, &rs->buf_size); + if (*rs->buf == '\0') + error (_("Target does not support enabling tracepoints while a trace run is ongoing.")); + if (strcmp (rs->buf, "OK") != 0) + error (_("Error on target while enabling tracepoint.")); +} + +static void +remote_disable_tracepoint (struct bp_location *location) +{ + struct remote_state *rs = get_remote_state (); + char addr_buf[40]; + + sprintf_vma (addr_buf, location->address); + sprintf (rs->buf, "QTDisable:%x:%s", location->owner->number, addr_buf); + putpkt (rs->buf); + remote_get_noisy_reply (&rs->buf, &rs->buf_size); + if (*rs->buf == '\0') + error (_("Target does not support disabling tracepoints while a trace run is ongoing.")); + if (strcmp (rs->buf, "OK") != 0) + error (_("Error on target while disabling tracepoint.")); +} + static void remote_trace_set_readonly_regions (void) { @@ -10272,7 +10327,7 @@ Specify the serial device it is connected to\n\ remote_ops.to_kill = remote_kill; remote_ops.to_load = generic_load; remote_ops.to_mourn_inferior = remote_mourn; - remote_ops.to_notice_signals = remote_notice_signals; + remote_ops.to_pass_signals = remote_pass_signals; remote_ops.to_thread_alive = remote_thread_alive; remote_ops.to_find_new_threads = remote_threads_info; remote_ops.to_pid_to_str = remote_pid_to_str; @@ -10300,15 +10355,17 @@ Specify the serial device it is connected to\n\ remote_ops.to_can_async_p = remote_can_async_p; remote_ops.to_is_async_p = remote_is_async_p; remote_ops.to_async = remote_async; - remote_ops.to_async_mask = remote_async_mask; remote_ops.to_terminal_inferior = remote_terminal_inferior; remote_ops.to_terminal_ours = remote_terminal_ours; remote_ops.to_supports_non_stop = remote_supports_non_stop; remote_ops.to_supports_multi_process = remote_supports_multi_process; + remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint; remote_ops.to_trace_init = remote_trace_init; remote_ops.to_download_tracepoint = remote_download_tracepoint; remote_ops.to_download_trace_state_variable = remote_download_trace_state_variable; + remote_ops.to_enable_tracepoint = remote_enable_tracepoint; + remote_ops.to_disable_tracepoint = remote_disable_tracepoint; remote_ops.to_trace_set_readonly_regions = remote_trace_set_readonly_regions; remote_ops.to_trace_start = remote_trace_start; remote_ops.to_get_trace_status = remote_get_trace_status; @@ -10364,7 +10421,7 @@ remote_can_async_p (void) return 0; /* We're async whenever the serial device is. */ - return remote_async_mask_value && serial_can_async_p (remote_desc); + return serial_can_async_p (remote_desc); } static int @@ -10375,7 +10432,7 @@ remote_is_async_p (void) return 0; /* We're async whenever the serial device is. */ - return remote_async_mask_value && serial_is_async_p (remote_desc); + return serial_is_async_p (remote_desc); } /* Pass the SERIAL event on and up to the client. One day this code @@ -10411,10 +10468,6 @@ static void remote_async (void (*callback) (enum inferior_event_type event_type, void *context), void *context) { - if (remote_async_mask_value == 0) - internal_error (__FILE__, __LINE__, - _("Calling remote_async when async is masked")); - if (callback != NULL) { serial_async (remote_desc, remote_async_serial_handler, NULL); @@ -10425,15 +10478,6 @@ remote_async (void (*callback) (enum inferior_event_type event_type, serial_async (remote_desc, NULL, NULL); } -static int -remote_async_mask (int new_mask) -{ - int curr_mask = remote_async_mask_value; - - remote_async_mask_value = new_mask; - return curr_mask; -} - static void set_remote_cmd (char *args, int from_tty) { @@ -10565,7 +10609,7 @@ _initialize_remote (void) sigint_remote_token = create_async_signal_handler (async_remote_interrupt, NULL); sigint_remote_twice_token = - create_async_signal_handler (inferior_event_handler_wrapper, NULL); + create_async_signal_handler (async_remote_interrupt_twice, NULL); #if 0 init_remote_threadtests ();