diff options
| author | Patrick Mooney <pmooney@pfmooney.com> | 2015-11-05 18:37:33 +0000 |
|---|---|---|
| committer | Patrick Mooney <pmooney@pfmooney.com> | 2015-11-11 20:37:43 +0000 |
| commit | d02acd3660b1cdab6856f3f37304f21788ecb5a0 (patch) | |
| tree | a5e037b7d0490ea16fb273b7a95008cfd92a3ec1 /usr/src | |
| parent | a5808573c4af894c001f22888db6ef10705a38b3 (diff) | |
| download | illumos-joyent-d02acd3660b1cdab6856f3f37304f21788ecb5a0.tar.gz | |
OS-4930 lxbrand ptrace should be more mindful of segregs
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/uts/intel/brand/lx/lx_archdep.c | 106 | ||||
| -rw-r--r-- | usr/src/uts/intel/ia32/os/archdep.c | 2 |
2 files changed, 71 insertions, 37 deletions
diff --git a/usr/src/uts/intel/brand/lx/lx_archdep.c b/usr/src/uts/intel/brand/lx/lx_archdep.c index 254985f23b..f743d5efaf 100644 --- a/usr/src/uts/intel/brand/lx/lx_archdep.c +++ b/usr/src/uts/intel/brand/lx/lx_archdep.c @@ -29,10 +29,24 @@ #include <sys/stack.h> #include <sys/sdt.h> #include <sys/sysmacros.h> +#include <sys/psw.h> #include <lx_errno.h> +/* + * Argument constants for fix_segreg. + * See usr/src/uts/intel/ia32/os/archdep.c for the originals. + */ +#define IS_CS 1 +#define IS_NOT_CS 0 + +extern greg_t fix_segreg(greg_t, int, model_t); + + #define LX_REG(ucp, r) ((ucp)->uc_mcontext.gregs[(r)]) +#define PSLMERGE(oldval, newval) \ + (((oldval) & ~PSL_USERMASK) | ((newval) & PSL_USERMASK)) + #ifdef __amd64 /* 64-bit native user_regs_struct */ typedef struct lx_user_regs64 { @@ -444,15 +458,20 @@ lx_set_user_regs32_uc(klwp_t *lwp, void *ucp, lx_user_regs32_t *lxrp) LX_REG(&uc, ESI) = lxrp->lxur_esi; LX_REG(&uc, EDI) = lxrp->lxur_edi; LX_REG(&uc, EIP) = lxrp->lxur_eip; - LX_REG(&uc, EFL) = lxrp->lxur_eflags; + LX_REG(&uc, EFL) = PSLMERGE(LX_REG(&uc, EFL), lxrp->lxur_eflags); LX_REG(&uc, UESP) = lxrp->lxur_esp; - LX_REG(&uc, SS) = lxrp->lxur_xss; + LX_REG(&uc, SS) = fix_segreg(lxrp->lxur_xss, IS_NOT_CS, + DATAMODEL_ILP32); /* %cs is ignored because of our lies */ - LX_REG(&uc, DS) = lxrp->lxur_xds; - LX_REG(&uc, ES) = lxrp->lxur_xes; - LX_REG(&uc, FS) = lxrp->lxur_xfs; - LX_REG(&uc, GS) = lxrp->lxur_xgs; + LX_REG(&uc, DS) = fix_segreg(lxrp->lxur_xds, IS_NOT_CS, + DATAMODEL_ILP32); + LX_REG(&uc, ES) = fix_segreg(lxrp->lxur_xes, IS_NOT_CS, + DATAMODEL_ILP32); + LX_REG(&uc, FS) = fix_segreg(lxrp->lxur_xfs, IS_NOT_CS, + DATAMODEL_ILP32); + LX_REG(&uc, GS) = fix_segreg(lxrp->lxur_xgs, IS_NOT_CS, + DATAMODEL_ILP32); if (lx_write_uc(p, ucp, &uc, sizeof (uc)) != 0) { return (-1); @@ -498,16 +517,17 @@ lx_set_user_regs32(lx_lwp_data_t *lwpd, lx_user_regs32_t *lxrp) rp->r_rax = (int32_t)lxrp->lxur_eax; lwpd->br_syscall_num = (int)lxrp->lxur_orig_eax; rp->r_rip = (int32_t)lxrp->lxur_eip; - rp->r_rfl = (int32_t)lxrp->lxur_eflags; + rp->r_rfl = (int32_t)PSLMERGE(rp->r_rfl, lxrp->lxur_eflags); rp->r_rsp = (int32_t)lxrp->lxur_esp; - rp->r_ss = (int32_t)lxrp->lxur_xss; + rp->r_ss = (int32_t)fix_segreg(lxrp->lxur_xss, IS_NOT_CS, + DATAMODEL_ILP32); kpreempt_disable(); pcb->pcb_rupdate = 1; - pcb->pcb_ds = lxrp->lxur_xds; - pcb->pcb_es = lxrp->lxur_xes; - pcb->pcb_fs = lxrp->lxur_xfs; - pcb->pcb_gs = lxrp->lxur_xgs; + pcb->pcb_ds = fix_segreg(lxrp->lxur_xds, IS_NOT_CS, DATAMODEL_ILP32); + pcb->pcb_es = fix_segreg(lxrp->lxur_xes, IS_NOT_CS, DATAMODEL_ILP32); + pcb->pcb_fs = fix_segreg(lxrp->lxur_xfs, IS_NOT_CS, DATAMODEL_ILP32); + pcb->pcb_gs = fix_segreg(lxrp->lxur_xgs, IS_NOT_CS, DATAMODEL_ILP32); kpreempt_enable(); #else /* __i386 */ rp->r_ebx = lxrp->lxur_ebx; @@ -519,14 +539,14 @@ lx_set_user_regs32(lx_lwp_data_t *lwpd, lx_user_regs32_t *lxrp) rp->r_eax = lxrp->lxur_eax; lwpd->br_syscall_num = (int)lxrp->lxur_orig_eax; rp->r_eip = lxrp->lxur_eip; - rp->r_efl = lxrp->lxur_eflags; + rp->r_efl = PSLMERGE(rp->r_efl, lxrp->lxur_eflags); rp->r_esp = lxrp->lxur_esp; - rp->r_ss = lxrp->lxur_xss; + rp->r_ss = fix_segreg(lxrp->lxur_xss, IS_NOT_CS, DATAMODEL_ILP32); - rp->r_ds = lxrp->lxur_xds; - rp->r_es = lxrp->lxur_xes; - rp->r_fs = lxrp->lxur_xfs; - rp->r_gs = lxrp->lxur_xgs; + rp->r_ds = fix_segreg(lxrp->lxur_xds, IS_NOT_CS, DATAMODEL_ILP32); + rp->r_es = fix_segreg(lxrp->lxur_xes, IS_NOT_CS, DATAMODEL_ILP32); + rp->r_fs = fix_segreg(lxrp->lxur_xfs, IS_NOT_CS, DATAMODEL_ILP32); + rp->r_gs = fix_segreg(lxrp->lxur_xgs, IS_NOT_CS, DATAMODEL_ILP32); #endif /* __amd64 */ return (0); @@ -774,17 +794,23 @@ lx_set_user_regs64_uc(klwp_t *lwp, void *ucp, lx_user_regs64_t *lxrp) LX_REG(&uc, REG_RSI) = lxrp->lxur_rsi; LX_REG(&uc, REG_RDI) = lxrp->lxur_rdi; LX_REG(&uc, REG_RIP) = lxrp->lxur_rip; - LX_REG(&uc, REG_RFL) = lxrp->lxur_rflags; + LX_REG(&uc, REG_RFL) = PSLMERGE(LX_REG(&uc, REG_RFL), + lxrp->lxur_rflags); LX_REG(&uc, REG_RSP) = lxrp->lxur_rsp; - LX_REG(&uc, REG_SS) = lxrp->lxur_xss; + LX_REG(&uc, REG_SS) = fix_segreg(lxrp->lxur_xss, IS_NOT_CS, + DATAMODEL_LP64); LX_REG(&uc, REG_FSBASE) = lxrp->lxur_xfs_base; LX_REG(&uc, REG_GSBASE) = lxrp->lxur_xgs_base; /* %cs is ignored because of our lies */ - LX_REG(&uc, REG_DS) = lxrp->lxur_xds; - LX_REG(&uc, REG_ES) = lxrp->lxur_xes; - LX_REG(&uc, REG_FS) = lxrp->lxur_xfs; - LX_REG(&uc, REG_GS) = lxrp->lxur_xgs; + LX_REG(&uc, REG_DS) = fix_segreg(lxrp->lxur_xds, IS_NOT_CS, + DATAMODEL_LP64); + LX_REG(&uc, REG_ES) = fix_segreg(lxrp->lxur_xes, IS_NOT_CS, + DATAMODEL_LP64); + LX_REG(&uc, REG_FS) = fix_segreg(lxrp->lxur_xfs, IS_NOT_CS, + DATAMODEL_LP64); + LX_REG(&uc, REG_GS) = fix_segreg(lxrp->lxur_xgs, IS_NOT_CS, + DATAMODEL_LP64); if (lx_write_uc(p, ucp, &uc, sizeof (uc)) != 0) { return (-1); @@ -812,15 +838,21 @@ lx_set_user_regs64_uc(klwp_t *lwp, void *ucp, lx_user_regs64_t *lxrp) LX_REG(&uc, ESI) = (int32_t)lxrp->lxur_rsi; LX_REG(&uc, EDI) = (int32_t)lxrp->lxur_rdi; LX_REG(&uc, EIP) = (int32_t)lxrp->lxur_rip; - LX_REG(&uc, EFL) = (int32_t)lxrp->lxur_rflags; + LX_REG(&uc, EFL) = (int32_t)PSLMERGE(LX_REG(&uc, EFL), + lxrp->lxur_rflags); LX_REG(&uc, UESP) = (int32_t)lxrp->lxur_rsp; - LX_REG(&uc, SS) = (int32_t)lxrp->lxur_xss; + LX_REG(&uc, SS) = (int32_t)fix_segreg(lxrp->lxur_xss, + IS_NOT_CS, DATAMODEL_ILP32); /* %cs is ignored because of our lies */ - LX_REG(&uc, DS) = (int32_t)lxrp->lxur_xds; - LX_REG(&uc, ES) = (int32_t)lxrp->lxur_xes; - LX_REG(&uc, FS) = (int32_t)lxrp->lxur_xfs; - LX_REG(&uc, GS) = (int32_t)lxrp->lxur_xgs; + LX_REG(&uc, DS) = (int32_t)fix_segreg(lxrp->lxur_xds, + IS_NOT_CS, DATAMODEL_ILP32); + LX_REG(&uc, ES) = (int32_t)fix_segreg(lxrp->lxur_xes, + IS_NOT_CS, DATAMODEL_ILP32); + LX_REG(&uc, FS) = (int32_t)fix_segreg(lxrp->lxur_xfs, + IS_NOT_CS, DATAMODEL_ILP32); + LX_REG(&uc, GS) = (int32_t)fix_segreg(lxrp->lxur_xgs, + IS_NOT_CS, DATAMODEL_ILP32); if (lx_write_uc(p, ucp, &uc, sizeof (uc)) != 0) { return (-1); @@ -843,6 +875,8 @@ lx_set_user_regs64(lx_lwp_data_t *lwpd, lx_user_regs64_t *lxrp) struct pcb *pcb = &lwp->lwp_pcb; void *ucp; + VERIFY(lwp_getdatamodel(lwp) == DATAMODEL_LP64); + switch (lx_regs_location(lwpd, &ucp, B_TRUE)) { case LX_REG_LOC_UNAVAIL: return (-1); @@ -876,18 +910,18 @@ lx_set_user_regs64(lx_lwp_data_t *lwpd, lx_user_regs64_t *lxrp) rp->r_rdi = lxrp->lxur_rdi; lwpd->br_syscall_num = (int)lxrp->lxur_orig_rax; rp->r_rip = lxrp->lxur_rip; - rp->r_rfl = lxrp->lxur_rflags; + rp->r_rfl = PSLMERGE(rp->r_rfl, lxrp->lxur_rflags); rp->r_rsp = lxrp->lxur_rsp; - rp->r_ss = lxrp->lxur_xss; + rp->r_ss = fix_segreg(lxrp->lxur_xss, IS_NOT_CS, DATAMODEL_LP64); pcb->pcb_fsbase = lxrp->lxur_xfs_base; pcb->pcb_gsbase = lxrp->lxur_xgs_base; kpreempt_disable(); pcb->pcb_rupdate = 1; - pcb->pcb_ds = lxrp->lxur_xds; - pcb->pcb_es = lxrp->lxur_xes; - pcb->pcb_fs = lxrp->lxur_xfs; - pcb->pcb_gs = lxrp->lxur_xgs; + pcb->pcb_ds = fix_segreg(lxrp->lxur_xds, IS_NOT_CS, DATAMODEL_LP64); + pcb->pcb_es = fix_segreg(lxrp->lxur_xes, IS_NOT_CS, DATAMODEL_LP64); + pcb->pcb_fs = fix_segreg(lxrp->lxur_xfs, IS_NOT_CS, DATAMODEL_LP64); + pcb->pcb_gs = fix_segreg(lxrp->lxur_xgs, IS_NOT_CS, DATAMODEL_LP64); kpreempt_enable(); return (0); diff --git a/usr/src/uts/intel/ia32/os/archdep.c b/usr/src/uts/intel/ia32/os/archdep.c index db4ccac06b..22a9af8970 100644 --- a/usr/src/uts/intel/ia32/os/archdep.c +++ b/usr/src/uts/intel/ia32/os/archdep.c @@ -636,7 +636,7 @@ getuserpc() #define IS_NOT_CS 0 /*ARGSUSED*/ -static greg_t +greg_t fix_segreg(greg_t sr, int iscs, model_t datamodel) { kthread_t *t = curthread; |
