/* BFD back-end for linux flavored m68k a.out binaries.
   Copyright (C) 1992-2016 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.  */

#define	TARGET_PAGE_SIZE 4096
#define ZMAGIC_DISK_BLOCK_SIZE 1024
#define	SEGMENT_SIZE TARGET_PAGE_SIZE
#define TEXT_START_ADDR	0x0

#define MACHTYPE_OK(mtype) ((mtype) == M_68020 || (mtype) == M_UNKNOWN)

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "aout/aout64.h"
#include "aout/stab_gnu.h"
#include "aout/ar.h"
#include "libaout.h"           /* BFD a.out internal data structures */

#define TARGET_IS_BIG_ENDIAN_P
#define DEFAULT_ARCH bfd_arch_m68k

/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
   remove whitespace added here, and thus will fail to concatenate
   the tokens.  */
#define MY(OP) CONCAT2 (m68k_aout_linux_,OP)
#define TARGETNAME "a.out-m68k-linux"

extern const bfd_target MY(vec);

/* We always generate QMAGIC files in preference to ZMAGIC files.  It
   would be possible to make this a linker option, if that ever
   becomes important.  */

static void MY_final_link_callback
  (bfd *, file_ptr *, file_ptr *, file_ptr *);

static bfd_boolean
m68klinux_bfd_final_link (bfd *abfd,
			  struct bfd_link_info *info)
{
  obj_aout_subformat (abfd) = q_magic_format;
  return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
}

#define MY_bfd_final_link m68klinux_bfd_final_link

/* Set the machine type correctly.  */

static bfd_boolean
m68klinux_write_object_contents (bfd *abfd)
{
  struct external_exec exec_bytes;
  struct internal_exec *execp = exec_hdr (abfd);

  N_SET_MACHTYPE (execp, M_68020);

  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;

  WRITE_HEADERS (abfd, execp);

  return TRUE;
}

#define MY_write_object_contents m68klinux_write_object_contents

/* Code to link against Linux a.out shared libraries.  */

/* See if a symbol name is a reference to the global offset table.  */

#ifndef GOT_REF_PREFIX
#define	GOT_REF_PREFIX	"__GOT_"
#endif

#define IS_GOT_SYM(name)  (CONST_STRNEQ (name, GOT_REF_PREFIX))

/* See if a symbol name is a reference to the procedure linkage table.  */

#ifndef PLT_REF_PREFIX
#define	PLT_REF_PREFIX	"__PLT_"
#endif

#define IS_PLT_SYM(name)  (CONST_STRNEQ (name, PLT_REF_PREFIX))

/* This string is used to generate specialized error messages.  */

#ifndef NEEDS_SHRLIB
#define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
#endif

/* This special symbol is a set vector that contains a list of
   pointers to fixup tables.  It will be present in any dynamically
   linked file.  The linker generated fixup table should also be added
   to the list, and it should always appear in the second slot (the
   first one is a dummy with a magic number that is defined in
   crt0.o).  */

#ifndef SHARABLE_CONFLICTS
#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__"
#endif

/* We keep a list of fixups.  The terminology is a bit strange, but
   each fixup contains two 32 bit numbers.  A regular fixup contains
   an address and a pointer, and at runtime we should store the
   address at the location pointed to by the pointer.  A builtin fixup
   contains two pointers, and we should read the address using one
   pointer and store it at the location pointed to by the other
   pointer.  Builtin fixups come into play when we have duplicate
   __GOT__ symbols for the same variable.  The builtin fixup will copy
   the GOT pointer from one over into the other.  */

struct fixup
{
  struct fixup *next;
  struct linux_link_hash_entry *h;
  bfd_vma value;

  /* Nonzero if this is a jump instruction that needs to be fixed,
     zero if this is just a pointer */
  char jump;

  char builtin;
};

/* We don't need a special hash table entry structure, but we do need
   to keep some information between linker passes, so we use a special
   hash table.  */

struct linux_link_hash_entry
{
  struct aout_link_hash_entry root;
};

struct linux_link_hash_table
{
  struct aout_link_hash_table root;

  /* First dynamic object found in link.  */
  bfd *dynobj;

  /* Number of fixups.  */
  size_t fixup_count;

  /* Number of builtin fixups.  */
  size_t local_builtins;

  /* List of fixups.  */
  struct fixup *fixup_list;
};

/* Routine to create an entry in an Linux link hash table.  */

static struct bfd_hash_entry *
linux_link_hash_newfunc (struct bfd_hash_entry *entry,
			 struct bfd_hash_table *table,
			 const char *string)
{
  struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry;

  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (ret == (struct linux_link_hash_entry *) NULL)
    ret = ((struct linux_link_hash_entry *)
	   bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
  if (ret == NULL)
    return (struct bfd_hash_entry *) ret;

  /* Call the allocation method of the superclass.  */
  ret = ((struct linux_link_hash_entry *)
	 NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
				       table, string));
  if (ret != NULL)
    {
      /* Set local fields; there aren't any.  */
    }

  return (struct bfd_hash_entry *) ret;
}

/* Create a Linux link hash table.  */

static struct bfd_link_hash_table *
linux_link_hash_table_create (bfd *abfd)
{
  struct linux_link_hash_table *ret;
  bfd_size_type amt = sizeof (struct linux_link_hash_table);

  ret = (struct linux_link_hash_table *) bfd_zmalloc (amt);
  if (ret == (struct linux_link_hash_table *) NULL)
    {
      bfd_set_error (bfd_error_no_memory);
      return (struct bfd_link_hash_table *) NULL;
    }
  if (!NAME(aout,link_hash_table_init) (&ret->root, abfd,
					linux_link_hash_newfunc,
					sizeof (struct linux_link_hash_entry)))
    {
      free (ret);
      return (struct bfd_link_hash_table *) NULL;
    }

  return &ret->root.root;
}

/* Look up an entry in a Linux link hash table.  */

#define linux_link_hash_lookup(table, string, create, copy, follow) \
  ((struct linux_link_hash_entry *) \
   aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
			  (follow)))

/* Traverse a Linux link hash table.  */

#define linux_link_hash_traverse(table, func, info)			\
  (aout_link_hash_traverse						\
   (&(table)->root,							\
    (bfd_boolean (*) (struct aout_link_hash_entry *, void *)) (func),	\
    (info)))

/* Get the Linux link hash table from the info structure.  This is
   just a cast.  */

#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash))

/* Store the information for a new fixup.  */

static struct fixup *
new_fixup (struct bfd_link_info *info,
	   struct linux_link_hash_entry *h,
	   bfd_vma value,
	   int builtin)
{
  struct fixup *f;

  f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
					  sizeof (struct fixup));
  if (f == NULL)
    return f;
  f->next = linux_hash_table (info)->fixup_list;
  linux_hash_table (info)->fixup_list = f;
  f->h = h;
  f->value = value;
  f->builtin = builtin;
  f->jump = 0;
  ++linux_hash_table (info)->fixup_count;
  return f;
}

/* We come here once we realize that we are going to link to a shared
   library.  We need to create a special section that contains the
   fixup table, and we ultimately need to add a pointer to this into
   the set vector for SHARABLE_CONFLICTS.  At this point we do not
   know the size of the section, but that's OK - we just need to
   create it for now.  */

static bfd_boolean
linux_link_create_dynamic_sections (bfd *abfd,
				    struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  flagword flags;
  asection *s;

  /* Note that we set the SEC_IN_MEMORY flag.  */
  flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;

  /* We choose to use the name ".linux-dynamic" for the fixup table.
     Why not? */
  s = bfd_make_section_with_flags (abfd, ".linux-dynamic", flags);
  if (s == NULL
      || ! bfd_set_section_alignment (abfd, s, 2))
    return FALSE;
  s->size = 0;
  s->contents = 0;

  return TRUE;
}

/* Function to add a single symbol to the linker hash table.  This is
   a wrapper around _bfd_generic_link_add_one_symbol which handles the
   tweaking needed for dynamic linking support.  */

static bfd_boolean
linux_add_one_symbol (struct bfd_link_info *info,
		      bfd *abfd,
		      const char *name,
		      flagword flags,
		      asection *section,
		      bfd_vma value,
		      const char *string,
		      bfd_boolean copy,
		      bfd_boolean collect,
		      struct bfd_link_hash_entry **hashp)
{
  struct linux_link_hash_entry *h;
  bfd_boolean insert;

  /* Look up and see if we already have this symbol in the hash table.
     If we do, and the defining entry is from a shared library, we
     need to create the dynamic sections.

     FIXME: What if abfd->xvec != info->output_bfd->xvec?  We may
     want to be able to link Linux a.out and ELF objects together,
     but serious confusion is possible.  */

  insert = FALSE;

  if (! bfd_link_relocatable (info)
      && linux_hash_table (info)->dynobj == NULL
      && strcmp (name, SHARABLE_CONFLICTS) == 0
      && (flags & BSF_CONSTRUCTOR) != 0
      && abfd->xvec == info->output_bfd->xvec)
    {
      if (! linux_link_create_dynamic_sections (abfd, info))
	return FALSE;
      linux_hash_table (info)->dynobj = abfd;
      insert = TRUE;
    }

  if (bfd_is_abs_section (section)
      && abfd->xvec == info->output_bfd->xvec)
    {
      h = linux_link_hash_lookup (linux_hash_table (info), name, FALSE,
				  FALSE, FALSE);
      if (h != NULL
	  && (h->root.root.type == bfd_link_hash_defined
	      || h->root.root.type == bfd_link_hash_defweak))
	{
	  struct fixup *f;

	  if (hashp != NULL)
	    *hashp = (struct bfd_link_hash_entry *) h;

	  f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
	  if (f == NULL)
	    return FALSE;
	  f->jump = IS_PLT_SYM (name);

	  return TRUE;
	}
    }

  /* Do the usual procedure for adding a symbol.  */
  if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
					  value, string, copy, collect,
					  hashp))
    return FALSE;

  /* Insert a pointer to our table in the set vector.  The dynamic
     linker requires this information */
  if (insert)
    {
      asection *s;

      /* Here we do our special thing to add the pointer to the
	 dynamic section in the SHARABLE_CONFLICTS set vector.  */
      s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
				   ".linux-dynamic");
      BFD_ASSERT (s != NULL);

      if (! (_bfd_generic_link_add_one_symbol
	     (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
	      BSF_GLOBAL | BSF_CONSTRUCTOR, s, (bfd_vma) 0, NULL,
	      FALSE, FALSE, NULL)))
	return FALSE;
    }

  return TRUE;
}

/* We will crawl the hash table and come here for every global symbol.
   We will examine each entry and see if there are indications that we
   need to add a fixup.  There are two possible cases - one is where
   you have duplicate definitions of PLT or GOT symbols - these will
   have already been caught and added as "builtin" fixups.  If we find
   that the corresponding non PLT/GOT symbol is also present, we
   convert it to a regular fixup instead.

   This function is called via linux_link_hash_traverse.  */

static bfd_boolean
linux_tally_symbols (struct linux_link_hash_entry *h,
		     void * data)
{
  struct bfd_link_info *info = (struct bfd_link_info *) data;
  struct fixup *f, *f1;
  int is_plt;
  struct linux_link_hash_entry *h1, *h2;
  bfd_boolean exists;

  if (h->root.root.type == bfd_link_hash_undefined
      && CONST_STRNEQ (h->root.root.root.string, NEEDS_SHRLIB))
    {
      const char *name;
      char *p;
      char *alloc = NULL;

      name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
      p = strrchr (name, '_');
      if (p != NULL)
	alloc = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 1);

      if (p == NULL || alloc == NULL)
	(*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),
			       name);
      else
	{
	  strcpy (alloc, name);
	  p = strrchr (alloc, '_');
	  *p++ = '\0';
	  (*_bfd_error_handler)
	    (_("Output file requires shared library `%s.so.%s'\n"),
	     alloc, p);
	  free (alloc);
	}

      abort ();
    }

  /* If this symbol is not a PLT/GOT, we do not even need to look at it */
  is_plt = IS_PLT_SYM (h->root.root.root.string);

  if (is_plt || IS_GOT_SYM (h->root.root.root.string))
    {
      /* Look up this symbol twice.  Once just as a regular lookup,
	 and then again following all of the indirect links until we
	 reach a real symbol.  */
      h1 = linux_link_hash_lookup (linux_hash_table (info),
				   (h->root.root.root.string
				    + sizeof PLT_REF_PREFIX - 1),
				   FALSE, FALSE, TRUE);
      /* h2 does not follow indirect symbols.  */
      h2 = linux_link_hash_lookup (linux_hash_table (info),
				   (h->root.root.root.string
				    + sizeof PLT_REF_PREFIX - 1),
				   FALSE, FALSE, FALSE);

      /* The real symbol must exist but if it is also an ABS symbol,
	 there is no need to have a fixup.  This is because they both
	 came from the same library.  If on the other hand, we had to
	 use an indirect symbol to get to the real symbol, we add the
	 fixup anyway, since there are cases where these symbols come
	 from different shared libraries */
      if (h1 != NULL
	  && (((h1->root.root.type == bfd_link_hash_defined
		|| h1->root.root.type == bfd_link_hash_defweak)
	       && ! bfd_is_abs_section (h1->root.root.u.def.section))
	      || h2->root.root.type == bfd_link_hash_indirect))
	{
	  /* See if there is a "builtin" fixup already present
	     involving this symbol.  If so, convert it to a regular
	     fixup.  In the end, this relaxes some of the requirements
	     about the order of performing fixups.  */
	  exists = FALSE;
	  for (f1 = linux_hash_table (info)->fixup_list;
	       f1 != NULL;
	       f1 = f1->next)
	    {
	      if ((f1->h != h && f1->h != h1)
		  || (! f1->builtin && ! f1->jump))
		continue;
	      if (f1->h == h1)
		exists = TRUE;
	      if (! exists
		  && bfd_is_abs_section (h->root.root.u.def.section))
		{
		  f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
		  f->jump = is_plt;
		}
	      f1->h = h1;
	      f1->jump = is_plt;
	      f1->builtin = 0;
	      exists = TRUE;
	    }
	  if (! exists
	      && bfd_is_abs_section (h->root.root.u.def.section))
	    {
	      f = new_fixup (info, h1, h->root.root.u.def.value, 0);
	      if (f == NULL)
		{
		  /* FIXME: No way to return error.  */
		  abort ();
		}
	      f->jump = is_plt;
	    }
	}

      /* Quick and dirty way of stripping these symbols from the
	 symtab.  */
      if (bfd_is_abs_section (h->root.root.u.def.section))
	h->root.written = TRUE;
    }

  return TRUE;
}

/* This is called to set the size of the .linux-dynamic section is.
   It is called by the Linux linker emulation before_allocation
   routine.  We have finished reading all of the input files, and now
   we just scan the hash tables to find out how many additional fixups
   are required.  */

bfd_boolean
bfd_m68klinux_size_dynamic_sections (bfd *output_bfd,
				     struct bfd_link_info *info)
{
  struct fixup *f;
  asection *s;

  if (output_bfd->xvec != &MY(vec))
    return TRUE;

  /* First find the fixups...  */
  linux_link_hash_traverse (linux_hash_table (info),
			    linux_tally_symbols,
			    info);

  /* If there are builtin fixups, leave room for a marker.  This is
     used by the dynamic linker so that it knows that all that follow
     are builtin fixups instead of regular fixups.  */
  for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
    {
      if (f->builtin)
	{
	  ++linux_hash_table (info)->fixup_count;
	  ++linux_hash_table (info)->local_builtins;
	  break;
	}
    }

  if (linux_hash_table (info)->dynobj == NULL)
    {
      if (linux_hash_table (info)->fixup_count > 0)
	abort ();
      return TRUE;
    }

  /* Allocate memory for our fixup table.  We will fill it in later.  */
  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
			       ".linux-dynamic");
  if (s != NULL)
    {
      s->size = linux_hash_table (info)->fixup_count + 1;
      s->size *= 8;
      s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->size);
      if (s->contents == NULL)
	{
	  bfd_set_error (bfd_error_no_memory);
	  return FALSE;
	}
    }

  return TRUE;
}

/* We come here once we are ready to actually write the fixup table to
   the output file.  Scan the fixup tables and so forth and generate
   the stuff we need.  */

static bfd_boolean
linux_finish_dynamic_link (bfd *output_bfd, struct bfd_link_info *info)
{
  asection *s, *os, *is;
  bfd_byte *fixup_table;
  struct linux_link_hash_entry *h;
  struct fixup *f;
  unsigned int new_addr;
  int section_offset;
  unsigned int fixups_written;

  if (linux_hash_table (info)->dynobj == NULL)
    return TRUE;

  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
			       ".linux-dynamic");
  BFD_ASSERT (s != NULL);
  os = s->output_section;
  fixups_written = 0;

#ifdef LINUX_LINK_DEBUG
  printf ("Fixup table file offset: %x  VMA: %x\n",
	  os->filepos + s->output_offset,
	  os->vma + s->output_offset);
#endif

  fixup_table = s->contents;
  bfd_put_32 (output_bfd, (bfd_vma) linux_hash_table (info)->fixup_count,
	      fixup_table);
  fixup_table += 4;

  /* Fill in fixup table.  */
  for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
    {
      if (f->builtin)
	continue;

      if (f->h->root.root.type != bfd_link_hash_defined
	  && f->h->root.root.type != bfd_link_hash_defweak)
	{
	  (*_bfd_error_handler)
	    (_("Symbol %s not defined for fixups\n"),
	     f->h->root.root.root.string);
	  continue;
	}

      is = f->h->root.root.u.def.section;
      section_offset = is->output_section->vma + is->output_offset;
      new_addr = f->h->root.root.u.def.value + section_offset;

#ifdef LINUX_LINK_DEBUG
      printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
	      new_addr, f->value);
#endif

      if (f->jump)
	{
	  bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
	  fixup_table += 4;
	  bfd_put_32 (output_bfd, f->value + 2, fixup_table);
	  fixup_table += 4;
	}
      else
	{
	  bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
	  fixup_table += 4;
	  bfd_put_32 (output_bfd, f->value, fixup_table);
	  fixup_table += 4;
	}
      ++fixups_written;
    }

  if (linux_hash_table (info)->local_builtins != 0)
    {
      /* Special marker so we know to switch to the other type of fixup */
      bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
      fixup_table += 4;
      bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
      fixup_table += 4;
      ++fixups_written;
      for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
	{
	  if (! f->builtin)
	    continue;

	  if (f->h->root.root.type != bfd_link_hash_defined
	      && f->h->root.root.type != bfd_link_hash_defweak)
	    {
	      (*_bfd_error_handler)
		(_("Symbol %s not defined for fixups\n"),
		 f->h->root.root.root.string);
	      continue;
	    }

	  is = f->h->root.root.u.def.section;
	  section_offset = is->output_section->vma + is->output_offset;
	  new_addr = f->h->root.root.u.def.value + section_offset;

#ifdef LINUX_LINK_DEBUG
	  printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
		  new_addr, f->value);
#endif

	  bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
	  fixup_table += 4;
	  bfd_put_32 (output_bfd, f->value, fixup_table);
	  fixup_table += 4;
	  ++fixups_written;
	}
  }

  if (linux_hash_table (info)->fixup_count != fixups_written)
    {
      (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));
      while (linux_hash_table (info)->fixup_count > fixups_written)
	{
	  bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
	  fixup_table += 4;
	  bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
	  fixup_table += 4;
	  ++fixups_written;
	}
    }

  h = linux_link_hash_lookup (linux_hash_table (info),
			      "__BUILTIN_FIXUPS__",
			      FALSE, FALSE, FALSE);

  if (h != NULL
      && (h->root.root.type == bfd_link_hash_defined
	  || h->root.root.type == bfd_link_hash_defweak))
    {
      is = h->root.root.u.def.section;
      section_offset = is->output_section->vma + is->output_offset;
      new_addr = h->root.root.u.def.value + section_offset;

#ifdef LINUX_LINK_DEBUG
      printf ("Builtin fixup table at %x\n", new_addr);
#endif

      bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
    }
  else
    bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);

  if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset),
		SEEK_SET) != 0)
    return FALSE;

  if (bfd_bwrite (s->contents, s->size, output_bfd) != s->size)
    return FALSE;

  return TRUE;
}

#define MY_bfd_link_hash_table_create linux_link_hash_table_create
#define MY_add_one_symbol linux_add_one_symbol
#define MY_finish_dynamic_link linux_finish_dynamic_link

#define MY_zmagic_contiguous 1

#include "aout-target.h"
