51f3bbd6249c9325ffbc5289cc526684728d888f
[deliverable/binutils-gdb.git] / ld / emultempl / hppaelf.em
1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 cat >e${EMULATION_NAME}.c <<EOF
4 /* This file is is generated by a shell script. DO NOT EDIT! */
5
6 /* An emulation for HP PA-RISC ELF linkers.
7 Copyright (C) 1991, 93, 94, 95, 97, 99, 2000
8 Free Software Foundation, Inc.
9 Written by Steve Chamberlain steve@cygnus.com
10
11 This file is part of GLD, the Gnu Linker.
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26
27 #include "bfd.h"
28 #include "sysdep.h"
29 #include <ctype.h>
30 #include "bfdlink.h"
31
32 #include "ld.h"
33 #include "ldmain.h"
34 #include "ldemul.h"
35 #include "ldfile.h"
36 #include "ldmisc.h"
37 #include "ldexp.h"
38 #include "ldlang.h"
39 #include "ldgram.h"
40 #include "ldctor.h"
41 #include "elf32-hppa.h"
42
43 static void hppaelf_before_parse PARAMS ((void));
44 static void hppaelf_set_output_arch PARAMS ((void));
45 static void hppaelf_create_output_section_statements PARAMS ((void));
46 static void hppaelf_delete_padding_statements
47 PARAMS ((lang_statement_list_type *list));
48 static void hppaelf_finish PARAMS ((void));
49 static boolean gld${EMULATION_NAME}_place_orphan
50 PARAMS ((lang_input_statement_type *, asection *));
51 static lang_output_section_statement_type *output_rel_find PARAMS ((void));
52 static char *hppaelf_get_script PARAMS ((int *));
53
54
55 /* Fake input file for stubs. */
56 static lang_input_statement_type *stub_file;
57
58 /* Perform some emulation specific initialization. For PA ELF we set
59 up the local label prefix and the output architecture. */
60
61 static void
62 hppaelf_before_parse ()
63 {
64 ldfile_output_architecture = bfd_arch_hppa;
65 }
66
67 /* Set the output architecture and machine. */
68
69 static void
70 hppaelf_set_output_arch()
71 {
72 unsigned long machine = 0;
73
74 bfd_set_arch_mach (output_bfd, ldfile_output_architecture, machine);
75 }
76
77 /* This is called before the input files are opened. We create a new
78 fake input file to hold the stub sections. */
79
80 static void
81 hppaelf_create_output_section_statements ()
82 {
83 stub_file = lang_add_input_file ("linker stubs",
84 lang_input_file_is_fake_enum,
85 NULL);
86 stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
87 if (stub_file->the_bfd == NULL
88 || ! bfd_set_arch_mach (stub_file->the_bfd,
89 bfd_get_arch (output_bfd),
90 bfd_get_mach (output_bfd)))
91 {
92 einfo ("%X%P: can not create BFD %E\n");
93 return;
94 }
95
96 ldlang_add_file (stub_file);
97 }
98
99 /* Walk all the lang statements splicing out any padding statements from
100 the list. */
101
102 static void
103 hppaelf_delete_padding_statements (list)
104 lang_statement_list_type *list;
105 {
106 lang_statement_union_type *s;
107 lang_statement_union_type **ps;
108 for (ps = &list->head; (s = *ps) != NULL; ps = &s->next)
109 {
110 switch (s->header.type)
111 {
112
113 /* We want to recursively walk these sections. */
114 case lang_constructors_statement_enum:
115 hppaelf_delete_padding_statements (&constructor_list);
116 break;
117
118 case lang_output_section_statement_enum:
119 hppaelf_delete_padding_statements (&s->output_section_statement.children);
120 break;
121
122 case lang_group_statement_enum:
123 hppaelf_delete_padding_statements (&s->group_statement.children);
124 break;
125
126 case lang_wild_statement_enum:
127 hppaelf_delete_padding_statements (&s->wild_statement.children);
128 break;
129
130 /* Here's what we are really looking for. Splice these out of
131 the list. */
132 case lang_padding_statement_enum:
133 *ps = s->next;
134 if (*ps == NULL)
135 list->tail = ps;
136 break;
137
138 /* We don't care about these cases. */
139 case lang_data_statement_enum:
140 case lang_object_symbols_statement_enum:
141 case lang_output_statement_enum:
142 case lang_target_statement_enum:
143 case lang_input_section_enum:
144 case lang_input_statement_enum:
145 case lang_assignment_statement_enum:
146 case lang_address_statement_enum:
147 break;
148
149 default:
150 abort ();
151 break;
152 }
153 }
154 }
155
156
157 struct hook_stub_info
158 {
159 lang_statement_list_type add;
160 asection *input_section;
161 };
162
163 /* Traverse the linker tree to find the spot where the stub goes. */
164
165 static boolean
166 hook_in_stub (info, lp)
167 struct hook_stub_info *info;
168 lang_statement_union_type **lp;
169 {
170 lang_statement_union_type *l;
171 boolean ret;
172
173 for (; (l = *lp) != NULL; lp = &l->next)
174 {
175 switch (l->header.type)
176 {
177 case lang_constructors_statement_enum:
178 ret = hook_in_stub (info, &constructor_list.head);
179 if (ret)
180 return ret;
181 break;
182
183 case lang_output_section_statement_enum:
184 ret = hook_in_stub (info,
185 &l->output_section_statement.children.head);
186 if (ret)
187 return ret;
188 break;
189
190 case lang_wild_statement_enum:
191 ret = hook_in_stub (info, &l->wild_statement.children.head);
192 if (ret)
193 return ret;
194 break;
195
196 case lang_group_statement_enum:
197 ret = hook_in_stub (info, &l->group_statement.children.head);
198 if (ret)
199 return ret;
200 break;
201
202 case lang_input_section_enum:
203 if (l->input_section.section == info->input_section)
204 {
205 /* We've found our section. Insert the stub immediately
206 before its associated input section. */
207 *lp = info->add.head;
208 *(info->add.tail) = l;
209 return true;
210 }
211 break;
212
213 case lang_data_statement_enum:
214 case lang_reloc_statement_enum:
215 case lang_object_symbols_statement_enum:
216 case lang_output_statement_enum:
217 case lang_target_statement_enum:
218 case lang_input_statement_enum:
219 case lang_assignment_statement_enum:
220 case lang_padding_statement_enum:
221 case lang_address_statement_enum:
222 case lang_fill_statement_enum:
223 break;
224
225 default:
226 FAIL ();
227 break;
228 }
229 }
230 return false;
231 }
232
233 /* Call-back for elf32_hppa_size_stubs. */
234
235 /* Create a new stub section, and arrange for it to be linked
236 immediately before INPUT_SECTION. */
237
238 static asection *
239 hppaelf_add_stub_section (stub_name, input_section)
240 const char *stub_name;
241 asection *input_section;
242 {
243 asection *stub_sec;
244 flagword flags;
245 asection *output_section;
246 const char *secname;
247 lang_output_section_statement_type *os;
248 struct hook_stub_info info;
249
250 stub_sec = bfd_make_section_anyway (stub_file->the_bfd, stub_name);
251 if (stub_sec == NULL)
252 goto err_ret;
253
254 flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
255 | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_KEEP);
256 if (!bfd_set_section_flags (stub_file->the_bfd, stub_sec, flags))
257 goto err_ret;
258
259 output_section = input_section->output_section;
260 secname = bfd_get_section_name (output_section->owner, output_section);
261 os = lang_output_section_find (secname);
262
263 info.input_section = input_section;
264 lang_list_init (&info.add);
265 wild_doit (&info.add, stub_sec, os, stub_file);
266
267 if (info.add.head == NULL)
268 goto err_ret;
269
270 if (hook_in_stub (&info, &os->children.head))
271 return stub_sec;
272
273 err_ret:
274 einfo ("%X%P: can not make stub section: %E\n");
275 return NULL;
276 }
277
278 /* Another call-back for elf32_hppa_size_stubs. */
279
280 static void
281 hppaelf_layaout_sections_again ()
282 {
283 /* If we have changed sizes of the stub sections, then we need
284 to recalculate all the section offsets. This may mean we need to
285 add even more stubs. */
286
287 /* Delete all the padding statements, they're no longer valid. */
288 hppaelf_delete_padding_statements (stat_ptr);
289
290 /* Resize the sections. */
291 lang_size_sections (stat_ptr->head, abs_output_section,
292 &stat_ptr->head, 0, (bfd_vma) 0, false);
293
294 /* Redo special stuff. */
295 ldemul_after_allocation ();
296
297 /* Do the assignments again. */
298 lang_do_assignments (stat_ptr->head, abs_output_section,
299 (fill_type) 0, (bfd_vma) 0);
300 }
301
302
303 /* Final emulation specific call. For the PA we use this opportunity
304 to build linker stubs. */
305
306 static void
307 hppaelf_finish ()
308 {
309 /* If generating a relocateable output file, then we don't
310 have to examine the relocs. */
311 if (link_info.relocateable)
312 return;
313
314 /* Call into the BFD backend to do the real work. */
315 if (elf32_hppa_size_stubs (stub_file->the_bfd,
316 &link_info,
317 &hppaelf_add_stub_section,
318 &hppaelf_layaout_sections_again) == false)
319 {
320 einfo ("%X%P: can not size stub section: %E\n");
321 return;
322 }
323
324 /* Now build the linker stubs. */
325 if (stub_file->the_bfd->sections != NULL)
326 {
327 if (elf32_hppa_build_stubs (stub_file->the_bfd, &link_info) == false)
328 einfo ("%X%P: can not build stubs: %E\n");
329 }
330 }
331
332
333 /* Place an orphan section. We use this to put random SHF_ALLOC
334 sections in the right segment. */
335
336 struct orphan_save
337 {
338 lang_output_section_statement_type *os;
339 asection **section;
340 lang_statement_union_type **stmt;
341 };
342
343 /*ARGSUSED*/
344 static boolean
345 gld${EMULATION_NAME}_place_orphan (file, s)
346 lang_input_statement_type *file;
347 asection *s;
348 {
349 static struct orphan_save hold_text;
350 static struct orphan_save hold_rodata;
351 static struct orphan_save hold_data;
352 static struct orphan_save hold_bss;
353 static struct orphan_save hold_rel;
354 static struct orphan_save hold_interp;
355 struct orphan_save *place;
356 lang_statement_list_type *old;
357 lang_statement_list_type add;
358 etree_type *address;
359 const char *secname, *ps;
360 const char *outsecname;
361 lang_output_section_statement_type *os;
362
363 secname = bfd_get_section_name (s->owner, s);
364
365 /* Look through the script to see where to place this section. */
366 os = lang_output_section_find (secname);
367
368 if (os != NULL
369 && os->bfd_section != NULL
370 && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)
371 {
372 /* We have already placed a section with this name. */
373 wild_doit (&os->children, s, os, file);
374 return true;
375 }
376
377 if (hold_text.os == NULL)
378 hold_text.os = lang_output_section_find (".text");
379
380 /* If this is a final link, then always put .gnu.warning.SYMBOL
381 sections into the .text section to get them out of the way. */
382 if (! link_info.shared
383 && ! link_info.relocateable
384 && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
385 && hold_text.os != NULL)
386 {
387 wild_doit (&hold_text.os->children, s, hold_text.os, file);
388 return true;
389 }
390
391 /* Decide which segment the section should go in based on the
392 section name and section flags. We put loadable .note sections
393 right after the .interp section, so that the PT_NOTE segment is
394 stored right after the program headers where the OS can read it
395 in the first page. */
396 #define HAVE_SECTION(hold, name) \
397 (hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
398
399 if (s->flags & SEC_EXCLUDE)
400 return false;
401 else if ((s->flags & SEC_ALLOC) == 0)
402 place = NULL;
403 else if ((s->flags & SEC_LOAD) != 0
404 && strncmp (secname, ".note", 4) == 0
405 && HAVE_SECTION (hold_interp, ".interp"))
406 place = &hold_interp;
407 else if ((s->flags & SEC_HAS_CONTENTS) == 0
408 && HAVE_SECTION (hold_bss, ".bss"))
409 place = &hold_bss;
410 else if ((s->flags & SEC_READONLY) == 0
411 && HAVE_SECTION (hold_data, ".data"))
412 place = &hold_data;
413 else if (strncmp (secname, ".rel", 4) == 0
414 && (hold_rel.os != NULL
415 || (hold_rel.os = output_rel_find ()) != NULL))
416 place = &hold_rel;
417 else if ((s->flags & SEC_CODE) == 0
418 && (s->flags & SEC_READONLY) != 0
419 && HAVE_SECTION (hold_rodata, ".rodata"))
420 place = &hold_rodata;
421 else if ((s->flags & SEC_READONLY) != 0
422 && hold_text.os != NULL)
423 place = &hold_text;
424 else
425 place = NULL;
426
427 #undef HAVE_SECTION
428
429 /* Choose a unique name for the section. This will be needed if the
430 same section name appears in the input file with different
431 loadable or allocateable characteristics. */
432 outsecname = secname;
433 if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
434 {
435 unsigned int len;
436 char *newname;
437 unsigned int i;
438
439 len = strlen (outsecname);
440 newname = xmalloc (len + 5);
441 strcpy (newname, outsecname);
442 i = 0;
443 do
444 {
445 sprintf (newname + len, "%d", i);
446 ++i;
447 }
448 while (bfd_get_section_by_name (output_bfd, newname) != NULL);
449
450 outsecname = newname;
451 }
452
453 if (place != NULL)
454 {
455 /* Start building a list of statements for this section. */
456 old = stat_ptr;
457 stat_ptr = &add;
458 lang_list_init (stat_ptr);
459
460 /* If the name of the section is representable in C, then create
461 symbols to mark the start and the end of the section. */
462 for (ps = outsecname; *ps != '\0'; ps++)
463 if (! isalnum ((unsigned char) *ps) && *ps != '_')
464 break;
465 if (*ps == '\0' && config.build_constructors)
466 {
467 char *symname;
468 etree_type *e_align;
469
470 symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
471 sprintf (symname, "__start_%s", outsecname);
472 e_align = exp_unop (ALIGN_K,
473 exp_intop ((bfd_vma) 1 << s->alignment_power));
474 lang_add_assignment (exp_assop ('=', symname, e_align));
475 }
476 }
477
478 if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
479 address = exp_intop ((bfd_vma) 0);
480 else
481 address = NULL;
482
483 os = lang_enter_output_section_statement (outsecname, address, 0,
484 (bfd_vma) 0,
485 (etree_type *) NULL,
486 (etree_type *) NULL,
487 (etree_type *) NULL);
488
489 wild_doit (&os->children, s, os, file);
490
491 lang_leave_output_section_statement
492 ((bfd_vma) 0, "*default*",
493 (struct lang_output_section_phdr_list *) NULL, "*default*");
494
495 if (place != NULL)
496 {
497 asection *snew, **pps;
498
499 stat_ptr = &add;
500
501 if (*ps == '\0' && config.build_constructors)
502 {
503 char *symname;
504
505 symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
506 sprintf (symname, "__stop_%s", outsecname);
507 lang_add_assignment (exp_assop ('=', symname,
508 exp_nameop (NAME, ".")));
509 }
510 stat_ptr = old;
511
512 snew = os->bfd_section;
513 if (place->os->bfd_section != NULL || place->section != NULL)
514 {
515 /* Shuffle the section to make the output file look neater. */
516 if (place->section == NULL)
517 {
518 #if 0
519 /* Finding the end of the list is a little tricky. We
520 make a wild stab at it by comparing section flags. */
521 flagword first_flags = place->os->bfd_section->flags;
522 for (pps = &place->os->bfd_section->next;
523 *pps != NULL && (*pps)->flags == first_flags;
524 pps = &(*pps)->next)
525 ;
526 place->section = pps;
527 #else
528 /* Put orphans after the first section on the list. */
529 place->section = &place->os->bfd_section->next;
530 #endif
531 }
532
533 /* Unlink the section. */
534 for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
535 ;
536 *pps = snew->next;
537
538 /* Now tack it on to the "place->os" section list. */
539 snew->next = *place->section;
540 *place->section = snew;
541 }
542 place->section = &snew->next; /* Save the end of this list. */
543
544 if (place->stmt == NULL)
545 {
546 /* Put the new statement list right at the head. */
547 *add.tail = place->os->header.next;
548 place->os->header.next = add.head;
549 }
550 else
551 {
552 /* Put it after the last orphan statement we added. */
553 *add.tail = *place->stmt;
554 *place->stmt = add.head;
555 }
556 place->stmt = add.tail; /* Save the end of this list. */
557 }
558
559 return true;
560 }
561
562 /* A variant of lang_output_section_find. */
563 static lang_output_section_statement_type *
564 output_rel_find ()
565 {
566 lang_statement_union_type *u;
567 lang_output_section_statement_type *lookup;
568
569 for (u = lang_output_section_statement.head;
570 u != (lang_statement_union_type *) NULL;
571 u = lookup->next)
572 {
573 lookup = &u->output_section_statement;
574 if (strncmp (".rel", lookup->name, 4) == 0
575 && lookup->bfd_section != NULL
576 && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
577 {
578 return lookup;
579 }
580 }
581 return (lang_output_section_statement_type *) NULL;
582 }
583
584 /* The script itself gets inserted here. */
585
586 static char *
587 hppaelf_get_script(isfile)
588 int *isfile;
589 EOF
590
591 if test -n "$COMPILE_IN"
592 then
593 # Scripts compiled in.
594
595 # sed commands to quote an ld script as a C string.
596 sc="-f stringify.sed"
597
598 cat >>e${EMULATION_NAME}.c <<EOF
599 {
600 *isfile = 0;
601
602 if (link_info.relocateable == true && config.build_constructors == true)
603 return
604 EOF
605 sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
606 echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
607 sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
608 echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
609 sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
610 echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
611 sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
612
613 if test -n "$GENERATE_SHLIB_SCRIPT" ; then
614 echo ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c
615 sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c
616 fi
617
618 echo ' ; else return' >> e${EMULATION_NAME}.c
619 sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
620 echo '; }' >> e${EMULATION_NAME}.c
621
622 else
623 # Scripts read from the filesystem.
624
625 cat >>e${EMULATION_NAME}.c <<EOF
626 {
627 *isfile = 1;
628
629 if (link_info.relocateable == true && config.build_constructors == true)
630 return "ldscripts/${EMULATION_NAME}.xu";
631 else if (link_info.relocateable == true)
632 return "ldscripts/${EMULATION_NAME}.xr";
633 else if (!config.text_read_only)
634 return "ldscripts/${EMULATION_NAME}.xbn";
635 else if (!config.magic_demand_paged)
636 return "ldscripts/${EMULATION_NAME}.xn";
637 else if (link_info.shared)
638 return "ldscripts/${EMULATION_NAME}.xs";
639 else
640 return "ldscripts/${EMULATION_NAME}.x";
641 }
642 EOF
643
644 fi
645
646 cat >>e${EMULATION_NAME}.c <<EOF
647
648 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
649 {
650 hppaelf_before_parse,
651 syslib_default,
652 hll_default,
653 after_parse_default,
654 after_open_default,
655 after_allocation_default,
656 hppaelf_set_output_arch,
657 ldemul_default_target,
658 before_allocation_default,
659 hppaelf_get_script,
660 "${EMULATION_NAME}",
661 "elf32-hppa",
662 hppaelf_finish,
663 hppaelf_create_output_section_statements,
664 NULL, /* open dynamic */
665 gld${EMULATION_NAME}_place_orphan,
666 NULL, /* set_symbols */
667 NULL, /* parse_args */
668 NULL, /* unrecognized_file */
669 NULL, /* list_options */
670 NULL, /* recognized_file */
671 NULL /* find_potential_libraries */
672 };
673 EOF
This page took 0.045766 seconds and 4 git commands to generate.