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}
7130561Sobrien   Copyright 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
8218822Sdim   2004, 2005, 2007 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
25218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2660484Sobrien
2760484Sobrien#define TARGET_IS_${EMULATION_NAME}
2860484Sobrien
29218822Sdim#include "sysdep.h"
3060484Sobrien#include "bfd.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
43130561Sobrien/* If TRUE, then interworking stubs which support calls to old,
44130561Sobrien   non-interworking aware ARM code should be generated.  */
4560484Sobrien
4660484Sobrienstatic int support_old_code = 0;
4760484Sobrienstatic char * thumb_entry_symbol = NULL;
4860484Sobrien
4960484Sobrien#define OPTION_SUPPORT_OLD_CODE		300
5060484Sobrien#define OPTION_THUMB_ENTRY		301
5160484Sobrien
52130561Sobrienstatic void
53130561Sobriengld${EMULATION_NAME}_add_options
54130561Sobrien  (int ns ATTRIBUTE_UNUSED, char **shortopts ATTRIBUTE_UNUSED, int nl,
55130561Sobrien   struct option **longopts, int nrl ATTRIBUTE_UNUSED,
56130561Sobrien   struct option **really_longopts ATTRIBUTE_UNUSED)
5760484Sobrien{
58130561Sobrien  static const struct option xtra_long[] = {
59130561Sobrien    {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
60130561Sobrien    {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
61130561Sobrien    {NULL, no_argument, NULL, 0}
62130561Sobrien  };
6360484Sobrien
64130561Sobrien  *longopts = xrealloc (*longopts,
65130561Sobrien			nl * sizeof (struct option) + sizeof (xtra_long));
66130561Sobrien  memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
67130561Sobrien}
68130561Sobrien
6960484Sobrienstatic void
70130561Sobriengld${EMULATION_NAME}_list_options (FILE *file)
7160484Sobrien{
7260484Sobrien  fprintf (file, _("  --support-old-code   Support interworking with old code\n"));
7360484Sobrien  fprintf (file, _("  --thumb-entry=<sym>  Set the entry point to be Thumb symbol <sym>\n"));
7460484Sobrien}
7560484Sobrien
76130561Sobrienstatic bfd_boolean
77130561Sobriengld${EMULATION_NAME}_handle_option (int optc)
7860484Sobrien{
7960484Sobrien  switch (optc)
8060484Sobrien    {
8160484Sobrien    default:
82130561Sobrien      return FALSE;
8360484Sobrien
8460484Sobrien    case OPTION_SUPPORT_OLD_CODE:
8560484Sobrien      support_old_code = 1;
8660484Sobrien      break;
8760484Sobrien
8860484Sobrien    case OPTION_THUMB_ENTRY:
8960484Sobrien      thumb_entry_symbol = optarg;
9060484Sobrien      break;
9160484Sobrien    }
92130561Sobrien
93130561Sobrien  return TRUE;
9460484Sobrien}
9560484Sobrien
9660484Sobrienstatic void
97130561Sobriengld${EMULATION_NAME}_before_parse (void)
9860484Sobrien{
9960484Sobrien#ifndef TARGET_			/* I.e., if not generic.  */
100130561Sobrien  ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
10160484Sobrien#endif /* not TARGET_ */
10260484Sobrien}
10360484Sobrien
10460484Sobrien/* This is called after the sections have been attached to output
10560484Sobrien   sections, but before any sizes or addresses have been set.  */
10660484Sobrien
10760484Sobrienstatic void
108130561Sobriengld${EMULATION_NAME}_before_allocation (void)
10960484Sobrien{
11060484Sobrien  /* we should be able to set the size of the interworking stub section */
11160484Sobrien
11260484Sobrien  /* Here we rummage through the found bfds to collect glue information */
11360484Sobrien  /* FIXME: should this be based on a command line option? krk@cygnus.com */
11460484Sobrien  {
11560484Sobrien    LANG_FOR_EACH_INPUT_STATEMENT (is)
11660484Sobrien      {
11760484Sobrien	if (! bfd_arm_process_before_allocation
11860484Sobrien	    (is->the_bfd, & link_info, support_old_code))
11960484Sobrien	  {
12060484Sobrien	    /* xgettext:c-format */
12160484Sobrien	    einfo (_("Errors encountered processing file %s"), is->filename);
12260484Sobrien	  }
12360484Sobrien      }
12460484Sobrien  }
12560484Sobrien
12660484Sobrien  /* We have seen it all. Allocate it, and carry on */
12760484Sobrien  bfd_arm_allocate_interworking_sections (& link_info);
128218822Sdim
129218822Sdim  before_allocation_default ();
13060484Sobrien}
13160484Sobrien
13260484Sobrienstatic void
133130561Sobriengld${EMULATION_NAME}_after_open (void)
13460484Sobrien{
13560484Sobrien  if (strstr (bfd_get_target (output_bfd), "arm") == NULL)
13660484Sobrien    {
13760484Sobrien      /* The arm backend needs special fields in the output hash structure.
13860484Sobrien	 These will only be created if the output format is an arm format,
13960484Sobrien	 hence we do not support linking and changing output formats at the
14060484Sobrien	 same time.  Use a link followed by objcopy to change output formats.  */
14160484Sobrien      einfo ("%F%X%P: error: cannot change output format whilst linking ARM binaries\n");
14260484Sobrien      return;
14360484Sobrien    }
144130561Sobrien
14560484Sobrien  {
14660484Sobrien    LANG_FOR_EACH_INPUT_STATEMENT (is)
14760484Sobrien      {
14860484Sobrien	if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info))
14960484Sobrien	  break;
15060484Sobrien      }
15160484Sobrien  }
15260484Sobrien}
15360484Sobrien
15460484Sobrienstatic void
155130561Sobriengld${EMULATION_NAME}_finish (void)
15660484Sobrien{
157218822Sdim  if (thumb_entry_symbol != NULL)
158218822Sdim    {
159218822Sdim      struct bfd_link_hash_entry * h;
16060484Sobrien
161218822Sdim      h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol,
162218822Sdim				FALSE, FALSE, TRUE);
16360484Sobrien
164218822Sdim      if (h != (struct bfd_link_hash_entry *) NULL
165218822Sdim	  && (h->type == bfd_link_hash_defined
166218822Sdim	      || h->type == bfd_link_hash_defweak)
167218822Sdim	  && h->u.def.section->output_section != NULL)
168218822Sdim	{
169218822Sdim	  static char buffer[32];
170218822Sdim	  bfd_vma val;
171130561Sobrien
172218822Sdim	  /* Special procesing is required for a Thumb entry symbol.  The
173218822Sdim	     bottom bit of its address must be set.  */
174218822Sdim	  val = (h->u.def.value
175218822Sdim		 + bfd_get_section_vma (output_bfd,
176218822Sdim					h->u.def.section->output_section)
177218822Sdim		 + h->u.def.section->output_offset);
178130561Sobrien
179218822Sdim	  val |= 1;
180130561Sobrien
181218822Sdim	  /* Now convert this value into a string and store it in entry_symbol
182218822Sdim	     where the lang_finish() function will pick it up.  */
183218822Sdim	  buffer[0] = '0';
184218822Sdim	  buffer[1] = 'x';
18560484Sobrien
186218822Sdim	  sprintf_vma (buffer + 2, val);
187130561Sobrien
188218822Sdim	  if (entry_symbol.name != NULL && entry_from_cmdline)
189218822Sdim	    einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
190218822Sdim		   thumb_entry_symbol, entry_symbol.name);
191218822Sdim	  entry_symbol.name = buffer;
192218822Sdim	}
193218822Sdim      else
194218822Sdim	einfo (_("%P: warning: connot find thumb start symbol %s\n"),
195218822Sdim	       thumb_entry_symbol);
196218822Sdim    }
19760484Sobrien
198218822Sdim  finish_default ();
19960484Sobrien}
20060484Sobrien
20160484Sobrienstatic char *
202130561Sobriengld${EMULATION_NAME}_get_script (int *isfile)
20360484SobrienEOF
20460484Sobrien
20560484Sobrienif test -n "$COMPILE_IN"
20660484Sobrienthen
20760484Sobrien# Scripts compiled in.
20860484Sobrien
20960484Sobrien# sed commands to quote an ld script as a C string.
21060484Sobriensc="-f stringify.sed"
21160484Sobrien
21260484Sobriencat >>e${EMULATION_NAME}.c <<EOF
213130561Sobrien{
21460484Sobrien  *isfile = 0;
21560484Sobrien
216130561Sobrien  if (link_info.relocatable && config.build_constructors)
21760484Sobrien    return
21860484SobrienEOF
219130561Sobriensed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
220130561Sobrienecho '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
221130561Sobriensed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
222130561Sobrienecho '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
223130561Sobriensed $sc ldscripts/${EMULATION_NAME}.xbn                >> e${EMULATION_NAME}.c
224130561Sobrienecho '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
225130561Sobriensed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
226130561Sobrienecho '  ; else return'                                 >> e${EMULATION_NAME}.c
227130561Sobriensed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
228130561Sobrienecho '; }'                                             >> e${EMULATION_NAME}.c
22960484Sobrien
23060484Sobrienelse
23160484Sobrien# Scripts read from the filesystem.
23260484Sobrien
23360484Sobriencat >>e${EMULATION_NAME}.c <<EOF
234130561Sobrien{
23560484Sobrien  *isfile = 1;
23660484Sobrien
237130561Sobrien  if (link_info.relocatable && config.build_constructors)
23860484Sobrien    return "ldscripts/${EMULATION_NAME}.xu";
239130561Sobrien  else if (link_info.relocatable)
24060484Sobrien    return "ldscripts/${EMULATION_NAME}.xr";
24160484Sobrien  else if (!config.text_read_only)
24260484Sobrien    return "ldscripts/${EMULATION_NAME}.xbn";
24360484Sobrien  else if (!config.magic_demand_paged)
24460484Sobrien    return "ldscripts/${EMULATION_NAME}.xn";
24560484Sobrien  else
24660484Sobrien    return "ldscripts/${EMULATION_NAME}.x";
24760484Sobrien}
24860484SobrienEOF
24960484Sobrien
25060484Sobrienfi
25160484Sobrien
25260484Sobriencat >>e${EMULATION_NAME}.c <<EOF
25360484Sobrien
254130561Sobrienstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
25560484Sobrien{
25660484Sobrien  gld${EMULATION_NAME}_before_parse,
25760484Sobrien  syslib_default,
25860484Sobrien  hll_default,
25960484Sobrien  after_parse_default,
26060484Sobrien  gld${EMULATION_NAME}_after_open,
26160484Sobrien  after_allocation_default,
26260484Sobrien  set_output_arch_default,
26360484Sobrien  ldemul_default_target,
26460484Sobrien  gld${EMULATION_NAME}_before_allocation,
26560484Sobrien  gld${EMULATION_NAME}_get_script,
26660484Sobrien  "${EMULATION_NAME}",
26760484Sobrien  "${OUTPUT_FORMAT}",
26860484Sobrien  gld${EMULATION_NAME}_finish,
26960484Sobrien  NULL,	/* create output section statements */
27060484Sobrien  NULL,	/* open dynamic archive */
27160484Sobrien  NULL,	/* place orphan */
27260484Sobrien  NULL,	/* set symbols */
273130561Sobrien  NULL, /* parse_args */
274130561Sobrien  gld${EMULATION_NAME}_add_options,
275130561Sobrien  gld${EMULATION_NAME}_handle_option,
27660484Sobrien  NULL,	/* unrecognised file */
27760484Sobrien  gld${EMULATION_NAME}_list_options,
27860484Sobrien  NULL,	/* recognized file */
279104834Sobrien  NULL,	/* find_potential_libraries */
280104834Sobrien  NULL	/* new_vers_pattern */
28160484Sobrien};
28260484SobrienEOF
283