* configure.srv (m68k*-*-uclinux*): New target.
authorNathan Sidwell <nathan@codesourcery.com>
Tue, 9 May 2006 15:21:19 +0000 (15:21 +0000)
committerNathan Sidwell <nathan@codesourcery.com>
Tue, 9 May 2006 15:21:19 +0000 (15:21 +0000)
* linux-low.c (linux_create_inferior): Use vfork on mmuless systems.
(linux_resume_one_process): Remove extraneous cast.
(linux_read_offsets): New.
(linux_target_op): Add linux_read_offsets on mmuless systems.
* server.c (handle_query): Add qOffsets logic.
* target.h (struct target_ops): Add read_offsets.

gdb/gdbserver/ChangeLog
gdb/gdbserver/configure.srv
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/gdbserver/target.h

index 3c13ba6d8730fe9c6cb072e83f9c319a7e2a8477..1a0ddf3e017f6ee6025e3b3f645ac536e5a14ce3 100644 (file)
@@ -1,3 +1,13 @@
+2006-05-09  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * configure.srv (m68k*-*-uclinux*): New target.
+       * linux-low.c (linux_create_inferior): Use vfork on mmuless systems.
+       (linux_resume_one_process): Remove extraneous cast.
+       (linux_read_offsets): New.
+       (linux_target_op): Add linux_read_offsets on mmuless systems.
+       * server.c (handle_query): Add qOffsets logic.
+       * target.h (struct target_ops): Add read_offsets.
+
 2006-03-15  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * linux-mips-low.c: Include <sys/ptrace.h> and "gdb_proc_service.h".
index e2d52c09e75089522109c18b79599c01e973fd19..ca41c179473894e85c23df31f40ec6a8ab8d6daf 100644 (file)
@@ -54,6 +54,12 @@ case "${target}" in
                        srv_linux_regsets=yes
                        srv_linux_thread_db=yes
                        ;;
+  m68*-*-uclinux*)     srv_regobj=reg-m68k.o
+                       srv_tgtobj="linux-low.o linux-m68k-low.o"
+                       srv_linux_usrregs=yes
+                       srv_linux_regsets=yes
+                       srv_linux_thread_db=yes
+                       ;;
   mips*-*-linux*)      srv_regobj=reg-mips.o
                        srv_tgtobj="linux-low.o linux-mips-low.o"
                        srv_linux_usrregs=yes
index 8518484fa76e5b8849ce6866c32921d7e9b40adf..08f1d89466d60250e8e1649343cbd2a3798ec8e0 100644 (file)
@@ -140,7 +140,11 @@ linux_create_inferior (char *program, char **allargs)
   void *new_process;
   int pid;
 
+#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__)
+  pid = vfork ();
+#else
   pid = fork ();
+#endif
   if (pid < 0)
     perror_with_name ("fork");
 
@@ -896,7 +900,7 @@ linux_resume_one_process (struct inferior_list_entry *entry,
   if (debug_threads && the_low_target.get_pc != NULL)
     {
       fprintf (stderr, "  ");
-      (long) (*the_low_target.get_pc) ();
+      (*the_low_target.get_pc) ();
     }
 
   /* If we have pending signals, consume one unless we are trying to reinsert
@@ -1550,6 +1554,51 @@ linux_stopped_data_address (void)
     return 0;
 }
 
+#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__)
+#if defined(__mcoldfire__)
+/* These should really be defined in the kernel's ptrace.h header.  */
+#define PT_TEXT_ADDR 49*4
+#define PT_DATA_ADDR 50*4
+#define PT_TEXT_END_ADDR  51*4
+#endif
+
+/* Under uClinux, programs are loaded at non-zero offsets, which we need
+   to tell gdb about.  */
+
+static int
+linux_read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p)
+{
+#if defined(PT_TEXT_ADDR) && defined(PT_DATA_ADDR) && defined(PT_TEXT_END_ADDR)
+  unsigned long text, text_end, data;
+  int pid = get_thread_process (current_inferior)->head.id;
+
+  errno = 0;
+
+  text = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_ADDR, 0);
+  text_end = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_END_ADDR, 0);
+  data = ptrace (PTRACE_PEEKUSER, pid, (long)PT_DATA_ADDR, 0);
+
+  if (errno == 0)
+    {
+      /* Both text and data offsets produced at compile-time (and so
+         used by gdb) are relative to the beginning of the program,
+         with the data segment immediately following the text segment.
+         However, the actual runtime layout in memory may put the data
+         somewhere else, so when we send gdb a data base-address, we
+         use the real data base address and subtract the compile-time
+         data base-address from it (which is just the length of the
+         text segment).  BSS immediately follows data in both
+         cases.  */
+      *text_p = text;
+      *data_p = data - (text_end - text);
+      
+      return 1;
+    }
+#endif
+ return 0;
+}
+#endif
+
 static struct target_ops linux_target_ops = {
   linux_create_inferior,
   linux_attach,
@@ -1569,6 +1618,9 @@ static struct target_ops linux_target_ops = {
   linux_remove_watchpoint,
   linux_stopped_by_watchpoint,
   linux_stopped_data_address,
+#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__)
+  linux_read_offsets,
+#endif
 };
 
 static void
index 0722e5996ef9045ece14b4a9b579f58d0242c447..51b87642a83bd3a921df2726c17363e0167547a5 100644 (file)
@@ -129,6 +129,20 @@ handle_query (char *own_buf)
        }
     }
 
+  if (the_target->read_offsets != NULL
+      && strcmp ("qOffsets", own_buf) == 0)
+    {
+      CORE_ADDR text, data;
+      
+      if (the_target->read_offsets (&text, &data))
+       sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX",
+                (long)text, (long)data, (long)data);
+      else
+       write_enn (own_buf);
+      
+      return;
+    }
+
   if (the_target->read_auxv != NULL
       && strncmp ("qPart:auxv:read::", own_buf, 17) == 0)
     {
index 7f65d3dbe4a06965de843c8a0e1fec6529074a27..6c9a4d7baa5529fbfe016a13bce635598db78cf0 100644 (file)
@@ -156,6 +156,11 @@ struct target_ops
 
   CORE_ADDR (*stopped_data_address) (void);
 
+  /* Reports the text, data offsets of the executable.  This is
+     needed for uclinux where the executable is relocated during load
+     time.  */
+  
+  int (*read_offsets) (CORE_ADDR *text, CORE_ADDR *data);
 };
 
 extern struct target_ops *the_target;