Back to index

glibc  2.9
Defines | Functions | Variables
dl-sysdep.c File Reference
#include <hurd.h>
#include <link.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <ldsodefs.h>
#include <sys/wait.h>
#include <assert.h>
#include <sysdep.h>
#include <mach/mig_support.h>
#include "hurdstartup.h"
#include <hurd/lookup.h>
#include <hurd/auth.h>
#include <hurd/term.h>
#include <stdarg.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <entry.h>
#include <dl-machine.h>
#include <dl-procinfo.h>
#include <abort-instr.h>

Go to the source code of this file.

Defines

#define FMH   defined(__i386__)
#define fmh()   ((void)0)
#define unfmh()   ((void)0)
#define ABORT_INSTRUCTION

Functions

void __mach_init (void)
 ElfW (Addr)
void internal_function _dl_sysdep_start_cleanup (void)
static error_t open_file (const char *file_name, int flags, mach_port_t *port, struct stat64 *stat)
int weak_function __open (const char *file_name, int mode,...)
int weak_function __close (int fd)
__ssize_t weak_function __libc_read (int fd, void *buf, size_t nbytes)
 libc_hidden_weak (__libc_read)
 libc_hidden_weak (__libc_write)
off64_t weak_function __libc_lseek64 (int fd, off64_t offset, int whence)
__ptr_t weak_function __mmap (__ptr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
int weak_function __fxstat64 (int vers, int fd, struct stat64 *buf)
 libc_hidden_def (__fxstat64)
 libc_hidden_def (__xstat64)
pid_t weak_function __getpid ()
char *weak_function __getcwd (char *buf, size_t size)
void weak_function attribute_hidden _exit (int status)
 strong_alias (_exit, __GI__exit)
 strong_alias (abort, __GI_abort)
void internal_function _dl_show_auxv (void)
struct r_strlenpair
*internal_function 
_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, size_t *max_capstrlen)
void weak_function _dl_init_first (int argc,...)

Variables

int _dl_argc
char ** _dl_argv
char ** _environ
int __libc_enable_secure = 0
int __libc_multiple_libcs = 0
void * __libc_stack_end
struct hurd_startup_data_dl_hurd_data
int errno attribute_hidden
unsigned long int __hurd_sigthread_stack_base
unsigned long int __hurd_sigthread_stack_end
unsigned long int__hurd_sigthread_variables
static unsigned long int threadvars [_HURD_THREADVAR_MAX]
unsigned long int __hurd_threadvar_stack_offset = (unsigned long int) &threadvars
unsigned long int __hurd_threadvar_stack_mask

Define Documentation

#define FMH   defined(__i386__)

Definition at line 84 of file dl-sysdep.c.

#define fmh ( )    ((void)0)

Definition at line 86 of file dl-sysdep.c.

#define unfmh ( )    ((void)0)

Definition at line 87 of file dl-sysdep.c.


Function Documentation

Definition at line 355 of file dl-sysdep.c.

{
  if (fd != (int) MACH_PORT_NULL)
    __mach_port_deallocate (__mach_task_self (), (mach_port_t) fd);
  return 0;
}

Here is the call graph for this function:

int weak_function __fxstat64 ( int  vers,
int  fd,
struct stat64 buf 
)

Definition at line 510 of file dl-sysdep.c.

{
  error_t err;

  assert (vers == _STAT_VER);

  err = __io_stat ((mach_port_t) fd, buf);
  if (err)
    return __hurd_fail (err);

  return 0;
}

Here is the call graph for this function:

char* weak_function __getcwd ( char *  buf,
size_t  size 
)

Definition at line 574 of file dl-sysdep.c.

{
  errno = ENOSYS;
  return NULL;
}

Definition at line 554 of file dl-sysdep.c.

{
  pid_t pid, ppid;
  int orphaned;

  if (__proc_getpids (_dl_hurd_data->portarray[INIT_PORT_PROC],
                    &pid, &ppid, &orphaned))
    return -1;

  return pid;
}
off64_t weak_function __libc_lseek64 ( int  fd,
off64_t  offset,
int  whence 
)

Definition at line 437 of file dl-sysdep.c.

{
  error_t err;

  err = __io_seek ((mach_port_t) fd, offset, whence, &offset);
  if (err)
    return __hurd_fail (err);

  return offset;
}

Here is the call graph for this function:

__ssize_t weak_function __libc_read ( int  fd,
void *  buf,
size_t  nbytes 
)

Definition at line 363 of file dl-sysdep.c.

{
  error_t err;
  char *data;
  mach_msg_type_number_t nread;

  data = buf;
  nread = nbytes;
  err = __io_read ((mach_port_t) fd, &data, &nread, -1, nbytes);
  if (err)
    return __hurd_fail (err);

  if (data != buf)
    {
      memcpy (buf, data, nread);
      __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread);
    }

  return nread;
}

Here is the call graph for this function:

void __mach_init ( void  )
__ptr_t weak_function __mmap ( __ptr_t  addr,
size_t  len,
int  prot,
int  flags,
int  fd,
off_t  offset 
)

Definition at line 449 of file dl-sysdep.c.

{
  error_t err;
  vm_prot_t vmprot;
  vm_address_t mapaddr;
  mach_port_t memobj_rd, memobj_wr;

  vmprot = VM_PROT_NONE;
  if (prot & PROT_READ)
    vmprot |= VM_PROT_READ;
  if (prot & PROT_WRITE)
    vmprot |= VM_PROT_WRITE;
  if (prot & PROT_EXEC)
    vmprot |= VM_PROT_EXECUTE;

  if (flags & MAP_ANON)
    memobj_rd = MACH_PORT_NULL;
  else
    {
      assert (!(flags & MAP_SHARED));
      err = __io_map ((mach_port_t) fd, &memobj_rd, &memobj_wr);
      if (err)
       return __hurd_fail (err), MAP_FAILED;
      __mach_port_deallocate (__mach_task_self (), memobj_wr);
    }

  mapaddr = (vm_address_t) addr;
  err = __vm_map (__mach_task_self (),
                &mapaddr, (vm_size_t) len, ELF_MACHINE_USER_ADDRESS_MASK,
                !(flags & MAP_FIXED),
                memobj_rd,
                (vm_offset_t) offset,
                flags & (MAP_COPY|MAP_PRIVATE),
                vmprot, VM_PROT_ALL,
                (flags & MAP_SHARED) ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
  if (err == KERN_NO_SPACE && (flags & MAP_FIXED))
    {
      /* XXX this is not atomic as it is in unix! */
      /* The region is already allocated; deallocate it first.  */
      err = __vm_deallocate (__mach_task_self (), mapaddr, len);
      if (! err)
       err = __vm_map (__mach_task_self (),
                     &mapaddr, (vm_size_t) len,
                     ELF_MACHINE_USER_ADDRESS_MASK,
                     !(flags & MAP_FIXED),
                     memobj_rd, (vm_offset_t) offset,
                     flags & (MAP_COPY|MAP_PRIVATE),
                     vmprot, VM_PROT_ALL,
                     (flags & MAP_SHARED)
                     ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
    }

  if ((flags & MAP_ANON) == 0)
    __mach_port_deallocate (__mach_task_self (), memobj_rd);

  if (err)
    return __hurd_fail (err), MAP_FAILED;
  return (__ptr_t) mapaddr;
}

Here is the call graph for this function:

int weak_function __open ( const char *  file_name,
int  mode,
  ... 
)

Definition at line 344 of file dl-sysdep.c.

{
  mach_port_t port;
  error_t err = open_file (file_name, mode, &port, 0);
  if (err)
    return __hurd_fail (err);
  else
    return (int)port;
}

Here is the call graph for this function:

struct r_strlenpair* internal_function _dl_important_hwcaps ( const char *  platform,
size_t  platform_len,
size_t sz,
size_t max_capstrlen 
) [read]

Definition at line 649 of file dl-sysdep.c.

{
  struct r_strlenpair *result;

  /* Return an empty array.  Hurd has no hardware capabilities.  */
  result = (struct r_strlenpair *) malloc (sizeof (*result));
  if (result == NULL)
    _dl_signal_error (ENOMEM, NULL, NULL, "cannot create capability list");

  result[0].str = (char *) result; /* Does not really matter.  */
  result[0].len = 0;

  *sz = 1;
  return result;
}

Here is the call graph for this function:

void weak_function _dl_init_first ( int  argc,
  ... 
)

Definition at line 667 of file dl-sysdep.c.

{
  /* This no-op definition only gets used if libc is not linked in.  */
}

Definition at line 640 of file dl-sysdep.c.

{
  /* There is nothing to print.  Hurd has no auxiliary vector.  */
}

Definition at line 274 of file dl-sysdep.c.

{
  /* Deallocate the reply port and task port rights acquired by
     __mach_init.  We are done with them now, and the user will
     reacquire them for himself when he wants them.  */
  __mig_dealloc_reply_port (MACH_PORT_NULL);
  __mach_port_deallocate (__mach_task_self (), __mach_task_self_);
}

Here is the call graph for this function:

Definition at line 581 of file dl-sysdep.c.

{
  __proc_mark_exit (_dl_hurd_data->portarray[INIT_PORT_PROC],
                  W_EXITCODE (status, 0), 0);
  while (__task_terminate (__mach_task_self ()))
    __mach_task_self_ = (__mach_task_self) ();
}

Here is the call graph for this function:

ElfW ( Addr  )

Definition at line 116 of file dl-sysdep.c.

{
  void go (intptr_t *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;

      INTUSE(__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 ElfW(Phdr) *) _dl_hurd_data->phdr,
                _dl_hurd_data->phdrsz / sizeof (ElfW(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 (INTUSE(__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.  */
  GLRO(dl_pagesize) = __getpagesize ();

#if HP_TIMING_AVAIL
  HP_TIMING_NOW (_dl_cpuclock_offset);
#endif

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 ();
}

Here is the call graph for this function:

Definition at line 522 of file dl-sysdep.c.

{
  error_t err;
  mach_port_t port;

  assert (vers == _STAT_VER);

  err = open_file (file, 0, &port, buf);
  if (err)
    return __hurd_fail (err);

  __mach_port_deallocate (__mach_task_self (), port);

  return 0;
}

Here is the call graph for this function:

Definition at line 540 of file dl-sysdep.c.

{
  errno = ENOSYS;
  return -1;
}

Definition at line 383 of file dl-sysdep.c.

{
  error_t err;
  mach_msg_type_number_t nwrote;

  assert (fd < _hurd_init_dtablesize);

  err = __io_write (_hurd_init_dtable[fd], buf, nbytes, -1, &nwrote);
  if (err)
    return __hurd_fail (err);

  return nwrote;
}

Here is the call graph for this function:

Definition at line 399 of file dl-sysdep.c.

{
  if (fd >= _hurd_init_dtablesize)
    {
      errno = EBADF;
      return -1;
    }

  int i;
  size_t total = 0;
  for (i = 0; i < niov; ++i)
    total += iov[i].iov_len;

  if (total != 0)
    {
      char buf[total], *bufp = buf;
      error_t err;
      mach_msg_type_number_t nwrote;

      for (i = 0; i < niov; ++i)
       bufp = (memcpy (bufp, iov[i].iov_base, iov[i].iov_len)
              + iov[i].iov_len);

      err = __io_write (_hurd_init_dtable[fd], buf, total, -1, &nwrote);
      if (err)
       return __hurd_fail (err);

      return nwrote;
    }
  return 0;
}

Here is the call graph for this function:

static error_t open_file ( const char *  file_name,
int  flags,
mach_port_t *  port,
struct stat64 stat 
) [static]

Definition at line 291 of file dl-sysdep.c.

{
  enum retry_type doretry;
  char retryname[1024];            /* XXX string_t LOSES! */
  file_t startdir;
  error_t err;

  error_t use_init_port (int which, error_t (*operate) (file_t))
    {
      return (which < _dl_hurd_data->portarraysize
             ? ((*operate) (_dl_hurd_data->portarray[which]))
             : EGRATUITOUS);
    }
  file_t get_dtable_port (int fd)
    {
      if ((unsigned int) fd < _dl_hurd_data->dtablesize
         && _dl_hurd_data->dtable[fd] != MACH_PORT_NULL)
       {
         __mach_port_mod_refs (__mach_task_self (), _dl_hurd_data->dtable[fd],
                            MACH_PORT_RIGHT_SEND, +1);
         return _dl_hurd_data->dtable[fd];
       }
      errno = EBADF;
      return MACH_PORT_NULL;
    }

  assert (!(flags & ~O_READ));

  startdir = _dl_hurd_data->portarray[file_name[0] == '/' ?
                                  INIT_PORT_CRDIR : INIT_PORT_CWDIR];

  while (file_name[0] == '/')
    file_name++;

  err = __dir_lookup (startdir, (char *)file_name, O_RDONLY, 0,
                    &doretry, retryname, port);

  if (!err)
    err = __hurd_file_name_lookup_retry (use_init_port, get_dtable_port,
                                    __dir_lookup, doretry, retryname,
                                    O_RDONLY, 0, port);
  if (!err && stat)
    {
      err = __io_stat (*port, stat);
      if (err)
       __mach_port_deallocate (__mach_task_self (), *port);
    }

  return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

strong_alias ( _exit  ,
__GI__exit   
)

Definition at line 590 of file dl-sysdep.c.

{
  /* Try to abort using the system specific command.  */
  ABORT_INSTRUCTION;

  /* If the abort instruction failed, exit.  */
  _exit (127);

  /* If even this fails, make sure we never return.  */
  while (1)
    /* Try for ever and ever.  */
    ABORT_INSTRUCTION;
}
strong_alias ( abort  ,
__GI_abort   
)

Definition at line 617 of file dl-sysdep.c.

{
  return __mach_msg (msg, option, send_size, rcv_size, rcv_name,
                   timeout, notify);
}

Here is the call graph for this function:


Variable Documentation

Definition at line 70 of file dl-sysdep.c.

Definition at line 71 of file dl-sysdep.c.

Definition at line 72 of file dl-sysdep.c.

Definition at line 82 of file dl-sysdep.c.

unsigned long int __hurd_threadvar_stack_offset = (unsigned long int) &threadvars

Definition at line 81 of file dl-sysdep.c.

Definition at line 51 of file dl-sysdep.c.

Definition at line 53 of file dl-sysdep.c.

Definition at line 56 of file dl-sysdep.c.

char** _dl_argv

Definition at line 37 of file dl-support.c.

Definition at line 63 of file dl-sysdep.c.

char** _environ

Definition at line 67 of file dl-sysdep.c.

unsigned long int threadvars[_HURD_THREADVAR_MAX] [static]

Definition at line 79 of file dl-sysdep.c.