From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4984 invoked by alias); 8 May 2006 14:16:51 -0000 Received: (qmail 4934 invoked by uid 22791); 8 May 2006 14:16:48 -0000 X-Spam-Check-By: sourceware.org Received: from intranet.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.6) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 08 May 2006 14:16:45 +0000 Received: (qmail 2045 invoked from network); 8 May 2006 14:16:42 -0000 Received: from unknown (HELO ?192.168.189.145?) (nathan@127.0.0.2) by mail.codesourcery.com with ESMTPA; 8 May 2006 14:16:42 -0000 Message-ID: <445F5278.3000900@codesourcery.com> Date: Mon, 08 May 2006 16:57:00 -0000 From: Nathan Sidwell User-Agent: Mozilla Thunderbird 1.0.7 (X11/20051013) MIME-Version: 1.0 To: gdb@sources.redhat.com CC: Daniel Jacobowitz , jr.peulve@wanadoo.fr Subject: gdbserver for m68k-uclinux Content-Type: multipart/mixed; boundary="------------000308070106010505020100" Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2006-05/txt/msg00080.txt.bz2 This is a multi-part message in MIME format. --------------000308070106010505020100 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 660 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 --------------000308070106010505020100 Content-Type: text/plain; name="all.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="all.diff" Content-length: 6140 2006-05-08 Nathan Sidwell * 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 * linux-mips-low.c: Include 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; --------------000308070106010505020100--