1# This shell script emits a C file. -*- C -*-
2# It does some substitutions.
3cat >e${EMULATION_NAME}.c <<EOF
4/* intel coff loader emulation specific stuff
5   Copyright 1991, 1992, 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2003
6   Free Software Foundation, Inc.
7   Written by Steve Chamberlain steve@cygnus.com
8
9This file is part of GLD, the Gnu Linker.
10
11GLD is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation; either version 2, or (at your option)
14any later version.
15
16GLD is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with GLD; see the file COPYING.  If not, write to
23the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
24
25#include "libiberty.h"
26#include "bfd.h"
27#include "sysdep.h"
28#include "bfdlink.h"
29
30/*#include "archures.h"*/
31#include "ld.h"
32#include "ldmain.h"
33#include "ldmisc.h"
34#include "ldexp.h"
35#include "ldlang.h"
36#include "ldfile.h"
37#include "ldemul.h"
38
39typedef struct lib_list {
40  char *name;
41  struct lib_list *next;
42} lib_list_type;
43
44static lib_list_type *hll_list;
45static lib_list_type **hll_list_tail = &hll_list;
46
47static lib_list_type *syslib_list;
48static lib_list_type **syslib_list_tail = &syslib_list;
49
50
51static void
52append (lib_list_type ***list, char *name)
53{
54  lib_list_type *element = (lib_list_type *) xmalloc (sizeof (lib_list_type));
55
56  element->name = name;
57  element->next = (lib_list_type *) NULL;
58  **list = element;
59  *list = &element->next;
60
61}
62
63static bfd_boolean had_hll = FALSE;
64static bfd_boolean had_hll_name = FALSE;
65
66static void
67lnk960_hll (char *name)
68{
69  had_hll = TRUE;
70  if (name != (char *) NULL)
71    {
72      had_hll_name = TRUE;
73      append (&hll_list_tail, name);
74    }
75}
76
77static void
78lnk960_syslib (char *name)
79{
80  append (&syslib_list_tail, name);
81}
82
83
84#ifdef GNU960
85
86static void
87lnk960_before_parse (void)
88{
89  static char *env_variables[] = { "G960LIB", "G960BASE", 0 };
90  char **p;
91  char *env ;
92
93  for (p = env_variables; *p; p++)
94    {
95      env = (char *) getenv (*p);
96      if (env)
97	ldfile_add_library_path (concat (env, "/lib/libcoff", ""), FALSE);
98    }
99
100  env = (char *) getenv ("I960BASE");
101  if (env)
102    ldfile_add_library_path(concat (env, "/lib", ""), FALSE);
103
104  ldfile_output_architecture = bfd_arch_i960;
105  ldfile_output_machine = bfd_mach_i960_core;
106}
107
108#else	/* not GNU960 */
109
110static void
111lnk960_before_parse (void)
112{
113  char *name = getenv ("I960BASE");
114
115  if (name == (char *) NULL)
116    {
117      name = getenv("G960BASE");
118      if (name == (char *) NULL)
119	einfo ("%P%F I960BASE and G960BASE not set\n");
120    }
121
122
123  ldfile_add_library_path (concat (name, "/lib", ""), FALSE);
124  ldfile_output_architecture = bfd_arch_i960;
125  ldfile_output_machine = bfd_mach_i960_core;
126}
127
128#endif	/* GNU960 */
129
130
131static void
132add_on (lib_list_type *list, lang_input_file_enum_type search)
133{
134  while (list)
135    {
136      lang_add_input_file (list->name, search, (char *) NULL);
137      list = list->next;
138    }
139}
140
141static void
142lnk960_after_parse (void)
143{
144  /* If there has been no arch, default to -KB */
145  if (ldfile_output_machine_name[0] == 0)
146    ldfile_add_arch ("KB");
147
148  /* if there has been no hll list then add our own */
149
150  if (had_hll && !had_hll_name)
151    {
152      append (&hll_list_tail, "cg");
153      if (ldfile_output_machine == bfd_mach_i960_ka_sa
154	  || ldfile_output_machine == bfd_mach_i960_ca)
155	append (&hll_list_tail, "fpg");
156    }
157
158  add_on (hll_list, lang_input_file_is_l_enum);
159  add_on (syslib_list, lang_input_file_is_search_file_enum);
160}
161
162static void
163lnk960_before_allocation (void)
164{
165}
166
167static void
168lnk960_after_allocation (void)
169{
170  if (!link_info.relocatable)
171    {
172      lang_abs_symbol_at_end_of (".text", "_etext");
173      lang_abs_symbol_at_end_of (".data", "_edata");
174      lang_abs_symbol_at_beginning_of (".bss", "_bss_start");
175      lang_abs_symbol_at_end_of (".bss", "_end");
176    }
177}
178
179
180static struct
181 {
182   unsigned  long number;
183   char *name;
184 }
185machine_table[] =
186{
187  { bfd_mach_i960_core	,"CORE" },
188  { bfd_mach_i960_kb_sb	,"KB" },
189  { bfd_mach_i960_kb_sb	,"SB" },
190  { bfd_mach_i960_mc	,"MC" },
191  { bfd_mach_i960_xa	,"XA" },
192  { bfd_mach_i960_ca	,"CA" },
193  { bfd_mach_i960_ka_sa	,"KA" },
194  { bfd_mach_i960_ka_sa	,"SA" },
195  { bfd_mach_i960_jx	,"JX" },
196  { bfd_mach_i960_hx	,"HX" },
197
198  { bfd_mach_i960_core	,"core" },
199  { bfd_mach_i960_kb_sb	,"kb" },
200  { bfd_mach_i960_kb_sb	,"sb" },
201  { bfd_mach_i960_mc	,"mc" },
202  { bfd_mach_i960_xa	,"xa" },
203  { bfd_mach_i960_ca	,"ca" },
204  { bfd_mach_i960_ka_sa	,"ka" },
205  { bfd_mach_i960_ka_sa	,"sa" },
206  { bfd_mach_i960_jx	,"jx" },
207  { bfd_mach_i960_hx	,"hx" },
208
209  { 0, (char *) NULL }
210};
211
212static void
213lnk960_set_output_arch (void)
214{
215  /* Set the output architecture and machine if possible */
216  unsigned int i;
217  ldfile_output_machine = bfd_mach_i960_core;
218  for (i= 0; machine_table[i].name != (char*) NULL; i++)
219    {
220      if (strcmp (ldfile_output_machine_name, machine_table[i].name) == 0)
221	{
222	  ldfile_output_machine = machine_table[i].number;
223	  break;
224	}
225    }
226  bfd_set_arch_mach (output_bfd, ldfile_output_architecture,
227		     ldfile_output_machine);
228}
229
230static char *
231lnk960_choose_target (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
232{
233#ifdef GNU960
234
235  return bfd_make_targ_name (BFD_COFF_FORMAT, 0);
236
237#else
238
239  char *from_outside = getenv (TARGET_ENVIRON);
240  if (from_outside != (char *) NULL)
241    return from_outside;
242#ifdef LNK960_LITTLE
243  return "coff-Intel-little";
244#else
245  return "coff-Intel-big";
246#endif
247#endif
248
249}
250
251static char *
252lnk960_get_script (int *isfile)
253EOF
254
255if test -n "$COMPILE_IN"
256then
257# Scripts compiled in.
258
259# sed commands to quote an ld script as a C string.
260sc="-f stringify.sed"
261
262cat >>e${EMULATION_NAME}.c <<EOF
263{
264  *isfile = 0;
265
266  if (link_info.relocatable && config.build_constructors)
267    return
268EOF
269sed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
270echo '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
271sed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
272echo '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
273sed $sc ldscripts/${EMULATION_NAME}.xbn                >> e${EMULATION_NAME}.c
274echo '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
275sed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
276echo '  ; else return'                                 >> e${EMULATION_NAME}.c
277sed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
278echo '; }'                                             >> e${EMULATION_NAME}.c
279
280else
281# Scripts read from the filesystem.
282
283cat >>e${EMULATION_NAME}.c <<EOF
284{
285  *isfile = 1;
286
287  if (link_info.relocatable && config.build_constructors)
288    return "ldscripts/${EMULATION_NAME}.xu";
289  else if (link_info.relocatable)
290    return "ldscripts/${EMULATION_NAME}.xr";
291  else if (!config.text_read_only)
292    return "ldscripts/${EMULATION_NAME}.xbn";
293  else if (!config.magic_demand_paged)
294    return "ldscripts/${EMULATION_NAME}.xn";
295  else
296    return "ldscripts/${EMULATION_NAME}.x";
297}
298EOF
299
300fi
301
302cat >>e${EMULATION_NAME}.c <<EOF
303
304struct ld_emulation_xfer_struct ld_lnk960_emulation =
305{
306  lnk960_before_parse,
307  lnk960_syslib,
308  lnk960_hll,
309  lnk960_after_parse,
310  NULL,			/* after_open */
311  lnk960_after_allocation,
312  lnk960_set_output_arch,
313  lnk960_choose_target,
314  lnk960_before_allocation,
315  lnk960_get_script,
316  "lnk960",
317  "",
318  NULL,	/* finish */
319  NULL,	/* create output section statements */
320  NULL,	/* open dynamic archive */
321  NULL,	/* place orphan */
322  NULL,	/* set symbols */
323  NULL,	/* parse args */
324  NULL,	/* add_options */
325  NULL,	/* handle_option */
326  NULL,	/* unrecognized file */
327  NULL,	/* list options */
328  NULL,	/* recognized file */
329  NULL,	/* find_potential_libraries */
330  NULL	/* new_vers_pattern */
331};
332EOF
333