* gdbserver for m68k-uclinux
@ 2006-05-08 16:57 Nathan Sidwell
2006-05-09 11:58 ` Jean-Rene Peulve
2006-05-09 13:20 ` Daniel Jacobowitz
0 siblings, 2 replies; 7+ messages in thread
From: Nathan Sidwell @ 2006-05-08 16:57 UTC (permalink / raw)
To: gdb; +Cc: Daniel Jacobowitz, jr.peulve
[-- Attachment #1: Type: text/plain, Size: 660 bytes --]
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
[-- Attachment #2: all.diff --]
[-- Type: text/plain, Size: 6140 bytes --]
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;
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: gdbserver for m68k-uclinux
2006-05-08 16:57 gdbserver for m68k-uclinux Nathan Sidwell
@ 2006-05-09 11:58 ` Jean-Rene Peulve
2006-05-09 12:19 ` Nathan Sidwell
2006-05-09 13:20 ` Daniel Jacobowitz
1 sibling, 1 reply; 7+ messages in thread
From: Jean-Rene Peulve @ 2006-05-09 11:58 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: gdb, Daniel Jacobowitz
Hi Nathan,
Oups: I resend this because the previous email was html and got bounced by
gdb@sources.redhat.com
I have been forced to change your patch to make it works.
1) missing return in server.c
2) I also add an fprintf to stderr with the address of the text and data
section to allow the use of add-symbol_file command which requires these
address.
The response to qOffsets being hidden by gdb, I then can get it from the
target console or telnet.
Jean-René Peulvé
Here are my revised patches based on yours:
--- server.c.orig 2006-02-08 20:26:00.000000000 +0100
+++ server.c 2006-05-09 11:07:15.000000000 +0200
@@ -129,6 +129,23 @@
}
}
+ 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);
+ return;
+ }
+ else
+ write_enn (own_buf);
+
+ return;
+ }
+
+
if (the_target->read_auxv != NULL
&& strncmp ("qPart:auxv:read::", own_buf, 17) == 0)
{
--- linux-low.c.orig 2006-05-09 11:21:12.000000000 +0200
+++ linux-low.c 2006-05-09 10:58:55.000000000 +0200
@@ -140,7 +140,11 @@
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 @@
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,52 @@
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);
+
+ fprintf(stderr, "text=%lx data=%lx errno=%d\n", text, data, errno);
+ 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 +1619,9 @@
linux_remove_watchpoint,
linux_stopped_by_watchpoint,
linux_stopped_data_address,
+#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__)
+ linux_read_offsets,
+#endif
};
static void
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: gdbserver for m68k-uclinux
2006-05-09 11:58 ` Jean-Rene Peulve
@ 2006-05-09 12:19 ` Nathan Sidwell
2006-05-09 12:34 ` Jean-Rene Peulve
0 siblings, 1 reply; 7+ messages in thread
From: Nathan Sidwell @ 2006-05-09 12:19 UTC (permalink / raw)
To: Jean-Rene Peulve; +Cc: gdb, Daniel Jacobowitz
Jean-Rene Peulve wrote:
> Hi Nathan,
> Oups: I resend this because the previous email was html and got bounced
> by gdb@sources.redhat.com
Thanks for testing the patch out!
> I have been forced to change your patch to make it works.
>
> 1) missing return in server.c
The return you've added is unnecessary.
> 2) I also add an fprintf to stderr with the address of the text and data
> section to allow the use of add-symbol_file command which requires these
> address.
> The response to qOffsets being hidden by gdb, I then can get it from
> the target console or telnet.
Dan, I'll leave this change for you to decide. I don't understand the usage
here. Why is it not necessary to know the text_end address in this case, for
instance?
> + if (the_target->read_offsets (&text, &data)) {
> + sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX",
> + (long)text, (long)data, (long)data);
> + return;
This return is not needed, why did you find it necessary?
> + }
> + else
> + write_enn (own_buf);
> +
> + return;
> + }
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: gdbserver for m68k-uclinux
2006-05-09 12:19 ` Nathan Sidwell
@ 2006-05-09 12:34 ` Jean-Rene Peulve
2006-05-09 12:39 ` Daniel Jacobowitz
0 siblings, 1 reply; 7+ messages in thread
From: Jean-Rene Peulve @ 2006-05-09 12:34 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: gdb, Daniel Jacobowitz
Hi Natan,
Sorry you were right. No need for my extra return. I did not spot the
return just below !
About my extra fprintf on the target console:
I am also debugging kernel modules and I am used to specify the
add-symbol-file for several of them
in adition to the kernel.
For gdbserver, I was using one gdb command file to debug several
applications then when I start
gdb I didn't specify the file to debug in the command line and then I used
add-symbol-file afterward.
With your remark in mind, I try to specify the application to debug in the
command line and you are also right: the extra fprintf is not mandatory but
I need to spend more time on it to see if there is any need left.
Jean-René
At 12:07 09/05/06, Nathan Sidwell wrote:
>Jean-Rene Peulve wrote:
>>Hi Nathan,
>>Oups: I resend this because the previous email was html and got bounced
>>by gdb@sources.redhat.com
>
>Thanks for testing the patch out!
>
>>I have been forced to change your patch to make it works.
>>1) missing return in server.c
>The return you've added is unnecessary.
>
>>2) I also add an fprintf to stderr with the address of the text and data
>>section to allow the use of add-symbol_file command which requires these
>>address.
>> The response to qOffsets being hidden by gdb, I then can get it from
>> the target console or telnet.
>
>Dan, I'll leave this change for you to decide. I don't understand the
>usage here. Why is it not necessary to know the text_end address in this
>case, for instance?
>
>>+ if (the_target->read_offsets (&text, &data)) {
>>+ sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX",
>>+ (long)text, (long)data, (long)data);
>>+ return;
>This return is not needed, why did you find it necessary?
>
>>+ }
>>+ else
>>+ write_enn (own_buf);
>>+
>>+ return;
>>+ }
>
>nathan
>
>--
>Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
>nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: gdbserver for m68k-uclinux
2006-05-09 12:34 ` Jean-Rene Peulve
@ 2006-05-09 12:39 ` Daniel Jacobowitz
0 siblings, 0 replies; 7+ messages in thread
From: Daniel Jacobowitz @ 2006-05-09 12:39 UTC (permalink / raw)
To: Jean-Rene Peulve; +Cc: Nathan Sidwell, gdb
On Tue, May 09, 2006 at 01:58:23PM +0200, Jean-Rene Peulve wrote:
> With your remark in mind, I try to specify the application to debug in the
> command line and you are also right: the extra fprintf is not mandatory but
> I need to spend more time on it to see if there is any need left.
There should not be.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: gdbserver for m68k-uclinux
2006-05-08 16:57 gdbserver for m68k-uclinux Nathan Sidwell
2006-05-09 11:58 ` Jean-Rene Peulve
@ 2006-05-09 13:20 ` Daniel Jacobowitz
2006-05-09 14:13 ` Nathan Sidwell
1 sibling, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2006-05-09 13:20 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: gdb, jr.peulve
On Mon, May 08, 2006 at 03:15:20PM +0100, Nathan Sidwell wrote:
> 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?
Yes, this is OK. Thanks.
> + 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
> + ;;
Is LDFLAGS really necessary here? I thought the toolchain took care of
it.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: gdbserver for m68k-uclinux
2006-05-09 13:20 ` Daniel Jacobowitz
@ 2006-05-09 14:13 ` Nathan Sidwell
0 siblings, 0 replies; 7+ messages in thread
From: Nathan Sidwell @ 2006-05-09 14:13 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb, jr.peulve
Daniel Jacobowitz wrote:
> On Mon, May 08, 2006 at 03:15:20PM +0100, Nathan Sidwell wrote:
>
>>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?
>
>
> Yes, this is OK. Thanks.
>
> Is LDFLAGS really necessary here? I thought the toolchain took care of
> it.
I think at the point I developed this patch, the compiler didn't take care of it
:) I can remove it.
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-05-09 13:20 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-08 16:57 gdbserver for m68k-uclinux Nathan Sidwell
2006-05-09 11:58 ` Jean-Rene Peulve
2006-05-09 12:19 ` Nathan Sidwell
2006-05-09 12:34 ` Jean-Rene Peulve
2006-05-09 12:39 ` Daniel Jacobowitz
2006-05-09 13:20 ` Daniel Jacobowitz
2006-05-09 14:13 ` Nathan Sidwell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox