Index: lib/libc/gen/auxv.c =================================================================== --- lib/libc/gen/auxv.c +++ lib/libc/gen/auxv.c @@ -70,7 +70,7 @@ static int pagesize, osreldate, canary_len, ncpus, pagesizes_len, bsdflags; static int hwcap_present, hwcap2_present; static char *canary, *pagesizes, *execpath; -static void *timekeep; +static void *ps_strings, *timekeep; static u_long hwcap, hwcap2; #ifdef __powerpc__ @@ -135,6 +135,10 @@ case AT_TIMEKEEP: timekeep = aux->a_un.a_ptr; break; + + case AT_PS_STRINGS: + ps_strings = aux->a_un.a_ptr; + break; #ifdef __powerpc__ /* * Since AT_STACKPROT is always set, and the common @@ -337,6 +341,16 @@ } else res = EINVAL; break; + case AT_PS_STRINGS: + if (buflen == sizeof(void *)) { + if (ps_strings != NULL) { + *(void **)buf = ps_strings; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; default: res = ENOENT; break; Index: lib/libc/gen/setproctitle.c =================================================================== --- lib/libc/gen/setproctitle.c +++ lib/libc/gen/setproctitle.c @@ -20,6 +20,7 @@ #include "namespace.h" #include +#include #include #include @@ -112,6 +113,10 @@ /* Nothing to restore */ return (NULL); + if (ps_strings == NULL) + (void)_elf_aux_info(AT_PS_STRINGS, &ps_strings, + sizeof(ps_strings)); + if (ps_strings == NULL) { len = sizeof(ul_ps_strings); if (sysctlbyname("kern.ps_strings", &ul_ps_strings, &len, NULL, @@ -120,6 +125,9 @@ ps_strings = (struct ps_strings *)ul_ps_strings; } + if (ps_strings == NULL) + return (NULL); + /* * PS_STRINGS points to zeroed memory on a style #2 kernel. * Should not happen. Index: sys/amd64/ia32/ia32_signal.c =================================================================== --- sys/amd64/ia32/ia32_signal.c +++ sys/amd64/ia32/ia32_signal.c @@ -961,7 +961,7 @@ regs->tf_rflags = PSL_USER | saved_rflags; regs->tf_ss = _udatasel; regs->tf_cs = _ucode32sel; - regs->tf_rbx = imgp->ps_strings; + regs->tf_rbx = (register_t)imgp->ps_strings; regs->tf_ds = _udatasel; regs->tf_es = _udatasel; regs->tf_fs = _ufssel; Index: sys/amd64/linux32/linux32_sysvec.c =================================================================== --- sys/amd64/linux32/linux32_sysvec.c +++ sys/amd64/linux32/linux32_sysvec.c @@ -708,7 +708,7 @@ regs->tf_ss = _udatasel; regs->tf_flags = TF_HASSEGS; regs->tf_cs = _ucode32sel; - regs->tf_rbx = imgp->ps_strings; + regs->tf_rbx = (register_t)imgp->ps_strings; fpstate_drop(td); Index: sys/compat/freebsd32/freebsd32_misc.c =================================================================== --- sys/compat/freebsd32/freebsd32_misc.c +++ sys/compat/freebsd32/freebsd32_misc.c @@ -3142,6 +3142,7 @@ execpath_len = 0; arginfo = (struct freebsd32_ps_strings *)curproc->p_sysent-> sv_psstrings; + imgp->ps_strings = arginfo; if (imgp->proc->p_sysent->sv_sigcode_base == 0) szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); else @@ -3241,6 +3242,7 @@ /* * Fill in "ps_strings" struct for ps, w, etc. */ + imgp->argv = vectp; if (suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp) != 0 || suword32(&arginfo->ps_nargvstr, argc) != 0) return (EFAULT); @@ -3260,6 +3262,7 @@ if (suword32(vectp++, 0) != 0) return (EFAULT); + imgp->envv = vectp; if (suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp) != 0 || suword32(&arginfo->ps_nenvstr, envc) != 0) return (EFAULT); Index: sys/kern/imgact_aout.c =================================================================== --- sys/kern/imgact_aout.c +++ sys/kern/imgact_aout.c @@ -200,7 +200,7 @@ file_offset = 0; /* Pass PS_STRINGS for BSD/OS binaries only. */ if (N_GETMID(*a_out) == MID_ZERO) - imgp->ps_strings = aout_sysvec.sv_psstrings; + imgp->ps_strings = (void *)aout_sysvec.sv_psstrings; break; default: /* NetBSD compatibility */ Index: sys/kern/imgact_elf.c =================================================================== --- sys/kern/imgact_elf.c +++ sys/kern/imgact_elf.c @@ -1374,6 +1374,11 @@ AUXARGS_ENTRY(pos, AT_HWCAP2, *imgp->sysent->sv_hwcap2); AUXARGS_ENTRY(pos, AT_BSDFLAGS, __elfN(sigfastblock) ? ELF_BSDF_SIGFASTBLK : 0); + AUXARGS_ENTRY(pos, AT_ARGC, imgp->args->argc); + AUXARGS_ENTRY_PTR(pos, AT_ARGV, imgp->argv); + AUXARGS_ENTRY(pos, AT_ENVC, imgp->args->envc); + AUXARGS_ENTRY_PTR(pos, AT_ENVV, imgp->envv); + AUXARGS_ENTRY_PTR(pos, AT_PS_STRINGS, imgp->ps_strings); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); Index: sys/kern/kern_exec.c =================================================================== --- sys/kern/kern_exec.c +++ sys/kern/kern_exec.c @@ -1546,6 +1546,7 @@ p = imgp->proc; szsigcode = 0; arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; + imgp->ps_strings = arginfo; if (p->p_sysent->sv_sigcode_base == 0) { if (p->p_sysent->sv_szsigcode != NULL) szsigcode = *(p->p_sysent->sv_szsigcode); @@ -1645,6 +1646,7 @@ /* * Fill in "ps_strings" struct for ps, w, etc. */ + imgp->argv = vectp; if (suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp) != 0 || suword32(&arginfo->ps_nargvstr, argc) != 0) return (EFAULT); @@ -1664,6 +1666,7 @@ if (suword(vectp++, 0) != 0) return (EFAULT); + imgp->envv = vectp; if (suword(&arginfo->ps_envstr, (long)(intptr_t)vectp) != 0 || suword32(&arginfo->ps_nenvstr, envc) != 0) return (EFAULT); Index: sys/sys/elf_common.h =================================================================== --- sys/sys/elf_common.h +++ sys/sys/elf_common.h @@ -956,8 +956,13 @@ #define AT_HWCAP 25 /* CPU feature flags. */ #define AT_HWCAP2 26 /* CPU feature flags 2. */ #define AT_BSDFLAGS 27 /* ELF BSD Flags. */ +#define AT_ARGC 28 /* Argument count */ +#define AT_ARGV 29 /* Argument vector */ +#define AT_ENVC 30 /* Environment count */ +#define AT_ENVV 31 /* Environment vector */ +#define AT_PS_STRINGS 32 /* struct ps_strings */ -#define AT_COUNT 28 /* Count of defined aux entry types. */ +#define AT_COUNT 33 /* Count of defined aux entry types. */ /* * Relocation types. Index: sys/sys/imgact.h =================================================================== --- sys/sys/imgact.h +++ sys/sys/imgact.h @@ -75,9 +75,11 @@ char *interpreter_name; /* name of the interpreter */ void *auxargs; /* ELF Auxinfo structure pointer */ struct sf_buf *firstpage; /* first page that we mapped */ - unsigned long ps_strings; /* PS_STRINGS for BSD/OS binaries */ + void *ps_strings; /* pointer to ps_string (user space) */ struct image_args *args; /* system call arguments */ struct sysentvec *sysent; /* system entry vector */ + void *argv; /* pointer to argv (user space) */ + void *envv; /* pointer to envv (user space) */ char *execpath; unsigned long execpathp; char *freepath; Index: sys/sys/imgact_elf.h =================================================================== --- sys/sys/imgact_elf.h +++ sys/sys/imgact_elf.h @@ -39,6 +39,13 @@ #define AUXARGS_ENTRY(pos, id, val) \ {(pos)->a_type = (id); (pos)->a_un.a_val = (val); (pos)++;} +#if (defined(__LP64__) && __ELF_WORD_SIZE == 32) +#define AUXARGS_ENTRY_PTR(pos, id, ptr) \ + {(pos)->a_type = (id); (pos)->a_un.a_val = (uintptr_t)(ptr); (pos)++;} +#else +#define AUXARGS_ENTRY_PTR(pos, id, ptr) \ + {(pos)->a_type = (id); (pos)->a_un.a_ptr = (ptr); (pos)++;} +#endif struct image_params; struct thread; Index: usr.bin/procstat/procstat_auxv.c =================================================================== --- usr.bin/procstat/procstat_auxv.c +++ usr.bin/procstat/procstat_auxv.c @@ -202,6 +202,36 @@ xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_BSDFLAGS/%#lx}\n", prefix, "AT_BSDFLAGS", (u_long)auxv[i].a_un.a_val); break; +#endif +#ifdef AT_ARGC + case AT_ARGC: + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ARGC/%ld}\n", + prefix, "AT_ARGC", (long)auxv[i].a_un.a_val); + break; +#endif +#ifdef AT_ARGV + case AT_ARGV: + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ARGV/%p}\n", + prefix, "AT_ARGV", auxv[i].a_un.a_ptr); + break; +#endif +#ifdef AT_ENVC + case AT_ENVC: + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENVC/%ld}\n", + prefix, "AT_ENVC", (long)auxv[i].a_un.a_val); + break; +#endif +#ifdef AT_ENVV + case AT_ENVV: + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENVV/%p}\n", + prefix, "AT_ENVV", auxv[i].a_un.a_ptr); + break; +#endif +#ifdef AT_PS_STRINGS + case AT_PS_STRINGS: + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PS_STRINGS/%p}\n", + prefix, "AT_PS_STRINGS", auxv[i].a_un.a_ptr); + break; #endif default: xo_emit("{dw:/%s}{Lw:/%16ld/%ld}{:UNKNOWN/%#lx}\n",