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
This commit is contained in:
parent
01d0f9c0e4
commit
6d5ca5199c
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user