aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/linux32/linux32_sysvec.c
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2009-03-04 12:14:33 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2009-03-04 12:14:33 +0000
commit4d7c2e8a483ba53273aa5cbad8ee3f6fc3dbd791 (patch)
tree62f76cca88478d27784a620e697797cefd2ec667 /sys/amd64/linux32/linux32_sysvec.c
parent09efd0ec6a6bd656dd613ee7110f3ab4e118fdd4 (diff)
downloadsrc-4d7c2e8a483ba53273aa5cbad8ee3f6fc3dbd791.tar.gz
src-4d7c2e8a483ba53273aa5cbad8ee3f6fc3dbd791.zip
Add AT_PLATFORM, AT_HWCAP and AT_CLKTCK auxiliary vector entries which
are used by glibc. This silents the message "2.4+ kernel w/o ELF notes?" from some programs at start, among them are top and pkill. Do the assignment of the vector entries in elf_linux_fixup() as it is done in glibc. Fix some minor style issues. Submitted by: Marcin Cieslak <saper at SYSTEM PL> Approved by: kib (mentor) MFC after: 1 week
Notes
Notes: svn path=/head/; revision=189362
Diffstat (limited to 'sys/amd64/linux32/linux32_sysvec.c')
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index bcb6069aca6d..312687adc099 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include <amd64/linux32/linux32_proto.h>
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_mib.h>
+#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_util.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, LINUX_AT_SECURE, 0);
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_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);
@@ -857,23 +869,27 @@ linux_copyout_strings(struct image_params *imgp)
char *stringp, *destp;
u_int32_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
@@ -885,7 +901,7 @@ 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
@@ -919,14 +935,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++;
@@ -935,14 +951,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++;
@@ -1089,6 +1105,8 @@ linux_elf_modevent(module_t mod, int type, void *data)
linux_schedtail, NULL, 1000);
linux_exec_tag = EVENTHANDLER_REGISTER(process_exec,
linux_proc_exec, NULL, 1000);
+ linux_szplatform = roundup(strlen(linux_platform) + 1,
+ sizeof(char *));
if (bootverbose)
printf("Linux ELF exec handler installed\n");
} else