diff options
-rw-r--r-- | gdb/gdbserver/ChangeLog | 19 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 61 | ||||
-rw-r--r-- | gdb/gdbserver/lynx-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/nto-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/server.c | 3 | ||||
-rw-r--r-- | gdb/gdbserver/spu-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/target.h | 10 | ||||
-rw-r--r-- | gdb/gdbserver/win32-low.c | 1 |
8 files changed, 84 insertions, 13 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index d215d7a..cff2f36 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,24 @@ 2015-07-24 Yao Qi <yao.qi@linaro.org> + * linux-low.c (linux_arch_setup): New function. + (linux_low_filter_event): If proc->tdesc is NULL and + proc->attached is true, call the_low_target.arch_setup. + Otherwise, keep status pending, and return. + (linux_resume_one_lwp_throw): Don't call get_pc if + thread->while_stepping isn't NULL. Don't call + get_thread_regcache if proc->tdesc is NULL. + (need_step_over_p): Return 0 if proc->tdesc is NULL. + (linux_target_ops): Install arch_setup. + * server.c (start_inferior): Call the_target->arch_setup. + * target.h (struct target_ops) <arch_setup>: New field. + (target_arch_setup): New marco. + * lynx-low.c (lynx_target_ops): Update. + * nto-low.c (nto_target_ops): Update. + * spu-low.c (spu_target_ops): Update. + * win32-low.c (win32_target_ops): Update. + +2015-07-24 Yao Qi <yao.qi@linaro.org> + * linux-low.c (linux_add_process): Don't set proc->priv->new_inferior. (linux_create_inferior): Set proc->priv->new_inferior to 1. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index fa9dc29..ac1ad6f 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -822,6 +822,14 @@ linux_create_inferior (char *program, char **allargs) return pid; } +/* Implement the arch_setup target_ops method. */ + +static void +linux_arch_setup (void) +{ + the_low_target.arch_setup (); +} + /* Attach to an inferior process. Returns 0 on success, ERRNO on error. */ @@ -2105,23 +2113,35 @@ linux_low_filter_event (int lwpid, int wstat) { struct process_info *proc; - /* Architecture-specific setup after inferior is running. This - needs to happen after we have attached to the inferior and it - is stopped for the first time, but before we access any - inferior registers. */ + /* Architecture-specific setup after inferior is running. */ proc = find_process_pid (pid_of (thread)); - if (proc->priv->new_inferior) + if (proc->tdesc == NULL) { - struct thread_info *saved_thread; + if (proc->attached) + { + struct thread_info *saved_thread; - saved_thread = current_thread; - current_thread = thread; + /* This needs to happen after we have attached to the + inferior and it is stopped for the first time, but + before we access any inferior registers. */ + saved_thread = current_thread; + current_thread = thread; - the_low_target.arch_setup (); + the_low_target.arch_setup (); - current_thread = saved_thread; + current_thread = saved_thread; - proc->priv->new_inferior = 0; + proc->priv->new_inferior = 0; + } + else + { + /* The process is started, but GDBserver will do + architecture-specific setup after the program stops at + the first instruction. */ + child->status_pending_p = 1; + child->status_pending = wstat; + return child; + } } } @@ -3651,6 +3671,14 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, struct thread_info *thread = get_lwp_thread (lwp); struct thread_info *saved_thread; int fast_tp_collecting; + struct process_info *proc = get_thread_process (thread); + + /* Note that target description may not be initialised + (proc->tdesc == NULL) at this point because the program hasn't + stopped at the first instruction yet. It means GDBserver skips + the extra traps from the wrapper program (see option --wrapper). + Code in this function that requires register access should be + guarded by proc->tdesc == NULL or something else. */ if (lwp->stopped == 0) return; @@ -3661,7 +3689,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, /* Cancel actions that rely on GDB not changing the PC (e.g., the user used the "jump" command, or "set $pc = foo"). */ - if (lwp->stop_pc != get_pc (lwp)) + if (thread->while_stepping != NULL && lwp->stop_pc != get_pc (lwp)) { /* Collecting 'while-stepping' actions doesn't make sense anymore. */ @@ -3787,7 +3815,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, step = 1; } - if (the_low_target.get_pc != NULL) + if (proc->tdesc != NULL && the_low_target.get_pc != NULL) { struct regcache *regcache = get_thread_regcache (current_thread, 1); @@ -4014,6 +4042,12 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy) struct lwp_info *lwp = get_thread_lwp (thread); struct thread_info *saved_thread; CORE_ADDR pc; + struct process_info *proc = get_thread_process (thread); + + /* GDBserver is skipping the extra traps from the wrapper program, + don't have to do step over. */ + if (proc->tdesc == NULL) + return 0; /* LWPs which will not be resumed are not interesting, because we might not wait for them next time through linux_wait. */ @@ -6635,6 +6669,7 @@ current_lwp_ptid (void) static struct target_ops linux_target_ops = { linux_create_inferior, + linux_arch_setup, linux_attach, linux_kill, linux_detach, diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c index ee7b28a..5cf03be 100644 --- a/gdb/gdbserver/lynx-low.c +++ b/gdb/gdbserver/lynx-low.c @@ -722,6 +722,7 @@ lynx_request_interrupt (void) static struct target_ops lynx_target_ops = { lynx_create_inferior, + NULL, /* arch_setup */ lynx_attach, lynx_kill, lynx_detach, diff --git a/gdb/gdbserver/nto-low.c b/gdb/gdbserver/nto-low.c index 9276736..19f492f 100644 --- a/gdb/gdbserver/nto-low.c +++ b/gdb/gdbserver/nto-low.c @@ -925,6 +925,7 @@ nto_supports_non_stop (void) static struct target_ops nto_target_ops = { nto_create_inferior, + NULL, /* arch_setup */ nto_attach, nto_kill, nto_detach, diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 36e8987..2918770 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -272,6 +272,7 @@ start_inferior (char **argv) } while (last_status.value.sig != GDB_SIGNAL_TRAP); } + target_arch_setup (); return signal_pid; } @@ -279,6 +280,8 @@ start_inferior (char **argv) (assuming success). */ last_ptid = mywait (pid_to_ptid (signal_pid), &last_status, 0, 0); + target_arch_setup (); + if (last_status.kind != TARGET_WAITKIND_EXITED && last_status.kind != TARGET_WAITKIND_SIGNALLED) { diff --git a/gdb/gdbserver/spu-low.c b/gdb/gdbserver/spu-low.c index a56a889..cbee960 100644 --- a/gdb/gdbserver/spu-low.c +++ b/gdb/gdbserver/spu-low.c @@ -638,6 +638,7 @@ spu_request_interrupt (void) static struct target_ops spu_target_ops = { spu_create_inferior, + NULL, /* arch_setup */ spu_attach, spu_kill, spu_detach, diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h index 9a40867..fefd8d1 100644 --- a/gdb/gdbserver/target.h +++ b/gdb/gdbserver/target.h @@ -74,6 +74,9 @@ struct target_ops int (*create_inferior) (char *program, char **args); + /* Architecture-specific setup. */ + void (*arch_setup) (void); + /* Attach to a running process. PID is the process ID to attach to, specified by the user @@ -445,6 +448,13 @@ void set_target_ops (struct target_ops *); #define create_inferior(program, args) \ (*the_target->create_inferior) (program, args) +#define target_arch_setup() \ + do \ + { \ + if (the_target->arch_setup != NULL) \ + (*the_target->arch_setup) (); \ + } while (0) + #define myattach(pid) \ (*the_target->attach) (pid) diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c index 64caf24..7ccb3dd 100644 --- a/gdb/gdbserver/win32-low.c +++ b/gdb/gdbserver/win32-low.c @@ -1785,6 +1785,7 @@ win32_get_tib_address (ptid_t ptid, CORE_ADDR *addr) static struct target_ops win32_target_ops = { win32_create_inferior, + NULL, /* arch_setup */ win32_attach, win32_kill, win32_detach, |