aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/gdbserver/ChangeLog19
-rw-r--r--gdb/gdbserver/linux-low.c61
-rw-r--r--gdb/gdbserver/lynx-low.c1
-rw-r--r--gdb/gdbserver/nto-low.c1
-rw-r--r--gdb/gdbserver/server.c3
-rw-r--r--gdb/gdbserver/spu-low.c1
-rw-r--r--gdb/gdbserver/target.h10
-rw-r--r--gdb/gdbserver/win32-low.c1
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,