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