/* Return number of program headers in the ELF file.
   Copyright (C) 2010, 2014 Red Hat, Inc.
   This file is part of elfutils.

   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 <gelf.h>
#include <stddef.h>

#include "libelfP.h"


int
__elf_getphdrnum_rdlock (elf, dst)
     Elf *elf;
     size_t *dst;
{
 if (unlikely (elf->state.elf64.ehdr == NULL))
   {
     /* Maybe no ELF header was created yet.  */
     __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
     return -1;
   }

 *dst = (elf->class == ELFCLASS32
	 ? elf->state.elf32.ehdr->e_phnum
	 : elf->state.elf64.ehdr->e_phnum);

 if (*dst == PN_XNUM)
   {
     const Elf_ScnList *const scns = (elf->class == ELFCLASS32
				      ? &elf->state.elf32.scns
				      : &elf->state.elf64.scns);

     /* If there are no section headers, perhaps this is really just 65536
	written without PN_XNUM support.  Either that or it's bad data.  */

     if (elf->class == ELFCLASS32)
       {
	 if (likely (scns->cnt > 0
		     && elf->state.elf32.scns.data[0].shdr.e32 != NULL))
	   *dst = scns->data[0].shdr.e32->sh_info;
       }
     else
       {
	 if (likely (scns->cnt > 0
		     && elf->state.elf64.scns.data[0].shdr.e64 != NULL))
	   *dst = scns->data[0].shdr.e64->sh_info;
       }
   }

 return 0;
}

int
elf_getphdrnum (elf, dst)
     Elf *elf;
     size_t *dst;
{
  int result;

  if (elf == NULL)
    return -1;

  if (unlikely (elf->kind != ELF_K_ELF))
    {
      __libelf_seterrno (ELF_E_INVALID_HANDLE);
      return -1;
    }

  rwlock_rdlock (elf->lock);
  result = __elf_getphdrnum_rdlock (elf, dst);

  /* Do some sanity checking to make sure phnum and phoff are consistent.  */
  Elf64_Off off = (elf->class == ELFCLASS32
		   ? elf->state.elf32.ehdr->e_phoff
		   : elf->state.elf64.ehdr->e_phoff);
  if (unlikely (off == 0))
    {
      *dst = 0;
      goto out;
    }

  if (unlikely (off >= elf->maximum_size))
    {
      __libelf_seterrno (ELF_E_INVALID_DATA);
      result = -1;
      goto out;
    }

  /* Check for too many sections.  */
  size_t phdr_size = (elf->class == ELFCLASS32
		      ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr));
  if (unlikely (*dst > SIZE_MAX / phdr_size))
    {
      __libelf_seterrno (ELF_E_INVALID_DATA);
      result = -1;
      goto out;
    }

  /* Truncated file?  Don't return more than can be indexed.  */
  if (unlikely (elf->maximum_size - off < *dst * phdr_size))
    *dst = (elf->maximum_size - off) / phdr_size;

out:
  rwlock_unlock (elf->lock);

  return result;
}
