1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 if [ -z "$MACHINE" ]; then
6 OUTPUT_ARCH=${ARCH}:${MACHINE}
9 /* This file is part of GLD, the Gnu Linker.
10 Copyright (C) 1995-2024 Free Software Foundation, Inc.
12 This file is part of the GNU Binutils.
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 3 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
27 MA 02110-1301, USA. */
31 /* The original file generated returned different default scripts depending
32 on whether certain switches were set, but these switches pertain to the
33 Linux system and that particular version of coff. In the NT case, we
34 only determine if the subsystem is console or windows in order to select
35 the correct entry point by default. */
42 #include "libiberty.h"
43 #include "filenames.h"
54 #include "coff/internal.h"
55 #include "../bfd/libcoff.h"
57 #define TARGET_IS_${EMULATION_NAME}
59 static struct internal_extra_pe_aouthdr pe;
62 extern const char *output_filename;
65 gld${EMULATION_NAME}_before_parse (void)
67 ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
68 output_filename = "a.exe";
71 /* PE format extra command line options. */
74 gld${EMULATION_NAME}_add_options
75 (int ns ATTRIBUTE_UNUSED, char **shortopts ATTRIBUTE_UNUSED, int nl,
76 struct option **longopts, int nrl ATTRIBUTE_UNUSED,
77 struct option **really_longopts ATTRIBUTE_UNUSED)
79 static const struct option xtra_long[] = {
81 {"base-file", required_argument, NULL, OPTION_BASE_FILE},
82 {"dll", no_argument, NULL, OPTION_DLL},
83 {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
84 {"heap", required_argument, NULL, OPTION_HEAP},
85 {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
86 {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
87 {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
88 {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
89 {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
90 {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
91 {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
92 {"stack", required_argument, NULL, OPTION_STACK},
93 {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
94 {NULL, no_argument, NULL, 0}
97 *longopts = (struct option *)
98 xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
99 memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
103 /* PE/WIN32; added routines to get the subsystem type, heap and/or stack
104 parameters which may be input from the command line */
114 #define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0}
116 static definfo init[] =
118 /* imagebase must be first */
119 #define IMAGEBASEOFF 0
120 D(ImageBase,"__image_base__", BEOS_EXE_IMAGE_BASE),
122 {&dll, sizeof(dll), 0, "__dll__", 0},
123 D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
124 D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
125 D(MajorOperatingSystemVersion,"__major_os_version__", 4),
126 D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
127 D(MajorImageVersion,"__major_image_version__", 1),
128 D(MinorImageVersion,"__minor_image_version__", 0),
129 D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
130 D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
131 D(Subsystem,"__subsystem__", 3),
132 D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
133 D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
134 D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
135 D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
136 D(LoaderFlags,"__loader_flags__", 0x0),
137 { NULL, 0, 0, NULL, 0 }
142 set_pe_name (char *name, long val)
145 /* Find the name and set it. */
146 for (i = 0; init[i].ptr; i++)
148 if (strcmp (name, init[i].symbol) == 0)
160 set_pe_subsystem (void)
173 { "native", 1, "_NtProcessStartup" },
174 { "windows", 2, "_WinMainCRTStartup" },
175 { "wwindows", 2, "_wWinMainCRTStartup" },
176 { "console", 3, "_mainCRTStartup" },
177 { "wconsole", 3, "_wmainCRTStartup" },
178 { "posix", 7, "___PosixProcessStartup"},
182 sver = strchr (optarg, ':');
184 len = strlen (optarg);
190 set_pe_name ("__major_subsystem_version__",
191 strtoul (sver + 1, &end, 0));
193 set_pe_name ("__minor_subsystem_version__",
194 strtoul (end + 1, &end, 0));
196 einfo (_("%P: warning: bad version number in -subsystem option\n"));
199 for (i = 0; v[i].name; i++)
201 if (strncmp (optarg, v[i].name, len) == 0
202 && v[i].name[len] == '\0')
204 set_pe_name ("__subsystem__", v[i].value);
206 /* If the subsystem is windows, we use a different entry
208 lang_default_entry (v[i].entry);
213 einfo (_("%F%P: invalid subsystem type %s\n"), optarg);
218 set_pe_value (char *name)
221 set_pe_name (name, strtoul (optarg, &end, 0));
224 einfo (_("%F%P: invalid hex number for PE parameter '%s'\n"), optarg);
231 set_pe_stack_heap (char *resname, char *comname)
233 set_pe_value (resname);
237 set_pe_value (comname);
241 einfo (_("%F%P: strange hex info for PE parameter '%s'\n"), optarg);
247 gld${EMULATION_NAME}_handle_option (int optc)
254 case OPTION_BASE_FILE:
255 link_info.base_file = fopen (optarg, FOPEN_WB);
256 if (link_info.base_file == NULL)
257 einfo (_("%F%P: cannot open base file %s\n"), optarg);
262 set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
265 set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
267 case OPTION_SUBSYSTEM:
270 case OPTION_MAJOR_OS_VERSION:
271 set_pe_value ("__major_os_version__");
273 case OPTION_MINOR_OS_VERSION:
274 set_pe_value ("__minor_os_version__");
276 case OPTION_MAJOR_SUBSYSTEM_VERSION:
277 set_pe_value ("__major_subsystem_version__");
279 case OPTION_MINOR_SUBSYSTEM_VERSION:
280 set_pe_value ("__minor_subsystem_version__");
282 case OPTION_MAJOR_IMAGE_VERSION:
283 set_pe_value ("__major_image_version__");
285 case OPTION_MINOR_IMAGE_VERSION:
286 set_pe_value ("__minor_image_version__");
288 case OPTION_FILE_ALIGNMENT:
289 set_pe_value ("__file_alignment__");
291 case OPTION_SECTION_ALIGNMENT:
292 set_pe_value ("__section_alignment__");
295 set_pe_name ("__dll__", 1);
297 case OPTION_IMAGE_BASE:
298 set_pe_value ("__image_base__");
304 /* Assign values to the special symbols before the linker script is
308 gld${EMULATION_NAME}_set_symbols (void)
310 /* Run through and invent symbols for all the
311 names and insert the defaults. */
314 if (!init[IMAGEBASEOFF].inited)
316 if (bfd_link_relocatable (&link_info))
317 init[IMAGEBASEOFF].value = 0;
318 else if (init[DLLOFF].value)
319 init[IMAGEBASEOFF].value = BEOS_DLL_IMAGE_BASE;
321 init[IMAGEBASEOFF].value = BEOS_EXE_IMAGE_BASE;
324 /* Don't do any symbol assignments if this is a relocatable link. */
325 if (bfd_link_relocatable (&link_info))
328 /* Glue the assignments into the abs section */
329 push_stat_ptr (&abs_output_section->children);
331 for (j = 0; init[j].ptr; j++)
333 long val = init[j].value;
334 lang_add_assignment (exp_assign (init[j].symbol, exp_intop (val),
336 if (init[j].size == sizeof(short))
337 *(short *)init[j].ptr = val;
338 else if (init[j].size == sizeof(int))
339 *(int *)init[j].ptr = val;
340 else if (init[j].size == sizeof(long))
341 *(long *)init[j].ptr = val;
342 /* This might be a long long or other special type. */
343 else if (init[j].size == sizeof(bfd_vma))
344 *(bfd_vma *)init[j].ptr = val;
347 /* Restore the pointer. */
350 if (pe.FileAlignment >
353 einfo (_("%P: warning, file alignment > section alignment\n"));
358 gld${EMULATION_NAME}_after_open (void)
360 after_open_default ();
362 /* Pass the wacky PE command line options into the output bfd.
363 FIXME: This should be done via a function, rather than by
364 including an internal BFD header. */
365 if (!obj_pe (link_info.output_bfd))
367 einfo (_("%F%P: PE operations on non PE file\n"));
370 pe_data(link_info.output_bfd)->pe_opthdr = pe;
371 pe_data(link_info.output_bfd)->dll = init[DLLOFF].value;
375 /* Callback functions for qsort in sort_sections. */
378 sort_by_file_name (const void *a, const void *b)
380 const lang_input_section_type *const *ra = a;
381 const lang_input_section_type *const *rb = b;
382 asection *sa = (*ra)->section;
383 asection *sb = (*rb)->section;
386 i = filename_cmp (bfd_get_filename (sa->owner->my_archive),
387 bfd_get_filename (sb->owner->my_archive));
391 i = filename_cmp (bfd_get_filename (sa->owner),
392 bfd_get_filename (sb->owner));
395 /* the tail idata4/5 are the only ones without relocs to an
396 idata$6 section unless we are importing by ordinal,
397 so sort them to last to terminate the IAT
398 and HNT properly. if no reloc this one is import by ordinal
399 so we have to sort by section contents */
401 if (sa->reloc_count + sb->reloc_count != 0)
403 i = sa->reloc_count > sb->reloc_count ? -1 : 0;
407 return sa->reloc_count > sb->reloc_count ? 0 : 1;
411 /* don't sort .idata$6 or .idata$7 FIXME dlltool eliminate .idata$7 */
412 if ((strcmp (sa->name, ".idata$6") == 0))
415 if (!bfd_get_section_contents (sa->owner, sa, &a_sec, (file_ptr) 0,
416 (bfd_size_type) sizeof (a_sec)))
417 einfo (_("%F%P: %pB: can't read contents of section .idata: %E\n"),
420 if (!bfd_get_section_contents (sb->owner, sb, &b_sec, (file_ptr) 0,
421 (bfd_size_type) sizeof (b_sec)))
422 einfo (_("%F%P: %pB: can't read contents of section .idata: %E\n"),
425 i = a_sec < b_sec ? -1 : 0;
428 return a_sec < b_sec ? 0 : 1;
434 sort_by_section_name (const void *a, const void *b)
436 const lang_input_section_type *const *ra = a;
437 const lang_input_section_type *const *rb = b;
438 const char *sna = (*ra)->section->name;
439 const char *snb = (*rb)->section->name;
441 i = strcmp (sna, snb);
442 /* This is a hack to make .stab and .stabstr last, so we don't have
443 to fix strip/objcopy for .reloc sections.
444 FIXME stripping images with a .rsrc section still needs to be fixed. */
447 if ((startswith (sna, ".stab"))
448 && (!startswith (snb, ".stab")))
454 /* Subroutine of sort_sections to a contiguous subset of a list of sections.
455 NEXT_AFTER is the element after the last one to sort.
456 The result is a pointer to the last element's "next" pointer. */
458 static lang_statement_union_type **
459 sort_sections_1 (lang_statement_union_type **startptr,
460 lang_statement_union_type *next_after,
462 int (*sort_func) (const void *, const void *))
464 lang_statement_union_type **vec;
465 lang_statement_union_type *p;
467 lang_statement_union_type **ret;
472 vec = ((lang_statement_union_type **)
473 xmalloc (count * sizeof (lang_statement_union_type *)));
475 for (p = *startptr, i = 0; i < count; i++, p = p->header.next)
478 qsort (vec, count, sizeof (vec[0]), sort_func);
480 /* Fill in the next pointers again. */
482 for (i = 0; i < count - 1; i++)
483 vec[i]->header.next = vec[i + 1];
484 vec[i]->header.next = next_after;
485 ret = &vec[i]->header.next;
490 /* Sort the .idata\$foo input sections of archives into filename order.
491 The reason is so dlltool can arrange to have the pe dll import information
492 generated correctly - the head of the list goes into dh.o, the tail into
493 dt.o, and the guts into ds[nnnn].o. Note that this is only needed for the
495 FIXME: This may no longer be necessary with grouped sections. Instead of
496 sorting on dh.o, ds[nnnn].o, dt.o, one could, for example, have dh.o use
497 .idata\$4h, have ds[nnnn].o use .idata\$4s[nnnn], and have dt.o use .idata\$4t.
498 This would have to be elaborated upon to handle multiple dll's
499 [assuming such an eloboration is possible of course].
501 We also sort sections in '\$' wild statements. These are created by the
502 place_orphans routine to implement grouped sections. */
505 sort_sections (lang_statement_union_type *s)
507 for (; s ; s = s->header.next)
508 switch (s->header.type)
510 case lang_output_section_statement_enum:
511 sort_sections (s->output_section_statement.children.head);
513 case lang_wild_statement_enum:
515 lang_statement_union_type **p = &s->wild_statement.children.head;
516 struct wildcard_list *sec;
518 for (sec = s->wild_statement.section_list; sec; sec = sec->next)
520 /* Is this the .idata section? */
521 if (sec->spec.name != NULL
522 && startswith (sec->spec.name, ".idata"))
524 /* Sort the children. We want to sort any objects in
525 the same archive. In order to handle the case of
526 including a single archive multiple times, we sort
527 all the children by archive name and then by object
528 name. After sorting them, we re-thread the pointer
533 lang_statement_union_type *start = *p;
534 if (start->header.type != lang_input_section_enum
535 || !start->input_section.section->owner->my_archive)
536 p = &(start->header.next);
539 lang_statement_union_type *end;
542 for (end = start, count = 0;
543 end && (end->header.type
544 == lang_input_section_enum);
545 end = end->header.next)
548 p = sort_sections_1 (p, end, count,
555 /* If this is a collection of grouped sections, sort them.
556 The linker script must explicitly mention "*(.foo\$)" or
557 "*(.foo\$*)". Don't sort them if \$ is not the last
558 character (not sure if this is really useful, but it
559 allows explicitly mentioning some \$ sections and letting
560 the linker handle the rest). */
561 if (sec->spec.name != NULL)
563 char *q = strchr (sec->spec.name, '\$');
567 || (q[1] == '*' && q[2] == '\0')))
569 lang_statement_union_type *end;
572 for (end = *p, count = 0; end; end = end->header.next)
574 if (end->header.type != lang_input_section_enum)
578 (void) sort_sections_1 (p, end, count,
579 sort_by_section_name);
592 gld${EMULATION_NAME}_before_allocation (void)
594 #ifdef TARGET_IS_armpe
595 /* FIXME: we should be able to set the size of the interworking stub
598 Here we rummage through the found bfds to collect glue
599 information. FIXME: should this be based on a command line
600 option? krk@cygnus.com */
602 LANG_FOR_EACH_INPUT_STATEMENT (is)
604 if (!arm_process_before_allocation (is->the_bfd, & link_info))
606 einfo (_("%P: errors encountered processing file %s\n"),
612 /* We have seen it all. Allocate it, and carry on */
613 arm_allocate_interworking_sections (& link_info);
614 #endif /* TARGET_IS_armpe */
616 sort_sections (stat_ptr->head);
618 before_allocation_default ();
621 /* Place an orphan section. We use this to put sections with a '\$' in them
622 into the right place. Any section with a '\$' in them (e.g. .text\$foo)
623 gets mapped to the output section with everything from the '\$' on stripped
625 See the Microsoft Portable Executable and Common Object File Format
626 Specification 4.1, section 4.2, Grouped Sections.
628 FIXME: This is now handled by the linker script using wildcards,
629 but I'm leaving this here in case we want to enable it for sections
630 which are not mentioned in the linker script. */
632 static lang_output_section_statement_type *
633 gld${EMULATION_NAME}_place_orphan (asection *s,
637 char *output_secname, *ps;
638 lang_output_section_statement_type *os;
639 lang_statement_union_type *l;
641 if ((s->flags & SEC_ALLOC) == 0)
644 /* Don't process grouped sections unless doing a final link.
645 If they're marked as COMDAT sections, we don't want .text\$foo to
646 end up in .text and then have .text disappear because it's marked
647 link-once-discard. */
648 if (bfd_link_relocatable (&link_info))
651 /* Everything from the '\$' on gets deleted so don't allow '\$' as the
653 if (*secname == '\$')
654 einfo (_("%F%P: section %s has '\$' as first character\n"), secname);
655 if (strchr (secname + 1, '\$') == NULL)
658 /* Look up the output section. The Microsoft specs say sections names in
659 image files never contain a '\$'. Fortunately, lang_..._lookup creates
660 the section if it doesn't exist. */
661 output_secname = xstrdup (secname);
662 ps = strchr (output_secname + 1, '\$');
664 os = lang_output_section_statement_lookup (output_secname, constraint, true);
666 /* Find the '\$' wild statement for this section. We currently require the
667 linker script to explicitly mention "*(.foo\$)". */
671 for (l = os->children.head; l; l = l->header.next)
672 if (l->header.type == lang_wild_statement_enum)
674 struct wildcard_list *sec;
676 for (sec = l->wild_statement.section_list; sec; sec = sec->next)
677 if (sec->spec.name && strcmp (sec->spec.name, output_secname) == 0)
684 einfo (_("%F%P: *(%s\$) missing from linker script\n"), output_secname);
686 /* Link the input section in and we're done for now.
687 The sections still have to be sorted, but that has to wait until
688 all such sections have been processed by us. The sorting is done by
690 lang_add_section (&l->wild_statement.children, s, NULL, NULL, os);
696 gld${EMULATION_NAME}_get_script (int *isfile)
699 if test x"$COMPILE_IN" = xyes
701 # Scripts compiled in.
703 # sed commands to quote an ld script as a C string.
704 sc="-f ${srcdir}/emultempl/stringify.sed"
710 if (bfd_link_relocatable (&link_info) && config.build_constructors)
713 sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
714 echo ' ; else if (bfd_link_relocatable (&link_info)) return' >> e${EMULATION_NAME}.c
715 sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
716 echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
717 sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
718 echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
719 sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
720 echo ' ; else return' >> e${EMULATION_NAME}.c
721 sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
722 echo '; }' >> e${EMULATION_NAME}.c
725 # Scripts read from the filesystem.
731 if (bfd_link_relocatable (&link_info) && config.build_constructors)
732 return "ldscripts/${EMULATION_NAME}.xu";
733 else if (bfd_link_relocatable (&link_info))
734 return "ldscripts/${EMULATION_NAME}.xr";
735 else if (!config.text_read_only)
736 return "ldscripts/${EMULATION_NAME}.xbn";
737 else if (!config.magic_demand_paged)
738 return "ldscripts/${EMULATION_NAME}.xn";
740 return "ldscripts/${EMULATION_NAME}.x";
745 LDEMUL_AFTER_OPEN=gld${EMULATION_NAME}_after_open
746 LDEMUL_BEFORE_ALLOCATION=gld${EMULATION_NAME}_before_allocation
747 LDEMUL_PLACE_ORPHAN=gld${EMULATION_NAME}_place_orphan
748 LDEMUL_SET_SYMBOLS=gld${EMULATION_NAME}_set_symbols
749 LDEMUL_ADD_OPTIONS=gld${EMULATION_NAME}_add_options
750 LDEMUL_HANDLE_OPTION=gld${EMULATION_NAME}_handle_option
752 source_em ${srcdir}/emultempl/emulation.em