armcoff.em revision 60484
1214501Srpaulo# This shell script emits a C file. -*- C -*-
2214501Srpaulo# It does some substitutions.
3214501Srpaulocat >e${EMULATION_NAME}.c <<EOF
4214501Srpaulo/* This file is is generated by a shell script.  DO NOT EDIT! */
5214501Srpaulo
6214501Srpaulo/* emulate the original gld for the given ${EMULATION_NAME}
7214501Srpaulo   Copyright (C) 1991, 93, 96, 97, 98, 1999 Free Software Foundation, Inc.
8214501Srpaulo   Written by Steve Chamberlain steve@cygnus.com
9214501Srpaulo
10214501SrpauloThis file is part of GLD, the Gnu Linker.
11214501Srpaulo
12214501SrpauloThis program is free software; you can redistribute it and/or modify
13214501Srpauloit under the terms of the GNU General Public License as published by
14214501Srpaulothe Free Software Foundation; either version 2 of the License, or
15214501Srpaulo(at your option) any later version.
16214501Srpaulo
17214501SrpauloThis program is distributed in the hope that it will be useful,
18214501Srpaulobut WITHOUT ANY WARRANTY; without even the implied warranty of
19214501SrpauloMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20214501SrpauloGNU General Public License for more details.
21214501Srpaulo
22214501SrpauloYou should have received a copy of the GNU General Public License
23214501Srpauloalong with this program; if not, write to the Free Software
24214501SrpauloFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
25214501Srpaulo
26214501Srpaulo#define TARGET_IS_${EMULATION_NAME}
27214501Srpaulo
28214501Srpaulo#include "bfd.h"
29214501Srpaulo#include "sysdep.h"
30214501Srpaulo#include "bfdlink.h"
31214501Srpaulo#include "getopt.h"
32214501Srpaulo
33214501Srpaulo#include "ld.h"
34214501Srpaulo#include "ldmain.h"
35214501Srpaulo#include "ldemul.h"
36214501Srpaulo#include "ldfile.h"
37214501Srpaulo#include "ldmisc.h"
38214501Srpaulo
39214501Srpaulo#include "ldexp.h"
40214501Srpaulo#include "ldlang.h"
41214501Srpaulo
42214501Srpaulostatic void gld${EMULATION_NAME}_before_parse PARAMS ((void));
43214501Srpaulostatic void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
44214501Srpaulostatic char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
45214501Srpaulostatic int  gld${EMULATION_NAME}_parse_args PARAMS((int, char **));
46214501Srpaulostatic void gld${EMULATION_NAME}_list_options PARAMS ((FILE *));
47214501Srpaulostatic void gld${EMULATION_NAME}_finish PARAMS ((void));
48214501Srpaulo
49214501Srpaulo/* If true, then interworking stubs which support calls to old, non-interworking
50214501Srpaulo   aware ARM code should be generated.  */
51214501Srpaulo
52214501Srpaulostatic int support_old_code = 0;
53214501Srpaulostatic char * thumb_entry_symbol = NULL;
54214501Srpaulo
55214501Srpaulo#define OPTION_SUPPORT_OLD_CODE		300
56214501Srpaulo#define OPTION_THUMB_ENTRY		301
57214501Srpaulo
58214501Srpaulostatic struct option longopts[] =
59214501Srpaulo{
60214501Srpaulo  {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
61214501Srpaulo  {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
62214501Srpaulo  {NULL, no_argument, NULL, 0}
63214501Srpaulo};
64214501Srpaulo
65214501Srpaulostatic void
66214501Srpaulogld${EMULATION_NAME}_list_options (file)
67214501Srpaulo     FILE * file;
68214501Srpaulo{
69214501Srpaulo  fprintf (file, _("  --support-old-code   Support interworking with old code\n"));
70214501Srpaulo  fprintf (file, _("  --thumb-entry=<sym>  Set the entry point to be Thumb symbol <sym>\n"));
71214501Srpaulo}
72214501Srpaulo
73214501Srpaulostatic int
74214501Srpaulogld${EMULATION_NAME}_parse_args (argc, argv)
75214501Srpaulo     int     argc;
76214501Srpaulo     char ** argv;
77214501Srpaulo{
78214501Srpaulo  int        longind;
79214501Srpaulo  int        optc;
80214501Srpaulo  int        prevoptind = optind;
81214501Srpaulo  int        prevopterr = opterr;
82214501Srpaulo  int        wanterror;
83214501Srpaulo  static int lastoptind = -1;
84214501Srpaulo
85214501Srpaulo  if (lastoptind != optind)
86214501Srpaulo    opterr = 0;
87214501Srpaulo  
88214501Srpaulo  wanterror  = opterr;
89214501Srpaulo  lastoptind = optind;
90214501Srpaulo
91214501Srpaulo  optc   = getopt_long_only (argc, argv, "-", longopts, & longind);
92214501Srpaulo  opterr = prevopterr;
93214501Srpaulo
94214501Srpaulo  switch (optc)
95214501Srpaulo    {
96214501Srpaulo    default:
97214501Srpaulo      if (wanterror)
98214501Srpaulo	xexit (1);
99214501Srpaulo      optind =  prevoptind;
100214501Srpaulo      return 0;
101214501Srpaulo
102214501Srpaulo    case OPTION_SUPPORT_OLD_CODE:
103214501Srpaulo      support_old_code = 1;
104214501Srpaulo      break;
105214501Srpaulo
106214501Srpaulo    case OPTION_THUMB_ENTRY:
107214501Srpaulo      thumb_entry_symbol = optarg;
108214501Srpaulo      break;
109214501Srpaulo    }
110214501Srpaulo  
111214501Srpaulo  return 1;
112214501Srpaulo}
113214501Srpaulo
114214501Srpaulostatic void
115214501Srpaulogld${EMULATION_NAME}_before_parse ()
116214501Srpaulo{
117214501Srpaulo#ifndef TARGET_			/* I.e., if not generic.  */
118214501Srpaulo  ldfile_set_output_arch ("`echo ${ARCH}`");
119214501Srpaulo#endif /* not TARGET_ */
120214501Srpaulo}
121214501Srpaulo
122214501Srpaulo/* This is called after the sections have been attached to output
123214501Srpaulo   sections, but before any sizes or addresses have been set.  */
124214501Srpaulo
125214501Srpaulostatic void
126214501Srpaulogld${EMULATION_NAME}_before_allocation ()
127214501Srpaulo{
128214501Srpaulo  /* we should be able to set the size of the interworking stub section */
129214501Srpaulo
130214501Srpaulo  /* Here we rummage through the found bfds to collect glue information */
131214501Srpaulo  /* FIXME: should this be based on a command line option? krk@cygnus.com */
132214501Srpaulo  {
133214501Srpaulo    LANG_FOR_EACH_INPUT_STATEMENT (is)
134214501Srpaulo      {
135214501Srpaulo	if (! bfd_arm_process_before_allocation
136214501Srpaulo	    (is->the_bfd, & link_info, support_old_code))
137214501Srpaulo	  {
138214501Srpaulo	    /* xgettext:c-format */
139214501Srpaulo	    einfo (_("Errors encountered processing file %s"), is->filename);
140214501Srpaulo	  }
141214501Srpaulo      }
142214501Srpaulo  }
143214501Srpaulo
144214501Srpaulo  /* We have seen it all. Allocate it, and carry on */
145214501Srpaulo  bfd_arm_allocate_interworking_sections (& link_info);
146214501Srpaulo}
147214501Srpaulo
148214501Srpaulostatic void
149214501Srpaulogld${EMULATION_NAME}_after_open ()
150214501Srpaulo{
151214501Srpaulo  if (strstr (bfd_get_target (output_bfd), "arm") == NULL)
152214501Srpaulo    {
153214501Srpaulo      /* The arm backend needs special fields in the output hash structure.
154214501Srpaulo	 These will only be created if the output format is an arm format,
155214501Srpaulo	 hence we do not support linking and changing output formats at the
156214501Srpaulo	 same time.  Use a link followed by objcopy to change output formats.  */
157214501Srpaulo      einfo ("%F%X%P: error: cannot change output format whilst linking ARM binaries\n");
158214501Srpaulo      return;
159214501Srpaulo    }
160214501Srpaulo  
161214501Srpaulo  {
162214501Srpaulo    LANG_FOR_EACH_INPUT_STATEMENT (is)
163214501Srpaulo      {
164214501Srpaulo	if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info))
165214501Srpaulo	  break;
166214501Srpaulo      }
167214501Srpaulo  }
168214501Srpaulo}
169214501Srpaulo
170214501Srpaulostatic void
171214501Srpaulogld${EMULATION_NAME}_finish PARAMS((void))
172214501Srpaulo{
173214501Srpaulo  struct bfd_link_hash_entry * h;
174214501Srpaulo
175214501Srpaulo  if (thumb_entry_symbol == NULL)
176214501Srpaulo    return;
177214501Srpaulo  
178214501Srpaulo  h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, false, false, true);
179214501Srpaulo
180214501Srpaulo  if (h != (struct bfd_link_hash_entry *) NULL
181214501Srpaulo      && (h->type == bfd_link_hash_defined
182214501Srpaulo	  || h->type == bfd_link_hash_defweak)
183214501Srpaulo      && h->u.def.section->output_section != NULL)
184214501Srpaulo    {
185214501Srpaulo      static char buffer[32];
186214501Srpaulo      bfd_vma val;
187214501Srpaulo      
188214501Srpaulo      /* Special procesing is required for a Thumb entry symbol.  The
189214501Srpaulo	 bottom bit of its address must be set.  */
190214501Srpaulo      val = (h->u.def.value
191214501Srpaulo	     + bfd_get_section_vma (output_bfd,
192214501Srpaulo				    h->u.def.section->output_section)
193214501Srpaulo	     + h->u.def.section->output_offset);
194214501Srpaulo      
195214501Srpaulo      val |= 1;
196214501Srpaulo
197214501Srpaulo      /* Now convert this value into a string and store it in entry_symbol
198214501Srpaulo         where the lang_finish() function will pick it up.  */
199214501Srpaulo      buffer[0] = '0';
200214501Srpaulo      buffer[1] = 'x';
201214501Srpaulo      
202214501Srpaulo      sprintf_vma (buffer + 2, val);
203214501Srpaulo
204214501Srpaulo      if (entry_symbol != NULL && entry_from_cmdline)
205214501Srpaulo	einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
206214501Srpaulo	       thumb_entry_symbol, entry_symbol);
207214501Srpaulo      entry_symbol = buffer;
208214501Srpaulo    }
209214501Srpaulo  else
210214501Srpaulo    einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol);
211214501Srpaulo}
212214501Srpaulo
213214501Srpaulostatic char *
214214501Srpaulogld${EMULATION_NAME}_get_script (isfile)
215214501Srpaulo     int *isfile;
216214501SrpauloEOF
217214501Srpaulo
218214501Srpauloif test -n "$COMPILE_IN"
219214501Srpaulothen
220214501Srpaulo# Scripts compiled in.
221214501Srpaulo
222214501Srpaulo# sed commands to quote an ld script as a C string.
223214501Srpaulosc="-f stringify.sed"
224214501Srpaulo
225214501Srpaulocat >>e${EMULATION_NAME}.c <<EOF
226214501Srpaulo{			     
227214501Srpaulo  *isfile = 0;
228243419Scperciva
229243419Scperciva  if (link_info.relocateable == true && config.build_constructors == true)
230243419Scperciva    return
231243419ScpercivaEOF
232243419Scpercivased $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
233243419Scpercivaecho '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
234243419Scpercivased $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
235243419Scpercivaecho '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
236214501Srpaulosed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
237214501Srpauloecho '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
238214501Srpaulosed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
239214501Srpauloecho '  ; else return'                                     >> e${EMULATION_NAME}.c
240214501Srpaulosed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
241214501Srpauloecho '; }'                                                 >> e${EMULATION_NAME}.c
242214501Srpaulo
243214501Srpauloelse
244214501Srpaulo# Scripts read from the filesystem.
245214501Srpaulo
246214501Srpaulocat >>e${EMULATION_NAME}.c <<EOF
247214501Srpaulo{			     
248214501Srpaulo  *isfile = 1;
249214501Srpaulo
250214501Srpaulo  if (link_info.relocateable == true && config.build_constructors == true)
251214501Srpaulo    return "ldscripts/${EMULATION_NAME}.xu";
252214501Srpaulo  else if (link_info.relocateable == true)
253214501Srpaulo    return "ldscripts/${EMULATION_NAME}.xr";
254214501Srpaulo  else if (!config.text_read_only)
255214501Srpaulo    return "ldscripts/${EMULATION_NAME}.xbn";
256214501Srpaulo  else if (!config.magic_demand_paged)
257214501Srpaulo    return "ldscripts/${EMULATION_NAME}.xn";
258214501Srpaulo  else
259214501Srpaulo    return "ldscripts/${EMULATION_NAME}.x";
260214501Srpaulo}
261214501SrpauloEOF
262214501Srpaulo
263214501Srpaulofi
264214501Srpaulo
265214501Srpaulocat >>e${EMULATION_NAME}.c <<EOF
266214501Srpaulo
267214501Srpaulostruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
268214501Srpaulo{
269214501Srpaulo  gld${EMULATION_NAME}_before_parse,
270214501Srpaulo  syslib_default,
271214501Srpaulo  hll_default,
272214501Srpaulo  after_parse_default,
273214501Srpaulo  gld${EMULATION_NAME}_after_open,
274214501Srpaulo  after_allocation_default,
275214501Srpaulo  set_output_arch_default,
276214501Srpaulo  ldemul_default_target,
277214501Srpaulo  gld${EMULATION_NAME}_before_allocation,
278214501Srpaulo  gld${EMULATION_NAME}_get_script,
279214501Srpaulo  "${EMULATION_NAME}",
280214501Srpaulo  "${OUTPUT_FORMAT}",
281214501Srpaulo  gld${EMULATION_NAME}_finish,
282214501Srpaulo  NULL,	/* create output section statements */
283214501Srpaulo  NULL,	/* open dynamic archive */
284214501Srpaulo  NULL,	/* place orphan */
285214501Srpaulo  NULL,	/* set symbols */
286214501Srpaulo  gld${EMULATION_NAME}_parse_args,
287214501Srpaulo  NULL,	/* unrecognised file */
288214501Srpaulo  gld${EMULATION_NAME}_list_options,
289214501Srpaulo  NULL,	/* recognized file */
290214501Srpaulo  NULL 	/* find_potential_libraries */
291214501Srpaulo};
292214501SrpauloEOF
293214501Srpaulo