Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat/irix Fixed stack setup for argument passing. argc...



details:   https://anonhg.NetBSD.org/src/rev/e8688a59484c
branches:  trunk
changeset: 518730:e8688a59484c
user:      manu <manu%NetBSD.org@localhost>
date:      Tue Dec 04 22:13:41 2001 +0000

description:
Fixed stack setup for argument passing. argc and **argv need to be aligned
on a 16 bytes boundary. To get things done, we currently duplicate a lot of
code from copyargs(), this should be done in a nicer way.

diffstat:

 sys/compat/irix/irix_exec.c       |    6 +-
 sys/compat/irix/irix_exec.h       |    8 +-
 sys/compat/irix/irix_exec_elf32.c |  131 +++++++++++++++++++++++++++++++++++--
 3 files changed, 131 insertions(+), 14 deletions(-)

diffs (215 lines):

diff -r 1fdfc47d6954 -r e8688a59484c sys/compat/irix/irix_exec.c
--- a/sys/compat/irix/irix_exec.c       Tue Dec 04 21:50:50 2001 +0000
+++ b/sys/compat/irix/irix_exec.c       Tue Dec 04 22:13:41 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: irix_exec.c,v 1.5 2001/12/02 16:16:57 manu Exp $ */
+/*     $NetBSD: irix_exec.c,v 1.6 2001/12/04 22:13:41 manu Exp $ */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: irix_exec.c,v 1.5 2001/12/02 16:16:57 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: irix_exec.c,v 1.6 2001/12/04 22:13:41 manu Exp $");
 
 #ifndef ELFSIZE
 #define ELFSIZE                32      /* XXX should die */
@@ -193,6 +193,8 @@
        *pos = ELF_NO_ADDR;
 #ifdef DEBUG_IRIX
        printf("irix_probe: returning 0\n");
+       printf("epp->ep_vm_minaddr = 0x%lx\n", epp->ep_vm_minaddr);
 #endif
+       epp->ep_vm_minaddr = epp->ep_vm_minaddr & ~0xfUL;
        return 0;
 }
diff -r 1fdfc47d6954 -r e8688a59484c sys/compat/irix/irix_exec.h
--- a/sys/compat/irix/irix_exec.h       Tue Dec 04 21:50:50 2001 +0000
+++ b/sys/compat/irix/irix_exec.h       Tue Dec 04 22:13:41 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: irix_exec.h,v 1.2 2001/11/26 21:36:24 manu Exp $ */
+/*     $NetBSD: irix_exec.h,v 1.3 2001/12/04 22:13:41 manu Exp $ */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -43,8 +43,10 @@
 #include <sys/exec.h>
 #include <sys/exec_elf.h>
 
+#define IRIX_ELF_AUX_ENTRIES 7
+
 #ifdef EXEC_ELF32
-#define IRIX_AUX_ARGSIZ howmany(ELF_AUX_ENTRIES * sizeof(Aux32Info), \
+#define IRIX_AUX_ARGSIZ howmany(IRIX_ELF_AUX_ENTRIES * sizeof(Aux32Info), \
     sizeof (Elf32_Addr))
 
 int irix_elf32_copyargs __P((struct exec_package *, struct ps_strings *,
@@ -55,7 +57,7 @@
 #endif
 
 #ifdef EXEC_ELF64
-#define IRIX_AUX_ARGSIZ howmany(ELF_AUX_ENTRIES * sizeof(Aux64Info), \
+#define IRIX_AUX_ARGSIZ howmany(IRIX_ELF_AUX_ENTRIES * sizeof(Aux64Info), \
     sizeof (Elf64_Addr))
 
 int irix_elf64_copyargs __P((struct exec_package *, struct ps_strings *,
diff -r 1fdfc47d6954 -r e8688a59484c sys/compat/irix/irix_exec_elf32.c
--- a/sys/compat/irix/irix_exec_elf32.c Tue Dec 04 21:50:50 2001 +0000
+++ b/sys/compat/irix/irix_exec_elf32.c Tue Dec 04 22:13:41 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: irix_exec_elf32.c,v 1.2 2001/11/26 21:44:53 manu Exp $ */
+/*     $NetBSD: irix_exec_elf32.c,v 1.3 2001/12/04 22:13:41 manu Exp $ */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -37,27 +37,140 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: irix_exec_elf32.c,v 1.2 2001/11/26 21:44:53 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: irix_exec_elf32.c,v 1.3 2001/12/04 22:13:41 manu Exp $");
 
 #ifndef ELFSIZE
 #define ELFSIZE                32      /* XXX should die */
 #endif
 
 #include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/null.h>
+#include <sys/malloc.h>
+#include <sys/syslimits.h>
 #include <sys/exec.h>
 #include <sys/exec_elf.h>
 
+#include <machine/vmparam.h>
+
 #include <compat/irix/irix_exec.h>
 
 int
 ELFNAME2(irix,copyargs)(pack, arginfo, stackp, argp)
-        struct exec_package *pack;
-        struct ps_strings *arginfo;
-        char **stackp;
-        void *argp;
+       struct exec_package *pack;
+       struct ps_strings *arginfo;
+       char **stackp;
+       void *argp;
 {
-       /* Align the stack frame on a 16 bytes boundary */
-       *stackp = (char *)(((unsigned long)*stackp) & ~0xfUL);
+       char **cpp, *dp, *sp;
+       size_t len;
+       void *nullp;
+       long argc, envc;
+       AuxInfo ai[ELF_AUX_ENTRIES], *a;
+       struct elf_args *ap;
+       int error;
+
+       /*
+        * IRIX seems to expect argc and **argv to be aligned on a 
+        * 16 bytes boundary. It seems there is no other way of
+        * getting **argv aligned than duplicating and customizing
+        * the code that sets up the stack in copyargs():
+        */
+#ifdef DEBUG_IRIX
+       printf("irix_elf32_copyargs(): *stackp = %p\n", *stackp);
+#endif
+       /* 
+        * This is borrowed from sys/kern/kern_exec.c:copyargs()
+        */
+       cpp = (char **)*stackp;
+       nullp = NULL;
+       argc = arginfo->ps_nargvstr;
+       envc = arginfo->ps_nenvstr;
+       if ((error = copyout(&argc, cpp++, sizeof(argc))) != 0)
+               return error;
+
+       dp = (char *) (cpp + argc + envc + 2 + pack->ep_es->es_arglen);
+
+       /* Align **argv on a 16 bytes boundary */
+       dp = (char *)(((unsigned long)dp + 0xf) & ~0xfUL);
+
+       sp = argp;
+
+       arginfo->ps_argvstr = cpp; /* remember location of argv for later */
+
+       for (; --argc >= 0; sp += len, dp += len) {
+#ifdef DEBUG_IRIX
+       printf("irix_elf32_copyargs(): argc = %d, cpp = %p, dp = %p\n", (int)argc, cpp, dp);
+#endif
+               if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
+                   (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
+                       return error;
+       }
+
+       if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
+               return error;
+
+       arginfo->ps_envstr = cpp; /* remember location of envp for later */
+
+       for (; --envc >= 0; sp += len, dp += len)
+               if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
+                   (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
+                       return error;
 
-        return ELFNAME(copyargs)(pack, arginfo, stackp, argp);
+       if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
+               return error;
+
+       *stackp = (char *)cpp;
+
+       /*
+        * This is borrowed from sys/kern/exec_elf32.c:elf32_copyargs
+        */
+       a = ai;
+
+       /*
+        * Push extra arguments on the stack needed by dynamically
+        * linked binaries
+        */
+       if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
+
+               a->a_type = AT_PHDR;
+               a->a_v = ap->arg_phaddr;
+               a++;
+
+               a->a_type = AT_PHENT;
+               a->a_v = ap->arg_phentsize;
+               a++;
+
+               a->a_type = AT_PHNUM;
+               a->a_v = ap->arg_phnum;
+               a++;
+
+               a->a_type = AT_ENTRY;
+               a->a_v = ap->arg_entry;
+               a++;
+
+               a->a_type = AT_BASE;
+               a->a_v = ap->arg_interp;
+               a++;
+
+               a->a_type = AT_PAGESZ;
+               a->a_v = PAGE_SIZE;
+               a++;
+
+               free((char *)ap, M_TEMP);
+               pack->ep_emul_arg = NULL;
+       }
+
+       a->a_type = AT_NULL;
+       a->a_v = 0;
+       a++;
+
+       len = (a - ai) * sizeof(AuxInfo);
+       if ((error = copyout(ai, *stackp, len)) != 0)
+               return error;
+/*     *stackp += len; */
+#ifdef DEBUG_IRIX
+       printf("*stackp = %p\n", *stackp);
+#endif
+       return 0;
 }



Home | Main Index | Thread Index | Old Index