/* 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;
}

static bfd_boolean
segment_nonexecutable_and_has_contents (struct elf_segment_map *seg)
{
  bfd_boolean any_contents = FALSE;
  unsigned int i;
  for (i = 0; i < seg->count; ++i)
    {
      if (seg->sections[i]->flags & SEC_CODE)
        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_tdata (abfd)->segment_map;
  struct elf_segment_map **first_load = NULL;
  struct elf_segment_map **last_load = NULL;
  bfd_boolean moved_headers = FALSE;

  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_nonexecutable_and_has_contents (seg))
            {
              /* 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 ATTRIBUTE_UNUSED)
{
  struct elf_segment_map **m = &elf_tdata (abfd)->segment_map;
  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;
}
