remove unnecessary blank line
[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));
fe6e2957 51static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
a1613b5f
DE
52static boolean gld${EMULATION_NAME}_place_orphan
53 PARAMS ((lang_input_statement_type *, asection *));
fe6e2957
DE
54static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
55static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
56
57#if 0 /* argument to qsort so don't prototype */
58static int sort_by_file_name PARAMS ((void *, void *));
59static int sort_by_section_name PARAMS ((void *, void *));
60#endif
61static lang_statement_union_type **sort_sections_1
62 PARAMS ((lang_statement_union_type **, lang_statement_union_type *, int,
63 int (*)()));
64static void sort_sections PARAMS ((lang_statement_union_type *));
5f8ac7e7
SC
65
66static struct internal_extra_pe_aouthdr pe;
67static int dll;
68
3535c3c0
NC
69extern const char *output_filename;
70
5f8ac7e7
SC
71static void
72gld_${EMULATION_NAME}_before_parse()
73{
3535c3c0 74 output_filename = "a.exe";
5f8ac7e7
SC
75 ldfile_output_architecture = bfd_arch_${ARCH};
76}
fe6e2957
DE
77\f
78/* PE format extra command line options. */
5f8ac7e7
SC
79
80/* Used for setting flags in the PE header. */
81#define OPTION_BASE_FILE (300 + 1)
82#define OPTION_DLL (OPTION_BASE_FILE + 1)
83#define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1)
84#define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1)
85#define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1)
86#define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1)
87#define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1)
88#define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
89#define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1)
90#define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1)
91#define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
92#define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1)
93#define OPTION_SUBSYSTEM (OPTION_STACK + 1)
94#define OPTION_HEAP (OPTION_SUBSYSTEM + 1)
95
a1613b5f 96static struct option longopts[] = {
5f8ac7e7
SC
97 /* PE options */
98 {"base-file", required_argument, NULL, OPTION_BASE_FILE},
99 {"dll", no_argument, NULL, OPTION_DLL},
100 {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
101 {"heap", required_argument, NULL, OPTION_HEAP},
102 {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
103 {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
104 {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
105 {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
106 {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
107 {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
108 {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
109 {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
110 {"stack", required_argument, NULL, OPTION_STACK},
111 {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
112 {NULL, no_argument, NULL, 0}
113 };
114
115
116/* PE/WIN32; added routines to get the subsystem type, heap and/or stack
117 parameters which may be input from the command line */
118
5f8ac7e7
SC
119typedef struct {
120 void *ptr;
121 int size;
122 int value;
123 char *symbol;
124 int inited;
125} definfo;
126
127#define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0}
128
129static definfo init[] =
130{
131 /* imagebase must be first */
132#define IMAGEBASEOFF 0
133 D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
134#define DLLOFF 1
135 {&dll, sizeof(dll), 0, "__dll__"},
136 D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
137 D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
138 D(MajorOperatingSystemVersion,"__major_os_version__", 4),
139 D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
140 D(MajorImageVersion,"__major_image_version__", 1),
141 D(MinorImageVersion,"__minor_image_version__", 0),
142 D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
143 D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
144 D(Subsystem,"__subsystem__", 3),
417fe276 145 D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
5f8ac7e7
SC
146 D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
147 D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
148 D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
149 D(LoaderFlags,"__loader_flags__", 0x0),
3535c3c0 150 { NULL, 0, 0, NULL, 0 }
5f8ac7e7
SC
151};
152
153
154static void
155set_pe_name (name, val)
156 char *name;
157 long val;
158{
159 int i;
160 /* Find the name and set it. */
161 for (i = 0; init[i].ptr; i++)
162 {
163 if (strcmp (name, init[i].symbol) == 0)
164 {
165 init[i].value = val;
166 init[i].inited = 1;
167 return;
168 }
169 }
170 abort();
171}
172
173
174static void
175set_pe_subsystem ()
176{
3535c3c0
NC
177 const char *sver;
178 int len;
5f8ac7e7 179 int i;
3535c3c0 180 static const struct
5f8ac7e7 181 {
3535c3c0
NC
182 const char *name;
183 const int value;
184 const char *entry;
5f8ac7e7
SC
185 }
186 v[] =
187 {
3535c3c0
NC
188 { "native", 1, "_NtProcessStartup" },
189 { "windows", 2, "_WinMainCRTStartup" },
190 { "console", 3, "_mainCRTStartup" },
191#if 0
192 /* The Microsoft linker does not recognize this. */
193 { "os2", 5, "" },
194#endif
195 { "posix", 7, "___PosixProcessStartup"},
196 { 0, 0, 0 }
5f8ac7e7
SC
197 };
198
3535c3c0
NC
199 sver = strchr (optarg, ':');
200 if (sver == NULL)
201 len = strlen (optarg);
202 else
203 {
204 char *end;
205
206 len = sver - optarg;
207 set_pe_name ("__major_subsystem_version__",
208 strtoul (sver + 1, &end, 0));
209 if (*end == '.')
210 set_pe_name ("__minor_subsystem_version__",
211 strtoul (end + 1, &end, 0));
212 if (*end != '\0')
213 einfo ("%P: warning: bad version number in -subsystem option\n");
214 }
215
5f8ac7e7
SC
216 for (i = 0; v[i].name; i++)
217 {
3535c3c0
NC
218 if (strncmp (optarg, v[i].name, len) == 0
219 && v[i].name[len] == '\0')
5f8ac7e7
SC
220 {
221 set_pe_name ("__subsystem__", v[i].value);
d0d63887
ILT
222
223 /* If the subsystem is windows, we use a different entry
224 point. We also register the entry point as an undefined
225 symbol. The reason we do this is so that the user
226 doesn't have to because they would have to use the -u
227 switch if they were specifying an entry point other than
228 _mainCRTStartup. Specifically, if creating a windows
229 application, entry point _WinMainCRTStartup must be
230 specified. What I have found for non console
231 applications (entry not _mainCRTStartup) is that the .obj
232 that contains mainCRTStartup is brought in since it is
233 the first encountered in libc.lib and it has other
234 symbols in it which will be pulled in by the link
235 process. To avoid this, adding -u with the entry point
236 name specified forces the correct .obj to be used. We
237 can avoid making the user do this by always adding the
238 entry point name as an undefined symbol. */
3535c3c0
NC
239 lang_add_entry (v[i].entry, 1);
240 ldlang_add_undef (v[i].entry);
d0d63887 241
5f8ac7e7
SC
242 return;
243 }
244 }
245 einfo ("%P%F: invalid subsystem type %s\n", optarg);
246}
247
248
249
250static void
251set_pe_value (name)
252 char *name;
253
254{
255 char *end;
fe6e2957 256 set_pe_name (name, strtoul (optarg, &end, 0));
5f8ac7e7
SC
257 if (end == optarg)
258 {
259 einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg);
260 }
261
262 optarg = end;
263}
264
265static void
266set_pe_stack_heap (resname, comname)
267 char *resname;
268 char *comname;
269{
5f8ac7e7
SC
270 set_pe_value (resname);
271 if (*optarg == ',')
272 {
273 optarg++;
274 set_pe_value (comname);
275 }
276 else if (*optarg)
277 {
278 einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg);
279 }
280}
281
282
283
284static int
285gld_${EMULATION_NAME}_parse_args(argc, argv)
286 int argc;
287 char **argv;
288{
289 int longind;
290 int optc;
291 int prevoptind = optind;
292 int prevopterr = opterr;
2543860d
SC
293 int wanterror;
294 static int lastoptind = -1;
295
296 if (lastoptind != optind)
297 opterr = 0;
298 wanterror = opterr;
299
300 lastoptind = optind;
301
5f8ac7e7
SC
302 optc = getopt_long_only (argc, argv, "-", longopts, &longind);
303 opterr = prevopterr;
2543860d 304
5f8ac7e7
SC
305 switch (optc)
306 {
307 default:
2543860d
SC
308 if (wanterror)
309 xexit (1);
310 optind = prevoptind;
5f8ac7e7
SC
311 return 0;
312
313 case OPTION_BASE_FILE:
d4279937 314 link_info.base_file = (PTR) fopen (optarg, FOPEN_WB);
5f8ac7e7
SC
315 if (link_info.base_file == NULL)
316 {
317 fprintf (stderr, "%s: Can't open base file %s\n",
318 program_name, optarg);
319 xexit (1);
320 }
321 break;
322
323 /* PE options */
324 case OPTION_HEAP:
a1613b5f 325 set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
5f8ac7e7
SC
326 break;
327 case OPTION_STACK:
a1613b5f 328 set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
5f8ac7e7
SC
329 break;
330 case OPTION_SUBSYSTEM:
331 set_pe_subsystem ();
332 break;
333 case OPTION_MAJOR_OS_VERSION:
334 set_pe_value ("__major_os_version__");
335 break;
336 case OPTION_MINOR_OS_VERSION:
337 set_pe_value ("__minor_os_version__");
338 break;
339 case OPTION_MAJOR_SUBSYSTEM_VERSION:
340 set_pe_value ("__major_subsystem_version__");
341 break;
342 case OPTION_MINOR_SUBSYSTEM_VERSION:
2543860d 343 set_pe_value ("__minor_subsystem_version__");
5f8ac7e7
SC
344 break;
345 case OPTION_MAJOR_IMAGE_VERSION:
346 set_pe_value ("__major_image_version__");
347 break;
348 case OPTION_MINOR_IMAGE_VERSION:
349 set_pe_value ("__minor_image_version__");
350 break;
351 case OPTION_FILE_ALIGNMENT:
352 set_pe_value ("__file_alignment__");
353 break;
354 case OPTION_SECTION_ALIGNMENT:
355 set_pe_value ("__section_alignment__");
356 break;
357 case OPTION_DLL:
358 set_pe_name ("__dll__", 1);
359 break;
360 case OPTION_IMAGE_BASE:
361 set_pe_value ("__image_base__");
362 break;
363 }
364 return 1;
365}
fe6e2957 366\f
3535c3c0
NC
367/* Assign values to the special symbols before the linker script is
368 read. */
369
5f8ac7e7 370static void
fe6e2957 371gld_${EMULATION_NAME}_set_symbols()
5f8ac7e7 372{
5f8ac7e7
SC
373 /* Run through and invent symbols for all the
374 names and insert the defaults. */
375 int j;
2543860d 376 lang_statement_list_type *save;
5f8ac7e7
SC
377
378 if (!init[IMAGEBASEOFF].inited)
3535c3c0
NC
379 {
380 if (link_info.relocateable)
381 init[IMAGEBASEOFF].value = 0;
382 else if (init[DLLOFF].value)
383 init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE;
384 else
385 init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE;
386 }
387
388 /* Don't do any symbol assignments if this is a relocateable link. */
389 if (link_info.relocateable)
390 return;
5f8ac7e7 391
2543860d 392 /* Glue the assignments into the abs section */
d4279937 393 save = stat_ptr;
2543860d
SC
394
395 stat_ptr = &(abs_output_section->children);
d4279937 396
5f8ac7e7
SC
397 for (j = 0; init[j].ptr; j++)
398 {
399 long val = init[j].value;
400 lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
401 if (init[j].size == sizeof(short))
402 *(short *)init[j].ptr = val;
403 else if (init[j].size == sizeof(int))
404 *(int *)init[j].ptr = val;
405 else if (init[j].size == sizeof(long))
406 *(long *)init[j].ptr = val;
3535c3c0
NC
407 /* This might be a long long or other special type. */
408 else if (init[j].size == sizeof(bfd_vma))
409 *(bfd_vma *)init[j].ptr = val;
5f8ac7e7
SC
410 else abort();
411 }
2543860d
SC
412 /* Restore the pointer. */
413 stat_ptr = save;
414
5f8ac7e7
SC
415 if (pe.FileAlignment >
416 pe.SectionAlignment)
417 {
418 einfo ("%P: warning, file alignment > section alignment.\n");
419 }
420}
421
422static void
423gld_${EMULATION_NAME}_after_open()
424{
3535c3c0
NC
425 /* Pass the wacky PE command line options into the output bfd.
426 FIXME: This should be done via a function, rather than by
427 including an internal BFD header. */
5f8ac7e7
SC
428 if (!coff_data(output_bfd)->pe)
429 {
430 einfo ("%F%P: PE operations on non PE file.\n");
431 }
432
433 pe_data(output_bfd)->pe_opthdr = pe;
434 pe_data(output_bfd)->dll = init[DLLOFF].value;
435
436}
a1613b5f 437\f
fe6e2957 438/* Callback functions for qsort in sort_sections. */
5f8ac7e7 439
fe6e2957
DE
440static int
441sort_by_file_name (a, b)
442 void *a;
443 void *b;
5f8ac7e7
SC
444{
445 lang_statement_union_type **ra = a;
446 lang_statement_union_type **rb = b;
3535c3c0
NC
447 int i;
448
449 i = strcmp ((*ra)->input_section.ifile->the_bfd->my_archive->filename,
450 (*rb)->input_section.ifile->the_bfd->my_archive->filename);
451 if (i != 0)
452 return i;
453
5f8ac7e7
SC
454 return strcmp ((*ra)->input_section.ifile->filename,
455 (*rb)->input_section.ifile->filename);
456}
457
fe6e2957
DE
458static int
459sort_by_section_name (a, b)
460 void *a;
461 void *b;
462{
463 lang_statement_union_type **ra = a;
464 lang_statement_union_type **rb = b;
465 return strcmp ((*ra)->input_section.section->name,
466 (*rb)->input_section.section->name);
467}
468
469/* Subroutine of sort_sections to a contiguous subset of a list of sections.
470 NEXT_AFTER is the element after the last one to sort.
471 The result is a pointer to the last element's "next" pointer. */
472
473static lang_statement_union_type **
474sort_sections_1 (startptr, next_after, count, sort_func)
475 lang_statement_union_type **startptr,*next_after;
476 int count;
477 int (*sort_func) ();
478{
479 lang_statement_union_type **vec;
480 lang_statement_union_type *p;
481 int i;
3535c3c0 482 lang_statement_union_type **ret;
fe6e2957
DE
483
484 if (count == 0)
485 return startptr;
486
3535c3c0
NC
487 vec = ((lang_statement_union_type **)
488 xmalloc (count * sizeof (lang_statement_union_type *)));
fe6e2957
DE
489
490 for (p = *startptr, i = 0; i < count; i++, p = p->next)
491 vec[i] = p;
492
493 qsort (vec, count, sizeof (vec[0]), sort_func);
494
495 /* Fill in the next pointers again. */
496 *startptr = vec[0];
497 for (i = 0; i < count - 1; i++)
498 vec[i]->header.next = vec[i + 1];
499 vec[i]->header.next = next_after;
3535c3c0
NC
500 ret = &vec[i]->header.next;
501 free (vec);
502 return ret;
fe6e2957
DE
503}
504
505/* Sort the .idata\$foo input sections of archives into filename order.
506 The reason is so dlltool can arrange to have the pe dll import information
507 generated correctly - the head of the list goes into dh.o, the tail into
508 dt.o, and the guts into ds[nnnn].o. Note that this is only needed for the
509 .idata section.
510 FIXME: This may no longer be necessary with grouped sections. Instead of
511 sorting on dh.o, ds[nnnn].o, dt.o, one could, for example, have dh.o use
512 .idata\$4h, have ds[nnnn].o use .idata\$4s[nnnn], and have dt.o use .idata\$4t.
513 This would have to be elaborated upon to handle multiple dll's
514 [assuming such an eloboration is possible of course].
515
516 We also sort sections in '\$' wild statements. These are created by the
517 place_orphans routine to implement grouped sections. */
a1613b5f 518
5f8ac7e7
SC
519static void
520sort_sections (s)
521 lang_statement_union_type *s;
522{
523 for (; s ; s = s->next)
524 switch (s->header.type)
525 {
526 case lang_output_section_statement_enum:
527 sort_sections (s->output_section_statement.children.head);
528 break;
529 case lang_wild_statement_enum:
530 {
531 lang_statement_union_type **p = &s->wild_statement.children.head;
532
fe6e2957 533 /* Is this the .idata section? */
417fe276
GN
534 if (s->wild_statement.section_name != NULL
535 && strncmp (s->wild_statement.section_name, ".idata", 6) == 0)
5f8ac7e7 536 {
3535c3c0
NC
537 /* Sort the children. We want to sort any objects in
538 the same archive. In order to handle the case of
539 including a single archive multiple times, we sort
540 all the children by archive name and then by object
541 name. After sorting them, we re-thread the pointer
542 chain. */
fe6e2957
DE
543
544 while (*p)
5f8ac7e7 545 {
fe6e2957
DE
546 lang_statement_union_type *start = *p;
547 if (start->header.type != lang_input_section_enum
548 || !start->input_section.ifile->the_bfd->my_archive)
549 p = &(start->header.next);
550 else
551 {
552 lang_statement_union_type *end;
553 int count;
554
555 for (end = start, count = 0;
3535c3c0 556 end && end->header.type == lang_input_section_enum;
fe6e2957
DE
557 end = end->next)
558 count++;
559
560 p = sort_sections_1 (p, end, count, sort_by_file_name);
561 }
5f8ac7e7 562 }
fe6e2957 563 break;
5f8ac7e7 564 }
fe6e2957
DE
565
566 /* If this is a collection of grouped sections, sort them.
3535c3c0
NC
567 The linker script must explicitly mention "*(.foo\$)" or
568 "*(.foo\$*)". Don't sort them if \$ is not the last
569 character (not sure if this is really useful, but it
570 allows explicitly mentioning some \$ sections and letting
571 the linker handle the rest). */
417fe276
GN
572 if (s->wild_statement.section_name != NULL)
573 {
574 char *q = strchr (s->wild_statement.section_name, '\$');
575
3535c3c0
NC
576 if (q != NULL
577 && (q[1] == '\0'
578 || (q[1] == '*' && q[2] == '\0')))
417fe276
GN
579 {
580 lang_statement_union_type *end;
581 int count;
582
583 for (end = *p, count = 0; end; end = end->next)
584 {
585 if (end->header.type != lang_input_section_enum)
586 abort ();
587 count++;
588 }
589 (void) sort_sections_1 (p, end, count, sort_by_section_name);
590 }
591 break;
592 }
5f8ac7e7
SC
593 }
594 break;
595 default:
596 break;
597 }
598}
599
600static void
601gld_${EMULATION_NAME}_before_allocation()
602{
603 extern lang_statement_list_type *stat_ptr;
d4279937
SC
604
605#ifdef TARGET_IS_ppcpe
606 /* Here we rummage through the found bfds to collect toc information */
607 {
608 LANG_FOR_EACH_INPUT_STATEMENT (is)
609 {
417fe276
GN
610 if (!ppc_process_before_allocation(is->the_bfd, &link_info))
611 {
3535c3c0 612 einfo("Errors encountered processing file %s\n", is->filename);
417fe276 613 }
d4279937
SC
614 }
615 }
616
617 /* We have seen it all. Allocate it, and carry on */
618 ppc_allocate_toc_section (&link_info);
3535c3c0
NC
619#else
620 /* FIXME: we should be able to set the size of the interworking stub section */
621 /* Here we rummage through the found bfds to collect glue information. */
622 /* FIXME: should this be based on a command line option? krk@cygnus.com */
623 {
624 LANG_FOR_EACH_INPUT_STATEMENT (is)
625 {
626 if (!arm_process_before_allocation (is->the_bfd, & link_info))
627 {
628 einfo ("Errors encountered processing file %s", is->filename);
629 }
630 }
631 }
632
633 /* We have seen it all. Allocate it, and carry on */
634 arm_allocate_interworking_sections (& link_info);
d4279937
SC
635#endif
636
fe6e2957 637 sort_sections (stat_ptr->head);
5f8ac7e7 638}
a1613b5f 639\f
fe6e2957
DE
640/* Place an orphan section. We use this to put sections with a '\$' in them
641 into the right place. Any section with a '\$' in them (e.g. .text\$foo)
642 gets mapped to the output section with everything from the '\$' on stripped
643 (e.g. .text).
644 See the Microsoft Portable Executable and Common Object File Format
3535c3c0
NC
645 Specification 4.1, section 4.2, Grouped Sections.
646
647 FIXME: This is now handled by the linker script using wildcards,
648 but I'm leaving this here in case we want to enable it for sections
649 which are not mentioned in the linker script. */
a1613b5f
DE
650
651/*ARGSUSED*/
652static boolean
653gld${EMULATION_NAME}_place_orphan (file, s)
654 lang_input_statement_type *file;
655 asection *s;
656{
fe6e2957
DE
657 const char *secname;
658 char *output_secname, *ps;
a1613b5f 659 lang_output_section_statement_type *os;
fe6e2957 660 lang_statement_union_type *l;
a1613b5f
DE
661
662 if ((s->flags & SEC_ALLOC) == 0)
663 return false;
664
fe6e2957
DE
665 /* Don't process grouped sections unless doing a final link.
666 If they're marked as COMDAT sections, we don't want .text\$foo to
667 end up in .text and then have .text disappear because it's marked
668 link-once-discard. */
669 if (link_info.relocateable)
670 return false;
a1613b5f
DE
671
672 secname = bfd_get_section_name (s->owner, s);
673
fe6e2957
DE
674 /* Everything from the '\$' on gets deleted so don't allow '\$' as the
675 first character. */
676 if (*secname == '\$')
677 einfo ("%P%F: section %s has '\$' as first character\n", secname);
678 if (strchr (secname + 1, '\$') == NULL)
a1613b5f
DE
679 return false;
680
fe6e2957
DE
681 /* Look up the output section. The Microsoft specs say sections names in
682 image files never contain a '\$'. Fortunately, lang_..._lookup creates
683 the section if it doesn't exist. */
684 output_secname = buystring (secname);
685 ps = strchr (output_secname + 1, '\$');
686 *ps = 0;
687 os = lang_output_section_statement_lookup (output_secname);
688
689 /* Find the '\$' wild statement for this section. We currently require the
690 linker script to explicitly mention "*(.foo\$)".
691 FIXME: ppcpe.sc has .CRT\$foo in the .rdata section. According to the
692 Microsoft docs this isn't correct so it's not (currently) handled. */
693
694 ps[0] = '\$';
695 ps[1] = 0;
696 for (l = os->children.head; l; l = l->next)
a1613b5f 697 {
fe6e2957
DE
698 if (l->header.type == lang_wild_statement_enum
699 && strcmp (l->wild_statement.section_name, output_secname) == 0)
700 break;
a1613b5f 701 }
fe6e2957
DE
702 ps[0] = 0;
703 if (l == NULL)
704#if 1
705 einfo ("%P%F: *(%s\$) missing from linker script\n", output_secname);
706#else /* FIXME: This block is untried. It exists to convey the intent,
707 should one decide to not require *(.foo\$) to appear in the linker
708 script. */
a1613b5f 709 {
fe6e2957
DE
710 lang_wild_statement_type *new = new_stat (lang_wild_statement,
711 &os->children);
712 new->section_name = xmalloc (strlen (output_secname) + 2);
713 sprintf (new->section_name, "%s\$", output_secname);
714 new->filename = NULL;
715 lang_list_init (&new->children);
716 l = new;
a1613b5f
DE
717 }
718#endif
719
fe6e2957
DE
720 /* Link the input section in and we're done for now.
721 The sections still have to be sorted, but that has to wait until
722 all such sections have been processed by us. The sorting is done by
723 sort_sections. */
724 wild_doit (&l->wild_statement.children, s, os, file);
a1613b5f
DE
725
726 return true;
727}
a1613b5f 728\f
5f8ac7e7
SC
729static char *
730gld_${EMULATION_NAME}_get_script(isfile)
731 int *isfile;
732EOF
733# Scripts compiled in.
734# sed commands to quote an ld script as a C string.
735sc="-f ${srcdir}/emultempl/stringify.sed"
736
737cat >>e${EMULATION_NAME}.c <<EOF
738{
739 *isfile = 0;
740
741 if (link_info.relocateable == true && config.build_constructors == true)
742 return
743EOF
744sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
745echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
746sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
747echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
748sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
749echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
750sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
751echo ' ; else return' >> e${EMULATION_NAME}.c
752sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
753echo '; }' >> e${EMULATION_NAME}.c
754
755cat >>e${EMULATION_NAME}.c <<EOF
756
757
5f8ac7e7
SC
758struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
759{
760 gld_${EMULATION_NAME}_before_parse,
761 syslib_default,
762 hll_default,
763 after_parse_default,
764 gld_${EMULATION_NAME}_after_open,
765 after_allocation_default,
766 set_output_arch_default,
767 ldemul_default_target,
768 gld_${EMULATION_NAME}_before_allocation,
769 gld_${EMULATION_NAME}_get_script,
770 "${EMULATION_NAME}",
771 "${OUTPUT_FORMAT}",
772 NULL, /* finish */
773 NULL, /* create output section statements */
774 NULL, /* open dynamic archive */
a1613b5f 775 gld${EMULATION_NAME}_place_orphan,
5f8ac7e7
SC
776 gld_${EMULATION_NAME}_set_symbols,
777 gld_${EMULATION_NAME}_parse_args
778};
779EOF
This page took 0.133602 seconds and 4 git commands to generate.