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