aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-05-04 09:00:10 +0000
committerRoland McGrath <roland@gnu.org>1995-05-04 09:00:10 +0000
commite4448b6f58406744ff1a5f400b492ba27e466b56 (patch)
tree84725f363a935ae8498d5f0eaa3a44239af3b5df
parentd66e34cd423425c348bcc83df127dd19711b0b9a (diff)
downloadglibc-e4448b6f58406744ff1a5f400b492ba27e466b56.tar
glibc-e4448b6f58406744ff1a5f400b492ba27e466b56.tar.gz
glibc-e4448b6f58406744ff1a5f400b492ba27e466b56.tar.bz2
glibc-e4448b6f58406744ff1a5f400b492ba27e466b56.zip
Wed May 3 11:56:35 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/dup2.c: Fixed broken test in last change. * elf/dl-error.c (_dl_catch_error): Actually call the OPERATE function. Duh. * hurd/Makefile (distribute): Added hurdstartup.h. * hurd/hurd.h: Remove _hurd_startup decl. * hurd/hurd/ioctl.h (_HURD_HANDLE_IOCTLS): Use __attribute__ ((__unused__)) instead of gratuitous self reference. * sysdeps/mach/hurd/dup2.c: Call _hurd_alloc_fd to expand the table if FD2 doesn't fit. * sysdeps/mach/hurd/getdtsz.c: Return the RLIM_NOFILE soft limit, not the current table size. * sysdeps/i386/init-first.c: New file. * sysdeps/stub/init-first.c: New file.
-rw-r--r--ChangeLog23
-rw-r--r--elf/dl-error.c1
-rw-r--r--hurd/Makefile2
-rw-r--r--hurd/hurd.h20
-rw-r--r--hurd/hurd/ioctl.h6
-rw-r--r--sysdeps/i386/init-first.c46
-rw-r--r--sysdeps/mach/hurd/dup2.c40
-rw-r--r--sysdeps/mach/hurd/getdtsz.c6
-rw-r--r--sysdeps/mach/hurd/start.c314
-rw-r--r--sysdeps/stub/init-first.c46
10 files changed, 152 insertions, 352 deletions
diff --git a/ChangeLog b/ChangeLog
index f417e2878d..2bf9c5aa2d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
+Wed May 3 11:56:35 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
+
+ * sysdeps/mach/hurd/dup2.c: Fixed broken test in last change.
+
Tue May 2 01:52:58 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
+ * elf/dl-error.c (_dl_catch_error): Actually call the OPERATE
+ function. Duh.
+
+ * hurd/Makefile (distribute): Added hurdstartup.h.
+ * hurd/hurd.h: Remove _hurd_startup decl.
+
+ * hurd/hurd/ioctl.h (_HURD_HANDLE_IOCTLS): Use __attribute__
+ ((__unused__)) instead of gratuitous self reference.
+
+ * sysdeps/mach/hurd/dup2.c: Call _hurd_alloc_fd to expand the
+ table if FD2 doesn't fit.
+
+ * sysdeps/mach/hurd/getdtsz.c: Return the RLIM_NOFILE soft limit,
+ not the current table size.
+
* sysdeps/mach/i386/sysdep.h (SNARF_ARGS, CALL_WITH_SP): Rewritten.
Implemented runtime dynamic linker to support ELF shared libraries.
@@ -25,7 +44,9 @@ Tue May 2 01:52:58 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/i386/elf/start.S: New file.
* sysdeps/generic/dl-sysdep.c: New file.
* sysdeps/mach/hurd/dl-sysdep.c: New file.
-
+ * sysdeps/i386/init-first.c: New file.
+ * sysdeps/stub/init-first.c: New file.
+
Mon May 1 18:48:30 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* Makerules (LDFLAGS-c.so): Add -interp and -e switches to make
diff --git a/elf/dl-error.c b/elf/dl-error.c
index 5b5a616d91..b9ee3516b5 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -38,6 +38,7 @@ _dl_catch_error (const char **errstring, void (*operate) (void))
signalled_errstring = NULL;
errcode = setjmp (catch_env);
+ (*operate) ();
*errstring = signalled_errstring;
return *errstring ? errcode : 0;
}
diff --git a/hurd/Makefile b/hurd/Makefile
index 0ef626f5e3..f5b36867a5 100644
--- a/hurd/Makefile
+++ b/hurd/Makefile
@@ -28,7 +28,7 @@ headers = hurd.h $(interface-headers) \
$(addprefix hurd/,fd.h id.h port.h signal.h userlink.h \
resource.h threadvar.h)
-distribute := hurdfault.h intr-rpc.awk intr-rpc.defs STATUS
+distribute := hurdstartup.h hurdfault.h intr-rpc.awk intr-rpc.defs STATUS
# The RPC interfaces go in a separate library.
interface-library := libhurduser
diff --git a/hurd/hurd.h b/hurd/hurd.h
index b0bbfbea3b..968910fffb 100644
--- a/hurd/hurd.h
+++ b/hurd/hurd.h
@@ -227,26 +227,6 @@ extern error_t _hurd_exec (task_t task,
extern void _hurd_exit (int status) __attribute__ ((noreturn));
-/* Initialize Mach RPCs and essential Hurd things (_hurd_preinit_hook); do
- initial handshake with the exec server (or extract the arguments from
- the stack in the case of the bootstrap task); if cthreads is in use,
- initialize it now and switch the calling thread to a cthread stack;
- finally, call *MAIN with the information gleaned. That function is not
- expected to return. ARGPTR should be the address of the first argument
- of the entry point function that is called with the stack exactly as the
- exec server or kernel sets it. */
-
-extern void _hurd_startup (void **argptr,
- void (*main) (int argc, char **argv, char **envp,
- int flags,
- mach_port_t *portarray,
- mach_msg_type_number_t portarraysize,
- int *intarray,
- mach_msg_type_number_t intarraysize,
- vm_address_t phdr, vm_size_t phdrsz,
- vm_address_t user_entry))
- __attribute__ ((noreturn));
-
/* Initialize the library data structures from the
ints and ports passed to us by the exec server.
Then vm_deallocate PORTARRAY and INTARRAY. */
diff --git a/hurd/hurd/ioctl.h b/hurd/hurd/ioctl.h
index cc83433c17..518ef51b33 100644
--- a/hurd/hurd/ioctl.h
+++ b/hurd/hurd/ioctl.h
@@ -52,9 +52,9 @@ extern int hurd_register_ioctl_handler (int first_request, int last_request,
avoid `defined but not used' warnings. */
#define _HURD_HANDLE_IOCTLS(handler, first, last) \
- static const struct ioctl_handler handler##_ioctl_handler = \
- { (first), (last), (int (*) (int, int, void *)) (handler), \
- (&(handler), &(handler##_ioctl_handler), NULL) }; \
+ static const struct ioctl_handler handler##_ioctl_handler \
+ __attribute__ ((__unused__)) = \
+ { (first), (last), (int (*) (int, int, void *)) (handler), NULL }; \
text_set_element (_hurd_ioctl_handler_lists, ##handler##_ioctl_handler)
/* Define a library-internal handler for a single ioctl command. */
diff --git a/sysdeps/i386/init-first.c b/sysdeps/i386/init-first.c
new file mode 100644
index 0000000000..06f433d2be
--- /dev/null
+++ b/sysdeps/i386/init-first.c
@@ -0,0 +1,46 @@
+/* Initialization code run first thing by the ELF startup code. For i386/Unix.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include <hurd.h>
+#include <unistd.h>
+
+extern void __libc_init (int, char **, char **);
+
+#ifdef PIC
+static void soinit (int argc, char *arg0, ...)
+ __attribute__ ((unused, section (".init")));
+
+void
+__libc_init_first (void)
+{
+}
+#endif
+
+#ifdef PIC
+static void soinit
+#else
+void __libc_init_first
+#endif
+(int argc, char *arg0, ...)
+{
+ char **argv = &arg0, **envp = &argv[argc + 1];
+
+ __environ = envp;
+ __libc_init (argc, argv, envp);
+}
diff --git a/sysdeps/mach/hurd/dup2.c b/sysdeps/mach/hurd/dup2.c
index f4ec623b05..c4b16698b8 100644
--- a/sysdeps/mach/hurd/dup2.c
+++ b/sysdeps/mach/hurd/dup2.c
@@ -58,8 +58,7 @@ DEFUN(__dup2, (fd, fd2), int fd AND int fd2)
io_t ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
io_t port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D. */
- __mutex_lock (&_hurd_dtable_lock);
- if (fd2 < 0 || fd2 >= _hurd_dtablesize)
+ if (fd2 < 0)
{
errno = EBADF;
fd2 = -1;
@@ -67,16 +66,37 @@ DEFUN(__dup2, (fd, fd2), int fd AND int fd2)
else
{
/* Get a hold of the destination descriptor. */
- struct hurd_fd *d2 = _hurd_dtable[fd2];
- if (d2 == NULL)
+ struct hurd_fd *d2;
+
+ if (fd2 >= _hurd_dtablesize)
+ {
+ /* The table is not large enough to hold the destination
+ descriptor. Enlarge it as necessary to allocate this
+ descriptor. */
+ __mutex_unlock (&_hurd_dtable_lock);
+ /* We still hold FD1's lock, but this is safe because
+ _hurd_alloc_fd will only examine the cells starting
+ at FD2. */
+ d2 = _hurd_alloc_fd (NULL, fd2);
+ if (d2)
+ __spin_unlock (&d2->port.lock);
+ __mutex_lock (&_hurd_dtable_lock);
+ }
+ else
{
- /* Must allocate a new one. We don't initialize the port cells
- with this call so that if it fails (out of memory), we will
- not have already added user references for the ports, which we
- would then have to deallocate. */
- d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL,
- MACH_PORT_NULL);
+ d2 = _hurd_dtable[fd2];
+ if (d2 == NULL)
+ {
+ /* Must allocate a new one. We don't initialize the port
+ cells with this call so that if it fails (out of
+ memory), we will not have already added user
+ references for the ports, which we would then have to
+ deallocate. */
+ d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL,
+ MACH_PORT_NULL);
+ }
}
+
if (d2 == NULL)
{
fd2 = -1;
diff --git a/sysdeps/mach/hurd/getdtsz.c b/sysdeps/mach/hurd/getdtsz.c
index e506963ac3..3e6385f64e 100644
--- a/sysdeps/mach/hurd/getdtsz.c
+++ b/sysdeps/mach/hurd/getdtsz.c
@@ -29,9 +29,9 @@ DEFUN_VOID(__getdtablesize)
{
int size;
HURD_CRITICAL_BEGIN;
- __mutex_lock (&_hurd_dtable_lock);
- size = _hurd_dtablesize;
- __mutex_unlock (&_hurd_dtable_lock);
+ __mutex_lock (&_hurd_rlimits_lock);
+ size = _hurd_rlimits[RLIM_NOFILE].rlim_cur; /* XXX RLIM_INFINITY?? */
+ __mutex_unlock (&_hurd_rlimits_lock);
HURD_CRITICAL_END;
return size;
}
diff --git a/sysdeps/mach/hurd/start.c b/sysdeps/mach/hurd/start.c
deleted file mode 100644
index 9a70e0ddd4..0000000000
--- a/sysdeps/mach/hurd/start.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <hurd.h>
-#include <hurd/exec.h>
-#include <sysdep.h>
-#include <hurd/threadvar.h>
-#include <unistd.h>
-#include "set-hooks.h"
-#include "hurdmalloc.h" /* XXX */
-
-/* The first piece of initialized data. */
-int __data_start = 0;
-weak_alias (__data_start, data_start)
-
-mach_port_t *_hurd_init_dtable;
-mach_msg_type_number_t _hurd_init_dtablesize;
-
-unsigned int __hurd_threadvar_max;
-unsigned long int __hurd_threadvar_stack_mask;
-unsigned long int __hurd_threadvar_stack_offset;
-
-/* These are set up by _hurdsig_init. */
-unsigned long int __hurd_sigthread_stack_base;
-unsigned long int __hurd_sigthread_stack_end;
-unsigned long int *__hurd_sigthread_variables;
-
-vm_address_t _hurd_stack_base;
-vm_size_t _hurd_stack_size;
-
-/* Things that want to be run before _hurd_init or much anything else.
- Importantly, these are called before anything tries to use malloc. */
-DEFINE_HOOK (_hurd_preinit_hook, (void));
-
-extern void __mach_init (void);
-extern void __libc_init (int argc, char **argv, char **envp);
-extern int main (int argc, char **argv, char **envp);
-
-void *(*_cthread_init_routine) (void); /* Returns new SP to use. */
-void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
-
-int _hurd_split_args (char *, size_t, char **);
-
-/* These communicate values from _start to start1,
- where we cannot use the stack for anything. */
-static char *args, *env;
-static mach_port_t *portarray;
-static int *intarray;
-static mach_msg_type_number_t argslen, envlen, portarraysize, intarraysize;
-static int flags;
-static char **argv, **envp;
-static int argc;
-
-
-static void start1 (void) __attribute__ ((__noreturn__));
-
-
-/* Entry point. This is the first thing in the text segment.
-
- The exec server started the initial thread in our task with this spot the
- PC, and a stack that is presumably big enough. We do basic Mach
- initialization so mig-generated stubs work, and then do an exec_startup
- RPC on our bootstrap port, to which the exec server responds with the
- information passed in the exec call, as well as our original bootstrap
- port, and the base address and size of the preallocated stack.
-
- If using cthreads, we are given a new stack by cthreads initialization and
- deallocate the stack set up by the exec server. On the new stack we call
- `start1' (above) to do the rest of the startup work. Since the stack may
- disappear out from under us in a machine-dependent way, we use a pile of
- static variables to communicate the information from exec_startup to start1.
- This is unfortunate but preferable to machine-dependent frobnication to copy
- the state from the old stack to the new one. */
-
-#ifndef START_ARGS
-#define START_ARGS void
-#endif
-#ifdef START_MACHDEP
-START_MACHDEP
-#define _start _start0
-#endif
-
-void
-_start (START_ARGS)
-{
- error_t err;
- mach_port_t in_bootstrap;
-
- /* Basic Mach initialization, must be done before RPCs can be done. */
- __mach_init ();
-
- /* Run things that want to do initialization as soon as possible. We do
- this before exec_startup so that no out of line data arrives and
- clutters up the address space before brk initialization. */
-
- RUN_HOOK (_hurd_preinit_hook, ());
-
- if (err = __task_get_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT,
- &in_bootstrap))
- LOSE;
-
- if (in_bootstrap != MACH_PORT_NULL)
- {
- /* Call the exec server on our bootstrap port and
- get all our standard information from it. */
-
- argslen = envlen = 0;
- _hurd_init_dtablesize = portarraysize = intarraysize = 0;
-
- err = __exec_startup (in_bootstrap,
- &_hurd_stack_base, &_hurd_stack_size,
- &flags,
- &args, &argslen, &env, &envlen,
- &_hurd_init_dtable, &_hurd_init_dtablesize,
- &portarray, &portarraysize,
- &intarray, &intarraysize);
- __mach_port_deallocate (__mach_task_self (), in_bootstrap);
- }
-
- if (err || in_bootstrap == MACH_PORT_NULL)
- {
- /* Either we have no bootstrap port, or the RPC to the exec server
- failed. Try to snarf the args in the canonical Mach way.
- Hopefully either they will be on the stack as expected, or the
- stack will be zeros so we don't crash. Set all our other
- variables to have empty information. */
-
- /* SNARF_ARGS (ARGC, ARGV, ENVP) snarfs the arguments and environment
- from the stack, assuming they were put there by the microkernel. */
- SNARF_ARGS (argc, argv, envp);
-
- flags = 0;
- args = env = NULL;
- argslen = envlen = 0;
- _hurd_init_dtable = NULL;
- _hurd_init_dtablesize = 0;
- portarray = NULL;
- portarraysize = 0;
- intarray = NULL;
- intarraysize = 0;
- }
- else
- argv = envp = NULL;
-
-
- /* The user might have defined a value for this, to get more variables.
- Otherwise it will be zero on startup. We must make sure it is set
- properly before before cthreads initialization, so cthreads can know
- how much space to leave for thread variables. */
- if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
- __hurd_threadvar_max = _HURD_THREADVAR_MAX;
-
- /* Do cthreads initialization and switch to the cthread stack. */
-
- if (_cthread_init_routine != NULL)
- CALL_WITH_SP (start1, (*_cthread_init_routine) ());
- else
- start1 ();
-
- /* Should never get here. */
- LOSE;
-}
-
-
-static void
-start1 (void)
-{
- register int envc = 0;
-
- {
- /* Check if the stack we are now on is different from
- the one described by _hurd_stack_{base,size}. */
-
- char dummy;
- const vm_address_t newsp = (vm_address_t) &dummy;
-
- if (_hurd_stack_size != 0 && (newsp < _hurd_stack_base ||
- newsp - _hurd_stack_base > _hurd_stack_size))
- /* The new stack pointer does not intersect with the
- stack the exec server set up for us, so free that stack. */
- __vm_deallocate (__mach_task_self (),
- _hurd_stack_base, _hurd_stack_size);
- }
-
- if (__hurd_threadvar_stack_mask == 0)
- {
- /* We are not using cthreads, so we will have just a single allocated
- area for the per-thread variables of the main user thread. */
- unsigned long int i;
- __hurd_threadvar_stack_offset
- = (unsigned long int) malloc (__hurd_threadvar_max *
- sizeof (unsigned long int));
- if (__hurd_threadvar_stack_offset == 0)
- __libc_fatal ("Can't allocate single-threaded per-thread variables.");
- for (i = 0; i < __hurd_threadvar_max; ++i)
- ((unsigned long int *) __hurd_threadvar_stack_offset)[i] = 0;
- }
-
-
- /* Turn the block of null-separated strings we were passed for the
- arguments and environment into vectors of pointers to strings. */
-
- if (! argv)
- {
- if (args)
- /* Count up the arguments so we can allocate ARGV. */
- argc = _hurd_split_args (args, argslen, NULL);
- if (! args || argc == 0)
- {
- /* No arguments passed; set argv to { NULL }. */
- argc = 0;
- args = NULL;
- argv = (char **) &args;
- }
- }
-
- if (! envp)
- {
- if (env)
- /* Count up the environment variables so we can allocate ENVP. */
- envc = _hurd_split_args (env, envlen, NULL);
- if (! env || envc == 0)
- {
- /* No environment passed; set __environ to { NULL }. */
- env = NULL;
- envp = (char **) &env;
- }
- }
-
- if (! argv)
- {
- /* There were some arguments.
- Allocate space for the vectors of pointers and fill them in. */
- argv = __alloca ((argc + 1) * sizeof (char *));
- _hurd_split_args (args, argslen, argv);
- }
-
- if (! envp)
- {
- /* There was some environment.
- Allocate space for the vectors of pointers and fill them in. */
- envp = __alloca ((envc + 1) * sizeof (char *));
- _hurd_split_args (env, envlen, envp);
- }
-
- __environ = envp;
-
- if (portarray || intarray)
- /* Initialize library data structures, start signal processing, etc. */
- _hurd_init (flags, argv, portarray, portarraysize, intarray, intarraysize);
-
- /* Random library initialization. These functions may assume that
- _hurd_init has already run (if it is going to), and POSIX.1 facilities
- are initialized and available. */
- __libc_init (argc, argv, __environ);
-
- /* Finally, run the user program. */
- (_cthread_exit_routine != NULL ? *_cthread_exit_routine : exit)
- (main (argc, argv, __environ));
-
- /* Should never get here. */
- LOSE;
-}
-
-/* Split ARGSLEN bytes at ARGS into words, breaking at NUL characters. If
- ARGV is not a null pointer, store a pointer to the start of each word in
- ARGV[n], and null-terminate ARGV. Return the number of words split. */
-
-int
-_hurd_split_args (char *args, size_t argslen, char **argv)
-{
- char *p = args;
- size_t n = argslen;
- int argc = 0;
-
- while (n > 0)
- {
- char *end = memchr (p, '\0', n);
-
- if (argv)
- argv[argc] = p;
- ++argc;
-
- if (end == NULL)
- /* The last argument is unterminated. */
- break;
-
- n -= end + 1 - p;
- p = end + 1;
- }
-
- if (argv)
- argv[argc] = NULL;
- return argc;
-}
diff --git a/sysdeps/stub/init-first.c b/sysdeps/stub/init-first.c
new file mode 100644
index 0000000000..9f4b010f52
--- /dev/null
+++ b/sysdeps/stub/init-first.c
@@ -0,0 +1,46 @@
+/* Initialization code run first thing by the ELF startup code. Stub version.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include <hurd.h>
+#include <unistd.h>
+
+extern void __libc_init (int, char **, char **);
+
+#ifdef PIC
+static void soinit (int argc, char *arg0, ...)
+ __attribute__ ((unused, section (".init")));
+
+void
+__libc_init_first (void)
+{
+}
+#endif
+
+#ifdef PIC
+static void soinit
+#else
+void __libc_init_first
+#endif
+(int argc, char *arg0, ...)
+{
+ char **argv = &arg0, **envp = &argv[argc + 1];
+
+ __environ = envp;
+ __libc_init (argc, argv, envp);
+}