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

   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 <endian.h>
#include <libelf.h>
#include <stdbool.h>
#include <string.h>

#include <system.h>
#include "libelfP.h"
#include "elf-knowledge.h"

#ifndef LIBELFBITS
# define LIBELFBITS 32
#endif

/* Some fields contain 32/64 sizes.  We cannot use Elf32/64_Word for those,
   since those are both 32bits.  Elf32/64_Xword is always 64bits.  */
#define Elf32_SizeWord Elf32_Word
#define Elf64_SizeWord Elf64_Xword


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))
    {
      ehdr->e_version = EV_CURRENT;
      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
    }
  else if (unlikely (ehdr->e_version != EV_CURRENT))
    {
      __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;
    }

  /* If phnum is zero make sure e_phoff is also zero and not some random
     value.  That would cause trouble in update_file.  */
  if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0)
    {
      ehdr->e_phoff = 0;
      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
    }

  return 0;
}


int64_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.  */
  ElfW2(LIBELFBITS,SizeWord) size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);

  /* Set the program header position.  */
  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
    (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
    {
      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,
		      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)
    {
      struct Elf_Scn *scn1 = NULL;
      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;

      /* Find the first section. */
      if (list->cnt > 1)
	scn1 = &list->data[1];
      else if (list->next != NULL)
	scn1 = &list->next->data[0];

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

      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);
	      int64_t offset = 0;

	      assert (shdr != NULL);
	      ElfW2(LIBELFBITS,SizeWord) sh_entsize = shdr->sh_entsize;
	      ElfW2(LIBELFBITS,SizeWord) sh_align = shdr->sh_addralign ?: 1;
	      if (unlikely (! powerof2 (sh_align)))
		{
		  __libelf_seterrno (ELF_E_INVALID_ALIGN);
		  return -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_CURRENT))
			{
			  __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 ((ElfW2(LIBELFBITS,SizeWord))
					(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 (size,
			      (shdr->sh_type != SHT_NOBITS
			       ? shdr->sh_offset + 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 ?: 1) < 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, 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.  */
		  int size_changed = 0;
		  update_if_changed (shdr->sh_size,
				     (ElfW2(LIBELFBITS,SizeWord)) offset,
				     size_changed);
		  changed |= size_changed;

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

		  scn->shdr_flags |= (offset_changed | size_changed);
		  scn->flags |= changed;
		}

	      /* Check that the section size is actually a multiple of
		 the entry size.  */
	      if (shdr->sh_entsize != 0 && shdr->sh_entsize != 1
		  && (elf->flags & ELF_F_PERMISSIVE) == 0)
		{
		  /* For compressed sections check the uncompressed size.  */
		  ElfW2(LIBELFBITS,SizeWord) sh_size;
		  if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
		    sh_size = shdr->sh_size;
		  else
		    {
		      ElfW2(LIBELFBITS,Chdr) *chdr;
		      chdr = elfw2(LIBELFBITS,getchdr) (scn);
		      if (unlikely (chdr == NULL))
			return -1;
		      sh_size = chdr->ch_size;
		    }

		  if (unlikely (sh_size % shdr->sh_entsize != 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.  */
      update_if_changed (ehdr->e_shentsize,
			 elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), ehdr_flags);
      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 (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, size, elf->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;
}
