# This shell script emits a C file. -*- C -*-
# It does some substitutions.
cat >e${EMULATION_NAME}.c <<EOF
/* An emulation for HP PA-RISC ELF linkers.
   Copyright (C) 1991, 93, 94, 95, 1997 Free Software Foundation, Inc.
   Written by Steve Chamberlain steve@cygnus.com

This file is part of GLD, the Gnu Linker.

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 "ld.h"
#include "ldemul.h"
#include "ldfile.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldmisc.h"
#include "ldmain.h"
#include "ldctor.h"

/* Section in which we build stubs.  */
static asection *stub_sec;
static lang_input_statement_type *stub_file;


/* FIXME.  This doesn't belong here.  */
extern lang_statement_list_type file_chain;

/* Perform some emulation specific initialization.  For PA ELF we set
   up the local label prefix and the output architecture.  */

static void
hppaelf_before_parse ()
{
  ldfile_output_architecture = bfd_arch_hppa;
}

/* Set the output architecture and machine.  */

static void
hppaelf_set_output_arch()
{
  unsigned long machine = 0;

  bfd_set_arch_mach (output_bfd, ldfile_output_architecture, machine);
}

/* This is called before the input files are opened.  We create a new
   fake input file to hold the stub section.  */

static void
hppaelf_create_output_section_statements ()
{
  stub_file = lang_add_input_file ("linker stubs",
				   lang_input_file_is_fake_enum,
				   NULL);
  stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
  if (stub_file->the_bfd == NULL
      || ! bfd_set_arch_mach (stub_file->the_bfd,
			      bfd_get_arch (output_bfd),
			      bfd_get_mach (output_bfd)))
    {
      einfo ("%X%P: can not create BFD %E\n");
      return;
    }

  stub_sec = bfd_make_section_old_way (stub_file->the_bfd, ".text");
  /* Don't set SEC_RELOC until we actually have relocations in this
     section.  */
  if (stub_sec == NULL
      || ! bfd_set_section_flags (stub_file->the_bfd, stub_sec,
				  (SEC_HAS_CONTENTS
				   | SEC_ALLOC
				   | SEC_LOAD
				   | SEC_CODE
				   | SEC_IN_MEMORY)))
    {
      einfo ("%X%P: can not create stub section: %E\n");
      return;
    }

  ldlang_add_file (stub_file);
}

/* Walk all the lang statements splicing out any padding statements from 
   the list.  */

static void
hppaelf_delete_padding_statements (s, prev)
     lang_statement_union_type *s;
     lang_statement_union_type **prev;
{
  lang_statement_union_type *sprev = NULL;
  for (; s != NULL; s = s->next)
    {
      switch (s->header.type)
	{

	/* We want recursively walk these sections.  */
	case lang_constructors_statement_enum:
	  hppaelf_delete_padding_statements (constructor_list.head,
					     &constructor_list.head);
	  break;

	case lang_output_section_statement_enum:
	  hppaelf_delete_padding_statements (s->output_section_statement.
					       children.head,
					     &s->output_section_statement.
					       children.head);
	  break;

	/* Huh?  What is a lang_wild_statement?  */
	case lang_wild_statement_enum:
	  hppaelf_delete_padding_statements (s->wild_statement.
					       children.head,
					     &s->wild_statement.
					       children.head);
	  break;

	/* Here's what we are really looking for.  Splice these out of
	   the list.  */
	case lang_padding_statement_enum:
	  if (sprev)
	    sprev->header.next = s->header.next;
	  else
	    **prev = *s;
	  break;

	/* We don't care about these cases.  */
	case lang_data_statement_enum:
	case lang_object_symbols_statement_enum:
	case lang_output_statement_enum:
	case lang_target_statement_enum:
	case lang_input_section_enum:
	case lang_input_statement_enum:
	case lang_assignment_statement_enum:
	case lang_address_statement_enum:
	  break;

	default:
	  abort ();
	  break;
	}
      sprev = s;
    }
}

/* Final emulation specific call.  For the PA we use this opportunity
   to build linker stubs.  */

static void
hppaelf_finish ()
{
  /* Call into the BFD backend to do the real work.  */
  if (elf32_hppa_size_stubs (stub_file->the_bfd, output_bfd, &link_info)
      == false)
    {
      einfo ("%X%P: can not size stub section: %E\n");
      return;
    }
  
  /* If the size of the stub section is nonzero, then we need
     to resize the sections, recompute the assignments, and finally
     build the stubs.  */
  if (bfd_section_size (stub_file->the_bfd, stub_file->the_bfd->sections) != 0)
    {
      /* Delete all the padding statements, they're no longer valid.  */
      hppaelf_delete_padding_statements (stat_ptr->head, &stat_ptr->head);
      
      /* Resize the sections.  */
      lang_size_sections (stat_ptr->head, abs_output_section,
			  &stat_ptr->head, 0, (bfd_vma) 0, false);
      
      /* Redo special stuff.  */
      ldemul_after_allocation ();
      
      /* Do the assignments again.  */
      lang_do_assignments (stat_ptr->head,
			   abs_output_section,
			   (fill_type) 0, (bfd_vma) 0);
      
      /* Now build the linker stubs.  */
      if (elf32_hppa_build_stubs (stub_file->the_bfd, &link_info) == false)
	{
	  einfo ("%X%P: can not build stubs: %E\n");
	  return;
	}
    }
}

/* The script itself gets inserted here.  */

static char *
hppaelf_get_script(isfile)
     int *isfile;
EOF

if test -n "$COMPILE_IN"
then
# Scripts compiled in.

# sed commands to quote an ld script as a C string.
sc='s/["\\]/\\&/g
s/$/\\n\\/
1s/^/"/
$s/$/n"/
'

cat >>e${EMULATION_NAME}.c <<EOF
{			     
  *isfile = 0;

  if (link_info.relocateable == true && config.build_constructors == true)
    return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
  else if (link_info.relocateable == true)
    return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
  else if (!config.text_read_only)
    return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
  else if (!config.magic_demand_paged)
    return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
  else
    return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
}
EOF

else
# Scripts read from the filesystem.

cat >>e${EMULATION_NAME}.c <<EOF
{			     
  *isfile = 1;

  if (link_info.relocateable == true && config.build_constructors == true)
    return "ldscripts/${EMULATION_NAME}.xu";
  else if (link_info.relocateable == true)
    return "ldscripts/${EMULATION_NAME}.xr";
  else if (!config.text_read_only)
    return "ldscripts/${EMULATION_NAME}.xbn";
  else if (!config.magic_demand_paged)
    return "ldscripts/${EMULATION_NAME}.xn";
  else
    return "ldscripts/${EMULATION_NAME}.x";
}
EOF

fi

cat >>e${EMULATION_NAME}.c <<EOF

struct ld_emulation_xfer_struct ld_hppaelf_emulation = 
{
  hppaelf_before_parse,
  syslib_default,
  hll_default,
  after_parse_default,
  after_open_default,
  after_allocation_default,
  hppaelf_set_output_arch,
  ldemul_default_target,
  before_allocation_default,
  hppaelf_get_script,
  "hppaelf",
  "elf32-hppa",
  hppaelf_finish,
  hppaelf_create_output_section_statements,
};
EOF
