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/libpthread_db.c | |
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/libpthread_db.c')
-rw-r--r-- | lib/libthread_db/libpthread_db.c | 100 |
1 files changed, 100 insertions, 0 deletions
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 }; |