]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/gdbserver/linux-low.c
gdb/
[thirdparty/binutils-gdb.git] / gdb / gdbserver / linux-low.c
index a9cdacac51a47edaed8a547dfce077e20d05db66..999ca92c8fa902e1feaf162891bfd20a6fed897e 100644 (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,