* 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.
This commit is contained in:
Nathan Sidwell 2006-05-09 15:21:19 +00:00
parent 6e0080dd37
commit 52fb643739
5 changed files with 88 additions and 1 deletions

View File

@ -1,3 +1,13 @@
2006-05-09 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".

View File

@ -54,6 +54,12 @@ case "${target}" in
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
;;
mips*-*-linux*) srv_regobj=reg-mips.o
srv_tgtobj="linux-low.o linux-mips-low.o"
srv_linux_usrregs=yes

View File

@ -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

View File

@ -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)
{

View File

@ -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;