add armelf.em to things to keep.
[deliverable/binutils-gdb.git] / ld / emultempl / pe.em
CommitLineData
5f8ac7e7
SC
1# This shell script emits a C file. -*- C -*-
2# It does some substitutions.
3cat >e${EMULATION_NAME}.c <<EOF
5f8ac7e7 4/* This file is part of GLD, the Gnu Linker.
3535c3c0 5 Copyright 1995, 96, 97, 1998 Free Software Foundation, Inc.
5f8ac7e7
SC
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
3535c3c0
NC
21/* For WINDOWS_NT */
22/* The original file generated returned different default scripts depending
23 on whether certain switches were set, but these switches pertain to the
24 Linux system and that particular version of coff. In the NT case, we
25 only determine if the subsystem is console or windows in order to select
26 the correct entry point by default. */
27
5f8ac7e7
SC
28#include "bfd.h"
29#include "sysdep.h"
30#include "bfdlink.h"
31#include "getopt.h"
3535c3c0 32#include "libiberty.h"
5f8ac7e7
SC
33#include "ld.h"
34#include "ldmain.h"
35#include "ldgram.h"
36#include "ldexp.h"
37#include "ldlang.h"
38#include "ldemul.h"
39#include "ldlex.h"
40#include "ldmisc.h"
41#include "ldctor.h"
42#include "ldfile.h"
43#include "coff/internal.h"
44#include "../bfd/libcoff.h"
45
d4279937
SC
46#define TARGET_IS_${EMULATION_NAME}
47
fe6e2957
DE
48static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void));
49static void gld_${EMULATION_NAME}_after_open PARAMS ((void));
5f8ac7e7 50static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
5b6ca067 51static void gld_${EMULATION_NAME}_after_parse PARAMS ((void));
fe6e2957 52static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
5b6ca067 53static boolean gld_${EMULATION_NAME}_place_orphan
a1613b5f 54 PARAMS ((lang_input_statement_type *, asection *));
7617a822
ILT
55static void gld${EMULATION_NAME}_place_section
56 PARAMS ((lang_statement_union_type *));
fe6e2957
DE
57static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
58static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
59
5f8ac7e7
SC
60static struct internal_extra_pe_aouthdr pe;
61static int dll;
5b6ca067 62static int support_old_code = 0;
5f8ac7e7 63
3535c3c0
NC
64extern const char *output_filename;
65
5f8ac7e7
SC
66static void
67gld_${EMULATION_NAME}_before_parse()
68{
3535c3c0 69 output_filename = "a.exe";
5f8ac7e7
SC
70 ldfile_output_architecture = bfd_arch_${ARCH};
71}
fe6e2957
DE
72\f
73/* PE format extra command line options. */
5f8ac7e7
SC
74
75/* Used for setting flags in the PE header. */
76#define OPTION_BASE_FILE (300 + 1)
77#define OPTION_DLL (OPTION_BASE_FILE + 1)
78#define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1)
79#define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1)
80#define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1)
81#define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1)
82#define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1)
83#define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
84#define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1)
85#define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1)
86#define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
87#define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1)
88#define OPTION_SUBSYSTEM (OPTION_STACK + 1)
89#define OPTION_HEAP (OPTION_SUBSYSTEM + 1)
5b6ca067 90#define OPTION_SUPPORT_OLD_CODE (OPTION_HEAP + 1)
5f8ac7e7 91
5b6ca067
ILT
92static struct option longopts[] =
93{
5f8ac7e7 94 /* PE options */
5b6ca067
ILT
95 {"base-file", required_argument, NULL, OPTION_BASE_FILE},
96 {"dll", no_argument, NULL, OPTION_DLL},
97 {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
98 {"heap", required_argument, NULL, OPTION_HEAP},
99 {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
100 {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
101 {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
102 {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
103 {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
104 {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
105 {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
106 {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
107 {"stack", required_argument, NULL, OPTION_STACK},
108 {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
109 {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
110 {NULL, no_argument, NULL, 0}
111};
5f8ac7e7
SC
112
113
114/* PE/WIN32; added routines to get the subsystem type, heap and/or stack
115 parameters which may be input from the command line */
116
5b6ca067
ILT
117typedef struct
118{
5f8ac7e7
SC
119 void *ptr;
120 int size;
121 int value;
122 char *symbol;
123 int inited;
124} definfo;
125
126#define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0}
127
128static definfo init[] =
129{
130 /* imagebase must be first */
131#define IMAGEBASEOFF 0
132 D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
133#define DLLOFF 1
134 {&dll, sizeof(dll), 0, "__dll__"},
135 D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
136 D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
137 D(MajorOperatingSystemVersion,"__major_os_version__", 4),
138 D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
139 D(MajorImageVersion,"__major_image_version__", 1),
140 D(MinorImageVersion,"__minor_image_version__", 0),
141 D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
142 D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
143 D(Subsystem,"__subsystem__", 3),
417fe276 144 D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
5f8ac7e7
SC
145 D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
146 D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
147 D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
148 D(LoaderFlags,"__loader_flags__", 0x0),
3535c3c0 149 { NULL, 0, 0, NULL, 0 }
5f8ac7e7
SC
150};
151
5b6ca067
ILT
152static void
153gld_${EMULATION_NAME}_list_options (file)
154 FILE * file;
155{
156 fprintf (file, _(" --base_file <basefile> Generate a base file for relocatable DLLs\n"));
157 fprintf (file, _(" --dll Set image base to the default for DLLs\n"));
158 fprintf (file, _(" --file-alignment <size> Set file alignment\n"));
159 fprintf (file, _(" --heap <size> Set initial size of the heap\n"));
160 fprintf (file, _(" --image-base <address> Set start address of the executable\n"));
161 fprintf (file, _(" --major-image-version <number> Set version number of the executable\n"));
162 fprintf (file, _(" --major-os-version <number> Set minimum required OS version\n"));
163 fprintf (file, _(" --major-subsystem-version <number> Set minimum required OS subsystem version\n"));
164 fprintf (file, _(" --minor-image-version <number> Set revision number of the executable\n"));
165 fprintf (file, _(" --minor-os-version <number> Set minimum required OS revision\n"));
166 fprintf (file, _(" --minor-subsystem-version <number> Set minimum required OS subsystem revision\n"));
167 fprintf (file, _(" --section-alignment <size> Set section alignment\n"));
168 fprintf (file, _(" --stack <size> Set size of the initial stack\n"));
169 fprintf (file, _(" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n"));
170 fprintf (file, _(" --support-old-code Support interworking with old code\n"));
171}
5f8ac7e7
SC
172
173static void
174set_pe_name (name, val)
175 char *name;
176 long val;
177{
178 int i;
179 /* Find the name and set it. */
180 for (i = 0; init[i].ptr; i++)
181 {
182 if (strcmp (name, init[i].symbol) == 0)
183 {
184 init[i].value = val;
185 init[i].inited = 1;
186 return;
187 }
188 }
189 abort();
190}
191
192
193static void
194set_pe_subsystem ()
195{
3535c3c0
NC
196 const char *sver;
197 int len;
5f8ac7e7 198 int i;
3535c3c0 199 static const struct
5f8ac7e7 200 {
3535c3c0
NC
201 const char *name;
202 const int value;
203 const char *entry;
5f8ac7e7
SC
204 }
205 v[] =
206 {
3535c3c0
NC
207 { "native", 1, "_NtProcessStartup" },
208 { "windows", 2, "_WinMainCRTStartup" },
209 { "console", 3, "_mainCRTStartup" },
210#if 0
211 /* The Microsoft linker does not recognize this. */
212 { "os2", 5, "" },
213#endif
214 { "posix", 7, "___PosixProcessStartup"},
215 { 0, 0, 0 }
5f8ac7e7
SC
216 };
217
3535c3c0
NC
218 sver = strchr (optarg, ':');
219 if (sver == NULL)
220 len = strlen (optarg);
221 else
222 {
223 char *end;
224
225 len = sver - optarg;
226 set_pe_name ("__major_subsystem_version__",
227 strtoul (sver + 1, &end, 0));
228 if (*end == '.')
229 set_pe_name ("__minor_subsystem_version__",
230 strtoul (end + 1, &end, 0));
231 if (*end != '\0')
5b6ca067 232 einfo (_("%P: warning: bad version number in -subsystem option\n"));
3535c3c0
NC
233 }
234
5f8ac7e7
SC
235 for (i = 0; v[i].name; i++)
236 {
3535c3c0
NC
237 if (strncmp (optarg, v[i].name, len) == 0
238 && v[i].name[len] == '\0')
5f8ac7e7
SC
239 {
240 set_pe_name ("__subsystem__", v[i].value);
d0d63887 241
3535c3c0 242 lang_add_entry (v[i].entry, 1);
d0d63887 243
5f8ac7e7
SC
244 return;
245 }
246 }
5b6ca067
ILT
247
248 einfo (_("%P%F: invalid subsystem type %s\n"), optarg);
5f8ac7e7
SC
249}
250
251
252
253static void
254set_pe_value (name)
255 char *name;
256
257{
258 char *end;
5b6ca067 259
fe6e2957 260 set_pe_name (name, strtoul (optarg, &end, 0));
5b6ca067 261
5f8ac7e7 262 if (end == optarg)
5b6ca067 263 einfo (_("%P%F: invalid hex number for PE parameter '%s'\n"), optarg);
5f8ac7e7
SC
264
265 optarg = end;
266}
267
268static void
269set_pe_stack_heap (resname, comname)
270 char *resname;
271 char *comname;
272{
5f8ac7e7 273 set_pe_value (resname);
5b6ca067 274
5f8ac7e7
SC
275 if (*optarg == ',')
276 {
277 optarg++;
278 set_pe_value (comname);
279 }
280 else if (*optarg)
5b6ca067 281 einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg);
5f8ac7e7
SC
282}
283
284
285
286static int
287gld_${EMULATION_NAME}_parse_args(argc, argv)
288 int argc;
289 char **argv;
290{
291 int longind;
292 int optc;
293 int prevoptind = optind;
294 int prevopterr = opterr;
2543860d
SC
295 int wanterror;
296 static int lastoptind = -1;
297
298 if (lastoptind != optind)
299 opterr = 0;
300 wanterror = opterr;
301
302 lastoptind = optind;
303
5f8ac7e7
SC
304 optc = getopt_long_only (argc, argv, "-", longopts, &longind);
305 opterr = prevopterr;
2543860d 306
5f8ac7e7
SC
307 switch (optc)
308 {
309 default:
2543860d
SC
310 if (wanterror)
311 xexit (1);
312 optind = prevoptind;
5f8ac7e7
SC
313 return 0;
314
315 case OPTION_BASE_FILE:
d4279937 316 link_info.base_file = (PTR) fopen (optarg, FOPEN_WB);
5f8ac7e7
SC
317 if (link_info.base_file == NULL)
318 {
5b6ca067
ILT
319 /* xgettext:c-format */
320 fprintf (stderr, _("%s: Can't open base file %s\n"),
5f8ac7e7
SC
321 program_name, optarg);
322 xexit (1);
323 }
324 break;
325
326 /* PE options */
327 case OPTION_HEAP:
a1613b5f 328 set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
5f8ac7e7
SC
329 break;
330 case OPTION_STACK:
a1613b5f 331 set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
5f8ac7e7
SC
332 break;
333 case OPTION_SUBSYSTEM:
334 set_pe_subsystem ();
335 break;
336 case OPTION_MAJOR_OS_VERSION:
337 set_pe_value ("__major_os_version__");
338 break;
339 case OPTION_MINOR_OS_VERSION:
340 set_pe_value ("__minor_os_version__");
341 break;
342 case OPTION_MAJOR_SUBSYSTEM_VERSION:
343 set_pe_value ("__major_subsystem_version__");
344 break;
345 case OPTION_MINOR_SUBSYSTEM_VERSION:
2543860d 346 set_pe_value ("__minor_subsystem_version__");
5f8ac7e7
SC
347 break;
348 case OPTION_MAJOR_IMAGE_VERSION:
349 set_pe_value ("__major_image_version__");
350 break;
351 case OPTION_MINOR_IMAGE_VERSION:
352 set_pe_value ("__minor_image_version__");
353 break;
354 case OPTION_FILE_ALIGNMENT:
355 set_pe_value ("__file_alignment__");
356 break;
357 case OPTION_SECTION_ALIGNMENT:
358 set_pe_value ("__section_alignment__");
359 break;
360 case OPTION_DLL:
361 set_pe_name ("__dll__", 1);
362 break;
363 case OPTION_IMAGE_BASE:
364 set_pe_value ("__image_base__");
365 break;
5b6ca067
ILT
366 case OPTION_SUPPORT_OLD_CODE:
367 support_old_code = 1;
368 break;
5f8ac7e7
SC
369 }
370 return 1;
371}
fe6e2957 372\f
3535c3c0
NC
373/* Assign values to the special symbols before the linker script is
374 read. */
375
5f8ac7e7 376static void
5b6ca067 377gld_${EMULATION_NAME}_set_symbols ()
5f8ac7e7 378{
5f8ac7e7
SC
379 /* Run through and invent symbols for all the
380 names and insert the defaults. */
381 int j;
2543860d 382 lang_statement_list_type *save;
5f8ac7e7
SC
383
384 if (!init[IMAGEBASEOFF].inited)
3535c3c0
NC
385 {
386 if (link_info.relocateable)
387 init[IMAGEBASEOFF].value = 0;
388 else if (init[DLLOFF].value)
389 init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE;
390 else
391 init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE;
392 }
393
394 /* Don't do any symbol assignments if this is a relocateable link. */
395 if (link_info.relocateable)
396 return;
5f8ac7e7 397
2543860d 398 /* Glue the assignments into the abs section */
d4279937 399 save = stat_ptr;
2543860d
SC
400
401 stat_ptr = &(abs_output_section->children);
d4279937 402
5f8ac7e7
SC
403 for (j = 0; init[j].ptr; j++)
404 {
405 long val = init[j].value;
406 lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
407 if (init[j].size == sizeof(short))
408 *(short *)init[j].ptr = val;
409 else if (init[j].size == sizeof(int))
410 *(int *)init[j].ptr = val;
411 else if (init[j].size == sizeof(long))
412 *(long *)init[j].ptr = val;
3535c3c0
NC
413 /* This might be a long long or other special type. */
414 else if (init[j].size == sizeof(bfd_vma))
415 *(bfd_vma *)init[j].ptr = val;
5f8ac7e7
SC
416 else abort();
417 }
2543860d
SC
418 /* Restore the pointer. */
419 stat_ptr = save;
420
5f8ac7e7
SC
421 if (pe.FileAlignment >
422 pe.SectionAlignment)
423 {
5b6ca067 424 einfo (_("%P: warning, file alignment > section alignment.\n"));
5f8ac7e7
SC
425 }
426}
427
5b6ca067
ILT
428/* This is called after the linker script and the command line options
429 have been read. */
430
431static void
432gld_${EMULATION_NAME}_after_parse ()
433{
434 /* The Windows libraries are designed for the linker to treat the
435 entry point as an undefined symbol. Otherwise, the .obj that
436 defines mainCRTStartup is brought in because it is the first
437 encountered in libc.lib and it has other symbols in it which will
438 be pulled in by the link process. To avoid this, we act as
439 though the user specified -u with the entry point symbol.
440
441 This function is called after the linker script and command line
442 options have been read, so at this point we know the right entry
443 point. This function is called before the input files are
444 opened, so registering the symbol as undefined will make a
445 difference. */
446
447 ldlang_add_undef (entry_symbol);
448}
449
5f8ac7e7 450static void
5b6ca067 451gld_${EMULATION_NAME}_after_open ()
5f8ac7e7 452{
3535c3c0
NC
453 /* Pass the wacky PE command line options into the output bfd.
454 FIXME: This should be done via a function, rather than by
455 including an internal BFD header. */
5b6ca067
ILT
456
457 if (!coff_data (output_bfd)->pe)
458 einfo (_("%F%P: PE operations on non PE file.\n"));
5f8ac7e7 459
5b6ca067
ILT
460 pe_data (output_bfd)->pe_opthdr = pe;
461 pe_data (output_bfd)->dll = init[DLLOFF].value;
5f8ac7e7 462
5b6ca067
ILT
463#ifdef TARGET_IS_armpe
464 {
465 /* Find a BFD that can hold the interworking stubs. */
466 LANG_FOR_EACH_INPUT_STATEMENT (is)
467 {
468 if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info))
469 break;
470 }
471 }
472#endif
5f8ac7e7 473}
a1613b5f 474\f
5f8ac7e7
SC
475static void
476gld_${EMULATION_NAME}_before_allocation()
477{
d4279937
SC
478#ifdef TARGET_IS_ppcpe
479 /* Here we rummage through the found bfds to collect toc information */
480 {
481 LANG_FOR_EACH_INPUT_STATEMENT (is)
482 {
5b6ca067 483 if (!ppc_process_before_allocation (is->the_bfd, &link_info))
417fe276 484 {
5b6ca067
ILT
485 /* xgettext:c-format */
486 einfo (_("Errors encountered processing file %s\n"), is->filename);
417fe276 487 }
d4279937
SC
488 }
489 }
490
491 /* We have seen it all. Allocate it, and carry on */
492 ppc_allocate_toc_section (&link_info);
5b6ca067
ILT
493#endif /* TARGET_IS_ppcpe */
494
495#ifdef TARGET_IS_armpe
496 /* FIXME: we should be able to set the size of the interworking stub
497 section.
498
499 Here we rummage through the found bfds to collect glue
500 information. FIXME: should this be based on a command line
501 option? krk@cygnus.com */
3535c3c0
NC
502 {
503 LANG_FOR_EACH_INPUT_STATEMENT (is)
504 {
5b6ca067
ILT
505 if (! bfd_arm_process_before_allocation
506 (is->the_bfd, & link_info, support_old_code))
3535c3c0 507 {
5b6ca067
ILT
508 /* xgettext:c-format */
509 einfo (_("Errors encountered processing file %s for interworking"),
510 is->filename);
3535c3c0
NC
511 }
512 }
513 }
514
515 /* We have seen it all. Allocate it, and carry on */
5b6ca067
ILT
516 bfd_arm_allocate_interworking_sections (& link_info);
517#endif /* TARGET_IS_armpe */
5f8ac7e7 518}
a1613b5f 519\f
7617a822
ILT
520/* Place an orphan section.
521
522 We use this to put sections in a reasonable place in the file, and
523 to ensure that they are aligned as required.
524
525 We handle grouped sections here as well. A section named .foo$nn
526 goes into the output section .foo. All grouped sections are sorted
527 by name.
3535c3c0 528
7617a822
ILT
529 Grouped sections for the default sections are handled by the
530 default linker script using wildcards, and are sorted by
531 sort_sections. */
532
533static asection *hold_section;
534static char *hold_section_name;
535static lang_output_section_statement_type *hold_use;
536static lang_output_section_statement_type *hold_text;
537static lang_output_section_statement_type *hold_rdata;
538static lang_output_section_statement_type *hold_data;
539static lang_output_section_statement_type *hold_bss;
540
541/* Place an orphan section. We use this to put random SHF_ALLOC
542 sections in the right segment. */
a1613b5f
DE
543
544/*ARGSUSED*/
545static boolean
5b6ca067 546gld_${EMULATION_NAME}_place_orphan (file, s)
a1613b5f
DE
547 lang_input_statement_type *file;
548 asection *s;
549{
fe6e2957 550 const char *secname;
7617a822 551 char *dollar;
a1613b5f
DE
552
553 if ((s->flags & SEC_ALLOC) == 0)
554 return false;
555
a1613b5f
DE
556 secname = bfd_get_section_name (s->owner, s);
557
7617a822
ILT
558 /* Look through the script to see where to place this section. */
559
560 hold_section = s;
561
562 hold_section_name = xstrdup (secname);
563 dollar = strchr (hold_section_name, '$');
564 if (dollar != NULL)
565 *dollar = '\0';
566
567 hold_use = NULL;
568 lang_for_each_statement (gld${EMULATION_NAME}_place_section);
a1613b5f 569
7617a822 570 if (hold_use == NULL)
a1613b5f 571 {
7617a822
ILT
572 lang_output_section_statement_type *place;
573 char *outsecname;
574 asection *snew, **pps;
575 lang_statement_list_type *old;
576 lang_statement_list_type add;
577 etree_type *address;
578
579 /* Try to put the new output section in a reasonable place based
580 on the section name and section flags. */
581 place = NULL;
582 if ((s->flags & SEC_HAS_CONTENTS) == 0
583 && hold_bss != NULL)
584 place = hold_bss;
585 else if ((s->flags & SEC_READONLY) == 0
586 && hold_data != NULL)
587 place = hold_data;
588 else if ((s->flags & SEC_CODE) == 0
589 && (s->flags & SEC_READONLY) != 0
590 && hold_rdata != NULL)
591 place = hold_rdata;
592 else if ((s->flags & SEC_READONLY) != 0
593 && hold_text != NULL)
594 place = hold_text;
595
596 /* Choose a unique name for the section. This will be needed if
597 the same section name appears in the input file with
598 different loadable or allocateable characteristics. */
599 outsecname = xstrdup (hold_section_name);
600 if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
601 {
602 unsigned int len;
603 char *newname;
604 unsigned int i;
605
606 len = strlen (outsecname);
607 newname = xmalloc (len + 5);
608 strcpy (newname, outsecname);
609 i = 0;
610 do
611 {
612 sprintf (newname + len, "%d", i);
613 ++i;
614 }
615 while (bfd_get_section_by_name (output_bfd, newname) != NULL);
616
617 free (outsecname);
618 outsecname = newname;
619 }
620
621 /* We don't want to free OUTSECNAME, as it may get attached to
622 the output section statement. */
623
624 /* Create the section in the output file, and put it in the
625 right place. This shuffling is to make the output file look
626 neater. */
627 snew = bfd_make_section (output_bfd, outsecname);
628 if (snew == NULL)
629 einfo ("%P%F: output format %s cannot represent section called %s\n",
630 output_bfd->xvec->name, outsecname);
631 if (place != NULL && place->bfd_section != NULL)
632 {
633 for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
634 ;
635 *pps = snew->next;
636 snew->next = place->bfd_section->next;
637 place->bfd_section->next = snew;
638 }
639
640 /* Start building a list of statements for this section. */
641 old = stat_ptr;
642 stat_ptr = &add;
643 lang_list_init (stat_ptr);
644
645 if (link_info.relocateable)
646 address = NULL;
647 else
648 {
649 /* All sections in an executable must be aligned to a page
650 boundary. */
651 address = exp_unop (ALIGN_K,
652 exp_nameop (NAME, "__section_alignment__"));
653 }
654
655 lang_enter_output_section_statement (outsecname, address, 0,
656 (bfd_vma) 0,
657 (etree_type *) NULL,
658 (etree_type *) NULL,
659 (etree_type *) NULL);
660
661 hold_use = lang_output_section_statement_lookup (outsecname);
662
663 lang_leave_output_section_statement
664 ((bfd_vma) 0, "*default*",
665 (struct lang_output_section_phdr_list *) NULL);
666
667 /* Now stick the new statement list right after PLACE. */
668 if (place != NULL)
669 {
670 *add.tail = place->header.next;
671 place->header.next = add.head;
672 }
673
674 stat_ptr = old;
a1613b5f 675 }
7617a822
ILT
676
677 if (dollar == NULL)
678 wild_doit (&hold_use->children, s, hold_use, file);
679 else
a1613b5f 680 {
7617a822
ILT
681 lang_statement_union_type **pl;
682 boolean found_dollar;
683 lang_statement_list_type list;
684
685 /* The section name has a '$'. Sort it with the other '$'
686 sections. */
687
688 found_dollar = false;
689 for (pl = &hold_use->children.head; *pl != NULL; pl = &(*pl)->next)
690 {
691 lang_input_section_type *ls;
692 const char *lname;
693
694 if ((*pl)->header.type != lang_input_section_enum)
695 continue;
696
697 ls = &(*pl)->input_section;
698
699 lname = bfd_get_section_name (ls->ifile->the_bfd, ls->section);
700 if (strchr (lname, '$') == NULL)
701 {
702 if (found_dollar)
703 break;
704 }
705 else
706 {
707 found_dollar = true;
708 if (strcmp (secname, lname) < 0)
709 break;
710 }
711 }
712
713 lang_list_init (&list);
714 wild_doit (&list, s, hold_use, file);
715 ASSERT (list.head != NULL && list.head->next == NULL);
716
717 list.head->next = *pl;
718 *pl = list.head;
a1613b5f 719 }
a1613b5f 720
7617a822 721 free (hold_section_name);
a1613b5f
DE
722
723 return true;
724}
7617a822
ILT
725
726static void
727gld${EMULATION_NAME}_place_section (s)
728 lang_statement_union_type *s;
729{
730 lang_output_section_statement_type *os;
731
732 if (s->header.type != lang_output_section_statement_enum)
733 return;
734
735 os = &s->output_section_statement;
736
737 if (strcmp (os->name, hold_section_name) == 0
738 && os->bfd_section != NULL
739 && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
740 == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
741 hold_use = os;
742
743 if (strcmp (os->name, ".text") == 0)
744 hold_text = os;
745 else if (strcmp (os->name, ".rdata") == 0)
746 hold_rdata = os;
747 else if (strcmp (os->name, ".data") == 0)
748 hold_data = os;
749 else if (strcmp (os->name, ".bss") == 0)
750 hold_bss = os;
751}
a1613b5f 752\f
5f8ac7e7
SC
753static char *
754gld_${EMULATION_NAME}_get_script(isfile)
755 int *isfile;
756EOF
757# Scripts compiled in.
758# sed commands to quote an ld script as a C string.
759sc="-f ${srcdir}/emultempl/stringify.sed"
760
761cat >>e${EMULATION_NAME}.c <<EOF
762{
763 *isfile = 0;
764
765 if (link_info.relocateable == true && config.build_constructors == true)
766 return
767EOF
768sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
769echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
770sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
771echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
772sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
773echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
774sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
775echo ' ; else return' >> e${EMULATION_NAME}.c
776sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
777echo '; }' >> e${EMULATION_NAME}.c
778
779cat >>e${EMULATION_NAME}.c <<EOF
780
781
5f8ac7e7
SC
782struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
783{
784 gld_${EMULATION_NAME}_before_parse,
785 syslib_default,
786 hll_default,
5b6ca067 787 gld_${EMULATION_NAME}_after_parse,
5f8ac7e7
SC
788 gld_${EMULATION_NAME}_after_open,
789 after_allocation_default,
790 set_output_arch_default,
791 ldemul_default_target,
792 gld_${EMULATION_NAME}_before_allocation,
793 gld_${EMULATION_NAME}_get_script,
794 "${EMULATION_NAME}",
795 "${OUTPUT_FORMAT}",
796 NULL, /* finish */
797 NULL, /* create output section statements */
798 NULL, /* open dynamic archive */
5b6ca067 799 gld_${EMULATION_NAME}_place_orphan,
5f8ac7e7 800 gld_${EMULATION_NAME}_set_symbols,
5b6ca067
ILT
801 gld_${EMULATION_NAME}_parse_args,
802 NULL, /* unrecognised file */
803 gld_${EMULATION_NAME}_list_options
5f8ac7e7
SC
804};
805EOF
This page took 0.148031 seconds and 4 git commands to generate.