Home | History | Annotate | Line # | Download | only in aarch64
      1 /* $NetBSD: exec_machdep.c,v 1.10 2021/09/23 15:19:03 ryo Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2014 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Matt Thomas of 3am Software Foundry.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 
     34 __KERNEL_RCSID(1, "$NetBSD: exec_machdep.c,v 1.10 2021/09/23 15:19:03 ryo Exp $");
     35 
     36 #include "opt_compat_netbsd.h"
     37 #include "opt_compat_netbsd32.h"
     38 
     39 #include <sys/param.h>
     40 #include <sys/systm.h>
     41 #include <sys/proc.h>
     42 #include <sys/exec.h>
     43 #include <sys/cprng.h>
     44 
     45 #include <uvm/uvm_extern.h>
     46 
     47 #include <compat/common/compat_util.h>
     48 #include <sys/exec_elf.h>			/* mandatory */
     49 
     50 #ifdef COMPAT_NETBSD32
     51 #include <compat/netbsd32/netbsd32_exec.h>
     52 #endif
     53 
     54 #include <aarch64/armreg.h>
     55 #include <aarch64/frame.h>
     56 #include <aarch64/machdep.h>
     57 
     58 #include <arm/cpufunc.h>
     59 
     60 #if EXEC_ELF64
     61 int
     62 aarch64_netbsd_elf64_probe(struct lwp *l, struct exec_package *epp, void *eh0,
     63 	char *itp, vaddr_t *start_p)
     64 {
     65 	return 0;
     66 }
     67 #endif
     68 
     69 #if EXEC_ELF32
     70 int
     71 aarch64_netbsd_elf32_probe(struct lwp *l, struct exec_package *epp, void *eh0,
     72 	char *itp, vaddr_t *start_p)
     73 {
     74 	const Elf32_Ehdr * const eh = eh0;
     75 	const bool elf_aapcs_p =
     76 	    (eh->e_flags & EF_ARM_EABIMASK) >= EF_ARM_EABI_VER4;
     77 
     78 	/* OABI not support */
     79 	if (!elf_aapcs_p)
     80 		return ENOEXEC;
     81 #ifdef __AARCH64EB__
     82 	/* BE32 not support */
     83 	if ((eh->e_flags & EF_ARM_BE8) == 0)
     84 		return ENOEXEC;
     85 #endif
     86 
     87 	/*
     88 	 * require aarch32 feature.
     89 	 * XXX should consider some cluster may have no aarch32?
     90 	 */
     91 	if (__SHIFTOUT(l->l_cpu->ci_id.ac_aa64pfr0, ID_AA64PFR0_EL1_EL0) !=
     92 	    ID_AA64PFR0_EL1_EL0_64_32)
     93 		return ENOEXEC;
     94 
     95 	/*
     96 	 * Copy (if any) the machine_arch of the executable to the proc.
     97 	 */
     98 	CTASSERT(sizeof(l->l_proc->p_md.md_march32) ==
     99 	    sizeof(epp->ep_machine_arch));
    100 	if (epp->ep_machine_arch[0] != 0)
    101 		strlcpy(l->l_proc->p_md.md_march32, epp->ep_machine_arch,
    102 		    sizeof(l->l_proc->p_md.md_march32));
    103 
    104 	return 0;
    105 }
    106 #endif
    107 
    108 void
    109 aarch64_setregs_ptrauth(struct lwp *l, bool randomize)
    110 {
    111 #ifdef ARMV83_PAC
    112 	if (!aarch64_pac_enabled)
    113 		return;
    114 
    115 	if (randomize) {
    116 		cprng_strong(kern_cprng, l->l_md.md_ia_user,
    117 		    sizeof(l->l_md.md_ia_user), 0);
    118 		cprng_strong(kern_cprng, l->l_md.md_ib_user,
    119 		    sizeof(l->l_md.md_ib_user), 0);
    120 		cprng_strong(kern_cprng, l->l_md.md_da_user,
    121 		    sizeof(l->l_md.md_da_user), 0);
    122 		cprng_strong(kern_cprng, l->l_md.md_db_user,
    123 		    sizeof(l->l_md.md_db_user), 0);
    124 		cprng_strong(kern_cprng, l->l_md.md_ga_user,
    125 		    sizeof(l->l_md.md_ga_user), 0);
    126 	} else {
    127 		memset(l->l_md.md_ia_user, 0,
    128 		    sizeof(l->l_md.md_ia_user));
    129 		memset(l->l_md.md_ib_user, 0,
    130 		    sizeof(l->l_md.md_ib_user));
    131 		memset(l->l_md.md_da_user, 0,
    132 		    sizeof(l->l_md.md_da_user));
    133 		memset(l->l_md.md_db_user, 0,
    134 		    sizeof(l->l_md.md_db_user));
    135 		memset(l->l_md.md_ga_user, 0,
    136 		    sizeof(l->l_md.md_ga_user));
    137 	}
    138 #endif
    139 }
    140 
    141 void
    142 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
    143 {
    144 	struct proc * const p = l->l_proc;
    145 	struct trapframe * const tf = lwp_trapframe(l);
    146 
    147 	aarch64_setregs_ptrauth(l, true);
    148 
    149 	p->p_flag &= ~PK_32;
    150 
    151 	/*
    152 	 * void __start(void (*cleanup)(void), const Obj_Entry *obj,
    153 	 *    struct ps_strings *ps_strings);
    154 	 */
    155 	memset(tf, 0, sizeof(*tf));
    156 	tf->tf_reg[2] = p->p_psstrp;
    157 	tf->tf_pc = pack->ep_entry;
    158 	tf->tf_sp = stack & -16L;
    159 	tf->tf_spsr = SPSR_M_EL0T;
    160 }
    161