-y support
[platform/upstream/binutils.git] / ld / lnk960.em
1 cat >em_${EMULATION_NAME}.c <<EOF
2 /* intel coff loader emulation specific stuff
3    Copyright (C) 1991 Free Software Foundation, Inc.
4    Written by Steve Chamberlain steve@cygnus.com
5
6 This file is part of GLD, the Gnu Linker.
7
8 GLD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GLD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GLD; see the file COPYING.  If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24
25 /*#include "archures.h"*/
26 #include "ld.h"
27 #include "config.h"
28 #include "ldemul.h"
29 #include "ldmisc.h"
30 #include "ldlang.h"
31 #include "ldfile.h"
32
33 extern  boolean lang_float_flag;
34 extern bfd *output_bfd;
35
36
37
38 extern enum bfd_architecture ldfile_output_architecture;
39 extern unsigned long ldfile_output_machine;
40 extern char *ldfile_output_machine_name;
41
42
43 typedef struct lib_list {
44   char *name;
45   struct lib_list *next;
46 } lib_list_type;
47
48 static lib_list_type *hll_list;
49 static lib_list_type **hll_list_tail = &hll_list;
50
51 static lib_list_type *syslib_list;
52 static lib_list_type **syslib_list_tail = &syslib_list;
53
54
55 static void
56 append(list, name)
57 lib_list_type ***list;
58 char *name;
59 {
60   lib_list_type *element = 
61     (lib_list_type *)(ldmalloc(sizeof(lib_list_type)));
62
63   element->name = name;
64   element->next = (lib_list_type *)NULL;
65   **list = element;
66   *list = &element->next;
67
68 }
69
70 static boolean had_hll = false;
71 static boolean had_hll_name = false;
72 static void
73 lnk960_hll(name)
74 char *name;
75 {
76   had_hll = true;
77   if (name != (char *)NULL) {
78     had_hll_name = true;
79     append(&hll_list_tail, name);
80   }
81 }
82
83 static void 
84 lnk960_syslib(name)
85 char *name;
86 {
87   append(&syslib_list_tail,name);
88 }
89
90
91
92 #ifdef GNU960
93
94 static void 
95 lnk960_before_parse()
96 {
97   static char *env_variables[] = { "G960LIB", "G960BASE", 0 };
98   char **p;
99   char *env ;
100
101   for ( p = env_variables; *p; p++ ){
102     env =  (char *) getenv(*p);
103     if (env) {
104       ldfile_add_library_path(concat(env,"/lib/libcoff",""));
105     }
106   }
107
108   env= (char *) getenv("I960BASE");
109   if ( env ) {
110     ldfile_add_library_path(concat(env,"/lib",""));
111   }
112
113   ldfile_output_architecture = bfd_arch_i960;
114   ldfile_output_machine = bfd_mach_i960_core;
115 }
116
117 #else   /* not GNU960 */
118
119 static void 
120 lnk960_before_parse()
121 {
122   char *name = getenv("I960BASE");
123
124   if (name == (char *)NULL) {
125     name = getenv("G960BASE");
126     if (name == (char *)NULL) {
127       einfo("%P%F I960BASE and G960BASE not set\n");
128     }
129   }
130
131
132   ldfile_add_library_path(concat(name,"/lib",""));
133   ldfile_output_architecture = bfd_arch_i960;
134   ldfile_output_machine = bfd_mach_i960_core;
135 }
136
137 #endif  /* GNU960 */
138
139
140 static void
141 add_on(list, search)
142 lib_list_type *list;
143 lang_input_file_enum_type search;
144 {
145   while (list) {
146     lang_add_input_file(list->name,
147                         search,
148                         (char *)NULL);
149     list = list->next;
150   }
151 }
152 static void lnk960_after_parse()
153 {
154
155   /* If there has been no arch, default to -KB */
156   if (ldfile_output_machine_name[0] ==0) {
157     ldfile_add_arch("KB");
158   }
159
160   /* if there has been no hll list then add our own */
161   
162   if(had_hll && !had_hll_name) {
163     append(&hll_list_tail,"cg");
164     if (ldfile_output_machine == bfd_mach_i960_ka_sa ||
165         ldfile_output_machine == bfd_mach_i960_ca) {
166         {
167           append(&hll_list_tail,"fpg");
168         }
169     }
170   }
171   
172   add_on(hll_list, lang_input_file_is_l_enum);
173   add_on(syslib_list, lang_input_file_is_search_file_enum);
174 }
175
176 static void
177 lnk960_before_allocation()
178 {
179 }
180 static void
181 lnk960_after_allocation()
182 {
183   extern ld_config_type config;
184   if (config.relocateable_output == false) {
185     lang_abs_symbol_at_end_of(".text","_etext");
186     lang_abs_symbol_at_end_of(".data","_edata");
187     lang_abs_symbol_at_beginning_of(".bss","_bss_start");
188     lang_abs_symbol_at_end_of(".bss","_end");
189   }
190 }
191
192
193 static struct
194  {
195    unsigned  long number;
196    char *name; 
197  }
198 machine_table[] = {
199         bfd_mach_i960_core      ,"CORE",
200         bfd_mach_i960_kb_sb     ,"KB",
201         bfd_mach_i960_kb_sb     ,"SB",
202         bfd_mach_i960_mc        ,"MC",
203         bfd_mach_i960_xa        ,"XA",
204         bfd_mach_i960_ca        ,"CA",
205         bfd_mach_i960_ka_sa     ,"KA",
206         bfd_mach_i960_ka_sa     ,"SA",
207
208         bfd_mach_i960_core      ,"core",
209         bfd_mach_i960_kb_sb     ,"kb",
210         bfd_mach_i960_kb_sb     ,"sb",
211         bfd_mach_i960_mc        ,"mc",
212         bfd_mach_i960_xa        ,"xa",
213         bfd_mach_i960_ca        ,"ca",
214         bfd_mach_i960_ka_sa     ,"ka",
215         bfd_mach_i960_ka_sa     ,"sa",
216         0,(char *)NULL
217 };
218
219 static void
220 lnk960_set_output_arch()
221 {
222   /* Set the output architecture and machine if possible */
223   unsigned int i;
224   ldfile_output_machine = bfd_mach_i960_core;
225   for (i= 0; machine_table[i].name != (char*)NULL; i++) {
226     if (strcmp(ldfile_output_machine_name,machine_table[i].name)==0) {
227       ldfile_output_machine = machine_table[i].number;
228       break;
229     }
230   }
231   bfd_set_arch_mach(output_bfd, ldfile_output_architecture, ldfile_output_machine);
232 }
233
234 static char *
235 lnk960_choose_target()
236 {
237 #ifdef GNU960
238
239   return bfd_make_targ_name(BFD_COFF_FORMAT, 0);
240
241 #else
242
243   char *from_outside = getenv(TARGET_ENVIRON);
244   if (from_outside != (char *)NULL)
245     return from_outside;
246 #ifdef LNK960_LITTLE
247   return "coff-Intel-little";
248 #else
249   return "coff-Intel-big";
250 #endif
251 #endif
252
253 }
254
255 /* The default script if none is offered */
256 static char *lnk960_script = 
257 #include "lnk960.x"
258 ;
259
260
261 static char *lnk960_script_relocateable = 
262 #include "lnk960.xr"
263 ;
264
265 static char *lnk960_get_script()
266 {
267   extern ld_config_type config;
268   if (config.relocateable_output) {
269     return lnk960_script_relocateable;
270   }
271   return lnk960_script;
272 }
273 struct ld_emulation_xfer_struct ld_lnk960_emulation = 
274 {
275   lnk960_before_parse,
276   lnk960_syslib,
277   lnk960_hll,
278   lnk960_after_parse,
279   lnk960_after_allocation,
280   lnk960_set_output_arch,
281   lnk960_choose_target,
282   lnk960_before_allocation,
283   lnk960_get_script,
284   "lnk960",
285   ""
286 };
287 EOF