X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fremote.c;h=ae8c5236085eff03eb3625b07be07f3ee83b2ac7;hb=0d866f62e8517512fdc0fe92e3f2e4675b2d716f;hp=60086d25f03cf4fd3767ecd22e337bb80a5a7305;hpb=f48ff2a7d3f69653dbf164e03d3397de8f6ba7c0;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote.c b/gdb/remote.c index 60086d25f0..ae8c523608 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -1,6 +1,6 @@ /* Remote target communications for serial-line targets in custom GDB protocol - Copyright (C) 1988-2013 Free Software Foundation, Inc. + Copyright (C) 1988-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -20,7 +20,7 @@ /* See the GDB User Guide for details of the GDB remote protocol. */ #include "defs.h" -#include "gdb_string.h" +#include #include #include #include "inferior.h" @@ -45,8 +45,8 @@ #include "target-descriptions.h" #include "gdb_bfd.h" #include "filestuff.h" +#include "rsp-low.h" -#include #include #include "event-loop.h" @@ -60,7 +60,7 @@ #include "remote-fileio.h" #include "gdb/fileio.h" -#include "gdb_stat.h" +#include #include "xml-support.h" #include "memory-map.h" @@ -98,7 +98,8 @@ static void async_handle_remote_sigint_twice (int); static void remote_files_info (struct target_ops *ignore); -static void remote_prepare_to_store (struct regcache *regcache); +static void remote_prepare_to_store (struct target_ops *self, + struct regcache *regcache); static void remote_open (char *name, int from_tty); @@ -106,7 +107,7 @@ static void extended_remote_open (char *name, int from_tty); static void remote_open_1 (char *, int, struct target_ops *, int extended_p); -static void remote_close (void); +static void remote_close (struct target_ops *self); static void remote_mourn (struct target_ops *ops); @@ -124,16 +125,14 @@ static void remote_serial_write (const char *str, int len); static void remote_kill (struct target_ops *ops); -static int tohex (int nib); - -static int remote_can_async_p (void); +static int remote_can_async_p (struct target_ops *); -static int remote_is_async_p (void); +static int remote_is_async_p (struct target_ops *); -static void remote_async (void (*callback) (enum inferior_event_type event_type, - void *context), void *context); - -static void remote_detach (struct target_ops *ops, char *args, int from_tty); +static void remote_async (struct target_ops *ops, + void (*callback) (enum inferior_event_type event_type, + void *context), + void *context); static void sync_remote_interrupt_twice (int signo); @@ -154,9 +153,7 @@ static void init_remote_ops (void); static void init_extended_remote_ops (void); -static void remote_stop (ptid_t); - -static int ishex (int ch, int *val); +static void remote_stop (struct target_ops *self, ptid_t); static int stubhex (int ch); @@ -178,8 +175,6 @@ static ptid_t remote_current_thread (ptid_t oldptid); static void remote_find_new_threads (void); -static int fromhex (int a); - static int putpkt_binary (char *buf, int cnt); static void check_binary_download (CORE_ADDR addr); @@ -220,20 +215,20 @@ struct stop_reply; static void stop_reply_xfree (struct stop_reply *); static void remote_parse_stop_reply (char *, struct stop_reply *); static void push_stop_reply (struct stop_reply *); -static void discard_pending_stop_replies_in_queue (void); +static void discard_pending_stop_replies_in_queue (struct remote_state *); static int peek_stop_reply (ptid_t ptid); static void remote_async_inferior_event_handler (gdb_client_data); -static void remote_terminal_ours (void); +static void remote_terminal_ours (struct target_ops *self); static int remote_read_description_p (struct target_ops *target); static void remote_console_output (char *msg); -static int remote_supports_cond_breakpoints (void); +static int remote_supports_cond_breakpoints (struct target_ops *self); -static int remote_can_run_breakpoint_commands (void); +static int remote_can_run_breakpoint_commands (struct target_ops *self); /* For "remote". */ @@ -1564,7 +1559,18 @@ remote_add_inferior (int fake_pid_p, int pid, int attached) static void remote_add_thread (ptid_t ptid, int running) { - add_thread (ptid); + struct remote_state *rs = get_remote_state (); + + /* GDB historically didn't pull threads in the initial connection + setup. If the remote target doesn't even have a concept of + threads (e.g., a bare-metal target), even if internally we + consider that a single-threaded target, mentioning a new thread + might be confusing to the user. Be silent then, preserving the + age old behavior. */ + if (rs->starting_up) + add_thread_silent (ptid); + else + add_thread (ptid); set_executing (ptid, running); set_running (ptid, running); @@ -1642,9 +1648,15 @@ remote_notice_new_inferior (ptid_t currthread, int running) /* If we found a new inferior, let the common code do whatever it needs to with it (e.g., read shared libraries, insert - breakpoints). */ + breakpoints), unless we're just setting up an all-stop + connection. */ if (inf != NULL) - notice_new_inferior (currthread, running, 0); + { + struct remote_state *rs = get_remote_state (); + + if (non_stop || !rs->starting_up) + notice_new_inferior (currthread, running, 0); + } } } @@ -1683,7 +1695,8 @@ record_currthread (struct remote_state *rs, ptid_t currthread) it can simply pass through to the inferior without reporting. */ static void -remote_pass_signals (int numsigs, unsigned char *pass_signals) +remote_pass_signals (struct target_ops *self, + int numsigs, unsigned char *pass_signals) { if (remote_protocol_packets[PACKET_QPassSignals].support != PACKET_DISABLE) { @@ -1717,11 +1730,9 @@ remote_pass_signals (int numsigs, unsigned char *pass_signals) *p = 0; if (!rs->last_pass_packet || strcmp (rs->last_pass_packet, pass_packet)) { - char *buf = rs->buf; - putpkt (pass_packet); getpkt (&rs->buf, &rs->buf_size, 0); - packet_ok (buf, &remote_protocol_packets[PACKET_QPassSignals]); + packet_ok (rs->buf, &remote_protocol_packets[PACKET_QPassSignals]); if (rs->last_pass_packet) xfree (rs->last_pass_packet); rs->last_pass_packet = pass_packet; @@ -1735,7 +1746,8 @@ remote_pass_signals (int numsigs, unsigned char *pass_signals) signals it should pass through to the inferior when detaching. */ static void -remote_program_signals (int numsigs, unsigned char *signals) +remote_program_signals (struct target_ops *self, + int numsigs, unsigned char *signals) { if (remote_protocol_packets[PACKET_QProgramSignals].support != PACKET_DISABLE) { @@ -1770,11 +1782,9 @@ remote_program_signals (int numsigs, unsigned char *signals) if (!rs->last_program_signals_packet || strcmp (rs->last_program_signals_packet, packet) != 0) { - char *buf = rs->buf; - putpkt (packet); getpkt (&rs->buf, &rs->buf_size, 0); - packet_ok (buf, &remote_protocol_packets[PACKET_QProgramSignals]); + packet_ok (rs->buf, &remote_protocol_packets[PACKET_QProgramSignals]); xfree (rs->last_program_signals_packet); rs->last_program_signals_packet = packet; } @@ -1926,14 +1936,8 @@ struct gdb_ext_thread_info #define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES * 2) -char *unpack_varlen_hex (char *buff, ULONGEST *result); - static char *unpack_nibble (char *buf, int *val); -static char *pack_nibble (char *buf, int nibble); - -static char *pack_hex_byte (char *pkt, int /* unsigned char */ byte); - static char *unpack_byte (char *buf, int *value); static char *pack_int (char *buf, int value); @@ -2060,31 +2064,6 @@ read_ptid (char *buf, char **obuf) return ptid_build (pid, 0, tid); } -/* Encode 64 bits in 16 chars of hex. */ - -static const char hexchars[] = "0123456789abcdef"; - -static int -ishex (int ch, int *val) -{ - if ((ch >= 'a') && (ch <= 'f')) - { - *val = ch - 'a' + 10; - return 1; - } - if ((ch >= 'A') && (ch <= 'F')) - { - *val = ch - 'A' + 10; - return 1; - } - if ((ch >= '0') && (ch <= '9')) - { - *val = ch - '0'; - return 1; - } - return 0; -} - static int stubhex (int ch) { @@ -2114,23 +2093,6 @@ stub_unpack_int (char *buff, int fieldlength) return retval; } -char * -unpack_varlen_hex (char *buff, /* packet to parse */ - ULONGEST *result) -{ - int nibble; - ULONGEST retval = 0; - - while (ishex (*buff, &nibble)) - { - buff++; - retval = retval << 4; - retval |= nibble & 0x0f; - } - *result = retval; - return buff; -} - static char * unpack_nibble (char *buf, int *val) { @@ -2138,21 +2100,6 @@ unpack_nibble (char *buf, int *val) return buf; } -static char * -pack_nibble (char *buf, int nibble) -{ - *buf++ = hexchars[(nibble & 0x0f)]; - return buf; -} - -static char * -pack_hex_byte (char *pkt, int byte) -{ - *pkt++ = hexchars[(byte >> 4) & 0xf]; - *pkt++ = hexchars[(byte & 0xf)]; - return pkt; -} - static char * unpack_byte (char *buf, int *value) { @@ -2861,7 +2808,7 @@ remote_threads_info (struct target_ops *ops) */ static char * -remote_threads_extra_info (struct thread_info *tp) +remote_threads_extra_info (struct target_ops *self, struct thread_info *tp) { struct remote_state *rs = get_remote_state (); int result; @@ -3022,7 +2969,7 @@ remote_static_tracepoint_markers_by_strid (const char *strid) /* Implement the to_get_ada_task_ptid function for the remote targets. */ static ptid_t -remote_get_ada_task_ptid (long lwp, long thread) +remote_get_ada_task_ptid (struct target_ops *self, long lwp, long thread) { return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp); } @@ -3046,7 +2993,7 @@ extended_remote_restart (void) /* Clean up connection to a remote debugger. */ static void -remote_close (void) +remote_close (struct target_ops *self) { struct remote_state *rs = get_remote_state (); @@ -3055,7 +3002,7 @@ remote_close (void) /* Make sure we leave stdin registered in the event loop, and we don't leave the async SIGINT signal handler installed. */ - remote_terminal_ours (); + remote_terminal_ours (self); serial_close (rs->remote_desc); rs->remote_desc = NULL; @@ -3069,7 +3016,7 @@ remote_close (void) /* We are closing the remote target, so we should discard everything of this target. */ - discard_pending_stop_replies_in_queue (); + discard_pending_stop_replies_in_queue (rs); if (remote_async_inferior_event_token) delete_async_event_handler (&remote_async_inferior_event_token); @@ -3312,6 +3259,28 @@ stop_reply_extract_thread (char *stop_reply) return null_ptid; } +/* Determine the remote side's current thread. If we have a stop + reply handy (in WAIT_STATUS), maybe it's a T stop reply with a + "thread" register we can extract the current thread from. If not, + ask the remote which is the current thread with qC. The former + method avoids a roundtrip. */ + +static ptid_t +get_current_thread (char *wait_status) +{ + ptid_t ptid; + + /* Note we don't use remote_parse_stop_reply as that makes use of + the target architecture, which we haven't yet fully determined at + this point. */ + if (wait_status != NULL) + ptid = stop_reply_extract_thread (wait_status); + if (ptid_equal (ptid, null_ptid)) + ptid = remote_current_thread (inferior_ptid); + + return ptid; +} + /* Query the remote target for which is the current thread/process, add it to our tables, and update INFERIOR_PTID. The caller is responsible for setting the state such that the remote end is ready @@ -3332,18 +3301,8 @@ add_current_inferior_and_thread (char *wait_status) inferior_ptid = null_ptid; - /* Now, if we have thread information, update inferior_ptid. First - if we have a stop reply handy, maybe it's a T stop reply with a - "thread" register we can extract the current thread from. If - not, ask the remote which is the current thread, with qC. The - former method avoids a roundtrip. Note we don't use - remote_parse_stop_reply as that makes use of the target - architecture, which we haven't yet fully determined at this - point. */ - if (wait_status != NULL) - ptid = stop_reply_extract_thread (wait_status); - if (ptid_equal (ptid, null_ptid)) - ptid = remote_current_thread (inferior_ptid); + /* Now, if we have thread information, update inferior_ptid. */ + ptid = get_current_thread (wait_status); if (!ptid_equal (ptid, null_ptid)) { @@ -3513,10 +3472,35 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p) strcpy (wait_status, rs->buf); } + /* Fetch thread list. */ + target_find_new_threads (); + /* Let the stub know that we want it to return the thread. */ set_continue_thread (minus_one_ptid); - add_current_inferior_and_thread (wait_status); + if (thread_count () == 0) + { + /* Target has no concept of threads at all. GDB treats + non-threaded target as single-threaded; add a main + thread. */ + add_current_inferior_and_thread (wait_status); + } + else + { + /* We have thread information; select the thread the target + says should be current. If we're reconnecting to a + multi-threaded program, this will ideally be the thread + that last reported an event before GDB disconnected. */ + inferior_ptid = get_current_thread (wait_status); + if (ptid_equal (inferior_ptid, null_ptid)) + { + /* Odd... The target was able to list threads, but not + tell us which thread was current (no "thread" + register in T stop reply?). Just pick the first + thread in the thread list then. */ + inferior_ptid = thread_list->ptid; + } + } /* init_wait_for_inferior should be called before get_offsets in order to manage `inserted' flag in bp loc in a correct state. @@ -3610,13 +3594,13 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p) gdb_assert (wait_status == NULL); /* Report all signals during attach/startup. */ - remote_pass_signals (0, NULL); + remote_pass_signals (target, 0, NULL); } /* If we connected to a live target, do some additional setup. */ if (target_has_execution) { - if (exec_bfd) /* No use without an exec file. */ + if (symfile_objfile) /* No use without a symbol-file. */ remote_check_symbols (); } @@ -4425,7 +4409,7 @@ remote_open_1 (char *name, int from_tty, die when it hits one. */ static void -remote_detach_1 (char *args, int from_tty, int extended) +remote_detach_1 (const char *args, int from_tty, int extended) { int pid = ptid_get_pid (inferior_ptid); struct remote_state *rs = get_remote_state (); @@ -4469,13 +4453,13 @@ remote_detach_1 (char *args, int from_tty, int extended) } static void -remote_detach (struct target_ops *ops, char *args, int from_tty) +remote_detach (struct target_ops *ops, const char *args, int from_tty) { remote_detach_1 (args, from_tty, 0); } static void -extended_remote_detach (struct target_ops *ops, char *args, int from_tty) +extended_remote_detach (struct target_ops *ops, const char *args, int from_tty) { remote_detach_1 (args, from_tty, 1); } @@ -4617,68 +4601,6 @@ extended_remote_attach (struct target_ops *ops, char *args, int from_tty) extended_remote_attach_1 (ops, args, from_tty); } -/* Convert hex digit A to a number. */ - -static int -fromhex (int a) -{ - if (a >= '0' && a <= '9') - return a - '0'; - else if (a >= 'a' && a <= 'f') - return a - 'a' + 10; - else if (a >= 'A' && a <= 'F') - return a - 'A' + 10; - else - error (_("Reply contains invalid hex digit %d"), a); -} - -int -hex2bin (const char *hex, gdb_byte *bin, int count) -{ - int i; - - for (i = 0; i < count; i++) - { - if (hex[0] == 0 || hex[1] == 0) - { - /* Hex string is short, or of uneven length. - Return the count that has been converted so far. */ - return i; - } - *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]); - hex += 2; - } - return i; -} - -/* Convert number NIB to a hex digit. */ - -static int -tohex (int nib) -{ - if (nib < 10) - return '0' + nib; - else - return 'a' + nib - 10; -} - -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); - - for (i = 0; i < count; i++) - { - *hex++ = tohex ((*bin >> 4) & 0xf); - *hex++ = tohex (*bin++ & 0xf); - } - *hex = 0; - return i; -} /* Check for the availability of vCont. This function should also check the response. */ @@ -5163,7 +5085,7 @@ remote_stop_as (ptid_t ptid) will eventually end up here. */ static void -remote_stop (ptid_t ptid) +remote_stop (struct target_ops *self, ptid_t ptid) { if (remote_debug) fprintf_unfiltered (gdb_stdlog, "remote_stop called\n"); @@ -5205,7 +5127,7 @@ Give up (and stop debugging it)? "))) is required. */ static void -remote_terminal_inferior (void) +remote_terminal_inferior (struct target_ops *self) { if (!target_async_permitted) /* Nothing to do. */ @@ -5228,7 +5150,7 @@ remote_terminal_inferior (void) } static void -remote_terminal_ours (void) +remote_terminal_ours (struct target_ops *self) { if (!target_async_permitted) /* Nothing to do. */ @@ -5274,6 +5196,11 @@ typedef struct stop_reply /* The identifier of the thread about this event */ ptid_t ptid; + /* The remote state this event is associated with. When the remote + connection, represented by a remote_state object, is closed, + all the associated stop_reply events should be released. */ + struct remote_state *rs; + struct target_waitstatus ws; /* Expedited registers. This makes remote debugging a bit more @@ -5352,7 +5279,7 @@ static struct notif_event * remote_notif_stop_alloc_reply (void) { struct notif_event *r - = (struct notif_event *) XMALLOC (struct stop_reply); + = (struct notif_event *) XNEW (struct stop_reply); r->dtr = stop_reply_dtr; @@ -5434,19 +5361,40 @@ discard_pending_stop_replies (struct inferior *inf) remove_stop_reply_for_inferior, ¶m); } -/* Discard the stop replies in stop_reply_queue. */ +/* If its remote state is equal to the given remote state, + remove EVENT from the stop reply queue. */ + +static int +remove_stop_reply_of_remote_state (QUEUE (stop_reply_p) *q, + QUEUE_ITER (stop_reply_p) *iter, + stop_reply_p event, + void *data) +{ + struct queue_iter_param *param = data; + struct remote_state *rs = param->input; + + if (event->rs == rs) + { + stop_reply_xfree (event); + QUEUE_remove_elem (stop_reply_p, q, iter); + } + + return 1; +} + +/* Discard the stop replies for RS in stop_reply_queue. */ static void -discard_pending_stop_replies_in_queue (void) +discard_pending_stop_replies_in_queue (struct remote_state *rs) { struct queue_iter_param param; - param.input = NULL; + param.input = rs; param.output = NULL; /* Discard the stop replies we have already pulled with vStopped. */ QUEUE_iterate (stop_reply_p, stop_reply_queue, - remove_stop_reply_for_inferior, ¶m); + remove_stop_reply_of_remote_state, ¶m); } /* A parameter to pass data in and out. */ @@ -5559,6 +5507,7 @@ remote_parse_stop_reply (char *buf, struct stop_reply *event) char *p; event->ptid = null_ptid; + event->rs = get_remote_state (); event->ws.kind = TARGET_WAITKIND_IGNORE; event->ws.value.integer = 0; event->stopped_by_watchpoint_p = 0; @@ -5693,9 +5642,16 @@ Packet: '%s'\n"), /* fall through */ case 'S': /* Old style status, just signal only. */ - event->ws.kind = TARGET_WAITKIND_STOPPED; - event->ws.value.sig = (enum gdb_signal) - (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))); + { + int sig; + + event->ws.kind = TARGET_WAITKIND_STOPPED; + sig = (fromhex (buf[1]) << 4) + fromhex (buf[2]); + if (GDB_SIGNAL_FIRST <= sig && sig < GDB_SIGNAL_LAST) + event->ws.value.sig = (enum gdb_signal) sig; + else + event->ws.value.sig = GDB_SIGNAL_UNKNOWN; + } break; case 'W': /* Target exited. */ case 'X': @@ -5719,7 +5675,10 @@ Packet: '%s'\n"), { /* The remote process exited with a signal. */ event->ws.kind = TARGET_WAITKIND_SIGNALLED; - event->ws.value.sig = (enum gdb_signal) value; + if (GDB_SIGNAL_FIRST <= value && value < GDB_SIGNAL_LAST) + event->ws.value.sig = (enum gdb_signal) value; + else + event->ws.value.sig = GDB_SIGNAL_UNKNOWN; } /* If no process is specified, assume inferior_ptid. */ @@ -6378,7 +6337,7 @@ remote_fetch_registers (struct target_ops *ops, first. */ static void -remote_prepare_to_store (struct regcache *regcache) +remote_prepare_to_store (struct target_ops *self, struct regcache *regcache) { struct remote_arch_state *rsa = get_remote_arch_state (); int i; @@ -6594,91 +6553,6 @@ remote_address_masked (CORE_ADDR addr) return addr; } -/* Convert BUFFER, binary data at least LEN bytes long, into escaped - binary data in OUT_BUF. Set *OUT_LEN to the length of the data - encoded in OUT_BUF, and return the number of bytes in OUT_BUF - (which may be more than *OUT_LEN due to escape characters). The - total number of bytes in the output buffer will be at most - OUT_MAXLEN. */ - -static int -remote_escape_output (const gdb_byte *buffer, int len, - gdb_byte *out_buf, int *out_len, - int out_maxlen) -{ - int input_index, output_index; - - output_index = 0; - for (input_index = 0; input_index < len; input_index++) - { - gdb_byte b = buffer[input_index]; - - if (b == '$' || b == '#' || b == '}') - { - /* These must be escaped. */ - if (output_index + 2 > out_maxlen) - break; - out_buf[output_index++] = '}'; - out_buf[output_index++] = b ^ 0x20; - } - else - { - if (output_index + 1 > out_maxlen) - break; - out_buf[output_index++] = b; - } - } - - *out_len = input_index; - return output_index; -} - -/* Convert BUFFER, escaped data LEN bytes long, into binary data - in OUT_BUF. Return the number of bytes written to OUT_BUF. - Raise an error if the total number of bytes exceeds OUT_MAXLEN. - - This function reverses remote_escape_output. It allows more - escaped characters than that function does, in particular because - '*' must be escaped to avoid the run-length encoding processing - in reading packets. */ - -static int -remote_unescape_input (const gdb_byte *buffer, int len, - gdb_byte *out_buf, int out_maxlen) -{ - int input_index, output_index; - int escaped; - - output_index = 0; - escaped = 0; - for (input_index = 0; input_index < len; input_index++) - { - gdb_byte b = buffer[input_index]; - - if (output_index + 1 > out_maxlen) - { - warning (_("Received too much data from remote target;" - " ignoring overflow.")); - return output_index; - } - - if (escaped) - { - out_buf[output_index++] = b ^ 0x20; - escaped = 0; - } - else if (b == '}') - escaped = 1; - else - out_buf[output_index++] = b; - } - - if (escaped) - error (_("Unmatched escape character in target response.")); - - return output_index; -} - /* Determine whether the remote target supports binary downloading. This is accomplished by sending a no-op memory write of zero length to the target at the specified address. It does not suffice to send @@ -6753,14 +6627,15 @@ check_binary_download (CORE_ADDR addr) If USE_LENGTH is 0, then the field and the preceding comma are omitted. - Returns the number of bytes transferred, or a negative value (an - 'enum target_xfer_error' value) for error. Only transfer a single - packet. */ + Return the transferred status, error or OK (an + 'enum target_xfer_status' value). Save the number of bytes + transferred in *XFERED_LEN. Only transfer a single packet. */ -static LONGEST +static enum target_xfer_status remote_write_bytes_aux (const char *header, CORE_ADDR memaddr, - const gdb_byte *myaddr, ssize_t len, - char packet_format, int use_length) + const gdb_byte *myaddr, ULONGEST len, + ULONGEST *xfered_len, char packet_format, + int use_length) { struct remote_state *rs = get_remote_state (); char *p; @@ -6776,8 +6651,8 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr, internal_error (__FILE__, __LINE__, _("remote_write_bytes_aux: bad packet format")); - if (len <= 0) - return 0; + if (len == 0) + return TARGET_XFER_EOF; payload_size = get_memory_write_packet_size (); @@ -6900,7 +6775,8 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr, /* Return NR_BYTES, not TODO, in case escape chars caused us to send fewer bytes than we'd planned. */ - return nr_bytes; + *xfered_len = (ULONGEST) nr_bytes; + return TARGET_XFER_OK; } /* Write memory data directly to the remote machine. @@ -6909,12 +6785,13 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr, MYADDR is the address of the buffer in our space. LEN is the number of bytes. - Returns number of bytes transferred, or a negative value (an 'enum - target_xfer_error' value) for error. Only transfer a single - packet. */ + Return the transferred status, error or OK (an + 'enum target_xfer_status' value). Save the number of bytes + transferred in *XFERED_LEN. Only transfer a single packet. */ -static LONGEST -remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len) +static enum target_xfer_status +remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len, + ULONGEST *xfered_len) { char *packet_format = 0; @@ -6937,7 +6814,8 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len) } return remote_write_bytes_aux (packet_format, - memaddr, myaddr, len, packet_format[0], 1); + memaddr, myaddr, len, xfered_len, + packet_format[0], 1); } /* Read memory data directly from the remote machine. @@ -6946,11 +6824,13 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len) MYADDR is the address of the buffer in our space. LEN is the number of bytes. - Returns number of bytes transferred, or a negative value (an 'enum - target_xfer_error' value) for error. */ + Return the transferred status, error or OK (an + 'enum target_xfer_status' value). Save the number of bytes + transferred in *XFERED_LEN. */ -static LONGEST -remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len) +static enum target_xfer_status +remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, + ULONGEST *xfered_len) { struct remote_state *rs = get_remote_state (); int max_buf_size; /* Max size of packet output buffer. */ @@ -6958,7 +6838,7 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len) int todo; int i; - if (len <= 0) + if (len == 0) return 0; max_buf_size = get_memory_read_packet_size (); @@ -6987,7 +6867,8 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len) p = rs->buf; i = hex2bin (p, myaddr, todo); /* Return what we have. Let higher layers handle partial reads. */ - return i; + *xfered_len = (ULONGEST) i; + return TARGET_XFER_OK; } @@ -7059,18 +6940,19 @@ remote_flash_erase (struct target_ops *ops, do_cleanups (back_to); } -static LONGEST -remote_flash_write (struct target_ops *ops, - ULONGEST address, LONGEST length, - const gdb_byte *data) +static enum target_xfer_status +remote_flash_write (struct target_ops *ops, ULONGEST address, + ULONGEST length, ULONGEST *xfered_len, + const gdb_byte *data) { int saved_remote_timeout = remote_timeout; - LONGEST ret; + enum target_xfer_status ret; struct cleanup *back_to = make_cleanup (restore_remote_timeout, - &saved_remote_timeout); + &saved_remote_timeout); remote_timeout = remote_flash_timeout; - ret = remote_write_bytes_aux ("vFlashWrite:", address, data, length, 'X', 0); + ret = remote_write_bytes_aux ("vFlashWrite:", address, data, length, + xfered_len,'X', 0); do_cleanups (back_to); return ret; @@ -7655,7 +7537,7 @@ getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever, we get a packet. */ for (;;) { - /* If we get a timeout or bad checksm, retry up to MAX_TRIES + /* If we get a timeout or bad checksum, retry up to MAX_TRIES times. */ for (tries = 1; tries <= MAX_TRIES; tries++) { @@ -7781,23 +7663,39 @@ getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever, } -/* A helper function that just calls putpkt; for type correctness. */ - -static int -putpkt_for_catch_errors (void *arg) -{ - return putpkt (arg); -} - static void remote_kill (struct target_ops *ops) { - /* Use catch_errors so the user can quit from gdb even when we + volatile struct gdb_exception ex; + + /* Catch errors so the user can quit from gdb even when we aren't on speaking terms with the remote system. */ - catch_errors (putpkt_for_catch_errors, "k", "", RETURN_MASK_ERROR); + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + putpkt ("k"); + } + if (ex.reason < 0) + { + if (ex.error == TARGET_CLOSE_ERROR) + { + /* If we got an (EOF) error that caused the target + to go away, then we're done, that's what we wanted. + "k" is susceptible to cause a premature EOF, given + that the remote server isn't actually required to + reply to "k", and it can happen that it doesn't + even get to reply ACK to the "k". */ + return; + } + + /* Otherwise, something went wrong. We didn't actually kill + the target. Just propagate the exception, and let the + user or higher layers decide what to do. */ + throw_exception (ex); + } - /* Don't wait for it to die. I'm not really sure it matters whether - we do or not. For the existing stubs, kill is a noop. */ + /* We've killed the remote end, we get to mourn it. Since this is + target remote, single-process, mourning the inferior also + unpushes remote_ops. */ target_mourn_inferior (); } @@ -7936,7 +7834,7 @@ extended_remote_mourn (struct target_ops *ops) } static int -extended_remote_supports_disable_randomization (void) +extended_remote_supports_disable_randomization (struct target_ops *self) { return (remote_protocol_packets[PACKET_QDisableRandomization].support == PACKET_ENABLE); @@ -7974,7 +7872,8 @@ extended_remote_run (char *args) if (strlen (remote_exec_file) * 2 + len >= get_remote_packet_size ()) error (_("Remote file name too long for run packet")); - len += 2 * bin2hex ((gdb_byte *) remote_exec_file, rs->buf + len, 0); + len += 2 * bin2hex ((gdb_byte *) remote_exec_file, rs->buf + len, + strlen (remote_exec_file)); gdb_assert (args != NULL); if (*args) @@ -7990,7 +7889,8 @@ extended_remote_run (char *args) if (strlen (argv[i]) * 2 + 1 + len >= get_remote_packet_size ()) error (_("Argument list too long for run packet")); rs->buf[len++] = ';'; - len += 2 * bin2hex ((gdb_byte *) argv[i], rs->buf + len, 0); + len += 2 * bin2hex ((gdb_byte *) argv[i], rs->buf + len, + strlen (argv[i])); } do_cleanups (back_to); } @@ -8026,8 +7926,9 @@ extended_remote_run (char *args) environment. */ static void -extended_remote_create_inferior_1 (char *exec_file, char *args, - char **env, int from_tty) +extended_remote_create_inferior (struct target_ops *ops, + char *exec_file, char *args, + char **env, int from_tty) { int run_worked; char *stop_reply; @@ -8039,7 +7940,7 @@ extended_remote_create_inferior_1 (char *exec_file, char *args, target_async (inferior_event_handler, 0); /* Disable address space randomization if requested (and supported). */ - if (extended_remote_supports_disable_randomization ()) + if (extended_remote_supports_disable_randomization (ops)) extended_remote_disable_randomization (disable_randomization); /* Now restart the remote server. */ @@ -8073,14 +7974,6 @@ extended_remote_create_inferior_1 (char *exec_file, char *args, /* Get updated offsets, if the stub uses qOffsets. */ get_offsets (); } - -static void -extended_remote_create_inferior (struct target_ops *ops, - char *exec_file, char *args, - char **env, int from_tty) -{ - extended_remote_create_inferior_1 (exec_file, args, env, from_tty); -} /* Given a location's target info BP_TGT and the packet buffer BUF, output @@ -8116,8 +8009,6 @@ remote_add_target_side_condition (struct gdbarch *gdbarch, buf = pack_hex_byte (buf, aexpr->buf[i]); *buf = '\0'; } - - VEC_free (agent_expr_p, bp_tgt->conditions); return 0; } @@ -8148,8 +8039,6 @@ remote_add_target_side_commands (struct gdbarch *gdbarch, buf = pack_hex_byte (buf, aexpr->buf[i]); *buf = '\0'; } - - VEC_free (agent_expr_p, bp_tgt->tcommands); } /* Insert a breakpoint. On targets that have software breakpoint @@ -8157,7 +8046,8 @@ remote_add_target_side_commands (struct gdbarch *gdbarch, which don't, we insert a traditional memory breakpoint. */ static int -remote_insert_breakpoint (struct gdbarch *gdbarch, +remote_insert_breakpoint (struct target_ops *ops, + struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { /* Try the "Z" s/w breakpoint packet if it is not already disabled. @@ -8191,10 +8081,10 @@ remote_insert_breakpoint (struct gdbarch *gdbarch, p += hexnumstr (p, addr); xsnprintf (p, endbuf - p, ",%d", bpsize); - if (remote_supports_cond_breakpoints ()) + if (remote_supports_cond_breakpoints (ops)) remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf); - if (remote_can_run_breakpoint_commands ()) + if (remote_can_run_breakpoint_commands (ops)) remote_add_target_side_commands (gdbarch, bp_tgt, p); putpkt (rs->buf); @@ -8213,11 +8103,18 @@ remote_insert_breakpoint (struct gdbarch *gdbarch, } } - return memory_insert_breakpoint (gdbarch, bp_tgt); + /* If this breakpoint has target-side commands but this stub doesn't + support Z0 packets, throw error. */ + if (!VEC_empty (agent_expr_p, bp_tgt->tcommands)) + throw_error (NOT_SUPPORTED_ERROR, _("\ +Target doesn't support breakpoints that have target side commands.")); + + return memory_insert_breakpoint (ops, gdbarch, bp_tgt); } static int -remote_remove_breakpoint (struct gdbarch *gdbarch, +remote_remove_breakpoint (struct target_ops *ops, + struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { CORE_ADDR addr = bp_tgt->placed_address; @@ -8247,7 +8144,7 @@ remote_remove_breakpoint (struct gdbarch *gdbarch, return (rs->buf[0] == 'E'); } - return memory_remove_breakpoint (gdbarch, bp_tgt); + return memory_remove_breakpoint (ops, gdbarch, bp_tgt); } static int @@ -8271,7 +8168,8 @@ watchpoint_to_Z_packet (int type) } static int -remote_insert_watchpoint (CORE_ADDR addr, int len, int type, +remote_insert_watchpoint (struct target_ops *self, + CORE_ADDR addr, int len, int type, struct expression *cond) { struct remote_state *rs = get_remote_state (); @@ -8320,7 +8218,8 @@ remote_watchpoint_addr_within_range (struct target_ops *target, CORE_ADDR addr, static int -remote_remove_watchpoint (CORE_ADDR addr, int len, int type, +remote_remove_watchpoint (struct target_ops *self, + CORE_ADDR addr, int len, int type, struct expression *cond) { struct remote_state *rs = get_remote_state (); @@ -8362,7 +8261,8 @@ int remote_hw_watchpoint_length_limit = -1; int remote_hw_breakpoint_limit = -1; static int -remote_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +remote_region_ok_for_hw_watchpoint (struct target_ops *self, + CORE_ADDR addr, int len) { if (remote_hw_watchpoint_length_limit == 0) return 0; @@ -8375,7 +8275,8 @@ remote_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) } static int -remote_check_watch_resources (int type, int cnt, int ot) +remote_check_watch_resources (struct target_ops *self, + int type, int cnt, int ot) { if (type == bp_hardware_breakpoint) { @@ -8401,7 +8302,7 @@ remote_check_watch_resources (int type, int cnt, int ot) } static int -remote_stopped_by_watchpoint (void) +remote_stopped_by_watchpoint (struct target_ops *ops) { struct remote_state *rs = get_remote_state (); @@ -8414,7 +8315,7 @@ remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) struct remote_state *rs = get_remote_state (); int rc = 0; - if (remote_stopped_by_watchpoint ()) + if (remote_stopped_by_watchpoint (target)) { *addr_p = rs->remote_watch_data_address; rc = 1; @@ -8425,7 +8326,7 @@ remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) static int -remote_insert_hw_breakpoint (struct gdbarch *gdbarch, +remote_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { CORE_ADDR addr; @@ -8459,10 +8360,10 @@ remote_insert_hw_breakpoint (struct gdbarch *gdbarch, p += hexnumstr (p, (ULONGEST) addr); xsnprintf (p, endbuf - p, ",%x", bp_tgt->placed_size); - if (remote_supports_cond_breakpoints ()) + if (remote_supports_cond_breakpoints (self)) remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf); - if (remote_can_run_breakpoint_commands ()) + if (remote_can_run_breakpoint_commands (self)) remote_add_target_side_commands (gdbarch, bp_tgt, p); putpkt (rs->buf); @@ -8489,7 +8390,7 @@ remote_insert_hw_breakpoint (struct gdbarch *gdbarch, static int -remote_remove_hw_breakpoint (struct gdbarch *gdbarch, +remote_remove_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { CORE_ADDR addr; @@ -8639,10 +8540,10 @@ the loaded file\n")); into remote target. The number of bytes written to the remote target is returned, or -1 for error. */ -static LONGEST +static enum target_xfer_status remote_write_qxfer (struct target_ops *ops, const char *object_name, const char *annex, const gdb_byte *writebuf, - ULONGEST offset, LONGEST len, + ULONGEST offset, LONGEST len, ULONGEST *xfered_len, struct packet_config *packet) { int i, buf_len; @@ -8651,7 +8552,7 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name, int max_size = get_memory_write_packet_size (); if (packet->support == PACKET_DISABLE) - return -1; + return TARGET_XFER_E_IO; /* Insert header. */ i = snprintf (rs->buf, max_size, @@ -8667,10 +8568,12 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name, if (putpkt_binary (rs->buf, i + buf_len) < 0 || getpkt_sane (&rs->buf, &rs->buf_size, 0) < 0 || packet_ok (rs->buf, packet) != PACKET_OK) - return -1; + return TARGET_XFER_E_IO; unpack_varlen_hex (rs->buf, &n); - return n; + + *xfered_len = n; + return TARGET_XFER_OK; } /* Read OBJECT_NAME/ANNEX from the remote target using a qXfer packet. @@ -8680,17 +8583,18 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name, EOF. PACKET is checked and updated to indicate whether the remote target supports this object. */ -static LONGEST +static enum target_xfer_status remote_read_qxfer (struct target_ops *ops, const char *object_name, const char *annex, gdb_byte *readbuf, ULONGEST offset, LONGEST len, + ULONGEST *xfered_len, struct packet_config *packet) { struct remote_state *rs = get_remote_state (); LONGEST i, n, packet_len; if (packet->support == PACKET_DISABLE) - return -1; + return TARGET_XFER_E_IO; /* Check whether we've cached an end-of-object packet that matches this request. */ @@ -8699,7 +8603,8 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name, if (strcmp (object_name, rs->finished_object) == 0 && strcmp (annex ? annex : "", rs->finished_annex) == 0 && offset == rs->finished_offset) - return 0; + return TARGET_XFER_EOF; + /* Otherwise, we're now reading something different. Discard the cache. */ @@ -8720,12 +8625,12 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name, phex_nz (n, sizeof n)); i = putpkt (rs->buf); if (i < 0) - return -1; + return TARGET_XFER_E_IO; rs->buf[0] = '\0'; packet_len = getpkt_sane (&rs->buf, &rs->buf_size, 0); if (packet_len < 0 || packet_ok (rs->buf, packet) != PACKET_OK) - return -1; + return TARGET_XFER_E_IO; if (rs->buf[0] != 'l' && rs->buf[0] != 'm') error (_("Unknown remote qXfer reply: %s"), rs->buf); @@ -8750,13 +8655,20 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name, rs->finished_offset = offset + i; } - return i; + if (i == 0) + return TARGET_XFER_EOF; + else + { + *xfered_len = i; + return TARGET_XFER_OK; + } } -static LONGEST +static enum target_xfer_status remote_xfer_partial (struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, - const gdb_byte *writebuf, ULONGEST offset, LONGEST len) + const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, + ULONGEST *xfered_len) { struct remote_state *rs; int i; @@ -8771,20 +8683,16 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, /* Handle memory using the standard memory routines. */ if (object == TARGET_OBJECT_MEMORY) { - LONGEST xfered; - /* If the remote target is connected but not running, we should pass this request down to a lower stratum (e.g. the executable file). */ if (!target_has_execution) - return 0; + return TARGET_XFER_EOF; if (writebuf != NULL) - xfered = remote_write_bytes (offset, writebuf, len); + return remote_write_bytes (offset, writebuf, len, xfered_len); else - xfered = remote_read_bytes (offset, readbuf, len); - - return xfered; + return remote_read_bytes (offset, readbuf, len, xfered_len); } /* Handle SPU memory using qxfer packets. */ @@ -8792,12 +8700,12 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, { if (readbuf) return remote_read_qxfer (ops, "spu", annex, readbuf, offset, len, - &remote_protocol_packets - [PACKET_qXfer_spu_read]); + xfered_len, &remote_protocol_packets + [PACKET_qXfer_spu_read]); else return remote_write_qxfer (ops, "spu", annex, writebuf, offset, len, - &remote_protocol_packets - [PACKET_qXfer_spu_write]); + xfered_len, &remote_protocol_packets + [PACKET_qXfer_spu_write]); } /* Handle extra signal info using qxfer packets. */ @@ -8805,11 +8713,11 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, { if (readbuf) return remote_read_qxfer (ops, "siginfo", annex, readbuf, offset, len, - &remote_protocol_packets + xfered_len, &remote_protocol_packets [PACKET_qXfer_siginfo_read]); else return remote_write_qxfer (ops, "siginfo", annex, - writebuf, offset, len, + writebuf, offset, len, xfered_len, &remote_protocol_packets [PACKET_qXfer_siginfo_write]); } @@ -8818,11 +8726,11 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, { if (readbuf) return remote_read_qxfer (ops, "statictrace", annex, - readbuf, offset, len, + readbuf, offset, len, xfered_len, &remote_protocol_packets [PACKET_qXfer_statictrace_read]); else - return -1; + return TARGET_XFER_E_IO; } /* Only handle flash writes. */ @@ -8833,10 +8741,11 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, switch (object) { case TARGET_OBJECT_FLASH: - return remote_flash_write (ops, offset, len, writebuf); + return remote_flash_write (ops, offset, len, xfered_len, + writebuf); default: - return -1; + return TARGET_XFER_E_IO; } } @@ -8851,60 +8760,66 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, case TARGET_OBJECT_AUXV: gdb_assert (annex == NULL); return remote_read_qxfer (ops, "auxv", annex, readbuf, offset, len, + xfered_len, &remote_protocol_packets[PACKET_qXfer_auxv]); case TARGET_OBJECT_AVAILABLE_FEATURES: return remote_read_qxfer - (ops, "features", annex, readbuf, offset, len, + (ops, "features", annex, readbuf, offset, len, xfered_len, &remote_protocol_packets[PACKET_qXfer_features]); case TARGET_OBJECT_LIBRARIES: return remote_read_qxfer - (ops, "libraries", annex, readbuf, offset, len, + (ops, "libraries", annex, readbuf, offset, len, xfered_len, &remote_protocol_packets[PACKET_qXfer_libraries]); case TARGET_OBJECT_LIBRARIES_SVR4: return remote_read_qxfer - (ops, "libraries-svr4", annex, readbuf, offset, len, + (ops, "libraries-svr4", annex, readbuf, offset, len, xfered_len, &remote_protocol_packets[PACKET_qXfer_libraries_svr4]); case TARGET_OBJECT_MEMORY_MAP: gdb_assert (annex == NULL); return remote_read_qxfer (ops, "memory-map", annex, readbuf, offset, len, + xfered_len, &remote_protocol_packets[PACKET_qXfer_memory_map]); case TARGET_OBJECT_OSDATA: /* Should only get here if we're connected. */ gdb_assert (rs->remote_desc); return remote_read_qxfer - (ops, "osdata", annex, readbuf, offset, len, + (ops, "osdata", annex, readbuf, offset, len, xfered_len, &remote_protocol_packets[PACKET_qXfer_osdata]); case TARGET_OBJECT_THREADS: gdb_assert (annex == NULL); return remote_read_qxfer (ops, "threads", annex, readbuf, offset, len, + xfered_len, &remote_protocol_packets[PACKET_qXfer_threads]); case TARGET_OBJECT_TRACEFRAME_INFO: gdb_assert (annex == NULL); return remote_read_qxfer - (ops, "traceframe-info", annex, readbuf, offset, len, + (ops, "traceframe-info", annex, readbuf, offset, len, xfered_len, &remote_protocol_packets[PACKET_qXfer_traceframe_info]); case TARGET_OBJECT_FDPIC: return remote_read_qxfer (ops, "fdpic", annex, readbuf, offset, len, + xfered_len, &remote_protocol_packets[PACKET_qXfer_fdpic]); case TARGET_OBJECT_OPENVMS_UIB: return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len, + xfered_len, &remote_protocol_packets[PACKET_qXfer_uib]); case TARGET_OBJECT_BTRACE: return remote_read_qxfer (ops, "btrace", annex, readbuf, offset, len, + xfered_len, &remote_protocol_packets[PACKET_qXfer_btrace]); default: - return -1; + return TARGET_XFER_E_IO; } /* Note: a zero OFFSET and LEN can be used to query the minimum @@ -8914,7 +8829,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, /* Minimum outbuf size is get_remote_packet_size (). If LEN is not large enough let the caller deal with it. */ if (len < get_remote_packet_size ()) - return -1; + return TARGET_XFER_E_IO; len = get_remote_packet_size (); /* Except for querying the minimum buffer size, target must be open. */ @@ -8946,12 +8861,13 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, i = putpkt (rs->buf); if (i < 0) - return i; + return TARGET_XFER_E_IO; getpkt (&rs->buf, &rs->buf_size, 0); strcpy ((char *) readbuf, rs->buf); - return strlen ((char *) readbuf); + *xfered_len = strlen ((char *) readbuf); + return TARGET_XFER_OK; } static int @@ -9046,7 +8962,7 @@ remote_search_memory (struct target_ops* ops, } static void -remote_rcmd (char *command, +remote_rcmd (struct target_ops *self, char *command, struct ui_file *outbuf) { struct remote_state *rs = get_remote_state (); @@ -9068,7 +8984,7 @@ remote_rcmd (char *command, error (_("\"monitor\" command ``%s'' is too long."), command); /* Encode the actual command. */ - bin2hex ((gdb_byte *) command, p, 0); + bin2hex ((gdb_byte *) command, p, strlen (command)); if (putpkt (rs->buf) < 0) error (_("Communication problem with target.")); @@ -9739,7 +9655,8 @@ remote_hostio_send_command (int command_bytes, int which_packet, *REMOTE_ERRNO). */ static int -remote_hostio_open (const char *filename, int flags, int mode, +remote_hostio_open (struct target_ops *self, + const char *filename, int flags, int mode, int *remote_errno) { struct remote_state *rs = get_remote_state (); @@ -9766,7 +9683,8 @@ remote_hostio_open (const char *filename, int flags, int mode, set *REMOTE_ERRNO). */ static int -remote_hostio_pwrite (int fd, const gdb_byte *write_buf, int len, +remote_hostio_pwrite (struct target_ops *self, + int fd, const gdb_byte *write_buf, int len, ULONGEST offset, int *remote_errno) { struct remote_state *rs = get_remote_state (); @@ -9985,7 +9903,8 @@ remote_bfd_iovec_open (struct bfd *abfd, void *open_closure) gdb_assert (remote_filename_p (filename)); - fd = remote_hostio_open (filename + 7, FILEIO_O_RDONLY, 0, &remote_errno); + fd = remote_hostio_open (find_target_at (process_stratum), + filename + 7, FILEIO_O_RDONLY, 0, &remote_errno); if (fd == -1) { errno = remote_fileio_errno_to_host (remote_errno); @@ -10091,7 +10010,8 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) perror_with_name (local_file); back_to = make_cleanup_fclose (file); - fd = remote_hostio_open (remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT + fd = remote_hostio_open (find_target_at (process_stratum), + remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT | FILEIO_O_TRUNC), 0700, &remote_errno); if (fd == -1) @@ -10135,7 +10055,8 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) bytes += bytes_in_buffer; bytes_in_buffer = 0; - retcode = remote_hostio_pwrite (fd, buffer, bytes, + retcode = remote_hostio_pwrite (find_target_at (process_stratum), + fd, buffer, bytes, offset, &remote_errno); if (retcode < 0) @@ -10175,7 +10096,8 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty) if (!rs->remote_desc) error (_("command can only be used with remote target")); - fd = remote_hostio_open (remote_file, FILEIO_O_RDONLY, 0, &remote_errno); + fd = remote_hostio_open (find_target_at (process_stratum), + remote_file, FILEIO_O_RDONLY, 0, &remote_errno); if (fd == -1) remote_hostio_error (remote_errno); @@ -10299,7 +10221,7 @@ remote_command (char *args, int from_tty) } static int -remote_can_execute_reverse (void) +remote_can_execute_reverse (struct target_ops *self) { if (remote_protocol_packets[PACKET_bs].support == PACKET_ENABLE || remote_protocol_packets[PACKET_bc].support == PACKET_ENABLE) @@ -10309,20 +10231,20 @@ remote_can_execute_reverse (void) } static int -remote_supports_non_stop (void) +remote_supports_non_stop (struct target_ops *self) { return 1; } static int -remote_supports_disable_randomization (void) +remote_supports_disable_randomization (struct target_ops *self) { /* Only supported in extended mode. */ return 0; } static int -remote_supports_multi_process (void) +remote_supports_multi_process (struct target_ops *self) { struct remote_state *rs = get_remote_state (); @@ -10342,7 +10264,7 @@ remote_supports_cond_tracepoints (void) } static int -remote_supports_cond_breakpoints (void) +remote_supports_cond_breakpoints (struct target_ops *self) { struct remote_state *rs = get_remote_state (); @@ -10374,7 +10296,7 @@ remote_supports_install_in_trace (void) } static int -remote_supports_enable_disable_tracepoint (void) +remote_supports_enable_disable_tracepoint (struct target_ops *self) { struct remote_state *rs = get_remote_state (); @@ -10382,7 +10304,7 @@ remote_supports_enable_disable_tracepoint (void) } static int -remote_supports_string_tracing (void) +remote_supports_string_tracing (struct target_ops *self) { struct remote_state *rs = get_remote_state (); @@ -10390,7 +10312,7 @@ remote_supports_string_tracing (void) } static int -remote_can_run_breakpoint_commands (void) +remote_can_run_breakpoint_commands (struct target_ops *self) { struct remote_state *rs = get_remote_state (); @@ -10685,7 +10607,7 @@ remote_download_trace_state_variable (struct trace_state_variable *tsv) p = rs->buf + strlen (rs->buf); if ((p - rs->buf) + strlen (tsv->name) * 2 >= get_remote_packet_size ()) error (_("Trace state variable name too long for tsv definition packet")); - p += 2 * bin2hex ((gdb_byte *) (tsv->name), p, 0); + 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); @@ -11015,7 +10937,7 @@ remote_save_trace_data (const char *filename) p += strlen (p); if ((p - rs->buf) + strlen (filename) * 2 >= get_remote_packet_size ()) error (_("Remote file name too long for trace save packet")); - p += 2 * bin2hex ((gdb_byte *) filename, p, 0); + p += 2 * bin2hex ((gdb_byte *) filename, p, strlen (filename)); *p++ = '\0'; putpkt (rs->buf); reply = remote_get_noisy_reply (&target_buf, &target_buf_size); @@ -11120,6 +11042,11 @@ remote_traceframe_info (void) { char *text; + /* If current traceframe is not selected, don't bother the remote + stub. */ + if (get_traceframe_number () < 0) + return NULL; + text = target_read_stralloc (¤t_target, TARGET_OBJECT_TRACEFRAME_INFO, NULL); if (text != NULL) @@ -11215,21 +11142,21 @@ remote_set_trace_notes (const char *user, const char *notes, if (user) { buf += xsnprintf (buf, endbuf - buf, "user:"); - nbytes = bin2hex ((gdb_byte *) user, buf, 0); + nbytes = bin2hex ((gdb_byte *) user, buf, strlen (user)); buf += 2 * nbytes; *buf++ = ';'; } if (notes) { buf += xsnprintf (buf, endbuf - buf, "notes:"); - nbytes = bin2hex ((gdb_byte *) notes, buf, 0); + nbytes = bin2hex ((gdb_byte *) notes, buf, strlen (notes)); buf += 2 * nbytes; *buf++ = ';'; } if (stop_notes) { buf += xsnprintf (buf, endbuf - buf, "tstop:"); - nbytes = bin2hex ((gdb_byte *) stop_notes, buf, 0); + nbytes = bin2hex ((gdb_byte *) stop_notes, buf, strlen (stop_notes)); buf += 2 * nbytes; *buf++ = ';'; } @@ -11284,7 +11211,7 @@ struct btrace_target_info /* Check whether the target supports branch tracing. */ static int -remote_supports_btrace (void) +remote_supports_btrace (struct target_ops *self) { if (remote_protocol_packets[PACKET_Qbtrace_off].support != PACKET_ENABLE) return 0; @@ -11375,13 +11302,14 @@ remote_teardown_btrace (struct btrace_target_info *tinfo) /* Read the branch trace. */ -static VEC (btrace_block_s) * -remote_read_btrace (struct btrace_target_info *tinfo, +static enum btrace_error +remote_read_btrace (VEC (btrace_block_s) **btrace, + struct btrace_target_info *tinfo, enum btrace_read_type type) { struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace]; struct remote_state *rs = get_remote_state (); - VEC (btrace_block_s) *btrace = NULL; + struct cleanup *cleanup; const char *annex; char *xml; @@ -11394,12 +11322,15 @@ remote_read_btrace (struct btrace_target_info *tinfo, switch (type) { - case btrace_read_all: + case BTRACE_READ_ALL: annex = "all"; break; - case btrace_read_new: + case BTRACE_READ_NEW: annex = "new"; break; + case BTRACE_READ_DELTA: + annex = "delta"; + break; default: internal_error (__FILE__, __LINE__, _("Bad branch tracing read type: %u."), @@ -11408,15 +11339,14 @@ remote_read_btrace (struct btrace_target_info *tinfo, xml = target_read_stralloc (¤t_target, TARGET_OBJECT_BTRACE, annex); - if (xml != NULL) - { - struct cleanup *cleanup = make_cleanup (xfree, xml); + if (xml == NULL) + return BTRACE_ERR_UNKNOWN; - btrace = parse_xml_btrace (xml); - do_cleanups (cleanup); - } + cleanup = make_cleanup (xfree, xml); + *btrace = parse_xml_btrace (xml); + do_cleanups (cleanup); - return btrace; + return BTRACE_ERR_NONE; } static int @@ -11427,6 +11357,14 @@ remote_augmented_libraries_svr4_read (void) return rs->augmented_libraries_svr4_read; } +/* Implementation of to_load. */ + +static void +remote_load (struct target_ops *self, char *name, int from_tty) +{ + generic_load (name, from_tty); +} + static void init_remote_ops (void) { @@ -11460,7 +11398,7 @@ Specify the serial device it is connected to\n\ remote_ops.to_insert_watchpoint = remote_insert_watchpoint; remote_ops.to_remove_watchpoint = remote_remove_watchpoint; remote_ops.to_kill = remote_kill; - remote_ops.to_load = generic_load; + remote_ops.to_load = remote_load; remote_ops.to_mourn_inferior = remote_mourn; remote_ops.to_pass_signals = remote_pass_signals; remote_ops.to_program_signals = remote_program_signals; @@ -11577,7 +11515,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya)."; } static int -remote_can_async_p (void) +remote_can_async_p (struct target_ops *ops) { struct remote_state *rs = get_remote_state (); @@ -11590,7 +11528,7 @@ remote_can_async_p (void) } static int -remote_is_async_p (void) +remote_is_async_p (struct target_ops *ops) { struct remote_state *rs = get_remote_state (); @@ -11625,8 +11563,10 @@ remote_async_inferior_event_handler (gdb_client_data data) } static void -remote_async (void (*callback) (enum inferior_event_type event_type, - void *context), void *context) +remote_async (struct target_ops *ops, + void (*callback) (enum inferior_event_type event_type, + void *context), + void *context) { struct remote_state *rs = get_remote_state ();