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
This commit is contained in:
parent
e4399d169a
commit
adea0d6368
@ -382,6 +382,9 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
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,8 +410,29 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
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);
|
||||
init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr, aux_info);
|
||||
|
@ -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)
|
||||
{
|
||||
@ -1383,6 +1479,11 @@ __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--;
|
||||
if (suword(base, imgp->args->argc) == -1)
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user