# This shell script emits a C file. -*- C -*-
#   Copyright 2003, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# 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.
#

# This file is sourced from elf32.em, and defines extra powerpc32-elf
# specific routines.
#
fragment <<EOF

#include "libbfd.h"
#include "elf32-ppc.h"

#define is_ppc_elf(bfd) \
  (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
   && elf_object_id (bfd) == PPC32_ELF_TDATA)

/* Whether to run tls optimization.  */
static int notlsopt = 0;
static int no_tls_get_addr_opt = 0;

/* Whether to emit symbols for stubs.  */
static int emit_stub_syms = -1;

/* Chooses the correct place for .plt and .got.  */
static enum ppc_elf_plt_type plt_style = PLT_UNSET;
static int old_got = 0;

static void
ppc_after_open (void)
{
  if (is_ppc_elf (link_info.output_bfd))
    {
      int new_plt;
      int keep_new;
      unsigned int num_plt;
      unsigned int num_got;
      lang_output_section_statement_type *os;
      lang_output_section_statement_type *plt_os[2];
      lang_output_section_statement_type *got_os[2];

      if (emit_stub_syms < 0)
	emit_stub_syms = link_info.emitrelocations || link_info.shared;
      new_plt = ppc_elf_select_plt_layout (link_info.output_bfd, &link_info,
					   plt_style, emit_stub_syms);
      if (new_plt < 0)
	einfo ("%X%P: select_plt_layout problem %E\n");

      num_got = 0;
      num_plt = 0;
      for (os = &lang_output_section_statement.head->output_section_statement;
	   os != NULL;
	   os = os->next)
	{
	  if (os->constraint == SPECIAL && strcmp (os->name, ".plt") == 0)
	    {
	      if (num_plt < 2)
		plt_os[num_plt] = os;
	      ++num_plt;
	    }
	  if (os->constraint == SPECIAL && strcmp (os->name, ".got") == 0)
	    {
	      if (num_got < 2)
		got_os[num_got] = os;
	      ++num_got;
	    }
	}

      keep_new = new_plt == 1 ? 0 : -1;
      if (num_plt == 2)
	{
	  plt_os[0]->constraint = keep_new;
	  plt_os[1]->constraint = ~keep_new;
	}
      if (num_got == 2)
	{
	  if (old_got)
	    keep_new = -1;
	  got_os[0]->constraint = keep_new;
	  got_os[1]->constraint = ~keep_new;
	}
    }

  gld${EMULATION_NAME}_after_open ();
}

static void
ppc_before_allocation (void)
{
  if (is_ppc_elf (link_info.output_bfd))
    {
      if (ppc_elf_tls_setup (link_info.output_bfd, &link_info,
			     no_tls_get_addr_opt)
	  && !notlsopt)
	{
	  if (!ppc_elf_tls_optimize (link_info.output_bfd, &link_info))
	    {
	      einfo ("%X%P: TLS problem %E\n");
	      return;
	    }
	}
    }

  gld${EMULATION_NAME}_before_allocation ();

  /* Turn on relaxation if executable sections have addresses that
     might make branches overflow.  */
  if (!command_line.relax)
    {
      bfd_vma low = (bfd_vma) -1;
      bfd_vma high = 0;
      asection *o;

      /* Run lang_size_sections (if not already done).  */
      if (expld.phase != lang_mark_phase_enum)
	{
	  expld.phase = lang_mark_phase_enum;
	  expld.dataseg.phase = exp_dataseg_none;
	  one_lang_size_sections_pass (NULL, FALSE);
	  lang_reset_memory_regions ();
	}

      for (o = link_info.output_bfd->sections; o != NULL; o = o->next)
	{
	  if ((o->flags & (SEC_ALLOC | SEC_CODE)) != (SEC_ALLOC | SEC_CODE))
	    continue;
	  if (o->rawsize == 0)
	    continue;
	  if (low > o->vma)
	    low = o->vma;
	  if (high < o->vma + o->rawsize - 1)
	    high = o->vma + o->rawsize - 1;
	}
      if (high > low && high - low > (1 << 25) - 1)
	command_line.relax = TRUE;
    }
}

EOF

if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
  fragment <<EOF
/* Special handling for embedded SPU executables.  */
extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *);
static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *);

static bfd_boolean
ppc_recognized_file (lang_input_statement_type *entry)
{
  if (embedded_spu_file (entry, "-m32"))
    return TRUE;

  return gld${EMULATION_NAME}_load_symbols (entry);
}

EOF
LDEMUL_RECOGNIZED_FILE=ppc_recognized_file
fi

# Define some shell vars to insert bits of code into the standard elf
# parse_args and list_options functions.
#
PARSE_AND_LIST_PROLOGUE='
#define OPTION_NO_TLS_OPT		301
#define OPTION_NO_TLS_GET_ADDR_OPT	(OPTION_NO_TLS_OPT + 1)
#define OPTION_NEW_PLT			(OPTION_NO_TLS_GET_ADDR_OPT + 1)
#define OPTION_OLD_PLT			(OPTION_NEW_PLT + 1)
#define OPTION_OLD_GOT			(OPTION_OLD_PLT + 1)
#define OPTION_STUBSYMS			(OPTION_OLD_GOT + 1)
#define OPTION_NO_STUBSYMS		(OPTION_STUBSYMS + 1)
'

PARSE_AND_LIST_LONGOPTS='
  { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
  { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
  { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
  { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
  { "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
  { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
  { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },
'

PARSE_AND_LIST_OPTIONS='
  fprintf (file, _("\
  --emit-stub-syms            Label linker stubs with a symbol.\n\
  --no-emit-stub-syms         Don'\''t label linker stubs with a symbol.\n\
  --no-tls-optimize           Don'\''t try to optimize TLS accesses.\n\
  --no-tls-get-addr-optimize  Don'\''t use a special __tls_get_addr call.\n\
  --secure-plt                Use new-style PLT if possible.\n\
  --bss-plt                   Force old-style BSS PLT.\n\
  --sdata-got                 Force GOT location just before .sdata.\n"
		   ));
'

PARSE_AND_LIST_ARGS_CASES='
    case OPTION_STUBSYMS:
      emit_stub_syms = 1;
      break;

    case OPTION_NO_STUBSYMS:
      emit_stub_syms = 0;
      break;

    case OPTION_NO_TLS_OPT:
      notlsopt = 1;
      break;

    case OPTION_NO_TLS_GET_ADDR_OPT:
      no_tls_get_addr_opt = 1;
      break;

    case OPTION_NEW_PLT:
      plt_style = PLT_NEW;
      break;

    case OPTION_OLD_PLT:
      plt_style = PLT_OLD;
      break;

    case OPTION_OLD_GOT:
      old_got = 1;
      break;
'

# Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation
#
LDEMUL_AFTER_OPEN=ppc_after_open
LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
