diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2006-05-09 15:21:19 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@codesourcery.com> | 2006-05-09 15:21:19 +0000 |
commit | 52fb643739a7929a3091586e95336c4d991ee3b6 (patch) | |
tree | aad3914f0175fb68899a7a52a94fe545b888ab6a /gdb/gdbserver/linux-low.c | |
parent | 6e0080dd37a13129b04c34c7aa18ec2bee85b731 (diff) | |
download | gdb-52fb643739a7929a3091586e95336c4d991ee3b6.zip gdb-52fb643739a7929a3091586e95336c4d991ee3b6.tar.gz gdb-52fb643739a7929a3091586e95336c4d991ee3b6.tar.bz2 |
* 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.
Diffstat (limited to 'gdb/gdbserver/linux-low.c')
-rw-r--r-- | gdb/gdbserver/linux-low.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 8518484..08f1d89 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -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 |