* remote.c (PACKET_qXfer_fdpic): New enum value.
        (remote_protocol_features): Add qXfer:fdpic:read packet.
        (remote_xfer_partial): Support TARGET_OBJECT_FDPIC.
        (_initialize_remote): Add set/show remote read-fdpic-loadmap command.
        * target.h (enum target_object): Add TARGET_OBJECT_FDPIC.

        gdb/gdbserver:
        * target.h (struct target_ops): Add read_loadmap.
        * linux-low.c (struct target_loadseg): New type.
        (struct target_loadmap): New type.
        (linux_read_loadmap): New function.
        (linux_target_ops): Add linux_read_loadmap.
        * server.c (handle_query): Support qXfer:fdpic:read packet.
	* win32-low.c (win32_target_ops): Initialize field `read_loadmap' to NULL.

        gdb/doc/
        * gdb.texinfo : Document qXfer:fdpic:read packet.
This commit is contained in:
Yao Qi
2011-08-14 13:03:13 +00:00
parent d3e3fa9393
commit 78d8519916
10 changed files with 143 additions and 1 deletions

View File

@@ -4654,6 +4654,66 @@ linux_qxfer_spu (const char *annex, unsigned char *readbuf,
return ret;
}
#if defined PT_GETDSBT
struct target_loadseg
{
/* Core address to which the segment is mapped. */
Elf32_Addr addr;
/* VMA recorded in the program header. */
Elf32_Addr p_vaddr;
/* Size of this segment in memory. */
Elf32_Word p_memsz;
};
struct target_loadmap
{
/* Protocol version number, must be zero. */
Elf32_Word version;
/* Pointer to the DSBT table, its size, and the DSBT index. */
unsigned *dsbt_table;
unsigned dsbt_size, dsbt_index;
/* Number of segments in this map. */
Elf32_Word nsegs;
/* The actual memory map. */
struct target_loadseg segs[/*nsegs*/];
};
#endif
#if defined PT_GETDSBT
static int
linux_read_loadmap (const char *annex, CORE_ADDR offset,
unsigned char *myaddr, unsigned int len)
{
int pid = lwpid_of (get_thread_lwp (current_inferior));
int addr = -1;
struct target_loadmap *data = NULL;
unsigned int actual_length, copy_length;
if (strcmp (annex, "exec") == 0)
addr= (int) PTRACE_GETDSBT_EXEC;
else if (strcmp (annex, "interp") == 0)
addr = (int) PTRACE_GETDSBT_INTERP;
else
return -1;
if (ptrace (PT_GETDSBT, pid, addr, &data) != 0)
return -1;
if (data == NULL)
return -1;
actual_length = sizeof (struct target_loadmap)
+ sizeof (struct target_loadseg) * data->nsegs;
if (offset < 0 || offset > actual_length)
return -1;
copy_length = actual_length - offset < len ? actual_length - offset : len;
memcpy (myaddr, (char *) data + offset, copy_length);
return copy_length;
}
#endif /* defined PT_GETDSBT */
static void
linux_process_qsupported (const char *query)
{
@@ -4802,6 +4862,11 @@ static struct target_ops linux_target_ops = {
NULL,
#endif
linux_common_core_of_thread,
#if defined PT_GETDSBT
linux_read_loadmap,
#else
NULL,
#endif
linux_process_qsupported,
linux_supports_tracepoints,
linux_read_pc,