1*3d8817e4Smiod# This shell script emits a C file. -*- C -*-
2*3d8817e4Smiod# It does some substitutions.
3*3d8817e4Smiodcat >e${EMULATION_NAME}.c <<EOF
4*3d8817e4Smiod/* This file is is generated by a shell script.  DO NOT EDIT! */
5*3d8817e4Smiod
6*3d8817e4Smiod/* emulate the original gld for the given ${EMULATION_NAME}
7*3d8817e4Smiod   Copyright 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
8*3d8817e4Smiod   2004, 2005 Free Software Foundation, Inc.
9*3d8817e4Smiod   Written by Steve Chamberlain steve@cygnus.com
10*3d8817e4Smiod
11*3d8817e4SmiodThis file is part of GLD, the Gnu Linker.
12*3d8817e4Smiod
13*3d8817e4SmiodThis program is free software; you can redistribute it and/or modify
14*3d8817e4Smiodit under the terms of the GNU General Public License as published by
15*3d8817e4Smiodthe Free Software Foundation; either version 2 of the License, or
16*3d8817e4Smiod(at your option) any later version.
17*3d8817e4Smiod
18*3d8817e4SmiodThis program is distributed in the hope that it will be useful,
19*3d8817e4Smiodbut WITHOUT ANY WARRANTY; without even the implied warranty of
20*3d8817e4SmiodMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21*3d8817e4SmiodGNU General Public License for more details.
22*3d8817e4Smiod
23*3d8817e4SmiodYou should have received a copy of the GNU General Public License
24*3d8817e4Smiodalong with this program; if not, write to the Free Software
25*3d8817e4SmiodFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
26*3d8817e4Smiod
27*3d8817e4Smiod#define TARGET_IS_${EMULATION_NAME}
28*3d8817e4Smiod
29*3d8817e4Smiod#include "bfd.h"
30*3d8817e4Smiod#include "sysdep.h"
31*3d8817e4Smiod#include "bfdlink.h"
32*3d8817e4Smiod#include "getopt.h"
33*3d8817e4Smiod
34*3d8817e4Smiod#include "ld.h"
35*3d8817e4Smiod#include "ldmain.h"
36*3d8817e4Smiod#include "ldmisc.h"
37*3d8817e4Smiod
38*3d8817e4Smiod#include "ldexp.h"
39*3d8817e4Smiod#include "ldlang.h"
40*3d8817e4Smiod#include "ldfile.h"
41*3d8817e4Smiod#include "ldemul.h"
42*3d8817e4Smiod
43*3d8817e4Smiod/* If TRUE, then interworking stubs which support calls to old,
44*3d8817e4Smiod   non-interworking aware ARM code should be generated.  */
45*3d8817e4Smiod
46*3d8817e4Smiodstatic int support_old_code = 0;
47*3d8817e4Smiodstatic char * thumb_entry_symbol = NULL;
48*3d8817e4Smiod
49*3d8817e4Smiod#define OPTION_SUPPORT_OLD_CODE		300
50*3d8817e4Smiod#define OPTION_THUMB_ENTRY		301
51*3d8817e4Smiod
52*3d8817e4Smiodstatic void
53*3d8817e4Smiodgld${EMULATION_NAME}_add_options
54*3d8817e4Smiod  (int ns ATTRIBUTE_UNUSED, char **shortopts ATTRIBUTE_UNUSED, int nl,
55*3d8817e4Smiod   struct option **longopts, int nrl ATTRIBUTE_UNUSED,
56*3d8817e4Smiod   struct option **really_longopts ATTRIBUTE_UNUSED)
57*3d8817e4Smiod{
58*3d8817e4Smiod  static const struct option xtra_long[] = {
59*3d8817e4Smiod    {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
60*3d8817e4Smiod    {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
61*3d8817e4Smiod    {NULL, no_argument, NULL, 0}
62*3d8817e4Smiod  };
63*3d8817e4Smiod
64*3d8817e4Smiod  *longopts = xrealloc (*longopts,
65*3d8817e4Smiod			nl * sizeof (struct option) + sizeof (xtra_long));
66*3d8817e4Smiod  memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
67*3d8817e4Smiod}
68*3d8817e4Smiod
69*3d8817e4Smiodstatic void
70*3d8817e4Smiodgld${EMULATION_NAME}_list_options (FILE *file)
71*3d8817e4Smiod{
72*3d8817e4Smiod  fprintf (file, _("  --support-old-code   Support interworking with old code\n"));
73*3d8817e4Smiod  fprintf (file, _("  --thumb-entry=<sym>  Set the entry point to be Thumb symbol <sym>\n"));
74*3d8817e4Smiod}
75*3d8817e4Smiod
76*3d8817e4Smiodstatic bfd_boolean
77*3d8817e4Smiodgld${EMULATION_NAME}_handle_option (int optc)
78*3d8817e4Smiod{
79*3d8817e4Smiod  switch (optc)
80*3d8817e4Smiod    {
81*3d8817e4Smiod    default:
82*3d8817e4Smiod      return FALSE;
83*3d8817e4Smiod
84*3d8817e4Smiod    case OPTION_SUPPORT_OLD_CODE:
85*3d8817e4Smiod      support_old_code = 1;
86*3d8817e4Smiod      break;
87*3d8817e4Smiod
88*3d8817e4Smiod    case OPTION_THUMB_ENTRY:
89*3d8817e4Smiod      thumb_entry_symbol = optarg;
90*3d8817e4Smiod      break;
91*3d8817e4Smiod    }
92*3d8817e4Smiod
93*3d8817e4Smiod  return TRUE;
94*3d8817e4Smiod}
95*3d8817e4Smiod
96*3d8817e4Smiodstatic void
97*3d8817e4Smiodgld${EMULATION_NAME}_before_parse (void)
98*3d8817e4Smiod{
99*3d8817e4Smiod#ifndef TARGET_			/* I.e., if not generic.  */
100*3d8817e4Smiod  ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
101*3d8817e4Smiod#endif /* not TARGET_ */
102*3d8817e4Smiod}
103*3d8817e4Smiod
104*3d8817e4Smiod/* This is called after the sections have been attached to output
105*3d8817e4Smiod   sections, but before any sizes or addresses have been set.  */
106*3d8817e4Smiod
107*3d8817e4Smiodstatic void
108*3d8817e4Smiodgld${EMULATION_NAME}_before_allocation (void)
109*3d8817e4Smiod{
110*3d8817e4Smiod  /* we should be able to set the size of the interworking stub section */
111*3d8817e4Smiod
112*3d8817e4Smiod  /* Here we rummage through the found bfds to collect glue information */
113*3d8817e4Smiod  /* FIXME: should this be based on a command line option? krk@cygnus.com */
114*3d8817e4Smiod  {
115*3d8817e4Smiod    LANG_FOR_EACH_INPUT_STATEMENT (is)
116*3d8817e4Smiod      {
117*3d8817e4Smiod	if (! bfd_arm_process_before_allocation
118*3d8817e4Smiod	    (is->the_bfd, & link_info, support_old_code))
119*3d8817e4Smiod	  {
120*3d8817e4Smiod	    /* xgettext:c-format */
121*3d8817e4Smiod	    einfo (_("Errors encountered processing file %s"), is->filename);
122*3d8817e4Smiod	  }
123*3d8817e4Smiod      }
124*3d8817e4Smiod  }
125*3d8817e4Smiod
126*3d8817e4Smiod  /* We have seen it all. Allocate it, and carry on */
127*3d8817e4Smiod  bfd_arm_allocate_interworking_sections (& link_info);
128*3d8817e4Smiod
129*3d8817e4Smiod  before_allocation_default ();
130*3d8817e4Smiod}
131*3d8817e4Smiod
132*3d8817e4Smiodstatic void
133*3d8817e4Smiodgld${EMULATION_NAME}_after_open (void)
134*3d8817e4Smiod{
135*3d8817e4Smiod  if (strstr (bfd_get_target (output_bfd), "arm") == NULL)
136*3d8817e4Smiod    {
137*3d8817e4Smiod      /* The arm backend needs special fields in the output hash structure.
138*3d8817e4Smiod	 These will only be created if the output format is an arm format,
139*3d8817e4Smiod	 hence we do not support linking and changing output formats at the
140*3d8817e4Smiod	 same time.  Use a link followed by objcopy to change output formats.  */
141*3d8817e4Smiod      einfo ("%F%X%P: error: cannot change output format whilst linking ARM binaries\n");
142*3d8817e4Smiod      return;
143*3d8817e4Smiod    }
144*3d8817e4Smiod
145*3d8817e4Smiod  {
146*3d8817e4Smiod    LANG_FOR_EACH_INPUT_STATEMENT (is)
147*3d8817e4Smiod      {
148*3d8817e4Smiod	if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info))
149*3d8817e4Smiod	  break;
150*3d8817e4Smiod      }
151*3d8817e4Smiod  }
152*3d8817e4Smiod}
153*3d8817e4Smiod
154*3d8817e4Smiodstatic void
155*3d8817e4Smiodgld${EMULATION_NAME}_finish (void)
156*3d8817e4Smiod{
157*3d8817e4Smiod  struct bfd_link_hash_entry * h;
158*3d8817e4Smiod
159*3d8817e4Smiod  if (thumb_entry_symbol == NULL)
160*3d8817e4Smiod    return;
161*3d8817e4Smiod
162*3d8817e4Smiod  h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol,
163*3d8817e4Smiod			    FALSE, FALSE, TRUE);
164*3d8817e4Smiod
165*3d8817e4Smiod  if (h != (struct bfd_link_hash_entry *) NULL
166*3d8817e4Smiod      && (h->type == bfd_link_hash_defined
167*3d8817e4Smiod	  || h->type == bfd_link_hash_defweak)
168*3d8817e4Smiod      && h->u.def.section->output_section != NULL)
169*3d8817e4Smiod    {
170*3d8817e4Smiod      static char buffer[32];
171*3d8817e4Smiod      bfd_vma val;
172*3d8817e4Smiod
173*3d8817e4Smiod      /* Special procesing is required for a Thumb entry symbol.  The
174*3d8817e4Smiod	 bottom bit of its address must be set.  */
175*3d8817e4Smiod      val = (h->u.def.value
176*3d8817e4Smiod	     + bfd_get_section_vma (output_bfd,
177*3d8817e4Smiod				    h->u.def.section->output_section)
178*3d8817e4Smiod	     + h->u.def.section->output_offset);
179*3d8817e4Smiod
180*3d8817e4Smiod      val |= 1;
181*3d8817e4Smiod
182*3d8817e4Smiod      /* Now convert this value into a string and store it in entry_symbol
183*3d8817e4Smiod	 where the lang_finish() function will pick it up.  */
184*3d8817e4Smiod      buffer[0] = '0';
185*3d8817e4Smiod      buffer[1] = 'x';
186*3d8817e4Smiod
187*3d8817e4Smiod      sprintf_vma (buffer + 2, val);
188*3d8817e4Smiod
189*3d8817e4Smiod      if (entry_symbol.name != NULL && entry_from_cmdline)
190*3d8817e4Smiod	einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
191*3d8817e4Smiod	       thumb_entry_symbol, entry_symbol.name);
192*3d8817e4Smiod      entry_symbol.name = buffer;
193*3d8817e4Smiod    }
194*3d8817e4Smiod  else
195*3d8817e4Smiod    einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol);
196*3d8817e4Smiod
197*3d8817e4Smiod  finish_default ();
198*3d8817e4Smiod}
199*3d8817e4Smiod
200*3d8817e4Smiodstatic char *
201*3d8817e4Smiodgld${EMULATION_NAME}_get_script (int *isfile)
202*3d8817e4SmiodEOF
203*3d8817e4Smiod
204*3d8817e4Smiodif test -n "$COMPILE_IN"
205*3d8817e4Smiodthen
206*3d8817e4Smiod# Scripts compiled in.
207*3d8817e4Smiod
208*3d8817e4Smiod# sed commands to quote an ld script as a C string.
209*3d8817e4Smiodsc="-f stringify.sed"
210*3d8817e4Smiod
211*3d8817e4Smiodcat >>e${EMULATION_NAME}.c <<EOF
212*3d8817e4Smiod{
213*3d8817e4Smiod  *isfile = 0;
214*3d8817e4Smiod
215*3d8817e4Smiod  if (link_info.relocatable && config.build_constructors)
216*3d8817e4Smiod    return
217*3d8817e4SmiodEOF
218*3d8817e4Smiodsed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
219*3d8817e4Smiodecho '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
220*3d8817e4Smiodsed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
221*3d8817e4Smiodecho '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
222*3d8817e4Smiodsed $sc ldscripts/${EMULATION_NAME}.xbn                >> e${EMULATION_NAME}.c
223*3d8817e4Smiodecho '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
224*3d8817e4Smiodsed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
225*3d8817e4Smiodecho '  ; else return'                                 >> e${EMULATION_NAME}.c
226*3d8817e4Smiodsed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
227*3d8817e4Smiodecho '; }'                                             >> e${EMULATION_NAME}.c
228*3d8817e4Smiod
229*3d8817e4Smiodelse
230*3d8817e4Smiod# Scripts read from the filesystem.
231*3d8817e4Smiod
232*3d8817e4Smiodcat >>e${EMULATION_NAME}.c <<EOF
233*3d8817e4Smiod{
234*3d8817e4Smiod  *isfile = 1;
235*3d8817e4Smiod
236*3d8817e4Smiod  if (link_info.relocatable && config.build_constructors)
237*3d8817e4Smiod    return "ldscripts/${EMULATION_NAME}.xu";
238*3d8817e4Smiod  else if (link_info.relocatable)
239*3d8817e4Smiod    return "ldscripts/${EMULATION_NAME}.xr";
240*3d8817e4Smiod  else if (!config.text_read_only)
241*3d8817e4Smiod    return "ldscripts/${EMULATION_NAME}.xbn";
242*3d8817e4Smiod  else if (!config.magic_demand_paged)
243*3d8817e4Smiod    return "ldscripts/${EMULATION_NAME}.xn";
244*3d8817e4Smiod  else
245*3d8817e4Smiod    return "ldscripts/${EMULATION_NAME}.x";
246*3d8817e4Smiod}
247*3d8817e4SmiodEOF
248*3d8817e4Smiod
249*3d8817e4Smiodfi
250*3d8817e4Smiod
251*3d8817e4Smiodcat >>e${EMULATION_NAME}.c <<EOF
252*3d8817e4Smiod
253*3d8817e4Smiodstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
254*3d8817e4Smiod{
255*3d8817e4Smiod  gld${EMULATION_NAME}_before_parse,
256*3d8817e4Smiod  syslib_default,
257*3d8817e4Smiod  hll_default,
258*3d8817e4Smiod  after_parse_default,
259*3d8817e4Smiod  gld${EMULATION_NAME}_after_open,
260*3d8817e4Smiod  after_allocation_default,
261*3d8817e4Smiod  set_output_arch_default,
262*3d8817e4Smiod  ldemul_default_target,
263*3d8817e4Smiod  gld${EMULATION_NAME}_before_allocation,
264*3d8817e4Smiod  gld${EMULATION_NAME}_get_script,
265*3d8817e4Smiod  "${EMULATION_NAME}",
266*3d8817e4Smiod  "${OUTPUT_FORMAT}",
267*3d8817e4Smiod  gld${EMULATION_NAME}_finish,
268*3d8817e4Smiod  NULL,	/* create output section statements */
269*3d8817e4Smiod  NULL,	/* open dynamic archive */
270*3d8817e4Smiod  NULL,	/* place orphan */
271*3d8817e4Smiod  NULL,	/* set symbols */
272*3d8817e4Smiod  NULL, /* parse_args */
273*3d8817e4Smiod  gld${EMULATION_NAME}_add_options,
274*3d8817e4Smiod  gld${EMULATION_NAME}_handle_option,
275*3d8817e4Smiod  NULL,	/* unrecognised file */
276*3d8817e4Smiod  gld${EMULATION_NAME}_list_options,
277*3d8817e4Smiod  NULL,	/* recognized file */
278*3d8817e4Smiod  NULL,	/* find_potential_libraries */
279*3d8817e4Smiod  NULL	/* new_vers_pattern */
280*3d8817e4Smiod};
281*3d8817e4SmiodEOF
282