X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fremote.c;h=62b87c494b23747fb2d6bb66073b45cb569a2130;hb=0b39b52e6e92cf6d465d48499c657fcb17a63c7f;hp=8e8ee6f8705069a3f69fd8c883b7ea37db5de851;hpb=4fa847d78edd4a3901414655bd4b31234b91ba2a;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote.c b/gdb/remote.c index 8e8ee6f870..62b87c494b 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -72,10 +72,9 @@ #include "btrace.h" #include "record-btrace.h" #include - -/* Temp hacks for tracepoint encoding migration. */ -static char *target_buf; -static long target_buf_size; +#include "common/scoped_restore.h" +#include "environ.h" +#include "common/byte-vector.h" /* Per-program-space data key. */ static const struct program_space_data *remote_pspace_data; @@ -168,10 +167,6 @@ static CORE_ADDR remote_address_masked (CORE_ADDR); static void print_packet (const char *); -static void compare_sections_command (char *, int); - -static void packet_command (char *, int); - static int stub_unpack_int (char *buff, int fieldlength); static ptid_t remote_current_thread (ptid_t oldptid); @@ -190,7 +185,7 @@ static void show_remote_protocol_packet_cmd (struct ui_file *file, const char *value); static char *write_ptid (char *buf, const char *endbuf, ptid_t ptid); -static ptid_t read_ptid (char *buf, char **obuf); +static ptid_t read_ptid (const char *buf, const char **obuf); static void remote_set_permissions (struct target_ops *self); @@ -207,8 +202,6 @@ static void remote_query_supported (void); static void remote_check_symbols (void); -void _initialize_remote (void); - struct stop_reply; static void stop_reply_xfree (struct stop_reply *); static void remote_parse_stop_reply (char *, struct stop_reply *); @@ -241,6 +234,8 @@ static void readahead_cache_invalidate (void); static void remote_unpush_and_throw (void); +static struct remote_state *get_remote_state (void); + /* For "remote". */ static struct cmd_list_element *remote_cmdlist; @@ -451,6 +446,10 @@ struct private_thread_info char *name; int core; + /* Thread handle, perhaps a pthread_t or thread_t value, stored as a + sequence of bytes. */ + gdb::byte_vector *thread_handle; + /* Whether the target stopped for a breakpoint/watchpoint. */ enum target_stop_reason stop_reason; @@ -482,6 +481,7 @@ free_private_thread_info (struct private_thread_info *info) { xfree (info->extra); xfree (info->name); + delete info->thread_handle; xfree (info); } @@ -573,24 +573,26 @@ trace_error (char *buf) } /* Utility: wait for reply from stub, while accepting "O" packets. */ + static char * -remote_get_noisy_reply (char **buf_p, - long *sizeof_buf) +remote_get_noisy_reply () { + struct remote_state *rs = get_remote_state (); + 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; + getpkt (&rs->buf, &rs->buf_size, 0); + buf = rs->buf; if (buf[0] == 'E') trace_error (buf); else if (startswith (buf, "qRelocInsn:")) { ULONGEST ul; CORE_ADDR from, to, org_to; - char *p, *pp; + const char *p, *pp; int adjusted_size = 0; int relocated = 0; @@ -636,7 +638,7 @@ remote_get_noisy_reply (char **buf_p, { adjusted_size = to - org_to; - xsnprintf (buf, *sizeof_buf, "qRelocInsn:%x", adjusted_size); + xsnprintf (buf, rs->buf_size, "qRelocInsn:%x", adjusted_size); putpkt (buf); } } @@ -652,11 +654,11 @@ remote_get_noisy_reply (char **buf_p, static struct gdbarch_data *remote_gdbarch_data_handle; static struct remote_arch_state * -get_remote_arch_state (void) +get_remote_arch_state (struct gdbarch *gdbarch) { - gdb_assert (target_gdbarch () != NULL); + gdb_assert (gdbarch != NULL); return ((struct remote_arch_state *) - gdbarch_data (target_gdbarch (), remote_gdbarch_data_handle)); + gdbarch_data (gdbarch, remote_gdbarch_data_handle)); } /* Fetch the global remote target state. */ @@ -669,7 +671,7 @@ get_remote_state (void) function which calls getpkt also needs to be mindful of changes to rs->buf, but this call limits the number of places which run into trouble. */ - get_remote_arch_state (); + get_remote_arch_state (target_gdbarch ()); return get_remote_state_raw (); } @@ -801,21 +803,15 @@ int remote_register_number_and_offset (struct gdbarch *gdbarch, int regnum, int *pnum, int *poffset) { - struct packet_reg *regs; - struct cleanup *old_chain; - gdb_assert (regnum < gdbarch_num_regs (gdbarch)); - regs = XCNEWVEC (struct packet_reg, gdbarch_num_regs (gdbarch)); - old_chain = make_cleanup (xfree, regs); + std::vector regs (gdbarch_num_regs (gdbarch)); - map_regcache_remote_table (gdbarch, regs); + map_regcache_remote_table (gdbarch, regs.data ()); *pnum = regs[regnum].pnum; *poffset = regs[regnum].offset; - do_cleanups (old_chain); - return *pnum != -1; } @@ -876,7 +872,7 @@ static long get_remote_packet_size (void) { struct remote_state *rs = get_remote_state (); - struct remote_arch_state *rsa = get_remote_arch_state (); + remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ()); if (rs->explicit_packet_size) return rs->explicit_packet_size; @@ -885,9 +881,10 @@ get_remote_packet_size (void) } static struct packet_reg * -packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum) +packet_reg_from_regnum (struct gdbarch *gdbarch, struct remote_arch_state *rsa, + long regnum) { - if (regnum < 0 && regnum >= gdbarch_num_regs (target_gdbarch ())) + if (regnum < 0 && regnum >= gdbarch_num_regs (gdbarch)) return NULL; else { @@ -899,11 +896,12 @@ packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum) } static struct packet_reg * -packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum) +packet_reg_from_pnum (struct gdbarch *gdbarch, struct remote_arch_state *rsa, + LONGEST pnum) { int i; - for (i = 0; i < gdbarch_num_regs (target_gdbarch ()); i++) + for (i = 0; i < gdbarch_num_regs (gdbarch); i++) { struct packet_reg *r = &rsa->regs[i]; @@ -1009,11 +1007,6 @@ show_remotebreak (struct ui_file *file, int from_tty, static unsigned int remote_address_size; -/* Temporary to track who currently owns the terminal. See - remote_terminal_* for more details. */ - -static int remote_async_terminal_ours_p; - /* User configurable variables for the number of characters in a memory read/write packet. MIN (rsa->remote_packet_size, @@ -1047,7 +1040,7 @@ static long get_memory_packet_size (struct memory_packet_config *config) { struct remote_state *rs = get_remote_state (); - struct remote_arch_state *rsa = get_remote_arch_state (); + remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ()); long what_they_get; if (config->fixed_p) @@ -1090,7 +1083,7 @@ get_memory_packet_size (struct memory_packet_config *config) something really big then do a sanity check. */ static void -set_memory_packet_size (char *args, struct memory_packet_config *config) +set_memory_packet_size (const char *args, struct memory_packet_config *config) { int fixed_p = config->fixed_p; long size = config->size; @@ -1151,13 +1144,13 @@ static struct memory_packet_config memory_write_packet_config = }; static void -set_memory_write_packet_size (char *args, int from_tty) +set_memory_write_packet_size (const char *args, int from_tty) { set_memory_packet_size (args, &memory_write_packet_config); } static void -show_memory_write_packet_size (char *args, int from_tty) +show_memory_write_packet_size (const char *args, int from_tty) { show_memory_packet_size (&memory_write_packet_config); } @@ -1174,13 +1167,13 @@ static struct memory_packet_config memory_read_packet_config = }; static void -set_memory_read_packet_size (char *args, int from_tty) +set_memory_read_packet_size (const char *args, int from_tty) { set_memory_packet_size (args, &memory_read_packet_config); } static void -show_memory_read_packet_size (char *args, int from_tty) +show_memory_read_packet_size (const char *args, int from_tty) { show_memory_packet_size (&memory_read_packet_config); } @@ -1428,7 +1421,11 @@ enum { PACKET_QPassSignals, PACKET_QCatchSyscalls, PACKET_QProgramSignals, + PACKET_QSetWorkingDir, PACKET_QStartupWithShell, + PACKET_QEnvironmentHexEncoded, + PACKET_QEnvironmentReset, + PACKET_QEnvironmentUnset, PACKET_qCRC, PACKET_qSearch_memory, PACKET_vAttach, @@ -1968,6 +1965,7 @@ get_private_info_thread (struct thread_info *thread) priv->last_resume_step = 0; priv->last_resume_sig = GDB_SIGNAL_0; priv->vcont_resumed = 0; + priv->thread_handle = nullptr; } return thread->priv; @@ -2053,7 +2051,7 @@ remote_set_syscall_catchpoint (struct target_ops *self, int pid, int needed, int any_count, int table_size, int *table) { - char *catch_packet; + const char *catch_packet; enum packet_result result; int n_sysno = 0; @@ -2083,53 +2081,45 @@ remote_set_syscall_catchpoint (struct target_ops *self, pid, needed, any_count, n_sysno); } + std::string built_packet; if (needed) { /* Prepare a packet with the sysno list, assuming max 8+1 characters for a sysno. If the resulting packet size is too big, fallback on the non-selective packet. */ const int maxpktsz = strlen ("QCatchSyscalls:1") + n_sysno * 9 + 1; - - catch_packet = (char *) xmalloc (maxpktsz); - strcpy (catch_packet, "QCatchSyscalls:1"); + built_packet.reserve (maxpktsz); + built_packet = "QCatchSyscalls:1"; if (!any_count) { - int i; - char *p; - - p = catch_packet; - p += strlen (p); - /* Add in catch_packet each syscall to be caught (table[i] != 0). */ - for (i = 0; i < table_size; i++) + for (int i = 0; i < table_size; i++) { if (table[i] != 0) - p += xsnprintf (p, catch_packet + maxpktsz - p, ";%x", i); + string_appendf (built_packet, ";%x", i); } } - if (strlen (catch_packet) > get_remote_packet_size ()) + if (built_packet.size () > get_remote_packet_size ()) { /* catch_packet too big. Fallback to less efficient non selective mode, with GDB doing the filtering. */ - catch_packet[sizeof ("QCatchSyscalls:1") - 1] = 0; + catch_packet = "QCatchSyscalls:1"; } + else + catch_packet = built_packet.c_str (); } else - catch_packet = xstrdup ("QCatchSyscalls:0"); + catch_packet = "QCatchSyscalls:0"; - { - struct cleanup *old_chain = make_cleanup (xfree, catch_packet); - struct remote_state *rs = get_remote_state (); + struct remote_state *rs = get_remote_state (); - putpkt (catch_packet); - getpkt (&rs->buf, &rs->buf_size, 0); - result = packet_ok (rs->buf, &remote_protocol_packets[PACKET_QCatchSyscalls]); - do_cleanups (old_chain); - if (result == PACKET_OK) - return 0; - else - return -1; - } + putpkt (catch_packet); + getpkt (&rs->buf, &rs->buf_size, 0); + result = packet_ok (rs->buf, &remote_protocol_packets[PACKET_QCatchSyscalls]); + if (result == PACKET_OK) + return 0; + else + return -1; } /* If 'QProgramSignals' is supported, tell the remote stub what @@ -2439,14 +2429,15 @@ write_ptid (char *buf, const char *endbuf, ptid_t ptid) return buf; } -/* Extract a PTID from BUF. If non-null, OBUF is set to the to one - passed the last parsed char. Returns null_ptid on error. */ +/* Extract a PTID from BUF. If non-null, OBUF is set to one past the + last parsed char. Returns null_ptid if no thread id is found, and + throws an error if the thread id has an invalid format. */ static ptid_t -read_ptid (char *buf, char **obuf) +read_ptid (const char *buf, const char **obuf) { - char *p = buf; - char *pp; + const char *p = buf; + const char *pp; ULONGEST pid = 0, tid = 0; if (*p == 'p') @@ -2994,6 +2985,10 @@ typedef struct thread_item /* The core the thread was running on. -1 if not known. */ int core; + + /* The thread handle associated with the thread. */ + gdb::byte_vector *thread_handle; + } thread_item_t; DEF_VEC_O(thread_item_t); @@ -3021,6 +3016,7 @@ clear_threads_listing_context (void *p) { xfree (item->extra); xfree (item->name); + delete item->thread_handle; } VEC_free (thread_item_t, context->items); @@ -3059,6 +3055,7 @@ remote_newthread_step (threadref *ref, void *data) item.core = -1; item.name = NULL; item.extra = NULL; + item.thread_handle = nullptr; VEC_safe_push (thread_item_t, context->items, &item); @@ -3076,7 +3073,7 @@ remote_current_thread (ptid_t oldpid) getpkt (&rs->buf, &rs->buf_size, 0); if (rs->buf[0] == 'Q' && rs->buf[1] == 'C') { - char *obuf; + const char *obuf; ptid_t result; result = read_ptid (&rs->buf[2], &obuf); @@ -3129,6 +3126,17 @@ start_thread (struct gdb_xml_parser *parser, attr = xml_find_attribute (attributes, "name"); item.name = attr != NULL ? xstrdup ((const char *) attr->value) : NULL; + attr = xml_find_attribute (attributes, "handle"); + if (attr != NULL) + { + item.thread_handle = new gdb::byte_vector + (strlen ((const char *) attr->value) / 2); + hex2bin ((const char *) attr->value, item.thread_handle->data (), + item.thread_handle->size ()); + } + else + item.thread_handle = nullptr; + item.extra = 0; VEC_safe_push (thread_item_t, data->items, &item); @@ -3150,6 +3158,7 @@ const struct gdb_xml_attribute thread_attributes[] = { { "id", GDB_XML_AF_NONE, NULL, NULL }, { "core", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, { "name", GDB_XML_AF_OPTIONAL, NULL, NULL }, + { "handle", GDB_XML_AF_OPTIONAL, NULL, NULL }, { NULL, GDB_XML_AF_NONE, NULL, NULL } }; @@ -3181,16 +3190,15 @@ remote_get_threads_with_qxfer (struct target_ops *ops, #if defined(HAVE_LIBEXPAT) if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE) { - char *xml = target_read_stralloc (ops, TARGET_OBJECT_THREADS, NULL); - struct cleanup *back_to = make_cleanup (xfree, xml); + gdb::unique_xmalloc_ptr xml + = target_read_stralloc (ops, TARGET_OBJECT_THREADS, NULL); if (xml != NULL && *xml != '\0') { gdb_xml_parse_quick (_("threads"), "threads.dtd", - threads_elements, xml, context); + threads_elements, xml.get (), context); } - do_cleanups (back_to); return 1; } #endif @@ -3208,7 +3216,7 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops, if (rs->use_threadinfo_query) { - char *bufp; + const char *bufp; putpkt ("qfThreadInfo"); getpkt (&rs->buf, &rs->buf_size, 0); @@ -3225,6 +3233,7 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops, item.core = -1; item.name = NULL; item.extra = NULL; + item.thread_handle = nullptr; VEC_safe_push (thread_item_t, context->items, &item); } @@ -3330,6 +3339,8 @@ remote_update_thread_list (struct target_ops *ops) item->extra = NULL; info->name = item->name; item->name = NULL; + info->thread_handle = item->thread_handle; + item->thread_handle = nullptr; } } } @@ -3455,7 +3466,7 @@ remote_static_tracepoint_marker_at (struct target_ops *self, CORE_ADDR addr, if (*p++ == 'm') { - parse_static_tracepoint_marker_definition (p, &p, marker); + parse_static_tracepoint_marker_definition (p, NULL, marker); return 1; } @@ -3470,7 +3481,7 @@ remote_static_tracepoint_markers_by_strid (struct target_ops *self, VEC(static_tracepoint_marker_p) *markers = NULL; struct static_tracepoint_marker *marker = NULL; struct cleanup *old_chain; - char *p; + const char *p; /* Ask for a first packet of static tracepoint marker definition. */ @@ -3763,7 +3774,7 @@ stop_reply_extract_thread (char *stop_reply) { if (stop_reply[0] == 'T' && strlen (stop_reply) > 3) { - char *p; + const char *p; /* Txx r:val ; r:val (...) */ p = &stop_reply[3]; @@ -3771,7 +3782,7 @@ stop_reply_extract_thread (char *stop_reply) /* Look for "register" named "thread". */ while (*p != '\0') { - char *p1; + const char *p1; p1 = strchr (p, ':'); if (p1 == NULL) @@ -3830,19 +3841,16 @@ add_current_inferior_and_thread (char *wait_status) { struct remote_state *rs = get_remote_state (); int fake_pid_p = 0; - ptid_t ptid; inferior_ptid = null_ptid; /* Now, if we have thread information, update inferior_ptid. */ - ptid = get_current_thread (wait_status); + ptid_t curr_ptid = get_current_thread (wait_status); - if (!ptid_equal (ptid, null_ptid)) + if (curr_ptid != null_ptid) { if (!remote_multi_process_p (rs)) fake_pid_p = 1; - - inferior_ptid = ptid; } else { @@ -3850,14 +3858,17 @@ add_current_inferior_and_thread (char *wait_status) (such as kill) won't work. This variable serves (at least) double duty as both the pid of the target process (if it has such), and as a flag indicating that a target is active. */ - inferior_ptid = magic_null_ptid; + curr_ptid = magic_null_ptid; fake_pid_p = 1; } - remote_add_inferior (fake_pid_p, ptid_get_pid (inferior_ptid), -1, 1); + remote_add_inferior (fake_pid_p, ptid_get_pid (curr_ptid), -1, 1); - /* Add the main thread. */ - add_thread_silent (inferior_ptid); + /* Add the main thread and switch to it. Don't try reading + registers yet, since we haven't fetched the target description + yet. */ + thread_info *tp = add_thread_silent (curr_ptid); + switch_to_thread_no_regs (tp); } /* Print info about a thread that was found already stopped on @@ -4634,8 +4645,16 @@ static const struct protocol_feature remote_protocol_features[] = { PACKET_QCatchSyscalls }, { "QProgramSignals", PACKET_DISABLE, remote_supported_packet, PACKET_QProgramSignals }, + { "QSetWorkingDir", PACKET_DISABLE, remote_supported_packet, + PACKET_QSetWorkingDir }, { "QStartupWithShell", PACKET_DISABLE, remote_supported_packet, PACKET_QStartupWithShell }, + { "QEnvironmentHexEncoded", PACKET_DISABLE, remote_supported_packet, + PACKET_QEnvironmentHexEncoded }, + { "QEnvironmentReset", PACKET_DISABLE, remote_supported_packet, + PACKET_QEnvironmentReset }, + { "QEnvironmentUnset", PACKET_DISABLE, remote_supported_packet, + PACKET_QEnvironmentUnset }, { "QStartNoAckMode", PACKET_DISABLE, remote_supported_packet, PACKET_QStartNoAckMode }, { "multiprocess", PACKET_DISABLE, remote_supported_packet, @@ -4924,7 +4943,7 @@ remote_query_supported (void) instead. - The target has been resumed in the foreground - (target_terminal_is_ours is false) with a synchronous resume + (target_terminal::is_ours is false) with a synchronous resume packet, and we're blocked waiting for the stop reply, thus a Ctrl-C should be immediately sent to the target. @@ -4955,11 +4974,11 @@ remote_serial_quit_handler (void) remote_unpush_and_throw (); } /* If ^C has already been sent once, offer to disconnect. */ - else if (!target_terminal_is_ours () && rs->ctrlc_pending_p) + else if (!target_terminal::is_ours () && rs->ctrlc_pending_p) interrupt_query (); /* All-stop protocol, and blocked waiting for stop reply. Send an interrupt request. */ - else if (!target_terminal_is_ours () && rs->waiting_for_stop_reply) + else if (!target_terminal::is_ours () && rs->waiting_for_stop_reply) target_interrupt (inferior_ptid); else rs->got_ctrlc_during_io = 1; @@ -5085,9 +5104,6 @@ remote_open_1 (const char *name, int from_tty, readahead_cache_invalidate (); - /* Start out by owning the terminal. */ - remote_async_terminal_ours_p = 1; - if (target_async_permitted) { /* FIXME: cagney/1999-09-23: During the initial connection it is @@ -6271,15 +6287,6 @@ interrupt_query (void) static void remote_terminal_inferior (struct target_ops *self) { - /* FIXME: cagney/1999-09-27: Make calls to target_terminal_*() - idempotent. The event-loop GDB talking to an asynchronous target - with a synchronous command calls this function from both - event-top.c and infrun.c/infcmd.c. Once GDB stops trying to - transfer the terminal to the target when it shouldn't this guard - can go away. */ - if (!remote_async_terminal_ours_p) - return; - remote_async_terminal_ours_p = 0; /* NOTE: At this point we could also register our selves as the recipient of all input. Any characters typed could then be passed on down to the target. */ @@ -6288,10 +6295,6 @@ remote_terminal_inferior (struct target_ops *self) static void remote_terminal_ours (struct target_ops *self) { - /* See FIXME in remote_terminal_inferior. */ - if (remote_async_terminal_ours_p) - return; - remote_async_terminal_ours_p = 1; } static void @@ -6327,6 +6330,9 @@ typedef struct stop_reply struct target_waitstatus ws; + /* The architecture associated with the expedited registers. */ + gdbarch *arch; + /* Expedited registers. This makes remote debugging a bit more efficient for those targets that provide critical registers as part of their normal status mechanism (as another roundtrip to @@ -6801,9 +6807,9 @@ strprefix (const char *p, const char *pend, const char *prefix) static void remote_parse_stop_reply (char *buf, struct stop_reply *event) { - struct remote_arch_state *rsa = get_remote_arch_state (); + remote_arch_state *rsa = NULL; ULONGEST addr; - char *p; + const char *p; int skipregs = 0; event->ptid = null_ptid; @@ -6827,7 +6833,7 @@ remote_parse_stop_reply (char *buf, struct stop_reply *event) p = &buf[3]; /* after Txx */ while (*p) { - char *p1; + const char *p1; int fieldsize; p1 = strchr (p, ':'); @@ -6965,7 +6971,7 @@ Packet: '%s'\n"), else { ULONGEST pnum; - char *p_temp; + const char *p_temp; if (skipregs) { @@ -6981,9 +6987,47 @@ Packet: '%s'\n"), reason. */ if (p_temp == p1) { - struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum); + /* If we haven't parsed the event's thread yet, find + it now, in order to find the architecture of the + reported expedited registers. */ + if (event->ptid == null_ptid) + { + const char *thr = strstr (p1 + 1, ";thread:"); + if (thr != NULL) + event->ptid = read_ptid (thr + strlen (";thread:"), + NULL); + else + event->ptid = magic_null_ptid; + } + + if (rsa == NULL) + { + inferior *inf = (event->ptid == null_ptid + ? NULL + : find_inferior_ptid (event->ptid)); + /* If this is the first time we learn anything + about this process, skip the registers + included in this packet, since we don't yet + know which architecture to use to parse them. + We'll determine the architecture later when + we process the stop reply and retrieve the + target description, via + remote_notice_new_inferior -> + post_create_inferior. */ + if (inf == NULL) + { + p = strchrnul (p1 + 1, ';'); + p++; + continue; + } + + event->arch = inf->gdbarch; + rsa = get_remote_arch_state (event->arch); + } + + packet_reg *reg + = packet_reg_from_pnum (event->arch, rsa, pnum); cached_reg_t cached_reg; - struct gdbarch *gdbarch = target_gdbarch (); if (reg == NULL) error (_("Remote sent bad register number %s: %s\n\ @@ -6992,13 +7036,13 @@ Packet: '%s'\n"), cached_reg.num = reg->regnum; cached_reg.data = (gdb_byte *) - xmalloc (register_size (gdbarch, reg->regnum)); + xmalloc (register_size (event->arch, reg->regnum)); p = p1 + 1; fieldsize = hex2bin (p, cached_reg.data, - register_size (gdbarch, reg->regnum)); + register_size (event->arch, reg->regnum)); p += 2 * fieldsize; - if (fieldsize < register_size (gdbarch, reg->regnum)) + if (fieldsize < register_size (event->arch, reg->regnum)) warning (_("Remote reply is too short: %s"), buf); VEC_safe_push (cached_reg_t, event->regcache, &cached_reg); @@ -7035,7 +7079,7 @@ Packet: '%s'\n"), break; case 'w': /* Thread exited. */ { - char *p; + const char *p; ULONGEST value; event->ws.kind = TARGET_WAITKIND_THREAD_EXITED; @@ -7049,7 +7093,7 @@ Packet: '%s'\n"), case 'W': /* Target exited. */ case 'X': { - char *p; + const char *p; int pid; ULONGEST value; @@ -7214,7 +7258,7 @@ process_stop_reply (struct stop_reply *stop_reply, if (stop_reply->regcache) { struct regcache *regcache - = get_thread_arch_regcache (ptid, target_gdbarch ()); + = get_thread_arch_regcache (ptid, stop_reply->arch); cached_reg_t *reg; int ix; @@ -7403,12 +7447,12 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options) { /* Zero length reply means that we tried 'S' or 'C' and the remote system doesn't support it. */ - target_terminal_ours_for_output (); + target_terminal::ours_for_output (); printf_filtered ("Can't send signals to this remote system. %s not sent.\n", gdb_signal_to_name (rs->last_sent_signal)); rs->last_sent_signal = GDB_SIGNAL_0; - target_terminal_inferior (); + target_terminal::inferior (); strcpy (buf, rs->last_sent_step ? "s" : "c"); putpkt (buf); @@ -7476,7 +7520,7 @@ remote_wait (struct target_ops *ops, static int fetch_register_using_p (struct regcache *regcache, struct packet_reg *reg) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch *gdbarch = regcache->arch (); struct remote_state *rs = get_remote_state (); char *buf, *p; gdb_byte *regp = (gdb_byte *) alloca (register_size (gdbarch, reg->regnum)); @@ -7505,7 +7549,7 @@ fetch_register_using_p (struct regcache *regcache, struct packet_reg *reg) return 0; case PACKET_ERROR: error (_("Could not fetch register \"%s\"; remote failure reply '%s'"), - gdbarch_register_name (get_regcache_arch (regcache), + gdbarch_register_name (regcache->arch (), reg->regnum), buf); } @@ -7569,9 +7613,9 @@ send_g_packet (void) static void process_g_packet (struct regcache *regcache) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch *gdbarch = regcache->arch (); struct remote_state *rs = get_remote_state (); - struct remote_arch_state *rsa = get_remote_arch_state (); + remote_arch_state *rsa = get_remote_arch_state (gdbarch); int i, buf_len; char *p; char *regs; @@ -7580,7 +7624,8 @@ process_g_packet (struct regcache *regcache) /* Further sanity checks, with knowledge of the architecture. */ if (buf_len > 2 * rsa->sizeof_g_packet) - error (_("Remote 'g' packet reply is too long: %s"), rs->buf); + error (_("Remote 'g' packet reply is too long (expected %ld bytes, got %d " + "bytes): %s"), rsa->sizeof_g_packet, buf_len / 2, rs->buf); /* Save the size of the packet sent to us by the target. It is used as a heuristic when determining the max size of packets that the @@ -7704,7 +7749,8 @@ static void remote_fetch_registers (struct target_ops *ops, struct regcache *regcache, int regnum) { - struct remote_arch_state *rsa = get_remote_arch_state (); + struct gdbarch *gdbarch = regcache->arch (); + remote_arch_state *rsa = get_remote_arch_state (gdbarch); int i; set_remote_traceframe (); @@ -7712,7 +7758,7 @@ remote_fetch_registers (struct target_ops *ops, if (regnum >= 0) { - struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum); + packet_reg *reg = packet_reg_from_regnum (gdbarch, rsa, regnum); gdb_assert (reg != NULL); @@ -7738,7 +7784,7 @@ remote_fetch_registers (struct target_ops *ops, fetch_registers_using_g (regcache); - for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) + for (i = 0; i < gdbarch_num_regs (gdbarch); i++) if (!rsa->regs[i].in_g_packet) if (!fetch_register_using_p (regcache, &rsa->regs[i])) { @@ -7754,7 +7800,7 @@ remote_fetch_registers (struct target_ops *ops, static void remote_prepare_to_store (struct target_ops *self, struct regcache *regcache) { - struct remote_arch_state *rsa = get_remote_arch_state (); + remote_arch_state *rsa = get_remote_arch_state (regcache->arch ()); int i; /* Make sure the entire registers array is valid. */ @@ -7763,7 +7809,7 @@ remote_prepare_to_store (struct target_ops *self, struct regcache *regcache) case PACKET_DISABLE: case PACKET_SUPPORT_UNKNOWN: /* Make sure all the necessary registers are cached. */ - for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) + for (i = 0; i < gdbarch_num_regs (regcache->arch ()); i++) if (rsa->regs[i].in_g_packet) regcache_raw_update (regcache, rsa->regs[i].regnum); break; @@ -7779,7 +7825,7 @@ static int store_register_using_P (const struct regcache *regcache, struct packet_reg *reg) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch *gdbarch = regcache->arch (); struct remote_state *rs = get_remote_state (); /* Try storing a single register. */ char *buf = rs->buf; @@ -7820,7 +7866,7 @@ static void store_registers_using_G (const struct regcache *regcache) { struct remote_state *rs = get_remote_state (); - struct remote_arch_state *rsa = get_remote_arch_state (); + remote_arch_state *rsa = get_remote_arch_state (regcache->arch ()); gdb_byte *regs; char *p; @@ -7831,7 +7877,7 @@ store_registers_using_G (const struct regcache *regcache) regs = (gdb_byte *) alloca (rsa->sizeof_g_packet); memset (regs, 0, rsa->sizeof_g_packet); - for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) + for (i = 0; i < gdbarch_num_regs (regcache->arch ()); i++) { struct packet_reg *r = &rsa->regs[i]; @@ -7844,8 +7890,6 @@ store_registers_using_G (const struct regcache *regcache) each byte encoded as two hex characters. */ p = rs->buf; *p++ = 'G'; - /* remote_prepare_to_store insures that rsa->sizeof_g_packet gets - updated. */ bin2hex (regs, p, rsa->sizeof_g_packet); putpkt (rs->buf); getpkt (&rs->buf, &rs->buf_size, 0); @@ -7861,7 +7905,8 @@ static void remote_store_registers (struct target_ops *ops, struct regcache *regcache, int regnum) { - struct remote_arch_state *rsa = get_remote_arch_state (); + struct gdbarch *gdbarch = regcache->arch (); + remote_arch_state *rsa = get_remote_arch_state (gdbarch); int i; set_remote_traceframe (); @@ -7869,7 +7914,7 @@ remote_store_registers (struct target_ops *ops, if (regnum >= 0) { - struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum); + packet_reg *reg = packet_reg_from_regnum (gdbarch, rsa, regnum); gdb_assert (reg != NULL); @@ -7893,7 +7938,7 @@ remote_store_registers (struct target_ops *ops, store_registers_using_G (regcache); - for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) + for (i = 0; i < gdbarch_num_regs (gdbarch); i++) if (!rsa->regs[i].in_g_packet) if (!store_register_using_P (regcache, &rsa->regs[i])) /* See above for why we do not issue an error here. */ @@ -8384,7 +8429,7 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, if (get_traceframe_number () != -1) { - VEC(mem_range_s) *available; + std::vector available; /* If we fail to get the set of available memory, then the target does not support querying traceframe info, and so we @@ -8392,27 +8437,20 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, target implements the old QTro packet then). */ if (traceframe_available_memory (&available, memaddr, len)) { - struct cleanup *old_chain; - - old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available); - - if (VEC_empty (mem_range_s, available) - || VEC_index (mem_range_s, available, 0)->start != memaddr) + if (available.empty () || available[0].start != memaddr) { enum target_xfer_status res; /* Don't read into the traceframe's available memory. */ - if (!VEC_empty (mem_range_s, available)) + if (!available.empty ()) { LONGEST oldlen = len; - len = VEC_index (mem_range_s, available, 0)->start - memaddr; + len = available[0].start - memaddr; gdb_assert (len <= oldlen); } - do_cleanups (old_chain); - /* This goes through the topmost target again. */ res = remote_xfer_live_readonly_partial (ops, myaddr, memaddr, len, unit_size, xfered_len); @@ -8431,9 +8469,7 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, case the target implements the deprecated QTro packet to cater for older GDBs (the target's knowledge of read-only sections may be outdated by now). */ - len = VEC_index (mem_range_s, available, 0)->length; - - do_cleanups (old_chain); + len = available[0].length; } } @@ -8471,14 +8507,6 @@ remote_send_printf (const char *format, ...) return packet_check_result (rs->buf); } -static void -restore_remote_timeout (void *p) -{ - int value = *(int *)p; - - remote_timeout = value; -} - /* Flash writing can take quite some time. We'll set effectively infinite timeout for flash operations. In future, we'll need to decide on a better approach. */ @@ -8489,12 +8517,9 @@ remote_flash_erase (struct target_ops *ops, ULONGEST address, LONGEST length) { 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; + scoped_restore restore_timeout + = make_scoped_restore (&remote_timeout, remote_flash_timeout); ret = remote_send_printf ("vFlashErase:%s,%s", phex (address, addr_size), @@ -8508,8 +8533,6 @@ remote_flash_erase (struct target_ops *ops, default: break; } - - do_cleanups (back_to); } static enum target_xfer_status @@ -8517,30 +8540,21 @@ remote_flash_write (struct target_ops *ops, ULONGEST address, ULONGEST length, ULONGEST *xfered_len, const gdb_byte *data) { - int saved_remote_timeout = remote_timeout; - enum target_xfer_status ret; - struct cleanup *back_to = make_cleanup (restore_remote_timeout, - &saved_remote_timeout); - - remote_timeout = remote_flash_timeout; - ret = remote_write_bytes_aux ("vFlashWrite:", address, data, length, 1, - xfered_len,'X', 0); - do_cleanups (back_to); - - return ret; + scoped_restore restore_timeout + = make_scoped_restore (&remote_timeout, remote_flash_timeout); + return remote_write_bytes_aux ("vFlashWrite:", address, data, length, 1, + xfered_len,'X', 0); } static void remote_flash_done (struct target_ops *ops) { - int saved_remote_timeout = remote_timeout; int ret; - struct cleanup *back_to = make_cleanup (restore_remote_timeout, - &saved_remote_timeout); - remote_timeout = remote_flash_timeout; + scoped_restore restore_timeout + = make_scoped_restore (&remote_timeout, remote_flash_timeout); + ret = remote_send_printf ("vFlashDone"); - do_cleanups (back_to); switch (ret) { @@ -8588,18 +8602,18 @@ readchar (int timeout) { int ch; struct remote_state *rs = get_remote_state (); - struct cleanup *old_chain; - old_chain = make_cleanup_override_quit_handler (remote_serial_quit_handler); - - rs->got_ctrlc_during_io = 0; + { + scoped_restore restore_quit + = make_scoped_restore (&quit_handler, remote_serial_quit_handler); - ch = serial_readchar (rs->remote_desc, timeout); + rs->got_ctrlc_during_io = 0; - if (rs->got_ctrlc_during_io) - set_quit_flag (); + ch = serial_readchar (rs->remote_desc, timeout); - do_cleanups (old_chain); + if (rs->got_ctrlc_during_io) + set_quit_flag (); + } if (ch >= 0) return ch; @@ -8630,9 +8644,9 @@ static void remote_serial_write (const char *str, int len) { struct remote_state *rs = get_remote_state (); - struct cleanup *old_chain; - old_chain = make_cleanup_override_quit_handler (remote_serial_quit_handler); + scoped_restore restore_quit + = make_scoped_restore (&quit_handler, remote_serial_quit_handler); rs->got_ctrlc_during_io = 0; @@ -8644,8 +8658,6 @@ remote_serial_write (const char *str, int len) if (rs->got_ctrlc_during_io) set_quit_flag (); - - do_cleanups (old_chain); } /* Send the command in *BUF to the remote machine, and read the reply @@ -8705,8 +8717,8 @@ putpkt_binary (const char *buf, int cnt) struct remote_state *rs = get_remote_state (); int i; unsigned char csum = 0; - char *buf2 = (char *) xmalloc (cnt + 6); - struct cleanup *old_chain = make_cleanup (xfree, buf2); + gdb::def_vector data (cnt + 6); + char *buf2 = data.data (); int ch; int tcount = 0; @@ -8809,7 +8821,6 @@ putpkt_binary (const char *buf, int cnt) case '+': if (remote_debug) fprintf_unfiltered (gdb_stdlog, "Ack\n"); - do_cleanups (old_chain); return 1; case '-': if (remote_debug) @@ -8818,10 +8829,7 @@ putpkt_binary (const char *buf, int cnt) case SERIAL_TIMEOUT: tcount++; if (tcount > 3) - { - do_cleanups (old_chain); - return 0; - } + return 0; break; /* Retransmit buffer. */ case '$': { @@ -8905,7 +8913,6 @@ putpkt_binary (const char *buf, int cnt) #endif } - do_cleanups (old_chain); return 0; } @@ -9515,7 +9522,7 @@ extended_remote_disable_randomization (int val) xsnprintf (rs->buf, get_remote_packet_size (), "QDisableRandomization:%x", val); putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (*reply == '\0') error (_("Target does not support QDisableRandomization.")); if (strcmp (reply, "OK") != 0) @@ -9544,12 +9551,9 @@ extended_remote_run (const std::string &args) if (!args.empty ()) { - struct cleanup *back_to; int i; - char **argv; - argv = gdb_buildargv (args.c_str ()); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (args.c_str ()); for (i = 0; argv[i] != NULL; i++) { if (strlen (argv[i]) * 2 + 1 + len >= get_remote_packet_size ()) @@ -9558,7 +9562,6 @@ extended_remote_run (const std::string &args) len += 2 * bin2hex ((gdb_byte *) argv[i], rs->buf + len, strlen (argv[i])); } - do_cleanups (back_to); } rs->buf[len++] = '\0'; @@ -9585,6 +9588,96 @@ extended_remote_run (const std::string &args) } } +/* Helper function to send set/unset environment packets. ACTION is + either "set" or "unset". PACKET is either "QEnvironmentHexEncoded" + or "QEnvironmentUnsetVariable". VALUE is the variable to be + sent. */ + +static void +send_environment_packet (struct remote_state *rs, + const char *action, + const char *packet, + const char *value) +{ + /* Convert the environment variable to an hex string, which + is the best format to be transmitted over the wire. */ + std::string encoded_value = bin2hex ((const gdb_byte *) value, + strlen (value)); + + xsnprintf (rs->buf, get_remote_packet_size (), + "%s:%s", packet, encoded_value.c_str ()); + + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); + if (strcmp (rs->buf, "OK") != 0) + warning (_("Unable to %s environment variable '%s' on remote."), + action, value); +} + +/* Helper function to handle the QEnvironment* packets. */ + +static void +extended_remote_environment_support (struct remote_state *rs) +{ + if (packet_support (PACKET_QEnvironmentReset) != PACKET_DISABLE) + { + putpkt ("QEnvironmentReset"); + getpkt (&rs->buf, &rs->buf_size, 0); + if (strcmp (rs->buf, "OK") != 0) + warning (_("Unable to reset environment on remote.")); + } + + gdb_environ *e = ¤t_inferior ()->environment; + + if (packet_support (PACKET_QEnvironmentHexEncoded) != PACKET_DISABLE) + for (const std::string &el : e->user_set_env ()) + send_environment_packet (rs, "set", "QEnvironmentHexEncoded", + el.c_str ()); + + if (packet_support (PACKET_QEnvironmentUnset) != PACKET_DISABLE) + for (const std::string &el : e->user_unset_env ()) + send_environment_packet (rs, "unset", "QEnvironmentUnset", el.c_str ()); +} + +/* Helper function to set the current working directory for the + inferior in the remote target. */ + +static void +extended_remote_set_inferior_cwd (struct remote_state *rs) +{ + if (packet_support (PACKET_QSetWorkingDir) != PACKET_DISABLE) + { + const char *inferior_cwd = get_inferior_cwd (); + + if (inferior_cwd != NULL) + { + std::string hexpath = bin2hex ((const gdb_byte *) inferior_cwd, + strlen (inferior_cwd)); + + xsnprintf (rs->buf, get_remote_packet_size (), + "QSetWorkingDir:%s", hexpath.c_str ()); + } + else + { + /* An empty inferior_cwd means that the user wants us to + reset the remote server's inferior's cwd. */ + xsnprintf (rs->buf, get_remote_packet_size (), + "QSetWorkingDir:"); + } + + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); + if (packet_ok (rs->buf, + &remote_protocol_packets[PACKET_QSetWorkingDir]) + != PACKET_OK) + error (_("\ +Remote replied unexpectedly while setting the inferior's working\n\ +directory: %s"), + rs->buf); + + } +} + /* In the extended protocol we want to be able to do things like "run" and have them basically work as expected. So we need a special create_inferior function. We support changing the @@ -9625,6 +9718,10 @@ Remote replied unexpectedly while setting startup-with-shell: %s"), rs->buf); } + extended_remote_environment_support (rs); + + extended_remote_set_inferior_cwd (rs); + /* Now restart the remote server. */ run_worked = extended_remote_run (args) != -1; if (!run_worked) @@ -10181,10 +10278,9 @@ remote_verify_memory (struct target_ops *ops, Useful for verifying the image on the target against the exec file. */ static void -compare_sections_command (char *args, int from_tty) +compare_sections_command (const char *args, int from_tty) { asection *s; - struct cleanup *old_chain; gdb_byte *sectdata; const char *sectname; bfd_size_type size; @@ -10225,11 +10321,10 @@ compare_sections_command (char *args, int from_tty) matched = 1; /* Do this section. */ lma = s->lma; - sectdata = (gdb_byte *) xmalloc (size); - old_chain = make_cleanup (xfree, sectdata); - bfd_get_section_contents (exec_bfd, s, sectdata, 0, size); + gdb::byte_vector sectdata (size); + bfd_get_section_contents (exec_bfd, s, sectdata.data (), 0, size); - res = target_verify_memory (sectdata, lma, size); + res = target_verify_memory (sectdata.data (), lma, size); if (res == -1) error (_("target memory fault, section %s, range %s -- %s"), sectname, @@ -10246,8 +10341,6 @@ compare_sections_command (char *args, int from_tty) printf_filtered ("MIS-MATCHED!\n"); mismatched++; } - - do_cleanups (old_chain); } if (mismatched > 0) warning (_("One or more sections of the target image does not match\n\ @@ -10766,26 +10859,21 @@ remote_rcmd (struct target_ops *self, const char *command, } } -static VEC(mem_region_s) * +static std::vector remote_memory_map (struct target_ops *ops) { - VEC(mem_region_s) *result = NULL; - char *text = target_read_stralloc (¤t_target, - TARGET_OBJECT_MEMORY_MAP, NULL); + std::vector result; + gdb::unique_xmalloc_ptr text + = target_read_stralloc (¤t_target, TARGET_OBJECT_MEMORY_MAP, NULL); if (text) - { - struct cleanup *back_to = make_cleanup (xfree, text); - - result = parse_memory_map (text); - do_cleanups (back_to); - } + result = parse_memory_map (text.get ()); return result; } static void -packet_command (char *args, int from_tty) +packet_command (const char *args, int from_tty) { struct remote_state *rs = get_remote_state (); @@ -10830,7 +10918,7 @@ static void init_remote_threadtests (void); #define SAMPLE_THREAD 0x05060708 /* Truncated 64 bit threadid. */ static void -threadset_test_cmd (char *cmd, int tty) +threadset_test_cmd (const char *cmd, int tty) { int sample_thread = SAMPLE_THREAD; @@ -10840,7 +10928,7 @@ threadset_test_cmd (char *cmd, int tty) static void -threadalive_test (char *cmd, int tty) +threadalive_test (const char *cmd, int tty) { int sample_thread = SAMPLE_THREAD; int pid = ptid_get_pid (inferior_ptid); @@ -10865,7 +10953,7 @@ output_threadid (char *title, threadref *ref) } static void -threadlist_test_cmd (char *cmd, int tty) +threadlist_test_cmd (const char *cmd, int tty) { int startflag = 1; threadref nextthread; @@ -10910,7 +10998,7 @@ get_and_display_threadinfo (threadref *ref) } static void -threadinfo_test_cmd (char *cmd, int tty) +threadinfo_test_cmd (const char *cmd, int tty) { int athread = SAMPLE_THREAD; threadref thread; @@ -10930,7 +11018,7 @@ thread_display_step (threadref *ref, void *context) } static void -threadlist_update_test_cmd (char *cmd, int tty) +threadlist_update_test_cmd (const char *cmd, int tty) { printf_filtered ("Remote Threadlist update test\n"); remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS); @@ -11904,7 +11992,6 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) { struct cleanup *back_to, *close_cleanup; int retcode, fd, remote_errno, bytes, io_size; - FILE *file; gdb_byte *buffer; int bytes_in_buffer; int saw_eof; @@ -11914,10 +12001,9 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) if (!rs->remote_desc) error (_("command can only be used with remote target")); - file = gdb_fopen_cloexec (local_file, "rb"); + gdb_file_up file = gdb_fopen_cloexec (local_file, "rb"); if (file == NULL) perror_with_name (local_file); - back_to = make_cleanup_fclose (file); fd = remote_hostio_open (find_target_at (process_stratum), NULL, remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT @@ -11930,7 +12016,7 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) remote packet limit, so we'll transfer slightly fewer. */ io_size = get_remote_packet_size (); buffer = (gdb_byte *) xmalloc (io_size); - make_cleanup (xfree, buffer); + back_to = make_cleanup (xfree, buffer); close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd); @@ -11943,10 +12029,10 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) { bytes = fread (buffer + bytes_in_buffer, 1, io_size - bytes_in_buffer, - file); + file.get ()); if (bytes == 0) { - if (ferror (file)) + if (ferror (file.get ())) error (_("Error reading %s."), local_file); else { @@ -11997,7 +12083,6 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty) { struct cleanup *back_to, *close_cleanup; int fd, remote_errno, bytes, io_size; - FILE *file; gdb_byte *buffer; ULONGEST offset; struct remote_state *rs = get_remote_state (); @@ -12011,16 +12096,15 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty) if (fd == -1) remote_hostio_error (remote_errno); - file = gdb_fopen_cloexec (local_file, "wb"); + gdb_file_up file = gdb_fopen_cloexec (local_file, "wb"); if (file == NULL) perror_with_name (local_file); - back_to = make_cleanup_fclose (file); /* Send up to this many bytes at once. They won't all fit in the remote packet limit, so we'll transfer slightly fewer. */ io_size = get_remote_packet_size (); buffer = (gdb_byte *) xmalloc (io_size); - make_cleanup (xfree, buffer); + back_to = make_cleanup (xfree, buffer); close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd); @@ -12037,7 +12121,7 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty) offset += bytes; - bytes = fwrite (buffer, 1, bytes, file); + bytes = fwrite (buffer, 1, bytes, file.get ()); if (bytes == 0) perror_with_name (local_file); } @@ -12070,64 +12154,46 @@ remote_file_delete (const char *remote_file, int from_tty) } static void -remote_put_command (char *args, int from_tty) +remote_put_command (const char *args, int from_tty) { - struct cleanup *back_to; - char **argv; - if (args == NULL) error_no_arg (_("file to put")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (args); if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL) error (_("Invalid parameters to remote put")); remote_file_put (argv[0], argv[1], from_tty); - - do_cleanups (back_to); } static void -remote_get_command (char *args, int from_tty) +remote_get_command (const char *args, int from_tty) { - struct cleanup *back_to; - char **argv; - if (args == NULL) error_no_arg (_("file to get")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (args); if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL) error (_("Invalid parameters to remote get")); remote_file_get (argv[0], argv[1], from_tty); - - do_cleanups (back_to); } static void -remote_delete_command (char *args, int from_tty) +remote_delete_command (const char *args, int from_tty) { - struct cleanup *back_to; - char **argv; - if (args == NULL) error_no_arg (_("file to delete")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (args); if (argv[0] == NULL || argv[1] != NULL) error (_("Invalid parameters to remote delete")); remote_file_delete (argv[0], from_tty); - - do_cleanups (back_to); } static void -remote_command (char *args, int from_tty) +remote_command (const char *args, int from_tty) { help_list (remote_cmdlist, "remote ", all_commands, gdb_stdout); } @@ -12215,9 +12281,11 @@ remote_can_run_breakpoint_commands (struct target_ops *self) static void remote_trace_init (struct target_ops *self) { + struct remote_state *rs = get_remote_state (); + putpkt ("QTinit"); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (strcmp (target_buf, "OK") != 0) + remote_get_noisy_reply (); + if (strcmp (rs->buf, "OK") != 0) error (_("Target does not support this command.")); } @@ -12261,8 +12329,8 @@ remote_download_command_source (int num, ULONGEST addr, rs->buf + strlen (rs->buf), rs->buf_size - strlen (rs->buf)); putpkt (rs->buf); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (strcmp (target_buf, "OK")) + remote_get_noisy_reply (); + if (strcmp (rs->buf, "OK")) warning (_("Target does not support source download.")); if (cmd->control_type == while_control @@ -12276,8 +12344,8 @@ remote_download_command_source (int num, ULONGEST addr, rs->buf + strlen (rs->buf), rs->buf_size - strlen (rs->buf)); putpkt (rs->buf); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (strcmp (target_buf, "OK")) + remote_get_noisy_reply (); + if (strcmp (rs->buf, "OK")) warning (_("Target does not support source download.")); } } @@ -12298,6 +12366,7 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc) char *pkt; struct breakpoint *b = loc->owner; struct tracepoint *t = (struct tracepoint *) b; + struct remote_state *rs = get_remote_state (); encode_actions_rsp (loc, &tdp_actions, &stepping_actions); old_chain = make_cleanup (free_actions_list_cleanup_wrapper, @@ -12381,8 +12450,8 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc) if (b->commands || *default_collect) strcat (buf, "-"); putpkt (buf); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (strcmp (target_buf, "OK")) + remote_get_noisy_reply (); + if (strcmp (rs->buf, "OK")) error (_("Target does not support tracepoints.")); /* do_single_steps (t); */ @@ -12397,9 +12466,8 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc) ((tdp_actions[ndx + 1] || stepping_actions) ? '-' : 0)); putpkt (buf); - remote_get_noisy_reply (&target_buf, - &target_buf_size); - if (strcmp (target_buf, "OK")) + remote_get_noisy_reply (); + if (strcmp (rs->buf, "OK")) error (_("Error on target while setting tracepoints.")); } } @@ -12414,9 +12482,8 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc) stepping_actions[ndx], (stepping_actions[ndx + 1] ? "-" : "")); putpkt (buf); - remote_get_noisy_reply (&target_buf, - &target_buf_size); - if (strcmp (target_buf, "OK")) + remote_get_noisy_reply (); + if (strcmp (rs->buf, "OK")) error (_("Error on target while setting tracepoints.")); } } @@ -12430,8 +12497,8 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc) event_location_to_string (b->location.get ()), buf + strlen (buf), 2048 - strlen (buf)); putpkt (buf); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (strcmp (target_buf, "OK")) + remote_get_noisy_reply (); + if (strcmp (rs->buf, "OK")) warning (_("Target does not support source download.")); } if (b->cond_string) @@ -12441,8 +12508,8 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc) "cond", b->cond_string, buf + strlen (buf), 2048 - strlen (buf)); putpkt (buf); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (strcmp (target_buf, "OK")) + remote_get_noisy_reply (); + if (strcmp (rs->buf, "OK")) warning (_("Target does not support source download.")); } remote_download_command_source (b->number, loc->address, @@ -12496,10 +12563,10 @@ remote_download_trace_state_variable (struct target_ops *self, p += 2 * bin2hex ((gdb_byte *) (tsv->name), p, strlen (tsv->name)); *p++ = '\0'; putpkt (rs->buf); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (*target_buf == '\0') + remote_get_noisy_reply (); + if (*rs->buf == '\0') error (_("Target does not support this command.")); - if (strcmp (target_buf, "OK") != 0) + if (strcmp (rs->buf, "OK") != 0) error (_("Error on target while downloading trace state variable.")); } @@ -12514,7 +12581,7 @@ remote_enable_tracepoint (struct target_ops *self, xsnprintf (rs->buf, get_remote_packet_size (), "QTEnable:%x:%s", location->owner->number, addr_buf); putpkt (rs->buf); - remote_get_noisy_reply (&rs->buf, &rs->buf_size); + remote_get_noisy_reply (); if (*rs->buf == '\0') error (_("Target does not support enabling tracepoints while a trace run is ongoing.")); if (strcmp (rs->buf, "OK") != 0) @@ -12532,7 +12599,7 @@ remote_disable_tracepoint (struct target_ops *self, xsnprintf (rs->buf, get_remote_packet_size (), "QTDisable:%x:%s", location->owner->number, addr_buf); putpkt (rs->buf); - remote_get_noisy_reply (&rs->buf, &rs->buf_size); + remote_get_noisy_reply (); if (*rs->buf == '\0') error (_("Target does not support disabling tracepoints while a trace run is ongoing.")); if (strcmp (rs->buf, "OK") != 0) @@ -12552,8 +12619,10 @@ remote_trace_set_readonly_regions (struct target_ops *self) if (!exec_bfd) return; /* No information to give. */ - strcpy (target_buf, "QTro"); - offset = strlen (target_buf); + struct remote_state *rs = get_remote_state (); + + strcpy (rs->buf, "QTro"); + offset = strlen (rs->buf); for (s = exec_bfd->sections; s; s = s->next) { char tmp1[40], tmp2[40]; @@ -12570,33 +12639,35 @@ remote_trace_set_readonly_regions (struct target_ops *self) sprintf_vma (tmp1, vma); sprintf_vma (tmp2, vma + size); sec_length = 1 + strlen (tmp1) + 1 + strlen (tmp2); - if (offset + sec_length + 1 > target_buf_size) + if (offset + sec_length + 1 > rs->buf_size) { if (packet_support (PACKET_qXfer_traceframe_info) != PACKET_ENABLE) warning (_("\ Too many sections for read-only sections definition packet.")); break; } - xsnprintf (target_buf + offset, target_buf_size - offset, ":%s,%s", + xsnprintf (rs->buf + offset, rs->buf_size - offset, ":%s,%s", tmp1, tmp2); offset += sec_length; } if (anysecs) { - putpkt (target_buf); - getpkt (&target_buf, &target_buf_size, 0); + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); } } static void remote_trace_start (struct target_ops *self) { + struct remote_state *rs = get_remote_state (); + putpkt ("QTStart"); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (*target_buf == '\0') + remote_get_noisy_reply (); + if (*rs->buf == '\0') error (_("Target does not support this command.")); - if (strcmp (target_buf, "OK") != 0) - error (_("Bogus reply from target: %s"), target_buf); + if (strcmp (rs->buf, "OK") != 0) + error (_("Bogus reply from target: %s"), rs->buf); } static int @@ -12607,17 +12678,19 @@ remote_get_trace_status (struct target_ops *self, struct trace_status *ts) /* FIXME we need to get register block size some other way. */ extern int trace_regblock_size; enum packet_result result; + struct remote_state *rs = get_remote_state (); if (packet_support (PACKET_qTStatus) == PACKET_DISABLE) return -1; - trace_regblock_size = get_remote_arch_state ()->sizeof_g_packet; + trace_regblock_size + = get_remote_arch_state (target_gdbarch ())->sizeof_g_packet; putpkt ("qTStatus"); TRY { - p = remote_get_noisy_reply (&target_buf, &target_buf_size); + p = remote_get_noisy_reply (); } CATCH (ex, RETURN_MASK_ERROR) { @@ -12640,7 +12713,7 @@ remote_get_trace_status (struct target_ops *self, struct trace_status *ts) ts->filename = NULL; if (*p++ != 'T') - error (_("Bogus trace status reply from target: %s"), target_buf); + error (_("Bogus trace status reply from target: %s"), rs->buf); /* Function 'parse_trace_status' sets default value of each field of 'ts' at first, so we don't have to do it here. */ @@ -12672,7 +12745,7 @@ remote_get_tracepoint_status (struct target_ops *self, struct breakpoint *bp, xsnprintf (rs->buf, size, "qTP:%x:%s", tp->number_on_target, phex_nz (loc->address, 0)); putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (reply && *reply) { if (*reply == 'V') @@ -12687,7 +12760,7 @@ remote_get_tracepoint_status (struct target_ops *self, struct breakpoint *bp, xsnprintf (rs->buf, size, "qTP:%x:%s", utp->number, phex_nz (utp->addr, 0)); putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (reply && *reply) { if (*reply == 'V') @@ -12699,12 +12772,14 @@ remote_get_tracepoint_status (struct target_ops *self, struct breakpoint *bp, static void remote_trace_stop (struct target_ops *self) { + struct remote_state *rs = get_remote_state (); + putpkt ("QTStop"); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (*target_buf == '\0') + remote_get_noisy_reply (); + if (*rs->buf == '\0') error (_("Target does not support this command.")); - if (strcmp (target_buf, "OK") != 0) - error (_("Bogus reply from target: %s"), target_buf); + if (strcmp (rs->buf, "OK") != 0) + error (_("Bogus reply from target: %s"), rs->buf); } static int @@ -12751,7 +12826,7 @@ remote_trace_find (struct target_ops *self, } putpkt (rs->buf); - reply = remote_get_noisy_reply (&(rs->buf), &rs->buf_size); + reply = remote_get_noisy_reply (); if (*reply == '\0') error (_("Target does not support this command.")); @@ -12802,7 +12877,7 @@ remote_get_trace_state_variable_value (struct target_ops *self, xsnprintf (rs->buf, get_remote_packet_size (), "qTV:%x", tsvnum); putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (reply && *reply) { if (*reply == 'V') @@ -12829,7 +12904,7 @@ remote_save_trace_data (struct target_ops *self, const char *filename) p += 2 * bin2hex ((gdb_byte *) filename, p, strlen (filename)); *p++ = '\0'; putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (*reply == '\0') error (_("Target does not support this command.")); if (strcmp (reply, "OK") != 0) @@ -12860,7 +12935,7 @@ remote_get_raw_trace_data (struct target_ops *self, *p++ = '\0'; putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (reply && *reply) { /* 'l' by itself means we're at the end of the buffer and @@ -12873,7 +12948,7 @@ remote_get_raw_trace_data (struct target_ops *self, what was returned in the packet; if the target is unexpectedly generous and gives us a bigger reply than we asked for, we don't want to crash. */ - rslt = hex2bin (target_buf, buf, len); + rslt = hex2bin (reply, buf, len); return rslt; } @@ -12892,7 +12967,7 @@ remote_set_disconnected_tracing (struct target_ops *self, int val) xsnprintf (rs->buf, get_remote_packet_size (), "QTDisconnected:%x", val); putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (*reply == '\0') error (_("Target does not support this command.")); if (strcmp (reply, "OK") != 0) @@ -12920,29 +12995,21 @@ remote_set_circular_trace_buffer (struct target_ops *self, int val) xsnprintf (rs->buf, get_remote_packet_size (), "QTBuffer:circular:%x", val); putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (*reply == '\0') error (_("Target does not support this command.")); if (strcmp (reply, "OK") != 0) error (_("Bogus reply from target: %s"), reply); } -static struct traceframe_info * +static traceframe_info_up remote_traceframe_info (struct target_ops *self) { - char *text; - - text = target_read_stralloc (¤t_target, - TARGET_OBJECT_TRACEFRAME_INFO, NULL); + gdb::unique_xmalloc_ptr text + = target_read_stralloc (¤t_target, TARGET_OBJECT_TRACEFRAME_INFO, + NULL); if (text != NULL) - { - struct traceframe_info *info; - struct cleanup *back_to = make_cleanup (xfree, text); - - info = parse_traceframe_info (text); - do_cleanups (back_to); - return info; - } + return parse_traceframe_info (text.get ()); return NULL; } @@ -12968,7 +13035,7 @@ remote_get_min_fast_tracepoint_insn_len (struct target_ops *self) xsnprintf (rs->buf, get_remote_packet_size (), "qTMinFTPILen"); putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (*reply == '\0') return -1; else @@ -13003,7 +13070,7 @@ remote_set_trace_buffer_size (struct target_ops *self, LONGEST val) buf += hexnumstr (buf, (ULONGEST) val); putpkt (rs->buf); - remote_get_noisy_reply (&rs->buf, &rs->buf_size); + remote_get_noisy_reply (); result = packet_ok (rs->buf, &remote_protocol_packets[PACKET_QTBuffer_size]); @@ -13049,7 +13116,7 @@ remote_set_trace_notes (struct target_ops *self, *buf = '\0'; putpkt (rs->buf); - reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + reply = remote_get_noisy_reply (); if (*reply == '\0') return 0; @@ -13201,18 +13268,10 @@ btrace_sync_conf (const struct btrace_config *conf) static void btrace_read_config (struct btrace_config *conf) { - char *xml; - - xml = target_read_stralloc (¤t_target, - TARGET_OBJECT_BTRACE_CONF, ""); + gdb::unique_xmalloc_ptr xml + = target_read_stralloc (¤t_target, TARGET_OBJECT_BTRACE_CONF, ""); if (xml != NULL) - { - struct cleanup *cleanup; - - cleanup = make_cleanup (xfree, xml); - parse_xml_btrace_conf (conf, xml); - do_cleanups (cleanup); - } + parse_xml_btrace_conf (conf, xml.get ()); } /* Maybe reopen target btrace. */ @@ -13383,9 +13442,7 @@ remote_read_btrace (struct target_ops *self, enum btrace_read_type type) { struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace]; - struct cleanup *cleanup; const char *annex; - char *xml; if (packet_config_support (packet) != PACKET_ENABLE) error (_("Target does not support branch tracing.")); @@ -13411,14 +13468,12 @@ remote_read_btrace (struct target_ops *self, (unsigned int) type); } - xml = target_read_stralloc (¤t_target, - TARGET_OBJECT_BTRACE, annex); + gdb::unique_xmalloc_ptr xml + = target_read_stralloc (¤t_target, TARGET_OBJECT_BTRACE, annex); if (xml == NULL) return BTRACE_ERR_UNKNOWN; - cleanup = make_cleanup (xfree, xml); - parse_xml_btrace (btrace, xml); - do_cleanups (cleanup); + parse_xml_btrace (btrace, xml.get ()); return BTRACE_ERR_NONE; } @@ -13452,16 +13507,13 @@ remote_load (struct target_ops *self, const char *name, int from_tty) static char * remote_pid_to_exec_file (struct target_ops *self, int pid) { - static char *filename = NULL; + static gdb::unique_xmalloc_ptr filename; struct inferior *inf; char *annex = NULL; if (packet_support (PACKET_qXfer_exec_file) != PACKET_ENABLE) return NULL; - if (filename != NULL) - xfree (filename); - inf = find_inferior_pid (pid); if (inf == NULL) internal_error (__FILE__, __LINE__, @@ -13478,7 +13530,7 @@ remote_pid_to_exec_file (struct target_ops *self, int pid) filename = target_read_stralloc (¤t_target, TARGET_OBJECT_EXEC_FILE, annex); - return filename; + return filename.get (); } /* Implement the to_can_do_single_step target_ops method. */ @@ -13515,6 +13567,35 @@ remote_execution_direction (struct target_ops *self) return rs->last_resume_exec_dir; } +/* Return pointer to the thread_info struct which corresponds to + THREAD_HANDLE (having length HANDLE_LEN). */ + +static struct thread_info * +remote_thread_handle_to_thread_info (struct target_ops *ops, + const gdb_byte *thread_handle, + int handle_len, + struct inferior *inf) +{ + struct thread_info *tp; + + ALL_NON_EXITED_THREADS (tp) + { + struct private_thread_info *priv = get_private_info_thread (tp); + + if (tp->inf == inf && priv != NULL) + { + if (handle_len != priv->thread_handle->size ()) + error (_("Thread handle size mismatch: %d vs %zu (from remote)"), + handle_len, priv->thread_handle->size ()); + if (memcmp (thread_handle, priv->thread_handle->data (), + handle_len) == 0) + return tp; + } + } + + return NULL; +} + static void init_remote_ops (void) { @@ -13663,6 +13744,8 @@ Specify the serial device it is connected to\n\ remote_ops.to_insert_exec_catchpoint = remote_insert_exec_catchpoint; remote_ops.to_remove_exec_catchpoint = remote_remove_exec_catchpoint; remote_ops.to_execution_direction = remote_execution_direction; + remote_ops.to_thread_handle_to_thread_info = + remote_thread_handle_to_thread_info; } /* Set up the extended remote vector by making a copy of the standard @@ -13799,13 +13882,13 @@ remote_thread_events (struct target_ops *ops, int enable) } static void -set_remote_cmd (char *args, int from_tty) +set_remote_cmd (const char *args, int from_tty) { help_list (remote_set_cmdlist, "set remote ", all_commands, gdb_stdout); } static void -show_remote_cmd (char *args, int from_tty) +show_remote_cmd (const char *args, int from_tty) { /* We can't just use cmd_show_list here, because we want to skip the redundant "show remote Z-packet" and the legacy aliases. */ @@ -14115,9 +14198,25 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (&remote_protocol_packets[PACKET_QProgramSignals], "QProgramSignals", "program-signals", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_QSetWorkingDir], + "QSetWorkingDir", "set-working-dir", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_QStartupWithShell], "QStartupWithShell", "startup-with-shell", 0); + add_packet_config_cmd (&remote_protocol_packets + [PACKET_QEnvironmentHexEncoded], + "QEnvironmentHexEncoded", "environment-hex-encoded", + 0); + + add_packet_config_cmd (&remote_protocol_packets[PACKET_QEnvironmentReset], + "QEnvironmentReset", "environment-reset", + 0); + + add_packet_config_cmd (&remote_protocol_packets[PACKET_QEnvironmentUnset], + "QEnvironmentUnset", "environment-unset", + 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_qSymbol], "qSymbol", "symbol-lookup", 0); @@ -14439,8 +14538,4 @@ stepping is supported by the target. The default is on."), magic_null_ptid = ptid_build (42000, -1, 1); not_sent_ptid = ptid_build (42000, -2, 1); any_thread_ptid = ptid_build (42000, 0, 1); - - target_buf_size = 2048; - target_buf = (char *) xmalloc (target_buf_size); } -