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