1# This shell script emits a C file. -*- C -*- 2# Copyright 2003 3# Free Software Foundation, Inc. 4# 5# This file is part of GLD, the Gnu Linker. 6# 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 2 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program; if not, write to the Free Software 19# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20# 21 22# This file is sourced from elf32.em, and defines extra xtensa-elf 23# specific routines. 24# 25cat >>e${EMULATION_NAME}.c <<EOF 26 27#include <xtensa-config.h> 28 29static void xtensa_wild_group_interleave (lang_statement_union_type *); 30static void xtensa_colocate_output_literals (lang_statement_union_type *); 31 32 33/* Flag for the emulation-specific "--no-relax" option. */ 34static bfd_boolean disable_relaxation = FALSE; 35 36/* This number is irrelevant until we turn on use_literal_pages */ 37static bfd_vma xtensa_page_power = 12; /* 4K pages. */ 38 39/* To force a page break between literals and text, change 40 xtensa_use_literal_pages to "true". */ 41static bfd_boolean xtensa_use_literal_pages = FALSE; 42 43#define EXTRA_VALIDATION 0 44 45 46static char * 47elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED, 48 char **argv ATTRIBUTE_UNUSED) 49{ 50 if (XCHAL_HAVE_BE) 51 return "${BIG_OUTPUT_FORMAT}"; 52 else 53 return "${LITTLE_OUTPUT_FORMAT}"; 54} 55 56 57static bfd_boolean 58elf_xtensa_place_orphan (lang_input_statement_type *file, asection *s) 59{ 60 /* Early exit for relocatable links. */ 61 if (link_info.relocatable) 62 return FALSE; 63 64 return gld${EMULATION_NAME}_place_orphan (file, s); 65} 66 67 68static void 69elf_xtensa_before_parse (void) 70{ 71 /* Just call the default hook.... Tensilica's version of this function 72 does some other work that isn't relevant here. */ 73 gld${EMULATION_NAME}_before_parse (); 74} 75 76 77/* This is called after the sections have been attached to output 78 sections, but before any sizes or addresses have been set. */ 79 80static void 81elf_xtensa_before_allocation (void) 82{ 83 bfd *in_bfd; 84 bfd_boolean is_big_endian = XCHAL_HAVE_BE; 85 86 /* Check that the output endianness matches the Xtensa 87 configuration. The BFD library always includes both big and 88 little endian target vectors for Xtensa, but it only supports the 89 detailed instruction encode/decode operations (such as are 90 required to process relocations) for the selected Xtensa 91 configuration. */ 92 93 if (is_big_endian && output_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE) 94 { 95 einfo (_("%F%P: little endian output does not match " 96 "Xtensa configuration\n")); 97 } 98 if (!is_big_endian && output_bfd->xvec->byteorder == BFD_ENDIAN_BIG) 99 { 100 einfo (_("%F%P: big endian output does not match " 101 "Xtensa configuration\n")); 102 } 103 104 /* Check that the endianness for each input file matches the output. 105 The merge_private_bfd_data hook has already reported any mismatches 106 as errors, but those errors are not fatal. At this point, we 107 cannot go any further if there are any mismatches. */ 108 109 for (in_bfd = link_info.input_bfds; 110 in_bfd != NULL; 111 in_bfd = in_bfd->link_next) 112 { 113 if ((is_big_endian && in_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE) 114 || (!is_big_endian && in_bfd->xvec->byteorder == BFD_ENDIAN_BIG)) 115 einfo (_("%F%P: cross-endian linking not supported\n")); 116 } 117 118 /* Enable relaxation by default if the "--no-relax" option was not 119 specified. This is done here instead of in the before_parse hook 120 because there is a check in main() to prohibit use of --relax and 121 -r together and that combination should be allowed for Xtensa. */ 122 123 if (!disable_relaxation) 124 command_line.relax = TRUE; 125 126 gld${EMULATION_NAME}_before_allocation (); 127 128 xtensa_wild_group_interleave (stat_ptr->head); 129 if (command_line.relax) 130 xtensa_colocate_output_literals (stat_ptr->head); 131 132 /* TBD: We need to force the page alignments to here and only do 133 them as needed for the entire output section. Finally, if this 134 is a relocatable link then we need to add alignment notes so 135 that the literals can be separated later. */ 136} 137 138 139typedef struct wildcard_list section_name_list; 140 141typedef struct reloc_deps_e_t reloc_deps_e; 142typedef struct reloc_deps_section_t reloc_deps_section; 143typedef struct reloc_deps_graph_t reloc_deps_graph; 144 145 146struct reloc_deps_e_t 147{ 148 asection *src; /* Contains l32rs. */ 149 asection *tgt; /* Contains literals. */ 150 reloc_deps_e *next; 151}; 152 153/* Place these in the userdata field. */ 154struct reloc_deps_section_t 155{ 156 reloc_deps_e *preds; 157 reloc_deps_e *succs; 158 bfd_boolean is_only_literal; 159}; 160 161 162struct reloc_deps_graph_t 163{ 164 size_t count; 165 size_t size; 166 asection **sections; 167}; 168 169static void xtensa_layout_wild 170 (const reloc_deps_graph *, lang_wild_statement_type *); 171 172typedef void (*deps_callback_t) (asection *, /* src_sec */ 173 bfd_vma, /* src_offset */ 174 asection *, /* target_sec */ 175 bfd_vma, /* target_offset */ 176 void *); /* closure */ 177 178extern bfd_boolean xtensa_callback_required_dependence 179 (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *); 180static void xtensa_ldlang_clear_addresses 181 (lang_statement_union_type *); 182static bfd_boolean ld_local_file_relocations_fit 183 (lang_statement_union_type *, const reloc_deps_graph *); 184static bfd_vma ld_assign_relative_paged_dot 185 (bfd_vma, lang_statement_union_type *, const reloc_deps_graph *, 186 bfd_boolean); 187static bfd_vma ld_xtensa_insert_page_offsets 188 (bfd_vma, lang_statement_union_type *, reloc_deps_graph *, bfd_boolean); 189#if EXTRA_VALIDATION 190static size_t ld_count_children 191 (lang_statement_union_type *); 192#endif 193 194extern lang_statement_list_type constructor_list; 195 196/* Begin verbatim code from ldlang.c: 197 the following are copied from ldlang.c because they are defined 198 there statically. */ 199 200static void 201lang_for_each_statement_worker (void (*func) (lang_statement_union_type *), 202 lang_statement_union_type *s) 203{ 204 for (; s != (lang_statement_union_type *) NULL; s = s->header.next) 205 { 206 func (s); 207 208 switch (s->header.type) 209 { 210 case lang_constructors_statement_enum: 211 lang_for_each_statement_worker (func, constructor_list.head); 212 break; 213 case lang_output_section_statement_enum: 214 lang_for_each_statement_worker 215 (func, 216 s->output_section_statement.children.head); 217 break; 218 case lang_wild_statement_enum: 219 lang_for_each_statement_worker 220 (func, 221 s->wild_statement.children.head); 222 break; 223 case lang_group_statement_enum: 224 lang_for_each_statement_worker (func, 225 s->group_statement.children.head); 226 break; 227 case lang_data_statement_enum: 228 case lang_reloc_statement_enum: 229 case lang_object_symbols_statement_enum: 230 case lang_output_statement_enum: 231 case lang_target_statement_enum: 232 case lang_input_section_enum: 233 case lang_input_statement_enum: 234 case lang_assignment_statement_enum: 235 case lang_padding_statement_enum: 236 case lang_address_statement_enum: 237 case lang_fill_statement_enum: 238 break; 239 default: 240 FAIL (); 241 break; 242 } 243 } 244} 245 246/* End of verbatim code from ldlang.c. */ 247 248 249static reloc_deps_section * 250xtensa_get_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 251 asection *sec) 252{ 253 /* We have a separate function for this so that 254 we could in the future keep a completely independent 255 structure that maps a section to its dependence edges. 256 For now, we place these in the sec->userdata field. */ 257 reloc_deps_section *sec_deps = sec->userdata; 258 return sec_deps; 259} 260 261static void 262xtensa_set_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 263 asection *sec, 264 reloc_deps_section *deps_section) 265{ 266 sec->userdata = deps_section; 267} 268 269 270/* This is used to keep a list of all of the sections participating in 271 the graph so we can clean them up quickly. */ 272 273static void 274xtensa_append_section_deps (reloc_deps_graph *deps, asection *sec) 275{ 276 if (deps->size <= deps->count) 277 { 278 asection **new_sections; 279 size_t i; 280 size_t new_size; 281 282 new_size = deps->size * 2; 283 if (new_size == 0) 284 new_size = 20; 285 286 new_sections = xmalloc (sizeof (asection *) * new_size); 287 memset (new_sections, 0, sizeof (asection *) * new_size); 288 for (i = 0; i < deps->count; i++) 289 { 290 new_sections[i] = deps->sections[i]; 291 } 292 if (deps->sections != NULL) 293 free (deps->sections); 294 deps->sections = new_sections; 295 deps->size = new_size; 296 } 297 deps->sections[deps->count] = sec; 298 deps->count++; 299} 300 301 302static void 303free_reloc_deps_graph (reloc_deps_graph *deps) 304{ 305 size_t i; 306 for (i = 0; i < deps->count; i++) 307 { 308 asection *sec = deps->sections[i]; 309 reloc_deps_section *sec_deps; 310 sec_deps = xtensa_get_section_deps (deps, sec); 311 if (sec_deps) 312 { 313 reloc_deps_e *next; 314 while (sec_deps->succs != NULL) 315 { 316 next = sec_deps->succs->next; 317 free (sec_deps->succs); 318 sec_deps->succs = next; 319 } 320 321 while (sec_deps->preds != NULL) 322 { 323 next = sec_deps->preds->next; 324 free (sec_deps->preds); 325 sec_deps->preds = next; 326 } 327 free (sec_deps); 328 } 329 xtensa_set_section_deps (deps, sec, NULL); 330 } 331 if (deps->sections) 332 free (deps->sections); 333 334 free (deps); 335} 336 337 338static bfd_boolean 339section_is_source (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 340 lang_statement_union_type *s) 341{ 342 asection *sec; 343 const reloc_deps_section *sec_deps; 344 345 if (s->header.type != lang_input_section_enum) 346 return FALSE; 347 sec = s->input_section.section; 348 349 sec_deps = xtensa_get_section_deps (deps, sec); 350 return sec_deps && sec_deps->succs != NULL; 351} 352 353 354static bfd_boolean 355section_is_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 356 lang_statement_union_type *s) 357{ 358 asection *sec; 359 const reloc_deps_section *sec_deps; 360 361 if (s->header.type != lang_input_section_enum) 362 return FALSE; 363 sec = s->input_section.section; 364 365 sec_deps = xtensa_get_section_deps (deps, sec); 366 return sec_deps && sec_deps->preds != NULL; 367} 368 369static bfd_boolean 370section_is_source_or_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 371 lang_statement_union_type *s) 372{ 373 return (section_is_source (deps, s) 374 || section_is_target (deps, s)); 375} 376 377 378typedef struct xtensa_ld_iter_stack_t xtensa_ld_iter_stack; 379typedef struct xtensa_ld_iter_t xtensa_ld_iter; 380 381struct xtensa_ld_iter_t 382{ 383 lang_statement_union_type *parent; /* Parent of the list. */ 384 lang_statement_list_type *l; /* List that holds it. */ 385 lang_statement_union_type **loc; /* Place in the list. */ 386}; 387 388struct xtensa_ld_iter_stack_t 389{ 390 xtensa_ld_iter iterloc; /* List that hold it. */ 391 392 xtensa_ld_iter_stack *next; /* Next in the stack. */ 393 xtensa_ld_iter_stack *prev; /* Back pointer for stack. */ 394}; 395 396 397static void 398ld_xtensa_move_section_after (xtensa_ld_iter *to, xtensa_ld_iter *current) 399{ 400 lang_statement_union_type *to_next; 401 lang_statement_union_type *current_next; 402 lang_statement_union_type **e; 403 404#if EXTRA_VALIDATION 405 size_t old_to_count, new_to_count; 406 size_t old_current_count, new_current_count; 407#endif 408 409 if (to == current) 410 return; 411 412#if EXTRA_VALIDATION 413 old_to_count = ld_count_children (to->parent); 414 old_current_count = ld_count_children (current->parent); 415#endif 416 417 to_next = *(to->loc); 418 current_next = (*current->loc)->header.next; 419 420 *(to->loc) = *(current->loc); 421 422 *(current->loc) = current_next; 423 (*(to->loc))->header.next = to_next; 424 425 /* reset "to" list tail */ 426 for (e = &to->l->head; *e != NULL; e = &(*e)->header.next) 427 ; 428 to->l->tail = e; 429 430 /* reset "current" list tail */ 431 for (e = ¤t->l->head; *e != NULL; e = &(*e)->header.next) 432 ; 433 current->l->tail = e; 434 435#if EXTRA_VALIDATION 436 new_to_count = ld_count_children (to->parent); 437 new_current_count = ld_count_children (current->parent); 438 439 ASSERT ((old_to_count + old_current_count) 440 == (new_to_count + new_current_count)); 441#endif 442} 443 444 445/* Can only be called with lang_statements that have lists. Returns 446 false if the list is empty. */ 447 448static bfd_boolean 449iter_stack_empty (xtensa_ld_iter_stack **stack_p) 450{ 451 return *stack_p == NULL; 452} 453 454 455static bfd_boolean 456iter_stack_push (xtensa_ld_iter_stack **stack_p, 457 lang_statement_union_type *parent) 458{ 459 xtensa_ld_iter_stack *stack; 460 lang_statement_list_type *l = NULL; 461 462 switch (parent->header.type) 463 { 464 case lang_output_section_statement_enum: 465 l = &parent->output_section_statement.children; 466 break; 467 case lang_wild_statement_enum: 468 l = &parent->wild_statement.children; 469 break; 470 case lang_group_statement_enum: 471 l = &parent->group_statement.children; 472 break; 473 default: 474 ASSERT (0); 475 return FALSE; 476 } 477 478 /* Empty. do not push. */ 479 if (l->tail == &l->head) 480 return FALSE; 481 482 stack = xmalloc (sizeof (xtensa_ld_iter_stack)); 483 memset (stack, 0, sizeof (xtensa_ld_iter_stack)); 484 stack->iterloc.parent = parent; 485 stack->iterloc.l = l; 486 stack->iterloc.loc = &l->head; 487 488 stack->next = *stack_p; 489 stack->prev = NULL; 490 if (*stack_p != NULL) 491 (*stack_p)->prev = stack; 492 *stack_p = stack; 493 return TRUE; 494} 495 496 497static void 498iter_stack_pop (xtensa_ld_iter_stack **stack_p) 499{ 500 xtensa_ld_iter_stack *stack; 501 502 stack = *stack_p; 503 504 if (stack == NULL) 505 { 506 ASSERT (stack != NULL); 507 return; 508 } 509 510 if (stack->next != NULL) 511 stack->next->prev = NULL; 512 513 *stack_p = stack->next; 514 free (stack); 515} 516 517 518/* This MUST be called if, during iteration, the user changes the 519 underlying structure. It will check for a NULL current and advance 520 accordingly. */ 521 522static void 523iter_stack_update (xtensa_ld_iter_stack **stack_p) 524{ 525 if (!iter_stack_empty (stack_p) 526 && (*(*stack_p)->iterloc.loc) == NULL) 527 { 528 iter_stack_pop (stack_p); 529 530 while (!iter_stack_empty (stack_p) 531 && ((*(*stack_p)->iterloc.loc)->header.next == NULL)) 532 { 533 iter_stack_pop (stack_p); 534 } 535 if (!iter_stack_empty (stack_p)) 536 (*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next; 537 } 538} 539 540 541static void 542iter_stack_next (xtensa_ld_iter_stack **stack_p) 543{ 544 xtensa_ld_iter_stack *stack; 545 lang_statement_union_type *current; 546 stack = *stack_p; 547 548 current = *stack->iterloc.loc; 549 /* If we are on the first element. */ 550 if (current != NULL) 551 { 552 switch (current->header.type) 553 { 554 case lang_output_section_statement_enum: 555 case lang_wild_statement_enum: 556 case lang_group_statement_enum: 557 /* If the list if not empty, we are done. */ 558 if (iter_stack_push (stack_p, *stack->iterloc.loc)) 559 return; 560 /* Otherwise increment the pointer as normal. */ 561 break; 562 default: 563 break; 564 } 565 } 566 567 while (!iter_stack_empty (stack_p) 568 && ((*(*stack_p)->iterloc.loc)->header.next == NULL)) 569 { 570 iter_stack_pop (stack_p); 571 } 572 if (!iter_stack_empty (stack_p)) 573 (*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next; 574} 575 576 577static lang_statement_union_type * 578iter_stack_current (xtensa_ld_iter_stack **stack_p) 579{ 580 return *((*stack_p)->iterloc.loc); 581} 582 583 584/* The iter stack is a preorder. */ 585 586static void 587iter_stack_create (xtensa_ld_iter_stack **stack_p, 588 lang_statement_union_type *parent) 589{ 590 iter_stack_push (stack_p, parent); 591} 592 593 594static void 595iter_stack_copy_current (xtensa_ld_iter_stack **stack_p, 596 xtensa_ld_iter *front) 597{ 598 *front = (*stack_p)->iterloc; 599} 600 601 602static void 603xtensa_colocate_literals (reloc_deps_graph *deps, 604 lang_statement_union_type *statement) 605{ 606 /* Keep a stack of pointers to control iteration through the contours. */ 607 xtensa_ld_iter_stack *stack = NULL; 608 xtensa_ld_iter_stack **stack_p = &stack; 609 610 xtensa_ld_iter front; /* Location where new insertion should occur. */ 611 xtensa_ld_iter *front_p = NULL; 612 613 xtensa_ld_iter current; /* Location we are checking. */ 614 xtensa_ld_iter *current_p = NULL; 615 bfd_boolean in_literals = FALSE; 616 617 if (deps->count == 0) 618 return; 619 620#if 0 621 ld_assign_relative_paged_dot (0x100000, statement, deps, 622 xtensa_use_literal_pages); 623 624 if (!ld_local_file_relocations_fit (statement, deps)) 625 fprintf (stderr, "initial relocation placement does not fit\n"); 626 627 lang_for_each_statement_worker (xtensa_ldlang_clear_addresses, statement); 628#endif 629 630 iter_stack_create (stack_p, statement); 631 632 while (!iter_stack_empty (stack_p)) 633 { 634 bfd_boolean skip_increment = FALSE; 635 lang_statement_union_type *l = iter_stack_current (stack_p); 636 637 switch (l->header.type) 638 { 639 case lang_assignment_statement_enum: 640 /* Any assignment statement should block reordering across it. */ 641 front_p = NULL; 642 in_literals = FALSE; 643 break; 644 645 case lang_input_section_enum: 646 if (front_p == NULL) 647 { 648 in_literals = (section_is_target (deps, l) 649 && !section_is_source (deps, l)); 650 if (in_literals) 651 { 652 front_p = &front; 653 iter_stack_copy_current (stack_p, front_p); 654 } 655 } 656 else 657 { 658 bfd_boolean is_target; 659 current_p = ¤t; 660 iter_stack_copy_current (stack_p, current_p); 661 is_target = (section_is_target (deps, l) 662 && !section_is_source (deps, l)); 663 664 if (in_literals) 665 { 666 iter_stack_copy_current (stack_p, front_p); 667 if (!is_target) 668 in_literals = FALSE; 669 } 670 else 671 { 672 if (is_target) 673 { 674 /* Try to insert in place. */ 675 ld_xtensa_move_section_after (front_p, current_p); 676 ld_assign_relative_paged_dot (0x100000, 677 statement, 678 deps, 679 xtensa_use_literal_pages); 680 681 /* We use this code because it's already written. */ 682 if (!ld_local_file_relocations_fit (statement, deps)) 683 { 684 /* Move it back. */ 685 ld_xtensa_move_section_after (current_p, front_p); 686 /* Reset the literal placement. */ 687 iter_stack_copy_current (stack_p, front_p); 688 } 689 else 690 { 691 /* Move front pointer up by one. */ 692 front_p->loc = &(*front_p->loc)->header.next; 693 694 /* Do not increment the current pointer. */ 695 skip_increment = TRUE; 696 } 697 } 698 } 699 } 700 break; 701 default: 702 break; 703 } 704 705 if (!skip_increment) 706 iter_stack_next (stack_p); 707 else 708 /* Be careful to update the stack_p if it now is a null. */ 709 iter_stack_update (stack_p); 710 } 711 712 lang_for_each_statement_worker (xtensa_ldlang_clear_addresses, statement); 713} 714 715 716static void 717xtensa_move_dependencies_to_front (reloc_deps_graph *deps, 718 lang_wild_statement_type *w) 719{ 720 /* Keep a front pointer and a current pointer. */ 721 lang_statement_union_type **front; 722 lang_statement_union_type **current; 723 724 /* Walk to the end of the targets. */ 725 for (front = &w->children.head; 726 (*front != NULL) && section_is_source_or_target (deps, *front); 727 front = &(*front)->header.next) 728 ; 729 730 if (*front == NULL) 731 return; 732 733 current = &(*front)->header.next; 734 while (*current != NULL) 735 { 736 if (section_is_source_or_target (deps, *current)) 737 { 738 /* Insert in place. */ 739 xtensa_ld_iter front_iter; 740 xtensa_ld_iter current_iter; 741 742 front_iter.parent = (lang_statement_union_type *) w; 743 front_iter.l = &w->children; 744 front_iter.loc = front; 745 746 current_iter.parent = (lang_statement_union_type *) w; 747 current_iter.l = &w->children; 748 current_iter.loc = current; 749 750 ld_xtensa_move_section_after (&front_iter, ¤t_iter); 751 front = &(*front)->header.next; 752 } 753 else 754 { 755 current = &(*current)->header.next; 756 } 757 } 758} 759 760 761static bfd_boolean 762deps_has_sec_edge (const reloc_deps_graph *deps, 763 asection *src, 764 asection *tgt) 765{ 766 const reloc_deps_section *sec_deps; 767 const reloc_deps_e *sec_deps_e; 768 769 sec_deps = xtensa_get_section_deps (deps, src); 770 if (sec_deps == NULL) 771 return FALSE; 772 773 for (sec_deps_e = sec_deps->succs; 774 sec_deps_e != NULL; 775 sec_deps_e = sec_deps_e->next) 776 { 777 ASSERT (sec_deps_e->src == src); 778 if (sec_deps_e->tgt == tgt) 779 return TRUE; 780 } 781 return FALSE; 782} 783 784 785static bfd_boolean 786deps_has_edge (const reloc_deps_graph *deps, 787 lang_statement_union_type *src, 788 lang_statement_union_type *tgt) 789{ 790 if (!section_is_source (deps, src)) 791 return FALSE; 792 if (!section_is_target (deps, tgt)) 793 return FALSE; 794 795 if (src->header.type != lang_input_section_enum) 796 return FALSE; 797 if (tgt->header.type != lang_input_section_enum) 798 return FALSE; 799 800 return deps_has_sec_edge (deps, src->input_section.section, 801 tgt->input_section.section); 802} 803 804 805static void 806add_deps_edge (reloc_deps_graph *deps, 807 asection *src_sec, 808 asection *tgt_sec) 809{ 810 reloc_deps_section *src_sec_deps; 811 reloc_deps_section *tgt_sec_deps; 812 813 reloc_deps_e *src_edge; 814 reloc_deps_e *tgt_edge; 815 816 if (deps_has_sec_edge (deps, src_sec, tgt_sec)) 817 return; 818 819 src_sec_deps = xtensa_get_section_deps (deps, src_sec); 820 if (src_sec_deps == NULL) 821 { 822 /* Add a section. */ 823 src_sec_deps = xmalloc (sizeof (reloc_deps_section)); 824 memset (src_sec_deps, 0, sizeof (reloc_deps_section)); 825 src_sec_deps->is_only_literal = 0; 826 src_sec_deps->preds = NULL; 827 src_sec_deps->succs = NULL; 828 xtensa_set_section_deps (deps, src_sec, src_sec_deps); 829 xtensa_append_section_deps (deps, src_sec); 830 } 831 832 tgt_sec_deps = xtensa_get_section_deps (deps, tgt_sec); 833 if (tgt_sec_deps == NULL) 834 { 835 /* Add a section. */ 836 tgt_sec_deps = xmalloc (sizeof (reloc_deps_section)); 837 memset (tgt_sec_deps, 0, sizeof (reloc_deps_section)); 838 tgt_sec_deps->is_only_literal = 0; 839 tgt_sec_deps->preds = NULL; 840 tgt_sec_deps->succs = NULL; 841 xtensa_set_section_deps (deps, tgt_sec, tgt_sec_deps); 842 xtensa_append_section_deps (deps, tgt_sec); 843 } 844 845 /* Add the edges. */ 846 src_edge = xmalloc (sizeof (reloc_deps_e)); 847 memset (src_edge, 0, sizeof (reloc_deps_e)); 848 src_edge->src = src_sec; 849 src_edge->tgt = tgt_sec; 850 src_edge->next = src_sec_deps->succs; 851 src_sec_deps->succs = src_edge; 852 853 tgt_edge = xmalloc (sizeof (reloc_deps_e)); 854 memset (tgt_edge, 0, sizeof (reloc_deps_e)); 855 tgt_edge->src = src_sec; 856 tgt_edge->tgt = tgt_sec; 857 tgt_edge->next = tgt_sec_deps->preds; 858 tgt_sec_deps->preds = tgt_edge; 859} 860 861 862static void 863build_deps_graph_callback (asection *src_sec, 864 bfd_vma src_offset ATTRIBUTE_UNUSED, 865 asection *target_sec, 866 bfd_vma target_offset ATTRIBUTE_UNUSED, 867 void *closure) 868{ 869 reloc_deps_graph *deps = closure; 870 871 /* If the target is defined. */ 872 if (target_sec != NULL) 873 add_deps_edge (deps, src_sec, target_sec); 874} 875 876 877static reloc_deps_graph * 878ld_build_required_section_dependence (lang_statement_union_type *s) 879{ 880 reloc_deps_graph *deps; 881 xtensa_ld_iter_stack *stack = NULL; 882 883 deps = xmalloc (sizeof (reloc_deps_graph)); 884 deps->sections = NULL; 885 deps->count = 0; 886 deps->size = 0; 887 888 for (iter_stack_create (&stack, s); 889 !iter_stack_empty (&stack); 890 iter_stack_next (&stack)) 891 { 892 lang_statement_union_type *l = iter_stack_current (&stack); 893 894 if (l->header.type == lang_input_section_enum) 895 { 896 lang_input_section_type *input; 897 input = &l->input_section; 898 xtensa_callback_required_dependence (input->ifile->the_bfd, 899 input->section, 900 &link_info, 901 /* Use the same closure. */ 902 build_deps_graph_callback, 903 deps); 904 } 905 } 906 return deps; 907} 908 909 910#if EXTRA_VALIDATION 911static size_t 912ld_count_children (lang_statement_union_type *s) 913{ 914 size_t count = 0; 915 xtensa_ld_iter_stack *stack = NULL; 916 for (iter_stack_create (&stack, s); 917 !iter_stack_empty (&stack); 918 iter_stack_next (&stack)) 919 { 920 lang_statement_union_type *l = iter_stack_current (&stack); 921 ASSERT (l != NULL); 922 count++; 923 } 924 return count; 925} 926#endif /* EXTRA_VALIDATION */ 927 928 929static void 930xtensa_wild_group_interleave_callback (lang_statement_union_type *statement) 931{ 932 lang_wild_statement_type *w; 933 reloc_deps_graph *deps; 934 if (statement->header.type == lang_wild_statement_enum) 935 { 936#if EXTRA_VALIDATION 937 size_t old_child_count; 938 size_t new_child_count; 939#endif 940 bfd_boolean no_reorder; 941 942 w = &statement->wild_statement; 943 944 no_reorder = FALSE; 945 946 /* If it has 0 or 1 section bound, then do not reorder. */ 947 if (w->children.head == NULL 948 || (w->children.head->header.type == lang_input_section_enum 949 && w->children.head->header.next == NULL)) 950 no_reorder = TRUE; 951 952 if (w->filenames_sorted) 953 no_reorder = TRUE; 954 955 /* Check for sorting in a section list wildcard spec as well. */ 956 if (!no_reorder) 957 { 958 struct wildcard_list *l; 959 for (l = w->section_list; l != NULL; l = l->next) 960 { 961 if (l->spec.sorted == TRUE) 962 { 963 no_reorder = TRUE; 964 break; 965 } 966 } 967 } 968 969 /* Special case until the NOREORDER linker directive is supported: 970 *(.init) output sections and *(.fini) specs may NOT be reordered. */ 971 972 /* Check for sorting in a section list wildcard spec as well. */ 973 if (!no_reorder) 974 { 975 struct wildcard_list *l; 976 for (l = w->section_list; l != NULL; l = l->next) 977 { 978 if (l->spec.name 979 && ((strcmp (".init", l->spec.name) == 0) 980 || (strcmp (".fini", l->spec.name) == 0))) 981 { 982 no_reorder = TRUE; 983 break; 984 } 985 } 986 } 987 988#if EXTRA_VALIDATION 989 old_child_count = ld_count_children (statement); 990#endif 991 992 /* It is now officially a target. Build the graph of source 993 section -> target section (kept as a list of edges). */ 994 deps = ld_build_required_section_dependence (statement); 995 996 /* If this wildcard does not reorder.... */ 997 if (!no_reorder && deps->count != 0) 998 { 999 /* First check for reverse dependences. Fix if possible. */ 1000 xtensa_layout_wild (deps, w); 1001 1002 xtensa_move_dependencies_to_front (deps, w); 1003#if EXTRA_VALIDATION 1004 new_child_count = ld_count_children (statement); 1005 ASSERT (new_child_count == old_child_count); 1006#endif 1007 1008 xtensa_colocate_literals (deps, statement); 1009 1010#if EXTRA_VALIDATION 1011 new_child_count = ld_count_children (statement); 1012 ASSERT (new_child_count == old_child_count); 1013#endif 1014 } 1015 1016 /* Clean up. */ 1017 free_reloc_deps_graph (deps); 1018 } 1019} 1020 1021 1022static void 1023xtensa_wild_group_interleave (lang_statement_union_type *s) 1024{ 1025 lang_for_each_statement_worker (xtensa_wild_group_interleave_callback, s); 1026} 1027 1028 1029static void 1030xtensa_layout_wild (const reloc_deps_graph *deps, 1031 lang_wild_statement_type *w) 1032{ 1033 /* If it does not fit initially, we need to do this step. Move all 1034 of the wild literal sections to a new list, then move each of 1035 them back in just before the first section they depend on. */ 1036 lang_statement_union_type **s_p; 1037#if EXTRA_VALIDATION 1038 size_t old_count, new_count; 1039 size_t ct1, ct2; 1040#endif 1041 1042 lang_wild_statement_type literal_wild; 1043 literal_wild.header.next = NULL; 1044 literal_wild.header.type = lang_wild_statement_enum; 1045 literal_wild.filename = NULL; 1046 literal_wild.filenames_sorted = FALSE; 1047 literal_wild.section_list = NULL; 1048 literal_wild.keep_sections = FALSE; 1049 literal_wild.children.head = NULL; 1050 literal_wild.children.tail = &literal_wild.children.head; 1051 1052#if EXTRA_VALIDATION 1053 old_count = ld_count_children ((lang_statement_union_type*) w); 1054#endif 1055 1056 s_p = &w->children.head; 1057 while (*s_p != NULL) 1058 { 1059 lang_statement_union_type *l = *s_p; 1060 if (l->header.type == lang_input_section_enum) 1061 { 1062 if (section_is_target (deps, l) 1063 && ! section_is_source (deps, l)) 1064 { 1065 /* Detach. */ 1066 *s_p = l->header.next; 1067 if (*s_p == NULL) 1068 w->children.tail = s_p; 1069 l->header.next = NULL; 1070 1071 /* Append. */ 1072 *literal_wild.children.tail = l; 1073 literal_wild.children.tail = &l->header.next; 1074 continue; 1075 } 1076 } 1077 s_p = &(*s_p)->header.next; 1078 } 1079 1080#if EXTRA_VALIDATION 1081 ct1 = ld_count_children ((lang_statement_union_type*) w); 1082 ct2 = ld_count_children ((lang_statement_union_type*) &literal_wild); 1083 1084 ASSERT (old_count == (ct1 + ct2)); 1085#endif 1086 1087 /* Now place them back in front of their dependent sections. */ 1088 1089 while (literal_wild.children.head != NULL) 1090 { 1091 lang_statement_union_type *lit = literal_wild.children.head; 1092 bfd_boolean placed = FALSE; 1093 1094#if EXTRA_VALIDATION 1095 ASSERT (ct2 > 0); 1096 ct2--; 1097#endif 1098 1099 /* Detach. */ 1100 literal_wild.children.head = lit->header.next; 1101 if (literal_wild.children.head == NULL) 1102 literal_wild.children.tail = &literal_wild.children.head; 1103 lit->header.next = NULL; 1104 1105 /* Find a spot to place it. */ 1106 for (s_p = &w->children.head; *s_p != NULL; s_p = &(*s_p)->header.next) 1107 { 1108 lang_statement_union_type *src = *s_p; 1109 if (deps_has_edge (deps, src, lit)) 1110 { 1111 /* Place it here. */ 1112 lit->header.next = *s_p; 1113 *s_p = lit; 1114 placed = TRUE; 1115 break; 1116 } 1117 } 1118 1119 if (!placed) 1120 { 1121 /* Put it at the end. */ 1122 *w->children.tail = lit; 1123 w->children.tail = &lit->header.next; 1124 } 1125 } 1126 1127#if EXTRA_VALIDATION 1128 new_count = ld_count_children ((lang_statement_union_type*) w); 1129 ASSERT (new_count == old_count); 1130#endif 1131} 1132 1133 1134static void 1135xtensa_colocate_output_literals_callback (lang_statement_union_type *statement) 1136{ 1137 lang_output_section_statement_type *os; 1138 reloc_deps_graph *deps; 1139 if (statement->header.type == lang_output_section_statement_enum) 1140 { 1141 /* Now, we walk over the contours of the output section statement. 1142 1143 First we build the literal section dependences as before. 1144 1145 At the first uniquely_literal section, we mark it as a good 1146 spot to place other literals. Continue walking (and counting 1147 sizes) until we find the next literal section. If this 1148 section can be moved to the first one, then we move it. If 1149 we every find a modification of ".", start over. If we find 1150 a labeling of the current location, start over. Finally, at 1151 the end, if we require page alignment, add page alignments. */ 1152 1153#if EXTRA_VALIDATION 1154 size_t old_child_count; 1155 size_t new_child_count; 1156#endif 1157 bfd_boolean no_reorder = FALSE; 1158 1159 os = &statement->output_section_statement; 1160 1161#if EXTRA_VALIDATION 1162 old_child_count = ld_count_children (statement); 1163#endif 1164 1165 /* It is now officially a target. Build the graph of source 1166 section -> target section (kept as a list of edges). */ 1167 1168 deps = ld_build_required_section_dependence (statement); 1169 1170 /* If this wildcard does not reorder.... */ 1171 if (!no_reorder) 1172 { 1173 /* First check for reverse dependences. Fix if possible. */ 1174 xtensa_colocate_literals (deps, statement); 1175 1176#if EXTRA_VALIDATION 1177 new_child_count = ld_count_children (statement); 1178 ASSERT (new_child_count == old_child_count); 1179#endif 1180 } 1181 1182 /* Insert align/offset assignment statement. */ 1183 if (xtensa_use_literal_pages) 1184 { 1185 ld_xtensa_insert_page_offsets (0, statement, deps, 1186 xtensa_use_literal_pages); 1187 lang_for_each_statement_worker (xtensa_ldlang_clear_addresses, 1188 statement); 1189 } 1190 1191 /* Clean up. */ 1192 free_reloc_deps_graph (deps); 1193 } 1194} 1195 1196 1197static void 1198xtensa_colocate_output_literals (lang_statement_union_type *s) 1199{ 1200 lang_for_each_statement_worker (xtensa_colocate_output_literals_callback, s); 1201} 1202 1203 1204static void 1205xtensa_ldlang_clear_addresses (lang_statement_union_type *statement) 1206{ 1207 switch (statement->header.type) 1208 { 1209 case lang_input_section_enum: 1210 { 1211 asection *bfd_section = statement->input_section.section; 1212 bfd_section->output_offset = 0; 1213 } 1214 break; 1215 default: 1216 break; 1217 } 1218} 1219 1220 1221static bfd_vma 1222ld_assign_relative_paged_dot (bfd_vma dot, 1223 lang_statement_union_type *s, 1224 const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 1225 bfd_boolean lit_align) 1226{ 1227 /* Walk through all of the input statements in this wild statement 1228 assign dot to all of them. */ 1229 1230 xtensa_ld_iter_stack *stack = NULL; 1231 xtensa_ld_iter_stack **stack_p = &stack; 1232 1233 bfd_boolean first_section = FALSE; 1234 bfd_boolean in_literals = FALSE; 1235 1236 for (iter_stack_create (stack_p, s); 1237 !iter_stack_empty (stack_p); 1238 iter_stack_next (stack_p)) 1239 { 1240 lang_statement_union_type *l = iter_stack_current (stack_p); 1241 1242 switch (l->header.type) 1243 { 1244 case lang_input_section_enum: 1245 { 1246 asection *section = l->input_section.section; 1247 size_t align_pow = section->alignment_power; 1248 bfd_boolean do_xtensa_alignment = FALSE; 1249 1250 if (lit_align) 1251 { 1252 bfd_boolean sec_is_target = section_is_target (deps, l); 1253 bfd_boolean sec_is_source = section_is_source (deps, l); 1254 1255 if (section->_raw_size != 0 1256 && (first_section 1257 || (in_literals && !sec_is_target) 1258 || (!in_literals && sec_is_target))) 1259 { 1260 do_xtensa_alignment = TRUE; 1261 } 1262 first_section = FALSE; 1263 if (section->_raw_size != 0) 1264 in_literals = (sec_is_target && !sec_is_source); 1265 } 1266 1267 if (do_xtensa_alignment && xtensa_page_power != 0) 1268 dot += (1 << xtensa_page_power); 1269 1270 dot = align_power (dot, align_pow); 1271 section->output_offset = dot; 1272 dot += section->_raw_size; 1273 } 1274 break; 1275 case lang_fill_statement_enum: 1276 dot += l->fill_statement.size; 1277 break; 1278 case lang_padding_statement_enum: 1279 dot += l->padding_statement.size; 1280 break; 1281 default: 1282 break; 1283 } 1284 } 1285 return dot; 1286} 1287 1288 1289static bfd_boolean 1290ld_local_file_relocations_fit (lang_statement_union_type *statement, 1291 const reloc_deps_graph *deps ATTRIBUTE_UNUSED) 1292{ 1293 /* Walk over all of the dependencies that we identified and make 1294 sure that IF the source and target are here (addr != 0): 1295 1) target addr < source addr 1296 2) (roundup(source + source_size, 4) - rounddown(target, 4)) 1297 < (256K - (1 << bad align)) 1298 Need a worst-case proof.... */ 1299 1300 xtensa_ld_iter_stack *stack = NULL; 1301 xtensa_ld_iter_stack **stack_p = &stack; 1302 size_t max_align_power = 0; 1303 size_t align_penalty = 256; 1304 reloc_deps_e *e; 1305 size_t i; 1306 1307 /* Find the worst-case alignment requirement for this set of statements. */ 1308 for (iter_stack_create (stack_p, statement); 1309 !iter_stack_empty (stack_p); 1310 iter_stack_next (stack_p)) 1311 { 1312 lang_statement_union_type *l = iter_stack_current (stack_p); 1313 if (l->header.type == lang_input_section_enum) 1314 { 1315 lang_input_section_type *input = &l->input_section; 1316 asection *section = input->section; 1317 if (section->alignment_power > max_align_power) 1318 max_align_power = section->alignment_power; 1319 } 1320 } 1321 1322 /* Now check that everything fits. */ 1323 for (i = 0; i < deps->count; i++) 1324 { 1325 asection *sec = deps->sections[i]; 1326 const reloc_deps_section *deps_section = 1327 xtensa_get_section_deps (deps, sec); 1328 if (deps_section) 1329 { 1330 /* We choose to walk through the successors. */ 1331 for (e = deps_section->succs; e != NULL; e = e->next) 1332 { 1333 if (e->src != e->tgt 1334 && e->src->output_section == e->tgt->output_section 1335 && e->src->output_offset != 0 1336 && e->tgt->output_offset != 0) 1337 { 1338 bfd_vma l32r_addr = 1339 align_power (e->src->output_offset + e->src->_raw_size, 2); 1340 bfd_vma target_addr = e->tgt->output_offset & ~3; 1341 if (l32r_addr < target_addr) 1342 { 1343 fprintf (stderr, "Warning: " 1344 "l32r target section before l32r\n"); 1345 return FALSE; 1346 } 1347 1348 if (l32r_addr - target_addr > 256 * 1024 - align_penalty) 1349 return FALSE; 1350 } 1351 } 1352 } 1353 } 1354 1355 return TRUE; 1356} 1357 1358 1359static bfd_vma 1360ld_xtensa_insert_page_offsets (bfd_vma dot, 1361 lang_statement_union_type *s, 1362 reloc_deps_graph *deps, 1363 bfd_boolean lit_align) 1364{ 1365 xtensa_ld_iter_stack *stack = NULL; 1366 xtensa_ld_iter_stack **stack_p = &stack; 1367 1368 bfd_boolean first_section = FALSE; 1369 bfd_boolean in_literals = FALSE; 1370 1371 if (!lit_align) 1372 return FALSE; 1373 1374 for (iter_stack_create (stack_p, s); 1375 !iter_stack_empty (stack_p); 1376 iter_stack_next (stack_p)) 1377 { 1378 lang_statement_union_type *l = iter_stack_current (stack_p); 1379 1380 switch (l->header.type) 1381 { 1382 case lang_input_section_enum: 1383 { 1384 asection *section = l->input_section.section; 1385 bfd_boolean do_xtensa_alignment = FALSE; 1386 1387 if (lit_align) 1388 { 1389 if (section->_raw_size != 0 1390 && (first_section 1391 || (in_literals && !section_is_target (deps, l)) 1392 || (!in_literals && section_is_target (deps, l)))) 1393 { 1394 do_xtensa_alignment = TRUE; 1395 } 1396 first_section = FALSE; 1397 if (section->_raw_size != 0) 1398 { 1399 in_literals = (section_is_target (deps, l) 1400 && !section_is_source (deps, l)); 1401 } 1402 } 1403 1404 if (do_xtensa_alignment && xtensa_page_power != 0) 1405 { 1406 /* Create an expression that increments the current address, 1407 i.e., "dot", by (1 << xtensa_align_power). */ 1408 etree_type *name_op = exp_nameop (NAME, "."); 1409 etree_type *addend_op = exp_intop (1 << xtensa_page_power); 1410 etree_type *add_op = exp_binop ('+', name_op, addend_op); 1411 etree_type *assign_op = exp_assop ('=', ".", add_op); 1412 1413 lang_assignment_statement_type *assign_stmt; 1414 lang_statement_union_type *assign_union; 1415 lang_statement_list_type tmplist; 1416 lang_statement_list_type *old_stat_ptr = stat_ptr; 1417 1418 /* There is hidden state in "lang_add_assignment". It 1419 appends the new assignment statement to the stat_ptr 1420 list. Thus, we swap it before and after the call. */ 1421 1422 tmplist.head = NULL; 1423 tmplist.tail = &tmplist.head; 1424 1425 stat_ptr = &tmplist; 1426 /* Warning: side effect; statement appended to stat_ptr. */ 1427 assign_stmt = lang_add_assignment (assign_op); 1428 assign_union = (lang_statement_union_type *) assign_stmt; 1429 stat_ptr = old_stat_ptr; 1430 1431 assign_union->header.next = l; 1432 *(*stack_p)->iterloc.loc = assign_union; 1433 iter_stack_next (stack_p); 1434 } 1435 } 1436 break; 1437 default: 1438 break; 1439 } 1440 } 1441 return dot; 1442} 1443 1444EOF 1445 1446# Define some shell vars to insert bits of code into the standard elf 1447# parse_args and list_options functions. 1448# 1449PARSE_AND_LIST_PROLOGUE=' 1450#define OPTION_NO_RELAX 301 1451' 1452 1453PARSE_AND_LIST_LONGOPTS=' 1454 { "no-relax", no_argument, NULL, OPTION_NO_RELAX}, 1455' 1456 1457PARSE_AND_LIST_OPTIONS=' 1458 fprintf (file, _(" --no-relax\t\tDo not relax branches or coalesce literals\n")); 1459' 1460 1461PARSE_AND_LIST_ARGS_CASES=' 1462 case OPTION_NO_RELAX: 1463 disable_relaxation = TRUE; 1464 break; 1465' 1466 1467# Replace some of the standard ELF functions with our own versions. 1468# 1469LDEMUL_BEFORE_PARSE=elf_xtensa_before_parse 1470LDEMUL_CHOOSE_TARGET=elf_xtensa_choose_target 1471LDEMUL_PLACE_ORPHAN=elf_xtensa_place_orphan 1472LDEMUL_BEFORE_ALLOCATION=elf_xtensa_before_allocation 1473 1474