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
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=366162
@ -105,8 +105,6 @@ typedef struct { /* Auxiliary vector entry on initial stack */
|
|||||||
int a_type; /* Entry type. */
|
int a_type; /* Entry type. */
|
||||||
union {
|
union {
|
||||||
int a_val; /* Integer value. */
|
int a_val; /* Integer value. */
|
||||||
void *a_ptr; /* Address. */
|
|
||||||
void (*a_fcn)(void); /* Function pointer (not used). */
|
|
||||||
} a_un;
|
} a_un;
|
||||||
} Elf32_Auxinfo;
|
} Elf32_Auxinfo;
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
#include <vm/vm_param.h>
|
#include <vm/vm_param.h>
|
||||||
|
|
||||||
|
#include <machine/cpuinfo.h>
|
||||||
#include <machine/md_var.h>
|
#include <machine/md_var.h>
|
||||||
#include <machine/reg.h>
|
#include <machine/reg.h>
|
||||||
#include <machine/sigframe.h>
|
#include <machine/sigframe.h>
|
||||||
@ -455,6 +456,17 @@ freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap)
|
|||||||
switch (uap->op) {
|
switch (uap->op) {
|
||||||
case MIPS_SET_TLS:
|
case MIPS_SET_TLS:
|
||||||
td->td_md.md_tls = (void *)(intptr_t)uap->parms;
|
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);
|
return (0);
|
||||||
case MIPS_GET_TLS:
|
case MIPS_GET_TLS:
|
||||||
tlsbase = (int32_t)(intptr_t)td->td_md.md_tls;
|
tlsbase = (int32_t)(intptr_t)td->td_md.md_tls;
|
||||||
|
Loading…
Reference in New Issue
Block a user