/* Native Client support for ELF
   Copyright 2012 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston,
   MA 02111-1307, USA.  */

#include "sysdep.h"
#include "bfd.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, non-executable, and have contents.
   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 maxpagesize, bfd_vma sizeof_headers)
{
  bfd_boolean any_contents = FALSE;
  unsigned int i;
  if (seg->count == 0 || seg->sections[0]->lma % maxpagesize < sizeof_headers)
    return FALSE;
  for (i = 0; i < seg->count; ++i)
    {
      if ((seg->sections[i]->flags & (SEC_CODE|SEC_READONLY)) != SEC_READONLY)
        return FALSE;
      if (seg->sections[i]->flags & SEC_HAS_CONTENTS)
        any_contents = TRUE;
    }
  return any_contents;
}


/* 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)
{
  struct elf_segment_map **m = &elf_seg_map (abfd);
  struct elf_segment_map **first_load = NULL;
  struct elf_segment_map **last_load = NULL;
  bfd_boolean moved_headers = FALSE;
  int sizeof_headers = info == NULL ? 0 : bfd_sizeof_headers (abfd, info);
  bfd_vma maxpagesize = get_elf_backend_data (abfd)->maxpagesize;

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

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

      if (seg->p_type == PT_LOAD)
        {
          /* First, we're just finding the earliest PT_LOAD.
             By the normal rules, this will be the lowest-addressed one.
             We only have anything interesting to do if it's executable.  */
          last_load = m;
          if (first_load == NULL)
            {
              if (!segment_executable (*m))
                return TRUE;
              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 (!moved_headers
                   && segment_eligible_for_headers (seg, maxpagesize,
                                                    sizeof_headers))
            {
              /* This is the one we were looking for!

                 First, clear the flags on previous segments that
                 say they include the file header and phdrs.  */
              struct elf_segment_map *prevseg;
              for (prevseg = *first_load;
                   prevseg != seg;
                   prevseg = prevseg->next)
                if (prevseg->p_type == PT_LOAD)
                  {
                    prevseg->includes_filehdr = 0;
                    prevseg->includes_phdrs = 0;
                  }

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

              moved_headers = TRUE;
            }
        }

      m = &seg->next;
    }

  if (first_load != last_load && moved_headers)
    {
      /* Now swap the first and last PT_LOAD segments'
         positions in segment_map.  */
      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;

          first_seg->next = next_next;
          *first_load_seg = next_seg;

          next_seg->next = first_next;
          *next_load_seg = first_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;
}
