Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Dec 2019 15:49:20 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Justin Hibbits <jhibbits@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r356113 - in head: libexec/rtld-elf sys/kern sys/sys
Message-ID:  <20191227134920.GL23031@kib.kiev.ua>
In-Reply-To: <201912270407.xBR473Zh054687@repo.freebsd.org>
References:  <201912270407.xBR473Zh054687@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20191227134920.GL23031>