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