1# This shell script emits a C file. -*- C -*- 2# Copyright 2003, 2004, 2005, 2006 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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#include "../bfd/elf-bfd.h" 29#include "../bfd/libbfd.h" 30#include "elf/xtensa.h" 31#include "bfd.h" 32 33static void xtensa_wild_group_interleave (lang_statement_union_type *); 34static void xtensa_colocate_output_literals (lang_statement_union_type *); 35static void xtensa_strip_inconsistent_linkonce_sections 36 (lang_statement_list_type *); 37 38 39/* Flag for the emulation-specific "--no-relax" option. */ 40static bfd_boolean disable_relaxation = FALSE; 41 42/* This number is irrelevant until we turn on use_literal_pages */ 43static bfd_vma xtensa_page_power = 12; /* 4K pages. */ 44 45/* To force a page break between literals and text, change 46 xtensa_use_literal_pages to "TRUE". */ 47static bfd_boolean xtensa_use_literal_pages = FALSE; 48 49#define EXTRA_VALIDATION 0 50 51 52static char * 53elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED, 54 char **argv ATTRIBUTE_UNUSED) 55{ 56 if (XCHAL_HAVE_BE) 57 return "${BIG_OUTPUT_FORMAT}"; 58 else 59 return "${LITTLE_OUTPUT_FORMAT}"; 60} 61 62 63static void 64elf_xtensa_before_parse (void) 65{ 66 /* Just call the default hook.... Tensilica's version of this function 67 does some other work that isn't relevant here. */ 68 gld${EMULATION_NAME}_before_parse (); 69} 70 71 72static void 73remove_section (bfd *abfd, asection *os) 74{ 75 asection **spp; 76 for (spp = &abfd->sections; *spp; spp = &(*spp)->next) 77 if (*spp == os) 78 { 79 *spp = os->next; 80 os->owner->section_count--; 81 break; 82 } 83} 84 85 86static bfd_boolean 87replace_insn_sec_with_prop_sec (bfd *abfd, 88 const char *insn_sec_name, 89 const char *prop_sec_name, 90 char **error_message) 91{ 92 asection *insn_sec; 93 asection *prop_sec; 94 bfd_byte *prop_contents = NULL; 95 bfd_byte *insn_contents = NULL; 96 unsigned entry_count; 97 unsigned entry; 98 Elf_Internal_Shdr *symtab_hdr; 99 Elf_Internal_Rela *internal_relocs = NULL; 100 unsigned reloc_count; 101 102 *error_message = ""; 103 insn_sec = bfd_get_section_by_name (abfd, insn_sec_name); 104 if (insn_sec == NULL) 105 return TRUE; 106 entry_count = insn_sec->size / 8; 107 108 prop_sec = bfd_get_section_by_name (abfd, prop_sec_name); 109 if (prop_sec != NULL && insn_sec != NULL) 110 { 111 *error_message = _("file already has property tables"); 112 return FALSE; 113 } 114 115 if (insn_sec->size != 0) 116 { 117 insn_contents = (bfd_byte *) bfd_malloc (insn_sec->size); 118 if (insn_contents == NULL) 119 { 120 *error_message = _("out of memory"); 121 goto cleanup; 122 } 123 if (! bfd_get_section_contents (abfd, insn_sec, insn_contents, 124 (file_ptr) 0, insn_sec->size)) 125 { 126 *error_message = _("failed to read section contents"); 127 goto cleanup; 128 } 129 } 130 131 /* Create a Property table section and relocation section for it. */ 132 prop_sec_name = strdup (prop_sec_name); 133 prop_sec = bfd_make_section (abfd, prop_sec_name); 134 if (prop_sec == NULL 135 || ! bfd_set_section_flags (abfd, prop_sec, 136 bfd_get_section_flags (abfd, insn_sec)) 137 || ! bfd_set_section_alignment (abfd, prop_sec, 2)) 138 { 139 *error_message = _("could not create new section"); 140 goto cleanup; 141 } 142 143 if (! bfd_set_section_flags (abfd, prop_sec, 144 bfd_get_section_flags (abfd, insn_sec)) 145 || ! bfd_set_section_alignment (abfd, prop_sec, 2)) 146 { 147 *error_message = _("could not set new section properties"); 148 goto cleanup; 149 } 150 prop_sec->size = entry_count * 12; 151 prop_contents = (bfd_byte *) bfd_zalloc (abfd, prop_sec->size); 152 elf_section_data (prop_sec)->this_hdr.contents = prop_contents; 153 154 /* The entry size and size must be set to allow the linker to compute 155 the number of relocations since it does not use reloc_count. */ 156 elf_section_data (prop_sec)->rel_hdr.sh_entsize = 157 sizeof (Elf32_External_Rela); 158 elf_section_data (prop_sec)->rel_hdr.sh_size = 159 elf_section_data (insn_sec)->rel_hdr.sh_size; 160 161 if (prop_contents == NULL && prop_sec->size != 0) 162 { 163 *error_message = _("could not allocate section contents"); 164 goto cleanup; 165 } 166 167 /* Read the relocations. */ 168 reloc_count = insn_sec->reloc_count; 169 if (reloc_count != 0) 170 { 171 /* If there is already an internal_reloc, then save it so that the 172 read_relocs function freshly allocates a copy. */ 173 Elf_Internal_Rela *saved_relocs = elf_section_data (insn_sec)->relocs; 174 175 elf_section_data (insn_sec)->relocs = NULL; 176 internal_relocs = 177 _bfd_elf_link_read_relocs (abfd, insn_sec, NULL, NULL, FALSE); 178 elf_section_data (insn_sec)->relocs = saved_relocs; 179 180 if (internal_relocs == NULL) 181 { 182 *error_message = _("out of memory"); 183 goto cleanup; 184 } 185 } 186 187 /* Create a relocation section for the property section. */ 188 if (internal_relocs != NULL) 189 { 190 elf_section_data (prop_sec)->relocs = internal_relocs; 191 prop_sec->reloc_count = reloc_count; 192 } 193 194 /* Now copy each insn table entry to the prop table entry with 195 appropriate flags. */ 196 for (entry = 0; entry < entry_count; ++entry) 197 { 198 unsigned value; 199 unsigned flags = (XTENSA_PROP_INSN | XTENSA_PROP_INSN_NO_TRANSFORM 200 | XTENSA_PROP_INSN_NO_REORDER); 201 value = bfd_get_32 (abfd, insn_contents + entry * 8 + 0); 202 bfd_put_32 (abfd, value, prop_contents + entry * 12 + 0); 203 value = bfd_get_32 (abfd, insn_contents + entry * 8 + 4); 204 bfd_put_32 (abfd, value, prop_contents + entry * 12 + 4); 205 bfd_put_32 (abfd, flags, prop_contents + entry * 12 + 8); 206 } 207 208 /* Now copy all of the relocations. Change offsets for the 209 instruction table section to offsets in the property table 210 section. */ 211 if (internal_relocs) 212 { 213 unsigned i; 214 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 215 216 for (i = 0; i < reloc_count; i++) 217 { 218 Elf_Internal_Rela *rela; 219 unsigned r_offset; 220 221 rela = &internal_relocs[i]; 222 223 /* If this relocation is to the .xt.insn section, 224 change the section number and the offset. */ 225 r_offset = rela->r_offset; 226 r_offset += 4 * (r_offset / 8); 227 rela->r_offset = r_offset; 228 } 229 } 230 231 remove_section (abfd, insn_sec); 232 233 if (insn_contents) 234 free (insn_contents); 235 236 return TRUE; 237 238 cleanup: 239 if (prop_sec && prop_sec->owner) 240 remove_section (abfd, prop_sec); 241 if (insn_contents) 242 free (insn_contents); 243 if (internal_relocs) 244 free (internal_relocs); 245 246 return FALSE; 247} 248 249 250#define PROP_SEC_BASE_NAME ".xt.prop" 251#define INSN_SEC_BASE_NAME ".xt.insn" 252#define LINKONCE_SEC_OLD_TEXT_BASE_NAME ".gnu.linkonce.x." 253 254 255static void 256replace_instruction_table_sections (bfd *abfd, asection *sec) 257{ 258 char *message = ""; 259 const char *insn_sec_name = NULL; 260 char *prop_sec_name = NULL; 261 char *owned_prop_sec_name = NULL; 262 const char *sec_name; 263 264 sec_name = bfd_get_section_name (abfd, sec); 265 if (strcmp (sec_name, INSN_SEC_BASE_NAME) == 0) 266 { 267 insn_sec_name = INSN_SEC_BASE_NAME; 268 prop_sec_name = PROP_SEC_BASE_NAME; 269 } 270 else if (strncmp (sec_name, LINKONCE_SEC_OLD_TEXT_BASE_NAME, 271 strlen (LINKONCE_SEC_OLD_TEXT_BASE_NAME)) == 0) 272 { 273 insn_sec_name = sec_name; 274 owned_prop_sec_name = (char *) xmalloc (strlen (sec_name) + 20); 275 prop_sec_name = owned_prop_sec_name; 276 strcpy (prop_sec_name, ".gnu.linkonce.prop.t."); 277 strcat (prop_sec_name, 278 sec_name + strlen (LINKONCE_SEC_OLD_TEXT_BASE_NAME)); 279 } 280 if (insn_sec_name != NULL) 281 { 282 if (! replace_insn_sec_with_prop_sec (abfd, insn_sec_name, prop_sec_name, 283 &message)) 284 { 285 einfo (_("%P: warning: failed to convert %s table in %B (%s); subsequent disassembly may be incomplete\n"), 286 insn_sec_name, abfd, message); 287 } 288 } 289 if (owned_prop_sec_name) 290 free (owned_prop_sec_name); 291} 292 293 294/* This is called after all input sections have been opened to convert 295 instruction tables (.xt.insn, gnu.linkonce.x.*) tables into property 296 tables (.xt.prop) before any section placement. */ 297 298static void 299elf_xtensa_after_open (void) 300{ 301 bfd *abfd; 302 303 /* First call the ELF version. */ 304 gld${EMULATION_NAME}_after_open (); 305 306 /* Now search the input files looking for instruction table sections. */ 307 for (abfd = link_info.input_bfds; 308 abfd != NULL; 309 abfd = abfd->link_next) 310 { 311 asection *sec = abfd->sections; 312 asection *next_sec; 313 314 /* Do not use bfd_map_over_sections here since we are removing 315 sections as we iterate. */ 316 while (sec != NULL) 317 { 318 next_sec = sec->next; 319 replace_instruction_table_sections (abfd, sec); 320 sec = next_sec; 321 } 322 } 323} 324 325 326/* This is called after the sections have been attached to output 327 sections, but before any sizes or addresses have been set. */ 328 329static void 330elf_xtensa_before_allocation (void) 331{ 332 bfd *in_bfd; 333 bfd_boolean is_big_endian = XCHAL_HAVE_BE; 334 335 /* Check that the output endianness matches the Xtensa 336 configuration. The BFD library always includes both big and 337 little endian target vectors for Xtensa, but it only supports the 338 detailed instruction encode/decode operations (such as are 339 required to process relocations) for the selected Xtensa 340 configuration. */ 341 342 if (is_big_endian && output_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE) 343 { 344 einfo (_("%F%P: little endian output does not match " 345 "Xtensa configuration\n")); 346 } 347 if (!is_big_endian && output_bfd->xvec->byteorder == BFD_ENDIAN_BIG) 348 { 349 einfo (_("%F%P: big endian output does not match " 350 "Xtensa configuration\n")); 351 } 352 353 /* Check that the endianness for each input file matches the output. 354 The merge_private_bfd_data hook has already reported any mismatches 355 as errors, but those errors are not fatal. At this point, we 356 cannot go any further if there are any mismatches. */ 357 358 for (in_bfd = link_info.input_bfds; 359 in_bfd != NULL; 360 in_bfd = in_bfd->link_next) 361 { 362 if ((is_big_endian && in_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE) 363 || (!is_big_endian && in_bfd->xvec->byteorder == BFD_ENDIAN_BIG)) 364 einfo (_("%F%P: cross-endian linking not supported\n")); 365 } 366 367 /* Enable relaxation by default if the "--no-relax" option was not 368 specified. This is done here instead of in the before_parse hook 369 because there is a check in main() to prohibit use of --relax and 370 -r together and that combination should be allowed for Xtensa. */ 371 372 if (!disable_relaxation) 373 command_line.relax = TRUE; 374 375 xtensa_strip_inconsistent_linkonce_sections (stat_ptr); 376 377 gld${EMULATION_NAME}_before_allocation (); 378 379 xtensa_wild_group_interleave (stat_ptr->head); 380 if (command_line.relax) 381 xtensa_colocate_output_literals (stat_ptr->head); 382 383 /* TBD: We need to force the page alignments to here and only do 384 them as needed for the entire output section. Finally, if this 385 is a relocatable link then we need to add alignment notes so 386 that the literals can be separated later. */ 387} 388 389 390typedef struct wildcard_list section_name_list; 391 392typedef struct reloc_deps_e_t reloc_deps_e; 393typedef struct reloc_deps_section_t reloc_deps_section; 394typedef struct reloc_deps_graph_t reloc_deps_graph; 395 396 397struct reloc_deps_e_t 398{ 399 asection *src; /* Contains l32rs. */ 400 asection *tgt; /* Contains literals. */ 401 reloc_deps_e *next; 402}; 403 404/* Place these in the userdata field. */ 405struct reloc_deps_section_t 406{ 407 reloc_deps_e *preds; 408 reloc_deps_e *succs; 409 bfd_boolean is_only_literal; 410}; 411 412 413struct reloc_deps_graph_t 414{ 415 size_t count; 416 size_t size; 417 asection **sections; 418}; 419 420static void xtensa_layout_wild 421 (const reloc_deps_graph *, lang_wild_statement_type *); 422 423typedef void (*deps_callback_t) (asection *, /* src_sec */ 424 bfd_vma, /* src_offset */ 425 asection *, /* target_sec */ 426 bfd_vma, /* target_offset */ 427 void *); /* closure */ 428 429extern bfd_boolean xtensa_callback_required_dependence 430 (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *); 431static void xtensa_ldlang_clear_addresses (lang_statement_union_type *); 432static bfd_boolean ld_local_file_relocations_fit 433 (lang_statement_union_type *, const reloc_deps_graph *); 434static bfd_vma ld_assign_relative_paged_dot 435 (bfd_vma, lang_statement_union_type *, const reloc_deps_graph *, 436 bfd_boolean); 437static bfd_vma ld_xtensa_insert_page_offsets 438 (bfd_vma, lang_statement_union_type *, reloc_deps_graph *, bfd_boolean); 439#if EXTRA_VALIDATION 440static size_t ld_count_children (lang_statement_union_type *); 441#endif 442 443extern lang_statement_list_type constructor_list; 444 445/* Begin verbatim code from ldlang.c: 446 the following are copied from ldlang.c because they are defined 447 there statically. */ 448 449static void 450lang_for_each_statement_worker (void (*func) (lang_statement_union_type *), 451 lang_statement_union_type *s) 452{ 453 for (; s != (lang_statement_union_type *) NULL; s = s->header.next) 454 { 455 func (s); 456 457 switch (s->header.type) 458 { 459 case lang_constructors_statement_enum: 460 lang_for_each_statement_worker (func, constructor_list.head); 461 break; 462 case lang_output_section_statement_enum: 463 lang_for_each_statement_worker 464 (func, 465 s->output_section_statement.children.head); 466 break; 467 case lang_wild_statement_enum: 468 lang_for_each_statement_worker 469 (func, 470 s->wild_statement.children.head); 471 break; 472 case lang_group_statement_enum: 473 lang_for_each_statement_worker (func, 474 s->group_statement.children.head); 475 break; 476 case lang_data_statement_enum: 477 case lang_reloc_statement_enum: 478 case lang_object_symbols_statement_enum: 479 case lang_output_statement_enum: 480 case lang_target_statement_enum: 481 case lang_input_section_enum: 482 case lang_input_statement_enum: 483 case lang_assignment_statement_enum: 484 case lang_padding_statement_enum: 485 case lang_address_statement_enum: 486 case lang_fill_statement_enum: 487 break; 488 default: 489 FAIL (); 490 break; 491 } 492 } 493} 494 495/* End of verbatim code from ldlang.c. */ 496 497 498static reloc_deps_section * 499xtensa_get_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 500 asection *sec) 501{ 502 /* We have a separate function for this so that 503 we could in the future keep a completely independent 504 structure that maps a section to its dependence edges. 505 For now, we place these in the sec->userdata field. */ 506 reloc_deps_section *sec_deps = sec->userdata; 507 return sec_deps; 508} 509 510static void 511xtensa_set_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 512 asection *sec, 513 reloc_deps_section *deps_section) 514{ 515 sec->userdata = deps_section; 516} 517 518 519/* This is used to keep a list of all of the sections participating in 520 the graph so we can clean them up quickly. */ 521 522static void 523xtensa_append_section_deps (reloc_deps_graph *deps, asection *sec) 524{ 525 if (deps->size <= deps->count) 526 { 527 asection **new_sections; 528 size_t i; 529 size_t new_size; 530 531 new_size = deps->size * 2; 532 if (new_size == 0) 533 new_size = 20; 534 535 new_sections = xmalloc (sizeof (asection *) * new_size); 536 memset (new_sections, 0, sizeof (asection *) * new_size); 537 for (i = 0; i < deps->count; i++) 538 { 539 new_sections[i] = deps->sections[i]; 540 } 541 if (deps->sections != NULL) 542 free (deps->sections); 543 deps->sections = new_sections; 544 deps->size = new_size; 545 } 546 deps->sections[deps->count] = sec; 547 deps->count++; 548} 549 550 551static void 552free_reloc_deps_graph (reloc_deps_graph *deps) 553{ 554 size_t i; 555 for (i = 0; i < deps->count; i++) 556 { 557 asection *sec = deps->sections[i]; 558 reloc_deps_section *sec_deps; 559 sec_deps = xtensa_get_section_deps (deps, sec); 560 if (sec_deps) 561 { 562 reloc_deps_e *next; 563 while (sec_deps->succs != NULL) 564 { 565 next = sec_deps->succs->next; 566 free (sec_deps->succs); 567 sec_deps->succs = next; 568 } 569 570 while (sec_deps->preds != NULL) 571 { 572 next = sec_deps->preds->next; 573 free (sec_deps->preds); 574 sec_deps->preds = next; 575 } 576 free (sec_deps); 577 } 578 xtensa_set_section_deps (deps, sec, NULL); 579 } 580 if (deps->sections) 581 free (deps->sections); 582 583 free (deps); 584} 585 586 587static bfd_boolean 588section_is_source (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 589 lang_statement_union_type *s) 590{ 591 asection *sec; 592 const reloc_deps_section *sec_deps; 593 594 if (s->header.type != lang_input_section_enum) 595 return FALSE; 596 sec = s->input_section.section; 597 598 sec_deps = xtensa_get_section_deps (deps, sec); 599 return sec_deps && sec_deps->succs != NULL; 600} 601 602 603static bfd_boolean 604section_is_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 605 lang_statement_union_type *s) 606{ 607 asection *sec; 608 const reloc_deps_section *sec_deps; 609 610 if (s->header.type != lang_input_section_enum) 611 return FALSE; 612 sec = s->input_section.section; 613 614 sec_deps = xtensa_get_section_deps (deps, sec); 615 return sec_deps && sec_deps->preds != NULL; 616} 617 618 619static bfd_boolean 620section_is_source_or_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 621 lang_statement_union_type *s) 622{ 623 return (section_is_source (deps, s) 624 || section_is_target (deps, s)); 625} 626 627 628typedef struct xtensa_ld_iter_stack_t xtensa_ld_iter_stack; 629typedef struct xtensa_ld_iter_t xtensa_ld_iter; 630 631struct xtensa_ld_iter_t 632{ 633 lang_statement_union_type *parent; /* Parent of the list. */ 634 lang_statement_list_type *l; /* List that holds it. */ 635 lang_statement_union_type **loc; /* Place in the list. */ 636}; 637 638struct xtensa_ld_iter_stack_t 639{ 640 xtensa_ld_iter iterloc; /* List that hold it. */ 641 642 xtensa_ld_iter_stack *next; /* Next in the stack. */ 643 xtensa_ld_iter_stack *prev; /* Back pointer for stack. */ 644}; 645 646 647static void 648ld_xtensa_move_section_after (xtensa_ld_iter *to, xtensa_ld_iter *current) 649{ 650 lang_statement_union_type *to_next; 651 lang_statement_union_type *current_next; 652 lang_statement_union_type **e; 653 654#if EXTRA_VALIDATION 655 size_t old_to_count, new_to_count; 656 size_t old_current_count, new_current_count; 657#endif 658 659 if (to == current) 660 return; 661 662#if EXTRA_VALIDATION 663 old_to_count = ld_count_children (to->parent); 664 old_current_count = ld_count_children (current->parent); 665#endif 666 667 to_next = *(to->loc); 668 current_next = (*current->loc)->header.next; 669 670 *(to->loc) = *(current->loc); 671 672 *(current->loc) = current_next; 673 (*(to->loc))->header.next = to_next; 674 675 /* reset "to" list tail */ 676 for (e = &to->l->head; *e != NULL; e = &(*e)->header.next) 677 ; 678 to->l->tail = e; 679 680 /* reset "current" list tail */ 681 for (e = ¤t->l->head; *e != NULL; e = &(*e)->header.next) 682 ; 683 current->l->tail = e; 684 685#if EXTRA_VALIDATION 686 new_to_count = ld_count_children (to->parent); 687 new_current_count = ld_count_children (current->parent); 688 689 ASSERT ((old_to_count + old_current_count) 690 == (new_to_count + new_current_count)); 691#endif 692} 693 694 695/* Can only be called with lang_statements that have lists. Returns 696 FALSE if the list is empty. */ 697 698static bfd_boolean 699iter_stack_empty (xtensa_ld_iter_stack **stack_p) 700{ 701 return *stack_p == NULL; 702} 703 704 705static bfd_boolean 706iter_stack_push (xtensa_ld_iter_stack **stack_p, 707 lang_statement_union_type *parent) 708{ 709 xtensa_ld_iter_stack *stack; 710 lang_statement_list_type *l = NULL; 711 712 switch (parent->header.type) 713 { 714 case lang_output_section_statement_enum: 715 l = &parent->output_section_statement.children; 716 break; 717 case lang_wild_statement_enum: 718 l = &parent->wild_statement.children; 719 break; 720 case lang_group_statement_enum: 721 l = &parent->group_statement.children; 722 break; 723 default: 724 ASSERT (0); 725 return FALSE; 726 } 727 728 /* Empty. do not push. */ 729 if (l->tail == &l->head) 730 return FALSE; 731 732 stack = xmalloc (sizeof (xtensa_ld_iter_stack)); 733 memset (stack, 0, sizeof (xtensa_ld_iter_stack)); 734 stack->iterloc.parent = parent; 735 stack->iterloc.l = l; 736 stack->iterloc.loc = &l->head; 737 738 stack->next = *stack_p; 739 stack->prev = NULL; 740 if (*stack_p != NULL) 741 (*stack_p)->prev = stack; 742 *stack_p = stack; 743 return TRUE; 744} 745 746 747static void 748iter_stack_pop (xtensa_ld_iter_stack **stack_p) 749{ 750 xtensa_ld_iter_stack *stack; 751 752 stack = *stack_p; 753 754 if (stack == NULL) 755 { 756 ASSERT (stack != NULL); 757 return; 758 } 759 760 if (stack->next != NULL) 761 stack->next->prev = NULL; 762 763 *stack_p = stack->next; 764 free (stack); 765} 766 767 768/* This MUST be called if, during iteration, the user changes the 769 underlying structure. It will check for a NULL current and advance 770 accordingly. */ 771 772static void 773iter_stack_update (xtensa_ld_iter_stack **stack_p) 774{ 775 if (!iter_stack_empty (stack_p) 776 && (*(*stack_p)->iterloc.loc) == NULL) 777 { 778 iter_stack_pop (stack_p); 779 780 while (!iter_stack_empty (stack_p) 781 && ((*(*stack_p)->iterloc.loc)->header.next == NULL)) 782 { 783 iter_stack_pop (stack_p); 784 } 785 if (!iter_stack_empty (stack_p)) 786 (*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next; 787 } 788} 789 790 791static void 792iter_stack_next (xtensa_ld_iter_stack **stack_p) 793{ 794 xtensa_ld_iter_stack *stack; 795 lang_statement_union_type *current; 796 stack = *stack_p; 797 798 current = *stack->iterloc.loc; 799 /* If we are on the first element. */ 800 if (current != NULL) 801 { 802 switch (current->header.type) 803 { 804 case lang_output_section_statement_enum: 805 case lang_wild_statement_enum: 806 case lang_group_statement_enum: 807 /* If the list if not empty, we are done. */ 808 if (iter_stack_push (stack_p, *stack->iterloc.loc)) 809 return; 810 /* Otherwise increment the pointer as normal. */ 811 break; 812 default: 813 break; 814 } 815 } 816 817 while (!iter_stack_empty (stack_p) 818 && ((*(*stack_p)->iterloc.loc)->header.next == NULL)) 819 { 820 iter_stack_pop (stack_p); 821 } 822 if (!iter_stack_empty (stack_p)) 823 (*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next; 824} 825 826 827static lang_statement_union_type * 828iter_stack_current (xtensa_ld_iter_stack **stack_p) 829{ 830 return *((*stack_p)->iterloc.loc); 831} 832 833 834/* The iter stack is a preorder. */ 835 836static void 837iter_stack_create (xtensa_ld_iter_stack **stack_p, 838 lang_statement_union_type *parent) 839{ 840 iter_stack_push (stack_p, parent); 841} 842 843 844static void 845iter_stack_copy_current (xtensa_ld_iter_stack **stack_p, xtensa_ld_iter *front) 846{ 847 *front = (*stack_p)->iterloc; 848} 849 850 851static void 852xtensa_colocate_literals (reloc_deps_graph *deps, 853 lang_statement_union_type *statement) 854{ 855 /* Keep a stack of pointers to control iteration through the contours. */ 856 xtensa_ld_iter_stack *stack = NULL; 857 xtensa_ld_iter_stack **stack_p = &stack; 858 859 xtensa_ld_iter front; /* Location where new insertion should occur. */ 860 xtensa_ld_iter *front_p = NULL; 861 862 xtensa_ld_iter current; /* Location we are checking. */ 863 xtensa_ld_iter *current_p = NULL; 864 bfd_boolean in_literals = FALSE; 865 866 if (deps->count == 0) 867 return; 868 869 iter_stack_create (stack_p, statement); 870 871 while (!iter_stack_empty (stack_p)) 872 { 873 bfd_boolean skip_increment = FALSE; 874 lang_statement_union_type *l = iter_stack_current (stack_p); 875 876 switch (l->header.type) 877 { 878 case lang_assignment_statement_enum: 879 /* Any assignment statement should block reordering across it. */ 880 front_p = NULL; 881 in_literals = FALSE; 882 break; 883 884 case lang_input_section_enum: 885 if (front_p == NULL) 886 { 887 in_literals = (section_is_target (deps, l) 888 && !section_is_source (deps, l)); 889 if (in_literals) 890 { 891 front_p = &front; 892 iter_stack_copy_current (stack_p, front_p); 893 } 894 } 895 else 896 { 897 bfd_boolean is_target; 898 current_p = ¤t; 899 iter_stack_copy_current (stack_p, current_p); 900 is_target = (section_is_target (deps, l) 901 && !section_is_source (deps, l)); 902 903 if (in_literals) 904 { 905 iter_stack_copy_current (stack_p, front_p); 906 if (!is_target) 907 in_literals = FALSE; 908 } 909 else 910 { 911 if (is_target) 912 { 913 /* Try to insert in place. */ 914 ld_xtensa_move_section_after (front_p, current_p); 915 ld_assign_relative_paged_dot (0x100000, 916 statement, 917 deps, 918 xtensa_use_literal_pages); 919 920 /* We use this code because it's already written. */ 921 if (!ld_local_file_relocations_fit (statement, deps)) 922 { 923 /* Move it back. */ 924 ld_xtensa_move_section_after (current_p, front_p); 925 /* Reset the literal placement. */ 926 iter_stack_copy_current (stack_p, front_p); 927 } 928 else 929 { 930 /* Move front pointer up by one. */ 931 front_p->loc = &(*front_p->loc)->header.next; 932 933 /* Do not increment the current pointer. */ 934 skip_increment = TRUE; 935 } 936 } 937 } 938 } 939 break; 940 default: 941 break; 942 } 943 944 if (!skip_increment) 945 iter_stack_next (stack_p); 946 else 947 /* Be careful to update the stack_p if it now is a null. */ 948 iter_stack_update (stack_p); 949 } 950 951 lang_for_each_statement_worker (xtensa_ldlang_clear_addresses, statement); 952} 953 954 955static void 956xtensa_move_dependencies_to_front (reloc_deps_graph *deps, 957 lang_wild_statement_type *w) 958{ 959 /* Keep a front pointer and a current pointer. */ 960 lang_statement_union_type **front; 961 lang_statement_union_type **current; 962 963 /* Walk to the end of the targets. */ 964 for (front = &w->children.head; 965 (*front != NULL) && section_is_source_or_target (deps, *front); 966 front = &(*front)->header.next) 967 ; 968 969 if (*front == NULL) 970 return; 971 972 current = &(*front)->header.next; 973 while (*current != NULL) 974 { 975 if (section_is_source_or_target (deps, *current)) 976 { 977 /* Insert in place. */ 978 xtensa_ld_iter front_iter; 979 xtensa_ld_iter current_iter; 980 981 front_iter.parent = (lang_statement_union_type *) w; 982 front_iter.l = &w->children; 983 front_iter.loc = front; 984 985 current_iter.parent = (lang_statement_union_type *) w; 986 current_iter.l = &w->children; 987 current_iter.loc = current; 988 989 ld_xtensa_move_section_after (&front_iter, ¤t_iter); 990 front = &(*front)->header.next; 991 } 992 else 993 { 994 current = &(*current)->header.next; 995 } 996 } 997} 998 999 1000static bfd_boolean 1001deps_has_sec_edge (const reloc_deps_graph *deps, asection *src, asection *tgt) 1002{ 1003 const reloc_deps_section *sec_deps; 1004 const reloc_deps_e *sec_deps_e; 1005 1006 sec_deps = xtensa_get_section_deps (deps, src); 1007 if (sec_deps == NULL) 1008 return FALSE; 1009 1010 for (sec_deps_e = sec_deps->succs; 1011 sec_deps_e != NULL; 1012 sec_deps_e = sec_deps_e->next) 1013 { 1014 ASSERT (sec_deps_e->src == src); 1015 if (sec_deps_e->tgt == tgt) 1016 return TRUE; 1017 } 1018 return FALSE; 1019} 1020 1021 1022static bfd_boolean 1023deps_has_edge (const reloc_deps_graph *deps, 1024 lang_statement_union_type *src, 1025 lang_statement_union_type *tgt) 1026{ 1027 if (!section_is_source (deps, src)) 1028 return FALSE; 1029 if (!section_is_target (deps, tgt)) 1030 return FALSE; 1031 1032 if (src->header.type != lang_input_section_enum) 1033 return FALSE; 1034 if (tgt->header.type != lang_input_section_enum) 1035 return FALSE; 1036 1037 return deps_has_sec_edge (deps, src->input_section.section, 1038 tgt->input_section.section); 1039} 1040 1041 1042static void 1043add_deps_edge (reloc_deps_graph *deps, asection *src_sec, asection *tgt_sec) 1044{ 1045 reloc_deps_section *src_sec_deps; 1046 reloc_deps_section *tgt_sec_deps; 1047 1048 reloc_deps_e *src_edge; 1049 reloc_deps_e *tgt_edge; 1050 1051 if (deps_has_sec_edge (deps, src_sec, tgt_sec)) 1052 return; 1053 1054 src_sec_deps = xtensa_get_section_deps (deps, src_sec); 1055 if (src_sec_deps == NULL) 1056 { 1057 /* Add a section. */ 1058 src_sec_deps = xmalloc (sizeof (reloc_deps_section)); 1059 memset (src_sec_deps, 0, sizeof (reloc_deps_section)); 1060 src_sec_deps->is_only_literal = 0; 1061 src_sec_deps->preds = NULL; 1062 src_sec_deps->succs = NULL; 1063 xtensa_set_section_deps (deps, src_sec, src_sec_deps); 1064 xtensa_append_section_deps (deps, src_sec); 1065 } 1066 1067 tgt_sec_deps = xtensa_get_section_deps (deps, tgt_sec); 1068 if (tgt_sec_deps == NULL) 1069 { 1070 /* Add a section. */ 1071 tgt_sec_deps = xmalloc (sizeof (reloc_deps_section)); 1072 memset (tgt_sec_deps, 0, sizeof (reloc_deps_section)); 1073 tgt_sec_deps->is_only_literal = 0; 1074 tgt_sec_deps->preds = NULL; 1075 tgt_sec_deps->succs = NULL; 1076 xtensa_set_section_deps (deps, tgt_sec, tgt_sec_deps); 1077 xtensa_append_section_deps (deps, tgt_sec); 1078 } 1079 1080 /* Add the edges. */ 1081 src_edge = xmalloc (sizeof (reloc_deps_e)); 1082 memset (src_edge, 0, sizeof (reloc_deps_e)); 1083 src_edge->src = src_sec; 1084 src_edge->tgt = tgt_sec; 1085 src_edge->next = src_sec_deps->succs; 1086 src_sec_deps->succs = src_edge; 1087 1088 tgt_edge = xmalloc (sizeof (reloc_deps_e)); 1089 memset (tgt_edge, 0, sizeof (reloc_deps_e)); 1090 tgt_edge->src = src_sec; 1091 tgt_edge->tgt = tgt_sec; 1092 tgt_edge->next = tgt_sec_deps->preds; 1093 tgt_sec_deps->preds = tgt_edge; 1094} 1095 1096 1097static void 1098build_deps_graph_callback (asection *src_sec, 1099 bfd_vma src_offset ATTRIBUTE_UNUSED, 1100 asection *target_sec, 1101 bfd_vma target_offset ATTRIBUTE_UNUSED, 1102 void *closure) 1103{ 1104 reloc_deps_graph *deps = closure; 1105 1106 /* If the target is defined. */ 1107 if (target_sec != NULL) 1108 add_deps_edge (deps, src_sec, target_sec); 1109} 1110 1111 1112static reloc_deps_graph * 1113ld_build_required_section_dependence (lang_statement_union_type *s) 1114{ 1115 reloc_deps_graph *deps; 1116 xtensa_ld_iter_stack *stack = NULL; 1117 1118 deps = xmalloc (sizeof (reloc_deps_graph)); 1119 deps->sections = NULL; 1120 deps->count = 0; 1121 deps->size = 0; 1122 1123 for (iter_stack_create (&stack, s); 1124 !iter_stack_empty (&stack); 1125 iter_stack_next (&stack)) 1126 { 1127 lang_statement_union_type *l = iter_stack_current (&stack); 1128 1129 if (l->header.type == lang_input_section_enum) 1130 { 1131 lang_input_section_type *input; 1132 input = &l->input_section; 1133 xtensa_callback_required_dependence (input->section->owner, 1134 input->section, 1135 &link_info, 1136 /* Use the same closure. */ 1137 build_deps_graph_callback, 1138 deps); 1139 } 1140 } 1141 return deps; 1142} 1143 1144 1145#if EXTRA_VALIDATION 1146static size_t 1147ld_count_children (lang_statement_union_type *s) 1148{ 1149 size_t count = 0; 1150 xtensa_ld_iter_stack *stack = NULL; 1151 for (iter_stack_create (&stack, s); 1152 !iter_stack_empty (&stack); 1153 iter_stack_next (&stack)) 1154 { 1155 lang_statement_union_type *l = iter_stack_current (&stack); 1156 ASSERT (l != NULL); 1157 count++; 1158 } 1159 return count; 1160} 1161#endif /* EXTRA_VALIDATION */ 1162 1163 1164/* Check if a particular section is included in the link. This will only 1165 be true for one instance of a particular linkonce section. */ 1166 1167static bfd_boolean input_section_found = FALSE; 1168static asection *input_section_target = NULL; 1169 1170static void 1171input_section_linked_worker (lang_statement_union_type *statement) 1172{ 1173 if ((statement->header.type == lang_input_section_enum 1174 && (statement->input_section.section == input_section_target))) 1175 input_section_found = TRUE; 1176} 1177 1178static bfd_boolean 1179input_section_linked (asection *sec) 1180{ 1181 input_section_found = FALSE; 1182 input_section_target = sec; 1183 lang_for_each_statement_worker (input_section_linked_worker, stat_ptr->head); 1184 return input_section_found; 1185} 1186 1187 1188/* Strip out any linkonce literal sections or property tables where the 1189 associated linkonce text is from a different object file. Normally, 1190 a matching set of linkonce sections is taken from the same object file, 1191 but sometimes the files are compiled differently so that some of the 1192 linkonce sections are not present in all files. Stripping the 1193 inconsistent sections like this is not completely robust -- a much 1194 better solution is to use comdat groups. */ 1195 1196static int linkonce_len = sizeof (".gnu.linkonce.") - 1; 1197 1198static bfd_boolean 1199is_inconsistent_linkonce_section (asection *sec) 1200{ 1201 bfd *abfd = sec->owner; 1202 const char *sec_name = bfd_get_section_name (abfd, sec); 1203 char *prop_tag = 0; 1204 1205 if ((bfd_get_section_flags (abfd, sec) & SEC_LINK_ONCE) == 0 1206 || strncmp (sec_name, ".gnu.linkonce.", linkonce_len) != 0) 1207 return FALSE; 1208 1209 /* Check if this is an Xtensa property section. */ 1210 if (strncmp (sec_name + linkonce_len, "p.", 2) == 0) 1211 prop_tag = "p."; 1212 else if (strncmp (sec_name + linkonce_len, "prop.", 5) == 0) 1213 prop_tag = "prop."; 1214 if (prop_tag) 1215 { 1216 int tag_len = strlen (prop_tag); 1217 char *dep_sec_name = xmalloc (strlen (sec_name)); 1218 asection *dep_sec; 1219 1220 /* Get the associated linkonce text section and check if it is 1221 included in the link. If not, this section is inconsistent 1222 and should be stripped. */ 1223 strcpy (dep_sec_name, ".gnu.linkonce."); 1224 strcat (dep_sec_name, sec_name + linkonce_len + tag_len); 1225 dep_sec = bfd_get_section_by_name (abfd, dep_sec_name); 1226 if (dep_sec == NULL || ! input_section_linked (dep_sec)) 1227 { 1228 free (dep_sec_name); 1229 return TRUE; 1230 } 1231 free (dep_sec_name); 1232 } 1233 1234 return FALSE; 1235} 1236 1237 1238static void 1239xtensa_strip_inconsistent_linkonce_sections (lang_statement_list_type *slist) 1240{ 1241 lang_statement_union_type **s_p = &slist->head; 1242 while (*s_p) 1243 { 1244 lang_statement_union_type *s = *s_p; 1245 lang_statement_union_type *s_next = (*s_p)->header.next; 1246 1247 switch (s->header.type) 1248 { 1249 case lang_input_section_enum: 1250 if (is_inconsistent_linkonce_section (s->input_section.section)) 1251 { 1252 *s_p = s_next; 1253 continue; 1254 } 1255 break; 1256 1257 case lang_constructors_statement_enum: 1258 xtensa_strip_inconsistent_linkonce_sections (&constructor_list); 1259 break; 1260 1261 case lang_output_section_statement_enum: 1262 if (s->output_section_statement.children.head) 1263 xtensa_strip_inconsistent_linkonce_sections 1264 (&s->output_section_statement.children); 1265 break; 1266 1267 case lang_wild_statement_enum: 1268 xtensa_strip_inconsistent_linkonce_sections 1269 (&s->wild_statement.children); 1270 break; 1271 1272 case lang_group_statement_enum: 1273 xtensa_strip_inconsistent_linkonce_sections 1274 (&s->group_statement.children); 1275 break; 1276 1277 case lang_data_statement_enum: 1278 case lang_reloc_statement_enum: 1279 case lang_object_symbols_statement_enum: 1280 case lang_output_statement_enum: 1281 case lang_target_statement_enum: 1282 case lang_input_statement_enum: 1283 case lang_assignment_statement_enum: 1284 case lang_padding_statement_enum: 1285 case lang_address_statement_enum: 1286 case lang_fill_statement_enum: 1287 break; 1288 1289 default: 1290 FAIL (); 1291 break; 1292 } 1293 1294 s_p = &(*s_p)->header.next; 1295 } 1296 1297 /* Reset the tail of the list, in case the last entry was removed. */ 1298 if (s_p != slist->tail) 1299 slist->tail = s_p; 1300} 1301 1302 1303static void 1304xtensa_wild_group_interleave_callback (lang_statement_union_type *statement) 1305{ 1306 lang_wild_statement_type *w; 1307 reloc_deps_graph *deps; 1308 if (statement->header.type == lang_wild_statement_enum) 1309 { 1310#if EXTRA_VALIDATION 1311 size_t old_child_count; 1312 size_t new_child_count; 1313#endif 1314 bfd_boolean no_reorder; 1315 1316 w = &statement->wild_statement; 1317 1318 no_reorder = FALSE; 1319 1320 /* If it has 0 or 1 section bound, then do not reorder. */ 1321 if (w->children.head == NULL 1322 || (w->children.head->header.type == lang_input_section_enum 1323 && w->children.head->header.next == NULL)) 1324 no_reorder = TRUE; 1325 1326 if (w->filenames_sorted) 1327 no_reorder = TRUE; 1328 1329 /* Check for sorting in a section list wildcard spec as well. */ 1330 if (!no_reorder) 1331 { 1332 struct wildcard_list *l; 1333 for (l = w->section_list; l != NULL; l = l->next) 1334 { 1335 if (l->spec.sorted == TRUE) 1336 { 1337 no_reorder = TRUE; 1338 break; 1339 } 1340 } 1341 } 1342 1343 /* Special case until the NOREORDER linker directive is supported: 1344 *(.init) output sections and *(.fini) specs may NOT be reordered. */ 1345 1346 /* Check for sorting in a section list wildcard spec as well. */ 1347 if (!no_reorder) 1348 { 1349 struct wildcard_list *l; 1350 for (l = w->section_list; l != NULL; l = l->next) 1351 { 1352 if (l->spec.name 1353 && ((strcmp (".init", l->spec.name) == 0) 1354 || (strcmp (".fini", l->spec.name) == 0))) 1355 { 1356 no_reorder = TRUE; 1357 break; 1358 } 1359 } 1360 } 1361 1362#if EXTRA_VALIDATION 1363 old_child_count = ld_count_children (statement); 1364#endif 1365 1366 /* It is now officially a target. Build the graph of source 1367 section -> target section (kept as a list of edges). */ 1368 deps = ld_build_required_section_dependence (statement); 1369 1370 /* If this wildcard does not reorder.... */ 1371 if (!no_reorder && deps->count != 0) 1372 { 1373 /* First check for reverse dependences. Fix if possible. */ 1374 xtensa_layout_wild (deps, w); 1375 1376 xtensa_move_dependencies_to_front (deps, w); 1377#if EXTRA_VALIDATION 1378 new_child_count = ld_count_children (statement); 1379 ASSERT (new_child_count == old_child_count); 1380#endif 1381 1382 xtensa_colocate_literals (deps, statement); 1383 1384#if EXTRA_VALIDATION 1385 new_child_count = ld_count_children (statement); 1386 ASSERT (new_child_count == old_child_count); 1387#endif 1388 } 1389 1390 /* Clean up. */ 1391 free_reloc_deps_graph (deps); 1392 } 1393} 1394 1395 1396static void 1397xtensa_wild_group_interleave (lang_statement_union_type *s) 1398{ 1399 lang_for_each_statement_worker (xtensa_wild_group_interleave_callback, s); 1400} 1401 1402 1403static void 1404xtensa_layout_wild (const reloc_deps_graph *deps, lang_wild_statement_type *w) 1405{ 1406 /* If it does not fit initially, we need to do this step. Move all 1407 of the wild literal sections to a new list, then move each of 1408 them back in just before the first section they depend on. */ 1409 lang_statement_union_type **s_p; 1410#if EXTRA_VALIDATION 1411 size_t old_count, new_count; 1412 size_t ct1, ct2; 1413#endif 1414 1415 lang_wild_statement_type literal_wild; 1416 literal_wild.header.next = NULL; 1417 literal_wild.header.type = lang_wild_statement_enum; 1418 literal_wild.filename = NULL; 1419 literal_wild.filenames_sorted = FALSE; 1420 literal_wild.section_list = NULL; 1421 literal_wild.keep_sections = FALSE; 1422 literal_wild.children.head = NULL; 1423 literal_wild.children.tail = &literal_wild.children.head; 1424 1425#if EXTRA_VALIDATION 1426 old_count = ld_count_children ((lang_statement_union_type*) w); 1427#endif 1428 1429 s_p = &w->children.head; 1430 while (*s_p != NULL) 1431 { 1432 lang_statement_union_type *l = *s_p; 1433 if (l->header.type == lang_input_section_enum) 1434 { 1435 if (section_is_target (deps, l) 1436 && ! section_is_source (deps, l)) 1437 { 1438 /* Detach. */ 1439 *s_p = l->header.next; 1440 if (*s_p == NULL) 1441 w->children.tail = s_p; 1442 l->header.next = NULL; 1443 1444 /* Append. */ 1445 *literal_wild.children.tail = l; 1446 literal_wild.children.tail = &l->header.next; 1447 continue; 1448 } 1449 } 1450 s_p = &(*s_p)->header.next; 1451 } 1452 1453#if EXTRA_VALIDATION 1454 ct1 = ld_count_children ((lang_statement_union_type*) w); 1455 ct2 = ld_count_children ((lang_statement_union_type*) &literal_wild); 1456 1457 ASSERT (old_count == (ct1 + ct2)); 1458#endif 1459 1460 /* Now place them back in front of their dependent sections. */ 1461 1462 while (literal_wild.children.head != NULL) 1463 { 1464 lang_statement_union_type *lit = literal_wild.children.head; 1465 bfd_boolean placed = FALSE; 1466 1467#if EXTRA_VALIDATION 1468 ASSERT (ct2 > 0); 1469 ct2--; 1470#endif 1471 1472 /* Detach. */ 1473 literal_wild.children.head = lit->header.next; 1474 if (literal_wild.children.head == NULL) 1475 literal_wild.children.tail = &literal_wild.children.head; 1476 lit->header.next = NULL; 1477 1478 /* Find a spot to place it. */ 1479 for (s_p = &w->children.head; *s_p != NULL; s_p = &(*s_p)->header.next) 1480 { 1481 lang_statement_union_type *src = *s_p; 1482 if (deps_has_edge (deps, src, lit)) 1483 { 1484 /* Place it here. */ 1485 lit->header.next = *s_p; 1486 *s_p = lit; 1487 placed = TRUE; 1488 break; 1489 } 1490 } 1491 1492 if (!placed) 1493 { 1494 /* Put it at the end. */ 1495 *w->children.tail = lit; 1496 w->children.tail = &lit->header.next; 1497 } 1498 } 1499 1500#if EXTRA_VALIDATION 1501 new_count = ld_count_children ((lang_statement_union_type*) w); 1502 ASSERT (new_count == old_count); 1503#endif 1504} 1505 1506 1507static void 1508xtensa_colocate_output_literals_callback (lang_statement_union_type *statement) 1509{ 1510 lang_output_section_statement_type *os; 1511 reloc_deps_graph *deps; 1512 if (statement->header.type == lang_output_section_statement_enum) 1513 { 1514 /* Now, we walk over the contours of the output section statement. 1515 1516 First we build the literal section dependences as before. 1517 1518 At the first uniquely_literal section, we mark it as a good 1519 spot to place other literals. Continue walking (and counting 1520 sizes) until we find the next literal section. If this 1521 section can be moved to the first one, then we move it. If 1522 we every find a modification of ".", start over. If we find 1523 a labeling of the current location, start over. Finally, at 1524 the end, if we require page alignment, add page alignments. */ 1525 1526#if EXTRA_VALIDATION 1527 size_t old_child_count; 1528 size_t new_child_count; 1529#endif 1530 bfd_boolean no_reorder = FALSE; 1531 1532 os = &statement->output_section_statement; 1533 1534#if EXTRA_VALIDATION 1535 old_child_count = ld_count_children (statement); 1536#endif 1537 1538 /* It is now officially a target. Build the graph of source 1539 section -> target section (kept as a list of edges). */ 1540 1541 deps = ld_build_required_section_dependence (statement); 1542 1543 /* If this wildcard does not reorder.... */ 1544 if (!no_reorder) 1545 { 1546 /* First check for reverse dependences. Fix if possible. */ 1547 xtensa_colocate_literals (deps, statement); 1548 1549#if EXTRA_VALIDATION 1550 new_child_count = ld_count_children (statement); 1551 ASSERT (new_child_count == old_child_count); 1552#endif 1553 } 1554 1555 /* Insert align/offset assignment statement. */ 1556 if (xtensa_use_literal_pages) 1557 { 1558 ld_xtensa_insert_page_offsets (0, statement, deps, 1559 xtensa_use_literal_pages); 1560 lang_for_each_statement_worker (xtensa_ldlang_clear_addresses, 1561 statement); 1562 } 1563 1564 /* Clean up. */ 1565 free_reloc_deps_graph (deps); 1566 } 1567} 1568 1569 1570static void 1571xtensa_colocate_output_literals (lang_statement_union_type *s) 1572{ 1573 lang_for_each_statement_worker (xtensa_colocate_output_literals_callback, s); 1574} 1575 1576 1577static void 1578xtensa_ldlang_clear_addresses (lang_statement_union_type *statement) 1579{ 1580 switch (statement->header.type) 1581 { 1582 case lang_input_section_enum: 1583 { 1584 asection *bfd_section = statement->input_section.section; 1585 bfd_section->output_offset = 0; 1586 } 1587 break; 1588 default: 1589 break; 1590 } 1591} 1592 1593 1594static bfd_vma 1595ld_assign_relative_paged_dot (bfd_vma dot, 1596 lang_statement_union_type *s, 1597 const reloc_deps_graph *deps ATTRIBUTE_UNUSED, 1598 bfd_boolean lit_align) 1599{ 1600 /* Walk through all of the input statements in this wild statement 1601 assign dot to all of them. */ 1602 1603 xtensa_ld_iter_stack *stack = NULL; 1604 xtensa_ld_iter_stack **stack_p = &stack; 1605 1606 bfd_boolean first_section = FALSE; 1607 bfd_boolean in_literals = FALSE; 1608 1609 for (iter_stack_create (stack_p, s); 1610 !iter_stack_empty (stack_p); 1611 iter_stack_next (stack_p)) 1612 { 1613 lang_statement_union_type *l = iter_stack_current (stack_p); 1614 1615 switch (l->header.type) 1616 { 1617 case lang_input_section_enum: 1618 { 1619 asection *section = l->input_section.section; 1620 size_t align_pow = section->alignment_power; 1621 bfd_boolean do_xtensa_alignment = FALSE; 1622 1623 if (lit_align) 1624 { 1625 bfd_boolean sec_is_target = section_is_target (deps, l); 1626 bfd_boolean sec_is_source = section_is_source (deps, l); 1627 1628 if (section->size != 0 1629 && (first_section 1630 || (in_literals && !sec_is_target) 1631 || (!in_literals && sec_is_target))) 1632 { 1633 do_xtensa_alignment = TRUE; 1634 } 1635 first_section = FALSE; 1636 if (section->size != 0) 1637 in_literals = (sec_is_target && !sec_is_source); 1638 } 1639 1640 if (do_xtensa_alignment && xtensa_page_power != 0) 1641 dot += (1 << xtensa_page_power); 1642 1643 dot = align_power (dot, align_pow); 1644 section->output_offset = dot; 1645 dot += section->size; 1646 } 1647 break; 1648 case lang_fill_statement_enum: 1649 dot += l->fill_statement.size; 1650 break; 1651 case lang_padding_statement_enum: 1652 dot += l->padding_statement.size; 1653 break; 1654 default: 1655 break; 1656 } 1657 } 1658 return dot; 1659} 1660 1661 1662static bfd_boolean 1663ld_local_file_relocations_fit (lang_statement_union_type *statement, 1664 const reloc_deps_graph *deps ATTRIBUTE_UNUSED) 1665{ 1666 /* Walk over all of the dependencies that we identified and make 1667 sure that IF the source and target are here (addr != 0): 1668 1) target addr < source addr 1669 2) (roundup(source + source_size, 4) - rounddown(target, 4)) 1670 < (256K - (1 << bad align)) 1671 Need a worst-case proof.... */ 1672 1673 xtensa_ld_iter_stack *stack = NULL; 1674 xtensa_ld_iter_stack **stack_p = &stack; 1675 size_t max_align_power = 0; 1676 size_t align_penalty = 256; 1677 reloc_deps_e *e; 1678 size_t i; 1679 1680 /* Find the worst-case alignment requirement for this set of statements. */ 1681 for (iter_stack_create (stack_p, statement); 1682 !iter_stack_empty (stack_p); 1683 iter_stack_next (stack_p)) 1684 { 1685 lang_statement_union_type *l = iter_stack_current (stack_p); 1686 if (l->header.type == lang_input_section_enum) 1687 { 1688 lang_input_section_type *input = &l->input_section; 1689 asection *section = input->section; 1690 if (section->alignment_power > max_align_power) 1691 max_align_power = section->alignment_power; 1692 } 1693 } 1694 1695 /* Now check that everything fits. */ 1696 for (i = 0; i < deps->count; i++) 1697 { 1698 asection *sec = deps->sections[i]; 1699 const reloc_deps_section *deps_section = 1700 xtensa_get_section_deps (deps, sec); 1701 if (deps_section) 1702 { 1703 /* We choose to walk through the successors. */ 1704 for (e = deps_section->succs; e != NULL; e = e->next) 1705 { 1706 if (e->src != e->tgt 1707 && e->src->output_section == e->tgt->output_section 1708 && e->src->output_offset != 0 1709 && e->tgt->output_offset != 0) 1710 { 1711 bfd_vma l32r_addr = 1712 align_power (e->src->output_offset + e->src->size, 2); 1713 bfd_vma target_addr = e->tgt->output_offset & ~3; 1714 if (l32r_addr < target_addr) 1715 { 1716 fprintf (stderr, "Warning: " 1717 "l32r target section before l32r\n"); 1718 return FALSE; 1719 } 1720 1721 if (l32r_addr - target_addr > 256 * 1024 - align_penalty) 1722 return FALSE; 1723 } 1724 } 1725 } 1726 } 1727 1728 return TRUE; 1729} 1730 1731 1732static bfd_vma 1733ld_xtensa_insert_page_offsets (bfd_vma dot, 1734 lang_statement_union_type *s, 1735 reloc_deps_graph *deps, 1736 bfd_boolean lit_align) 1737{ 1738 xtensa_ld_iter_stack *stack = NULL; 1739 xtensa_ld_iter_stack **stack_p = &stack; 1740 1741 bfd_boolean first_section = FALSE; 1742 bfd_boolean in_literals = FALSE; 1743 1744 if (!lit_align) 1745 return FALSE; 1746 1747 for (iter_stack_create (stack_p, s); 1748 !iter_stack_empty (stack_p); 1749 iter_stack_next (stack_p)) 1750 { 1751 lang_statement_union_type *l = iter_stack_current (stack_p); 1752 1753 switch (l->header.type) 1754 { 1755 case lang_input_section_enum: 1756 { 1757 asection *section = l->input_section.section; 1758 bfd_boolean do_xtensa_alignment = FALSE; 1759 1760 if (lit_align) 1761 { 1762 if (section->size != 0 1763 && (first_section 1764 || (in_literals && !section_is_target (deps, l)) 1765 || (!in_literals && section_is_target (deps, l)))) 1766 { 1767 do_xtensa_alignment = TRUE; 1768 } 1769 first_section = FALSE; 1770 if (section->size != 0) 1771 { 1772 in_literals = (section_is_target (deps, l) 1773 && !section_is_source (deps, l)); 1774 } 1775 } 1776 1777 if (do_xtensa_alignment && xtensa_page_power != 0) 1778 { 1779 /* Create an expression that increments the current address, 1780 i.e., "dot", by (1 << xtensa_align_power). */ 1781 etree_type *name_op = exp_nameop (NAME, "."); 1782 etree_type *addend_op = exp_intop (1 << xtensa_page_power); 1783 etree_type *add_op = exp_binop ('+', name_op, addend_op); 1784 etree_type *assign_op = exp_assop ('=', ".", add_op); 1785 1786 lang_assignment_statement_type *assign_stmt; 1787 lang_statement_union_type *assign_union; 1788 lang_statement_list_type tmplist; 1789 lang_statement_list_type *old_stat_ptr = stat_ptr; 1790 1791 /* There is hidden state in "lang_add_assignment". It 1792 appends the new assignment statement to the stat_ptr 1793 list. Thus, we swap it before and after the call. */ 1794 1795 tmplist.head = NULL; 1796 tmplist.tail = &tmplist.head; 1797 1798 stat_ptr = &tmplist; 1799 /* Warning: side effect; statement appended to stat_ptr. */ 1800 assign_stmt = lang_add_assignment (assign_op); 1801 assign_union = (lang_statement_union_type *) assign_stmt; 1802 stat_ptr = old_stat_ptr; 1803 1804 assign_union->header.next = l; 1805 *(*stack_p)->iterloc.loc = assign_union; 1806 iter_stack_next (stack_p); 1807 } 1808 } 1809 break; 1810 default: 1811 break; 1812 } 1813 } 1814 return dot; 1815} 1816 1817EOF 1818 1819# Define some shell vars to insert bits of code into the standard ELF 1820# parse_args and list_options functions. 1821# 1822PARSE_AND_LIST_PROLOGUE=' 1823#define OPTION_OPT_SIZEOPT (300) 1824#define OPTION_NO_RELAX (OPTION_OPT_SIZEOPT + 1) 1825#define OPTION_LITERAL_MOVEMENT (OPTION_NO_RELAX + 1) 1826#define OPTION_NO_LITERAL_MOVEMENT (OPTION_LITERAL_MOVEMENT + 1) 1827extern int elf32xtensa_size_opt; 1828extern int elf32xtensa_no_literal_movement; 1829' 1830 1831PARSE_AND_LIST_LONGOPTS=' 1832 { "size-opt", no_argument, NULL, OPTION_OPT_SIZEOPT}, 1833 { "no-relax", no_argument, NULL, OPTION_NO_RELAX}, 1834 { "literal-movement", no_argument, NULL, OPTION_LITERAL_MOVEMENT}, 1835 { "no-literal-movement", no_argument, NULL, OPTION_NO_LITERAL_MOVEMENT}, 1836' 1837 1838PARSE_AND_LIST_OPTIONS=' 1839 fprintf (file, _(" --size-opt\t\tWhen relaxing longcalls, prefer size optimization\n\t\t\t over branch target alignment\n")); 1840 fprintf (file, _(" --no-relax\t\tDo not relax branches or coalesce literals\n")); 1841' 1842 1843PARSE_AND_LIST_ARGS_CASES=' 1844 case OPTION_OPT_SIZEOPT: 1845 elf32xtensa_size_opt = 1; 1846 break; 1847 case OPTION_NO_RELAX: 1848 disable_relaxation = TRUE; 1849 break; 1850 case OPTION_LITERAL_MOVEMENT: 1851 elf32xtensa_no_literal_movement = 0; 1852 break; 1853 case OPTION_NO_LITERAL_MOVEMENT: 1854 elf32xtensa_no_literal_movement = 1; 1855 break; 1856' 1857 1858# Replace some of the standard ELF functions with our own versions. 1859# 1860LDEMUL_BEFORE_PARSE=elf_xtensa_before_parse 1861LDEMUL_AFTER_OPEN=elf_xtensa_after_open 1862LDEMUL_CHOOSE_TARGET=elf_xtensa_choose_target 1863LDEMUL_BEFORE_ALLOCATION=elf_xtensa_before_allocation 1864 1865