|| (_dl_osversion && _dl_osversion < osversion))
|| (GL(dl_osversion) && GL(dl_osversion) < osversion))
open_verify (const char *name, struct filebuf *fbp){  /* This is the expected ELF header.  */#define ELF32_CLASS ELFCLASS32#define ELF64_CLASS ELFCLASS64#ifndef VALID_ELF_HEADER# define VALID_ELF_HEADER(hdr,exp,size)	(memcmp (hdr, exp, size) == 0)# define VALID_ELF_OSABI(osabi)		(osabi == ELFOSABI_SYSV)# define VALID_ELF_ABIVERSION(ver)	(ver == 0)#endif  static const unsigned char expected[EI_PAD] =  {    [EI_MAG0] = ELFMAG0,    [EI_MAG1] = ELFMAG1,    [EI_MAG2] = ELFMAG2,    [EI_MAG3] = ELFMAG3,    [EI_CLASS] = ELFW(CLASS),    [EI_DATA] = byteorder,    [EI_VERSION] = EV_CURRENT,    [EI_OSABI] = ELFOSABI_SYSV,    [EI_ABIVERSION] = 0  };  static const struct  {    ElfW(Word) vendorlen;    ElfW(Word) datalen;    ElfW(Word) type;    char vendor[4];  } expected_note = { 4, 16, 1, "GNU" };  int fd;  /* Initialize it to make the compiler happy.  */  const char *errstring = NULL;  int errval = 0;  /* Open the file.  We always open files read-only.  */  fd = __open (name, O_RDONLY);  if (fd != -1)    {      ElfW(Ehdr) *ehdr;      ElfW(Phdr) *phdr, *ph;      ElfW(Word) *abi_note, abi_note_buf[8];      unsigned int osversion;      size_t maplength;      /* We successfully openened the file.  Now verify it is a file	 we can use.  */      __set_errno (0);      fbp->len = __libc_read (fd, fbp->buf, sizeof (fbp->buf));      /* This is where the ELF header is loaded.  */      assert (sizeof (fbp->buf) > sizeof (ElfW(Ehdr)));      ehdr = (ElfW(Ehdr) *) fbp->buf;      /* Now run the tests.  */      if (__builtin_expect (fbp->len < (ssize_t) sizeof (ElfW(Ehdr)), 0))	{	  errval = errno;	  errstring = (errval == 0		       ? N_("file too short") : N_("cannot read file data"));	call_lose:	  lose (errval, fd, name, NULL, NULL, errstring);	}      /* See whether the ELF header is what we expect.  */      if (__builtin_expect (! VALID_ELF_HEADER (ehdr->e_ident, expected,						EI_PAD), 0))	{	  /* Something is wrong.  */	  if (*(Elf32_Word *) &ehdr->e_ident !=#if BYTE_ORDER == LITTLE_ENDIAN	      ((ELFMAG0 << (EI_MAG0 * 8)) |	       (ELFMAG1 << (EI_MAG1 * 8)) |	       (ELFMAG2 << (EI_MAG2 * 8)) |	       (ELFMAG3 << (EI_MAG3 * 8)))#else	      ((ELFMAG0 << (EI_MAG3 * 8)) |	       (ELFMAG1 << (EI_MAG2 * 8)) |	       (ELFMAG2 << (EI_MAG1 * 8)) |	       (ELFMAG3 << (EI_MAG0 * 8)))#endif	      )	    errstring = N_("invalid ELF header");	  else if (ehdr->e_ident[EI_CLASS] != ELFW(CLASS))	    /* This is not a fatal error.  On architectures where	       32-bit and 64-bit binaries can be run this might	       happen.  */	    goto close_and_out;	  else if (ehdr->e_ident[EI_DATA] != byteorder)	    {	      if (BYTE_ORDER == BIG_ENDIAN)		errstring = N_("ELF file data encoding not big-endian");	      else		errstring = N_("ELF file data encoding not little-endian");	    }	  else if (ehdr->e_ident[EI_VERSION] != EV_CURRENT)	    errstring	      = N_("ELF file version ident does not match current one");	  /* XXX We should be able so set system specific versions which are	     allowed here.  */	  else if (!VALID_ELF_OSABI (ehdr->e_ident[EI_OSABI]))	    errstring = N_("ELF file OS ABI invalid");	  else if (!VALID_ELF_ABIVERSION (ehdr->e_ident[EI_ABIVERSION]))	    errstring = N_("ELF file ABI version invalid");	  else	    /* Otherwise we don't know what went wrong.  */	    errstring = N_("internal error");	  goto call_lose;	}      if (__builtin_expect (ehdr->e_version, EV_CURRENT) != EV_CURRENT)	{	  errstring = N_("ELF file version does not match current one");	  goto call_lose;	}      if (! __builtin_expect (elf_machine_matches_host (ehdr), 1))	goto close_and_out;      else if (__builtin_expect (ehdr->e_phentsize, sizeof (ElfW(Phdr)))	       != sizeof (ElfW(Phdr)))	{	  errstring = N_("ELF file's phentsize not the expected size");	  goto call_lose;	}      else if (__builtin_expect (ehdr->e_type, ET_DYN) != ET_DYN	       && __builtin_expect (ehdr->e_type, ET_EXEC) != ET_EXEC)	{	  errstring = N_("only ET_DYN and ET_EXEC can be loaded");	  goto call_lose;	}      maplength = ehdr->e_phnum * sizeof (ElfW(Phdr));      if (ehdr->e_phoff + maplength <= fbp->len)	phdr = (void *) (fbp->buf + ehdr->e_phoff);      else	{	  phdr = alloca (maplength);	  __lseek (fd, SEEK_SET, ehdr->e_phoff);	  if (__libc_read (fd, (void *) phdr, maplength) != maplength)	    {	    read_error:	      errval = errno;	      errstring = N_("cannot read file data");	      goto call_lose;	    }	}      /* Check .note.ABI-tag if present.  */      for (ph = phdr; ph < &phdr[ehdr->e_phnum]; ++ph)	if (ph->p_type == PT_NOTE && ph->p_filesz == 32 && ph->p_align >= 4)	  {	    if (ph->p_offset + 32 <= fbp->len)	      abi_note = (void *) (fbp->buf + ph->p_offset);	    else	      {		__lseek (fd, SEEK_SET, ph->p_offset);		if (__libc_read (fd, (void *) abi_note_buf, 32) != 32)		  goto read_error;		abi_note = abi_note_buf;	      }	    if (memcmp (abi_note, &expected_note, sizeof (expected_note)))	      continue;	    osversion = (abi_note[5] & 0xff) * 65536			+ (abi_note[6] & 0xff) * 256			+ (abi_note[7] & 0xff);	    if (abi_note[4] != __ABI_TAG_OS		|| (_dl_osversion && _dl_osversion < osversion))	      {	      close_and_out:		__close (fd);		__set_errno (ENOENT);		fd = -1;	      }	    break;	  }    }  return fd;}