On Fri, Dec 27, 2019 at 04:07:03AM +0000, Justin Hibbits wrote:
> 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. */
Arguably these definitions must be in powerpc/include/elf.h.
Then you could use symbolic names in the rtld hack.

Ideally the rtld hack would be moved to powerpc64 subdirectory as well,
by providing an inline function, trivial on other arches.

> +
> +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__ */
And this must be moved to powerpc/powerpc/elf_machdep.c by providing
MD variant of sv_fixup, instead of contaminating the MI code.

>  
>       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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to