1# This shell script emits a C file. -*- C -*- 2# It does some substitutions. 3fragment <<EOF 4/* This file is is generated by a shell script. DO NOT EDIT! */ 5 6/* Emulate the original gld for the given ${EMULATION_NAME} 7 Copyright (C) 2014-2022 Free Software Foundation, Inc. 8 Written by Steve Chamberlain steve@cygnus.com 9 Extended for the MSP430 by Nick Clifton nickc@redhat.com 10 11 This file is part of the GNU Binutils. 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 3 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., 51 Franklin Street - Fifth Floor, Boston, 26 MA 02110-1301, USA. */ 27 28#define TARGET_IS_${EMULATION_NAME} 29 30#include "sysdep.h" 31#include "bfd.h" 32#include "bfdlink.h" 33#include "ctf-api.h" 34 35#include "ld.h" 36#include "getopt.h" 37#include "ldmain.h" 38#include "ldmisc.h" 39#include "ldexp.h" 40#include "ldlang.h" 41#include "ldfile.h" 42#include "ldemul.h" 43#include "libiberty.h" 44#include <ldgram.h> 45 46enum regions 47{ 48 REGION_NONE = 0, 49 REGION_LOWER, 50 REGION_UPPER, 51 REGION_EITHER = 3, 52}; 53 54enum either_placement_stage 55{ 56 LOWER_TO_UPPER, 57 UPPER_TO_LOWER, 58}; 59 60enum { ROM, RAM }; 61 62static int data_region = REGION_NONE; 63static int code_region = REGION_NONE; 64static bool disable_sec_transformation = false; 65 66#define MAX_PREFIX_LENGTH 7 67 68EOF 69 70# Import any needed special functions and/or overrides. 71# 72if test -n "$EXTRA_EM_FILE" ; then 73 source_em ${srcdir}/emultempl/${EXTRA_EM_FILE}.em 74fi 75 76if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then 77fragment <<EOF 78 79static void 80gld${EMULATION_NAME}_before_parse (void) 81{ 82#ifndef TARGET_ /* I.e., if not generic. */ 83 ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown); 84#endif /* not TARGET_ */ 85 86 /* The MSP430 port *needs* linker relaxtion in order to cope with large 87 functions where conditional branches do not fit into a +/- 1024 byte range. */ 88 if (!bfd_link_relocatable (&link_info)) 89 TARGET_ENABLE_RELAXATION; 90} 91 92EOF 93fi 94 95if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then 96fragment <<EOF 97 98static char * 99gld${EMULATION_NAME}_get_script (int *isfile) 100EOF 101 102if test x"$COMPILE_IN" = xyes 103then 104# Scripts compiled in. 105 106# sed commands to quote an ld script as a C string. 107sc="-f stringify.sed" 108 109fragment <<EOF 110{ 111 *isfile = 0; 112 113 if (bfd_link_relocatable (&link_info) && config.build_constructors) 114 return 115EOF 116sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c 117echo ' ; else if (bfd_link_relocatable (&link_info)) return' >> e${EMULATION_NAME}.c 118sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c 119echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c 120sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c 121echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c 122sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c 123echo ' ; else return' >> e${EMULATION_NAME}.c 124sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c 125echo '; }' >> e${EMULATION_NAME}.c 126 127else 128# Scripts read from the filesystem. 129 130fragment <<EOF 131{ 132 *isfile = 1; 133 134 if (bfd_link_relocatable (&link_info) && config.build_constructors) 135 return "ldscripts/${EMULATION_NAME}.xu"; 136 else if (bfd_link_relocatable (&link_info)) 137 return "ldscripts/${EMULATION_NAME}.xr"; 138 else if (!config.text_read_only) 139 return "ldscripts/${EMULATION_NAME}.xbn"; 140 else if (!config.magic_demand_paged) 141 return "ldscripts/${EMULATION_NAME}.xn"; 142 else 143 return "ldscripts/${EMULATION_NAME}.x"; 144} 145EOF 146fi 147fi 148 149if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then 150fragment <<EOF 151 152static unsigned int 153data_statement_size (lang_data_statement_type *d) 154{ 155 unsigned int size = 0; 156 switch (d->type) 157 { 158 case QUAD: 159 case SQUAD: 160 size = QUAD_SIZE; 161 break; 162 case LONG: 163 size = LONG_SIZE; 164 break; 165 case SHORT: 166 size = SHORT_SIZE; 167 break; 168 case BYTE: 169 size = BYTE_SIZE; 170 break; 171 default: 172 einfo (_("%P: error: unhandled data_statement size\n")); 173 FAIL (); 174 } 175 return size; 176} 177 178/* Helper function for place_orphan that computes the size 179 of sections already mapped to the given statement. */ 180 181static bfd_size_type 182scan_children (lang_statement_union_type * l) 183{ 184 bfd_size_type amount = 0; 185 186 while (l != NULL) 187 { 188 switch (l->header.type) 189 { 190 case lang_input_section_enum: 191 if (l->input_section.section->flags & SEC_ALLOC) 192 amount += l->input_section.section->size; 193 break; 194 195 case lang_constructors_statement_enum: 196 case lang_assignment_statement_enum: 197 case lang_padding_statement_enum: 198 break; 199 200 case lang_wild_statement_enum: 201 amount += scan_children (l->wild_statement.children.head); 202 break; 203 204 case lang_data_statement_enum: 205 amount += data_statement_size (&l->data_statement); 206 break; 207 208 default: 209 fprintf (stderr, "msp430 orphan placer: unhandled lang type %d\n", l->header.type); 210 break; 211 } 212 213 l = l->header.next; 214 } 215 216 return amount; 217} 218 219#define WARN_UPPER 0 220#define WARN_LOWER 1 221#define WARN_TEXT 0 222#define WARN_DATA 1 223#define WARN_BSS 2 224#define WARN_RODATA 3 225 226/* Warn only once per output section. 227 * NAME starts with ".upper." or ".lower.". */ 228static void 229warn_no_output_section (const char *name) 230{ 231 static bool warned[2][4] = {{false, false, false, false}, 232 {false, false, false, false}}; 233 int i = WARN_LOWER; 234 235 if (strncmp (name, ".upper.", 7) == 0) 236 i = WARN_UPPER; 237 238 if (!warned[i][WARN_TEXT] && strcmp (name + 6, ".text") == 0) 239 warned[i][WARN_TEXT] = true; 240 else if (!warned[i][WARN_DATA] && strcmp (name + 6, ".data") == 0) 241 warned[i][WARN_DATA] = true; 242 else if (!warned[i][WARN_BSS] && strcmp (name + 6, ".bss") == 0) 243 warned[i][WARN_BSS] = true; 244 else if (!warned[i][WARN_RODATA] && strcmp (name + 6, ".rodata") == 0) 245 warned[i][WARN_RODATA] = true; 246 else 247 return; 248 einfo ("%P: warning: no input section rule matches %s in linker script\n", 249 name); 250} 251 252 253/* Place an orphan section. We use this to put .either sections 254 into either their lower or their upper equivalents. */ 255 256static lang_output_section_statement_type * 257gld${EMULATION_NAME}_place_orphan (asection * s, 258 const char * secname, 259 int constraint) 260{ 261 char * lower_name; 262 char * upper_name; 263 char * name; 264 lang_output_section_statement_type * lower; 265 lang_output_section_statement_type * upper; 266 267 if ((s->flags & SEC_ALLOC) == 0) 268 return NULL; 269 270 if (bfd_link_relocatable (&link_info)) 271 return NULL; 272 273 /* If constraints are involved let the linker handle the placement normally. */ 274 if (constraint != 0) 275 return NULL; 276 277 if (strncmp (secname, ".upper.", 7) == 0 278 || strncmp (secname, ".lower.", 7) == 0) 279 { 280 warn_no_output_section (secname); 281 return NULL; 282 } 283 284 /* We only need special handling for .either sections. */ 285 if (strncmp (secname, ".either.", 8) != 0) 286 return NULL; 287 288 /* Skip the .either prefix. */ 289 secname += 7; 290 291 /* Compute the names of the corresponding upper and lower 292 sections. If the input section name contains another period, 293 only use the part of the name before the second dot. */ 294 if (strchr (secname + 1, '.') != NULL) 295 { 296 name = xstrdup (secname); 297 298 * strchr (name + 1, '.') = 0; 299 } 300 else 301 name = (char *) secname; 302 303 lower_name = concat (".lower", name, NULL); 304 upper_name = concat (".upper", name, NULL); 305 306 /* Find the corresponding lower and upper sections. */ 307 lower = lang_output_section_find (lower_name); 308 upper = lang_output_section_find (upper_name); 309 310 if (lower == NULL && upper == NULL) 311 { 312 einfo (_("%P: error: no section named %s or %s in linker script\n"), 313 lower_name, upper_name); 314 goto end; 315 } 316 else if (lower == NULL) 317 { 318 lower = lang_output_section_find (name); 319 if (lower == NULL) 320 { 321 einfo (_("%P: error: no section named %s in linker script\n"), name); 322 goto end; 323 } 324 } 325 326 /* Always place orphaned sections in lower. Optimal placement of either 327 sections is performed later, once section sizes have been finalized. */ 328 lang_add_section (& lower->children, s, NULL, NULL, lower); 329 end: 330 free (upper_name); 331 free (lower_name); 332 return lower; 333} 334EOF 335fi 336 337fragment <<EOF 338 339static bool 340change_output_section (lang_statement_union_type **head, 341 asection *s, 342 lang_output_section_statement_type *new_os, 343 lang_output_section_statement_type *old_os) 344{ 345 asection *is; 346 lang_statement_union_type * prev = NULL; 347 lang_statement_union_type * curr; 348 349 curr = *head; 350 while (curr != NULL) 351 { 352 switch (curr->header.type) 353 { 354 case lang_input_section_enum: 355 is = curr->input_section.section; 356 if (is == s) 357 { 358 lang_statement_list_type *old_list 359 = (lang_statement_list_type *) &old_os->children; 360 s->output_section = NULL; 361 lang_add_section (&new_os->children, s, 362 curr->input_section.pattern, NULL, new_os); 363 364 /* Remove the section from the old output section. */ 365 if (prev == NULL) 366 *head = curr->header.next; 367 else 368 prev->header.next = curr->header.next; 369 /* If the input section we just moved is the tail of the old 370 output section, then we also need to adjust that tail. */ 371 if (old_list->tail == (lang_statement_union_type **) curr) 372 old_list->tail = (lang_statement_union_type **) prev; 373 374 return true; 375 } 376 break; 377 case lang_wild_statement_enum: 378 if (change_output_section (&(curr->wild_statement.children.head), 379 s, new_os, old_os)) 380 return true; 381 break; 382 default: 383 break; 384 } 385 prev = curr; 386 curr = curr->header.next; 387 } 388 return false; 389} 390 391static void 392add_region_prefix (bfd *abfd ATTRIBUTE_UNUSED, asection *s, 393 void *unused ATTRIBUTE_UNUSED) 394{ 395 const char *curr_name = bfd_section_name (s); 396 int region = REGION_NONE; 397 398 if (strncmp (curr_name, ".text", 5) == 0) 399 region = code_region; 400 else if (strncmp (curr_name, ".data", 5) == 0) 401 region = data_region; 402 else if (strncmp (curr_name, ".bss", 4) == 0) 403 region = data_region; 404 else if (strncmp (curr_name, ".rodata", 7) == 0) 405 region = data_region; 406 else 407 return; 408 409 switch (region) 410 { 411 case REGION_NONE: 412 break; 413 case REGION_UPPER: 414 bfd_rename_section (s, concat (".upper", curr_name, NULL)); 415 break; 416 case REGION_LOWER: 417 bfd_rename_section (s, concat (".lower", curr_name, NULL)); 418 break; 419 case REGION_EITHER: 420 s->name = concat (".either", curr_name, NULL); 421 break; 422 default: 423 /* Unreachable. */ 424 FAIL (); 425 break; 426 } 427} 428 429static void 430msp430_elf_after_open (void) 431{ 432 bfd *abfd; 433 434 gld${EMULATION_NAME}_after_open (); 435 436 /* If neither --code-region or --data-region have been passed, do not 437 transform sections names. */ 438 if ((code_region == REGION_NONE && data_region == REGION_NONE) 439 || disable_sec_transformation) 440 return; 441 442 for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next) 443 bfd_map_over_sections (abfd, add_region_prefix, NULL); 444} 445 446#define OPTION_CODE_REGION 321 447#define OPTION_DATA_REGION (OPTION_CODE_REGION + 1) 448#define OPTION_DISABLE_TRANS (OPTION_CODE_REGION + 2) 449 450static void 451gld${EMULATION_NAME}_add_options 452 (int ns, char **shortopts, int nl, struct option **longopts, 453 int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED) 454{ 455 static const char xtra_short[] = { }; 456 457 static const struct option xtra_long[] = 458 { 459 { "code-region", required_argument, NULL, OPTION_CODE_REGION }, 460 { "data-region", required_argument, NULL, OPTION_DATA_REGION }, 461 { "disable-sec-transformation", no_argument, NULL, 462 OPTION_DISABLE_TRANS }, 463 { NULL, no_argument, NULL, 0 } 464 }; 465 466 *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short)); 467 memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short)); 468 *longopts = (struct option *) 469 xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long)); 470 memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); 471} 472 473static void 474gld${EMULATION_NAME}_list_options (FILE * file) 475{ 476 fprintf (file, _(" --code-region={either,lower,upper,none}\n\ 477 Transform .text* sections to {either,lower,upper,none}.text* sections\n")); 478 fprintf (file, _(" --data-region={either,lower,upper,none}\n\ 479 Transform .data*, .rodata* and .bss* sections to\n\ 480 {either,lower,upper,none}.{bss,data,rodata}* sections\n")); 481 fprintf (file, _(" --disable-sec-transformation\n\ 482 Disable transformation of .{text,data,bss,rodata}* sections to\n\ 483 add the {either,lower,upper,none} prefixes\n")); 484} 485 486static bool 487gld${EMULATION_NAME}_handle_option (int optc) 488{ 489 switch (optc) 490 { 491 case OPTION_CODE_REGION: 492 if (strcmp (optarg, "upper") == 0) 493 code_region = REGION_UPPER; 494 else if (strcmp (optarg, "lower") == 0) 495 code_region = REGION_LOWER; 496 else if (strcmp (optarg, "either") == 0) 497 code_region = REGION_EITHER; 498 else if (strcmp (optarg, "none") == 0) 499 code_region = REGION_NONE; 500 else if (strlen (optarg) == 0) 501 { 502 einfo (_("%P: --code-region requires an argument: " 503 "{upper,lower,either,none}\n")); 504 return false; 505 } 506 else 507 { 508 einfo (_("%P: error: unrecognized argument to --code-region= option: " 509 "\"%s\"\n"), optarg); 510 return false; 511 } 512 break; 513 514 case OPTION_DATA_REGION: 515 if (strcmp (optarg, "upper") == 0) 516 data_region = REGION_UPPER; 517 else if (strcmp (optarg, "lower") == 0) 518 data_region = REGION_LOWER; 519 else if (strcmp (optarg, "either") == 0) 520 data_region = REGION_EITHER; 521 else if (strcmp (optarg, "none") == 0) 522 data_region = REGION_NONE; 523 else if (strlen (optarg) == 0) 524 { 525 einfo (_("%P: --data-region requires an argument: " 526 "{upper,lower,either,none}\n")); 527 return false; 528 } 529 else 530 { 531 einfo (_("%P: error: unrecognized argument to --data-region= option: " 532 "\"%s\"\n"), optarg); 533 return false; 534 } 535 break; 536 537 case OPTION_DISABLE_TRANS: 538 disable_sec_transformation = true; 539 break; 540 541 default: 542 return false; 543 } 544 return true; 545} 546 547static void 548eval_upper_either_sections (bfd *abfd ATTRIBUTE_UNUSED, 549 asection *s, void *data) 550{ 551 const char * base_sec_name; 552 const char * curr_name; 553 char * either_name; 554 int curr_region; 555 556 lang_output_section_statement_type * lower; 557 lang_output_section_statement_type * upper; 558 static bfd_size_type *lower_size = 0; 559 static bfd_size_type *upper_size = 0; 560 static bfd_size_type lower_size_rom = 0; 561 static bfd_size_type lower_size_ram = 0; 562 static bfd_size_type upper_size_rom = 0; 563 static bfd_size_type upper_size_ram = 0; 564 565 if ((s->flags & SEC_ALLOC) == 0) 566 return; 567 if (bfd_link_relocatable (&link_info)) 568 return; 569 570 base_sec_name = (const char *) data; 571 curr_name = bfd_section_name (s); 572 573 /* Only concerned with .either input sections in the upper output section. */ 574 either_name = concat (".either", base_sec_name, NULL); 575 if (strncmp (curr_name, either_name, strlen (either_name)) != 0 576 || strncmp (s->output_section->name, ".upper", 6) != 0) 577 goto end; 578 579 lower = lang_output_section_find (concat (".lower", base_sec_name, NULL)); 580 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL)); 581 582 if (upper == NULL || upper->region == NULL) 583 goto end; 584 else if (lower == NULL) 585 lower = lang_output_section_find (base_sec_name); 586 if (lower == NULL || lower->region == NULL) 587 goto end; 588 589 if (strcmp (base_sec_name, ".text") == 0 590 || strcmp (base_sec_name, ".rodata") == 0) 591 curr_region = ROM; 592 else 593 curr_region = RAM; 594 595 if (curr_region == ROM) 596 { 597 if (lower_size_rom == 0) 598 { 599 lower_size_rom = lower->region->current - lower->region->origin; 600 upper_size_rom = upper->region->current - upper->region->origin; 601 } 602 lower_size = &lower_size_rom; 603 upper_size = &upper_size_rom; 604 } 605 else if (curr_region == RAM) 606 { 607 if (lower_size_ram == 0) 608 { 609 lower_size_ram = lower->region->current - lower->region->origin; 610 upper_size_ram = upper->region->current - upper->region->origin; 611 } 612 lower_size = &lower_size_ram; 613 upper_size = &upper_size_ram; 614 } 615 616 /* If the upper region is overflowing, try moving sections to the lower 617 region. 618 Note that there isn't any general benefit to using lower memory over upper 619 memory, so we only move sections around with the goal of making the program 620 fit. */ 621 if (*upper_size > upper->region->length 622 && *lower_size + s->size < lower->region->length) 623 { 624 if (change_output_section (&(upper->children.head), s, lower, upper)) 625 { 626 *upper_size -= s->size; 627 *lower_size += s->size; 628 } 629 } 630 end: 631 free (either_name); 632} 633 634static void 635eval_lower_either_sections (bfd *abfd ATTRIBUTE_UNUSED, 636 asection *s, void *data) 637{ 638 const char * base_sec_name; 639 const char * curr_name; 640 char * either_name; 641 int curr_region; 642 lang_output_section_statement_type * output_sec; 643 lang_output_section_statement_type * lower; 644 lang_output_section_statement_type * upper; 645 646 static bfd_size_type *lower_size = 0; 647 static bfd_size_type lower_size_rom = 0; 648 static bfd_size_type lower_size_ram = 0; 649 650 if ((s->flags & SEC_ALLOC) == 0) 651 return; 652 if (bfd_link_relocatable (&link_info)) 653 return; 654 655 base_sec_name = (const char *) data; 656 curr_name = bfd_section_name (s); 657 658 /* Only concerned with .either input sections in the lower or "default" 659 output section i.e. not in the upper output section. */ 660 either_name = concat (".either", base_sec_name, NULL); 661 if (strncmp (curr_name, either_name, strlen (either_name)) != 0 662 || strncmp (s->output_section->name, ".upper", 6) == 0) 663 return; 664 665 if (strcmp (base_sec_name, ".text") == 0 666 || strcmp (base_sec_name, ".rodata") == 0) 667 curr_region = ROM; 668 else 669 curr_region = RAM; 670 671 output_sec = lang_output_section_find (s->output_section->name); 672 673 /* If the output_section doesn't exist, this has already been reported in 674 place_orphan, so don't need to warn again. */ 675 if (output_sec == NULL || output_sec->region == NULL) 676 goto end; 677 678 /* lower and output_sec might be the same, but in some cases an .either 679 section can end up in base_sec_name if it hasn't been placed by 680 place_orphan. */ 681 lower = lang_output_section_find (concat (".lower", base_sec_name, NULL)); 682 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL)); 683 if (upper == NULL) 684 goto end; 685 686 if (curr_region == ROM) 687 { 688 if (lower_size_rom == 0) 689 { 690 /* Get the size of other items in the lower region that aren't the 691 sections to be moved around. */ 692 lower_size_rom 693 = (output_sec->region->current - output_sec->region->origin) 694 - scan_children (output_sec->children.head); 695 if (output_sec != lower && lower != NULL) 696 lower_size_rom -= scan_children (lower->children.head); 697 } 698 lower_size = &lower_size_rom; 699 } 700 else if (curr_region == RAM) 701 { 702 if (lower_size_ram == 0) 703 { 704 lower_size_ram 705 = (output_sec->region->current - output_sec->region->origin) 706 - scan_children (output_sec->children.head); 707 if (output_sec != lower && lower != NULL) 708 lower_size_ram -= scan_children (lower->children.head); 709 } 710 lower_size = &lower_size_ram; 711 } 712 /* Move sections that cause the lower region to overflow to the upper region. */ 713 if (*lower_size + s->size > output_sec->region->length) 714 change_output_section (&(output_sec->children.head), s, upper, output_sec); 715 else 716 *lower_size += s->size; 717 end: 718 free (either_name); 719} 720 721/* This function is similar to lang_relax_sections, but without the size 722 evaluation code that is always executed after relaxation. */ 723static void 724intermediate_relax_sections (void) 725{ 726 int i = link_info.relax_pass; 727 728 /* The backend can use it to determine the current pass. */ 729 link_info.relax_pass = 0; 730 731 while (i--) 732 { 733 bool relax_again; 734 735 link_info.relax_trip = -1; 736 do 737 { 738 link_info.relax_trip++; 739 740 lang_do_assignments (lang_assigning_phase_enum); 741 742 lang_reset_memory_regions (); 743 744 relax_again = false; 745 lang_size_sections (&relax_again, false); 746 } 747 while (relax_again); 748 749 link_info.relax_pass++; 750 } 751} 752 753static void 754msp430_elf_after_allocation (void) 755{ 756 int relax_count = 0; 757 unsigned int i; 758 /* Go over each section twice, once to place either sections that don't fit 759 in lower into upper, and then again to move any sections in upper that 760 fit in lower into lower. */ 761 for (i = 0; i < 8; i++) 762 { 763 int placement_stage = (i < 4) ? LOWER_TO_UPPER : UPPER_TO_LOWER; 764 const char * base_sec_name; 765 lang_output_section_statement_type * upper; 766 767 switch (i % 4) 768 { 769 default: 770 case 0: 771 base_sec_name = ".text"; 772 break; 773 case 1: 774 base_sec_name = ".data"; 775 break; 776 case 2: 777 base_sec_name = ".bss"; 778 break; 779 case 3: 780 base_sec_name = ".rodata"; 781 break; 782 } 783 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL)); 784 if (upper != NULL) 785 { 786 /* Can't just use one iteration over the all the sections to make 787 both lower->upper and upper->lower transformations because the 788 iterator encounters upper sections before all lower sections have 789 been examined. */ 790 bfd *abfd; 791 792 if (placement_stage == LOWER_TO_UPPER) 793 { 794 /* Perform relaxation and get the final size of sections 795 before trying to fit .either sections in the correct 796 ouput sections. */ 797 if (relax_count == 0) 798 { 799 intermediate_relax_sections (); 800 relax_count++; 801 } 802 for (abfd = link_info.input_bfds; abfd != NULL; 803 abfd = abfd->link.next) 804 { 805 bfd_map_over_sections (abfd, eval_lower_either_sections, 806 (void *) base_sec_name); 807 } 808 } 809 else if (placement_stage == UPPER_TO_LOWER) 810 { 811 /* Relax again before moving upper->lower. */ 812 if (relax_count == 1) 813 { 814 intermediate_relax_sections (); 815 relax_count++; 816 } 817 for (abfd = link_info.input_bfds; abfd != NULL; 818 abfd = abfd->link.next) 819 { 820 bfd_map_over_sections (abfd, eval_upper_either_sections, 821 (void *) base_sec_name); 822 } 823 } 824 825 } 826 } 827 gld${EMULATION_NAME}_after_allocation (); 828} 829 830/* Return TRUE if a non-debug input section in L has positive size and matches 831 the given name. */ 832static int 833input_section_exists (lang_statement_union_type * l, const char * name) 834{ 835 while (l != NULL) 836 { 837 switch (l->header.type) 838 { 839 case lang_input_section_enum: 840 if ((l->input_section.section->flags & SEC_ALLOC) 841 && l->input_section.section->size > 0 842 && !strcmp (l->input_section.section->name, name)) 843 return true; 844 break; 845 846 case lang_wild_statement_enum: 847 if (input_section_exists (l->wild_statement.children.head, name)) 848 return true; 849 break; 850 851 default: 852 break; 853 } 854 l = l->header.next; 855 } 856 return false; 857} 858 859/* Some MSP430 linker scripts do not include ALIGN directives to ensure 860 __preinit_array_start, __init_array_start or __fini_array_start are word 861 aligned. 862 If __*_array_start symbols are not word aligned, the code in crt0 to run 863 through the array and call the functions will crash. 864 To avoid warning unnecessarily when the .*_array sections are not being 865 used for running constructors/destructors, only emit the warning if 866 the associated section exists and has size. */ 867static void 868check_array_section_alignment (void) 869{ 870 int i; 871 lang_output_section_statement_type * rodata_sec; 872 lang_output_section_statement_type * rodata2_sec; 873 const char * array_names[3][2] = { { ".init_array", "__init_array_start" }, 874 { ".preinit_array", "__preinit_array_start" }, 875 { ".fini_array", "__fini_array_start" } }; 876 877 /* .{preinit,init,fini}_array could be in either .rodata or .rodata2. */ 878 rodata_sec = lang_output_section_find (".rodata"); 879 rodata2_sec = lang_output_section_find (".rodata2"); 880 if (rodata_sec == NULL && rodata2_sec == NULL) 881 return; 882 883 /* There are 3 .*_array sections which must be checked for alignment. */ 884 for (i = 0; i < 3; i++) 885 { 886 struct bfd_link_hash_entry * sym; 887 if (((rodata_sec && input_section_exists (rodata_sec->children.head, 888 array_names[i][0])) 889 || (rodata2_sec && input_section_exists (rodata2_sec->children.head, 890 array_names[i][0]))) 891 && (sym = bfd_link_hash_lookup (link_info.hash, array_names[i][1], 892 false, false, true)) 893 && sym->type == bfd_link_hash_defined 894 && sym->u.def.value % 2) 895 { 896 einfo ("%P: warning: \"%s\" symbol (%pU) is not word aligned\n", 897 array_names[i][1], NULL); 898 } 899 } 900} 901 902static void 903gld${EMULATION_NAME}_finish (void) 904{ 905 finish_default (); 906 check_array_section_alignment (); 907} 908EOF 909 910LDEMUL_AFTER_OPEN=msp430_elf_after_open 911LDEMUL_AFTER_ALLOCATION=msp430_elf_after_allocation 912LDEMUL_PLACE_ORPHAN=${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan} 913LDEMUL_FINISH=gld${EMULATION_NAME}_finish 914LDEMUL_ADD_OPTIONS=gld${EMULATION_NAME}_add_options 915LDEMUL_HANDLE_OPTION=gld${EMULATION_NAME}_handle_option 916LDEMUL_LIST_OPTIONS=gld${EMULATION_NAME}_list_options 917 918source_em ${srcdir}/emultempl/emulation.em 919# 920# Local Variables: 921# mode: c 922# End: 923