X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fremote.c;h=71eee5d892abd1ee6ab04fa29fc5b44b9c61cc75;hb=0cf6dd1543299e30c82397ef49d00b32af911a63;hp=051443d49c79cce4087e70cb97237105a73c9b16;hpb=aa369b55ebb701c579d42962b1176fd3629c32fb;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote.c b/gdb/remote.c index 051443d49c..71eee5d892 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -212,6 +212,8 @@ static void show_remote_protocol_packet_cmd (struct ui_file *file, static char *write_ptid (char *buf, const char *endbuf, ptid_t ptid); static ptid_t read_ptid (char *buf, char **obuf); +static void remote_set_permissions (void); + struct remote_state; static int remote_get_trace_status (struct trace_status *ts); @@ -242,6 +244,8 @@ static void remote_terminal_ours (void); static int remote_read_description_p (struct target_ops *target); +static void remote_console_output (char *msg); + /* The non-stop remote protocol provisions for one pending stop reply. This is where we keep it until it is acknowledged. */ @@ -318,6 +322,9 @@ struct remote_state /* True if the stub reports support for fast tracepoints. */ int fast_tracepoints; + /* True if the stub reports support for static tracepoints. */ + int static_tracepoints; + /* True if the stub can continue running a trace while GDB is disconnected. */ int disconnected_tracing; @@ -427,11 +434,61 @@ remote_get_noisy_reply (char **buf_p, do /* Loop on reply from remote stub. */ { char *buf; + QUIT; /* allow user to bail out with ^C */ getpkt (buf_p, sizeof_buf, 0); buf = *buf_p; if (buf[0] == 'E') trace_error (buf); + else if (strncmp (buf, "qRelocInsn:", strlen ("qRelocInsn:")) == 0) + { + ULONGEST ul; + CORE_ADDR from, to, org_to; + char *p, *pp; + int adjusted_size = 0; + volatile struct gdb_exception ex; + + p = buf + strlen ("qRelocInsn:"); + pp = unpack_varlen_hex (p, &ul); + if (*pp != ';') + error (_("invalid qRelocInsn packet: %s"), buf); + from = ul; + + p = pp + 1; + pp = unpack_varlen_hex (p, &ul); + to = ul; + + org_to = to; + + TRY_CATCH (ex, RETURN_MASK_ALL) + { + gdbarch_relocate_instruction (target_gdbarch, &to, from); + } + if (ex.reason >= 0) + { + adjusted_size = to - org_to; + + sprintf (buf, "qRelocInsn:%x", adjusted_size); + putpkt (buf); + } + else if (ex.reason < 0 && ex.error == MEMORY_ERROR) + { + /* Propagate memory errors silently back to the target. + The stub may have limited the range of addresses we + can write to, for example. */ + putpkt ("E01"); + } + else + { + /* Something unexpectedly bad happened. Be verbose so + we can tell what, and propagate the error back to the + stub, so it doesn't get stuck waiting for a + response. */ + exception_fprintf (gdb_stderr, ex, + _("warning: relocating instruction: ")); + putpkt ("E01"); + } + } else if (buf[0] == 'O' && buf[1] != 'K') remote_console_output (buf + 1); /* 'O' message from stub */ else @@ -587,6 +644,7 @@ packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum) else { struct packet_reg *r = &rsa->regs[regnum]; + gdb_assert (r->regnum == regnum); return r; } @@ -596,9 +654,11 @@ static struct packet_reg * packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum) { int i; + for (i = 0; i < gdbarch_num_regs (target_gdbarch); i++) { struct packet_reg *r = &rsa->regs[i]; + if (r->pnum == pnum) return r; } @@ -812,6 +872,7 @@ set_memory_packet_size (char *args, struct memory_packet_config *config) { int fixed_p = config->fixed_p; long size = config->size; + if (args == NULL) error (_("Argument required (integer, `fixed' or `limited').")); else if (strcmp (args, "hard") == 0 @@ -823,6 +884,7 @@ set_memory_packet_size (char *args, struct memory_packet_config *config) else { char *end; + size = strtoul (args, &end, 0); if (args == end) error (_("Invalid %s (bad syntax)."), config->name); @@ -904,6 +966,7 @@ static long get_memory_read_packet_size (void) { long size = get_memory_packet_size (&memory_read_packet_config); + /* FIXME: cagney/1999-11-07: Functions like getpkt() need to get an extra buffer size argument before the memory read size can be increased beyond this. */ @@ -963,6 +1026,7 @@ static void show_packet_config_cmd (struct packet_config *config) { char *support = "internal-error"; + switch (config->support) { case PACKET_ENABLE: @@ -1019,6 +1083,7 @@ add_packet_config_cmd (struct packet_config *config, const char *name, if (legacy) { char *legacy_name; + legacy_name = xstrprintf ("%s-packet", name); add_alias_cmd (legacy_name, cmd_name, class_obscure, 0, &remote_set_cmdlist); @@ -1136,6 +1201,7 @@ enum { PACKET_qXfer_spu_write, PACKET_qXfer_osdata, PACKET_qXfer_threads, + PACKET_qXfer_statictrace_read, PACKET_qGetTIBAddr, PACKET_qGetTLSAddr, PACKET_qSupported, @@ -1150,9 +1216,11 @@ enum { PACKET_qAttached, PACKET_ConditionalTracepoints, PACKET_FastTracepoints, + PACKET_StaticTracepoints, PACKET_bc, PACKET_bs, PACKET_TracepointSource, + PACKET_QAllow, PACKET_MAX }; @@ -1221,6 +1289,7 @@ set_remote_protocol_Z_packet_cmd (char *args, int from_tty, struct cmd_list_element *c) { int i; + for (i = 0; i < NR_Z_PACKET_TYPES; i++) { remote_protocol_packets[PACKET_Z0 + i].detect = remote_Z_packet_detect; @@ -1234,6 +1303,7 @@ show_remote_protocol_Z_packet_cmd (struct ui_file *file, int from_tty, const char *value) { int i; + for (i = 0; i < NR_Z_PACKET_TYPES; i++) { show_packet_config_cmd (&remote_protocol_packets[PACKET_Z0 + i]); @@ -2482,6 +2552,21 @@ const struct gdb_xml_element threads_elements[] = { { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } }; +/* Discard the contents of the constructed thread info context. */ + +static void +clear_threads_parsing_context (void *p) +{ + struct threads_parsing_context *context = p; + int i; + struct thread_item *item; + + for (i = 0; VEC_iterate (thread_item_t, context->items, i, item); ++i) + xfree (item->extra); + + VEC_free (thread_item_t, context->items); +} + #endif /* @@ -2512,15 +2597,20 @@ remote_threads_info (struct target_ops *ops) { struct gdb_xml_parser *parser; struct threads_parsing_context context; + struct cleanup *clear_parsing_context; - make_cleanup (null_cleanup, NULL); context.items = 0; + /* Note: this parser cleanup is already guarded by BACK_TO + above. */ parser = gdb_xml_create_parser_and_cleanup (_("threads"), threads_elements, &context); gdb_xml_use_dtd (parser, "threads.dtd"); + clear_parsing_context + = make_cleanup (clear_threads_parsing_context, &context); + if (gdb_xml_parse (parser, xml) == 0) { int i; @@ -2542,13 +2632,12 @@ remote_threads_info (struct target_ops *ops) info = demand_private_info (item->ptid); info->core = item->core; info->extra = item->extra; - item->extra = 0; + item->extra = NULL; } - xfree (item->extra); } } - VEC_free (thread_item_t, context.items); + do_cleanups (clear_parsing_context); } do_cleanups (back_to); @@ -2631,6 +2720,7 @@ remote_threads_extra_info (struct thread_info *tp) if (remote_protocol_packets[PACKET_qXfer_threads].support == PACKET_ENABLE) { struct thread_info *info = find_thread_ptid (tp->ptid); + if (info && info->private) return info->private->extra; else @@ -2687,6 +2777,98 @@ remote_threads_extra_info (struct thread_info *tp) } +static int +remote_static_tracepoint_marker_at (CORE_ADDR addr, + struct static_tracepoint_marker *marker) +{ + struct remote_state *rs = get_remote_state (); + char *p = rs->buf; + + sprintf (p, "qTSTMat:"); + p += strlen (p); + p += hexnumstr (p, addr); + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); + p = rs->buf; + + if (*p == 'E') + error (_("Remote failure reply: %s"), p); + + if (*p++ == 'm') + { + parse_static_tracepoint_marker_definition (p, &p, marker); + return 1; + } + + return 0; +} + +static void +free_current_marker (void *arg) +{ + struct static_tracepoint_marker **marker_p = arg; + + if (*marker_p != NULL) + { + release_static_tracepoint_marker (*marker_p); + xfree (*marker_p); + } + else + *marker_p = NULL; +} + +static VEC(static_tracepoint_marker_p) * +remote_static_tracepoint_markers_by_strid (const char *strid) +{ + struct remote_state *rs = get_remote_state (); + VEC(static_tracepoint_marker_p) *markers = NULL; + struct static_tracepoint_marker *marker = NULL; + struct cleanup *old_chain; + char *p; + + /* Ask for a first packet of static tracepoint marker + definition. */ + putpkt ("qTfSTM"); + getpkt (&rs->buf, &rs->buf_size, 0); + p = rs->buf; + if (*p == 'E') + error (_("Remote failure reply: %s"), p); + + old_chain = make_cleanup (free_current_marker, &marker); + + while (*p++ == 'm') + { + if (marker == NULL) + marker = XCNEW (struct static_tracepoint_marker); + + do + { + parse_static_tracepoint_marker_definition (p, &p, marker); + + if (strid == NULL || strcmp (strid, marker->str_id) == 0) + { + VEC_safe_push (static_tracepoint_marker_p, + markers, marker); + marker = NULL; + } + else + { + release_static_tracepoint_marker (marker); + memset (marker, 0, sizeof (*marker)); + } + } + while (*p++ == ','); /* comma-separated list */ + /* Ask for another packet of static tracepoint definition. */ + putpkt ("qTsSTM"); + getpkt (&rs->buf, &rs->buf_size, 0); + p = rs->buf; + } + + do_cleanups (old_chain); + return markers; +} + + /* Implement the to_get_ada_task_ptid function for the remote targets. */ static ptid_t @@ -2729,6 +2911,7 @@ remote_close (int quitting) /* We don't have a connection to the remote stub anymore. Get rid of all the inferiors and their threads we were controlling. */ discard_all_inferiors (); + inferior_ptid = null_ptid; /* We're no longer interested in any of these events. */ discard_pending_stop_replies (-1); @@ -2964,6 +3147,10 @@ remote_start_remote (struct ui_out *uiout, void *opaque) which later probes to skip. */ remote_query_supported (); + /* If the stub wants to get a QAllow, compose one and send it. */ + if (remote_protocol_packets[PACKET_QAllow].support != PACKET_DISABLE) + remote_set_permissions (); + /* Next, we possibly activate noack mode. If the QStartNoAckMode packet configuration is set to AUTO, @@ -3229,6 +3416,7 @@ static void init_all_packet_configs (void) { int i; + for (i = 0; i < PACKET_MAX; i++) update_packet_config (&remote_protocol_packets[i]); } @@ -3309,6 +3497,36 @@ Some events may be lost, rendering further debugging impossible.")); return serial_open (name); } +/* Inform the target of our permission settings. The permission flags + work without this, but if the target knows the settings, it can do + a couple things. First, it can add its own check, to catch cases + that somehow manage to get by the permissions checks in target + methods. Second, if the target is wired to disallow particular + settings (for instance, a system in the field that is not set up to + be able to stop at a breakpoint), it can object to any unavailable + permissions. */ + +void +remote_set_permissions (void) +{ + struct remote_state *rs = get_remote_state (); + + sprintf (rs->buf, "QAllow:" + "WriteReg:%x;WriteMem:%x;" + "InsertBreak:%x;InsertTrace:%x;" + "InsertFastTrace:%x;Stop:%x", + may_write_registers, may_write_memory, + may_insert_breakpoints, may_insert_tracepoints, + may_insert_fast_tracepoints, may_stop); + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); + + /* 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); +} + /* This type describes each known response to the qSupported packet. */ struct protocol_feature @@ -3397,6 +3615,7 @@ remote_multi_process_feature (const struct protocol_feature *feature, enum packet_support support, const char *value) { struct remote_state *rs = get_remote_state (); + rs->multi_process_aware = (support == PACKET_ENABLE); } @@ -3405,6 +3624,7 @@ remote_non_stop_feature (const struct protocol_feature *feature, enum packet_support support, const char *value) { struct remote_state *rs = get_remote_state (); + rs->non_stop_aware = (support == PACKET_ENABLE); } @@ -3414,6 +3634,7 @@ remote_cond_tracepoint_feature (const struct protocol_feature *feature, const char *value) { struct remote_state *rs = get_remote_state (); + rs->cond_tracepoints = (support == PACKET_ENABLE); } @@ -3423,15 +3644,27 @@ remote_fast_tracepoint_feature (const struct protocol_feature *feature, const char *value) { struct remote_state *rs = get_remote_state (); + rs->fast_tracepoints = (support == PACKET_ENABLE); } +static void +remote_static_tracepoint_feature (const struct protocol_feature *feature, + enum packet_support support, + const char *value) +{ + struct remote_state *rs = get_remote_state (); + + rs->static_tracepoints = (support == PACKET_ENABLE); +} + static void remote_disconnected_tracing_feature (const struct protocol_feature *feature, enum packet_support support, const char *value) { struct remote_state *rs = get_remote_state (); + rs->disconnected_tracing = (support == PACKET_ENABLE); } @@ -3467,6 +3700,8 @@ static struct protocol_feature remote_protocol_features[] = { PACKET_ConditionalTracepoints }, { "FastTracepoints", PACKET_DISABLE, remote_fast_tracepoint_feature, PACKET_FastTracepoints }, + { "StaticTracepoints", PACKET_DISABLE, remote_static_tracepoint_feature, + PACKET_StaticTracepoints }, { "DisconnectedTracing", PACKET_DISABLE, remote_disconnected_tracing_feature, -1 }, { "ReverseContinue", PACKET_DISABLE, remote_supported_packet, @@ -3475,6 +3710,8 @@ static struct protocol_feature remote_protocol_features[] = { PACKET_bs }, { "TracepointSource", PACKET_DISABLE, remote_supported_packet, PACKET_TracepointSource }, + { "QAllow", PACKET_DISABLE, remote_supported_packet, + PACKET_QAllow }, }; static char *remote_support_xml; @@ -3504,9 +3741,9 @@ register_remote_support_xml (const char *xml) while ((p = strtok (NULL, ",")) != NULL); xfree (copy); - p = concat (remote_support_xml, ",", xml, (char *) NULL); - xfree (remote_support_xml); - remote_support_xml = p; + remote_support_xml = reconcat (remote_support_xml, + remote_support_xml, ",", xml, + (char *) NULL); } #endif } @@ -3515,11 +3752,7 @@ static char * remote_query_supported_append (char *msg, const char *append) { if (msg) - { - char *p = concat (msg, ";", append, (char *) NULL); - xfree (msg); - return p; - } + return reconcat (msg, msg, ";", append, (char *) NULL); else return xstrdup (append); } @@ -3543,26 +3776,20 @@ remote_query_supported (void) if (remote_protocol_packets[PACKET_qSupported].support != PACKET_DISABLE) { char *q = NULL; - const char *qsupported = gdbarch_qsupported (target_gdbarch); + struct cleanup *old_chain = make_cleanup (free_current_contents, &q); if (rs->extended) q = remote_query_supported_append (q, "multiprocess+"); - - if (qsupported) - q = remote_query_supported_append (q, qsupported); if (remote_support_xml) q = remote_query_supported_append (q, remote_support_xml); - if (q) - { - char *p = concat ("qSupported:", q, (char *) NULL); - xfree (q); - putpkt (p); - xfree (p); - } - else - putpkt ("qSupported"); + q = remote_query_supported_append (q, "qRelocInsn+"); + + q = reconcat (q, "qSupported:", q, (char *) NULL); + putpkt (q); + + do_cleanups (old_chain); getpkt (&rs->buf, &rs->buf_size, 0); @@ -4081,6 +4308,7 @@ int bin2hex (const gdb_byte *bin, char *hex, int count) { int i; + /* May use a length, or a nul-terminated string as input. */ if (count == 0) count = strlen ((char *) bin); @@ -4589,7 +4817,7 @@ remote_terminal_ours (void) remote_async_terminal_ours_p = 1; } -void +static void remote_console_output (char *msg) { char *p; @@ -4598,6 +4826,7 @@ remote_console_output (char *msg) { char tb[2]; char c = fromhex (p[0]) * 16 + fromhex (p[1]); + tb[0] = c; tb[1] = 0; fputs_unfiltered (tb, gdb_stdtarg); @@ -4639,6 +4868,7 @@ static struct stop_reply * stop_reply_xmalloc (void) { struct stop_reply *r = XMALLOC (struct stop_reply); + r->next = NULL; return r; } @@ -4696,6 +4926,7 @@ static void do_stop_reply_xfree (void *arg) { struct stop_reply *r = arg; + stop_reply_xfree (r); } @@ -4867,6 +5098,7 @@ Packet: '%s'\n"), else if (strncmp (p, "core", p1 - p) == 0) { ULONGEST c; + p = unpack_varlen_hex (++p1, &c); event->core = c; } @@ -4966,6 +5198,7 @@ Packet: '%s'\n"), "process:", sizeof ("process:") - 1) == 0) { ULONGEST upid; + p += sizeof ("process:") - 1; unpack_varlen_hex (p, &upid); pid = upid; @@ -5503,30 +5736,28 @@ process_g_packet (struct regcache *regcache) p += 2; } - { - int i; - for (i = 0; i < gdbarch_num_regs (gdbarch); i++) - { - struct packet_reg *r = &rsa->regs[i]; - if (r->in_g_packet) - { - if (r->offset * 2 >= strlen (rs->buf)) - /* This shouldn't happen - we adjusted in_g_packet above. */ - internal_error (__FILE__, __LINE__, - "unexpected end of 'g' packet reply"); - else if (rs->buf[r->offset * 2] == 'x') - { - gdb_assert (r->offset * 2 < strlen (rs->buf)); - /* The register isn't available, mark it as such (at - the same time setting the value to zero). */ - regcache_raw_supply (regcache, r->regnum, NULL); - } - else - regcache_raw_supply (regcache, r->regnum, - regs + r->offset); - } - } - } + for (i = 0; i < gdbarch_num_regs (gdbarch); i++) + { + struct packet_reg *r = &rsa->regs[i]; + + if (r->in_g_packet) + { + if (r->offset * 2 >= strlen (rs->buf)) + /* This shouldn't happen - we adjusted in_g_packet above. */ + internal_error (__FILE__, __LINE__, + "unexpected end of 'g' packet reply"); + else if (rs->buf[r->offset * 2] == 'x') + { + gdb_assert (r->offset * 2 < strlen (rs->buf)); + /* The register isn't available, mark it as such (at + the same time setting the value to zero). */ + regcache_raw_supply (regcache, r->regnum, NULL); + } + else + regcache_raw_supply (regcache, r->regnum, + regs + r->offset); + } + } } static void @@ -5548,6 +5779,7 @@ remote_fetch_registers (struct target_ops *ops, if (regnum >= 0) { struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum); + gdb_assert (reg != NULL); /* If this register might be in the 'g' packet, try that first - @@ -5663,11 +5895,13 @@ store_registers_using_G (const struct regcache *regcache) local buffer. */ { int i; + regs = alloca (rsa->sizeof_g_packet); memset (regs, 0, rsa->sizeof_g_packet); for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) { struct packet_reg *r = &rsa->regs[i]; + if (r->in_g_packet) regcache_raw_collect (regcache, r->regnum, regs + r->offset); } @@ -5702,6 +5936,7 @@ remote_store_registers (struct target_ops *ops, if (regnum >= 0) { struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum); + gdb_assert (reg != NULL); /* Always prefer to store registers using the 'P' packet if @@ -5751,6 +5986,7 @@ static int hexnumstr (char *buf, ULONGEST num) { int len = hexnumlen (num); + return hexnumnstr (buf, num, len); } @@ -5779,6 +6015,7 @@ static CORE_ADDR remote_address_masked (CORE_ADDR addr) { int address_size = remote_address_size; + /* If "remoteaddresssize" was not set, default to target address size. */ if (!address_size) address_size = gdbarch_addr_bit (target_gdbarch); @@ -5789,6 +6026,7 @@ remote_address_masked (CORE_ADDR addr) /* Only create a mask when that mask can safely be constructed in a ULONGEST variable. */ ULONGEST mask = 1; + mask = (mask << address_size) - 1; addr &= mask; } @@ -6246,6 +6484,7 @@ handle_notification (char *buf, size_t length) { struct cleanup *old_chain; struct stop_reply *reply = stop_reply_xmalloc (); + old_chain = make_cleanup (do_stop_reply_xfree, reply); remote_parse_stop_reply (buf + 5, reply); @@ -6302,8 +6541,8 @@ remote_send_printf (const char *format, ...) { struct remote_state *rs = get_remote_state (); int max_size = get_remote_packet_size (); - va_list ap; + va_start (ap, format); rs->buf[0] = '\0'; @@ -6323,6 +6562,7 @@ static void restore_remote_timeout (void *p) { int value = *(int *)p; + remote_timeout = value; } @@ -6338,9 +6578,9 @@ remote_flash_erase (struct target_ops *ops, int addr_size = gdbarch_addr_bit (target_gdbarch) / 8; int saved_remote_timeout = remote_timeout; enum packet_result ret; - struct cleanup *back_to = make_cleanup (restore_remote_timeout, &saved_remote_timeout); + remote_timeout = remote_flash_timeout; ret = remote_send_printf ("vFlashErase:%s,%s", @@ -6816,8 +7056,8 @@ Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n", case '*': /* Run length encoding. */ { int repeat; - csum += c; + csum += c; c = readchar (remote_timeout); csum += c; repeat = c - ' ' + 3; /* Compute repeat count. */ @@ -7406,7 +7646,8 @@ watchpoint_to_Z_packet (int type) } static int -remote_insert_watchpoint (CORE_ADDR addr, int len, int type) +remote_insert_watchpoint (CORE_ADDR addr, int len, int type, + struct expression *cond) { struct remote_state *rs = get_remote_state (); char *p; @@ -7439,7 +7680,8 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type) static int -remote_remove_watchpoint (CORE_ADDR addr, int len, int type) +remote_remove_watchpoint (CORE_ADDR addr, int len, int type, + struct expression *cond) { struct remote_state *rs = get_remote_state (); char *p; @@ -7508,6 +7750,7 @@ static int remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) { int rc = 0; + if (remote_stopped_by_watchpoint ()) { *addr_p = remote_watch_data_address; @@ -7866,6 +8109,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, if (object == TARGET_OBJECT_MEMORY) { int xfered; + errno = 0; /* If the remote target is connected but not running, we should @@ -7913,6 +8157,16 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, [PACKET_qXfer_siginfo_write]); } + if (object == TARGET_OBJECT_STATIC_TRACE_DATA) + { + if (readbuf) + return remote_read_qxfer (ops, "statictrace", annex, readbuf, offset, len, + &remote_protocol_packets + [PACKET_qXfer_statictrace_read]); + else + return -1; + } + /* Only handle flash writes. */ if (writebuf != NULL) { @@ -8167,6 +8421,7 @@ remote_rcmd (char *command, for (p = buf; p[0] != '\0' && p[1] != '\0'; p += 2) { char c = (fromhex (p[0]) << 4) + fromhex (p[1]); + fputc_unfiltered (c, outbuf); } break; @@ -8183,6 +8438,7 @@ remote_memory_map (struct target_ops *ops) if (text) { struct cleanup *back_to = make_cleanup (xfree, text); + result = parse_memory_map (text); do_cleanups (back_to); } @@ -9323,6 +9579,7 @@ static int remote_supports_multi_process (void) { struct remote_state *rs = get_remote_state (); + return remote_multi_process_p (rs); } @@ -9330,6 +9587,7 @@ int remote_supports_cond_tracepoints (void) { struct remote_state *rs = get_remote_state (); + return rs->cond_tracepoints; } @@ -9337,9 +9595,18 @@ int remote_supports_fast_tracepoints (void) { struct remote_state *rs = get_remote_state (); + return rs->fast_tracepoints; } +static int +remote_supports_static_tracepoints (void) +{ + struct remote_state *rs = get_remote_state (); + + return rs->static_tracepoints; +} + static void remote_trace_init (void) { @@ -9468,6 +9735,25 @@ remote_download_tracepoint (struct breakpoint *t) give up on the trace run. */ warning (_("Target does not support fast tracepoints, downloading %d as regular tracepoint"), t->number); } + else if (t->type == bp_static_tracepoint) + { + /* Only test for support at download time; we may not know + target capabilities at definition time. */ + if (remote_supports_static_tracepoints ()) + { + struct static_tracepoint_marker marker; + + if (target_static_tracepoint_marker_at (tpaddr, &marker)) + strcat (buf, ":S"); + else + error ("Static tracepoint not valid during download"); + } + else + /* Fast tracepoints are functionally identical to regular + tracepoints, so don't take lack of support as a reason + to give up on the trace run. */ + error (_("Target does not support static tracepoints")); + } /* If the tracepoint has a conditional, make it into an agent expression and append to the definition. */ if (loc->cond) @@ -9639,6 +9925,7 @@ remote_get_trace_status (struct trace_status *ts) char *p; /* FIXME we need to get register block size some other way */ extern int trace_regblock_size; + trace_regblock_size = get_remote_arch_state ()->sizeof_g_packet; putpkt ("qTStatus"); @@ -9857,6 +10144,7 @@ static int remote_core_of_thread (struct target_ops *ops, ptid_t ptid) { struct thread_info *info = find_thread_ptid (ptid); + if (info && info->private) return info->private->core; return -1; @@ -9960,6 +10248,11 @@ Specify the serial device it is connected to\n\ remote_ops.to_core_of_thread = remote_core_of_thread; remote_ops.to_verify_memory = remote_verify_memory; remote_ops.to_get_tib_address = remote_get_tib_address; + remote_ops.to_set_permissions = remote_set_permissions; + remote_ops.to_static_tracepoint_marker_at + = remote_static_tracepoint_marker_at; + remote_ops.to_static_tracepoint_markers_by_strid + = remote_static_tracepoint_markers_by_strid; } /* Set up the extended remote vector by making a copy of the standard @@ -10057,6 +10350,7 @@ static int remote_async_mask (int new_mask) { int curr_mask = remote_async_mask_value; + remote_async_mask_value = new_mask; return curr_mask; } @@ -10087,6 +10381,7 @@ show_remote_cmd (char *args, int from_tty) { struct cleanup *option_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "option"); + ui_out_field_string (uiout, "name", list->name); ui_out_text (uiout, ": "); if (list->type == show_cmd) @@ -10433,6 +10728,15 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (&remote_protocol_packets[PACKET_TracepointSource], "TracepointSource", "TracepointSource", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_QAllow], + "QAllow", "allow", 0); + + add_packet_config_cmd (&remote_protocol_packets[PACKET_StaticTracepoints], + "StaticTracepoints", "static-tracepoints", 0); + + add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_statictrace_read], + "qXfer:statictrace:read", "read-sdata-object", 0); + /* Keep the old ``set remote Z-packet ...'' working. Each individual Z sub-packet has its own set and show commands, but users may have sets to this variable in their .gdbinit files (or in their