summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjmallett <jmallett@FreeBSD.org>2012-03-06 07:50:45 +0000
committerjmallett <jmallett@FreeBSD.org>2012-03-06 07:50:45 +0000
commita14b2938a834ea913b22dcc43ff399403d137325 (patch)
tree8316c525a93e8d396ebe8859f59b756c4ca57ef7
parent00f892cca7dfff0d25fd2d10058ec295ec4b4193 (diff)
downloadFreeBSD-src-a14b2938a834ea913b22dcc43ff399403d137325.zip
FreeBSD-src-a14b2938a834ea913b22dcc43ff399403d137325.tar.gz
Fix two and a half oversights in COMPAT_FREEBSD32 related to contexts and
TLS: o) The mc_tls field used to store the TLS base when doing context gets and restores was left a pointer and not converted to a 32-bit integer. This had the bug of not correctly capturing the TLS value desired by the user, and the extra nastiness of making the structure the wrong size. o) The mc_tls field was not being saved by sendsig. As a result, the TLS base would always be set to NULL when restoring from a signal handler. Thanks to gonzo for helping track down a bunch of other TLS bugs that came out of tracking these down.
-rw-r--r--sys/mips/include/ucontext.h2
-rw-r--r--sys/mips/mips/freebsd32_machdep.c5
2 files changed, 4 insertions, 3 deletions
diff --git a/sys/mips/include/ucontext.h b/sys/mips/include/ucontext.h
index aafd1dc..a37fe7e 100644
--- a/sys/mips/include/ucontext.h
+++ b/sys/mips/include/ucontext.h
@@ -73,7 +73,7 @@ typedef struct __mcontext32 {
int mc_fpused;
int32_t mc_fpregs[33];
int32_t mc_fpc_eir;
- void *mc_tls;
+ int32_t mc_tls;
int __spare__[8];
} mcontext32_t;
diff --git a/sys/mips/mips/freebsd32_machdep.c b/sys/mips/mips/freebsd32_machdep.c
index 3fe8991..2fc4afe 100644
--- a/sys/mips/mips/freebsd32_machdep.c
+++ b/sys/mips/mips/freebsd32_machdep.c
@@ -222,7 +222,7 @@ get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
for (i = 0; i < 33; i++)
mcp->mc_fpregs[i] = mcp64.mc_fpregs[i];
mcp->mc_fpc_eir = mcp64.mc_fpc_eir;
- mcp->mc_tls = mcp64.mc_tls;
+ mcp->mc_tls = (int32_t)(intptr_t)mcp64.mc_tls;
return (0);
}
@@ -244,7 +244,7 @@ set_mcontext32(struct thread *td, const mcontext32_t *mcp)
for (i = 0; i < 33; i++)
mcp64.mc_fpregs[i] = mcp->mc_fpregs[i];
mcp64.mc_fpc_eir = mcp->mc_fpc_eir;
- mcp64.mc_tls = mcp->mc_tls;
+ mcp64.mc_tls = (void *)(intptr_t)mcp->mc_tls;
return (set_mcontext(td, &mcp64));
}
@@ -395,6 +395,7 @@ freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sf.sf_uc.uc_mcontext.mc_pc = regs.r_regs[PC];
sf.sf_uc.uc_mcontext.mullo = regs.r_regs[MULLO];
sf.sf_uc.uc_mcontext.mulhi = regs.r_regs[MULHI];
+ sf.sf_uc.uc_mcontext.mc_tls = (int32_t)(intptr_t)td->td_md.md_tls;
sf.sf_uc.uc_mcontext.mc_regs[0] = UCONTEXT_MAGIC; /* magic number */
for (i = 1; i < 32; i++)
sf.sf_uc.uc_mcontext.mc_regs[i] = regs.r_regs[i];
OpenPOWER on IntegriCloud