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