/* Native Client support for ELF
   Copyright (C) 2012-2019 Free Software Foundation, Inc.

   This file is part of BFD, the Binary File Descriptor library.

   This program 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; either version 3 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf-nacl.h"
#include "elf/common.h"
#include "elf/internal.h"

static bfd_boolean
segment_executable (struct elf_segment_map *seg)
{
  if (seg->p_flags_valid)
    return (seg->p_flags & PF_X) != 0;
  else
    {
      /* The p_flags value has not been computed yet,
	 so we have to look through the sections.  */
      unsigned int i;
      for (i = 0; i < seg->count; ++i)
	if (seg->sections[i]->flags & SEC_CODE)
	  return TRUE;
    }
  return FALSE;
}

/* Determine if this segment is eligible to receive the file and program
   headers.  It must be read-only and non-executable.
   Its first section must start far enough past the page boundary to
   allow space for the headers.  */
static bfd_boolean
segment_eligible_for_headers (struct elf_segment_map *seg,
			      bfd_vma minpagesize, bfd_vma sizeof_headers)
{
  unsigned int i;
  if (seg->count == 0 || seg->sections[0]->lma % minpagesize < sizeof_headers)
    return FALSE;
  for (i = 0; i < seg->count; ++i)
    {
      if ((seg->sections[i]->flags & (SEC_CODE|SEC_READONLY)) != SEC_READONLY)
	return FALSE;
    }
  return TRUE;
}


/* We permute the segment_map to get BFD to do the file layout we want:
   The first non-executable PT_LOAD segment appears first in the file
   and contains the ELF file header and phdrs.  */
bfd_boolean
nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
{
  const struct elf_backend_data *const bed = get_elf_backend_data (abfd);
  struct elf_segment_map **m = &elf_seg_map (abfd);
  struct elf_segment_map **first_load = NULL;
  struct elf_segment_map **headers = NULL;
  int sizeof_headers;

  if (info != NULL && info->user_phdrs)
    /* The linker script used PHDRS explicitly, so don't change what the
       user asked for.  */
    return TRUE;

  if (info != NULL)
    /* We're doing linking, so evalute SIZEOF_HEADERS as in a linker script.  */
    sizeof_headers = bfd_sizeof_headers (abfd, info);
  else
    {
      /* We're not doing linking, so this is objcopy or suchlike.
	 We just need to collect the size of the existing headers.  */
      struct elf_segment_map *seg;
      sizeof_headers = bed->s->sizeof_ehdr;
      for (seg = *m; seg != NULL; seg = seg->next)
	sizeof_headers += bed->s->sizeof_phdr;
    }

  while (*m != NULL)
    {
      struct elf_segment_map *seg = *m;

      if (seg->p_type == PT_LOAD)
	{
	  bfd_boolean executable = segment_executable (seg);

	  if (executable
	      && seg->count > 0
	      && seg->sections[0]->vma % bed->minpagesize == 0)
	    {
	      asection *lastsec = seg->sections[seg->count - 1];
	      bfd_vma end = lastsec->vma + lastsec->size;
	      if (end % bed->minpagesize != 0)
		{
		  /* This is an executable segment that starts on a page
		     boundary but does not end on a page boundary.  Fill
		     it out to a whole page with code fill (the tail of
		     the segment will not be within any section).  Thus
		     the entire code segment can be mapped from the file
		     as whole pages and that mapping will contain only
		     valid instructions.

		     To accomplish this, we must fake out the code in
		     assign_file_positions_for_load_sections (elf.c) so
		     that it advances past the rest of the final page,
		     rather than trying to put the next (unaligned, or
		     unallocated) section.  We do this by appending a
		     dummy section record to this element in the segment
		     map.  No such output section ever actually exists,
		     but this gets the layout logic to advance the file
		     positions past this partial page.  Since we are
		     lying to BFD like this, nothing will ever know to
		     write the section contents.  So we do that by hand
		     after the fact, in nacl_final_write_processing, below.  */

		  struct elf_segment_map *newseg;
		  asection *sec;
		  struct bfd_elf_section_data *secdata;

		  BFD_ASSERT (!seg->p_size_valid);

		  secdata = bfd_zalloc (abfd, sizeof *secdata);
		  if (secdata == NULL)
		    return FALSE;

		  sec = bfd_zalloc (abfd, sizeof *sec);
		  if (sec == NULL)
		    return FALSE;

		  /* Fill in only the fields that actually affect the logic
		     in assign_file_positions_for_load_sections.  */
		  sec->vma = end;
		  sec->lma = lastsec->lma + lastsec->size;
		  sec->size = bed->minpagesize - (end % bed->minpagesize);
		  sec->flags = (SEC_ALLOC | SEC_LOAD
				| SEC_READONLY | SEC_CODE | SEC_LINKER_CREATED);
		  sec->used_by_bfd = secdata;

		  secdata->this_hdr.sh_type = SHT_PROGBITS;
		  secdata->this_hdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR;
		  secdata->this_hdr.sh_addr = sec->vma;
		  secdata->this_hdr.sh_size = sec->size;

		  newseg = bfd_alloc (abfd,
				      sizeof *newseg + ((seg->count + 1)
							* sizeof (asection *)));
		  if (newseg == NULL)
		    return FALSE;
		  memcpy (newseg, seg,
			  sizeof *newseg + (seg->count * sizeof (asection *)));
		  newseg->sections[newseg->count++] = sec;
		  *m = seg = newseg;
		}
	    }

	  /* First, we're just finding the earliest PT_LOAD.
	     By the normal rules, this will be the lowest-addressed one.  */
	  if (first_load == NULL)
	    first_load = m;

	  /* Now that we've noted the first PT_LOAD, we're looking for
	     the first non-executable PT_LOAD with a nonempty p_filesz.  */
	  else if (headers == NULL
		   && segment_eligible_for_headers (seg, bed->minpagesize,
						    sizeof_headers))
	    headers = m;
	}
      m = &seg->next;
    }

  if (headers != NULL)
    {
      struct elf_segment_map **last_load = NULL;
      struct elf_segment_map *seg;

      m = first_load;
      while ((seg = *m) != NULL)
	{
	  if (seg->p_type == PT_LOAD)
	    {
	      /* Clear the flags on any previous segment that
		 included the file header and phdrs.  */
	      seg->includes_filehdr = 0;
	      seg->includes_phdrs = 0;
	      /* Also strip out empty segments.  */
	      if (seg->count == 0)
		{
		  if (headers == &seg->next)
		    headers = m;
		  *m = seg->next;
		  continue;
		}
	      last_load = m;
	    }
	  m = &seg->next;
	}

      /* This segment will include those headers instead.  */
      seg = *headers;
      seg->includes_filehdr = 1;
      seg->includes_phdrs = 1;

      if (last_load != NULL && first_load != last_load && first_load != headers)
	{
	  /* Put the first PT_LOAD header last.  */
	  struct elf_segment_map *first = *first_load;
	  struct elf_segment_map *last = *last_load;
	  *first_load = first->next;
	  first->next = last->next;
	  last->next = first;
	}
    }

  return TRUE;
}

/* After nacl_modify_segment_map has done its work, the file layout has
   been done as we wanted.  But the PT_LOAD phdrs are no longer in the
   proper order for the ELF rule that they must appear in ascending address
   order.  So find the two segments we swapped before, and swap them back.  */
bfd_boolean
nacl_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
{
  struct elf_segment_map **m = &elf_seg_map (abfd);
  Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
  Elf_Internal_Phdr *p = phdr;

  if (info != NULL && info->user_phdrs)
    /* The linker script used PHDRS explicitly, so don't change what the
       user asked for.  */
    return TRUE;

  /* Find the PT_LOAD that contains the headers (should be the first).  */
  while (*m != NULL)
    {
      if ((*m)->p_type == PT_LOAD && (*m)->includes_filehdr)
	break;

      m = &(*m)->next;
      ++p;
    }

  if (*m != NULL)
    {
      struct elf_segment_map **first_load_seg = m;
      Elf_Internal_Phdr *first_load_phdr = p;
      struct elf_segment_map **next_load_seg = NULL;
      Elf_Internal_Phdr *next_load_phdr = NULL;

      /* Now move past that first one and find the PT_LOAD that should be
	 before it by address order.  */

      m = &(*m)->next;
      ++p;

      while (*m != NULL)
	{
	  if (p->p_type == PT_LOAD && p->p_vaddr < first_load_phdr->p_vaddr)
	    {
	      next_load_seg = m;
	      next_load_phdr = p;
	      break;
	    }

	  m = &(*m)->next;
	  ++p;
	}

      /* Swap their positions in the segment_map back to how they used to be.
	 The phdrs have already been set up by now, so we have to slide up
	 the earlier ones to insert the one that should be first.  */
      if (next_load_seg != NULL)
	{
	  Elf_Internal_Phdr move_phdr;
	  struct elf_segment_map *first_seg = *first_load_seg;
	  struct elf_segment_map *next_seg = *next_load_seg;
	  struct elf_segment_map *first_next = first_seg->next;
	  struct elf_segment_map *next_next = next_seg->next;

	  if (next_load_seg == &first_seg->next)
	    {
	      *first_load_seg = next_seg;
	      next_seg->next = first_seg;
	      first_seg->next = next_next;
	    }
	  else
	    {
	      *first_load_seg = first_next;
	      *next_load_seg = next_next;

	      first_seg->next = *next_load_seg;
	      *next_load_seg = first_seg;

	      next_seg->next = *first_load_seg;
	      *first_load_seg = next_seg;
	    }

	  move_phdr = *next_load_phdr;
	  memmove (first_load_phdr + 1, first_load_phdr,
		   (next_load_phdr - first_load_phdr) * sizeof move_phdr);
	  *first_load_phdr = move_phdr;
	}
    }

  return TRUE;
}

void
nacl_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
{
  struct elf_segment_map *seg;
  for (seg = elf_seg_map (abfd); seg != NULL; seg = seg->next)
    if (seg->p_type == PT_LOAD
	&& seg->count > 1
	&& seg->sections[seg->count - 1]->owner == NULL)
      {
	/* This is a fake section added in nacl_modify_segment_map, above.
	   It's not a real BFD section, so nothing wrote its contents.
	   Now write out its contents.  */

	asection *sec = seg->sections[seg->count - 1];
	char *fill;

	BFD_ASSERT (sec->flags & SEC_LINKER_CREATED);
	BFD_ASSERT (sec->flags & SEC_CODE);
	BFD_ASSERT (sec->size > 0);

	fill = abfd->arch_info->fill (sec->size, bfd_big_endian (abfd), TRUE);

	if (fill == NULL
	    || bfd_seek (abfd, sec->filepos, SEEK_SET) != 0
	    || bfd_bwrite (fill, sec->size, abfd) != sec->size)
	  {
	    /* We don't have a proper way to report an error here.  So
	       instead fudge things so that elf_write_shdrs_and_ehdr will
	       fail.  */
	    elf_elfheader (abfd)->e_shoff = (file_ptr) -1;
	  }

	free (fill);
      }
}
