diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2006-03-31 15:35:33 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@codesourcery.com> | 2006-03-31 15:35:33 +0000 |
commit | 2c99eb21bce8f26926561e927b4285dbf406c919 (patch) | |
tree | cb7d77e5032307d165bca6faee693fdf2aa1f281 | |
parent | f18141ab3d3277ce865bff08f0066d980557e4e1 (diff) | |
download | gdb-2c99eb21bce8f26926561e927b4285dbf406c919.tar.gz |
* gdb/gdbserver/Makefile.in (reg-cf.o, reg-cf.c): New targets.
* gdb/gdbserver/configure.srv (m68k*-*-uclinux*): New target.
* gdb/gdbserver/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.
* gdb/gdbserver/server.c (handle_query): Add qOffsets logic.
* gdb/gdbserver/target.h (struct target_ops): Add read_offsets.
-rw-r--r-- | ChangeLog.csl | 12 | ||||
-rw-r--r-- | gdb/gdbserver/Makefile.in | 3 | ||||
-rw-r--r-- | gdb/gdbserver/configure.srv | 8 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 56 | ||||
-rw-r--r-- | gdb/gdbserver/server.c | 14 | ||||
-rw-r--r-- | gdb/gdbserver/target.h | 5 | ||||
-rw-r--r-- | gdb/regformats/reg-cf.dat | 33 |
7 files changed, 130 insertions, 1 deletions
diff --git a/ChangeLog.csl b/ChangeLog.csl index 7abedbfbb15..0e1e069e99b 100644 --- a/ChangeLog.csl +++ b/ChangeLog.csl @@ -1,3 +1,15 @@ +2006-03-31 Nathan Sidwell <nathan@codesourcery.com> + + * gdb/gdbserver/Makefile.in (reg-cf.o, reg-cf.c): New targets. + * gdb/gdbserver/configure.srv (m68k*-*-uclinux*): New target. + * gdb/gdbserver/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. + * gdb/gdbserver/server.c (handle_query): Add qOffsets logic. + * gdb/gdbserver/target.h (struct target_ops): Add read_offsets. + 2006-03-30 Mark Mitchell <mark@codesourcery.com> * libiberty/configure.ac: Add cygpath for mingw hosts. diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 0da5f6cde68..d13e465bc2c 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -309,6 +309,9 @@ reg-m32r.c : $(srcdir)/../regformats/reg-m32r.dat $(regdat_sh) reg-m68k.o : reg-m68k.c $(regdef_h) reg-m68k.c : $(srcdir)/../regformats/reg-m68k.dat $(regdat_sh) sh $(regdat_sh) $(srcdir)/../regformats/reg-m68k.dat reg-m68k.c +reg-cf.o : reg-cf.c $(regdef_h) +reg-cf.c : $(srcdir)/../regformats/reg-cf.dat $(regdat_sh) + sh $(regdat_sh) $(srcdir)/../regformats/reg-cf.dat reg-cf.c reg-mips.o : reg-mips.c $(regdef_h) reg-mips.c : $(srcdir)/../regformats/reg-mips.dat $(regdat_sh) sh $(regdat_sh) $(srcdir)/../regformats/reg-mips.dat reg-mips.c diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index e2d52c09e75..5249c6a6783 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -54,6 +54,14 @@ case "${target}" in srv_linux_regsets=yes srv_linux_thread_db=yes ;; + m68*-*-uclinux*) # FIXME, we really need a way of distinguishing + srv_regobj=reg-cf.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 diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 8518484fa76..c570e73bd02 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,53 @@ 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. */ + printf ("%lx, %lx, %lx\n", text, text_end, data); + + *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 +1620,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 diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 0722e5996ef..51b87642a83 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -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) { diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h index 7f65d3dbe4a..6c9a4d7baa5 100644 --- a/gdb/gdbserver/target.h +++ b/gdb/gdbserver/target.h @@ -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; diff --git a/gdb/regformats/reg-cf.dat b/gdb/regformats/reg-cf.dat new file mode 100644 index 00000000000..068aa755564 --- /dev/null +++ b/gdb/regformats/reg-cf.dat @@ -0,0 +1,33 @@ +name:m68k +expedite:sp,fp,pc +32:d0 +32:d1 +32:d2 +32:d3 +32:d4 +32:d5 +32:d6 +32:d7 +32:a0 +32:a1 +32:a2 +32:a3 +32:a4 +32:a5 +32:fp +32:sp +32:ps +32:pc + +64:fp0 +64:fp1 +64:fp2 +64:fp3 +64:fp4 +64:fp5 +64:fp6 +64:fp7 + +32:fpcontrol +32:fpstatus +32:fpiaddr |