Author: jhibbits
Date: Sat Oct  3 02:26:38 2020
New Revision: 366385
URL: https://svnweb.freebsd.org/changeset/base/366385

Log:
  MFC r366162,r366169,r366188
  
  Fix compat32 on mips64:
  * 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.

Modified:
  stable/12/sys/mips/include/elf.h
  stable/12/sys/mips/mips/freebsd32_machdep.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/mips/include/elf.h
==============================================================================
--- stable/12/sys/mips/include/elf.h    Fri Oct  2 23:48:57 2020        
(r366384)
+++ stable/12/sys/mips/include/elf.h    Sat Oct  3 02:26:38 2020        
(r366385)
@@ -105,8 +105,10 @@ typedef struct {   /* Auxiliary vector entry on initial 
        int     a_type;                 /* Entry type. */
        union {
                int     a_val;          /* Integer value. */
+#if defined(__mips_o32) || defined(__mips_n32)
                void    *a_ptr;         /* Address. */
                void    (*a_fcn)(void); /* Function pointer (not used). */
+#endif
        } a_un;
 } Elf32_Auxinfo;
 

Modified: stable/12/sys/mips/mips/freebsd32_machdep.c
==============================================================================
--- stable/12/sys/mips/mips/freebsd32_machdep.c Fri Oct  2 23:48:57 2020        
(r366384)
+++ stable/12/sys/mips/mips/freebsd32_machdep.c Sat Oct  3 02:26:38 2020        
(r366385)
@@ -57,6 +57,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>
@@ -476,6 +477,17 @@ freebsd32_sysarch(struct thread *td, struct freebsd32_
        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;
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to