From owner-svn-src-all@freebsd.org Fri Dec 27 04:07:04 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id BFB1A1E1CD5; Fri, 27 Dec 2019 04:07:04 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47kYDm4WBbz4ftl; Fri, 27 Dec 2019 04:07:04 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 95DB2B33B; Fri, 27 Dec 2019 04:07:04 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xBR474SE054691; Fri, 27 Dec 2019 04:07:04 GMT (envelope-from jhibbits@FreeBSD.org) Received: (from jhibbits@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xBR473Zh054687; Fri, 27 Dec 2019 04:07:03 GMT (envelope-from jhibbits@FreeBSD.org) Message-Id: <201912270407.xBR473Zh054687@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhibbits set sender to jhibbits@FreeBSD.org using -f From: Justin Hibbits Date: Fri, 27 Dec 2019 04:07:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r356113 - in head: libexec/rtld-elf sys/kern sys/sys X-SVN-Group: head X-SVN-Commit-Author: jhibbits X-SVN-Commit-Paths: in head: libexec/rtld-elf sys/kern sys/sys X-SVN-Commit-Revision: 356113 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Dec 2019 04:07:04 -0000 Author: jhibbits Date: Fri Dec 27 04:07:03 2019 New Revision: 356113 URL: https://svnweb.freebsd.org/changeset/base/356113 Log: Eliminate the last MI difference in AT_* definitions (for powerpc). Summary: As a transition aide, implement an alternative elfN_freebsd_fixup which is called for old powerpc binaries. Similarly, add a translation to rtld to convert old values to new ones (as expected by a new rtld). Translation of old<->new values is incomplete, but sufficient to allow an installworld of a new userspace from an old one when a new kernel is running. Test Plan: Someone needs to see how a new kernel/rtld/libc works with an old binary. If if works we can probalby ship this. If not we probalby need some more compat bits. Submitted by: brooks Reviewed by: jhibbits Differential Revision: https://reviews.freebsd.org/D20799 Modified: head/libexec/rtld-elf/rtld.c head/sys/kern/imgact_elf.c head/sys/sys/elf_common.h head/sys/sys/param.h Modified: head/libexec/rtld-elf/rtld.c ============================================================================== --- head/libexec/rtld-elf/rtld.c Fri Dec 27 04:00:04 2019 (r356112) +++ head/libexec/rtld-elf/rtld.c Fri Dec 27 04:07:03 2019 (r356113) @@ -382,6 +382,9 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entr caddr_t imgentry; char buf[MAXPATHLEN]; int argc, fd, i, phnum, rtld_argc; +#ifdef __powerpc__ + int old_auxv_format = 1; +#endif bool dir_enable, explicit_fd, search_in_path; /* @@ -407,7 +410,28 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entr for (auxp = aux; auxp->a_type != AT_NULL; auxp++) { if (auxp->a_type < AT_COUNT) aux_info[auxp->a_type] = auxp; +#ifdef __powerpc__ + if (auxp->a_type == 23) /* AT_STACKPROT */ + old_auxv_format = 0; +#endif } + +#ifdef __powerpc__ + if (old_auxv_format) { + /* Remap from old-style auxv numbers. */ + aux_info[23] = aux_info[21]; /* AT_STACKPROT */ + aux_info[21] = aux_info[19]; /* AT_PAGESIZESLEN */ + aux_info[19] = aux_info[17]; /* AT_NCPUS */ + aux_info[17] = aux_info[15]; /* AT_CANARYLEN */ + aux_info[15] = aux_info[13]; /* AT_EXECPATH */ + aux_info[13] = NULL; /* AT_GID */ + + aux_info[20] = aux_info[18]; /* AT_PAGESIZES */ + aux_info[18] = aux_info[16]; /* AT_OSRELDATE */ + aux_info[16] = aux_info[14]; /* AT_CANARY */ + aux_info[14] = NULL; /* AT_EGID */ + } +#endif /* Initialize and relocate ourselves. */ assert(aux_info[AT_BASE] != NULL); Modified: head/sys/kern/imgact_elf.c ============================================================================== --- head/sys/kern/imgact_elf.c Fri Dec 27 04:00:04 2019 (r356112) +++ head/sys/kern/imgact_elf.c Fri Dec 27 04:07:03 2019 (r356113) @@ -1323,6 +1323,102 @@ ret: #define suword __CONCAT(suword, __ELF_WORD_SIZE) +#ifdef __powerpc__ +#define OLD_AT_NULL AT_NULL +#define OLD_AT_IGNORE AT_IGNORE +#define OLD_AT_EXECFD AT_EXECFD +#define OLD_AT_PHDR AT_PHDR +#define OLD_AT_PHENT AT_PHENT +#define OLD_AT_PHNUM AT_PHNUM +#define OLD_AT_PAGESZ AT_PAGESZ +#define OLD_AT_BASE AT_BASE +#define OLD_AT_FLAGS AT_FLAGS +#define OLD_AT_ENTRY AT_ENTRY +#define OLD_AT_NOTELF AT_NOTELF +#define OLD_AT_UID AT_UID +#define OLD_AT_EUID AT_EUID +#define OLD_AT_EXECPATH 13 +#define OLD_AT_CANARY 14 +#define OLD_AT_CANARYLEN 15 +#define OLD_AT_OSRELDATE 16 +#define OLD_AT_NCPUS 17 +#define OLD_AT_PAGESIZES 18 +#define OLD_AT_PAGESIZESLEN 19 +#define OLD_AT_STACKPROT 21 +#define OLD_AT_TIMEKEEP AT_TIMEKEEP +#define OLD_AT_EHDRFLAGS AT_EHDRFLAGS +#define OLD_AT_HWCAP AT_HWCAP +#define OLD_AT_HWCAP2 AT_HWCAP2 + +#define OLD_AT_COUNT 27 /* Count of defined aux entry types. */ + +static int +__elfN(freebsd_fixup_old_auxargs)(register_t **stack_base, + struct image_params *imgp) +{ + Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; + Elf_Auxinfo *argarray, *pos; + Elf_Addr *base, *auxbase; + int error; + + base = (Elf_Addr *)*stack_base; + auxbase = base + imgp->args->argc + 1 + imgp->args->envc + 1; + argarray = pos = malloc(OLD_AT_COUNT * sizeof(*pos), M_TEMP, + M_WAITOK | M_ZERO); + + if (args->execfd != -1) + AUXARGS_ENTRY(pos, OLD_AT_EXECFD, args->execfd); + AUXARGS_ENTRY(pos, OLD_AT_PHDR, args->phdr); + AUXARGS_ENTRY(pos, OLD_AT_PHENT, args->phent); + AUXARGS_ENTRY(pos, OLD_AT_PHNUM, args->phnum); + AUXARGS_ENTRY(pos, OLD_AT_PAGESZ, args->pagesz); + AUXARGS_ENTRY(pos, OLD_AT_FLAGS, args->flags); + AUXARGS_ENTRY(pos, OLD_AT_ENTRY, args->entry); + AUXARGS_ENTRY(pos, OLD_AT_BASE, args->base); + AUXARGS_ENTRY(pos, OLD_AT_EHDRFLAGS, args->hdr_eflags); + if (imgp->execpathp != 0) + AUXARGS_ENTRY(pos, OLD_AT_EXECPATH, imgp->execpathp); + AUXARGS_ENTRY(pos, OLD_AT_OSRELDATE, + imgp->proc->p_ucred->cr_prison->pr_osreldate); + if (imgp->canary != 0) { + AUXARGS_ENTRY(pos, OLD_AT_CANARY, imgp->canary); + AUXARGS_ENTRY(pos, OLD_AT_CANARYLEN, imgp->canarylen); + } + AUXARGS_ENTRY(pos, OLD_AT_NCPUS, mp_ncpus); + if (imgp->pagesizes != 0) { + AUXARGS_ENTRY(pos, OLD_AT_PAGESIZES, imgp->pagesizes); + AUXARGS_ENTRY(pos, OLD_AT_PAGESIZESLEN, imgp->pagesizeslen); + } + if (imgp->sysent->sv_timekeep_base != 0) { + AUXARGS_ENTRY(pos, OLD_AT_TIMEKEEP, + imgp->sysent->sv_timekeep_base); + } + AUXARGS_ENTRY(pos, OLD_AT_STACKPROT, imgp->sysent->sv_shared_page_obj + != NULL && imgp->stack_prot != 0 ? imgp->stack_prot : + imgp->sysent->sv_stackprot); + if (imgp->sysent->sv_hwcap != NULL) + AUXARGS_ENTRY(pos, OLD_AT_HWCAP, *imgp->sysent->sv_hwcap); + if (imgp->sysent->sv_hwcap2 != NULL) + AUXARGS_ENTRY(pos, OLD_AT_HWCAP2, *imgp->sysent->sv_hwcap2); + AUXARGS_ENTRY(pos, OLD_AT_NULL, 0); + + free(imgp->auxargs, M_TEMP); + imgp->auxargs = NULL; + KASSERT(pos - argarray <= OLD_AT_COUNT, ("Too many auxargs")); + + error = copyout(argarray, auxbase, sizeof(*argarray) * OLD_AT_COUNT); + free(argarray, M_TEMP); + if (error != 0) + return (error); + + base--; + if (suword(base, imgp->args->argc) == -1) + return (EFAULT); + *stack_base = (register_t *)base; + return (0); +} +#endif /* __powerpc__ */ + int __elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t base) { @@ -1382,6 +1478,11 @@ int __elfN(freebsd_fixup)(uintptr_t *stack_base, struct image_params *imgp) { Elf_Addr *base; + +#ifdef __powerpc__ + if (imgp->proc->p_osrel < P_OSREL_POWERPC_NEW_AUX_ARGS) + return (__elfN(freebsd_fixup_old_auxargs)(stack_base, imgp)); +#endif /* __powerpc__ */ base = (Elf_Addr *)*stack_base; base--; Modified: head/sys/sys/elf_common.h ============================================================================== --- head/sys/sys/elf_common.h Fri Dec 27 04:00:04 2019 (r356112) +++ head/sys/sys/elf_common.h Fri Dec 27 04:07:03 2019 (r356113) @@ -935,7 +935,6 @@ typedef struct { #define AT_NOTELF 10 /* Program is not ELF ?? */ #define AT_UID 11 /* Real uid. */ #define AT_EUID 12 /* Effective uid. */ -#ifndef __powerpc__ #define AT_GID 13 /* Real gid. */ #define AT_EGID 14 /* Effective gid. */ #define AT_EXECPATH 15 /* Path to the executable. */ @@ -945,20 +944,8 @@ typedef struct { #define AT_NCPUS 19 /* Number of CPUs. */ #define AT_PAGESIZES 20 /* Pagesizes. */ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ -#else /* defined(__powerpc__) */ -#define AT_EXECPATH 13 -#define AT_CANARY 14 -#define AT_CANARYLEN 15 -#define AT_OSRELDATE 16 -#define AT_NCPUS 17 -#define AT_PAGESIZES 18 -#define AT_PAGESIZESLEN 19 -#define AT_STACKPROT 21 -#endif /* defined(__powerpc__) */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ -#ifndef __powerpc__ #define AT_STACKPROT 23 /* Initial stack protection. */ -#endif #define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ #define AT_HWCAP 25 /* CPU feature flags. */ #define AT_HWCAP2 26 /* CPU feature flags 2. */ Modified: head/sys/sys/param.h ============================================================================== --- head/sys/sys/param.h Fri Dec 27 04:00:04 2019 (r356112) +++ head/sys/sys/param.h Fri Dec 27 04:07:03 2019 (r356113) @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300069 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300070 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, @@ -90,6 +90,7 @@ #define P_OSREL_VMTOTAL64 1200054 #define P_OSREL_CK_SUPERBLOCK 1300000 #define P_OSREL_CK_INODE 1300005 +#define P_OSREL_POWERPC_NEW_AUX_ARGS 1300070 #define P_OSREL_MAJOR(x) ((x) / 100000) #endif