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