int
ELFNAME2(netbsd32,probe_noteless)(struct lwp *l, struct exec_package *epp,
				  void *eh, char *itp, vaddr_t *pos)
{
 	if (itp && epp->ep_interp == NULL) {
		extern const char machine32[];
		(void)compat_elf_check_interp(epp, itp, machine32);
	}
#ifdef _LP64
	epp->ep_flags |= EXEC_32 | EXEC_FORCEAUX;
#endif
	epp->ep_vm_minaddr = VM_MIN_ADDRESS;
	epp->ep_vm_maxaddr = USRSTACK32;
#ifdef ELF_INTERP_NON_RELOCATABLE
	*pos = ELF_LINK_ADDR;
#endif
	return 0;
}
Exemplo n.º 2
0
int
arm_netbsd_elf32_probe(struct lwp *l, struct exec_package *epp, void *eh0,
                       char *itp, vaddr_t *start_p)
{
    const char *itp_suffix = NULL;
    const Elf_Ehdr * const eh = eh0;
    const bool elf_aapcs_p =
        (eh->e_flags & EF_ARM_EABIMASK) >= EF_ARM_EABI_VER4;
#ifdef COMPAT_NETBSD32
    const bool netbsd32_p = (epp->ep_esch->es_emul == &emul_netbsd32);
#else
    const bool netbsd32_p = false;
#endif
#ifdef __ARM_EABI__
    const bool aapcs_p = true;
#else
    const bool aapcs_p = false;
#endif
#ifdef __ARMEB__
    const bool be8_p = (eh->e_flags & EF_ARM_BE8) != 0;

    /*
     * If the BE-8 model is supported, CPSR[7] will be clear.
     * If the BE-32 model is supported, CPSR[7] will be set.
     */
    register_t ctl = armreg_sctlr_read();
    if (((ctl & CPU_CONTROL_BEND_ENABLE) != 0) == be8_p)
        return ENOEXEC;
#endif /* __ARMEB__ */

    /*
     * This is subtle.  If we are netbsd32, then we don't want to match the
     * same ABI as the kernel.  If we aren't (netbsd32 == false), then we
     * don't want to be different from the kernel's ABI.
     *    true   true   true  ENOEXEC
     *    true   false  true  0
     *    true   true   false 0
     *    true   false  false ENOEXEC
     *    false  true   true  0
     *    false  false  true  ENOEXEC
     *    false  true   false ENOEXEC
     *    false  false  false 0
     */
    if (netbsd32_p ^ elf_aapcs_p ^ aapcs_p)
        return ENOEXEC;

    if (netbsd32_p)
        itp_suffix = (elf_aapcs_p) ? "eabi" : "oabi";

    if (itp_suffix != NULL)
        (void)compat_elf_check_interp(epp, itp, itp_suffix);

    /*
     * Copy (if any) the machine_arch of the executable to the proc.
     */
    if (epp->ep_machine_arch[0] != 0) {
        strlcpy(l->l_proc->p_md.md_march, epp->ep_machine_arch,
                sizeof(l->l_proc->p_md.md_march));
    }

    /*
     * If we are AAPCS (EABI) and armv6/armv7, we want alignment faults
     * to be off.
     */
    if (aapcs_p && (CPU_IS_ARMV7_P() || CPU_IS_ARMV6_P())) {
        l->l_md.md_flags |= MDLWP_NOALIGNFLT;
    } else {
        l->l_md.md_flags &= ~MDLWP_NOALIGNFLT;
    }
    return 0;
}