summaryrefslogtreecommitdiffstats
path: root/lib/libthread_db
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2005-05-31 09:43:04 +0000
committerdfr <dfr@FreeBSD.org>2005-05-31 09:43:04 +0000
commit874478d7fd90e4178b95bc5a6f3b15c0c057c491 (patch)
tree6e75a2cdc72929f6a8fcd18615399aea3228d568 /lib/libthread_db
parent0d07e4ee86c5f875d30d214612b6aea86b793a5a (diff)
downloadFreeBSD-src-874478d7fd90e4178b95bc5a6f3b15c0c057c491.zip
FreeBSD-src-874478d7fd90e4178b95bc5a6f3b15c0c057c491.tar.gz
Add support for XMM registers in GDB for x86 processors that support
SSE (or its successors). Reviewed by: marcel, davidxu MFC After: 2 weeks
Diffstat (limited to 'lib/libthread_db')
-rw-r--r--lib/libthread_db/arch/i386/libpthread_md.c14
-rw-r--r--lib/libthread_db/libc_r_db.c22
-rw-r--r--lib/libthread_db/libpthread_db.c100
-rw-r--r--lib/libthread_db/libpthread_db.h4
-rw-r--r--lib/libthread_db/libthr_db.c40
-rw-r--r--lib/libthread_db/thread_db.c19
-rw-r--r--lib/libthread_db/thread_db.h6
-rw-r--r--lib/libthread_db/thread_db_int.h4
8 files changed, 208 insertions, 1 deletions
diff --git a/lib/libthread_db/arch/i386/libpthread_md.c b/lib/libthread_db/arch/i386/libpthread_md.c
index 86bb88d..dc14e60 100644
--- a/lib/libthread_db/arch/i386/libpthread_md.c
+++ b/lib/libthread_db/arch/i386/libpthread_md.c
@@ -81,6 +81,20 @@ pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
}
void
+pt_fxsave_to_ucontext(const char* r, ucontext_t *uc)
+{
+ if (has_xmm_regs)
+ memcpy(&uc->uc_mcontext.mc_fpstate, r, sizeof(struct savexmm));
+}
+
+void
+pt_ucontext_to_fxsave(const ucontext_t *uc, char *r)
+{
+ if (has_xmm_regs)
+ memcpy(r, &uc->uc_mcontext.mc_fpstate, sizeof(struct savexmm));
+}
+
+void
pt_md_init(void)
{
ucontext_t uc;
diff --git a/lib/libthread_db/libc_r_db.c b/lib/libthread_db/libc_r_db.c
index 78be702..10f7df1 100644
--- a/lib/libthread_db/libc_r_db.c
+++ b/lib/libthread_db/libc_r_db.c
@@ -228,6 +228,14 @@ libc_r_db_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *ti)
return ((err == PS_OK) ? TD_OK : TD_ERR);
}
+#ifdef __i386__
+static td_err_e
+libc_r_db_thr_getxmmregs(const td_thrhandle_t *th, char *fxsave)
+{
+ return (TD_NOFPREGS);
+}
+#endif
+
static td_err_e
libc_r_db_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *r)
{
@@ -284,6 +292,14 @@ libc_r_db_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *ev)
return (0);
}
+#ifdef __i386__
+static td_err_e
+libc_r_db_thr_setxmmregs(const td_thrhandle_t *th, const char *fxsave)
+{
+ return (TD_NOFPREGS);
+}
+#endif
+
static td_err_e
libc_r_db_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *r)
{
@@ -324,5 +340,9 @@ struct ta_ops libc_r_db_ops = {
.to_thr_set_event = libc_r_db_thr_set_event,
.to_thr_setfpregs = libc_r_db_thr_setfpregs,
.to_thr_setgregs = libc_r_db_thr_setgregs,
- .to_thr_validate = libc_r_db_thr_validate
+ .to_thr_validate = libc_r_db_thr_validate,
+#ifdef __i386__
+ .to_thr_getxmmregs = libc_r_db_thr_getxmmregs,
+ .to_thr_setxmmregs = libc_r_db_thr_setxmmregs,
+#endif
};
diff --git a/lib/libthread_db/libpthread_db.c b/lib/libthread_db/libpthread_db.c
index 7f858e7..ea7f81c 100644
--- a/lib/libthread_db/libpthread_db.c
+++ b/lib/libthread_db/libpthread_db.c
@@ -641,6 +641,51 @@ pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
return (0);
}
+#ifdef __i386__
+static td_err_e
+pt_thr_getxmmregs(const td_thrhandle_t *th, char *fxsave)
+{
+ const td_thragent_t *ta = th->th_ta;
+ struct kse_thr_mailbox tmbx;
+ psaddr_t tcb_addr, tmbx_addr, ptr;
+ lwpid_t lwp;
+ int ret;
+
+ return TD_ERR;
+
+ TDBG_FUNC();
+
+ ret = pt_validate(th);
+ if (ret)
+ return (ret);
+
+ if (ta->map[th->th_tid].type == PT_LWP) {
+ ret = ps_lgetxmmregs(ta->ph, ta->map[th->th_tid].lwp, fxsave);
+ return (P2T(ret));
+ }
+
+ ret = ps_pread(ta->ph, ta->map[th->th_tid].thr + ta->thread_off_tcb,
+ &tcb_addr, sizeof(tcb_addr));
+ if (ret != 0)
+ return (P2T(ret));
+ tmbx_addr = tcb_addr + ta->thread_off_tmbx;
+ ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
+ ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
+ if (ret != 0)
+ return (P2T(ret));
+ if (lwp != 0) {
+ ret = ps_lgetxmmregs(ta->ph, lwp, fxsave);
+ return (P2T(ret));
+ }
+
+ ret = ps_pread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ if (ret != 0)
+ return (P2T(ret));
+ pt_ucontext_to_fxsave(&tmbx.tm_context, fxsave);
+ return (0);
+}
+#endif
+
static td_err_e
pt_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregs)
{
@@ -723,6 +768,57 @@ pt_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
return (0);
}
+#ifdef __i386__
+static td_err_e
+pt_thr_setxmmregs(const td_thrhandle_t *th, const char *fxsave)
+{
+ const td_thragent_t *ta = th->th_ta;
+ struct kse_thr_mailbox tmbx;
+ psaddr_t tcb_addr, tmbx_addr, ptr;
+ lwpid_t lwp;
+ int ret;
+
+ return TD_ERR;
+
+ TDBG_FUNC();
+
+ ret = pt_validate(th);
+ if (ret)
+ return (ret);
+
+ if (ta->map[th->th_tid].type == PT_LWP) {
+ ret = ps_lsetxmmregs(ta->ph, ta->map[th->th_tid].lwp, fxsave);
+ return (P2T(ret));
+ }
+
+ ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
+ ta->thread_off_tcb,
+ &tcb_addr, sizeof(tcb_addr));
+ if (ret != 0)
+ return (P2T(ret));
+ tmbx_addr = tcb_addr + ta->thread_off_tmbx;
+ ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
+ ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
+ if (ret != 0)
+ return (P2T(ret));
+ if (lwp != 0) {
+ ret = ps_lsetxmmregs(ta->ph, lwp, fxsave);
+ return (P2T(ret));
+ }
+ /*
+ * Read a copy of context, this makes sure that registers
+ * not covered by structure reg won't be clobbered
+ */
+ ret = ps_pread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ if (ret != 0)
+ return (P2T(ret));
+
+ pt_fxsave_to_ucontext(fxsave, &tmbx.tm_context);
+ ret = ps_pwrite(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ return (P2T(ret));
+}
+#endif
+
static td_err_e
pt_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
{
@@ -1009,4 +1105,8 @@ struct ta_ops libpthread_db_ops = {
/* FreeBSD specific extensions. */
.to_thr_sstep = pt_thr_sstep,
+#ifdef __i386__
+ .to_thr_getxmmregs = pt_thr_getxmmregs,
+ .to_thr_setxmmregs = pt_thr_setxmmregs,
+#endif
};
diff --git a/lib/libthread_db/libpthread_db.h b/lib/libthread_db/libpthread_db.h
index 7a17b79..5347d01 100644
--- a/lib/libthread_db/libpthread_db.h
+++ b/lib/libthread_db/libpthread_db.h
@@ -82,6 +82,10 @@ void pt_reg_to_ucontext(const struct reg *, ucontext_t *);
void pt_ucontext_to_reg(const ucontext_t *, struct reg *);
void pt_fpreg_to_ucontext(const struct fpreg *, ucontext_t *);
void pt_ucontext_to_fpreg(const ucontext_t *, struct fpreg *);
+#ifdef __i386__
+void pt_fxsave_to_ucontext(const char *, ucontext_t *);
+void pt_ucontext_to_fxsave(const ucontext_t *, char *);
+#endif
int pt_reg_sstep(struct reg *reg, int step);
#endif /* _LIBPTHREAD_DB_H_ */
diff --git a/lib/libthread_db/libthr_db.c b/lib/libthread_db/libthr_db.c
index 0bfa020..8986939 100644
--- a/lib/libthread_db/libthr_db.c
+++ b/lib/libthread_db/libthr_db.c
@@ -505,6 +505,24 @@ pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
return (0);
}
+#ifdef __i386__
+static td_err_e
+pt_thr_getxmmregs(const td_thrhandle_t *th, char *fxsave)
+{
+ const td_thragent_t *ta = th->th_ta;
+ int ret;
+
+ TDBG_FUNC();
+
+ ret = pt_validate(th);
+ if (ret)
+ return (ret);
+
+ ret = ps_lgetxmmregs(ta->ph, th->th_tid, fxsave);
+ return (P2T(ret));
+}
+#endif
+
static td_err_e
pt_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregs)
{
@@ -537,6 +555,24 @@ pt_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
return (P2T(ret));
}
+#ifdef __i386__
+static td_err_e
+pt_thr_setxmmregs(const td_thrhandle_t *th, const char *fxsave)
+{
+ const td_thragent_t *ta = th->th_ta;
+ int ret;
+
+ TDBG_FUNC();
+
+ ret = pt_validate(th);
+ if (ret)
+ return (ret);
+
+ ret = ps_lsetxmmregs(ta->ph, th->th_tid, fxsave);
+ return (P2T(ret));
+}
+#endif
+
static td_err_e
pt_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
{
@@ -742,4 +778,8 @@ struct ta_ops libthr_db_ops = {
/* FreeBSD specific extensions. */
.to_thr_sstep = pt_thr_sstep,
+#ifdef __i386__
+ .to_thr_getxmmregs = pt_thr_getxmmregs,
+ .to_thr_setxmmregs = pt_thr_setxmmregs,
+#endif
};
diff --git a/lib/libthread_db/thread_db.c b/lib/libthread_db/thread_db.c
index b1b1bcc..45400bf 100644
--- a/lib/libthread_db/thread_db.c
+++ b/lib/libthread_db/thread_db.c
@@ -184,6 +184,16 @@ td_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
return (ta->ta_ops->to_thr_get_info(th, info));
}
+#ifdef __i386__
+td_err_e
+td_thr_getxmmregs(const td_thrhandle_t *th, char *fxsave)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_getxmmregs(th, fxsave));
+}
+#endif
+
+
td_err_e
td_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregset)
{
@@ -205,6 +215,15 @@ td_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *events)
return (ta->ta_ops->to_thr_set_event(th, events));
}
+#ifdef __i386__
+td_err_e
+td_thr_setxmmregs(const td_thrhandle_t *th, const char *fxsave)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_setxmmregs(th, fxsave));
+}
+#endif
+
td_err_e
td_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
{
diff --git a/lib/libthread_db/thread_db.h b/lib/libthread_db/thread_db.h
index 9dcc55e..a05274e 100644
--- a/lib/libthread_db/thread_db.h
+++ b/lib/libthread_db/thread_db.h
@@ -227,9 +227,15 @@ td_err_e td_thr_dbsuspend(const td_thrhandle_t *);
td_err_e td_thr_event_enable(const td_thrhandle_t *, int);
td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *);
td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *);
+#ifdef __i386__
+td_err_e td_thr_getxmmregs(const td_thrhandle_t *, char *);
+#endif
td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *);
td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t);
td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *);
+#ifdef __i386__
+td_err_e td_thr_setxmmregs(const td_thrhandle_t *, const char *);
+#endif
td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *);
td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t);
td_err_e td_thr_validate(const td_thrhandle_t *);
diff --git a/lib/libthread_db/thread_db_int.h b/lib/libthread_db/thread_db_int.h
index 7dc152c..2e5ecba 100644
--- a/lib/libthread_db/thread_db_int.h
+++ b/lib/libthread_db/thread_db_int.h
@@ -79,6 +79,10 @@ struct ta_ops {
/* FreeBSD specific extensions. */
td_err_e (*to_thr_sstep)(const td_thrhandle_t *, int);
+#if defined(__i386__)
+ td_err_e (*to_thr_getxmmregs)(const td_thrhandle_t *, char *);
+ td_err_e (*to_thr_setxmmregs)(const td_thrhandle_t *, const char *);
+#endif
};
#ifdef TD_DEBUG
OpenPOWER on IntegriCloud