static void remote_files_info (struct target_ops *ignore);
-static void remote_prepare_to_store (void);
+static void remote_prepare_to_store (struct regcache *regcache);
-static void remote_fetch_registers (int regno);
+static void remote_fetch_registers (struct regcache *regcache, int regno);
static void remote_resume (ptid_t ptid, int step,
enum target_signal siggnal);
static void remote_close (int quitting);
-static void remote_store_registers (int regno);
+static void remote_store_registers (struct regcache *regcache, int regno);
static void remote_mourn (void);
static void remote_async_mourn (void);
rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state);
- /* Assume a 1:1 regnum<->pnum table. */
+ /* Use the architecture to build a regnum<->pnum table, which will be
+ 1:1 unless a feature set specifies otherwise. */
rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, NUM_REGS, struct packet_reg);
for (regnum = 0; regnum < NUM_REGS; regnum++)
{
struct packet_reg *r = &rsa->regs[regnum];
- r->pnum = regnum;
+
+ if (register_size (current_gdbarch, regnum) == 0)
+ /* Do not try to fetch zero-sized (placeholder) registers. */
+ r->pnum = -1;
+ else
+ r->pnum = gdbarch_remote_register_number (gdbarch, regnum);
+
r->regnum = regnum;
}
PACKET_Z3,
PACKET_Z4,
PACKET_qXfer_auxv,
+ PACKET_qXfer_features,
PACKET_qXfer_memory_map,
PACKET_qGetTLSAddr,
PACKET_qSupported,
{ "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
{ "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
PACKET_qXfer_auxv },
+ { "qXfer:features:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_features },
{ "qXfer:memory-map:read", PACKET_DISABLE, remote_supported_packet,
PACKET_qXfer_memory_map },
{ "QPassSignals", PACKET_DISABLE, remote_supported_packet,
/* Tell the remote target to detach. */
strcpy (rs->buf, "D");
- remote_send (&rs->buf, &rs->buf_size);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+
+ if (rs->buf[0] == 'E')
+ error (_("Can't detach process."));
/* Unregister the file descriptor from the event loop. */
if (target_is_async_p ())
/* Fetch a single register using a 'p' packet. */
static int
-fetch_register_using_p (struct packet_reg *reg)
+fetch_register_using_p (struct regcache *regcache, struct packet_reg *reg)
{
struct remote_state *rs = get_remote_state ();
char *buf, *p;
/* If this register is unfetchable, tell the regcache. */
if (buf[0] == 'x')
{
- regcache_raw_supply (current_regcache, reg->regnum, NULL);
- set_register_cached (reg->regnum, -1);
+ regcache_raw_supply (regcache, reg->regnum, NULL);
return 1;
}
regp[i++] = fromhex (p[0]) * 16 + fromhex (p[1]);
p += 2;
}
- regcache_raw_supply (current_regcache, reg->regnum, regp);
+ regcache_raw_supply (regcache, reg->regnum, regp);
return 1;
}
}
static void
-process_g_packet (void)
+process_g_packet (struct regcache *regcache)
{
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
gdb_assert (r->offset * 2 < strlen (rs->buf));
/* The register isn't available, mark it as such (at
the same time setting the value to zero). */
- regcache_raw_supply (current_regcache, r->regnum, NULL);
- set_register_cached (i, -1);
+ regcache_raw_supply (regcache, r->regnum, NULL);
}
else
- regcache_raw_supply (current_regcache, r->regnum,
+ regcache_raw_supply (regcache, r->regnum,
regs + r->offset);
}
}
}
static void
-fetch_registers_using_g (void)
+fetch_registers_using_g (struct regcache *regcache)
{
send_g_packet ();
- process_g_packet ();
+ process_g_packet (regcache);
}
static void
-remote_fetch_registers (int regnum)
+remote_fetch_registers (struct regcache *regcache, int regnum)
{
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
contents, so fall back to 'p'. */
if (reg->in_g_packet)
{
- fetch_registers_using_g ();
+ fetch_registers_using_g (regcache);
if (reg->in_g_packet)
return;
}
- if (fetch_register_using_p (reg))
+ if (fetch_register_using_p (regcache, reg))
return;
/* This register is not available. */
- regcache_raw_supply (current_regcache, reg->regnum, NULL);
- set_register_cached (reg->regnum, -1);
+ regcache_raw_supply (regcache, reg->regnum, NULL);
return;
}
- fetch_registers_using_g ();
+ fetch_registers_using_g (regcache);
for (i = 0; i < NUM_REGS; i++)
if (!rsa->regs[i].in_g_packet)
- if (!fetch_register_using_p (&rsa->regs[i]))
+ if (!fetch_register_using_p (regcache, &rsa->regs[i]))
{
/* This register is not available. */
- regcache_raw_supply (current_regcache, i, NULL);
- set_register_cached (i, -1);
+ regcache_raw_supply (regcache, i, NULL);
}
}
first. */
static void
-remote_prepare_to_store (void)
+remote_prepare_to_store (struct regcache *regcache)
{
struct remote_arch_state *rsa = get_remote_arch_state ();
int i;
/* Make sure all the necessary registers are cached. */
for (i = 0; i < NUM_REGS; i++)
if (rsa->regs[i].in_g_packet)
- regcache_raw_read (current_regcache, rsa->regs[i].regnum, buf);
+ regcache_raw_read (regcache, rsa->regs[i].regnum, buf);
break;
case PACKET_ENABLE:
break;
packet was not recognized. */
static int
-store_register_using_P (struct packet_reg *reg)
+store_register_using_P (const struct regcache *regcache, struct packet_reg *reg)
{
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
xsnprintf (buf, get_remote_packet_size (), "P%s=", phex_nz (reg->pnum, 0));
p = buf + strlen (buf);
- regcache_raw_collect (current_regcache, reg->regnum, regp);
+ regcache_raw_collect (regcache, reg->regnum, regp);
bin2hex (regp, p, register_size (current_gdbarch, reg->regnum));
remote_send (&rs->buf, &rs->buf_size);
contents of the register cache buffer. FIXME: ignores errors. */
static void
-store_registers_using_G (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 ();
{
struct packet_reg *r = &rsa->regs[i];
if (r->in_g_packet)
- regcache_raw_collect (current_regcache, r->regnum, regs + r->offset);
+ regcache_raw_collect (regcache, r->regnum, regs + r->offset);
}
}
of the register cache buffer. FIXME: ignores errors. */
static void
-remote_store_registers (int regnum)
+remote_store_registers (struct regcache *regcache, int regnum)
{
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
possible; we often change only a small number of registers.
Sometimes we change a larger number; we'd need help from a
higher layer to know to use 'G'. */
- if (store_register_using_P (reg))
+ if (store_register_using_P (regcache, reg))
return;
/* For now, don't complain if we have no way to write the
if (!reg->in_g_packet)
return;
- store_registers_using_G ();
+ store_registers_using_G (regcache);
return;
}
- store_registers_using_G ();
+ store_registers_using_G (regcache);
for (i = 0; i < NUM_REGS; i++)
if (!rsa->regs[i].in_g_packet)
- if (!store_register_using_P (&rsa->regs[i]))
+ if (!store_register_using_P (regcache, &rsa->regs[i]))
/* See above for why we do not issue an error here. */
continue;
}
internal_error (__FILE__, __LINE__,
"remote_write_bytes_aux: bad packet format");
- /* Should this be the selected frame? */
- gdbarch_remote_translate_xfer_address (current_gdbarch,
- current_regcache,
- memaddr, len,
- &memaddr, &len);
-
if (len <= 0)
return 0;
int max_buf_size; /* Max size of packet output buffer. */
int origlen;
- /* Should this be the selected frame? */
- gdbarch_remote_translate_xfer_address (current_gdbarch,
- current_regcache,
- memaddr, len,
- &memaddr, &len);
-
if (len <= 0)
return 0;
}
\f
-/* On some machines, e.g. 68k, we may use a different breakpoint
- instruction than other targets; in those use
- DEPRECATED_REMOTE_BREAKPOINT instead of just BREAKPOINT_FROM_PC.
- Also, bi-endian targets may define
- DEPRECATED_LITTLE_REMOTE_BREAKPOINT and
- DEPRECATED_BIG_REMOTE_BREAKPOINT. If none of these are defined, we
- just call the standard routines that are in mem-break.c. */
-
-/* NOTE: cagney/2003-06-08: This is silly. A remote and simulator
- target should use an identical BREAKPOINT_FROM_PC. As for native,
- the ARCH-OS-tdep.c code can override the default. */
-
-#if defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && defined (DEPRECATED_BIG_REMOTE_BREAKPOINT) && !defined(DEPRECATED_REMOTE_BREAKPOINT)
-#define DEPRECATED_REMOTE_BREAKPOINT
-#endif
-
-#ifdef DEPRECATED_REMOTE_BREAKPOINT
-
-/* If the target isn't bi-endian, just pretend it is. */
-#if !defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && !defined (DEPRECATED_BIG_REMOTE_BREAKPOINT)
-#define DEPRECATED_LITTLE_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT
-#define DEPRECATED_BIG_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT
-#endif
-
-static unsigned char big_break_insn[] = DEPRECATED_BIG_REMOTE_BREAKPOINT;
-static unsigned char little_break_insn[] = DEPRECATED_LITTLE_REMOTE_BREAKPOINT;
-
-#endif /* DEPRECATED_REMOTE_BREAKPOINT */
-
/* Insert a breakpoint. On targets that have software breakpoint
support, we ask the remote target to do the work; on targets
which don't, we insert a traditional memory breakpoint. */
{
CORE_ADDR addr = bp_tgt->placed_address;
struct remote_state *rs = get_remote_state ();
-#ifdef DEPRECATED_REMOTE_BREAKPOINT
- int val;
-#endif
/* Try the "Z" s/w breakpoint packet if it is not already disabled.
If it succeeds, then set the support to PACKET_ENABLE. If it
}
}
-#ifdef DEPRECATED_REMOTE_BREAKPOINT
- bp_tgt->placed_size = bp_tgt->shadow_len = sizeof big_break_insn;
- val = target_read_memory (addr, bp_tgt->shadow_contents, bp_tgt->shadow_len);
-
- if (val == 0)
- {
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- val = target_write_memory (addr, (char *) big_break_insn,
- sizeof big_break_insn);
- else
- val = target_write_memory (addr, (char *) little_break_insn,
- sizeof little_break_insn);
- }
-
- return val;
-#else
return memory_insert_breakpoint (bp_tgt);
-#endif /* DEPRECATED_REMOTE_BREAKPOINT */
}
static int
return (rs->buf[0] == 'E');
}
-#ifdef DEPRECATED_REMOTE_BREAKPOINT
- return target_write_memory (bp_tgt->placed_address, bp_tgt->shadow_contents,
- bp_tgt->shadow_len);
-#else
return memory_remove_breakpoint (bp_tgt);
-#endif /* DEPRECATED_REMOTE_BREAKPOINT */
}
static int
return remote_read_qxfer (ops, "auxv", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_auxv]);
+ case TARGET_OBJECT_AVAILABLE_FEATURES:
+ return remote_read_qxfer
+ (ops, "features", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_features]);
+
case TARGET_OBJECT_MEMORY_MAP:
gdb_assert (annex == NULL);
return remote_read_qxfer (ops, "memory-map", annex, readbuf, offset, len,
remote_address_size = TARGET_ADDR_BIT;
}
-/* Saved pointer to previous owner of the new_objfile event. */
-static void (*remote_new_objfile_chain) (struct objfile *);
-
/* Function to be called whenever a new objfile (shlib) is detected. */
static void
remote_new_objfile (struct objfile *objfile)
{
if (remote_desc != 0) /* Have a remote connection. */
- {
- remote_check_symbols (objfile);
- }
- /* Call predecessor on chain, if any. */
- if (remote_new_objfile_chain)
- remote_new_objfile_chain (objfile);
+ remote_check_symbols (objfile);
}
void
add_target (&extended_async_remote_ops);
/* Hook into new objfile notification. */
- remote_new_objfile_chain = deprecated_target_new_objfile_hook;
- deprecated_target_new_objfile_hook = remote_new_objfile;
+ observer_attach_new_objfile (remote_new_objfile);
#if 0
init_remote_threadtests ();
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_auxv],
"qXfer:auxv:read", "read-aux-vector", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_features],
+ "qXfer:features:read", "target-features", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_memory_map],
"qXfer:memory-map:read", "memory-map", 0);