armcoff.em revision 77298
160484Sobrien# This shell script emits a C file. -*- C -*-
260484Sobrien# It does some substitutions.
360484Sobriencat >e${EMULATION_NAME}.c <<EOF
460484Sobrien/* This file is is generated by a shell script.  DO NOT EDIT! */
560484Sobrien
660484Sobrien/* emulate the original gld for the given ${EMULATION_NAME}
777298Sobrien   Copyright (C) 1991, 93, 96, 97, 98, 99, 2000
877298Sobrien   Free Software Foundation, Inc.
960484Sobrien   Written by Steve Chamberlain steve@cygnus.com
1060484Sobrien
1160484SobrienThis file is part of GLD, the Gnu Linker.
1260484Sobrien
1360484SobrienThis program is free software; you can redistribute it and/or modify
1460484Sobrienit under the terms of the GNU General Public License as published by
1560484Sobrienthe Free Software Foundation; either version 2 of the License, or
1660484Sobrien(at your option) any later version.
1760484Sobrien
1860484SobrienThis program is distributed in the hope that it will be useful,
1960484Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
2060484SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2160484SobrienGNU General Public License for more details.
2260484Sobrien
2360484SobrienYou should have received a copy of the GNU General Public License
2460484Sobrienalong with this program; if not, write to the Free Software
2560484SobrienFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2660484Sobrien
2760484Sobrien#define TARGET_IS_${EMULATION_NAME}
2860484Sobrien
2960484Sobrien#include "bfd.h"
3060484Sobrien#include "sysdep.h"
3160484Sobrien#include "bfdlink.h"
3260484Sobrien#include "getopt.h"
3360484Sobrien
3460484Sobrien#include "ld.h"
3560484Sobrien#include "ldmain.h"
3660484Sobrien#include "ldmisc.h"
3760484Sobrien
3860484Sobrien#include "ldexp.h"
3960484Sobrien#include "ldlang.h"
4077298Sobrien#include "ldfile.h"
4177298Sobrien#include "ldemul.h"
4260484Sobrien
4360484Sobrienstatic void gld${EMULATION_NAME}_before_parse PARAMS ((void));
4460484Sobrienstatic void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
4560484Sobrienstatic char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
4660484Sobrienstatic int  gld${EMULATION_NAME}_parse_args PARAMS((int, char **));
4760484Sobrienstatic void gld${EMULATION_NAME}_list_options PARAMS ((FILE *));
4860484Sobrienstatic void gld${EMULATION_NAME}_finish PARAMS ((void));
4960484Sobrien
5060484Sobrien/* If true, then interworking stubs which support calls to old, non-interworking
5160484Sobrien   aware ARM code should be generated.  */
5260484Sobrien
5360484Sobrienstatic int support_old_code = 0;
5460484Sobrienstatic char * thumb_entry_symbol = NULL;
5560484Sobrien
5660484Sobrien#define OPTION_SUPPORT_OLD_CODE		300
5760484Sobrien#define OPTION_THUMB_ENTRY		301
5860484Sobrien
5960484Sobrienstatic struct option longopts[] =
6060484Sobrien{
6160484Sobrien  {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
6260484Sobrien  {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
6360484Sobrien  {NULL, no_argument, NULL, 0}
6460484Sobrien};
6560484Sobrien
6660484Sobrienstatic void
6760484Sobriengld${EMULATION_NAME}_list_options (file)
6860484Sobrien     FILE * file;
6960484Sobrien{
7060484Sobrien  fprintf (file, _("  --support-old-code   Support interworking with old code\n"));
7160484Sobrien  fprintf (file, _("  --thumb-entry=<sym>  Set the entry point to be Thumb symbol <sym>\n"));
7260484Sobrien}
7360484Sobrien
7460484Sobrienstatic int
7560484Sobriengld${EMULATION_NAME}_parse_args (argc, argv)
7660484Sobrien     int     argc;
7760484Sobrien     char ** argv;
7860484Sobrien{
7960484Sobrien  int        longind;
8060484Sobrien  int        optc;
8160484Sobrien  int        prevoptind = optind;
8260484Sobrien  int        prevopterr = opterr;
8360484Sobrien  int        wanterror;
8460484Sobrien  static int lastoptind = -1;
8560484Sobrien
8660484Sobrien  if (lastoptind != optind)
8760484Sobrien    opterr = 0;
8860484Sobrien  
8960484Sobrien  wanterror  = opterr;
9060484Sobrien  lastoptind = optind;
9160484Sobrien
9260484Sobrien  optc   = getopt_long_only (argc, argv, "-", longopts, & longind);
9360484Sobrien  opterr = prevopterr;
9460484Sobrien
9560484Sobrien  switch (optc)
9660484Sobrien    {
9760484Sobrien    default:
9860484Sobrien      if (wanterror)
9960484Sobrien	xexit (1);
10060484Sobrien      optind =  prevoptind;
10160484Sobrien      return 0;
10260484Sobrien
10360484Sobrien    case OPTION_SUPPORT_OLD_CODE:
10460484Sobrien      support_old_code = 1;
10560484Sobrien      break;
10660484Sobrien
10760484Sobrien    case OPTION_THUMB_ENTRY:
10860484Sobrien      thumb_entry_symbol = optarg;
10960484Sobrien      break;
11060484Sobrien    }
11160484Sobrien  
11260484Sobrien  return 1;
11360484Sobrien}
11460484Sobrien
11560484Sobrienstatic void
11660484Sobriengld${EMULATION_NAME}_before_parse ()
11760484Sobrien{
11860484Sobrien#ifndef TARGET_			/* I.e., if not generic.  */
11960484Sobrien  ldfile_set_output_arch ("`echo ${ARCH}`");
12060484Sobrien#endif /* not TARGET_ */
12160484Sobrien}
12260484Sobrien
12360484Sobrien/* This is called after the sections have been attached to output
12460484Sobrien   sections, but before any sizes or addresses have been set.  */
12560484Sobrien
12660484Sobrienstatic void
12760484Sobriengld${EMULATION_NAME}_before_allocation ()
12860484Sobrien{
12960484Sobrien  /* we should be able to set the size of the interworking stub section */
13060484Sobrien
13160484Sobrien  /* Here we rummage through the found bfds to collect glue information */
13260484Sobrien  /* FIXME: should this be based on a command line option? krk@cygnus.com */
13360484Sobrien  {
13460484Sobrien    LANG_FOR_EACH_INPUT_STATEMENT (is)
13560484Sobrien      {
13660484Sobrien	if (! bfd_arm_process_before_allocation
13760484Sobrien	    (is->the_bfd, & link_info, support_old_code))
13860484Sobrien	  {
13960484Sobrien	    /* xgettext:c-format */
14060484Sobrien	    einfo (_("Errors encountered processing file %s"), is->filename);
14160484Sobrien	  }
14260484Sobrien      }
14360484Sobrien  }
14460484Sobrien
14560484Sobrien  /* We have seen it all. Allocate it, and carry on */
14660484Sobrien  bfd_arm_allocate_interworking_sections (& link_info);
14760484Sobrien}
14860484Sobrien
14960484Sobrienstatic void
15060484Sobriengld${EMULATION_NAME}_after_open ()
15160484Sobrien{
15260484Sobrien  if (strstr (bfd_get_target (output_bfd), "arm") == NULL)
15360484Sobrien    {
15460484Sobrien      /* The arm backend needs special fields in the output hash structure.
15560484Sobrien	 These will only be created if the output format is an arm format,
15660484Sobrien	 hence we do not support linking and changing output formats at the
15760484Sobrien	 same time.  Use a link followed by objcopy to change output formats.  */
15860484Sobrien      einfo ("%F%X%P: error: cannot change output format whilst linking ARM binaries\n");
15960484Sobrien      return;
16060484Sobrien    }
16160484Sobrien  
16260484Sobrien  {
16360484Sobrien    LANG_FOR_EACH_INPUT_STATEMENT (is)
16460484Sobrien      {
16560484Sobrien	if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info))
16660484Sobrien	  break;
16760484Sobrien      }
16860484Sobrien  }
16960484Sobrien}
17060484Sobrien
17160484Sobrienstatic void
17260484Sobriengld${EMULATION_NAME}_finish PARAMS((void))
17360484Sobrien{
17460484Sobrien  struct bfd_link_hash_entry * h;
17560484Sobrien
17660484Sobrien  if (thumb_entry_symbol == NULL)
17760484Sobrien    return;
17860484Sobrien  
17960484Sobrien  h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, false, false, true);
18060484Sobrien
18160484Sobrien  if (h != (struct bfd_link_hash_entry *) NULL
18260484Sobrien      && (h->type == bfd_link_hash_defined
18360484Sobrien	  || h->type == bfd_link_hash_defweak)
18460484Sobrien      && h->u.def.section->output_section != NULL)
18560484Sobrien    {
18660484Sobrien      static char buffer[32];
18760484Sobrien      bfd_vma val;
18860484Sobrien      
18960484Sobrien      /* Special procesing is required for a Thumb entry symbol.  The
19060484Sobrien	 bottom bit of its address must be set.  */
19160484Sobrien      val = (h->u.def.value
19260484Sobrien	     + bfd_get_section_vma (output_bfd,
19360484Sobrien				    h->u.def.section->output_section)
19460484Sobrien	     + h->u.def.section->output_offset);
19560484Sobrien      
19660484Sobrien      val |= 1;
19760484Sobrien
19860484Sobrien      /* Now convert this value into a string and store it in entry_symbol
19960484Sobrien         where the lang_finish() function will pick it up.  */
20060484Sobrien      buffer[0] = '0';
20160484Sobrien      buffer[1] = 'x';
20260484Sobrien      
20360484Sobrien      sprintf_vma (buffer + 2, val);
20460484Sobrien
20560484Sobrien      if (entry_symbol != NULL && entry_from_cmdline)
20660484Sobrien	einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
20760484Sobrien	       thumb_entry_symbol, entry_symbol);
20860484Sobrien      entry_symbol = buffer;
20960484Sobrien    }
21060484Sobrien  else
21160484Sobrien    einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol);
21260484Sobrien}
21360484Sobrien
21460484Sobrienstatic char *
21560484Sobriengld${EMULATION_NAME}_get_script (isfile)
21660484Sobrien     int *isfile;
21760484SobrienEOF
21860484Sobrien
21960484Sobrienif test -n "$COMPILE_IN"
22060484Sobrienthen
22160484Sobrien# Scripts compiled in.
22260484Sobrien
22360484Sobrien# sed commands to quote an ld script as a C string.
22460484Sobriensc="-f stringify.sed"
22560484Sobrien
22660484Sobriencat >>e${EMULATION_NAME}.c <<EOF
22760484Sobrien{			     
22860484Sobrien  *isfile = 0;
22960484Sobrien
23060484Sobrien  if (link_info.relocateable == true && config.build_constructors == true)
23160484Sobrien    return
23260484SobrienEOF
23360484Sobriensed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
23460484Sobrienecho '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
23560484Sobriensed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
23660484Sobrienecho '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
23760484Sobriensed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
23860484Sobrienecho '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
23960484Sobriensed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
24060484Sobrienecho '  ; else return'                                     >> e${EMULATION_NAME}.c
24160484Sobriensed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
24260484Sobrienecho '; }'                                                 >> e${EMULATION_NAME}.c
24360484Sobrien
24460484Sobrienelse
24560484Sobrien# Scripts read from the filesystem.
24660484Sobrien
24760484Sobriencat >>e${EMULATION_NAME}.c <<EOF
24860484Sobrien{			     
24960484Sobrien  *isfile = 1;
25060484Sobrien
25160484Sobrien  if (link_info.relocateable == true && config.build_constructors == true)
25260484Sobrien    return "ldscripts/${EMULATION_NAME}.xu";
25360484Sobrien  else if (link_info.relocateable == true)
25460484Sobrien    return "ldscripts/${EMULATION_NAME}.xr";
25560484Sobrien  else if (!config.text_read_only)
25660484Sobrien    return "ldscripts/${EMULATION_NAME}.xbn";
25760484Sobrien  else if (!config.magic_demand_paged)
25860484Sobrien    return "ldscripts/${EMULATION_NAME}.xn";
25960484Sobrien  else
26060484Sobrien    return "ldscripts/${EMULATION_NAME}.x";
26160484Sobrien}
26260484SobrienEOF
26360484Sobrien
26460484Sobrienfi
26560484Sobrien
26660484Sobriencat >>e${EMULATION_NAME}.c <<EOF
26760484Sobrien
26860484Sobrienstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
26960484Sobrien{
27060484Sobrien  gld${EMULATION_NAME}_before_parse,
27160484Sobrien  syslib_default,
27260484Sobrien  hll_default,
27360484Sobrien  after_parse_default,
27460484Sobrien  gld${EMULATION_NAME}_after_open,
27560484Sobrien  after_allocation_default,
27660484Sobrien  set_output_arch_default,
27760484Sobrien  ldemul_default_target,
27860484Sobrien  gld${EMULATION_NAME}_before_allocation,
27960484Sobrien  gld${EMULATION_NAME}_get_script,
28060484Sobrien  "${EMULATION_NAME}",
28160484Sobrien  "${OUTPUT_FORMAT}",
28260484Sobrien  gld${EMULATION_NAME}_finish,
28360484Sobrien  NULL,	/* create output section statements */
28460484Sobrien  NULL,	/* open dynamic archive */
28560484Sobrien  NULL,	/* place orphan */
28660484Sobrien  NULL,	/* set symbols */
28760484Sobrien  gld${EMULATION_NAME}_parse_args,
28860484Sobrien  NULL,	/* unrecognised file */
28960484Sobrien  gld${EMULATION_NAME}_list_options,
29060484Sobrien  NULL,	/* recognized file */
29160484Sobrien  NULL 	/* find_potential_libraries */
29260484Sobrien};
29360484SobrienEOF
294