diff options
author | Daniel Jacobowitz <drow@false.org> | 2002-04-20 17:04:09 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2002-04-20 17:04:09 +0000 |
commit | 611cb4a54268cbb8f25175dd4900fff87eae161b (patch) | |
tree | 36f338fc4e4b09e0b70a51d1f96e648090173ed2 /gdb/gdbserver/linux-low.c | |
parent | e1015982836dff64160d26425ef428997c1de624 (diff) | |
download | gdb-611cb4a54268cbb8f25175dd4900fff87eae161b.zip gdb-611cb4a54268cbb8f25175dd4900fff87eae161b.tar.gz gdb-611cb4a54268cbb8f25175dd4900fff87eae161b.tar.bz2 |
2002-04-20 Daniel Jacobowitz <drow@mvista.com>
* gdbserver/mem-break.c: New file.
* gdbserver/mem-break.h: New file.
* gdbserver/Makefile.in: Add mem-break.o rule; update server.h
dependencies.
* gdbserver/inferiors.c (struct inferior_info): Add target_data
member.
(clear_inferiors): Free target_data member if set.
(inferior_target_data, set_inferior_target_data): New functions.
* gdbserver/linux-i386-low.c (i386_breakpoint, i386_breakpoint_len)
(i386_stop_pc, i386_set_pc): New. Add to the_low_target.
* gdbserver/linux-low.c (linux_bp_reinsert): New variable.
(struct inferior_linux_data): New.
(linux_create_inferior): Use set_inferior_target_data.
(linux_attach): Likewise. Call add_inferior.
(linux_wait_for_one_inferior): New function.
(linux_wait): Call it.
(linux_write_memory): Add const.
(initialize_low): Call set_breakpoint_data.
* gdbserver/linux-low.h (struct linux_target_ops): Add breakpoint
handling members.
* gdbserver/server.c (attach_inferior): Remove extra add_inferior
call.
* gdbserver/server.h: Include mem-break.h. Update inferior.c
prototypes.
* gdbserver/target.c (read_inferior_memory)
(write_inferior_memory): New functions.
* gdbserver/target.h (read_inferior_memory)
(write_inferior_memory): Change macros to prototypes.
(struct target_ops): Update comments. Add const to write_memory
definition.
Diffstat (limited to 'gdb/gdbserver/linux-low.c')
-rw-r--r-- | gdb/gdbserver/linux-low.c | 88 |
1 files changed, 83 insertions, 5 deletions
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index bd1a876..10966e0 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -35,6 +35,10 @@ #include <stdlib.h> #include <unistd.h> +static CORE_ADDR linux_bp_reinsert; + +static void linux_resume (int step, int signal); + #define PTRACE_ARG3_TYPE long #define PTRACE_XFER_TYPE long @@ -46,12 +50,18 @@ extern int errno; static int inferior_pid; +struct inferior_linux_data +{ + int pid; +}; + /* Start an inferior process and returns its pid. ALLARGS is a vector of program-name and args. */ static int linux_create_inferior (char *program, char **allargs) { + struct inferior_linux_data *tdata; int pid; pid = fork (); @@ -71,6 +81,10 @@ linux_create_inferior (char *program, char **allargs) } add_inferior (pid); + tdata = (struct inferior_linux_data *) malloc (sizeof (*tdata)); + tdata->pid = pid; + set_inferior_target_data (current_inferior, tdata); + /* FIXME remove */ inferior_pid = pid; return 0; @@ -81,6 +95,8 @@ linux_create_inferior (char *program, char **allargs) static int linux_attach (int pid) { + struct inferior_linux_data *tdata; + if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0) { fprintf (stderr, "Cannot attach to process %d: %s (%d)\n", pid, @@ -90,6 +106,10 @@ linux_attach (int pid) _exit (0177); } + add_inferior (pid); + tdata = (struct inferior_linux_data *) malloc (sizeof (*tdata)); + tdata->pid = pid; + set_inferior_target_data (current_inferior, tdata); return 0; } @@ -112,19 +132,75 @@ linux_thread_alive (int pid) return 1; } +static int +linux_wait_for_one_inferior (struct inferior_info *child) +{ + struct inferior_linux_data *child_data = inferior_target_data (child); + int pid, wstat; + + while (1) + { + pid = waitpid (child_data->pid, &wstat, 0); + + if (pid != child_data->pid) + perror_with_name ("wait"); + + /* If this target supports breakpoints, see if we hit one. */ + if (the_low_target.stop_pc != NULL + && WIFSTOPPED (wstat) + && WSTOPSIG (wstat) == SIGTRAP) + { + CORE_ADDR stop_pc; + + if (linux_bp_reinsert != 0) + { + reinsert_breakpoint (linux_bp_reinsert); + linux_bp_reinsert = 0; + linux_resume (0, 0); + continue; + } + + fetch_inferior_registers (0); + stop_pc = (*the_low_target.stop_pc) (); + + if (check_breakpoints (stop_pc) != 0) + { + if (the_low_target.set_pc != NULL) + (*the_low_target.set_pc) (stop_pc); + + if (the_low_target.breakpoint_reinsert_addr == NULL) + { + linux_bp_reinsert = stop_pc; + uninsert_breakpoint (stop_pc); + linux_resume (1, 0); + } + else + { + reinsert_breakpoint_by_bp + (stop_pc, (*the_low_target.breakpoint_reinsert_addr) ()); + linux_resume (0, 0); + } + + continue; + } + } + + return wstat; + } + /* NOTREACHED */ + return 0; +} + /* Wait for process, returns status */ static unsigned char linux_wait (char *status) { - int pid; int w; enable_async_io (); - pid = waitpid (inferior_pid, &w, 0); + w = linux_wait_for_one_inferior (current_inferior); disable_async_io (); - if (pid != inferior_pid) - perror_with_name ("wait"); if (WIFEXITED (w)) { @@ -440,7 +516,7 @@ linux_read_memory (CORE_ADDR memaddr, char *myaddr, int len) returns the value of errno. */ static int -linux_write_memory (CORE_ADDR memaddr, char *myaddr, int len) +linux_write_memory (CORE_ADDR memaddr, const char *myaddr, int len) { register int i; /* Round starting address down to longword boundary. */ @@ -508,5 +584,7 @@ void initialize_low (void) { set_target_ops (&linux_target_ops); + set_breakpoint_data (the_low_target.breakpoint, + the_low_target.breakpoint_len); init_registers (); } |