This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* See the GDB User Guide for details of the GDB remote protocol. */
static void async_remote_interrupt (gdb_client_data);
void async_remote_interrupt_twice (gdb_client_data);
-static void build_remote_gdbarch_data (void);
-
static void remote_files_info (struct target_ops *ignore);
static void remote_prepare_to_store (struct regcache *regcache);
/* 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,
- gdbarch_num_regs (current_gdbarch),
+ gdbarch_num_regs (gdbarch),
struct packet_reg);
- for (regnum = 0; regnum < gdbarch_num_regs (current_gdbarch); regnum++)
+ for (regnum = 0; regnum < gdbarch_num_regs (gdbarch); regnum++)
{
struct packet_reg *r = &rsa->regs[regnum];
- if (register_size (current_gdbarch, regnum) == 0)
+ if (register_size (gdbarch, regnum) == 0)
/* Do not try to fetch zero-sized (placeholder) registers. */
r->pnum = -1;
else
with a remote protocol number, in order of ascending protocol
number. */
- remote_regs = alloca (gdbarch_num_regs (current_gdbarch)
- * sizeof (struct packet_reg *));
+ remote_regs = alloca (gdbarch_num_regs (gdbarch)
+ * sizeof (struct packet_reg *));
for (num_remote_regs = 0, regnum = 0;
- regnum < gdbarch_num_regs (current_gdbarch);
+ regnum < gdbarch_num_regs (gdbarch);
regnum++)
if (rsa->regs[regnum].pnum != -1)
remote_regs[num_remote_regs++] = &rsa->regs[regnum];
{
remote_regs[regnum]->in_g_packet = 1;
remote_regs[regnum]->offset = offset;
- offset += register_size (current_gdbarch, remote_regs[regnum]->regnum);
+ offset += register_size (gdbarch, remote_regs[regnum]->regnum);
}
/* Record the maximum possible size of the g packet - it may turn out
PACKET_Z4,
PACKET_qXfer_auxv,
PACKET_qXfer_features,
+ PACKET_qXfer_libraries,
PACKET_qXfer_memory_map,
PACKET_qXfer_spu_read,
PACKET_qXfer_spu_write,
struct remote_state *rs = get_remote_state ();
char *buf;
char *ptr;
- int lose;
- CORE_ADDR text_addr, data_addr, bss_addr;
+ int lose, num_segments = 0, do_sections, do_segments;
+ CORE_ADDR text_addr, data_addr, bss_addr, segments[2];
struct section_offsets *offs;
+ struct symfile_segment_data *data;
+
+ if (symfile_objfile == NULL)
+ return;
putpkt ("qOffsets");
getpkt (&rs->buf, &rs->buf_size, 0);
/* Don't use strtol, could lose on big values. */
while (*ptr && *ptr != ';')
text_addr = (text_addr << 4) + fromhex (*ptr++);
- }
- else
- lose = 1;
- if (!lose && strncmp (ptr, ";Data=", 6) == 0)
- {
- ptr += 6;
- while (*ptr && *ptr != ';')
- data_addr = (data_addr << 4) + fromhex (*ptr++);
- }
- else
- lose = 1;
+ if (strncmp (ptr, ";Data=", 6) == 0)
+ {
+ ptr += 6;
+ while (*ptr && *ptr != ';')
+ data_addr = (data_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
- if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+ if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+ {
+ ptr += 5;
+ while (*ptr && *ptr != ';')
+ bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+
+ if (bss_addr != data_addr)
+ warning (_("Target reported unsupported offsets: %s"), buf);
+ }
+ else
+ lose = 1;
+ }
+ else if (strncmp (ptr, "TextSeg=", 8) == 0)
{
- ptr += 5;
+ ptr += 8;
+ /* Don't use strtol, could lose on big values. */
while (*ptr && *ptr != ';')
- bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+ text_addr = (text_addr << 4) + fromhex (*ptr++);
+ num_segments = 1;
+
+ if (strncmp (ptr, ";DataSeg=", 9) == 0)
+ {
+ ptr += 9;
+ while (*ptr && *ptr != ';')
+ data_addr = (data_addr << 4) + fromhex (*ptr++);
+ num_segments++;
+ }
}
else
lose = 1;
if (lose)
error (_("Malformed response to offset query, %s"), buf);
-
- if (symfile_objfile == NULL)
- return;
+ else if (*ptr != '\0')
+ warning (_("Target reported unsupported offsets: %s"), buf);
offs = ((struct section_offsets *)
alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections)));
memcpy (offs, symfile_objfile->section_offsets,
SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections));
- offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
+ data = get_symfile_segment_data (symfile_objfile->obfd);
+ do_segments = (data != NULL);
+ do_sections = num_segments == 0;
+
+ if (num_segments > 0)
+ {
+ segments[0] = text_addr;
+ segments[1] = data_addr;
+ }
+ /* If we have two segments, we can still try to relocate everything
+ by assuming that the .text and .data offsets apply to the whole
+ text and data segments. Convert the offsets given in the packet
+ to base addresses for symfile_map_offsets_to_segments. */
+ else if (data && data->num_segments == 2)
+ {
+ segments[0] = data->segment_bases[0] + text_addr;
+ segments[1] = data->segment_bases[1] + data_addr;
+ num_segments = 2;
+ }
+ /* There's no way to relocate by segment. */
+ else
+ do_segments = 0;
- /* This is a temporary kludge to force data and bss to use the same offsets
- because that's what nlmconv does now. The real solution requires changes
- to the stub and remote.c that I don't have time to do right now. */
+ if (do_segments)
+ {
+ int ret = symfile_map_offsets_to_segments (symfile_objfile->obfd, data,
+ offs, num_segments, segments);
+
+ if (ret == 0 && !do_sections)
+ error (_("Can not handle qOffsets TextSeg response with this symbol file"));
- offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr;
- offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr;
+ if (ret > 0)
+ do_sections = 0;
+ }
+
+ if (data)
+ free_symfile_segment_data (data);
+
+ if (do_sections)
+ {
+ offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
+
+ /* This is a temporary kludge to force data and bss to use the same offsets
+ because that's what nlmconv does now. The real solution requires changes
+ to the stub and remote.c that I don't have time to do right now. */
+
+ offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr;
+ offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr;
+ }
objfile_relocate (symfile_objfile, offs);
}
if (sym == NULL)
xsnprintf (msg, get_remote_packet_size (), "qSymbol::%s", &reply[8]);
else
- xsnprintf (msg, get_remote_packet_size (), "qSymbol:%s:%s",
- paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
- &reply[8]);
+ {
+ CORE_ADDR sym_addr = SYMBOL_VALUE_ADDRESS (sym);
+
+ /* If this is a function address, return the start of code
+ instead of any data function descriptor. */
+ sym_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+ sym_addr,
+ ¤t_target);
+
+ xsnprintf (msg, get_remote_packet_size (), "qSymbol:%s:%s",
+ paddr_nz (sym_addr), &reply[8]);
+ }
+
putpkt (msg);
getpkt (&rs->buf, &rs->buf_size, 0);
reply = rs->buf;
PACKET_qXfer_auxv },
{ "qXfer:features:read", PACKET_DISABLE, remote_supported_packet,
PACKET_qXfer_features },
+ { "qXfer:libraries:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_libraries },
{ "qXfer:memory-map:read", PACKET_DISABLE, remote_supported_packet,
PACKET_qXfer_memory_map },
{ "qXfer:spu:read", PACKET_DISABLE, remote_supported_packet,
struct remote_arch_state *rsa = get_remote_arch_state ();
ULONGEST thread_num = -1;
ULONGEST addr;
+ int solibs_changed = 0;
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
p = unpack_varlen_hex (++p1, &addr);
remote_watch_data_address = (CORE_ADDR)addr;
}
+ else if (strncmp (p, "library", p1 - p) == 0)
+ {
+ p1++;
+ p_temp = p1;
+ while (*p_temp && *p_temp != ';')
+ p_temp++;
+
+ solibs_changed = 1;
+ p = p_temp;
+ }
else
{
/* Silently skip unknown optional info. */
}
/* fall through */
case 'S': /* Old style status, just signal only. */
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = (enum target_signal)
- (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+ if (solibs_changed)
+ status->kind = TARGET_WAITKIND_LOADED;
+ else
+ {
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+ }
if (buf[3] == 'p')
{
struct remote_arch_state *rsa = get_remote_arch_state ();
ULONGEST thread_num = -1;
ULONGEST addr;
+ int solibs_changed = 0;
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
/* If this packet is an awatch packet, don't parse the 'a'
as a register number. */
- if (!strncmp (p, "awatch", strlen ("awatch")) != 0)
+ if (strncmp (p, "awatch", strlen("awatch")) != 0)
{
/* Read the register number. */
pnum = strtol (p, &p_temp, 16);
p = unpack_varlen_hex (++p1, &addr);
remote_watch_data_address = (CORE_ADDR)addr;
}
+ else if (strncmp (p, "library", p1 - p) == 0)
+ {
+ p1++;
+ p_temp = p1;
+ while (*p_temp && *p_temp != ';')
+ p_temp++;
+
+ solibs_changed = 1;
+ p = p_temp;
+ }
else
{
/* Silently skip unknown optional info. */
}
/* fall through */
case 'S': /* Old style status, just signal only. */
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = (enum target_signal)
- (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+ if (solibs_changed)
+ status->kind = TARGET_WAITKIND_LOADED;
+ else
+ {
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+ }
if (buf[3] == 'p')
{
return 0;
case PACKET_ERROR:
error (_("Could not fetch register \"%s\""),
- gdbarch_register_name (current_gdbarch, reg->regnum));
+ gdbarch_register_name (get_regcache_arch (regcache), reg->regnum));
}
/* If this register is unfetchable, tell the regcache. */
static void
process_g_packet (struct regcache *regcache)
{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
int i, buf_len;
{
rsa->sizeof_g_packet = buf_len / 2;
- for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+ for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
{
if (rsa->regs[i].pnum == -1)
continue;
{
int i;
- for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+ for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
{
struct packet_reg *r = &rsa->regs[i];
if (r->in_g_packet)
fetch_registers_using_g (regcache);
- for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+ for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
if (!rsa->regs[i].in_g_packet)
if (!fetch_register_using_p (regcache, &rsa->regs[i]))
{
case PACKET_DISABLE:
case PACKET_SUPPORT_UNKNOWN:
/* Make sure all the necessary registers are cached. */
- for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+ for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
if (rsa->regs[i].in_g_packet)
regcache_raw_read (regcache, rsa->regs[i].regnum, buf);
break;
static int
store_register_using_P (const struct regcache *regcache, struct packet_reg *reg)
{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
/* Try storing a single register. */
xsnprintf (buf, get_remote_packet_size (), "P%s=", phex_nz (reg->pnum, 0));
p = buf + strlen (buf);
regcache_raw_collect (regcache, reg->regnum, regp);
- bin2hex (regp, p, register_size (current_gdbarch, reg->regnum));
+ bin2hex (regp, p, register_size (gdbarch, reg->regnum));
remote_send (&rs->buf, &rs->buf_size);
switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_P]))
return 1;
case PACKET_ERROR:
error (_("Could not write register \"%s\""),
- gdbarch_register_name (current_gdbarch, reg->regnum));
+ gdbarch_register_name (gdbarch, reg->regnum));
case PACKET_UNKNOWN:
return 0;
default:
int i;
regs = alloca (rsa->sizeof_g_packet);
memset (regs, 0, rsa->sizeof_g_packet);
- for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+ for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
{
struct packet_reg *r = &rsa->regs[i];
if (r->in_g_packet)
store_registers_using_G (regcache);
- for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+ for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); 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. */
static CORE_ADDR
remote_address_masked (CORE_ADDR addr)
{
- if (remote_address_size > 0
- && remote_address_size < (sizeof (ULONGEST) * 8))
+ int address_size = remote_address_size;
+ /* If "remoteaddresssize" was not set, default to target address size. */
+ if (!address_size)
+ address_size = gdbarch_addr_bit (current_gdbarch);
+
+ if (address_size > 0
+ && address_size < (sizeof (ULONGEST) * 8))
{
/* Only create a mask when that mask can safely be constructed
in a ULONGEST variable. */
ULONGEST mask = 1;
- mask = (mask << remote_address_size) - 1;
+ mask = (mask << address_size) - 1;
addr &= mask;
}
return addr;
{
QUIT;
target_mourn_inferior ();
- error (_("Watchdog has expired. Target detached."));
+ error (_("Watchdog timeout has expired. Target detached."));
}
if (remote_debug)
fputs_filtered ("Timed out.\n", gdb_stdlog);
return remote_stopped_by_watchpoint_p;
}
-extern int stepped_after_stopped_by_watchpoint;
-
static int
remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
{
int rc = 0;
- if (remote_stopped_by_watchpoint ()
- || stepped_after_stopped_by_watchpoint)
+ if (remote_stopped_by_watchpoint ())
{
*addr_p = remote_watch_data_address;
rc = 1;
(ops, "features", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_features]);
+ case TARGET_OBJECT_LIBRARIES:
+ return remote_read_qxfer
+ (ops, "libraries", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_libraries]);
+
case TARGET_OBJECT_MEMORY_MAP:
gdb_assert (annex == NULL);
return remote_read_qxfer (ops, "memory-map", annex, readbuf, offset, len,
remote_async_ops.to_memory_map = remote_memory_map;
remote_async_ops.to_flash_erase = remote_flash_erase;
remote_async_ops.to_flash_done = remote_flash_done;
- remote_ops.to_read_description = remote_read_description;
+ remote_async_ops.to_read_description = remote_read_description;
}
/* Set up the async extended remote vector by making a copy of the standard
do_cleanups (showlist_chain);
}
-static void
-build_remote_gdbarch_data (void)
-{
- remote_address_size = gdbarch_addr_bit (current_gdbarch);
-}
/* Function to be called whenever a new objfile (shlib) is detected. */
static void
remote_g_packet_data_handle =
gdbarch_data_register_pre_init (remote_g_packet_data_init);
- /* Old tacky stuff. NOTE: This comes after the remote protocol so
- that the remote protocol has been initialized. */
- DEPRECATED_REGISTER_GDBARCH_SWAP (remote_address_size);
- deprecated_register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data);
-
/* Initialize the per-target state. At the moment there is only one
of these, not one per target. Only one target is active at a
time. The default buffer size is unimportant; it will be expanded
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_libraries],
+ "qXfer:libraries:read", "library-info", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_memory_map],
"qXfer:memory-map:read", "memory-map", 0);