diff options
author | dfr <dfr@FreeBSD.org> | 2005-05-31 09:43:04 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2005-05-31 09:43:04 +0000 |
commit | 874478d7fd90e4178b95bc5a6f3b15c0c057c491 (patch) | |
tree | 6e75a2cdc72929f6a8fcd18615399aea3228d568 /lib/libthread_db | |
parent | 0d07e4ee86c5f875d30d214612b6aea86b793a5a (diff) | |
download | FreeBSD-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.c | 14 | ||||
-rw-r--r-- | lib/libthread_db/libc_r_db.c | 22 | ||||
-rw-r--r-- | lib/libthread_db/libpthread_db.c | 100 | ||||
-rw-r--r-- | lib/libthread_db/libpthread_db.h | 4 | ||||
-rw-r--r-- | lib/libthread_db/libthr_db.c | 40 | ||||
-rw-r--r-- | lib/libthread_db/thread_db.c | 19 | ||||
-rw-r--r-- | lib/libthread_db/thread_db.h | 6 | ||||
-rw-r--r-- | lib/libthread_db/thread_db_int.h | 4 |
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 |