Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5199 | serge | 1 | /* ldemul.c -- clearing house for ld emulation states |
2 | Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, |
||
3 | 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010, 2011, 2012 |
||
4 | Free Software Foundation, Inc. |
||
5 | |||
6 | This file is part of the GNU Binutils. |
||
7 | |||
8 | This program 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 3 of the License, or |
||
11 | (at your option) any later version. |
||
12 | |||
13 | This program 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 this program; if not, write to the Free Software |
||
20 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
||
21 | MA 02110-1301, USA. */ |
||
22 | |||
23 | #include "sysdep.h" |
||
24 | #include "bfd.h" |
||
25 | #include "getopt.h" |
||
26 | #include "bfdlink.h" |
||
27 | |||
28 | #include "ld.h" |
||
29 | #include "ldmisc.h" |
||
30 | #include "ldexp.h" |
||
31 | #include "ldlang.h" |
||
32 | #include "ldfile.h" |
||
33 | #include "ldemul.h" |
||
34 | #include "ldmain.h" |
||
35 | #include "ldemul-list.h" |
||
36 | |||
37 | static ld_emulation_xfer_type *ld_emulation; |
||
38 | |||
39 | void |
||
40 | ldemul_hll (char *name) |
||
41 | { |
||
42 | ld_emulation->hll (name); |
||
43 | } |
||
44 | |||
45 | void |
||
46 | ldemul_syslib (char *name) |
||
47 | { |
||
48 | ld_emulation->syslib (name); |
||
49 | } |
||
50 | |||
51 | void |
||
52 | ldemul_after_parse (void) |
||
53 | { |
||
54 | ld_emulation->after_parse (); |
||
55 | } |
||
56 | |||
57 | void |
||
58 | ldemul_before_parse (void) |
||
59 | { |
||
60 | ld_emulation->before_parse (); |
||
61 | } |
||
62 | |||
63 | void |
||
64 | ldemul_after_open (void) |
||
65 | { |
||
66 | ld_emulation->after_open (); |
||
67 | } |
||
68 | |||
69 | void |
||
70 | ldemul_after_allocation (void) |
||
71 | { |
||
72 | ld_emulation->after_allocation (); |
||
73 | } |
||
74 | |||
75 | void |
||
76 | ldemul_before_allocation (void) |
||
77 | { |
||
78 | ld_emulation->before_allocation (); |
||
79 | } |
||
80 | |||
81 | void |
||
82 | ldemul_set_output_arch (void) |
||
83 | { |
||
84 | ld_emulation->set_output_arch (); |
||
85 | } |
||
86 | |||
87 | void |
||
88 | ldemul_finish (void) |
||
89 | { |
||
90 | ld_emulation->finish (); |
||
91 | } |
||
92 | |||
93 | void |
||
94 | ldemul_set_symbols (void) |
||
95 | { |
||
96 | if (ld_emulation->set_symbols) |
||
97 | ld_emulation->set_symbols (); |
||
98 | } |
||
99 | |||
100 | void |
||
101 | ldemul_create_output_section_statements (void) |
||
102 | { |
||
103 | if (ld_emulation->create_output_section_statements) |
||
104 | ld_emulation->create_output_section_statements (); |
||
105 | } |
||
106 | |||
107 | char * |
||
108 | ldemul_get_script (int *isfile) |
||
109 | { |
||
110 | return ld_emulation->get_script (isfile); |
||
111 | } |
||
112 | |||
113 | bfd_boolean |
||
114 | ldemul_open_dynamic_archive (const char *arch, search_dirs_type *search, |
||
115 | lang_input_statement_type *entry) |
||
116 | { |
||
117 | if (ld_emulation->open_dynamic_archive) |
||
118 | return (*ld_emulation->open_dynamic_archive) (arch, search, entry); |
||
119 | return FALSE; |
||
120 | } |
||
121 | |||
122 | lang_output_section_statement_type * |
||
123 | ldemul_place_orphan (asection *s, const char *name, int constraint) |
||
124 | { |
||
125 | if (ld_emulation->place_orphan) |
||
126 | return (*ld_emulation->place_orphan) (s, name, constraint); |
||
127 | return NULL; |
||
128 | } |
||
129 | |||
130 | void |
||
131 | ldemul_add_options (int ns, char **shortopts, int nl, |
||
132 | struct option **longopts, int nrl, |
||
133 | struct option **really_longopts) |
||
134 | { |
||
135 | if (ld_emulation->add_options) |
||
136 | (*ld_emulation->add_options) (ns, shortopts, nl, longopts, |
||
137 | nrl, really_longopts); |
||
138 | } |
||
139 | |||
140 | bfd_boolean |
||
141 | ldemul_handle_option (int optc) |
||
142 | { |
||
143 | if (ld_emulation->handle_option) |
||
144 | return (*ld_emulation->handle_option) (optc); |
||
145 | return FALSE; |
||
146 | } |
||
147 | |||
148 | bfd_boolean |
||
149 | ldemul_parse_args (int argc, char **argv) |
||
150 | { |
||
151 | /* Try and use the emulation parser if there is one. */ |
||
152 | if (ld_emulation->parse_args) |
||
153 | return (*ld_emulation->parse_args) (argc, argv); |
||
154 | return FALSE; |
||
155 | } |
||
156 | |||
157 | /* Let the emulation code handle an unrecognized file. */ |
||
158 | |||
159 | bfd_boolean |
||
160 | ldemul_unrecognized_file (lang_input_statement_type *entry) |
||
161 | { |
||
162 | if (ld_emulation->unrecognized_file) |
||
163 | return (*ld_emulation->unrecognized_file) (entry); |
||
164 | return FALSE; |
||
165 | } |
||
166 | |||
167 | /* Let the emulation code handle a recognized file. */ |
||
168 | |||
169 | bfd_boolean |
||
170 | ldemul_recognized_file (lang_input_statement_type *entry) |
||
171 | { |
||
172 | if (ld_emulation->recognized_file) |
||
173 | return (*ld_emulation->recognized_file) (entry); |
||
174 | return FALSE; |
||
175 | } |
||
176 | |||
177 | char * |
||
178 | ldemul_choose_target (int argc, char **argv) |
||
179 | { |
||
180 | return ld_emulation->choose_target (argc, argv); |
||
181 | } |
||
182 | |||
183 | |||
184 | /* The default choose_target function. */ |
||
185 | |||
186 | char * |
||
187 | ldemul_default_target (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) |
||
188 | { |
||
189 | char *from_outside = getenv (TARGET_ENVIRON); |
||
190 | if (from_outside != (char *) NULL) |
||
191 | return from_outside; |
||
192 | return ld_emulation->target_name; |
||
193 | } |
||
194 | |||
195 | /* If the entry point was not specified as an address, then add the |
||
196 | symbol as undefined. This will cause ld to extract an archive |
||
197 | element defining the entry if ld is linking against such an archive. |
||
198 | |||
199 | We don't do this when generating shared libraries unless given -e |
||
200 | on the command line, because most shared libs are not designed to |
||
201 | be run as an executable. However, some are, eg. glibc ld.so and |
||
202 | may rely on the default linker script supplying ENTRY. So we can't |
||
203 | remove the ENTRY from the script, but would rather not insert |
||
204 | undefined _start syms. */ |
||
205 | |||
206 | void |
||
207 | after_parse_default (void) |
||
208 | { |
||
209 | if (entry_symbol.name != NULL |
||
210 | && (link_info.executable || entry_from_cmdline)) |
||
211 | { |
||
212 | bfd_boolean is_vma = FALSE; |
||
213 | |||
214 | if (entry_from_cmdline) |
||
215 | { |
||
216 | const char *send; |
||
217 | |||
218 | bfd_scan_vma (entry_symbol.name, &send, 0); |
||
219 | is_vma = *send == '\0'; |
||
220 | } |
||
221 | if (!is_vma) |
||
222 | ldlang_add_undef (entry_symbol.name, entry_from_cmdline); |
||
223 | } |
||
224 | } |
||
225 | |||
226 | void |
||
227 | after_open_default (void) |
||
228 | { |
||
229 | } |
||
230 | |||
231 | void |
||
232 | after_allocation_default (void) |
||
233 | { |
||
234 | lang_relax_sections (FALSE); |
||
235 | } |
||
236 | |||
237 | void |
||
238 | before_allocation_default (void) |
||
239 | { |
||
240 | if (!link_info.relocatable) |
||
241 | strip_excluded_output_sections (); |
||
242 | } |
||
243 | |||
244 | void |
||
245 | finish_default (void) |
||
246 | { |
||
247 | if (!link_info.relocatable) |
||
248 | _bfd_fix_excluded_sec_syms (link_info.output_bfd, &link_info); |
||
249 | } |
||
250 | |||
251 | void |
||
252 | set_output_arch_default (void) |
||
253 | { |
||
254 | /* Set the output architecture and machine if possible. */ |
||
255 | bfd_set_arch_mach (link_info.output_bfd, |
||
256 | ldfile_output_architecture, ldfile_output_machine); |
||
257 | |||
258 | bfd_emul_set_maxpagesize (output_target, config.maxpagesize); |
||
259 | bfd_emul_set_commonpagesize (output_target, config.commonpagesize); |
||
260 | } |
||
261 | |||
262 | void |
||
263 | syslib_default (char *ignore ATTRIBUTE_UNUSED) |
||
264 | { |
||
265 | info_msg (_("%S SYSLIB ignored\n"), NULL); |
||
266 | } |
||
267 | |||
268 | void |
||
269 | hll_default (char *ignore ATTRIBUTE_UNUSED) |
||
270 | { |
||
271 | info_msg (_("%S HLL ignored\n"), NULL); |
||
272 | } |
||
273 | |||
274 | ld_emulation_xfer_type *ld_emulations[] = { EMULATION_LIST }; |
||
275 | |||
276 | void |
||
277 | ldemul_choose_mode (char *target) |
||
278 | { |
||
279 | ld_emulation_xfer_type **eptr = ld_emulations; |
||
280 | /* Ignore "gld" prefix. */ |
||
281 | if (target[0] == 'g' && target[1] == 'l' && target[2] == 'd') |
||
282 | target += 3; |
||
283 | for (; *eptr; eptr++) |
||
284 | { |
||
285 | if (strcmp (target, (*eptr)->emulation_name) == 0) |
||
286 | { |
||
287 | ld_emulation = *eptr; |
||
288 | return; |
||
289 | } |
||
290 | } |
||
291 | einfo (_("%P: unrecognised emulation mode: %s\n"), target); |
||
292 | einfo (_("Supported emulations: ")); |
||
293 | ldemul_list_emulations (stderr); |
||
294 | einfo ("%F\n"); |
||
295 | } |
||
296 | |||
297 | void |
||
298 | ldemul_list_emulations (FILE *f) |
||
299 | { |
||
300 | ld_emulation_xfer_type **eptr = ld_emulations; |
||
301 | bfd_boolean first = TRUE; |
||
302 | |||
303 | for (; *eptr; eptr++) |
||
304 | { |
||
305 | if (first) |
||
306 | first = FALSE; |
||
307 | else |
||
308 | fprintf (f, " "); |
||
309 | fprintf (f, "%s", (*eptr)->emulation_name); |
||
310 | } |
||
311 | } |
||
312 | |||
313 | void |
||
314 | ldemul_list_emulation_options (FILE *f) |
||
315 | { |
||
316 | ld_emulation_xfer_type **eptr; |
||
317 | int options_found = 0; |
||
318 | |||
319 | for (eptr = ld_emulations; *eptr; eptr++) |
||
320 | { |
||
321 | ld_emulation_xfer_type *emul = *eptr; |
||
322 | |||
323 | if (emul->list_options) |
||
324 | { |
||
325 | fprintf (f, "%s: \n", emul->emulation_name); |
||
326 | |||
327 | emul->list_options (f); |
||
328 | |||
329 | options_found = 1; |
||
330 | } |
||
331 | } |
||
332 | |||
333 | if (! options_found) |
||
334 | fprintf (f, _(" no emulation specific options.\n")); |
||
335 | } |
||
336 | |||
337 | int |
||
338 | ldemul_find_potential_libraries (char *name, lang_input_statement_type *entry) |
||
339 | { |
||
340 | if (ld_emulation->find_potential_libraries) |
||
341 | return ld_emulation->find_potential_libraries (name, entry); |
||
342 | |||
343 | return 0; |
||
344 | } |
||
345 | |||
346 | struct bfd_elf_version_expr * |
||
347 | ldemul_new_vers_pattern (struct bfd_elf_version_expr *entry) |
||
348 | { |
||
349 | if (ld_emulation->new_vers_pattern) |
||
350 | entry = (*ld_emulation->new_vers_pattern) (entry); |
||
351 | return entry; |
||
352 | } |