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