_dl_signal_error (errno, NULL, NULL, N_("cannot open zero fill device"));
INT(_dl_signal_error) (errno, NULL, NULL, N_("cannot open zero fill device"));
_dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,			char *realname, struct link_map *loader, int l_type,			int mode){  struct link_map *l = NULL;  const ElfW(Ehdr) *header;  const ElfW(Phdr) *phdr;  const ElfW(Phdr) *ph;  size_t maplength;  int type;  struct stat64 st;  /* Initialize to keep the compiler happy.  */  const char *errstring = NULL;  int errval = 0;  /* Get file information.  */  if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st) < 0, 0))    {      errstring = N_("cannot stat shared object");    call_lose_errno:      errval = errno;    call_lose:      lose (errval, fd, name, realname, l, errstring);    }  /* Look again to see if the real name matched another already loaded.  */  for (l = GL(dl_loaded); l; l = l->l_next)    if (l->l_ino == st.st_ino && l->l_dev == st.st_dev)      {	/* The object is already loaded.	   Just bump its reference count and return it.  */	__close (fd);	/* If the name is not in the list of names for this object add	   it.  */	free (realname);	add_name_to_object (l, name);	return l;      }  if (mode & RTLD_NOLOAD)    /* We are not supposed to load the object unless it is already       loaded.  So return now.  */    return NULL;  /* Print debugging message.  */  if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))    _dl_debug_printf ("file=%s;  generating link map\n", name);  /* This is the ELF header.  We read it in `open_verify'.  */  header = (void *) fbp->buf;#ifndef MAP_ANON# define MAP_ANON 0  if (_dl_zerofd == -1)    {      _dl_zerofd = _dl_sysdep_open_zero_fill ();      if (_dl_zerofd == -1)	{	  __close (fd);	  _dl_signal_error (errno, NULL, NULL,			    N_("cannot open zero fill device"));	}    }#endif  /* Enter the new object in the list of loaded objects.  */  l = _dl_new_object (realname, name, l_type, loader);  if (__builtin_expect (! l, 0))    {      errstring = N_("cannot create shared object descriptor");      goto call_lose_errno;    }  /* Extract the remaining details we need from the ELF header     and then read in the program header table.  */  l->l_entry = header->e_entry;  type = header->e_type;  l->l_phnum = header->e_phnum;  maplength = header->e_phnum * sizeof (ElfW(Phdr));  if (header->e_phoff + maplength <= fbp->len)    phdr = (void *) (fbp->buf + header->e_phoff);  else    {      phdr = alloca (maplength);      __lseek (fd, SEEK_SET, header->e_phoff);      if (__libc_read (fd, (void *) phdr, maplength) != maplength)	{	  errstring = N_("cannot read file data");	  goto call_lose_errno;	}    }  {    /* Scan the program header table, collecting its load commands.  */    struct loadcmd      {	ElfW(Addr) mapstart, mapend, dataend, allocend;	off_t mapoff;	int prot;      } loadcmds[l->l_phnum], *c;    size_t nloadcmds = 0;    /* The struct is initialized to zero so this is not necessary:    l->l_ld = 0;    l->l_phdr = 0;    l->l_addr = 0; */    for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph)      switch (ph->p_type)	{	  /* These entries tell us where to find things once the file's	     segments are mapped in.  We record the addresses it says	     verbatim, and later correct for the run-time load address.  */	case PT_DYNAMIC:	  l->l_ld = (void *) ph->p_vaddr;	  l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));	  break;	case PT_PHDR:	  l->l_phdr = (void *) ph->p_vaddr;	  break;	case PT_LOAD:	  /* A load command tells us to map in part of the file.	     We record the load commands and process them all later.  */	  if ((ph->p_align & (GL(dl_pagesize) - 1)) != 0)	    {	      errstring = N_("ELF load command alignment not page-aligned");	      goto call_lose;	    }	  if (((ph->p_vaddr - ph->p_offset) & (ph->p_align - 1)) != 0)	    {	      errstring		= N_("ELF load command address/offset not properly aligned");	      goto call_lose;	    }	  {	    struct loadcmd *c = &loadcmds[nloadcmds++];	    c->mapstart = ph->p_vaddr & ~(ph->p_align - 1);	    c->mapend = ((ph->p_vaddr + ph->p_filesz + GL(dl_pagesize) - 1)			 & ~(GL(dl_pagesize) - 1));	    c->dataend = ph->p_vaddr + ph->p_filesz;	    c->allocend = ph->p_vaddr + ph->p_memsz;	    c->mapoff = ph->p_offset & ~(ph->p_align - 1);	    /* Optimize a common case.  */#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7	    c->prot = (PF_TO_PROT		       >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf;#else	    c->prot = 0;	    if (ph->p_flags & PF_R)	      c->prot |= PROT_READ;	    if (ph->p_flags & PF_W)	      c->prot |= PROT_WRITE;	    if (ph->p_flags & PF_X)	      c->prot |= PROT_EXEC;#endif	  }	  break;	}    /* Now process the load commands and map segments into memory.  */    c = loadcmds;    /* Length of the sections to be loaded.  */    maplength = loadcmds[nloadcmds - 1].allocend - c->mapstart;    if (__builtin_expect (type, ET_DYN) == ET_DYN)      {	/* This is a position-independent shared object.  We can let the	   kernel map it anywhere it likes, but we must have space for all	   the segments in their specified positions relative to the first.	   So we map the first segment without MAP_FIXED, but with its	   extent increased to cover all the segments.  Then we remove	   access from excess portion, and there is known sufficient space	   there to remap from the later segments.	   As a refinement, sometimes we have an address that we would	   prefer to map such objects at; but this is only a preference,	   the OS can do whatever it likes. */	ElfW(Addr) mappref;	mappref = (ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart)		   - MAP_BASE_ADDR (l));	/* Remember which part of the address space this object uses.  */	l->l_map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplength,					      c->prot, MAP_COPY | MAP_FILE,					      fd, c->mapoff);	if ((void *) l->l_map_start == MAP_FAILED)	  {	  map_error:	    errstring = N_("failed to map segment from shared object");	    goto call_lose_errno;	  }	l->l_map_end = l->l_map_start + maplength;	l->l_addr = l->l_map_start - c->mapstart;	/* Change protection on the excess portion to disallow all access;	   the portions we do not remap later will be inaccessible as if	   unallocated.  Then jump into the normal segment-mapping loop to	   handle the portion of the segment past the end of the file	   mapping.  */	__mprotect ((caddr_t) (l->l_addr + c->mapend),		    loadcmds[nloadcmds - 1].allocend - c->mapend,		    PROT_NONE);	goto postmap;      }    else      {	/* This object is loaded at a fixed address.  This must never           happen for objects loaded with dlopen().  */	if (__builtin_expect (mode & __RTLD_DLOPEN, 0))	  {	    errstring = N_("cannot dynamically load executable");	    goto call_lose;	  }	/* Notify ELF_PREFERRED_ADDRESS that we have to load this one	   fixed.  */	ELF_FIXED_ADDRESS (loader, c->mapstart);      }    /* Remember which part of the address space this object uses.  */    l->l_map_start = c->mapstart + l->l_addr;    l->l_map_end = l->l_map_start + maplength;    while (c < &loadcmds[nloadcmds])      {	if (c->mapend > c->mapstart	    /* Map the segment contents from the file.  */	    && (__mmap ((void *) (l->l_addr + c->mapstart),			c->mapend - c->mapstart, c->prot,			MAP_FIXED | MAP_COPY | MAP_FILE, fd, c->mapoff)		== MAP_FAILED))	  goto map_error;      postmap:	if (l->l_phdr == 0	    && c->mapoff <= header->e_phoff	    && (c->mapend - c->mapstart + c->mapoff		>= header->e_phoff + header->e_phnum * sizeof (ElfW(Phdr))))	  /* Found the program header in this segment.  */	  l->l_phdr = (void *) (c->mapstart + header->e_phoff - c->mapoff);	if (c->allocend > c->dataend)	  {	    /* Extra zero pages should appear at the end of this segment,	       after the data mapped from the file.   */	    ElfW(Addr) zero, zeroend, zeropage;	    zero = l->l_addr + c->dataend;	    zeroend = l->l_addr + c->allocend;	    zeropage = ((zero + GL(dl_pagesize) - 1)			& ~(GL(dl_pagesize) - 1));	    if (zeroend < zeropage)	      /* All the extra data is in the last page of the segment.		 We can just zero it.  */	      zeropage = zeroend;	    if (zeropage > zero)	      {		/* Zero the final part of the last page of the segment.  */		if ((c->prot & PROT_WRITE) == 0)		  {		    /* Dag nab it.  */		    if (__mprotect ((caddr_t) (zero & ~(GL(dl_pagesize) - 1)),				    GL(dl_pagesize), c->prot|PROT_WRITE) < 0)		      {			errstring = N_("cannot change memory protections");			goto call_lose_errno;		      }		  }		memset ((void *) zero, '\0', zeropage - zero);		if ((c->prot & PROT_WRITE) == 0)		  __mprotect ((caddr_t) (zero & ~(GL(dl_pagesize) - 1)),			      GL(dl_pagesize), c->prot);	      }	    if (zeroend > zeropage)	      {		/* Map the remaining zero pages in from the zero fill FD.  */		caddr_t mapat;		mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage,				c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED,				ANONFD, 0);		if (mapat == MAP_FAILED)		  {		    errstring = N_("cannot map zero-fill pages");		    goto call_lose_errno;		  }	      }	  }	++c;      }    if (l->l_phdr == NULL)      {	/* The program header is not contained in any of the segments.	   We have to allocate memory ourself and copy it over from	   out temporary place.  */	ElfW(Phdr) *newp = (ElfW(Phdr) *) malloc (header->e_phnum						  * sizeof (ElfW(Phdr)));	if (newp == NULL)	  {	    errstring = N_("cannot allocate memory for program header");	    goto call_lose_errno;	  }	l->l_phdr = memcpy (newp, phdr,			    (header->e_phnum * sizeof (ElfW(Phdr))));	l->l_phdr_allocated = 1;      }    else      /* Adjust the PT_PHDR value by the runtime load address.  */      (ElfW(Addr)) l->l_phdr += l->l_addr;  }  /* We are done mapping in the file.  We no longer need the descriptor.  */  __close (fd);  /* Signal that we closed the file.  */  fd = -1;  if (l->l_type == lt_library && type == ET_EXEC)    l->l_type = lt_executable;  if (l->l_ld == 0)    {      if (type == ET_DYN)	{	  errstring = N_("object file has no dynamic section");	  goto call_lose;	}    }  else    (ElfW(Addr)) l->l_ld += l->l_addr;  l->l_entry += l->l_addr;  if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))    _dl_debug_printf ("  dynamic: 0x%0*lx  base: 0x%0*lx   size: 0x%0*Zx\n"		      "    entry: 0x%0*lx  phdr: 0x%0*lx  phnum:   %*u\n\n",		      (int) sizeof (void *) * 2, (unsigned long int) l->l_ld,		      (int) sizeof (void *) * 2, (unsigned long int) l->l_addr,		      (int) sizeof (void *) * 2, maplength,		      (int) sizeof (void *) * 2, (unsigned long int) l->l_entry,		      (int) sizeof (void *) * 2, (unsigned long int) l->l_phdr,		      (int) sizeof (void *) * 2, l->l_phnum);  elf_get_dynamic_info (l);  /* Make sure we are dlopen()ing an object which has the DF_1_NOOPEN     flag set.  */  if (__builtin_expect (l->l_flags_1 & DF_1_NOOPEN, 0)      && (mode & __RTLD_DLOPEN))    {      /* We are not supposed to load this object.  Free all resources.  */      __munmap ((void *) l->l_map_start, l->l_map_end - l->l_map_start);      if (!l->l_libname->dont_free)	free (l->l_libname);      if (l->l_phdr_allocated)	free ((void *) l->l_phdr);      errstring = N_("shared object cannot be dlopen()ed");      goto call_lose;    }  if (l->l_info[DT_HASH])    _dl_setup_hash (l);  /* If this object has DT_SYMBOLIC set modify now its scope.  We don't     have to do this for the main map.  */  if (__builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0)      && &l->l_searchlist != l->l_scope[0])    {      /* Create an appropriate searchlist.  It contains only this map.	 XXX This is the definition of DT_SYMBOLIC in SysVr4.  The old	 GNU ld.so implementation had a different interpretation which	 is more reasonable.  We are prepared to add this possibility	 back as part of a GNU extension of the ELF format.  */      l->l_symbolic_searchlist.r_list =	(struct link_map **) malloc (sizeof (struct link_map *));      if (l->l_symbolic_searchlist.r_list == NULL)	{	  errstring = N_("cannot create searchlist");	  goto call_lose_errno;	}      l->l_symbolic_searchlist.r_list[0] = l;      l->l_symbolic_searchlist.r_nlist = 1;      /* Now move the existing entries one back.  */      memmove (&l->l_scope[1], &l->l_scope[0],	       (l->l_scope_max - 1) * sizeof (l->l_scope[0]));      /* Now add the new entry.  */      l->l_scope[0] = &l->l_symbolic_searchlist;    }  /* Remember whether this object must be initialized first.  */  if (l->l_flags_1 & DF_1_INITFIRST)    GL(dl_initfirst) = l;  /* Finally the file information.  */  l->l_dev = st.st_dev;  l->l_ino = st.st_ino;  return l;}