/* Update data structures for changes.
   Copyright (C) 2000-2010 Red Hat, Inc.
   This file is part of Red Hat elfutils.
   Written by Ulrich Drepper <drepper@redhat.com>, 2000.

   Red Hat elfutils is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by the
   Free Software Foundation; version 2 of the License.

   Red Hat 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 a copy of the GNU General Public License along
   with Red Hat elfutils; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.

   In addition, as a special exception, Red Hat, Inc. gives You the
   additional right to link the code of Red Hat elfutils with code licensed
   under any Open Source Initiative certified open source license
   (http://www.opensource.org/licenses/index.php) which requires the
   distribution of source code with any binary distribution and to
   distribute linked combinations of the two.  Non-GPL Code permitted under
   this exception must only link to the code of Red Hat elfutils through
   those well defined interfaces identified in the file named EXCEPTION
   found in the source code files (the "Approved Interfaces").  The files
   of Non-GPL Code may instantiate templates or use macros or inline
   functions from the Approved Interfaces without causing the resulting
   work to be covered by the GNU General Public License.  Only Red Hat,
   Inc. may make changes or additions to the list of Approved Interfaces.
   Red Hat's grant of this exception is conditioned upon your not adding
   any new exceptions.  If you wish to add a new Approved Interface or
   exception, please contact Red Hat.  You must obey the GNU General Public
   License in all respects for all of the Red Hat elfutils code and other
   code used in conjunction with Red Hat elfutils except the Non-GPL Code
   covered by this exception.  If you modify this file, you may extend this
   exception to your version of the file, but you are not obligated to do
   so.  If you do not wish to provide this exception without modification,
   you must delete this exception statement from your version and license
   this file solely under the GPL without exception.

   Red Hat elfutils is an included package of the Open Invention Network.
   An included package of the Open Invention Network is a package for which
   Open Invention Network licensees cross-license their patents.  No patent
   license is granted, either expressly or impliedly, by designation as an
   included package.  Should you wish to participate in the Open Invention
   Network licensing program, please visit www.openinventionnetwork.com
   <http://www.openinventionnetwork.com>.  */

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

#include <assert.h>
#include <endian.h>
#include <libelf.h>
#include <stdbool.h>
#include <string.h>
#include <sys/param.h>

#include "libelfP.h"
#include "elf-knowledge.h"

#ifndef LIBELFBITS
# define LIBELFBITS 32
#endif



static int
ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
			       size_t shnum, int *change_bop)
{
  /* Always write the magic bytes.  */
  if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
    {
      memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);
      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
    }

  /* Always set the file class.  */
  update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS),
		     elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);

  /* Set the data encoding if necessary.  */
  if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE))
    {
      ehdr->e_ident[EI_DATA] =
	BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB;
      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
    }
  else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM))
    {
      __libelf_seterrno (ELF_E_DATA_ENCODING);
      return 1;
    }
  else
    *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN
		    && ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
		   || (BYTE_ORDER == BIG_ENDIAN
		       && ehdr->e_ident[EI_DATA] != ELFDATA2MSB));

  /* Unconditionally overwrite the ELF version.  */
  update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT,
		     elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);

  if (unlikely (ehdr->e_version == EV_NONE)
      || unlikely (ehdr->e_version >= EV_NUM))
    {
      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
      return 1;
    }

  if (unlikely (shnum >= SHN_LORESERVE))
    {
      update_if_changed (ehdr->e_shnum, 0,
			 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
    }
  else
    update_if_changed (ehdr->e_shnum, shnum,
		       elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);

  if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)))
    {
      ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
    }

  return 0;
}


off_t
internal_function
__elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
{
  ElfW2(LIBELFBITS,Ehdr) *ehdr;
  int changed = 0;
  int ehdr_flags = 0;

  ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf);

  /* Set the default values.  */
  if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0)
    return -1;

  /* At least the ELF header is there.  */
  off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);

  /* Set the program header position.  */
  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL
      && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN
	  || ehdr->e_type == ET_CORE))
    (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
    {
      /* Only executables, shared objects, and core files have a program
	 header.  */
      if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
	  && unlikely (ehdr->e_type != ET_CORE))
	{
	  __libelf_seterrno (ELF_E_INVALID_PHDR);
	  return -1;
	}

      size_t phnum;
      if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
	return -1;

      if (elf->flags & ELF_F_LAYOUT)
	{
	  /* The user is supposed to fill out e_phoff.  Use it and
	     e_phnum to determine the maximum extend.  */
	  size = MAX ((size_t) size,
		      ehdr->e_phoff
		      + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum));
	}
      else
	{
	  update_if_changed (ehdr->e_phoff,
			     elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
			     ehdr_flags);

	  /* We need no alignment here.  */
	  size += elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum);
	}
    }

  if (shnum > 0)
    {
      Elf_ScnList *list;
      bool first = true;

      assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0);

      if (shnum >= SHN_LORESERVE)
	{
	  /* We have to  fill in the number of sections in the header
	     of the zeroth section.  */
	  Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];

	  update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
			     shnum, scn0->shdr_flags);
	}

      /* Go over all sections and find out how large they are.  */
      list = &elf->state.ELFW(elf,LIBELFBITS).scns;

      /* Load the section headers if necessary.  This loads the
	 headers for all sections.  */
      if (list->data[1].shdr.ELFW(e,LIBELFBITS) == NULL)
	(void) __elfw2(LIBELFBITS,getshdr_wrlock) (&list->data[1]);

      do
	{
	  for (size_t cnt = first == true; cnt < list->cnt; ++cnt)
	    {
	      Elf_Scn *scn = &list->data[cnt];
	      ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
	      off_t offset = 0;

	      assert (shdr != NULL);
	      ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize;
	      ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1;

	      /* Set the sh_entsize value if we can reliably detect it.  */
	      switch (shdr->sh_type)
		{
		case SHT_SYMTAB:
		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
		  break;
		case SHT_RELA:
		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1);
		  break;
		case SHT_GROUP:
		  /* Only relocatable files can contain section groups.  */
		  if (ehdr->e_type != ET_REL)
		    {
		      __libelf_seterrno (ELF_E_GROUP_NOT_REL);
		      return -1;
		    }
		  /* FALLTHROUGH */
		case SHT_SYMTAB_SHNDX:
		  sh_entsize = elf_typesize (32, ELF_T_WORD, 1);
		  break;
		case SHT_HASH:
		  sh_entsize = SH_ENTSIZE_HASH (ehdr);
		  break;
		case SHT_DYNAMIC:
		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1);
		  break;
		case SHT_REL:
		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1);
		  break;
		case SHT_DYNSYM:
		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
		  break;
		case SHT_SUNW_move:
		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1);
		  break;
		case SHT_SUNW_syminfo:
		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1);
		  break;
		default:
		  break;
		}

	      /* If the section header contained the wrong entry size
		 correct it and mark the header as modified.  */
	      update_if_changed (shdr->sh_entsize, sh_entsize,
				 scn->shdr_flags);

	      if (scn->data_read == 0
		  && __libelf_set_rawdata_wrlock (scn) != 0)
		/* Something went wrong.  The error value is already set.  */
		return -1;

	      /* Iterate over all data blocks.  */
	      if (list->data[cnt].data_list_rear != NULL)
		{
		  Elf_Data_List *dl = &scn->data_list;

		  while (dl != NULL)
		    {
		      Elf_Data *data = &dl->data.d;
		      if (dl == &scn->data_list && data->d_buf == NULL
			  && scn->rawdata.d.d_buf != NULL)
			data = &scn->rawdata.d;

		      if (unlikely (data->d_version == EV_NONE)
			  || unlikely (data->d_version >= EV_NUM))
			{
			  __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
			  return -1;
			}

		      if (unlikely (! powerof2 (data->d_align)))
			{
			  __libelf_seterrno (ELF_E_INVALID_ALIGN);
			  return -1;
			}

		      sh_align = MAX (sh_align, data->d_align);

		      if (elf->flags & ELF_F_LAYOUT)
			{
			  /* The user specified the offset and the size.
			     All we have to do is check whether this block
			     fits in the size specified for the section.  */
			  if (unlikely ((GElf_Word) (data->d_off
						     + data->d_size)
					> shdr->sh_size))
			    {
			      __libelf_seterrno (ELF_E_SECTION_TOO_SMALL);
			      return -1;
			    }
			}
		      else
			{
			  /* Determine the padding.  */
			  offset = ((offset + data->d_align - 1)
				    & ~(data->d_align - 1));

			  update_if_changed (data->d_off, offset, changed);

			  offset += data->d_size;
			}

		      /* Next data block.  */
		      dl = dl->next;
		    }
		}
	      else
		/* Get the size of the section from the raw data.  If
		   none is available the value is zero.  */
		offset += scn->rawdata.d.d_size;

	      if (elf->flags & ELF_F_LAYOUT)
		{
		  size = MAX ((GElf_Word) size,
			      shdr->sh_offset
			      + (shdr->sh_type != SHT_NOBITS
				 ? shdr->sh_size : 0));

		  /* The alignment must be a power of two.  This is a
		     requirement from the ELF specification.  Additionally
		     we test for the alignment of the section being large
		     enough for the largest alignment required by a data
		     block.  */
		  if (unlikely (! powerof2 (shdr->sh_addralign))
		      || unlikely (shdr->sh_addralign < sh_align))
		    {
		      __libelf_seterrno (ELF_E_INVALID_ALIGN);
		      return -1;
		    }
		}
	      else
		{
		  /* How much alignment do we need for this section.  */
		  update_if_changed (shdr->sh_addralign, sh_align,
				     scn->shdr_flags);

		  size = (size + sh_align - 1) & ~(sh_align - 1);
		  int offset_changed = 0;
		  update_if_changed (shdr->sh_offset, (GElf_Word) size,
				     offset_changed);
		  changed |= offset_changed;

		  if (offset_changed && scn->data_list_rear == NULL)
		    {
		      /* The position of the section in the file
			 changed.  Create the section data list.  */
		      if (__elf_getdata_rdlock (scn, NULL) == NULL)
			return -1;
		    }

		  /* See whether the section size is correct.  */
		  update_if_changed (shdr->sh_size, (GElf_Word) offset,
				     changed);

		  if (shdr->sh_type != SHT_NOBITS)
		    size += offset;

		  scn->flags |= changed;
		}

	      /* Check that the section size is actually a multiple of
		 the entry size.  */
	      if (shdr->sh_entsize != 0
		  && unlikely (shdr->sh_size % shdr->sh_entsize != 0)
		  && (elf->flags & ELF_F_PERMISSIVE) == 0)
		{
		  __libelf_seterrno (ELF_E_INVALID_SHENTSIZE);
		  return -1;
		}
	    }

	  assert (list->next == NULL || list->cnt == list->max);

	  first = false;
	}
      while ((list = list->next) != NULL);

      /* Store section information.  */
      if (elf->flags & ELF_F_LAYOUT)
	{
	  /* The user is supposed to fill out e_shoff.  Use it and
	     e_shnum (or sh_size of the dummy, first section header)
	     to determine the maximum extend.  */
	  size = MAX ((GElf_Word) size,
		      (ehdr->e_shoff
		       + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum))));
	}
      else
	{
	  /* Align for section header table.

	     Yes, we use `sizeof' and not `__alignof__' since we do not
	     want to be surprised by architectures with less strict
	     alignment rules.  */
#define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off))
	  size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1);

	  update_if_changed (ehdr->e_shoff, (GElf_Word) size, elf->flags);
	  update_if_changed (ehdr->e_shentsize,
			     elf_typesize (LIBELFBITS, ELF_T_SHDR, 1),
			     ehdr_flags);

	  /* Account for the section header size.  */
	  size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum);
	}
    }

  elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags;

  return size;
}
