Index: head/sys/amd64/amd64/elf_machdep.c =================================================================== --- head/sys/amd64/amd64/elf_machdep.c +++ head/sys/amd64/amd64/elf_machdep.c @@ -68,6 +68,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_ALL, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_fixlimit = NULL, Index: head/sys/arm/arm/elf_machdep.c =================================================================== --- head/sys/arm/arm/elf_machdep.c +++ head/sys/arm/arm/elf_machdep.c @@ -75,6 +75,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_ALL, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_fixlimit = NULL, Index: head/sys/arm64/arm64/elf32_machdep.c =================================================================== --- head/sys/arm64/arm64/elf32_machdep.c +++ head/sys/arm64/arm64/elf32_machdep.c @@ -92,6 +92,7 @@ .sv_usrstack = FREEBSD32_USRSTACK, .sv_psstrings = FREEBSD32_PS_STRINGS, .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, + .sv_copyout_auxargs = elf32_freebsd_copyout_auxargs, .sv_copyout_strings = freebsd32_copyout_strings, .sv_setregs = freebsd32_setregs, .sv_fixlimit = NULL, // XXX Index: head/sys/arm64/arm64/elf_machdep.c =================================================================== --- head/sys/arm64/arm64/elf_machdep.c +++ head/sys/arm64/arm64/elf_machdep.c @@ -76,6 +76,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_fixlimit = NULL, Index: head/sys/compat/freebsd32/freebsd32_misc.c =================================================================== --- head/sys/compat/freebsd32/freebsd32_misc.c +++ head/sys/compat/freebsd32/freebsd32_misc.c @@ -3195,14 +3195,8 @@ if (imgp->sysent->sv_stackgap != NULL) imgp->sysent->sv_stackgap(imgp, (u_long *)&vectp); - if (imgp->auxargs) { - /* - * Allocate room on the stack for the ELF auxargs - * array. It has up to AT_COUNT entries. - */ - vectp -= howmany(AT_COUNT * sizeof(Elf32_Auxinfo), - sizeof(*vectp)); - } + if (imgp->auxargs) + imgp->sysent->sv_copyout_auxargs(imgp, (u_long *)&vectp); /* * Allocate room for the argv[] and env vectors including the Index: head/sys/compat/ia32/ia32_sysvec.c =================================================================== --- head/sys/compat/ia32/ia32_sysvec.c +++ head/sys/compat/ia32/ia32_sysvec.c @@ -114,6 +114,7 @@ .sv_usrstack = FREEBSD32_USRSTACK, .sv_psstrings = FREEBSD32_PS_STRINGS, .sv_stackprot = VM_PROT_ALL, + .sv_copyout_auxargs = elf32_freebsd_copyout_auxargs, .sv_copyout_strings = freebsd32_copyout_strings, .sv_setregs = ia32_setregs, .sv_fixlimit = ia32_fixlimit, Index: head/sys/i386/i386/elf_machdep.c =================================================================== --- head/sys/i386/i386/elf_machdep.c +++ head/sys/i386/i386/elf_machdep.c @@ -70,6 +70,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_ALL, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_fixlimit = NULL, Index: head/sys/kern/imgact_elf.c =================================================================== --- head/sys/kern/imgact_elf.c +++ head/sys/kern/imgact_elf.c @@ -1289,7 +1289,7 @@ addr = et_dyn_addr; /* - * Construct auxargs table (used by the fixup routine) + * Construct auxargs table (used by the copyout_auxargs routine) */ elf_auxargs = malloc(sizeof(Elf_Auxargs), M_TEMP, M_NOWAIT); if (elf_auxargs == NULL) { @@ -1323,16 +1323,13 @@ #define suword __CONCAT(suword, __ELF_WORD_SIZE) -int -__elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) +void +__elfN(freebsd_copyout_auxargs)(struct image_params *imgp, u_long *base) { Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; Elf_Auxinfo *argarray, *pos; - Elf_Addr *base, *auxbase; - int error; + u_long auxlen; - base = (Elf_Addr *)*stack_base; - auxbase = base + imgp->args->argc + 1 + imgp->args->envc + 1; argarray = pos = malloc(AT_COUNT * sizeof(*pos), M_TEMP, M_WAITOK | M_ZERO); @@ -1376,11 +1373,18 @@ imgp->auxargs = NULL; KASSERT(pos - argarray <= AT_COUNT, ("Too many auxargs")); - error = copyout(argarray, auxbase, sizeof(*argarray) * AT_COUNT); + auxlen = sizeof(*argarray) * (pos - argarray); + *base -= auxlen; + copyout(argarray, (void *)*base, auxlen); free(argarray, M_TEMP); - if (error != 0) - return (error); +} +int +__elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) +{ + Elf_Addr *base; + + base = (Elf_Addr *)*stack_base; base--; if (suword(base, imgp->args->argc) == -1) return (EFAULT); Index: head/sys/kern/kern_exec.c =================================================================== --- head/sys/kern/kern_exec.c +++ head/sys/kern/kern_exec.c @@ -1637,14 +1637,8 @@ if (imgp->sysent->sv_stackgap != NULL) imgp->sysent->sv_stackgap(imgp, (u_long *)&vectp); - if (imgp->auxargs) { - /* - * Allocate room on the stack for the ELF auxargs - * array. It has up to AT_COUNT entries. - */ - vectp -= howmany(AT_COUNT * sizeof(Elf_Auxinfo), - sizeof(*vectp)); - } + if (imgp->auxargs) + imgp->sysent->sv_copyout_auxargs(imgp, (u_long *)&vectp); /* * Allocate room for the argv[] and env vectors including the Index: head/sys/mips/mips/elf_machdep.c =================================================================== --- head/sys/mips/mips/elf_machdep.c +++ head/sys/mips/mips/elf_machdep.c @@ -71,6 +71,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_ALL, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_fixlimit = NULL, @@ -125,6 +126,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_ALL, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_fixlimit = NULL, Index: head/sys/mips/mips/freebsd32_machdep.c =================================================================== --- head/sys/mips/mips/freebsd32_machdep.c +++ head/sys/mips/mips/freebsd32_machdep.c @@ -94,6 +94,7 @@ .sv_usrstack = FREEBSD32_USRSTACK, .sv_psstrings = FREEBSD32_PS_STRINGS, .sv_stackprot = VM_PROT_ALL, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = freebsd32_copyout_strings, .sv_setregs = freebsd32_exec_setregs, .sv_fixlimit = NULL, Index: head/sys/powerpc/powerpc/elf32_machdep.c =================================================================== --- head/sys/powerpc/powerpc/elf32_machdep.c +++ head/sys/powerpc/powerpc/elf32_machdep.c @@ -87,6 +87,7 @@ .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_sendsig = sendsig, .sv_sigcode = sigcode32, .sv_szsigcode = &szsigcode32, Index: head/sys/powerpc/powerpc/elf64_machdep.c =================================================================== --- head/sys/powerpc/powerpc/elf64_machdep.c +++ head/sys/powerpc/powerpc/elf64_machdep.c @@ -74,6 +74,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_ALL, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs_funcdesc, .sv_fixlimit = NULL, @@ -111,6 +112,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_ALL, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_fixlimit = NULL, Index: head/sys/riscv/riscv/elf_machdep.c =================================================================== --- head/sys/riscv/riscv/elf_machdep.c +++ head/sys/riscv/riscv/elf_machdep.c @@ -79,6 +79,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_fixlimit = NULL, Index: head/sys/sparc64/sparc64/elf_machdep.c =================================================================== --- head/sys/sparc64/sparc64/elf_machdep.c +++ head/sys/sparc64/sparc64/elf_machdep.c @@ -75,6 +75,7 @@ .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, + .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_fixlimit = NULL, Index: head/sys/sys/imgact_elf.h =================================================================== --- head/sys/sys/imgact_elf.h +++ head/sys/sys/imgact_elf.h @@ -99,6 +99,7 @@ int __elfN(coredump)(struct thread *, struct vnode *, off_t, int); size_t __elfN(populate_note)(int, void *, void *, size_t, void **); void __elfN(stackgap)(struct image_params *, u_long *); +void __elfN(freebsd_copyout_auxargs)(struct image_params *, u_long *); /* Machine specific function to dump per-thread information. */ void __elfN(dump_thread)(struct thread *, void *, size_t *); Index: head/sys/sys/sysent.h =================================================================== --- head/sys/sys/sysent.h +++ head/sys/sys/sysent.h @@ -110,6 +110,7 @@ /* function to dump core, or NULL */ int (*sv_imgact_try)(struct image_params *); void (*sv_stackgap)(struct image_params *, u_long *); + void (*sv_copyout_auxargs)(struct image_params *, u_long *); int sv_minsigstksz; /* minimum signal stack size */ vm_offset_t sv_minuser; /* VM_MIN_ADDRESS */ vm_offset_t sv_maxuser; /* VM_MAXUSER_ADDRESS */