This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA 4/8] New port: TI C6x: Read loadmap from gdbserver


This patch is derived from bits from CodeSourcery SH-2A toolchain

  http://sourceware.org/ml/gdb-patches/2010-12/msg00291.html

DSBT's loadmap is similar to FDPIC's, so they can be handled in a
unified approach.  This patch adds a mechanism from gdb to gdbserver to
read loadmap.  This part is not c6x-specific, and can be reused by other
similar ports.

-- 
Yao (éå)
2011-07-19  Andrew Stubbs <ams@codesourcery.com>
            Yao Qi <yao@codesourcery.com>

        gdb/
        * 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:
        * 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.
        * target.h (struct target_ops): Add read_loadmap.
---
 gdb/gdbserver/linux-low.c |   60 +++++++++++++++++++++++++++++++++++++++++++++
 gdb/gdbserver/server.c    |   19 ++++++++++++++
 gdb/gdbserver/target.h    |    4 +++
 gdb/remote.c              |   10 +++++++
 gdb/target.h              |    2 +
 5 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index d84fd68..1e9a4fb 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4964,6 +4964,61 @@ linux_core_of_thread (ptid_t ptid)
   return core;
 }
 
+#if defined __DSBT__
+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 __DSBT__
+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 = (strcmp (annex, "exec") == 0 ? (int) PTRACE_GETDSBT_EXEC :
+	      (strcmp (annex, "interp") == 0 ? (int) PTRACE_GETDSBT_INTERP :
+	       -1));
+  struct target_loadmap *data = NULL;
+  unsigned int actual_length, copy_length;
+
+  if (addr == -1)
+    return -1;
+
+  ptrace (PTRACE_GETDSBT, pid, addr, &data);
+
+  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
 static void
 linux_process_qsupported (const char *query)
 {
@@ -5112,6 +5167,11 @@ static struct target_ops linux_target_ops = {
   NULL,
 #endif
   linux_core_of_thread,
+#if defined __DSBT__
+  linux_read_loadmap,
+#else
+  NULL,
+#endif
   linux_process_qsupported,
   linux_supports_tracepoints,
   linux_read_pc,
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index fd06c8f..7991307 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -1171,6 +1171,21 @@ handle_qxfer_traceframe_info (const char *annex,
   return len;
 }
 
+/* Handle qXfer:fdpic:read.  */
+
+static int
+handle_qxfer_fdpic (const char *annex, gdb_byte *readbuf,
+		    const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
+{
+  if (the_target->read_fdpic_loadmap == NULL)
+    return -2;
+
+  if (!target_running ())
+    return -1;
+
+  return (*the_target->read_fdpic_loadmap) (annex, offset, readbuf, len);
+}
+
 static const struct qxfer qxfer_packets[] =
   {
     { "auxv", handle_qxfer_auxv },
@@ -1182,6 +1197,7 @@ static const struct qxfer qxfer_packets[] =
     { "statictrace", handle_qxfer_statictrace },
     { "threads", handle_qxfer_threads },
     { "traceframe-info", handle_qxfer_traceframe_info },
+    {"fdpic", handle_qxfer_fdpic}
   };
 
 static int
@@ -1509,6 +1525,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
       if (the_target->qxfer_siginfo != NULL)
 	strcat (own_buf, ";qXfer:siginfo:read+;qXfer:siginfo:write+");
 
+      if (the_target->read_fdpic_loadmap != NULL)
+	strcat (own_buf, ";qXfer:fdpic:read+");
+
       /* We always report qXfer:features:read, as targets may
 	 install XML files on a subsequent call to arch_setup.
 	 If we reported to GDB on startup that we don't support
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 00214db..60f4f34 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -311,6 +311,10 @@ struct target_ops
   /* Returns the core given a thread, or -1 if not known.  */
   int (*core_of_thread) (ptid_t);
 
+  /* Read FDPIC loadmaps.  Read LEN bytes at OFFSET into a buffer at MYADDR.  */
+  int (*read_fdpic_loadmap) (const char *annex, CORE_ADDR offset,
+			     unsigned char *myaddr, unsigned int len);
+
   /* Target specific qSupported support.  */
   void (*process_qsupported) (const char *);
 
diff --git a/gdb/remote.c b/gdb/remote.c
index b03ef59..9a1c653 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -1262,6 +1262,7 @@ enum {
   PACKET_bs,
   PACKET_TracepointSource,
   PACKET_QAllow,
+  PACKET_qXfer_fdpic,
   PACKET_MAX
 };
 
@@ -3769,6 +3770,8 @@ static struct protocol_feature remote_protocol_features[] = {
     PACKET_QAllow },
   { "EnableDisableTracepoints", PACKET_DISABLE,
     remote_enable_disable_tracepoint_feature, -1 },
+  { "qXfer:fdpic:read", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_fdpic },
 };
 
 static char *remote_support_xml;
@@ -8299,6 +8302,10 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
       return remote_read_qxfer
 	(ops, "traceframe-info", annex, readbuf, offset, len,
 	 &remote_protocol_packets[PACKET_qXfer_traceframe_info]);
+
+    case TARGET_OBJECT_FDPIC:
+      return remote_read_qxfer (ops, "fdpic", annex, readbuf, offset, len,
+				&remote_protocol_packets[PACKET_qXfer_fdpic]);
     default:
       return -1;
     }
@@ -10903,6 +10910,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_statictrace_read],
                          "qXfer:statictrace:read", "read-sdata-object", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_fdpic],
+			 "qXfer:fdpic:read", "read-fdpic-loadmap", 0);
+
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
      have sets to this variable in their .gdbinit files (or in their
diff --git a/gdb/target.h b/gdb/target.h
index 3b39d6f..f1bb12d 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -274,6 +274,8 @@ enum target_object
   TARGET_OBJECT_HPUX_SOLIB_GOT,
   /* Traceframe info, in XML format.  */
   TARGET_OBJECT_TRACEFRAME_INFO,
+  /* Load maps for FDPIC systems.  */
+  TARGET_OBJECT_FDPIC
   /* Possible future objects: TARGET_OBJECT_FILE, ...  */
 };
 
-- 
1.7.0.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]