Removing some cruft...

Chagin Dmitry dchagin at freebsd.org
Wed Dec 17 09:38:50 PST 2008


On Tue, Dec 16, 2008 at 04:16:38PM -0700, M. Warner Losh wrote:
> In message: <20081216212746.GA28834 at freebsd.org>
>             Roman Divacky <rdivacky at freebsd.org> writes:
> : On Tue, Dec 16, 2008 at 01:18:45PM -0700, M. Warner Losh wrote:
> : > I was looking at the MIPS elf stuff based on a submission of some
> : > 64-bit support.  In doing so, I discovered a number of 'unused' types
> : > that appear to have comments that indicate that they can be removed
> : > now and were just slavishly copied from arch to arch to arch.
> : > 
> : > /*
> : >  * The following non-standard values are used for passing information
> : >  * from John Polstra's testbed program to the dynamic linker.  These
> : >  * are expected to go away soon.
> : >  *
> : >  * Unfortunately, these overlap the Linux non-standard values, so they
> : >  * must not be used in the same context.
> : >  */
> : > #define	AT_BRK		10	/* Starting point for sbrk and brk. */
> : > #define	AT_DEBUG	11	/* Debugging level. */
> : > 
> : > These have be slavishly copied to arm, powerpc, sparc64, ia64, mips,
> : > sun4v and amd64.  All these files have nearly identical comments
> : > (except powerpc, which changes the value).
> : > 
> : > The only place these are used in the kernel is in the Linux!
> : > emulation in i386/linux/linux_sysvec.c and
> : > amd64/linux32/linux32_sysvec.c:
> : > 
> : > 	if (args->trace)
> : > 		AUXARGS_ENTRY(pos, AT_DEBUG, 1);
> : > 
> : > Since AT_DEBUG and AT_UID have the same value, and we look at AT_UID
> : > later, we wind up passing the wrong value for AT_UID.  Fortunately, we
> : > don't use AT_UID for anything in the tree....
> : 
> : I cannot find any reference of AT_DEBUG in linux 2.6.16 sources and it
> : indeed looks bogus...
> 
> What do you think of the following patch?
> 
> Warner
> 

Hi, I am ready to offer more radical patch :)

Move all Linux aux entry types to a new file compat/linux/linux_elf.h
Add two new aux entries which improve work of futexes.

Please review. thnx!

diff --git a/sys/amd64/include/elf.h b/sys/amd64/include/elf.h
index a4c7f79..3c2cd20 100644
--- a/sys/amd64/include/elf.h
+++ b/sys/amd64/include/elf.h
@@ -81,16 +81,8 @@ __ElfType(Auxinfo);
 #define	AT_BASE		7	/* Interpreter's base address. */
 #define	AT_FLAGS	8	/* Flags (unused for i386). */
 #define	AT_ENTRY	9	/* Where interpreter should transfer control. */
-/*
- * The following non-standard values are used in Linux ELF binaries.
- */
-#define	AT_NOTELF	10	/* Program is not ELF ?? */
-#define	AT_UID		11	/* Real uid. */
-#define	AT_EUID		12	/* Effective uid. */
-#define	AT_GID		13	/* Real gid. */
-#define	AT_EGID		14	/* Effective gid. */
 
-#define	AT_COUNT	15	/* Count of defined aux entry types. */
+#define	AT_COUNT	10	/* Count of defined aux entry types. */
 
 /*
  * Relocation types.
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index e0ffcdf..3f04555 100644
--- a/sys/amd64/linux32/linux.h
+++ b/sys/amd64/linux32/linux.h
@@ -108,6 +108,12 @@ typedef struct {
 
 #define	LINUX_CTL_MAXNAME	10
 
+#define LINUX_AT_SYSINFO	32
+#define LINUX_AT_SYSINFO_EHDR	33
+#define	LINUX_AT_COUNT		16	/* Count of used aux entry types.
+					 * Keep this synchronized with
+					 * elf_linux_fixup() code.
+					 */
 struct l___sysctl_args
 {
 	l_uintptr_t	name;
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index aaa7458..2777e84 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
 
 #include <amd64/linux32/linux.h>
 #include <amd64/linux32/linux32_proto.h>
+#include <compat/linux/linux_elf.h>
 #include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_mib.h>
 #include <compat/linux/linux_signal.h>
@@ -106,6 +107,8 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
 #define	LINUX_SYS_linux_rt_sendsig	0
 #define	LINUX_SYS_linux_sendsig		0
 
+const char linux_platform[] = "i686";
+static int linux_szplatform;
 extern char linux_sigcode[];
 extern int linux_szsigcode;
 
@@ -246,7 +249,12 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
 {
 	Elf32_Auxargs *args;
 	Elf32_Addr *base;
-	Elf32_Addr *pos;
+	Elf32_Addr *pos, *uplatform;
+	struct linux32_ps_strings *arginfo;
+
+	arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
+	uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szsigcode -
+	    linux_szplatform);
 
 	KASSERT(curthread->td_proc == imgp->proc,
 	    ("unsafe elf_linux_fixup(), should be curproc"));
@@ -254,8 +262,8 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
 	args = (Elf32_Auxargs *)imgp->auxargs;
 	pos = base + (imgp->args->argc + imgp->args->envc + 2);
 
-	if (args->execfd != -1)
-		AUXARGS_ENTRY_32(pos, AT_EXECFD, args->execfd);
+	AUXARGS_ENTRY_32(pos, LINUX_AT_HWCAP, cpu_feature);
+	AUXARGS_ENTRY_32(pos, LINUX_AT_CLKTCK, hz);
 	AUXARGS_ENTRY_32(pos, AT_PHDR, args->phdr);
 	AUXARGS_ENTRY_32(pos, AT_PHENT, args->phent);
 	AUXARGS_ENTRY_32(pos, AT_PHNUM, args->phnum);
@@ -263,10 +271,14 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
 	AUXARGS_ENTRY_32(pos, AT_FLAGS, args->flags);
 	AUXARGS_ENTRY_32(pos, AT_ENTRY, args->entry);
 	AUXARGS_ENTRY_32(pos, AT_BASE, args->base);
-	AUXARGS_ENTRY_32(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
-	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, LINUX_AT_SECURE, 0);
+	AUXARGS_ENTRY_32(pos, LINUX_AT_UID, imgp->proc->p_ucred->cr_ruid);
+	AUXARGS_ENTRY_32(pos, LINUX_AT_EUID, imgp->proc->p_ucred->cr_svuid);
+	AUXARGS_ENTRY_32(pos, LINUX_AT_GID, imgp->proc->p_ucred->cr_rgid);
+	AUXARGS_ENTRY_32(pos, LINUX_AT_EGID, imgp->proc->p_ucred->cr_svgid);
+	AUXARGS_ENTRY_32(pos, LINUX_AT_PLATFORM, PTROUT(uplatform));
+	if (args->execfd != -1)
+		AUXARGS_ENTRY_32(pos, AT_EXECFD, args->execfd);
 	AUXARGS_ENTRY_32(pos, AT_NULL, 0);
 
 	free(imgp->auxargs, M_TEMP);
@@ -851,27 +863,31 @@ static register_t *
 linux_copyout_strings(struct image_params *imgp)
 {
 	int argc, envc;
-	u_int32_t *vectp;
+	uint32_t *vectp;
 	char *stringp, *destp;
-	u_int32_t *stack_base;
+	uint32_t *stack_base;
 	struct linux32_ps_strings *arginfo;
-	int sigcodesz;
 
 	/*
 	 * 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 *));
+	destp =	(caddr_t)arginfo - linux_szsigcode - SPARE_USRSPACE -
+	    linux_szplatform - roundup((ARG_MAX - imgp->args->stringspace),
+	    sizeof(char *));
 
 	/*
 	 * install sigcode
 	 */
-	if (sigcodesz)
-		copyout(imgp->proc->p_sysent->sv_sigcode,
-			((caddr_t)arginfo - sigcodesz), sigcodesz);
+	copyout(imgp->proc->p_sysent->sv_sigcode,
+	    ((caddr_t)arginfo - linux_szsigcode), linux_szsigcode);
+
+	/*
+	 * Install LINUX_PLATFORM
+	 */
+	copyout(linux_platform, ((caddr_t)arginfo - linux_szsigcode -
+	    linux_szplatform), linux_szplatform);
 
 	/*
 	 * If we have a valid auxargs ptr, prepare some room
@@ -883,22 +899,22 @@ linux_copyout_strings(struct image_params *imgp)
 		 * lower compatibility.
 		 */
 		imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
-			: (AT_COUNT * 2);
+			: (LINUX_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 = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 +
-				       imgp->auxarg_size) * sizeof(u_int32_t));
+		vectp = (uint32_t *) (destp - (imgp->args->argc +
+		    imgp->args->envc + 2 + imgp->auxarg_size) * sizeof(uint32_t));
 
 	} else
 		/*
 		 * The '+ 2' is for the null pointers at the end of each of
 		 * the arg and env vector sets
 		 */
-		vectp = (u_int32_t *)
-			(destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
+		vectp = (uint32_t *) (destp - (imgp->args->argc +
+		    imgp->args->envc + 2) * sizeof(uint32_t));
 
 	/*
 	 * vectp also becomes our initial stack base
@@ -916,14 +932,14 @@ linux_copyout_strings(struct image_params *imgp)
 	/*
 	 * Fill in "ps_strings" struct for ps, w, etc.
 	 */
-	suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
+	suword32(&arginfo->ps_argvstr, (uint32_t)(intptr_t)vectp);
 	suword32(&arginfo->ps_nargvstr, argc);
 
 	/*
 	 * Fill in argument portion of vector table.
 	 */
 	for (; argc > 0; --argc) {
-		suword32(vectp++, (u_int32_t)(intptr_t)destp);
+		suword32(vectp++, (uint32_t)(intptr_t)destp);
 		while (*stringp++ != 0)
 			destp++;
 		destp++;
@@ -932,14 +948,14 @@ linux_copyout_strings(struct image_params *imgp)
 	/* a null vector table pointer separates the argp's from the envp's */
 	suword32(vectp++, 0);
 
-	suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
+	suword32(&arginfo->ps_envstr, (uint32_t)(intptr_t)vectp);
 	suword32(&arginfo->ps_nenvstr, envc);
 
 	/*
 	 * Fill in environment portion of vector table.
 	 */
 	for (; envc > 0; --envc) {
-		suword32(vectp++, (u_int32_t)(intptr_t)destp);
+		suword32(vectp++, (uint32_t)(intptr_t)destp);
 		while (*stringp++ != 0)
 			destp++;
 		destp++;
@@ -1088,6 +1104,8 @@ linux_elf_modevent(module_t mod, int type, void *data)
 			      NULL, 1000);
 			if (bootverbose)
 				printf("Linux ELF exec handler installed\n");
+			linux_szplatform = roundup(strlen(linux_platform) + 1,
+			    sizeof(char *));
 		} else
 			printf("cannot insert Linux ELF brand handler\n");
 		break;
diff --git a/sys/arm/include/elf.h b/sys/arm/include/elf.h
index c516864..48260e1 100644
--- a/sys/arm/include/elf.h
+++ b/sys/arm/include/elf.h
@@ -70,13 +70,8 @@ __ElfType(Auxinfo);
 #define AT_BASE         7       /* Interpreter's base address. */
 #define AT_FLAGS        8       /* Flags (unused). */
 #define AT_ENTRY        9       /* Where interpreter should transfer control. */
-#define AT_NOTELF       10      /* Program is not ELF ?? */
-#define AT_UID          11      /* Real uid. */
-#define AT_EUID         12      /* Effective uid. */
-#define AT_GID          13      /* Real gid. */
-#define AT_EGID         14      /* Effective gid. */
 
-#define AT_COUNT        15      /* Count of defined aux entry types. */
+#define AT_COUNT	10	/* Count of defined aux entry types. */
 
 #define	R_ARM_COUNT		33	/* Count of defined relocation types. */
 
diff --git a/sys/compat/linux/linux_elf.h b/sys/compat/linux/linux_elf.h
new file mode 100644
index 0000000..680e39b
--- /dev/null
+++ b/sys/compat/linux/linux_elf.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2008 Chagin Dmitry
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LINUX_ELF_H_
+#define	_LINUX_ELF_H_
+
+/*
+ * Non-standard aux entry types used in Linux ELF binaries.
+ */
+
+#define	LINUX_AT_NOTELF		10	/* Program is not ELF ?? */
+#define	LINUX_AT_UID		11	/* Real uid. */
+#define	LINUX_AT_EUID		12	/* Effective uid. */
+#define	LINUX_AT_GID		13	/* Real gid. */
+#define	LINUX_AT_EGID		14	/* Effective gid. */
+#define	LINUX_AT_PLATFORM	15	/* String identifying CPU */
+#define	LINUX_AT_HWCAP		16	/* CPU capabilities */
+#define	LINUX_AT_CLKTCK		17	/* frequency at which times() increments */
+#define	LINUX_AT_SECURE		23	/* secure mode boolean */
+#define	LINUX_AT_BASE_PLATFORM	24	/* string identifying real platform, may
+					 * differ from AT_PLATFORM.
+					 */
+#define	LINUX_AT_EXECFN		31	/* filename of program */
+
+#endif /* !_LINUX_ELF_H_ */
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 93f4297..cf14da3 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -92,10 +92,6 @@ __FBSDID("$FreeBSD$");
 #include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_misc.h>
 
-#ifdef __i386__
-#include <machine/cputypes.h>
-#endif
-
 #define BSD_TO_LINUX_SIGNAL(sig)	\
 	(((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig)
 
@@ -731,34 +727,8 @@ linux_newuname(struct thread *td, struct linux_newuname_args *args)
 			*p = '\0';
 			break;
 		}
-#ifdef __i386__
-	{
-		const char *class;
+	strlcpy(utsname.machine, linux_platform, LINUX_MAX_UTSNAME);
 
-		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);
-	}
-#elif defined(__amd64__)	/* XXX: Linux can change 'personality'. */
-#ifdef COMPAT_LINUX32
-	strlcpy(utsname.machine, "i686", LINUX_MAX_UTSNAME);
-#else
-	strlcpy(utsname.machine, "x86_64", LINUX_MAX_UTSNAME);
-#endif /* COMPAT_LINUX32 */
-#else /* something other than i386 or amd64 - assume we and Linux agree */
-	strlcpy(utsname.machine, machine, LINUX_MAX_UTSNAME);
-#endif /* __i386__ */
 	mtx_lock(&hostname_mtx);
 	strlcpy(utsname.domainname, V_domainname, LINUX_MAX_UTSNAME);
 	mtx_unlock(&hostname_mtx);
diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h
index c80a432..2cdb3c3 100644
--- a/sys/compat/linux/linux_misc.h
+++ b/sys/compat/linux/linux_misc.h
@@ -45,4 +45,6 @@
 #define	LINUX_MREMAP_MAYMOVE	1
 #define	LINUX_MREMAP_FIXED	2
 
+extern const char linux_platform[];
+
 #endif	/* _LINUX_MISC_H_ */
diff --git a/sys/compat/svr4/svr4.h b/sys/compat/svr4/svr4.h
index 84ee720..261e3e9 100644
--- a/sys/compat/svr4/svr4.h
+++ b/sys/compat/svr4/svr4.h
@@ -36,4 +36,11 @@ extern struct sysentvec svr4_sysvec;
 
 #define COMPAT_SVR4_SOLARIS2
 
-#endif
+#define	SVR4_AT_UID		11	/* Real uid. */
+#define	SVR4_AT_EUID		12	/* Effective uid. */
+#define	SVR4_AT_GID		13	/* Real gid. */
+#define	SVR4_AT_EGID		14	/* Effective gid. */
+
+#define	SVR4_AT_COUNT		15	/* Count of defined aux entry types. */
+
+#endif /* !_LINUX_ELF_H_ */
diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c
index 0030e3a..24a742c 100644
--- a/sys/compat/svr4/svr4_sysvec.c
+++ b/sys/compat/svr4/svr4_sysvec.c
@@ -163,6 +163,115 @@ extern struct sysent svr4_sysent[];
 extern int svr4_szsigcode;
 extern char svr4_sigcode[];
 
+
+/*
+ * Copy strings out to the new process address space, constructing new arg
+ * and env vector tables. Return a pointer to the base so that it can be used
+ * as the initial stack pointer.
+ */
+static register_t *
+svr4_copyout_strings(struct image_params *imgp)
+{
+	int argc, envc;
+	char **vectp;
+	char *stringp, *destp;
+	register_t *stack_base;
+	struct ps_strings *arginfo;
+	struct proc *p;
+
+	/*
+	 * Calculate string base and vector table pointers.
+	 * Also deal with signal trampoline code for this exec type.
+	 */
+	p = imgp->proc;
+	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
+	destp =	(caddr_t)arginfo - svr4_szsigcode - SPARE_USRSPACE -
+	    roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
+
+	copyout(p->p_sysent->sv_sigcode, ((caddr_t)arginfo -
+	    svr4_szsigcode), svr4_szsigcode);
+
+	/*
+	 * 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 :
+		    (SVR4_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 svr4_sysvec = {
 	.sv_size	= SVR4_SYS_MAXSYSCALL,
 	.sv_table	= svr4_sysent,
@@ -187,7 +296,7 @@ struct sysentvec svr4_sysvec = {
 	.sv_usrstack	= USRSTACK,
 	.sv_psstrings	= PS_STRINGS,
 	.sv_stackprot	= VM_PROT_ALL,
-	.sv_copyout_strings = exec_copyout_strings,
+	.sv_copyout_strings = svr4_copyout_strings,
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz     = NULL,
@@ -227,10 +336,10 @@ svr4_fixup(register_t **stack_base, struct image_params *imgp)
 	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
 	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
 	AUXARGS_ENTRY(pos, AT_BASE, args->base);
-	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
-	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, SVR4_AT_UID, imgp->proc->p_ucred->cr_ruid);
+	AUXARGS_ENTRY(pos, SVR4_AT_EUID, imgp->proc->p_ucred->cr_svuid);
+	AUXARGS_ENTRY(pos, SVR4_AT_GID, imgp->proc->p_ucred->cr_rgid);
+	AUXARGS_ENTRY(pos, SVR4_AT_EGID, imgp->proc->p_ucred->cr_svgid);
 	AUXARGS_ENTRY(pos, AT_NULL, 0);
 	
 	free(imgp->auxargs, M_TEMP);      
@@ -307,3 +416,4 @@ static moduledata_t svr4_elf_mod = {
 };
 DECLARE_MODULE(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
 MODULE_DEPEND(svr4elf, streams, 1, 1, 1);
+
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index f9c7ee5..46478c0 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -102,6 +102,12 @@ typedef struct {
 
 #define	LINUX_CTL_MAXNAME	10
 
+#define LINUX_AT_SYSINFO	32
+#define LINUX_AT_SYSINFO_EHDR	33
+#define LINUX_AT_COUNT		16	/* Count of used aux entry types.
+					 * Keep this synchronized with
+					 * elf_linux_fixup() code.
+					 */
 struct l___sysctl_args
 {
 	l_int		*name;
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 42365fb..b44fb00 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -58,11 +58,13 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_param.h>
 
 #include <machine/cpu.h>
+#include <machine/cputypes.h>
 #include <machine/md_var.h>
 #include <machine/pcb.h>
 
 #include <i386/linux/linux.h>
 #include <i386/linux/linux_proto.h>
+#include <compat/linux/linux_elf.h>
 #include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_mib.h>
 #include <compat/linux/linux_signal.h>
@@ -107,6 +109,10 @@ static void	linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
 static void     linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
 static void	exec_linux_setregs(struct thread *td, u_long entry,
 				   u_long stack, u_long ps_strings);
+static register_t *linux_copyout_strings(struct image_params *imgp);
+
+static int linux_szplatform;
+const char *linux_platform;
 
 extern LIST_HEAD(futex_list, futex) futex_list;
 extern struct sx futex_sx;
@@ -231,22 +237,30 @@ linux_fixup(register_t **stack_base, struct image_params *imgp)
 	**stack_base = (intptr_t)(void *)argv;
 	(*stack_base)--;
 	**stack_base = imgp->args->argc;
-	return 0;
+	return (0);
 }
 
 static int
 elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
 {
+	struct proc *p;
 	Elf32_Auxargs *args;
+	Elf32_Addr *uplatform;
+	struct ps_strings *arginfo;
 	register_t *pos;
 
 	KASSERT(curthread->td_proc == imgp->proc,
 	    ("unsafe elf_linux_fixup(), should be curproc"));
+
+	p = imgp->proc;
+	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
+	uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szsigcode -
+	    linux_szplatform);
 	args = (Elf32_Auxargs *)imgp->auxargs;
 	pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
 
-	if (args->execfd != -1)
-		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
+	AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature);
+	AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, hz);
 	AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
 	AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
 	AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
@@ -254,10 +268,14 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
 	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
 	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
 	AUXARGS_ENTRY(pos, AT_BASE, args->base);
-	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
-	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, LINUX_AT_SECURE, 0);
+	AUXARGS_ENTRY(pos, LINUX_AT_UID, imgp->proc->p_ucred->cr_ruid);
+	AUXARGS_ENTRY(pos, LINUX_AT_EUID, imgp->proc->p_ucred->cr_svuid);
+	AUXARGS_ENTRY(pos, LINUX_AT_GID, imgp->proc->p_ucred->cr_rgid);
+	AUXARGS_ENTRY(pos, LINUX_AT_EGID, imgp->proc->p_ucred->cr_svgid);
+	AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(uplatform));
+	if (args->execfd != -1)
+		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
 	AUXARGS_ENTRY(pos, AT_NULL, 0);
 
 	free(imgp->auxargs, M_TEMP);
@@ -265,9 +283,125 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
 
 	(*stack_base)--;
 	**stack_base = (register_t)imgp->args->argc;
-	return 0;
+	return (0);
+}
+
+/*
+ * Copied from kern/kern_exec.c
+ */
+static register_t *
+linux_copyout_strings(struct image_params *imgp)
+{
+	int argc, envc;
+	char **vectp;
+	char *stringp, *destp;
+	register_t *stack_base;
+	struct ps_strings *arginfo;
+	struct proc *p;
+
+	/*
+	 * Calculate string base and vector table pointers.
+	 * Also deal with signal trampoline code for this exec type.
+	 */
+	p = imgp->proc;
+	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
+	destp = (caddr_t)arginfo - linux_szsigcode - SPARE_USRSPACE -
+	    linux_szplatform - roundup((ARG_MAX - imgp->args->stringspace),
+	    sizeof(char *));
+
+	/*
+	 * install sigcode
+	 */
+	copyout(p->p_sysent->sv_sigcode, ((caddr_t)arginfo -
+	    linux_szsigcode), linux_szsigcode);
+
+	/*
+	 * install LINUX_PLATFORM
+	 */
+	copyout(linux_platform, ((caddr_t)arginfo - linux_szsigcode -
+	    linux_szplatform), linux_szplatform);
+
+	/*
+	 * 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 :
+		    (LINUX_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);
 }
 
+
+
 extern int _ucodesel, _udatasel;
 extern unsigned long linux_sznonrtsigcode;
 
@@ -808,6 +942,29 @@ exec_linux_setregs(struct thread *td, u_long entry,
 	fldcw(&control);
 }
 
+static int
+linux_get_machine(const char **dst)
+{
+	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";
+	}
+	*dst = class;
+	return (0);
+}
+
+
 struct sysentvec linux_sysvec = {
 	.sv_size	= LINUX_SYS_MAXSYSCALL,
 	.sv_table	= linux_sysent,
@@ -863,7 +1020,7 @@ struct sysentvec elf_linux_sysvec = {
 	.sv_usrstack	= USRSTACK,
 	.sv_psstrings	= PS_STRINGS,
 	.sv_stackprot	= VM_PROT_ALL,
-	.sv_copyout_strings = exec_copyout_strings,
+	.sv_copyout_strings = linux_copyout_strings,
 	.sv_setregs	= exec_linux_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
@@ -929,6 +1086,9 @@ linux_elf_modevent(module_t mod, int type, void *data)
 			      NULL, 1000);
 			linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec,
 			      NULL, 1000);
+			linux_get_machine(&linux_platform);
+			linux_szplatform = roundup(strlen(linux_platform) + 1,
+			    sizeof(char *));
 			if (bootverbose)
 				printf("Linux ELF exec handler installed\n");
 		} else
diff --git a/sys/ia64/include/elf.h b/sys/ia64/include/elf.h
index faab8d1..982629c 100644
--- a/sys/ia64/include/elf.h
+++ b/sys/ia64/include/elf.h
@@ -82,16 +82,8 @@ __ElfType(Auxinfo);
 #define	AT_BASE		7	/* Interpreter's base address. */
 #define	AT_FLAGS	8	/* Flags (unused for i386). */
 #define	AT_ENTRY	9	/* Where interpreter should transfer control. */
-/*
- * The following non-standard values are used in Linux ELF binaries.
- */
-#define	AT_NOTELF	10	/* Program is not ELF ?? */
-#define	AT_UID		11	/* Real uid. */
-#define	AT_EUID		12	/* Effective uid. */
-#define	AT_GID		13	/* Real gid. */
-#define	AT_EGID		14	/* Effective gid. */
 
-#define	AT_COUNT	15	/* Count of defined aux entry types. */
+#define	AT_COUNT	10	/* Count of defined aux entry types. */
 
 /*
  * Values for e_flags.
diff --git a/sys/powerpc/include/elf.h b/sys/powerpc/include/elf.h
index 422a86a..d2b8e12 100644
--- a/sys/powerpc/include/elf.h
+++ b/sys/powerpc/include/elf.h
@@ -80,6 +80,9 @@ __ElfType(Auxinfo);
 
 #define	AT_COUNT	13	/* Count of defined aux entry types. */
 
+/* Used in John Polstra's testbed stuff. */
+#define	AT_DEBUG	14	/* Debugging level. */
+
 /*
  * Relocation types.
  */
diff --git a/sys/sparc64/include/elf.h b/sys/sparc64/include/elf.h
index 108ade1..c826197 100644
--- a/sys/sparc64/include/elf.h
+++ b/sys/sparc64/include/elf.h
@@ -78,16 +78,8 @@ __ElfType(Auxinfo);
 #define	AT_BASE		7	/* Interpreter's base address. */
 #define	AT_FLAGS	8	/* Flags (unused). */
 #define	AT_ENTRY	9	/* Where interpreter should transfer control. */
-/*
- * The following non-standard values are used in Linux ELF binaries.
- */
-#define	AT_NOTELF	10	/* Program is not ELF ?? */
-#define	AT_UID		11	/* Real uid. */
-#define	AT_EUID		12	/* Effective uid. */
-#define	AT_GID		13	/* Real gid. */
-#define	AT_EGID		14	/* Effective gid. */
 
-#define	AT_COUNT	15	/* Count of defined aux entry types. */
+#define	AT_COUNT	10	/* Count of defined aux entry types. */
 
 /* Define "machine" characteristics */
 #if __ELF_WORD_SIZE == 32
diff --git a/sys/sun4v/include/elf.h b/sys/sun4v/include/elf.h
index 108ade1..c826197 100644
--- a/sys/sun4v/include/elf.h
+++ b/sys/sun4v/include/elf.h
@@ -78,16 +78,8 @@ __ElfType(Auxinfo);
 #define	AT_BASE		7	/* Interpreter's base address. */
 #define	AT_FLAGS	8	/* Flags (unused). */
 #define	AT_ENTRY	9	/* Where interpreter should transfer control. */
-/*
- * The following non-standard values are used in Linux ELF binaries.
- */
-#define	AT_NOTELF	10	/* Program is not ELF ?? */
-#define	AT_UID		11	/* Real uid. */
-#define	AT_EUID		12	/* Effective uid. */
-#define	AT_GID		13	/* Real gid. */
-#define	AT_EGID		14	/* Effective gid. */
 
-#define	AT_COUNT	15	/* Count of defined aux entry types. */
+#define	AT_COUNT	10	/* Count of defined aux entry types. */
 
 /* Define "machine" characteristics */
 #if __ELF_WORD_SIZE == 32


-- 
Have fun!
chd


More information about the freebsd-arch mailing list