_dl_pagesize = __getpagesize ();
GL(dl_pagesize) = __getpagesize ();
_dl_sysdep_start (void **start_argptr,		  void (*dl_main) (const Elf32_Phdr *phdr, Elf32_Word phent,				   Elf32_Addr *user_entry)){  void go (int *argdata)    {      extern unsigned int _dl_skip_args; /* rtld.c */      char **p;      /* Cache the information in various global variables.  */      _dl_argc = *argdata;      _dl_argv = 1 + (char **) argdata;      _environ = &_dl_argv[_dl_argc + 1];      for (p = _environ; *p++;); /* Skip environ pointers and terminator.  */      if ((void *) p == _dl_argv[0])	{	  static struct hurd_startup_data nodata;	  _dl_hurd_data = &nodata;	  nodata.user_entry = (vm_address_t) ENTRY_POINT;	}      else	_dl_hurd_data = (void *) p;      __libc_enable_secure = _dl_hurd_data->flags & EXEC_SECURE;      if (_dl_hurd_data->flags & EXEC_STACK_ARGS &&	  _dl_hurd_data->user_entry == 0)	_dl_hurd_data->user_entry = (vm_address_t) ENTRY_POINT;unfmh();			/* XXX */#if 0				/* XXX make this work for real someday... */      if (_dl_hurd_data->user_entry == (vm_address_t) ENTRY_POINT)	/* We were invoked as a command, not as the program interpreter.	   The generic ld.so code supports this: it will parse the args	   as "ld.so PROGRAM [ARGS...]".  For booting the Hurd, we	   support an additional special syntax:	     ld.so [-LIBS...] PROGRAM [ARGS...]	   Each LIBS word consists of "FILENAME=MEMOBJ";	   for example "-/lib/libc.so=123" says that the contents of	   /lib/libc.so are found in a memory object whose port name	   in our task is 123.  */	while (_dl_argc > 2 && _dl_argv[1][0] == '-' && _dl_argv[1][1] != '-')	  {	    char *lastslash, *memobjname, *p;	    struct link_map *l;	    mach_port_t memobj;	    error_t err;	    ++_dl_skip_args;	    --_dl_argc;	    p = _dl_argv++[1] + 1;	    memobjname = strchr (p, '=');	    if (! memobjname)	      _dl_sysdep_fatal ("Bogus library spec: ", p, "\n", NULL);	    *memobjname++ = '\0';	    memobj = 0;	    while (*memobjname != '\0')	      memobj = (memobj * 10) + (*memobjname++ - '0');	    /* Add a user reference on the memory object port, so we will	       still have one after _dl_map_object_from_fd calls our	       `close'.  */	    err = __mach_port_mod_refs (__mach_task_self (), memobj,					MACH_PORT_RIGHT_SEND, +1);	    assert_perror (err);	    lastslash = strrchr (p, '/');	    l = _dl_map_object_from_fd (lastslash ? lastslash + 1 : p,					memobj, strdup (p), 0);	    /* Squirrel away the memory object port where it	       can be retrieved by the program later.  */	    l->l_info[DT_NULL] = (void *) memobj;	  }#endif      /* Call elf/rtld.c's main program.  It will set everything	 up and leave us to transfer control to USER_ENTRY.  */      (*dl_main) ((const Elf32_Phdr *) _dl_hurd_data->phdr,		  _dl_hurd_data->phdrsz / sizeof (Elf32_Phdr),		  &_dl_hurd_data->user_entry);      /* The call above might screw a few things up.	 First of all, if _dl_skip_args is nonzero, we are ignoring	 the first few arguments.  However, if we have no Hurd startup	 data, it is the magical convention that ARGV[0] == P.  The	 startup code in init-first.c will get confused if this is not	 the case, so we must rearrange things to make it so.  We'll	 overwrite the origional ARGV[0] at P with ARGV[_dl_skip_args].	 Secondly, if we need to be secure, it removes some dangerous	 environment variables.  If we have no Hurd startup date this	 changes P (since that's the location after the terminating	 NULL in the list of environment variables).  We do the same	 thing as in the first case but make sure we recalculate P.	 If we do have Hurd startup data, we have to move the data	 such that it starts just after the terminating NULL in the	 environment list.	 We use memmove, since the locations might overlap.  */      if (__libc_enable_secure || _dl_skip_args)	{	  char **newp;	  for (newp = _environ; *newp++;);	  if (_dl_argv[-_dl_skip_args] == (char *) p)	    {	      if ((char *) newp != _dl_argv[0])		{		  assert ((char *) newp < _dl_argv[0]);		  _dl_argv[0] = memmove ((char *) newp, _dl_argv[0],					 strlen (_dl_argv[0]) + 1);		}	    }	  else	    {	      if ((void *) newp != _dl_hurd_data)		memmove (newp, _dl_hurd_data, sizeof (*_dl_hurd_data));	    }	}      {	extern void _dl_start_user (void);	/* Unwind the stack to ARGDATA and simulate a return from _dl_start	   to the RTLD_START code which will run the user's entry point.  */	RETURN_TO (argdata, &_dl_start_user, _dl_hurd_data->user_entry);      }    }  /* Set up so we can do RPCs.  */  __mach_init ();  /* Initialize frequently used global variable.  */  _dl_pagesize = __getpagesize ();fmh();				/* XXX */  /* See hurd/hurdstartup.c; this deals with getting information     from the exec server and slicing up the arguments.     Then it will call `go', above.  */  _hurd_startup (start_argptr, &go);  LOSE;  abort ();}