/* ELF program property support.
   Copyright (C) 2017-2020 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., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

/* GNU program property draft is at:

   https://github.com/hjl-tools/linux-abi/wiki/property-draft.pdf
 */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"

/* Get a property, allocate a new one if needed.  */

elf_property *
_bfd_elf_get_property (bfd *abfd, unsigned int type, unsigned int datasz)
{
  elf_property_list *p, **lastp;

  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    {
      /* Never should happen.  */
      abort ();
    }

  /* Keep the property list in order of type.  */
  lastp = &elf_properties (abfd);
  for (p = *lastp; p; p = p->next)
    {
      /* Reuse the existing entry.  */
      if (type == p->property.pr_type)
	{
	  if (datasz > p->property.pr_datasz)
	    {
	      /* This can happen when mixing 32-bit and 64-bit objects.  */
	      p->property.pr_datasz = datasz;
	    }
	  return &p->property;
	}
      else if (type < p->property.pr_type)
	break;
      lastp = &p->next;
    }
  p = (elf_property_list *) bfd_alloc (abfd, sizeof (*p));
  if (p == NULL)
    {
      _bfd_error_handler (_("%pB: out of memory in _bfd_elf_get_property"),
			  abfd);
      _exit (EXIT_FAILURE);
    }
  memset (p, 0, sizeof (*p));
  p->property.pr_type = type;
  p->property.pr_datasz = datasz;
  p->next = *lastp;
  *lastp = p;
  return &p->property;
}

/* Parse GNU properties.  */

bfd_boolean
_bfd_elf_parse_gnu_properties (bfd *abfd, Elf_Internal_Note *note)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  unsigned int align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4;
  bfd_byte *ptr = (bfd_byte *) note->descdata;
  bfd_byte *ptr_end = ptr + note->descsz;

  if (note->descsz < 8 || (note->descsz % align_size) != 0)
    {
    bad_size:
      _bfd_error_handler
	(_("warning: %pB: corrupt GNU_PROPERTY_TYPE (%ld) size: %#lx"),
	 abfd, note->type, note->descsz);
      return FALSE;
    }

  while (ptr != ptr_end)
    {
      unsigned int type;
      unsigned int datasz;
      elf_property *prop;

      if ((size_t) (ptr_end - ptr) < 8)
	goto bad_size;

      type = bfd_h_get_32 (abfd, ptr);
      datasz = bfd_h_get_32 (abfd, ptr + 4);
      ptr += 8;

      if (datasz > (size_t) (ptr_end - ptr))
	{
	  _bfd_error_handler
	    (_("warning: %pB: corrupt GNU_PROPERTY_TYPE (%ld) type (0x%x) datasz: 0x%x"),
	     abfd, note->type, type, datasz);
	  /* Clear all properties.  */
	  elf_properties (abfd) = NULL;
	  return FALSE;
	}

      if (type >= GNU_PROPERTY_LOPROC)
	{
	  if (bed->elf_machine_code == EM_NONE)
	    {
	      /* Ignore processor-specific properties with generic ELF
		 target vector.  They should be handled by the matching
		 ELF target vector.  */
	      goto next;
	    }
	  else if (type < GNU_PROPERTY_LOUSER
		   && bed->parse_gnu_properties)
	    {
	      enum elf_property_kind kind
		= bed->parse_gnu_properties (abfd, type, ptr, datasz);
	      if (kind == property_corrupt)
		{
		  /* Clear all properties.  */
		  elf_properties (abfd) = NULL;
		  return FALSE;
		}
	      else if (kind != property_ignored)
		goto next;
	    }
	}
      else
	{
	  switch (type)
	    {
	    case GNU_PROPERTY_STACK_SIZE:
	      if (datasz != align_size)
		{
		  _bfd_error_handler
		    (_("warning: %pB: corrupt stack size: 0x%x"),
		     abfd, datasz);
		  /* Clear all properties.  */
		  elf_properties (abfd) = NULL;
		  return FALSE;
		}
	      prop = _bfd_elf_get_property (abfd, type, datasz);
	      if (datasz == 8)
		prop->u.number = bfd_h_get_64 (abfd, ptr);
	      else
		prop->u.number = bfd_h_get_32 (abfd, ptr);
	      prop->pr_kind = property_number;
	      goto next;

	    case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
	      if (datasz != 0)
		{
		  _bfd_error_handler
		    (_("warning: %pB: corrupt no copy on protected size: 0x%x"),
		     abfd, datasz);
		  /* Clear all properties.  */
		  elf_properties (abfd) = NULL;
		  return FALSE;
		}
	      prop = _bfd_elf_get_property (abfd, type, datasz);
	      elf_has_no_copy_on_protected (abfd) = TRUE;
	      prop->pr_kind = property_number;
	      goto next;

	    default:
	      break;
	    }
	}

      _bfd_error_handler
	(_("warning: %pB: unsupported GNU_PROPERTY_TYPE (%ld) type: 0x%x"),
	 abfd, note->type, type);

    next:
      ptr += (datasz + (align_size - 1)) & ~ (align_size - 1);
    }

  return TRUE;
}

/* Merge GNU property BPROP with APROP.  If APROP isn't NULL, return TRUE
   if APROP is updated.  Otherwise, return TRUE if BPROP should be merged
   with ABFD.  */

static bfd_boolean
elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd, bfd *bbfd,
			  elf_property *aprop, elf_property *bprop)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;

  if (bed->merge_gnu_properties != NULL
      && pr_type >= GNU_PROPERTY_LOPROC
      && pr_type < GNU_PROPERTY_LOUSER)
    return bed->merge_gnu_properties (info, abfd, bbfd, aprop, bprop);

  switch (pr_type)
    {
    case GNU_PROPERTY_STACK_SIZE:
      if (aprop != NULL && bprop != NULL)
	{
	  if (bprop->u.number > aprop->u.number)
	    {
	      aprop->u.number = bprop->u.number;
	      return TRUE;
	    }
	  break;
	}
      /* FALLTHROUGH */

    case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
      /* Return TRUE if APROP is NULL to indicate that BPROP should
	 be added to ABFD.  */
      return aprop == NULL;

    default:
      /* Never should happen.  */
      abort ();
    }

  return FALSE;
}

/* Return the property of TYPE on *LISTP and remove it from *LISTP if RM is
   true.  Return NULL if not found.  */

static elf_property *
elf_find_and_remove_property (elf_property_list **listp,
			      unsigned int type, bfd_boolean rm)
{
  elf_property_list *list;

  for (list = *listp; list; list = list->next)
    {
      if (type == list->property.pr_type)
	{
	  /* Remove this property.  */
	  if (rm)
	    *listp = list->next;
	  return &list->property;
	}
      else if (type < list->property.pr_type)
	break;
      listp = &list->next;
    }

  return NULL;
}

/* Merge GNU property list *LISTP in ABFD with FIRST_PBFD.  */

static void
elf_merge_gnu_property_list (struct bfd_link_info *info, bfd *first_pbfd,
			     bfd *abfd, elf_property_list **listp)
{
  elf_property_list *p, **lastp;
  elf_property *pr;
  bfd_boolean number_p;
  bfd_vma number = 0;

  /* Merge each GNU property in FIRST_PBFD with the one on *LISTP.  */
  lastp = &elf_properties (first_pbfd);
  for (p = *lastp; p; p = p->next)
    if (p->property.pr_kind != property_remove)
      {
	if (p->property.pr_kind == property_number)
	  {
	    number_p = TRUE;
	    number = p->property.u.number;
	  }
	else
	  number_p = FALSE;
	pr = elf_find_and_remove_property (listp, p->property.pr_type,
					   TRUE);
	/* Pass NULL to elf_merge_gnu_properties for the property which
	   isn't on *LISTP.  */
	elf_merge_gnu_properties (info, first_pbfd, abfd, &p->property, pr);
	if (p->property.pr_kind == property_remove)
	  {
	    if (info->has_map_file)
	      {
		if (number_p)
		  {
		    if (pr != NULL)
		      info->callbacks->minfo
			(_("Removed property %W to merge %pB (0x%v) "
			   "and %pB (0x%v)\n"),
			 (bfd_vma) p->property.pr_type, first_pbfd,
			 number, abfd, pr->u.number);
		    else
		      info->callbacks->minfo
			(_("Removed property %W to merge %pB (0x%v) "
			   "and %pB (not found)\n"),
			 (bfd_vma) p->property.pr_type, first_pbfd,
			 number, abfd);
		  }
		else
		  {
		    if (pr != NULL)
		      info->callbacks->minfo
			(_("Removed property %W to merge %pB and %pB\n"),
			 (bfd_vma) p->property.pr_type, first_pbfd, abfd);
		    else
		      info->callbacks->minfo
			(_("Removed property %W to merge %pB and %pB "
			   "(not found)\n"),
			 (bfd_vma) p->property.pr_type, first_pbfd, abfd);
		  }
	      }

	    /* Remove this property.  */
	    *lastp = p->next;
	    continue;
	  }
	else if (number_p)
	  {
	    if (pr != NULL)
	      {
		if (p->property.u.number != number
		    || p->property.u.number != pr->u.number)
		  info->callbacks->minfo
		    (_("Updated property %W (0x%v) to merge %pB (0x%v) "
		       "and %pB (0x%v)\n"),
		     (bfd_vma) p->property.pr_type, p->property.u.number,
		     first_pbfd, number, abfd, pr->u.number);
	      }
	    else
	      {
		if (p->property.u.number != number)
		  info->callbacks->minfo
		    (_("Updated property %W (%v) to merge %pB (0x%v) "
		       "and %pB (not found)\n"),
		     (bfd_vma) p->property.pr_type, p->property.u.number,
		     first_pbfd, number, abfd);
	      }
	  }
	lastp = &p->next;
      }

  /* Merge the remaining properties on *LISTP with FIRST_PBFD.  */
  for (p = *listp; p != NULL; p = p->next)
    {
      if (p->property.pr_kind == property_number)
	{
	  number_p = TRUE;
	  number = p->property.u.number;
	}
      else
	number_p = FALSE;

      if (elf_merge_gnu_properties (info, first_pbfd, abfd, NULL, &p->property))
	{
	  if (p->property.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED)
	    elf_has_no_copy_on_protected (first_pbfd) = TRUE;

	  pr = _bfd_elf_get_property (first_pbfd, p->property.pr_type,
				      p->property.pr_datasz);
	  /* It must be a new property.  */
	  if (pr->pr_kind != property_unknown)
	    abort ();
	  /* Add a new property.  */
	  *pr = p->property;
	}
      else
	{
	  pr = elf_find_and_remove_property (&elf_properties (first_pbfd),
					     p->property.pr_type,
					     FALSE);
	  if (pr == NULL)
	    {
	      if (number_p)
		info->callbacks->minfo
		  (_("Removed property %W to merge %pB (not found) and "
		     "%pB (0x%v)\n"),
		   (bfd_vma) p->property.pr_type, first_pbfd, abfd,
		   number);
	      else
		info->callbacks->minfo
		  (_("Removed property %W to merge %pB and %pB\n"),
		   (bfd_vma) p->property.pr_type, first_pbfd, abfd);
	    }
	  else if (pr->pr_kind != property_remove)
	    abort ();
	}
    }
}

/* Get GNU property section size.  */

static bfd_size_type
elf_get_gnu_property_section_size (elf_property_list *list,
				   unsigned int align_size)
{
  bfd_size_type size;
  unsigned int descsz;

  /* Compute the output section size.  */
  descsz = offsetof (Elf_External_Note, name[sizeof "GNU"]);
  descsz = (descsz + 3) & -(unsigned int) 4;
  size = descsz;
  for (; list != NULL; list = list->next)
    {
      unsigned int datasz;
      /* Check if this property should be skipped.  */
      if (list->property.pr_kind == property_remove)
	continue;
      /* There are 4 byte type + 4 byte datasz for each property.  */
      if (list->property.pr_type == GNU_PROPERTY_STACK_SIZE)
	datasz = align_size;
      else
	datasz = list->property.pr_datasz;
      size += 4 + 4 + datasz;
      /* Align each property.  */
      size = (size + (align_size - 1)) & ~(align_size - 1);
    }

  return size;
}

/* Write GNU properties.  */

static void
elf_write_gnu_properties (bfd *abfd, bfd_byte *contents,
			  elf_property_list *list, unsigned int size,
			  unsigned int align_size)
{
  unsigned int descsz;
  unsigned int datasz;
  Elf_External_Note *e_note;

  e_note = (Elf_External_Note *) contents;
  descsz = offsetof (Elf_External_Note, name[sizeof "GNU"]);
  descsz = (descsz + 3) & -(unsigned int) 4;
  bfd_h_put_32 (abfd, sizeof "GNU", &e_note->namesz);
  bfd_h_put_32 (abfd, size - descsz, &e_note->descsz);
  bfd_h_put_32 (abfd, NT_GNU_PROPERTY_TYPE_0, &e_note->type);
  memcpy (e_note->name, "GNU", sizeof "GNU");

  size = descsz;
  for (; list != NULL; list = list->next)
    {
      /* Check if this property should be skipped.  */
      if (list->property.pr_kind == property_remove)
	continue;
      /* There are 4 byte type + 4 byte datasz for each property.  */
      if (list->property.pr_type == GNU_PROPERTY_STACK_SIZE)
	datasz = align_size;
      else
	datasz = list->property.pr_datasz;
      bfd_h_put_32 (abfd, list->property.pr_type, contents + size);
      bfd_h_put_32 (abfd, datasz, contents + size + 4);
      size += 4 + 4;

      /* Write out property value.  */
      switch (list->property.pr_kind)
	{
	case property_number:
	  switch (datasz)
	    {
	    default:
	      /* Never should happen.  */
	      abort ();

	    case 0:
	      break;

	    case 4:
	      bfd_h_put_32 (abfd, list->property.u.number,
			    contents + size);
	      break;

	    case 8:
	      bfd_h_put_64 (abfd, list->property.u.number,
			    contents + size);
	      break;
	    }
	  break;

	default:
	  /* Never should happen.  */
	  abort ();
	}
      size += datasz;

      /* Align each property.  */
      size = (size + (align_size - 1)) & ~ (align_size - 1);
    }
}

/* Set up GNU properties.  Return the first relocatable ELF input with
   GNU properties if found.  Otherwise, return NULL.  */

bfd *
_bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
{
  bfd *abfd, *first_pbfd = NULL;
  elf_property_list *list;
  asection *sec;
  bfd_boolean has_properties = FALSE;
  const struct elf_backend_data *bed
    = get_elf_backend_data (info->output_bfd);
  unsigned int elfclass = bed->s->elfclass;
  int elf_machine_code = bed->elf_machine_code;

  /* Find the first relocatable ELF input with GNU properties.  */
  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
	&& (abfd->flags & DYNAMIC) == 0
	&& elf_properties (abfd) != NULL)
      {
	has_properties = TRUE;

	/* Ignore GNU properties from ELF objects with different machine
	   code or class.  Also skip objects without a GNU_PROPERTY note
	   section.  */
	if ((elf_machine_code
	     == get_elf_backend_data (abfd)->elf_machine_code)
	    && (elfclass
		== get_elf_backend_data (abfd)->s->elfclass)
	    && bfd_get_section_by_name (abfd,
					NOTE_GNU_PROPERTY_SECTION_NAME) != NULL
	    )
	  {
	    /* Keep .note.gnu.property section in FIRST_PBFD.  */
	    first_pbfd = abfd;
	    break;
	  }
      }

  /* Do nothing if there is no .note.gnu.property section.  */
  if (!has_properties)
    return NULL;

  /* Merge .note.gnu.property sections.  */
  info->callbacks->minfo (_("\n"));
  info->callbacks->minfo (_("Merging program properties\n"));
  info->callbacks->minfo (_("\n"));

  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
    if (abfd != first_pbfd
	&& (abfd->flags & (DYNAMIC | BFD_PLUGIN | BFD_LINKER_CREATED)) == 0)
      {
	elf_property_list *null_ptr = NULL;
	elf_property_list **listp = &null_ptr;

	/* Merge .note.gnu.property section in relocatable ELF input.  */
	if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
	  {
	    list = elf_properties (abfd);

	    /* Ignore GNU properties from ELF objects with different
	       machine code.  */
	    if (list != NULL
		&& (elf_machine_code
		    == get_elf_backend_data (abfd)->elf_machine_code))
	      listp = &elf_properties (abfd);
	  }
	else
	  list = NULL;

	/* Merge properties with FIRST_PBFD.  FIRST_PBFD can be NULL
	   when all properties are from ELF objects with different
	   machine code or class.  */
	if (first_pbfd != NULL)
	  elf_merge_gnu_property_list (info, first_pbfd, abfd, listp);

	if (list != NULL)
	  {
	    /* Discard the .note.gnu.property section in this bfd.  */
	    sec = bfd_get_section_by_name (abfd,
					   NOTE_GNU_PROPERTY_SECTION_NAME);
	    if (sec != NULL)
	      sec->output_section = bfd_abs_section_ptr;
	  }
      }

  /* Rewrite .note.gnu.property section so that GNU properties are
     always sorted by type even if input GNU properties aren't sorted.  */
  if (first_pbfd != NULL)
    {
      bfd_size_type size;
      bfd_byte *contents;
      unsigned int align_size = elfclass == ELFCLASS64 ? 8 : 4;

      sec = bfd_get_section_by_name (first_pbfd,
				     NOTE_GNU_PROPERTY_SECTION_NAME);
      BFD_ASSERT (sec != NULL);

      /* Update stack size in .note.gnu.property with -z stack-size=N
	 if N > 0.  */
      if (info->stacksize > 0)
	{
	  elf_property *p;
	  bfd_vma stacksize = info->stacksize;

	  p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_STACK_SIZE,
				     align_size);
	  if (p->pr_kind == property_unknown)
	    {
	      /* Create GNU_PROPERTY_STACK_SIZE.  */
	      p->u.number = stacksize;
	      p->pr_kind = property_number;
	    }
	  else if (stacksize > p->u.number)
	    p->u.number = stacksize;
	}
      else if (elf_properties (first_pbfd) == NULL)
	{
	  /* Discard .note.gnu.property section if all properties have
	     been removed.  */
	  sec->output_section = bfd_abs_section_ptr;
	  return NULL;
	}

      /* Fix up GNU properties.  */
      if (bed->fixup_gnu_properties)
	bed->fixup_gnu_properties (info, &elf_properties (first_pbfd));

      if (elf_properties (first_pbfd) == NULL)
	{
	  /* Discard .note.gnu.property section if all properties have
	     been removed.  */
	  sec->output_section = bfd_abs_section_ptr;
	  return NULL;
	}

      /* Compute the section size.  */
      list = elf_properties (first_pbfd);
      size = elf_get_gnu_property_section_size (list, align_size);

      /* Update .note.gnu.property section now.  */
      sec->size = size;
      contents = (bfd_byte *) bfd_zalloc (first_pbfd, size);

      elf_write_gnu_properties (first_pbfd, contents, list, size,
				align_size);

      /* Cache the section contents for elf_link_input_bfd.  */
      elf_section_data (sec)->this_hdr.contents = contents;

      /* If GNU_PROPERTY_NO_COPY_ON_PROTECTED is set, protected data
	 symbol is defined in the shared object.  */
      if (elf_has_no_copy_on_protected (first_pbfd))
	info->extern_protected_data = FALSE;
    }

  return first_pbfd;
}

/* Convert GNU property size.  */

bfd_size_type
_bfd_elf_convert_gnu_property_size (bfd *ibfd, bfd *obfd)
{
  unsigned int align_size;
  const struct elf_backend_data *bed;
  elf_property_list *list = elf_properties (ibfd);

  bed = get_elf_backend_data (obfd);
  align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4;

  /* Get the output .note.gnu.property section size.  */
  return elf_get_gnu_property_section_size (list, align_size);
}

/* Convert GNU properties.  */

bfd_boolean
_bfd_elf_convert_gnu_properties (bfd *ibfd, asection *isec,
				 bfd *obfd, bfd_byte **ptr,
				 bfd_size_type *ptr_size)
{
  unsigned int size;
  bfd_byte *contents;
  unsigned int align_shift;
  const struct elf_backend_data *bed;
  elf_property_list *list = elf_properties (ibfd);

  bed = get_elf_backend_data (obfd);
  align_shift = bed->s->elfclass == ELFCLASS64 ? 3 : 2;

  /* Get the output .note.gnu.property section size.  */
  size = bfd_section_size (isec->output_section);

  /* Update the output .note.gnu.property section alignment.  */
  bfd_set_section_alignment (isec->output_section, align_shift);

  if (size > bfd_section_size (isec))
    {
      contents = (bfd_byte *) bfd_malloc (size);
      if (contents == NULL)
	return FALSE;
      free (*ptr);
      *ptr = contents;
    }
  else
    contents = *ptr;

  *ptr_size = size;

  /* Generate the output .note.gnu.property section.  */
  elf_write_gnu_properties (ibfd, contents, list, size, 1 << align_shift);

  return TRUE;
}
