update copyrights
[deliverable/binutils-gdb.git] / ld / emultempl / elf32.em
CommitLineData
2a9fa50c
ILT
1# This shell script emits a C file. -*- C -*-
2# It does some substitutions.
3cat >e${EMULATION_NAME}.c <<EOF
4/* This file is is generated by a shell script. DO NOT EDIT! */
5
6/* 32 bit ELF emulation code for ${EMULATION_NAME}
5f3548d6 7 Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
2a9fa50c
ILT
8 Written by Steve Chamberlain <sac@cygnus.com>
9 ELF support by Ian Lance Taylor <ian@cygnus.com>
10
11This file is part of GLD, the Gnu Linker.
12
13This program is free software; you can redistribute it and/or modify
14it under the terms of the GNU General Public License as published by
15the Free Software Foundation; either version 2 of the License, or
16(at your option) any later version.
17
18This program is distributed in the hope that it will be useful,
19but WITHOUT ANY WARRANTY; without even the implied warranty of
20MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21GNU General Public License for more details.
22
23You should have received a copy of the GNU General Public License
24along with this program; if not, write to the Free Software
25Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26
27#define TARGET_IS_${EMULATION_NAME}
28
29#include "bfd.h"
30#include "sysdep.h"
5efddb2e
ILT
31
32#include <ctype.h>
33
2a9fa50c
ILT
34#include "bfdlink.h"
35
36#include "ld.h"
37#include "config.h"
38#include "ldmain.h"
39#include "ldemul.h"
40#include "ldfile.h"
41#include "ldmisc.h"
42#include "ldexp.h"
43#include "ldlang.h"
5efddb2e 44#include "ldgram.h"
2a9fa50c
ILT
45
46static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
5efddb2e
ILT
47static boolean gld${EMULATION_NAME}_open_dynamic_archive
48 PARAMS ((const char *, lang_input_statement_type *));
2a9fa50c
ILT
49static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
50static void gld${EMULATION_NAME}_find_statement_assignment
51 PARAMS ((lang_statement_union_type *));
52static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
5efddb2e
ILT
53static boolean gld${EMULATION_NAME}_place_orphan
54 PARAMS ((lang_input_statement_type *, asection *));
55static void gld${EMULATION_NAME}_place_section
56 PARAMS ((lang_statement_union_type *));
2a9fa50c
ILT
57static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
58
59static void
60gld${EMULATION_NAME}_before_parse()
61{
62 ldfile_output_architecture = bfd_arch_${ARCH};
5efddb2e
ILT
63 config.dynamic_link = ${DYNAMIC_LINK-true};
64}
65
66/* Try to open a dynamic archive. This is where we know that ELF
67 dynamic libraries have an extension of .so. */
68
69static boolean
70gld${EMULATION_NAME}_open_dynamic_archive (arch, entry)
71 const char *arch;
72 lang_input_statement_type *entry;
73{
74 const char *filename;
75
76 filename = entry->filename;
77
78 if (! ldfile_open_file_search (arch, entry, "lib", ".so"))
79 return false;
80
81 /* We have found a dynamic object to include in the link. The ELF
82 backend linker will create a DT_NEEDED entry in the .dynamic
83 section naming this file. If this file includes a DT_SONAME
84 entry, it will be used. Otherwise, the ELF linker will just use
85 the name of the file. For an archive found by searching, like
86 this one, the DT_NEEDED entry should consist of just the name of
87 the file, without the path information used to find it. Note
88 that we only need to do this if we have a dynamic object; an
89 archive will never be referenced by a DT_NEEDED entry.
90
91 FIXME: This approach--using bfd_elf_set_dt_needed_name--is not
92 very pretty. I haven't been able to think of anything that is
93 pretty, though. */
94 if (bfd_check_format (entry->the_bfd, bfd_object)
95 && (entry->the_bfd->flags & DYNAMIC) != 0)
96 {
97 char *needed_name;
98
99 ASSERT (entry->is_archive && entry->search_dirs_flag);
100 needed_name = (char *) xmalloc (strlen (filename)
101 + strlen (arch)
102 + sizeof "lib.so");
103 sprintf (needed_name, "lib%s%s.so", filename, arch);
104 bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
105 }
106
107 return true;
2a9fa50c
ILT
108}
109
110/* This is called after the sections have been attached to output
111 sections, but before any sizes or addresses have been set. */
112
113static void
114gld${EMULATION_NAME}_before_allocation ()
115{
7fb9ca5f 116 asection *sinterp;
5f3548d6 117 lang_input_statement_type *is;
7fb9ca5f 118
2a9fa50c
ILT
119 /* If we are going to make any variable assignments, we need to let
120 the ELF backend know about them in case the variables are
121 referred to by dynamic objects. */
122 lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
123
124 /* Let the ELF backend work out the sizes of any sections required
125 by dynamic linking. */
5efddb2e
ILT
126 if (! bfd_elf32_size_dynamic_sections (output_bfd,
127 command_line.soname,
128 command_line.rpath,
129 command_line.export_dynamic,
130 &link_info,
7fb9ca5f 131 &sinterp))
2a9fa50c 132 einfo ("%P%F: failed to set dynamic section sizes: %E\n");
7fb9ca5f
ILT
133
134 /* Let the user override the dynamic linker we are using. */
135 if (command_line.interpreter != NULL
136 && sinterp != NULL)
137 {
138 sinterp->contents = (bfd_byte *) command_line.interpreter;
139 sinterp->_raw_size = strlen (command_line.interpreter) + 1;
140 }
5f3548d6
ILT
141
142 /* Look for any sections named .gnu.warning. As a GNU extensions,
143 we treat such sections as containing warning messages. We print
144 out the warning message, and then zero out the section size so
145 that it does not get copied into the output file. */
146
147 {
148 LANG_FOR_EACH_INPUT_STATEMENT (is)
149 {
150 asection *s;
151 bfd_size_type sz;
152 char *msg;
153 boolean ret;
154
155 if (is->just_syms_flag)
156 continue;
157
158 s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning");
159 if (s == NULL)
160 continue;
161
162 sz = bfd_section_size (is->the_bfd, s);
163 msg = xmalloc ((size_t) sz + 1);
164 if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz))
165 einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
166 is->the_bfd);
167 msg[sz] = '\0';
168 ret = link_info.callbacks->warning (&link_info, msg);
169 ASSERT (ret);
170 free (msg);
171
172 /* Clobber the section size, so that we don't waste copying the
173 warning into the output file. */
174 s->_raw_size = 0;
175 }
176 }
2a9fa50c
ILT
177}
178
179/* This is called by the before_allocation routine via
180 lang_for_each_statement. It locates any assignment statements, and
181 tells the ELF backend about them, in case they are assignments to
182 symbols which are referred to by dynamic objects. */
183
184static void
185gld${EMULATION_NAME}_find_statement_assignment (s)
186 lang_statement_union_type *s;
187{
188 if (s->header.type == lang_assignment_statement_enum)
189 gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
190}
191
192/* Look through an expression for an assignment statement. */
193
194static void
195gld${EMULATION_NAME}_find_exp_assignment (exp)
196 etree_type *exp;
197{
198 switch (exp->type.node_class)
199 {
200 case etree_assign:
201 if (strcmp (exp->assign.dst, ".") != 0)
202 {
203 if (! bfd_elf32_record_link_assignment (output_bfd, &link_info,
204 exp->assign.dst))
205 einfo ("%P%F: failed to record assignment to %s: %E\n",
206 exp->assign.dst);
207 }
208 gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
209 break;
210
211 case etree_binary:
212 gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
213 gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
214 break;
215
216 case etree_trinary:
217 gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
218 gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
219 gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
220 break;
221
222 case etree_unary:
223 gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
224 break;
225
226 default:
227 break;
228 }
229}
230
5efddb2e
ILT
231/* Place an orphan section. We use this to put random SHF_ALLOC
232 sections in the right segment. */
233
234static asection *hold_section;
235static lang_output_section_statement_type *hold_use;
236static lang_output_section_statement_type *hold_text;
237static lang_output_section_statement_type *hold_data;
238static lang_output_section_statement_type *hold_bss;
239
240/*ARGSUSED*/
241static boolean
242gld${EMULATION_NAME}_place_orphan (file, s)
243 lang_input_statement_type *file;
244 asection *s;
245{
246 lang_output_section_statement_type *place;
247 asection *snew, **pps;
248 lang_statement_list_type *old;
249 lang_statement_list_type add;
250 etree_type *address;
251 const char *secname, *ps;
252 lang_output_section_statement_type *os;
253
254 if ((s->flags & SEC_ALLOC) == 0)
255 return false;
256
257 /* Look through the script to see where to place this section. */
258 hold_section = s;
259 hold_use = NULL;
260 lang_for_each_statement (gld${EMULATION_NAME}_place_section);
261
262 if (hold_use != NULL)
263 {
264 /* We have already placed a section with this name. */
265 wild_doit (&hold_use->children, s, hold_use, file);
266 return true;
267 }
268
269 /* Decide which segment the section should go in based on the
270 section flags. */
271 place = NULL;
272 if ((s->flags & SEC_HAS_CONTENTS) == 0
273 && hold_bss != NULL)
274 place = hold_bss;
275 else if ((s->flags & SEC_READONLY) == 0
276 && hold_data != NULL)
277 place = hold_data;
278 else if ((s->flags & SEC_READONLY) != 0
279 && hold_text != NULL)
280 place = hold_text;
281 if (place == NULL)
282 return false;
283
284 secname = bfd_get_section_name (s->owner, s);
285
5f3548d6
ILT
286 /* When generating an object which is to be dynamically linked, we
287 do not support orphaned reloc sections. This is because all the
288 reloc sections must be contiguous in order to generate correct
289 DT_REL entries. When this case arises, you can just add the
290 appropriate reloc sections to the linker script. Note that the
291 .rel.plt section must always be the last reloc section. FIXME:
292 This should simply be handled correctly here. */
293 ASSERT (strncmp (secname, ".rel", 4) != 0
294 || bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
295
5efddb2e
ILT
296 /* Create the section in the output file, and put it in the right
297 place. This shuffling to make the output file look neater, and
298 also means that the BFD backend does not have to sort the
299 sections in order by address. */
300 snew = bfd_make_section (output_bfd, secname);
301 if (snew == NULL)
302 einfo ("%P%F: output format %s cannot represent section called %s\n",
303 output_bfd->xvec->name, secname);
304 for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
305 ;
306 *pps = snew->next;
307 snew->next = place->bfd_section->next;
308 place->bfd_section->next = snew;
309
310 /* Start building a list of statements for this section. */
311 old = stat_ptr;
312 stat_ptr = &add;
313 lang_list_init (stat_ptr);
314
315 /* If the name of the section is representable in C, then create
316 symbols to mark the start and the end of the section. */
317 for (ps = secname; *ps != '\0'; ps++)
318 if (! isalnum (*ps) && *ps != '_')
319 break;
320 if (*ps == '\0' && config.build_constructors)
321 {
322 char *symname;
323
324 symname = (char *) xmalloc (ps - secname + sizeof "__start_");
325 sprintf (symname, "__start_%s", secname);
326 lang_add_assignment (exp_assop ('=', symname,
327 exp_nameop (NAME, ".")));
328 }
329
330 if (! link_info.relocateable)
331 address = NULL;
332 else
333 address = exp_intop ((bfd_vma) 0);
334
335 lang_enter_output_section_statement (secname, address, 0,
336 (bfd_vma) 0,
337 (etree_type *) NULL,
338 (etree_type *) NULL,
339 (etree_type *) NULL);
340
341 os = lang_output_section_statement_lookup (secname);
342 wild_doit (&os->children, s, os, file);
343
344 lang_leave_output_section_statement ((bfd_vma) 0, "*default*");
345 stat_ptr = &add;
346
347 if (*ps == '\0' && config.build_constructors)
348 {
349 char *symname;
350
351 symname = (char *) xmalloc (ps - secname + sizeof "__stop_");
352 sprintf (symname, "__stop_%s", secname);
353 lang_add_assignment (exp_assop ('=', symname,
354 exp_nameop (NAME, ".")));
355 }
356
357 /* Now stick the new statement list right after PLACE. */
358 *add.tail = place->header.next;
359 place->header.next = add.head;
360
361 stat_ptr = old;
362
363 return true;
364}
365
366static void
367gld${EMULATION_NAME}_place_section (s)
368 lang_statement_union_type *s;
369{
370 lang_output_section_statement_type *os;
371
372 if (s->header.type != lang_output_section_statement_enum)
373 return;
374
375 os = &s->output_section_statement;
376
377 if (strcmp (os->name, hold_section->name) == 0)
378 hold_use = os;
379
380 if (strcmp (os->name, ".text") == 0)
381 hold_text = os;
382 else if (strcmp (os->name, ".data") == 0)
383 hold_data = os;
384 else if (strcmp (os->name, ".bss") == 0)
385 hold_bss = os;
386}
387
2a9fa50c
ILT
388static char *
389gld${EMULATION_NAME}_get_script(isfile)
390 int *isfile;
391EOF
392
393if test -n "$COMPILE_IN"
394then
395# Scripts compiled in.
396
397# sed commands to quote an ld script as a C string.
398sc='s/["\\]/\\&/g
399s/$/\\n\\/
4001s/^/"/
401$s/$/n"/
402'
403
404cat >>e${EMULATION_NAME}.c <<EOF
405{
406 *isfile = 0;
407
408 if (link_info.relocateable == true && config.build_constructors == true)
409 return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
410 else if (link_info.relocateable == true)
411 return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
412 else if (!config.text_read_only)
413 return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
414 else if (!config.magic_demand_paged)
415 return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
5efddb2e
ILT
416 else if (link_info.shared)
417 return `sed "$sc" ldscripts/${EMULATION_NAME}.xs`;
2a9fa50c
ILT
418 else
419 return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
420}
421EOF
422
423else
424# Scripts read from the filesystem.
425
426cat >>e${EMULATION_NAME}.c <<EOF
427{
428 *isfile = 1;
429
430 if (link_info.relocateable == true && config.build_constructors == true)
431 return "ldscripts/${EMULATION_NAME}.xu";
432 else if (link_info.relocateable == true)
433 return "ldscripts/${EMULATION_NAME}.xr";
434 else if (!config.text_read_only)
435 return "ldscripts/${EMULATION_NAME}.xbn";
436 else if (!config.magic_demand_paged)
437 return "ldscripts/${EMULATION_NAME}.xn";
5efddb2e
ILT
438 else if (link_info.shared)
439 return "ldscripts/${EMULATION_NAME}.xs";
2a9fa50c
ILT
440 else
441 return "ldscripts/${EMULATION_NAME}.x";
442}
443EOF
444
445fi
446
447cat >>e${EMULATION_NAME}.c <<EOF
448
449struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
450{
451 gld${EMULATION_NAME}_before_parse,
452 syslib_default,
453 hll_default,
454 after_parse_default,
5f3548d6 455 after_open_default,
2a9fa50c
ILT
456 after_allocation_default,
457 set_output_arch_default,
458 ldemul_default_target,
459 gld${EMULATION_NAME}_before_allocation,
460 gld${EMULATION_NAME}_get_script,
461 "${EMULATION_NAME}",
5efddb2e
ILT
462 "${OUTPUT_FORMAT}",
463 NULL,
464 NULL,
465 gld${EMULATION_NAME}_open_dynamic_archive,
466 gld${EMULATION_NAME}_place_orphan
2a9fa50c
ILT
467};
468EOF
This page took 0.057197 seconds and 4 git commands to generate.