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