Commit | Line | Data |
---|---|---|
2fa0b342 DHW |
1 | /* Copyright (C) 1991 Free Software Foundation, Inc. |
2 | ||
3 | This file is part of GLD, the Gnu Linker. | |
4 | ||
5 | GLD is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 1, or (at your option) | |
8 | any later version. | |
9 | ||
10 | GLD is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with GLD; see the file COPYING. If not, write to | |
17 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
18 | ||
19 | /* | |
20 | $Id$ | |
21 | ||
22 | $Log$ | |
de7c1ff6 SC |
23 | Revision 1.3 1991/04/08 23:21:26 steve |
24 | *** empty log message *** | |
2fa0b342 | 25 | |
de7c1ff6 SC |
26 | * Revision 1.2 1991/03/22 23:02:31 steve |
27 | * Brought up to sync with Intel again. | |
28 | * | |
2fa0b342 DHW |
29 | * Revision 1.2 1991/03/15 18:45:55 rich |
30 | * foo | |
31 | * | |
32 | * Revision 1.1 1991/03/13 00:48:13 chrisb | |
33 | * Initial revision | |
34 | * | |
35 | * Revision 1.6 1991/03/10 09:31:20 rich | |
36 | * Modified Files: | |
37 | * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c | |
38 | * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h | |
39 | * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c | |
40 | * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c | |
41 | * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h | |
42 | * | |
43 | * As of this round of changes, ld now builds on all hosts of (Intel960) | |
44 | * interest and copy passes my copy test on big endian hosts again. | |
45 | * | |
46 | * Revision 1.5 1991/03/09 03:23:47 sac | |
47 | * Now looks in G960BASE if I960BASE isn't defined. | |
48 | * | |
49 | * Revision 1.4 1991/03/06 02:23:35 sac | |
50 | * Added support for partial linking. | |
51 | * | |
52 | * Revision 1.3 1991/02/22 17:14:58 sac | |
53 | * Added RCS keywords and copyrights | |
54 | * | |
55 | */ | |
56 | ||
57 | /* | |
58 | ||
59 | Written by Steve Chamberlain steve@cygnus.com | |
60 | ||
61 | * intel coff loader emulation specific stuff | |
62 | */ | |
63 | ||
64 | #include "sysdep.h" | |
65 | #include "bfd.h" | |
66 | ||
67 | /*#include "archures.h"*/ | |
68 | #include "ld.h" | |
69 | #include "config.h" | |
70 | #include "ld-emul.h" | |
71 | #include "ldmisc.h" | |
72 | #include "ldlang.h" | |
73 | #include "ldfile.h" | |
74 | ||
75 | extern boolean lang_float_flag; | |
76 | extern bfd *output_bfd; | |
77 | ||
78 | ||
79 | ||
80 | extern enum bfd_architecture ldfile_output_architecture; | |
81 | extern unsigned long ldfile_output_machine; | |
82 | extern char *ldfile_output_machine_name; | |
83 | ||
84 | ||
85 | typedef struct lib_list { | |
86 | char *name; | |
87 | struct lib_list *next; | |
88 | } lib_list_type; | |
89 | ||
90 | static lib_list_type *hll_list; | |
91 | static lib_list_type **hll_list_tail = &hll_list; | |
92 | ||
93 | static lib_list_type *syslib_list; | |
94 | static lib_list_type **syslib_list_tail = &syslib_list; | |
95 | ||
96 | ||
97 | static void | |
98 | append(list, name) | |
99 | lib_list_type ***list; | |
100 | char *name; | |
101 | { | |
102 | lib_list_type *element = | |
103 | (lib_list_type *)(ldmalloc(sizeof(lib_list_type))); | |
104 | ||
105 | element->name = name; | |
106 | element->next = (lib_list_type *)NULL; | |
107 | **list = element; | |
108 | *list = &element->next; | |
109 | ||
110 | } | |
111 | ||
112 | static boolean had_hll = false; | |
113 | static boolean had_hll_name = false; | |
114 | static void | |
115 | lnk960_hll(name) | |
116 | char *name; | |
117 | { | |
118 | had_hll = true; | |
119 | if (name != (char *)NULL) { | |
120 | had_hll_name = true; | |
121 | append(&hll_list_tail, name); | |
122 | } | |
123 | } | |
124 | ||
125 | static void | |
126 | lnk960_syslib(name) | |
127 | char *name; | |
128 | { | |
129 | append(&syslib_list_tail,name); | |
130 | } | |
131 | ||
132 | ||
133 | ||
134 | static void | |
135 | lnk960_before_parse() | |
136 | { | |
137 | char *name = getenv("I960BASE"); | |
138 | ||
139 | if (name == (char *)NULL) { | |
140 | name = getenv("G960BASE"); | |
141 | if (name == (char *)NULL) { | |
142 | info("%P%F I960BASE and G960BASE not set\n"); | |
143 | } | |
144 | } | |
145 | ||
146 | ||
147 | ldfile_add_library_path(concat(name,"/lib","")); | |
148 | ldfile_output_architecture = bfd_arch_i960; | |
149 | ldfile_output_machine = bfd_mach_i960_core; | |
150 | } | |
151 | ||
152 | static void | |
153 | add_on(list, search) | |
154 | lib_list_type *list; | |
155 | lang_input_file_enum_type search; | |
156 | { | |
157 | while (list) { | |
158 | lang_add_input_file(list->name, | |
159 | search, | |
160 | (char *)NULL); | |
161 | list = list->next; | |
162 | } | |
163 | } | |
164 | static void lnk960_after_parse() | |
165 | { | |
166 | ||
167 | /* If there has been no arch, default to -KB */ | |
168 | if (ldfile_output_machine_name[0] ==0) { | |
169 | ldfile_add_arch("kb"); | |
170 | } | |
171 | ||
172 | /* if there has been no hll list then add our own */ | |
173 | ||
174 | if(had_hll && !had_hll_name) { | |
175 | append(&hll_list_tail,"c"); | |
176 | if (lang_float_flag == true) { | |
177 | append(&hll_list_tail,"m"); | |
178 | } | |
179 | else { | |
180 | append(&hll_list_tail,"mstub"); | |
181 | } | |
182 | if (ldfile_output_machine == bfd_mach_i960_ka_sa || | |
183 | ldfile_output_machine == bfd_mach_i960_ca) { | |
184 | { | |
185 | append(&hll_list_tail,"f"); | |
186 | } | |
187 | } | |
188 | } | |
189 | ||
190 | ||
191 | ||
192 | add_on(hll_list, lang_input_file_is_l_enum); | |
193 | add_on(syslib_list, lang_input_file_is_search_file_enum); | |
194 | ||
195 | ||
196 | } | |
197 | ||
198 | static void | |
199 | lnk960_before_allocation() | |
200 | { | |
201 | } | |
202 | static void | |
203 | lnk960_after_allocation() | |
204 | { | |
de7c1ff6 SC |
205 | extern ld_config_type config; |
206 | if (config.relocateable_output == false) { | |
207 | lang_abs_symbol_at_end_of(".text","_etext"); | |
208 | lang_abs_symbol_at_end_of(".data","_edata"); | |
209 | lang_abs_symbol_at_beginning_of(".bss","_bss_start"); | |
210 | lang_abs_symbol_at_end_of(".bss","_end"); | |
211 | } | |
2fa0b342 DHW |
212 | } |
213 | ||
214 | static struct | |
215 | { | |
216 | unsigned long number; | |
217 | char *name; | |
218 | } | |
219 | machine_table[] = { | |
220 | bfd_mach_i960_core ,"CORE", | |
221 | bfd_mach_i960_kb_sb ,"KB", | |
222 | bfd_mach_i960_kb_sb ,"SB", | |
223 | bfd_mach_i960_mc ,"MC", | |
224 | bfd_mach_i960_xa ,"XA", | |
225 | bfd_mach_i960_ca ,"CA", | |
226 | bfd_mach_i960_ka_sa ,"KA", | |
227 | bfd_mach_i960_ka_sa ,"SA", | |
228 | ||
229 | bfd_mach_i960_core ,"core", | |
230 | bfd_mach_i960_kb_sb ,"kb", | |
231 | bfd_mach_i960_kb_sb ,"sb", | |
232 | bfd_mach_i960_mc ,"mc", | |
233 | bfd_mach_i960_xa ,"xa", | |
234 | bfd_mach_i960_ca ,"ca", | |
235 | bfd_mach_i960_ka_sa ,"ka", | |
236 | bfd_mach_i960_ka_sa ,"sa", | |
237 | 0,(char *)NULL | |
238 | }; | |
239 | ||
240 | static void | |
241 | lnk960_set_output_arch() | |
242 | { | |
243 | /* Set the output architecture and machine if possible */ | |
244 | unsigned int i; | |
245 | ldfile_output_machine = bfd_mach_i960_core; | |
246 | for (i= 0; machine_table[i].name != (char*)NULL; i++) { | |
247 | if (strcmp(ldfile_output_machine_name,machine_table[i].name)==0) { | |
248 | ldfile_output_machine = machine_table[i].number; | |
249 | break; | |
250 | } | |
251 | } | |
252 | bfd_set_arch_mach(output_bfd, ldfile_output_architecture, ldfile_output_machine); | |
253 | } | |
254 | ||
255 | static char * | |
256 | lnk960_choose_target() | |
257 | { | |
258 | char *from_outside = getenv(TARGET_ENVIRON); | |
259 | if (from_outside != (char *)NULL) | |
260 | return from_outside; | |
261 | return LNK960_TARGET; | |
262 | } | |
263 | ||
264 | /* The default script if none is offered */ | |
265 | static char *lnk960_script = "\ | |
266 | SECTIONS \ | |
267 | { \ | |
268 | .text : \ | |
269 | { \ | |
270 | *(.text) \ | |
271 | } \ | |
272 | _etext = .;\ | |
273 | .data SIZEOF(.text) + ADDR(.text):\ | |
274 | { \ | |
275 | *(.data) \ | |
276 | } \ | |
277 | _edata = .; \ | |
278 | .bss SIZEOF(.data) + ADDR(.data) : \ | |
279 | { \ | |
280 | _bss_start = . ;\ | |
281 | *(.bss) \ | |
282 | [COMMON] \ | |
283 | } \ | |
284 | _end = . ; \ | |
285 | } \ | |
286 | "; | |
287 | ||
288 | static char *lnk960_script_relocateable = "\ | |
289 | SECTIONS \ | |
290 | { \ | |
291 | .text 0x40000000: \ | |
292 | { \ | |
293 | *(.text) \ | |
294 | } \ | |
295 | .data 0:\ | |
296 | { \ | |
297 | *(.data) \ | |
298 | } \ | |
299 | .bss SIZEOF(.data) + ADDR(.data) : \ | |
300 | { \ | |
301 | *(.bss) \ | |
302 | [COMMON] \ | |
303 | } \ | |
304 | } \ | |
305 | "; | |
306 | ||
307 | static char *lnk960_get_script() | |
308 | { | |
309 | extern ld_config_type config; | |
310 | if (config.relocateable_output) { | |
311 | return lnk960_script_relocateable; | |
312 | } | |
313 | return lnk960_script; | |
314 | ||
315 | ||
316 | } | |
317 | struct ld_emulation_xfer_struct ld_lnk960_emulation = | |
318 | { | |
319 | lnk960_before_parse, | |
320 | lnk960_syslib, | |
321 | lnk960_hll, | |
322 | lnk960_after_parse, | |
323 | lnk960_after_allocation, | |
324 | lnk960_set_output_arch, | |
325 | lnk960_choose_target, | |
326 | lnk960_before_allocation, | |
327 | lnk960_get_script, | |
328 | }; |