/* Remote target communications for serial-line targets in custom GDB protocol
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This file is part of GDB.
#include "regcache.h"
#include "value.h"
#include "gdb_assert.h"
+#include "observer.h"
#include <ctype.h>
#include <sys/time.h>
#ifndef MAX_REMOTE_PACKET_SIZE
#define MAX_REMOTE_PACKET_SIZE 16384
#endif
- /* NOTE: 16 is just chosen at random. */
+ /* NOTE: 20 ensures we can write at least one byte. */
#ifndef MIN_REMOTE_PACKET_SIZE
-#define MIN_REMOTE_PACKET_SIZE 16
+#define MIN_REMOTE_PACKET_SIZE 20
#endif
long what_they_get;
if (config->fixed_p)
struct cmd_list_element **show_remote_list,
int legacy)
{
- struct cmd_list_element *set_cmd;
- struct cmd_list_element *show_cmd;
char *set_doc;
char *show_doc;
- char *help_doc;
- char *print;
char *cmd_name;
+
config->name = name;
config->title = title;
config->detect = AUTO_BOOLEAN_AUTO;
name, title);
show_doc = xstrprintf ("Show current use of remote protocol `%s' (%s) packet",
name, title);
- print = xstrprintf ("Current use of remote protocol `%s' (%s) is %%s",
- name, title);
/* set/show TITLE-packet {auto,on,off} */
cmd_name = xstrprintf ("%s-packet", title);
add_setshow_auto_boolean_cmd (cmd_name, class_obscure,
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_vcont);
}
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_qSymbol);
}
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_P);
}
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP]);
}
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_HARDWARE_BP]);
}
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_WRITE_WP]);
}
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_READ_WP]);
}
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP]);
}
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_binary_download);
}
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_qPart_auxv);
}
+/* Should we try the 'qGetTLSAddr' (Get Thread Local Storage Address) request? */
+static struct packet_config remote_protocol_qGetTLSAddr;
+
+static void
+set_remote_protocol_qGetTLSAddr_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_qGetTLSAddr);
+}
+
+static void
+show_remote_protocol_qGetTLSAddr_packet_cmd (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ show_packet_config_cmd (&remote_protocol_qGetTLSAddr);
+}
+
static struct packet_config remote_protocol_p;
static void
struct cmd_list_element *c,
const char *value)
{
- deprecated_show_value_hack (file, from_tty, c, value);
show_packet_config_cmd (&remote_protocol_p);
}
downloading. */
update_packet_config (&remote_protocol_binary_download);
update_packet_config (&remote_protocol_qPart_auxv);
+ update_packet_config (&remote_protocol_qGetTLSAddr);
}
/* Symbol look-up. */
remote_open_1 (char *name, int from_tty, struct target_ops *target,
int extended_p, int async_p)
{
- struct exception ex;
+ struct gdb_exception ex;
struct remote_state *rs = get_remote_state ();
if (name == 0)
error (_("To open a remote debug connection, you need to specify what\n"
remote_check_symbols (symfile_objfile);
}
#endif
+
+ observer_notify_inferior_created (¤t_target, from_tty);
}
/* This takes a program previously attached to and detaches it. After
static void
remote_disconnect (char *args, int from_tty)
{
- struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
-
if (args)
error (_("Argument given to \"detach\" when remotely debugging."));
struct remote_state *rs = get_remote_state ();
char *buf = alloca (rs->remote_packet_size);
int pid = PIDGET (ptid);
- char *p;
last_sent_signal = siggnal;
last_sent_step = step;
continue;
case 'T': /* Status with PC, SP, FP, ... */
{
- int i;
char regs[MAX_REGISTER_SIZE];
/* Expedited reply, containing Signal, {regno, reg} repeat. */
continue;
case 'T': /* Status with PC, SP, FP, ... */
{
- int i;
char regs[MAX_REGISTER_SIZE];
/* Expedited reply, containing Signal, {regno, reg} repeat. */
in the buffer is not a hex character, assume that has happened
and try to fetch another packet to read. */
while ((buf[0] < '0' || buf[0] > '9')
+ && (buf[0] < 'A' || buf[0] > 'F')
&& (buf[0] < 'a' || buf[0] > 'f')
&& buf[0] != 'x') /* New: unavailable register value. */
{
char *buf = alloca (rs->remote_packet_size);
char regp[MAX_REGISTER_SIZE];
char *p;
- int i;
sprintf (buf, "P%s=", phex_nz (reg->pnum, 0));
p = buf + strlen (buf);
struct remote_state *rs = get_remote_state ();
char *buf;
char *regs;
- int i;
char *p;
set_thread (PIDGET (inferior_ptid), 1);
{
int i;
regs = alloca (rs->sizeof_g_packet);
- memset (regs, rs->sizeof_g_packet, 0);
+ memset (regs, 0, rs->sizeof_g_packet);
for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
{
struct packet_reg *r = &rs->regs[i];
/* Verify that the target can support a binary download. */
check_binary_download (memaddr);
+ payload_size = get_memory_write_packet_size ();
+
/* Compute the size, and then allocate space for the largest
- possible packet. Include space for an extra trailing NULL. */
- sizeof_buf = get_memory_write_packet_size () + 1;
+ possible packet. Include space for an extra trailing NUL. */
+ sizeof_buf = payload_size + 1;
buf = alloca (sizeof_buf);
/* Compute the size of the actual payload by subtracting out the
- packet header and footer overhead: "$M<memaddr>,<len>:...#nn". */
- payload_size = (get_memory_write_packet_size () - (strlen ("$M,:#NN")
- + hexnumlen (memaddr)
- + hexnumlen (len)));
+ packet header and footer overhead: "$M<memaddr>,<len>:...#nn".
+ */
+ payload_size -= strlen ("$M,:#NN");
+ payload_size -= hexnumlen (memaddr);
/* Construct the packet header: "[MX]<memaddr>,<len>:". */
*p++ = 'X';
/* Best guess at number of bytes that will fit. */
todo = min (len, payload_size);
+ payload_size -= hexnumlen (todo);
+ todo = min (todo, payload_size);
break;
case PACKET_DISABLE:
*p++ = 'M';
/* Num bytes that will fit. */
todo = min (len, payload_size / 2);
+ payload_size -= hexnumlen (todo);
+ todo = min (todo, payload_size / 2);
break;
case PACKET_SUPPORT_UNKNOWN:
internal_error (__FILE__, __LINE__,
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
}
+ if (todo <= 0)
+ internal_error (__FILE__, __LINE__,
+ _("minumum packet size too small to write data"));
/* Append "<memaddr>". */
memaddr = remote_address_masked (memaddr);
struct ui_file *outbuf)
{
struct remote_state *rs = get_remote_state ();
- int i;
char *buf = alloca (rs->remote_packet_size);
char *p = buf;
static char *
remote_pid_to_str (ptid_t ptid)
{
- static char buf[30];
+ static char buf[32];
+ int size;
- sprintf (buf, "Thread %d", PIDGET (ptid));
+ size = snprintf (buf, sizeof buf, "thread %d", ptid_get_pid (ptid));
+ gdb_assert (size < sizeof buf);
return buf;
}
+/* Get the address of the thread local variable in OBJFILE which is
+ stored at OFFSET within the thread local storage for thread PTID. */
+
+static CORE_ADDR
+remote_get_thread_local_address (ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
+{
+ if (remote_protocol_qGetTLSAddr.support != PACKET_DISABLE)
+ {
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ char *p = buf;
+ enum packet_result result;
+
+ strcpy (p, "qGetTLSAddr:");
+ p += strlen (p);
+ p += hexnumstr (p, PIDGET (ptid));
+ *p++ = ',';
+ p += hexnumstr (p, offset);
+ *p++ = ',';
+ p += hexnumstr (p, lm);
+ *p++ = '\0';
+
+ putpkt (buf);
+ getpkt (buf, rs->remote_packet_size, 0);
+ result = packet_ok (buf, &remote_protocol_qGetTLSAddr);
+ if (result == PACKET_OK)
+ {
+ ULONGEST result;
+
+ unpack_varlen_hex (buf, &result);
+ return result;
+ }
+ else if (result == PACKET_UNKNOWN)
+ {
+ struct gdb_exception e
+ = { RETURN_ERROR, TLS_GENERIC_ERROR,
+ "Remote target doesn't support qGetTLSAddr packet" };
+ throw_exception (e);
+ }
+ else
+ {
+ struct gdb_exception e
+ = { RETURN_ERROR, TLS_GENERIC_ERROR,
+ "Remote target failed to process qGetTLSAddr request" };
+ throw_exception (e);
+
+ }
+ }
+ else
+ {
+ struct gdb_exception e
+ = { RETURN_ERROR, TLS_GENERIC_ERROR,
+ "TLS not supported or disabled on this target" };
+ throw_exception (e);
+ }
+ /* Not reached. */
+ return 0;
+}
+
static void
init_remote_ops (void)
{
remote_ops.to_stop = remote_stop;
remote_ops.to_xfer_partial = remote_xfer_partial;
remote_ops.to_rcmd = remote_rcmd;
+ remote_ops.to_get_thread_local_address = remote_get_thread_local_address;
remote_ops.to_stratum = process_stratum;
remote_ops.to_has_all_memory = 1;
remote_ops.to_has_memory = 1;
show_remote_protocol_vcont_packet_cmd (gdb_stdout, from_tty, NULL, NULL);
show_remote_protocol_binary_download_cmd (gdb_stdout, from_tty, NULL, NULL);
show_remote_protocol_qPart_auxv_packet_cmd (gdb_stdout, from_tty, NULL, NULL);
+ show_remote_protocol_qGetTLSAddr_packet_cmd (gdb_stdout, from_tty, NULL, NULL);
}
static void
{
static struct cmd_list_element *remote_set_cmdlist;
static struct cmd_list_element *remote_show_cmdlist;
- struct cmd_list_element *tmpcmd;
/* architecture specific data */
remote_gdbarch_data_handle =
NULL, NULL, /* FIXME: i18n: The maximum number of target hardware breakpoints is %s. */
&remote_set_cmdlist, &remote_show_cmdlist);
- deprecated_add_show_from_set
- (add_set_cmd ("remoteaddresssize", class_obscure,
- var_integer, (char *) &remote_address_size,
- "Set the maximum size of the address (in bits) \
-in a memory packet.\n",
- &setlist),
- &showlist);
+ add_setshow_integer_cmd ("remoteaddresssize", class_obscure,
+ &remote_address_size, _("\
+Set the maximum size of the address (in bits) in a memory packet."), _("\
+Show the maximum size of the address (in bits) in a memory packet."), NULL,
+ NULL,
+ NULL, /* FIXME: i18n: */
+ &setlist, &showlist);
add_packet_config_cmd (&remote_protocol_binary_download,
"X", "binary-download",
&remote_set_cmdlist, &remote_show_cmdlist,
0);
+ add_packet_config_cmd (&remote_protocol_qGetTLSAddr,
+ "qGetTLSAddr", "get-thread-local-storage-address",
+ set_remote_protocol_qGetTLSAddr_packet_cmd,
+ show_remote_protocol_qGetTLSAddr_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
/* Keep the old ``set remote Z-packet ...'' working. */
add_setshow_auto_boolean_cmd ("Z-packet", class_obscure,
&remote_Z_packet_detect, _("\