source: trunk/binutils/ld/emultempl/beos.em@ 3313

Last change on this file since 3313 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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