This is the mail archive of the gdb@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]

gdbserver for m68k-uclinux


This patch implements the necessary qOffsets logic tso that a uclinux hosted gdbserver can tell a remote gdb what the text & data offsets are. It also uses vfork on such systems.

This implementation clearly separates the gdb protocol pieces of qOffsets from the system specific pieces of determining the offsets. The original diff I found on the uclinux site did not have such a separation, I used that implementation for inspiration.

Tested on a m5208evb hosted uclinux system.

ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2006-05-08  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: gdbserver/configure.srv
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure.srv,v
retrieving revision 1.13
diff -c -3 -p -r1.13 configure.srv
*** gdbserver/configure.srv	2 Nov 2005 19:54:44 -0000	1.13
--- gdbserver/configure.srv	8 May 2006 14:07:50 -0000
*************** case "${target}" in
*** 54,59 ****
--- 54,66 ----
  			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
+ 			LDFLAGS=-elf2flt
+ 			;;
    mips*-*-linux*)	srv_regobj=reg-mips.o
  			srv_tgtobj="linux-low.o linux-mips-low.o"
  			srv_linux_usrregs=yes
Index: gdbserver/linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.43
diff -c -3 -p -r1.43 linux-low.c
*** gdbserver/linux-low.c	15 Feb 2006 14:36:32 -0000	1.43
--- gdbserver/linux-low.c	8 May 2006 14:07:51 -0000
*************** linux_create_inferior (char *program, ch
*** 140,146 ****
--- 140,150 ----
    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");
  
*************** linux_resume_one_process (struct inferio
*** 896,902 ****
    if (debug_threads && the_low_target.get_pc != NULL)
      {
        fprintf (stderr, "  ");
!       (long) (*the_low_target.get_pc) ();
      }
  
    /* If we have pending signals, consume one unless we are trying to reinsert
--- 900,906 ----
    if (debug_threads && the_low_target.get_pc != NULL)
      {
        fprintf (stderr, "  ");
!       (*the_low_target.get_pc) ();
      }
  
    /* If we have pending signals, consume one unless we are trying to reinsert
*************** linux_stopped_data_address (void)
*** 1550,1555 ****
--- 1554,1604 ----
      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,
*************** static struct target_ops linux_target_op
*** 1569,1574 ****
--- 1618,1626 ----
    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: gdbserver/server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.32
diff -c -3 -p -r1.32 server.c
*** gdbserver/server.c	8 Feb 2006 20:26:44 -0000	1.32
--- gdbserver/server.c	8 May 2006 14:07:52 -0000
*************** handle_query (char *own_buf)
*** 129,134 ****
--- 129,148 ----
  	}
      }
  
+   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: gdbserver/target.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/target.h,v
retrieving revision 1.15
diff -c -3 -p -r1.15 target.h
*** gdbserver/target.h	23 Dec 2005 18:11:55 -0000	1.15
--- gdbserver/target.h	8 May 2006 14:07:52 -0000
*************** struct target_ops
*** 156,161 ****
--- 156,166 ----
  
    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;

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