/* Create descriptor for processing file.
   Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 Red Hat, Inc.
   This file is part of elfutils.
   Written by Ulrich Drepper <drepper@redhat.com>, 1998.

   This file is free software; you can redistribute it and/or modify
   it under the terms of either

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at
       your option) any later version

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at
       your option) any later version

   or both in parallel, as here.

   elfutils 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
   General Public License for more details.

   You should have received copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see <http://www.gnu.org/licenses/>.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>

#include <system.h>
#include "libelfP.h"
#include "common.h"


/* Create descriptor for archive in memory.  */
static inline Elf *
file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize,
	      Elf_Cmd cmd, Elf *parent)
{
  Elf *elf;

  /* Create a descriptor.  */
  elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
                      ELF_K_AR, 0);
  if (elf != NULL)
    {
      /* We don't read all the symbol tables in advance.  All this will
	 happen on demand.  */
      elf->state.ar.offset = offset + SARMAG;

      elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name;
    }

  return elf;
}


static size_t
get_shnum (void *map_address, unsigned char *e_ident, int fildes,
	   int64_t offset, size_t maxsize)
{
  size_t result;
  union
  {
    Elf32_Ehdr *e32;
    Elf64_Ehdr *e64;
    void *p;
  } ehdr;
  union
  {
    Elf32_Ehdr e32;
    Elf64_Ehdr e64;
  } ehdr_mem;
  bool is32 = e_ident[EI_CLASS] == ELFCLASS32;

  /* Make the ELF header available.  */
  if (e_ident[EI_DATA] == MY_ELFDATA
      && (ALLOW_UNALIGNED
	  || (((size_t) e_ident
	       & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
		  - 1)) == 0)))
    ehdr.p = e_ident;
  else
    {
      /* We already read the ELF header.  We have to copy the header
	 since we possibly modify the data here and the caller
	 expects the memory it passes in to be preserved.  */
      ehdr.p = &ehdr_mem;

      if (is32)
	{
	  if (ALLOW_UNALIGNED)
	    {
	      ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
	      ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
	    }
	  else
	    memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));

	  if (e_ident[EI_DATA] != MY_ELFDATA)
	    {
	      CONVERT (ehdr_mem.e32.e_shnum);
	      CONVERT (ehdr_mem.e32.e_shoff);
	    }
	}
      else
	{
	  if (ALLOW_UNALIGNED)
	    {
	      ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
	      ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
	    }
	  else
	    memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));

	  if (e_ident[EI_DATA] != MY_ELFDATA)
	    {
	      CONVERT (ehdr_mem.e64.e_shnum);
	      CONVERT (ehdr_mem.e64.e_shoff);
	    }
	}
    }

  if (is32)
    {
      /* Get the number of sections from the ELF header.  */
      result = ehdr.e32->e_shnum;

      if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
	{
	  if (unlikely (ehdr.e32->e_shoff >= maxsize)
	      || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
	    /* Cannot read the first section header.  */
	    return 0;

	  if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
	      && (ALLOW_UNALIGNED
		  || (((size_t) ((char *) map_address + ehdr.e32->e_shoff))
		      & (__alignof__ (Elf32_Shdr) - 1)) == 0))
	    /* We can directly access the memory.  */
	    result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
				      + offset))->sh_size;
	  else
	    {
	      Elf32_Word size;
	      ssize_t r;

	      if (likely (map_address != NULL))
		/* gcc will optimize the memcpy to a simple memory
		   access while taking care of alignment issues.  */
		memcpy (&size, &((Elf32_Shdr *) ((char *) map_address
						 + ehdr.e32->e_shoff
						 + offset))->sh_size,
			sizeof (Elf32_Word));
	      else
		if (unlikely ((r = pread_retry (fildes, &size,
						sizeof (Elf32_Word),
						offset + ehdr.e32->e_shoff
						+ offsetof (Elf32_Shdr,
							    sh_size)))
			      != sizeof (Elf32_Word)))
		  {
		    if (r < 0)
		      __libelf_seterrno (ELF_E_INVALID_FILE);
		    else
		      __libelf_seterrno (ELF_E_INVALID_ELF);
		    return (size_t) -1l;
		  }

	      if (e_ident[EI_DATA] != MY_ELFDATA)
		CONVERT (size);

	      result = size;
	    }
	}

      /* If the section headers were truncated, pretend none were there.  */
      if (ehdr.e32->e_shoff > maxsize
	  || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
	result = 0;
    }
  else
    {
      /* Get the number of sections from the ELF header.  */
      result = ehdr.e64->e_shnum;

      if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
	{
	  if (unlikely (ehdr.e64->e_shoff >= maxsize)
	      || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
	    /* Cannot read the first section header.  */
	    return 0;

	  Elf64_Xword size;
	  if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
	      && (ALLOW_UNALIGNED
		  || (((size_t) ((char *) map_address + ehdr.e64->e_shoff))
		      & (__alignof__ (Elf64_Shdr) - 1)) == 0))
	    /* We can directly access the memory.  */
	    size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
				    + offset))->sh_size;
	  else
	    {
	      ssize_t r;
	      if (likely (map_address != NULL))
		/* gcc will optimize the memcpy to a simple memory
		   access while taking care of alignment issues.  */
		memcpy (&size, &((Elf64_Shdr *) ((char *) map_address
						 + ehdr.e64->e_shoff
						 + offset))->sh_size,
			sizeof (Elf64_Xword));
	      else
		if (unlikely ((r = pread_retry (fildes, &size,
						sizeof (Elf64_Xword),
						offset + ehdr.e64->e_shoff
						+ offsetof (Elf64_Shdr,
							    sh_size)))
			      != sizeof (Elf64_Xword)))
		  {
		    if (r < 0)
		      __libelf_seterrno (ELF_E_INVALID_FILE);
		    else
		      __libelf_seterrno (ELF_E_INVALID_ELF);
		    return (size_t) -1l;
		  }

	      if (e_ident[EI_DATA] != MY_ELFDATA)
		CONVERT (size);
	    }

	  /* Although sh_size is an Elf64_Xword and can contain a 64bit
	     value, we only expect an 32bit value max.  GElf_Word is
	     32bit unsigned.  */
	  if (size > ~((GElf_Word) 0))
	    {
	      /* Invalid value, it is too large.  */
	      __libelf_seterrno (ELF_E_INVALID_ELF);
	      return (size_t) -1l;
	    }

	  result = size;
	}

      /* If the section headers were truncated, pretend none were there.  */
      if (ehdr.e64->e_shoff > maxsize
	  || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
	result = 0;
    }

  return result;
}


/* Create descriptor for ELF file in memory.  */
static Elf *
file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
	       int64_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent)
{
  /* Verify the binary is of the class we can handle.  */
  if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
		 && e_ident[EI_CLASS] != ELFCLASS64)
		/* We also can only handle two encodings.  */
		|| (e_ident[EI_DATA] != ELFDATA2LSB
		    && e_ident[EI_DATA] != ELFDATA2MSB)))
    {
      /* Cannot handle this.  */
      __libelf_seterrno (ELF_E_INVALID_ELF);
      return NULL;
    }

  /* Determine the number of sections.  Returns -1 and sets libelf errno
     if the file handle or elf file is invalid.  Returns zero if there
     are no section headers (or they cannot be read).  */
  size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
  if (scncnt == (size_t) -1l)
    /* Could not determine the number of sections.  */
    return NULL;

  /* Check for too many sections.  */
  if (e_ident[EI_CLASS] == ELFCLASS32)
    {
      if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
	{
	  __libelf_seterrno (ELF_E_INVALID_ELF);
	  return NULL;
	}
    }
  else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
    {
      __libelf_seterrno (ELF_E_INVALID_ELF);
      return NULL;
    }

  /* We can now allocate the memory.  Even if there are no section headers,
     we allocate space for a zeroth section in case we need it later.  */
  const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
			 ? 1 : 0);
  Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
			   ELF_K_ELF, scnmax * sizeof (Elf_Scn));
  if (elf == NULL)
    /* Not enough memory.  allocate_elf will have set libelf errno.  */
    return NULL;

  assert ((unsigned int) scncnt == scncnt);
  assert (offsetof (struct Elf, state.elf32.scns)
	  == offsetof (struct Elf, state.elf64.scns));
  elf->state.elf32.scns.cnt = scncnt;
  elf->state.elf32.scns.max = scnmax;

  /* Some more or less arbitrary value.  */
  elf->state.elf.scnincr = 10;

  /* Make the class easily available.  */
  elf->class = e_ident[EI_CLASS];

  if (e_ident[EI_CLASS] == ELFCLASS32)
    {
      /* This pointer might not be directly usable if the alignment is
	 not sufficient for the architecture.  */
      Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset);

      /* This is a 32-bit binary.  */
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
	  && (ALLOW_UNALIGNED
	      || (((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0))
	{
	  /* We can use the mmapped memory.  */
	  elf->state.elf32.ehdr = ehdr;
	}
      else
	{
	  /* Copy the ELF header.  */
	  elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
					  sizeof (Elf32_Ehdr));

	  if (e_ident[EI_DATA] != MY_ELFDATA)
	    {
	      CONVERT (elf->state.elf32.ehdr_mem.e_type);
	      CONVERT (elf->state.elf32.ehdr_mem.e_machine);
	      CONVERT (elf->state.elf32.ehdr_mem.e_version);
	      CONVERT (elf->state.elf32.ehdr_mem.e_entry);
	      CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
	      CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
	      CONVERT (elf->state.elf32.ehdr_mem.e_flags);
	      CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
	      CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
	      CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
	      CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
	      CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
	      CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
	    }
	}

      /* Don't precache the phdr pointer here.
	 elf32_getphdr will validate it against the size when asked.  */

      Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff;
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
	  && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
	  && (ALLOW_UNALIGNED
	      || (((uintptr_t) ((char *) ehdr + e_shoff)
		   & (__alignof__ (Elf32_Shdr) - 1)) == 0)))
	{
	  if (unlikely (scncnt > 0 && e_shoff >= maxsize)
	      || unlikely (maxsize - e_shoff
			   < scncnt * sizeof (Elf32_Shdr)))
	    {
	    free_and_out:
	      free (elf);
	      __libelf_seterrno (ELF_E_INVALID_ELF);
	      return NULL;
	    }
	  elf->state.elf32.shdr
	    = (Elf32_Shdr *) ((char *) ehdr + e_shoff);

	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
	    {
	      elf->state.elf32.scns.data[cnt].index = cnt;
	      elf->state.elf32.scns.data[cnt].elf = elf;
	      elf->state.elf32.scns.data[cnt].shdr.e32 =
		&elf->state.elf32.shdr[cnt];
	      if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
		  && likely (elf->state.elf32.shdr[cnt].sh_size
			     <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
		elf->state.elf32.scns.data[cnt].rawdata_base =
		  elf->state.elf32.scns.data[cnt].data_base =
		  ((char *) map_address + offset
		   + elf->state.elf32.shdr[cnt].sh_offset);
	      elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;

	      /* If this is a section with an extended index add a
		 reference in the section which uses the extended
		 index.  */
	      if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
		  && elf->state.elf32.shdr[cnt].sh_link < scncnt)
		elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
		  = cnt;

	      /* Set the own shndx_index field in case it has not yet
		 been set.  */
	      if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
		elf->state.elf32.scns.data[cnt].shndx_index = -1;
	    }
	}
      else
	{
	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
	    {
	      elf->state.elf32.scns.data[cnt].index = cnt;
	      elf->state.elf32.scns.data[cnt].elf = elf;
	      elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
	    }
	}

      /* So far only one block with sections.  */
      elf->state.elf32.scns_last = &elf->state.elf32.scns;
    }
  else
    {
      /* This pointer might not be directly usable if the alignment is
	 not sufficient for the architecture.  */
      Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset);

      /* This is a 64-bit binary.  */
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
	  && (ALLOW_UNALIGNED
	      || (((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
	{
	  /* We can use the mmapped memory.  */
	  elf->state.elf64.ehdr = ehdr;
	}
      else
	{
	  /* Copy the ELF header.  */
	  elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
					  sizeof (Elf64_Ehdr));

	  if (e_ident[EI_DATA] != MY_ELFDATA)
	    {
	      CONVERT (elf->state.elf64.ehdr_mem.e_type);
	      CONVERT (elf->state.elf64.ehdr_mem.e_machine);
	      CONVERT (elf->state.elf64.ehdr_mem.e_version);
	      CONVERT (elf->state.elf64.ehdr_mem.e_entry);
	      CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
	      CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
	      CONVERT (elf->state.elf64.ehdr_mem.e_flags);
	      CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
	      CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
	      CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
	      CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
	      CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
	      CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
	    }
	}

      /* Don't precache the phdr pointer here.
	 elf64_getphdr will validate it against the size when asked.  */

      Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff;
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
	  && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
	  && (ALLOW_UNALIGNED
	      || (((uintptr_t) ((char *) ehdr + e_shoff)
		   & (__alignof__ (Elf64_Shdr) - 1)) == 0)))
	{
	  if (unlikely (scncnt > 0 && e_shoff >= maxsize)
	      || unlikely (maxsize - e_shoff
			   < scncnt * sizeof (Elf64_Shdr)))
	    goto free_and_out;
	  elf->state.elf64.shdr
	    = (Elf64_Shdr *) ((char *) ehdr + e_shoff);

	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
	    {
	      elf->state.elf64.scns.data[cnt].index = cnt;
	      elf->state.elf64.scns.data[cnt].elf = elf;
	      elf->state.elf64.scns.data[cnt].shdr.e64 =
		&elf->state.elf64.shdr[cnt];
	      if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
		  && likely (elf->state.elf64.shdr[cnt].sh_size
			     <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
		elf->state.elf64.scns.data[cnt].rawdata_base =
		  elf->state.elf64.scns.data[cnt].data_base =
		  ((char *) map_address + offset
		   + elf->state.elf64.shdr[cnt].sh_offset);
	      elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;

	      /* If this is a section with an extended index add a
		 reference in the section which uses the extended
		 index.  */
	      if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
		  && elf->state.elf64.shdr[cnt].sh_link < scncnt)
		elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
		  = cnt;

	      /* Set the own shndx_index field in case it has not yet
		 been set.  */
	      if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
		elf->state.elf64.scns.data[cnt].shndx_index = -1;
	    }
	}
      else
	{
	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
	    {
	      elf->state.elf64.scns.data[cnt].index = cnt;
	      elf->state.elf64.scns.data[cnt].elf = elf;
	      elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
	    }
	}

      /* So far only one block with sections.  */
      elf->state.elf64.scns_last = &elf->state.elf64.scns;
    }

  return elf;
}


Elf *
internal_function
__libelf_read_mmaped_file (int fildes, void *map_address,  int64_t offset,
			   size_t maxsize, Elf_Cmd cmd, Elf *parent)
{
  /* We have to find out what kind of file this is.  We handle ELF
     files and archives.  To find out what we have we must look at the
     header.  The header for an ELF file is EI_NIDENT bytes in size,
     the header for an archive file SARMAG bytes long.  */
  unsigned char *e_ident = (unsigned char *) map_address + offset;

  /* See what kind of object we have here.  */
  Elf_Kind kind = determine_kind (e_ident, maxsize);

  switch (kind)
    {
    case ELF_K_ELF:
      return file_read_elf (fildes, map_address, e_ident, offset, maxsize,
			    cmd, parent);

    case ELF_K_AR:
      return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);

    default:
      break;
    }

  /* This case is easy.  Since we cannot do anything with this file
     create a dummy descriptor.  */
  return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
		       ELF_K_NONE, 0);
}


static Elf *
read_unmmaped_file (int fildes, int64_t offset, size_t maxsize, Elf_Cmd cmd,
		    Elf *parent)
{
  /* We have to find out what kind of file this is.  We handle ELF
     files and archives.  To find out what we have we must read the
     header.  The identification header for an ELF file is EI_NIDENT
     bytes in size, but we read the whole ELF header since we will
     need it anyway later.  For archives the header in SARMAG bytes
     long.  Read the maximum of these numbers.

     XXX We have to change this for the extended `ar' format some day.

     Use a union to ensure alignment.  We might later access the
     memory as a ElfXX_Ehdr.  */
  union
  {
    Elf64_Ehdr ehdr;
    unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
  } mem;

  /* Read the head of the file.  */
  ssize_t nread = pread_retry (fildes, mem.header,
			       MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
				    maxsize),
			       offset);
  if (unlikely (nread == -1))
    {
      /* We cannot even read the head of the file.  Maybe FILDES is associated
	 with an unseekable device.  This is nothing we can handle.  */
      __libelf_seterrno (ELF_E_INVALID_FILE);
      return NULL;
    }

  /* See what kind of object we have here.  */
  Elf_Kind kind = determine_kind (mem.header, nread);

  switch (kind)
    {
    case ELF_K_AR:
      return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent);

    case ELF_K_ELF:
      /* Make sure at least the ELF header is contained in the file.  */
      if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32
			     ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
	return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
			      parent);
      FALLTHROUGH;

    default:
      break;
    }

  /* This case is easy.  Since we cannot do anything with this file
     create a dummy descriptor.  */
  return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent,
		       ELF_K_NONE, 0);
}


/* Open a file for reading.  If possible we will try to mmap() the file.  */
static struct Elf *
read_file (int fildes, int64_t offset, size_t maxsize,
	   Elf_Cmd cmd, Elf *parent)
{
  void *map_address = NULL;
  int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
		  || cmd == ELF_C_WRITE_MMAP
		  || cmd == ELF_C_READ_MMAP_PRIVATE);

  if (parent == NULL)
    {
      if (maxsize == ~((size_t) 0))
	{
	  /* We don't know in the moment how large the file is.
	     Determine it now.  */
	  struct stat st;

	  if (fstat (fildes, &st) == 0
	      && (sizeof (size_t) >= sizeof (st.st_size)
		  || st.st_size <= ~((size_t) 0)))
	    maxsize = (size_t) st.st_size;
	}
    }
  else
    {
      /* The parent is already loaded.  Use it.  */
      assert (maxsize != ~((size_t) 0));
    }

  if (use_mmap)
    {
      if (parent == NULL)
	{
	  /* We try to map the file ourself.  */
	  map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
					      ? PROT_READ
					      : PROT_READ|PROT_WRITE),
			      cmd == ELF_C_READ_MMAP_PRIVATE
			      || cmd == ELF_C_READ_MMAP
			      ? MAP_PRIVATE : MAP_SHARED,
			      fildes, offset);

	  if (map_address == MAP_FAILED)
	    map_address = NULL;
	}
      else
	{
	  map_address = parent->map_address;
	}
    }

  /* If we have the file in memory optimize the access.  */
  if (map_address != NULL)
    {
      assert (map_address != MAP_FAILED);

      struct Elf *result = __libelf_read_mmaped_file (fildes, map_address,
						      offset, maxsize, cmd,
						      parent);

      /* If something went wrong during the initialization unmap the
	 memory if we mmaped here.  */
      if (result == NULL
	  && (parent == NULL
	      || parent->map_address != map_address))
	munmap (map_address, maxsize);
      else if (parent == NULL)
	/* Remember that we mmap()ed the memory.  */
	result->flags |= ELF_F_MMAPPED;

      return result;
    }

  /* Otherwise we have to do it the hard way.  We read as much as necessary
     from the file whenever we need information which is not available.  */
  return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
}


/* Find the entry with the long names for the content of this archive.  */
static const char *
read_long_names (Elf *elf)
{
  off_t offset = SARMAG;	/* This is the first entry.  */
  struct ar_hdr hdrm;
  struct ar_hdr *hdr;
  char *newp;
  size_t len;

  while (1)
    {
      if (elf->map_address != NULL)
	{
	  if ((size_t) offset > elf->maximum_size
	      || elf->maximum_size - offset < sizeof (struct ar_hdr))
	    return NULL;

	  /* The data is mapped.  */
	  hdr = (struct ar_hdr *) (elf->map_address + offset);
	}
      else
	{
	  /* Read the header from the file.  */
	  if (unlikely (pread_retry (elf->fildes, &hdrm, sizeof (hdrm),
				     elf->start_offset + offset)
			!= sizeof (hdrm)))
	    return NULL;

	  hdr = &hdrm;
	}

      /* The ar_size is given as a fixed size decimal string, right
	 padded with spaces.  Make sure we read it properly even if
	 there is no terminating space.  */
      char buf[sizeof (hdr->ar_size) + 1];
      const char *string = hdr->ar_size;
      if (hdr->ar_size[sizeof (hdr->ar_size) - 1] != ' ')
	{
	  *((char *) mempcpy (buf, hdr->ar_size, sizeof (hdr->ar_size))) = '\0';
	  string = buf;
	}
      len = atol (string);

      if (memcmp (hdr->ar_name, "//              ", 16) == 0)
	break;

      offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
    }

  /* Sanity check len early if we can.  */
  if (elf->map_address != NULL)
    {
      if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
	return NULL;
    }

  /* Due to the stupid format of the long name table entry (which are not
     NUL terminted) we have to provide an appropriate representation anyhow.
     Therefore we always make a copy which has the appropriate form.  */
  newp = (char *) malloc (len);
  if (newp != NULL)
    {
      char *runp;

      if (elf->map_address != NULL)
	{
	  /* Simply copy it over.  */
	  elf->state.ar.long_names = (char *) memcpy (newp,
						      elf->map_address + offset
						      + sizeof (struct ar_hdr),
						      len);
	}
      else
	{
	  if (unlikely ((size_t) pread_retry (elf->fildes, newp, len,
					      elf->start_offset + offset
					      + sizeof (struct ar_hdr))
			!= len))
	    {
	      /* We were not able to read all data.  */
	      free (newp);
	      elf->state.ar.long_names = NULL;
	      return NULL;
	    }
	  elf->state.ar.long_names = newp;
	}

      elf->state.ar.long_names_len = len;

      /* Now NUL-terminate the strings.  */
      runp = newp;
      while (1)
        {
	  char *startp = runp;
	  runp = (char *) memchr (runp, '/', newp + len - runp);
	  if (runp == NULL)
	    {
	      /* This was the last entry.  Clear any left overs.  */
	      memset (startp, '\0', newp + len - startp);
	      break;
	    }

	  /* NUL-terminate the string.  */
	  *runp++ = '\0';

	  /* A sanity check.  Somebody might have generated invalid
	     archive.  */
	  if (runp >= newp + len)
	    break;
	}
    }

  return newp;
}


/* Read the next archive header.  */
int
internal_function
__libelf_next_arhdr_wrlock (Elf *elf)
{
  struct ar_hdr *ar_hdr;
  Elf_Arhdr *elf_ar_hdr;

  if (elf->map_address != NULL)
    {
      /* See whether this entry is in the file.  */
      if (unlikely ((size_t) elf->state.ar.offset
		    > elf->start_offset + elf->maximum_size
		    || (elf->start_offset + elf->maximum_size
			- elf->state.ar.offset) < sizeof (struct ar_hdr)))
	{
	  /* This record is not anymore in the file.  */
	  __libelf_seterrno (ELF_E_RANGE);
	  return -1;
	}
      ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
    }
  else
    {
      ar_hdr = &elf->state.ar.ar_hdr;

      if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr),
				 elf->state.ar.offset)
		    != sizeof (struct ar_hdr)))
	{
	  /* Something went wrong while reading the file.  */
	  __libelf_seterrno (ELF_E_RANGE);
	  return -1;
	}
    }

  /* One little consistency check.  */
  if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0))
    {
      /* This is no valid archive.  */
      __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
      return -1;
    }

  /* Copy the raw name over to a NUL terminated buffer.  */
  *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';

  elf_ar_hdr = &elf->state.ar.elf_ar_hdr;

  /* Now convert the `struct ar_hdr' into `Elf_Arhdr'.
     Determine whether this is a special entry.  */
  if (ar_hdr->ar_name[0] == '/')
    {
      if (ar_hdr->ar_name[1] == ' '
	  && memcmp (ar_hdr->ar_name, "/               ", 16) == 0)
	/* This is the index.  */
	elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
      else if (ar_hdr->ar_name[1] == 'S'
	       && memcmp (ar_hdr->ar_name, "/SYM64/         ", 16) == 0)
	/* 64-bit index.  */
	elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
      else if (ar_hdr->ar_name[1] == '/'
	       && memcmp (ar_hdr->ar_name, "//              ", 16) == 0)
	/* This is the array with the long names.  */
	elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
      else if (likely  (isdigit (ar_hdr->ar_name[1])))
	{
	  size_t offset;

	  /* This is a long name.  First we have to read the long name
	     table, if this hasn't happened already.  */
	  if (unlikely (elf->state.ar.long_names == NULL
			&& read_long_names (elf) == NULL))
	    {
	      /* No long name table although it is reference.  The archive is
		 broken.  */
	      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
	      return -1;
	    }

	  offset = atol (ar_hdr->ar_name + 1);
	  if (unlikely (offset >= elf->state.ar.long_names_len))
	    {
	      /* The index in the long name table is larger than the table.  */
	      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
	      return -1;
	    }
	  elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
	}
      else
	{
	  /* This is none of the known special entries.  */
	  __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
	  return -1;
	}
    }
  else
    {
      char *endp;

      /* It is a normal entry.  Copy over the name.  */
      endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
			       '/', 16);
      if (endp != NULL)
	endp[-1] = '\0';
      else
	{
	  /* In the old BSD style of archive, there is no / terminator.
	     Instead, there is space padding at the end of the name.  */
	  size_t i = 15;
	  do
	    elf->state.ar.ar_name[i] = '\0';
	  while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
	}

      elf_ar_hdr->ar_name = elf->state.ar.ar_name;
    }

  if (unlikely (ar_hdr->ar_size[0] == ' '))
    /* Something is really wrong.  We cannot live without a size for
       the member since it will not be possible to find the next
       archive member.  */
    {
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
      return -1;
    }

  /* Since there are no specialized functions to convert ASCII to
     time_t, uid_t, gid_t, mode_t, and off_t we use either atol or
     atoll depending on the size of the types.  We are also prepared
     for the case where the whole field in the `struct ar_hdr' is
     filled in which case we cannot simply use atol/l but instead have
     to create a temporary copy.  */

#define INT_FIELD(FIELD)						      \
  do									      \
    {									      \
      char buf[sizeof (ar_hdr->FIELD) + 1];				      \
      const char *string = ar_hdr->FIELD;				      \
      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')		      \
	{								      \
	  *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
	    = '\0';							      \
	  string = buf;							      \
	}								      \
      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))		      \
	elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string);     \
      else								      \
	elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string);    \
    }									      \
  while (0)

  INT_FIELD (ar_date);
  INT_FIELD (ar_uid);
  INT_FIELD (ar_gid);
  INT_FIELD (ar_mode);
  INT_FIELD (ar_size);

  if (elf_ar_hdr->ar_size < 0)
    {
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
      return -1;
    }

  /* Truncated file?  */
  size_t maxsize;
  maxsize = (elf->start_offset + elf->maximum_size
	     - elf->state.ar.offset - sizeof (struct ar_hdr));
  if ((size_t) elf_ar_hdr->ar_size > maxsize)
    elf_ar_hdr->ar_size = maxsize;

  return 0;
}


/* We were asked to return a clone of an existing descriptor.  This
   function must be called with the lock on the parent descriptor
   being held. */
static Elf *
dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
{
  struct Elf *result;

  if (fildes == -1)
    /* Allow the user to pass -1 as the file descriptor for the new file.  */
    fildes = ref->fildes;
  /* The file descriptor better should be the same.  If it was disconnected
     already (using `elf_cntl') we do not test it.  */
  else if (unlikely (ref->fildes != -1 && fildes != ref->fildes))
    {
      __libelf_seterrno (ELF_E_FD_MISMATCH);
      return NULL;
    }

  /* The mode must allow reading.  I.e., a descriptor creating with a
     command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is
     not allowed.  */
  if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
		&& ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
		&& ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
		&& ref->cmd != ELF_C_READ_MMAP_PRIVATE))
    {
      __libelf_seterrno (ELF_E_INVALID_OP);
      return NULL;
    }

  /* Now it is time to distinguish between reading normal files and
     archives.  Normal files can easily be handled be incrementing the
     reference counter and return the same descriptor.  */
  if (ref->kind != ELF_K_AR)
    {
      ++ref->ref_count;
      return ref;
    }

  /* This is an archive.  We must create a descriptor for the archive
     member the internal pointer of the archive file desriptor is
     pointing to.  First read the header of the next member if this
     has not happened already.  */
  if (ref->state.ar.elf_ar_hdr.ar_name == NULL
      && __libelf_next_arhdr_wrlock (ref) != 0)
    /* Something went wrong.  Maybe there is no member left.  */
    return NULL;

  /* We have all the information we need about the next archive member.
     Now create a descriptor for it.  */
  result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
		      ref->state.ar.elf_ar_hdr.ar_size, cmd, ref);

  /* Enlist this new descriptor in the list of children.  */
  if (result != NULL)
    {
      result->next = ref->state.ar.children;
      ref->state.ar.children = result;
    }

  return result;
}


/* Return desriptor for empty file ready for writing.  */
static struct Elf *
write_file (int fd, Elf_Cmd cmd)
{
  /* We simply create an empty `Elf' structure.  */
#define NSCNSALLOC	10
  Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF,
			      NSCNSALLOC * sizeof (Elf_Scn));

  if (result != NULL)
    {
      /* We have to write to the file in any case.  */
      result->flags = ELF_F_DIRTY;

      /* Some more or less arbitrary value.  */
      result->state.elf.scnincr = NSCNSALLOC;

      /* We have allocated room for some sections.  */
      assert (offsetof (struct Elf, state.elf32.scns)
	      == offsetof (struct Elf, state.elf64.scns));
      result->state.elf.scns_last = &result->state.elf32.scns;
      result->state.elf32.scns.max = NSCNSALLOC;
    }

  return result;
}

/* Lock if necessary before dup an archive.  */
static inline Elf *
lock_dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
{
  /* We need wrlock to dup an archive.  */
  if (ref->kind == ELF_K_AR)
    {
      rwlock_unlock (ref->lock);
      rwlock_wrlock (ref->lock);
    }
    /* Duplicate the descriptor.  */
  return dup_elf (fildes, cmd, ref);
}

/* Return a descriptor for the file belonging to FILDES.  */
Elf *
elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
{
  Elf *retval;

  if (unlikely (__libelf_version != EV_CURRENT))
    {
      /* Version wasn't set so far.  */
      __libelf_seterrno (ELF_E_NO_VERSION);
      return NULL;
    }

  if (ref != NULL)
    /* Make sure the descriptor is not suddenly going away.  */
    rwlock_rdlock (ref->lock);
  else if (unlikely (fcntl (fildes, F_GETFD) == -1 && errno == EBADF))
    {
      /* We cannot do anything productive without a file descriptor.  */
      __libelf_seterrno (ELF_E_INVALID_FILE);
      return NULL;
    }

  switch (cmd)
    {
    case ELF_C_NULL:
      /* We simply return a NULL pointer.  */
      retval = NULL;
      break;

    case ELF_C_READ_MMAP_PRIVATE:
      /* If we have a reference it must also be opened this way.  */
      if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
	{
	  __libelf_seterrno (ELF_E_INVALID_CMD);
	  retval = NULL;
	  break;
	}
      FALLTHROUGH;

    case ELF_C_READ:
    case ELF_C_READ_MMAP:
      if (ref != NULL)
	retval = lock_dup_elf (fildes, cmd, ref);
      else
	/* Create descriptor for existing file.  */
	retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
      break;

    case ELF_C_RDWR:
    case ELF_C_RDWR_MMAP:
      /* If we have a REF object it must also be opened using this
	 command.  */
      if (ref != NULL)
	{
	  if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
			&& ref->cmd != ELF_C_WRITE
			&& ref->cmd != ELF_C_WRITE_MMAP))
	    {
	      /* This is not ok.  REF must also be opened for writing.  */
	      __libelf_seterrno (ELF_E_INVALID_CMD);
	      retval = NULL;
	    }
	  else
	    retval = lock_dup_elf (fildes, cmd, ref);
	}
      else
	/* Create descriptor for existing file.  */
	retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
      break;

    case ELF_C_WRITE:
    case ELF_C_WRITE_MMAP:
      /* We ignore REF and prepare a descriptor to write a new file.  */
      retval = write_file (fildes, cmd);
      break;

    default:
      __libelf_seterrno (ELF_E_INVALID_CMD);
      retval = NULL;
      break;
    }

  /* Release the lock.  */
  if (ref != NULL)
    rwlock_unlock (ref->lock);

  return retval;
}
INTDEF(elf_begin)
