/* ELF linking support for BFD.
   Copyright 1995, 1996, 1997 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 2 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 "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#define ARCH_SIZE 0
#include "elf-bfd.h"

boolean
_bfd_elf_create_got_section (abfd, info)
     bfd *abfd;
     struct bfd_link_info *info;
{
  flagword flags;
  register asection *s;
  struct elf_link_hash_entry *h;
  struct elf_backend_data *bed = get_elf_backend_data (abfd);
  int ptralign;

  /* This function may be called more than once.  */
  if (bfd_get_section_by_name (abfd, ".got") != NULL)
    return true;

  switch (bed->s->arch_size)
    {
    case 32: ptralign = 2; break;
    case 64: ptralign = 3; break;
    default: abort();
    }

  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
	   | SEC_LINKER_CREATED);

  s = bfd_make_section (abfd, ".got");
  if (s == NULL
      || !bfd_set_section_flags (abfd, s, flags)
      || !bfd_set_section_alignment (abfd, s, ptralign))
    return false;

  if (bed->want_got_plt)
    {
      s = bfd_make_section (abfd, ".got.plt");
      if (s == NULL
	  || !bfd_set_section_flags (abfd, s, flags)
	  || !bfd_set_section_alignment (abfd, s, ptralign))
	return false;
    }

  /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
     (or .got.plt) section.  We don't do this in the linker script
     because we don't want to define the symbol if we are not creating
     a global offset table.  */
  h = NULL;
  if (!(_bfd_generic_link_add_one_symbol
	(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
	 bed->got_symbol_offset, (const char *) NULL, false,
	 bed->collect, (struct bfd_link_hash_entry **) &h)))
    return false;
  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
  h->type = STT_OBJECT;

  if (info->shared
      && ! _bfd_elf_link_record_dynamic_symbol (info, h))
    return false;

  elf_hash_table (info)->hgot = h;

  /* The first bit of the global offset table is the header.  */
  s->_raw_size += bed->got_header_size + bed->got_symbol_offset;

  return true;
}


/* Create dynamic sections when linking against a dynamic object.  */

boolean
_bfd_elf_create_dynamic_sections (abfd, info)
     bfd *abfd;
     struct bfd_link_info *info;
{
  flagword flags, pltflags;
  register asection *s;
  struct elf_backend_data *bed = get_elf_backend_data (abfd);
  int ptralign;

  switch (bed->s->arch_size)
    {
    case 32: ptralign = 2; break;
    case 64: ptralign = 3; break;
    default: abort();
    }

  /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
     .rel[a].bss sections.  */

  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
	   | SEC_LINKER_CREATED);

  pltflags = flags;
  pltflags |= SEC_CODE;
  if (bed->plt_not_loaded)
    pltflags &= ~ (SEC_LOAD | SEC_HAS_CONTENTS);
  if (bed->plt_readonly)
    pltflags |= SEC_READONLY;

  s = bfd_make_section (abfd, ".plt");
  if (s == NULL
      || ! bfd_set_section_flags (abfd, s, pltflags)
      || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
    return false;

  if (bed->want_plt_sym)
    {
      /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
	 .plt section.  */
      struct elf_link_hash_entry *h = NULL;
      if (! (_bfd_generic_link_add_one_symbol
	     (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
	      (bfd_vma) 0, (const char *) NULL, false,
	      get_elf_backend_data (abfd)->collect,
	      (struct bfd_link_hash_entry **) &h)))
	return false;
      h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
      h->type = STT_OBJECT;

      if (info->shared
	  && ! _bfd_elf_link_record_dynamic_symbol (info, h))
	return false;
    }

  s = bfd_make_section (abfd, bed->use_rela_p ? ".rela.plt" : ".rel.plt");
  if (s == NULL
      || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
      || ! bfd_set_section_alignment (abfd, s, ptralign))
    return false;

  if (! _bfd_elf_create_got_section (abfd, info))
    return false;

  /* The .dynbss section is a place to put symbols which are defined
     by dynamic objects, are referenced by regular objects, and are
     not functions.  We must allocate space for them in the process
     image and use a R_*_COPY reloc to tell the dynamic linker to
     initialize them at run time.  The linker script puts the .dynbss
     section into the .bss section of the final image.  */
  s = bfd_make_section (abfd, ".dynbss");
  if (s == NULL
      || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
    return false;

  /* The .rel[a].bss section holds copy relocs.  This section is not
     normally needed.  We need to create it here, though, so that the
     linker will map it to an output section.  We can't just create it
     only if we need it, because we will not know whether we need it
     until we have seen all the input files, and the first time the
     main linker code calls BFD after examining all the input files
     (size_dynamic_sections) the input sections have already been
     mapped to the output sections.  If the section turns out not to
     be needed, we can discard it later.  We will never need this
     section when generating a shared object, since they do not use
     copy relocs.  */
  if (! info->shared)
    {
      s = bfd_make_section (abfd, bed->use_rela_p ? ".rela.bss" : ".rel.bss");
      if (s == NULL
	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
	  || ! bfd_set_section_alignment (abfd, s, ptralign))
	return false;
    }

  return true;
}


/* Record a new dynamic symbol.  We record the dynamic symbols as we
   read the input files, since we need to have a list of all of them
   before we can determine the final sizes of the output sections.
   Note that we may actually call this function even though we are not
   going to output any dynamic symbols; in some cases we know that a
   symbol should be in the dynamic symbol table, but only if there is
   one.  */

boolean
_bfd_elf_link_record_dynamic_symbol (info, h)
     struct bfd_link_info *info;
     struct elf_link_hash_entry *h;
{
  if (h->dynindx == -1)
    {
      struct bfd_strtab_hash *dynstr;
      char *p, *alc;
      const char *name;
      boolean copy;
      bfd_size_type indx;

      h->dynindx = elf_hash_table (info)->dynsymcount;
      ++elf_hash_table (info)->dynsymcount;

      dynstr = elf_hash_table (info)->dynstr;
      if (dynstr == NULL)
	{
	  /* Create a strtab to hold the dynamic symbol names.  */
	  elf_hash_table (info)->dynstr = dynstr = _bfd_elf_stringtab_init ();
	  if (dynstr == NULL)
	    return false;
	}

      /* We don't put any version information in the dynamic string
         table.  */
      name = h->root.root.string;
      p = strchr (name, ELF_VER_CHR);
      if (p == NULL)
	{
	  alc = NULL;
	  copy = false;
	}
      else
	{
	  alc = bfd_malloc (p - name + 1);
	  if (alc == NULL)
	    return false;
	  strncpy (alc, name, p - name);
	  alc[p - name] = '\0';
	  name = alc;
	  copy = true;
	}

      indx = _bfd_stringtab_add (dynstr, name, true, copy);

      if (alc != NULL)
	free (alc);

      if (indx == (bfd_size_type) -1)
	return false;
      h->dynstr_index = indx;
    }

  return true;
}

/* Create a special linker section, or return a pointer to a linker section already created  */

elf_linker_section_t *
_bfd_elf_create_linker_section (abfd, info, which, defaults)
     bfd *abfd;
     struct bfd_link_info *info;
     enum elf_linker_section_enum which;
     elf_linker_section_t *defaults;
{
  bfd *dynobj = elf_hash_table (info)->dynobj;
  elf_linker_section_t *lsect;

  /* Record the first bfd section that needs the special section */
  if (!dynobj)
    dynobj = elf_hash_table (info)->dynobj = abfd;

  /* If this is the first time, create the section */
  lsect = elf_linker_section (dynobj, which);
  if (!lsect)
    {
      asection *s;

      lsect = (elf_linker_section_t *)
	bfd_alloc (dynobj, sizeof (elf_linker_section_t));

      *lsect = *defaults;
      elf_linker_section (dynobj, which) = lsect;
      lsect->which = which;
      lsect->hole_written_p = false;

      /* See if the sections already exist */
      lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name);
      if (!s || (s->flags & defaults->flags) != defaults->flags)
	{
	  lsect->section = s = bfd_make_section_anyway (dynobj, lsect->name);

	  if (s == NULL)
	    return (elf_linker_section_t *)0;

	  bfd_set_section_flags (dynobj, s, defaults->flags);
	  bfd_set_section_alignment (dynobj, s, lsect->alignment);
	}
      else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment)
	bfd_set_section_alignment (dynobj, s, lsect->alignment);

      s->_raw_size = align_power (s->_raw_size, lsect->alignment);

      /* Is there a hole we have to provide?  If so check whether the segment is
	 too big already */
      if (lsect->hole_size)
	{
	  lsect->hole_offset = s->_raw_size;
	  s->_raw_size += lsect->hole_size;
	  if (lsect->hole_offset > lsect->max_hole_offset)
	    {
	      (*_bfd_error_handler) (_("%s: Section %s is already to large to put hole of %ld bytes in"),
				     bfd_get_filename (abfd),
				     lsect->name,
				     (long)lsect->hole_size);

	      bfd_set_error (bfd_error_bad_value);
	      return (elf_linker_section_t *)0;
	    }
	}

#ifdef DEBUG
      fprintf (stderr, "Creating section %s, current size = %ld\n",
	       lsect->name, (long)s->_raw_size);
#endif

      if (lsect->sym_name)
	{
	  struct elf_link_hash_entry *h = NULL;
#ifdef DEBUG
	  fprintf (stderr, "Adding %s to section %s\n",
		   lsect->sym_name,
		   lsect->name);
#endif
	  h = (struct elf_link_hash_entry *)
	    bfd_link_hash_lookup (info->hash, lsect->sym_name, false, false, false);

	  if ((h == NULL || h->root.type == bfd_link_hash_undefined)
	      && !(_bfd_generic_link_add_one_symbol (info,
						     abfd,
						     lsect->sym_name,
						     BSF_GLOBAL,
						     s,
						     ((lsect->hole_size)
						      ? s->_raw_size - lsect->hole_size + lsect->sym_offset
						      : lsect->sym_offset),
						     (const char *) NULL,
						     false,
						     get_elf_backend_data (abfd)->collect,
						     (struct bfd_link_hash_entry **) &h)))
	    return (elf_linker_section_t *)0;

	  if ((defaults->which != LINKER_SECTION_SDATA)
	      && (defaults->which != LINKER_SECTION_SDATA2))
	    h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;

	  h->type = STT_OBJECT;
	  lsect->sym_hash = h;

	  if (info->shared
	      && ! _bfd_elf_link_record_dynamic_symbol (info, h))
	    return (elf_linker_section_t *)0;
	}
    }

#if 0
  /* This does not make sense.  The sections which may exist in the
     object file have nothing to do with the sections we want to
     create.  */

  /* Find the related sections if they have been created */
  if (lsect->bss_name && !lsect->bss_section)
    lsect->bss_section = bfd_get_section_by_name (dynobj, lsect->bss_name);

  if (lsect->rel_name && !lsect->rel_section)
    lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
#endif

  return lsect;
}


/* Find a linker generated pointer with a given addend and type.  */

elf_linker_section_pointers_t *
_bfd_elf_find_pointer_linker_section (linker_pointers, addend, which)
     elf_linker_section_pointers_t *linker_pointers;
     bfd_signed_vma addend;
     elf_linker_section_enum_t which;
{
  for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
    {
      if (which == linker_pointers->which && addend == linker_pointers->addend)
	return linker_pointers;
    }

  return (elf_linker_section_pointers_t *)0;
}


/* Make the .rela section corresponding to the generated linker section.  */

boolean
_bfd_elf_make_linker_section_rela (dynobj, lsect, alignment)
     bfd *dynobj;
     elf_linker_section_t *lsect;
     int alignment;
{
  if (lsect->rel_section)
    return true;

  lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
  if (lsect->rel_section == NULL)
    {
      lsect->rel_section = bfd_make_section (dynobj, lsect->rel_name);
      if (lsect->rel_section == NULL
	  || ! bfd_set_section_flags (dynobj,
				      lsect->rel_section,
				      (SEC_ALLOC
				       | SEC_LOAD
				       | SEC_HAS_CONTENTS
				       | SEC_IN_MEMORY
				       | SEC_LINKER_CREATED
				       | SEC_READONLY))
	  || ! bfd_set_section_alignment (dynobj, lsect->rel_section, alignment))
	return false;
    }

  return true;
}
