Index: sys/sys/imgact.h =================================================================== RCS file: /usr/home/ncvs/src/sys/sys/imgact.h,v retrieving revision 1.40 diff -u -r1.40 imgact.h --- sys/sys/imgact.h 15 Aug 2006 12:10:57 -0000 1.40 +++ sys/sys/imgact.h 11 Jul 2008 19:08:06 -0000 @@ -59,6 +59,7 @@ char interpreted; /* flag - this executable is interpreted */ char *interpreter_name; /* name of the interpreter */ void *auxargs; /* ELF Auxinfo structure pointer */ + char *machine; /* ELF Auxinfo AT_PLATFORM pointer */ struct sf_buf *firstpage; /* first page that we mapped */ unsigned long ps_strings; /* PS_STRINGS for BSD/OS binaries */ size_t auxarg_size; Index: sys/i386/include/elf.h =================================================================== RCS file: /usr/home/ncvs/src/sys/i386/include/elf.h,v retrieving revision 1.17 diff -u -r1.17 elf.h --- sys/i386/include/elf.h 4 Oct 2006 21:37:09 -0000 1.17 +++ sys/i386/include/elf.h 11 Jul 2008 11:20:03 -0000 @@ -104,8 +104,12 @@ #define AT_EUID 12 /* Effective uid. */ #define AT_GID 13 /* Real gid. */ #define AT_EGID 14 /* Effective gid. */ +#define AT_PLATFORM 15 /* CPU identification string. */ +#define AT_HWCAP 16 /* CPU capabilities (arch dependent). */ +#define AT_CLKTCK 17 /* Frequency at which times() increments */ +#define AT_SECURE 23 /* Secure mode */ -#define AT_COUNT 15 /* Count of defined aux entry types. */ +#define AT_COUNT 18 /* Count of defined aux entry types. */ /* * Relocation types. Index: sys/i386/linux/linux.h =================================================================== RCS file: /usr/home/ncvs/src/sys/i386/linux/linux.h,v retrieving revision 1.78 diff -u -r1.78 linux.h --- sys/i386/linux/linux.h 18 Sep 2007 19:50:33 -0000 1.78 +++ sys/i386/linux/linux.h 11 Jul 2008 09:52:51 -0000 @@ -309,6 +309,7 @@ int linux_to_bsd_sigaltstack(int lsa); int bsd_to_linux_sigaltstack(int bsa); +void linux_get_machine(struct l_new_utsname *utsname); typedef void (*l_handler_t)(l_int); typedef l_ulong l_osigset_t; Index: sys/i386/linux/linux_machdep.c =================================================================== RCS file: /usr/home/ncvs/src/sys/i386/linux/linux_machdep.c,v retrieving revision 1.78.2.2 diff -u -r1.78.2.2 linux_machdep.c --- sys/i386/linux/linux_machdep.c 14 Feb 2008 18:37:39 -0000 1.78.2.2 +++ sys/i386/linux/linux_machdep.c 11 Jul 2008 09:57:02 -0000 @@ -971,6 +971,27 @@ return (error); } +void +linux_get_machine(struct l_new_utsname *utsname) +{ + const char *class; + + switch (cpu_class) { + case CPUCLASS_686: + class = "i686"; + break; + case CPUCLASS_586: + class = "i586"; + break; + case CPUCLASS_486: + class = "i486"; + break; + default: + class = "i386"; + } + strlcpy(utsname->machine, class, LINUX_MAX_UTSNAME); +} + /* * Linux has two extra args, restart and oldmask. We dont use these, * but it seems that "restart" is actually a context pointer that Index: sys/i386/linux/linux_sysvec.c =================================================================== RCS file: /usr/home/ncvs/src/sys/i386/linux/linux_sysvec.c,v retrieving revision 1.150.2.1 diff -u -r1.150.2.1 linux_sysvec.c --- sys/i386/linux/linux_sysvec.c 27 Mar 2008 13:46:27 -0000 1.150.2.1 +++ sys/i386/linux/linux_sysvec.c 11 Jul 2008 19:29:58 -0000 @@ -260,6 +260,11 @@ AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); + AUXARGS_ENTRY(pos, AT_HWCAP, cpu_feature); + AUXARGS_ENTRY(pos, AT_PLATFORM, + (long)(intptr_t)imgp->machine); + AUXARGS_ENTRY(pos, AT_CLKTCK, hz); + AUXARGS_ENTRY(pos, AT_SECURE, 0); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); @@ -812,6 +817,126 @@ fldcw(&control); } +/* + * Copied from exec_copyout_strings XXX + */ +static register_t * +linux_copyout_strings(imgp) + struct image_params *imgp; +{ + int argc, envc; + char **vectp; + char *stringp, *destp; + register_t *stack_base; + struct ps_strings *arginfo; + struct proc *p; + int szsigcode, machsz; + struct l_new_utsname utsname; + + /* + * Calculate string base and vector table pointers. + * Also deal with signal trampoline code for this exec type. + */ + p = imgp->proc; + szsigcode = 0; + arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; + if (p->p_sysent->sv_szsigcode != NULL) + szsigcode = *(p->p_sysent->sv_szsigcode); + linux_get_machine(&utsname); + machsz = roundup(strlen(utsname.machine) + 1, sizeof(char *)); + imgp->machine = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - machsz; + destp = imgp->machine - roundup((ARG_MAX - imgp->args->stringspace), + sizeof(char *)); + + /* + * install sigcode + */ + if (szsigcode) + copyout(p->p_sysent->sv_sigcode, ((caddr_t)arginfo - + szsigcode), szsigcode); + + copyout(utsname.machine, imgp->machine, strlen(utsname.machine) + 1); + + /* + * If we have a valid auxargs ptr, prepare some room + * on the stack. + */ + if (imgp->auxargs) { + /* + * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for + * lower compatibility. + */ + imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size : + (AT_COUNT * 2); + /* + * The '+ 2' is for the null pointers at the end of each of + * the arg and env vector sets,and imgp->auxarg_size is room + * for argument of Runtime loader. + */ + vectp = (char **)(destp - (imgp->args->argc + + imgp->args->envc + 2 + imgp->auxarg_size) * + sizeof(char *)); + + } else { + /* + * The '+ 2' is for the null pointers at the end of each of + * the arg and env vector sets + */ + vectp = (char **)(destp - (imgp->args->argc + imgp->args->envc + 2) * + sizeof(char *)); + } + + /* + * vectp also becomes our initial stack base + */ + stack_base = (register_t *)vectp; + + stringp = imgp->args->begin_argv; + argc = imgp->args->argc; + envc = imgp->args->envc; + + /* + * Copy out strings - arguments and environment. + */ + copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); + + /* + * Fill in "ps_strings" struct for ps, w, etc. + */ + suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp); + suword(&arginfo->ps_nargvstr, argc); + + /* + * Fill in argument portion of vector table. + */ + for (; argc > 0; --argc) { + suword(vectp++, (long)(intptr_t)destp); + while (*stringp++ != 0) + destp++; + destp++; + } + + /* a null vector table pointer separates the argp's from the envp's */ + suword(vectp++, 0); + + suword(&arginfo->ps_envstr, (long)(intptr_t)vectp); + suword(&arginfo->ps_nenvstr, envc); + + /* + * Fill in environment portion of vector table. + */ + for (; envc > 0; --envc) { + suword(vectp++, (long)(intptr_t)destp); + while (*stringp++ != 0) + destp++; + destp++; + } + + /* end of vector table is a null pointer */ + suword(vectp, 0); + + return (stack_base); +} struct sysentvec linux_sysvec = { LINUX_SYS_MAXSYSCALL, linux_sysent, @@ -836,7 +961,7 @@ USRSTACK, PS_STRINGS, VM_PROT_ALL, - exec_copyout_strings, + linux_copyout_strings, exec_linux_setregs, NULL }; Index: sys/amd64/include/elf.h =================================================================== RCS file: /usr/home/ncvs/src/sys/amd64/include/elf.h,v retrieving revision 1.19 diff -u -r1.19 elf.h --- sys/amd64/include/elf.h 4 Oct 2006 21:37:09 -0000 1.19 +++ sys/amd64/include/elf.h 11 Jul 2008 08:53:56 -0000 @@ -101,8 +101,12 @@ #define AT_EUID 12 /* Effective uid. */ #define AT_GID 13 /* Real gid. */ #define AT_EGID 14 /* Effective gid. */ +#define AT_PLATFORM 15 /* CPU identification string. */ +#define AT_HWCAP 16 /* CPU capabilities (arch dependent). */ +#define AT_CLKTCK 17 /* Frequency at which times() increments */ +#define AT_SECURE 23 /* Secure mode */ -#define AT_COUNT 15 /* Count of defined aux entry types. */ +#define AT_COUNT 18 /* Count of defined aux entry types. */ /* * Relocation types. Index: sys/amd64/linux32/linux.h =================================================================== RCS file: /usr/home/ncvs/src/sys/amd64/linux32/linux.h,v retrieving revision 1.16 diff -u -r1.16 linux.h --- sys/amd64/linux32/linux.h 18 Sep 2007 19:50:32 -0000 1.16 +++ sys/amd64/linux32/linux.h 11 Jul 2008 09:47:58 -0000 @@ -334,6 +334,7 @@ int linux_to_bsd_sigaltstack(int lsa); int bsd_to_linux_sigaltstack(int bsa); +void linux_get_machine(struct l_new_utsname *utsname); typedef l_uintptr_t l_handler_t; typedef l_ulong l_osigset_t; Index: sys/amd64/linux32/linux32_machdep.c =================================================================== RCS file: /usr/home/ncvs/src/sys/amd64/linux32/linux32_machdep.c,v retrieving revision 1.45.2.1 diff -u -r1.45.2.1 linux32_machdep.c --- sys/amd64/linux32/linux32_machdep.c 14 Feb 2008 18:37:38 -0000 1.45.2.1 +++ sys/amd64/linux32/linux32_machdep.c 11 Jul 2008 09:51:41 -0000 @@ -103,6 +103,13 @@ return (lsa); } +void +linux_get_machine(struct l_new_utsname *utsname) +{ + /* XXX Linux can change 'personality'. */ + strlcpy(utsname->machine, "i686", LINUX_MAX_UTSNAME); +} + /* * Custom version of exec_copyin_args() so that we can translate * the pointers. Index: sys/amd64/linux32/linux32_sysvec.c =================================================================== RCS file: /usr/home/ncvs/src/sys/amd64/linux32/linux32_sysvec.c,v retrieving revision 1.31.2.1 diff -u -r1.31.2.1 linux32_sysvec.c --- sys/amd64/linux32/linux32_sysvec.c 27 Mar 2008 13:46:26 -0000 1.31.2.1 +++ sys/amd64/linux32/linux32_sysvec.c 11 Jul 2008 19:12:18 -0000 @@ -269,6 +269,11 @@ AUXARGS_ENTRY_32(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); AUXARGS_ENTRY_32(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); AUXARGS_ENTRY_32(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); + AUXARGS_ENTRY_32(pos, AT_HWCAP, cpu_feature); + AUXARGS_ENTRY_32(pos, AT_PLATFORM, + (u_int32_t)(intptr_t)imgp->machine); + AUXARGS_ENTRY_32(pos, AT_CLKTCK, hz); + AUXARGS_ENTRY_32(pos, AT_SECURE, 0); AUXARGS_ENTRY_32(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); @@ -858,16 +863,20 @@ char *stringp, *destp; u_int32_t *stack_base; struct linux32_ps_strings *arginfo; - int sigcodesz; + int sigcodesz, machsz; + struct l_new_utsname utsname; + linux_get_machine(&utsname); /* * Calculate string base and vector table pointers. * Also deal with signal trampoline code for this exec type. */ arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS; sigcodesz = *(imgp->proc->p_sysent->sv_szsigcode); - destp = (caddr_t)arginfo - sigcodesz - SPARE_USRSPACE - - roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); + machsz = roundup(strlen(utsname.machine) + 1, sizeof(char *)); + imgp->machine = (caddr_t)arginfo - sigcodesz - SPARE_USRSPACE - machsz; + destp = imgp->machine - roundup((ARG_MAX - imgp->args->stringspace), + sizeof(char *)); /* * install sigcode @@ -876,6 +885,8 @@ copyout(imgp->proc->p_sysent->sv_sigcode, ((caddr_t)arginfo - sigcodesz), sigcodesz); + copyout(utsname.machine, imgp->machine, strlen(utsname.machine) + 1); + /* * If we have a valid auxargs ptr, prepare some room * on the stack.