diff options
author | Justin Hibbits <jhibbits@FreeBSD.org> | 2020-09-25 17:13:45 +0000 |
---|---|---|
committer | Justin Hibbits <jhibbits@FreeBSD.org> | 2020-09-25 17:13:45 +0000 |
commit | 6d5ca5199c509904a202dc2c4f9fba24471d8151 (patch) | |
tree | aea1d51d13964f2fc542afa339b3f64a7f186c41 /sys/mips | |
parent | 01d0f9c0e40a44cff5e25842b72075cbaf0864de (diff) | |
download | src-6d5ca5199c509904a202dc2c4f9fba24471d8151.tar.gz src-6d5ca5199c509904a202dc2c4f9fba24471d8151.zip |
Fix compat32 on mips64
Summary:
Two bugs:
* Elf32_Auxinfo is broken, using pointers in the union, which are 64-bits not
32.
* freebsd32_sysarch() doesn't update the 'user local' register when handling
MIPS_SET_TLS, leading to a NULL pointer dereference in the 32-bit
application.
Reviewed by: #mips, brooks
MFC after: 1 week
Sponsored by: Juniper Networks, Inc
Differential Revision: https://reviews.freebsd.org/D26556
Notes
Notes:
svn path=/head/; revision=366162
Diffstat (limited to 'sys/mips')
-rw-r--r-- | sys/mips/include/elf.h | 2 | ||||
-rw-r--r-- | sys/mips/mips/freebsd32_machdep.c | 12 |
2 files changed, 12 insertions, 2 deletions
diff --git a/sys/mips/include/elf.h b/sys/mips/include/elf.h index d62b237fdac0..a0263bb3a975 100644 --- a/sys/mips/include/elf.h +++ b/sys/mips/include/elf.h @@ -105,8 +105,6 @@ typedef struct { /* Auxiliary vector entry on initial stack */ int a_type; /* Entry type. */ union { int a_val; /* Integer value. */ - void *a_ptr; /* Address. */ - void (*a_fcn)(void); /* Function pointer (not used). */ } a_un; } Elf32_Auxinfo; diff --git a/sys/mips/mips/freebsd32_machdep.c b/sys/mips/mips/freebsd32_machdep.c index 1488edb9fb77..13fe21df99af 100644 --- a/sys/mips/mips/freebsd32_machdep.c +++ b/sys/mips/mips/freebsd32_machdep.c @@ -58,6 +58,7 @@ #include <vm/vm.h> #include <vm/vm_param.h> +#include <machine/cpuinfo.h> #include <machine/md_var.h> #include <machine/reg.h> #include <machine/sigframe.h> @@ -455,6 +456,17 @@ freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap) switch (uap->op) { case MIPS_SET_TLS: td->td_md.md_tls = (void *)(intptr_t)uap->parms; + + /* + * If there is an user local register implementation (ULRI) + * update it as well. Add the TLS and TCB offsets so the + * value in this register is adjusted like in the case of the + * rdhwr trap() instruction handler. + */ + if (cpuinfo.userlocal_reg == true) { + mips_wr_userlocal((unsigned long)(uap->parms + + td->td_md.md_tls_tcb_offset)); + } return (0); case MIPS_GET_TLS: tlsbase = (int32_t)(intptr_t)td->td_md.md_tls; |