133965Sjdp/* Linker command language support. 278828Sobrien Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3218822Sdim 2001, 2002, 2003, 2004, 2005, 2006, 2007 438889Sjdp Free Software Foundation, Inc. 533965Sjdp 6130561Sobrien This file is part of GLD, the Gnu Linker. 733965Sjdp 8130561Sobrien GLD is free software; you can redistribute it and/or modify 9130561Sobrien it under the terms of the GNU General Public License as published by 10130561Sobrien the Free Software Foundation; either version 2, or (at your option) 11130561Sobrien any later version. 1233965Sjdp 13130561Sobrien GLD is distributed in the hope that it will be useful, 14130561Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 15130561Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130561Sobrien GNU General Public License for more details. 1733965Sjdp 18130561Sobrien You should have received a copy of the GNU General Public License 19130561Sobrien along with GLD; see the file COPYING. If not, write to the Free 20218822Sdim Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 21218822Sdim 02110-1301, USA. */ 2233965Sjdp 23218822Sdim#include "sysdep.h" 2433965Sjdp#include "bfd.h" 2533965Sjdp#include "libiberty.h" 2689857Sobrien#include "safe-ctype.h" 2733965Sjdp#include "obstack.h" 2833965Sjdp#include "bfdlink.h" 2933965Sjdp 3033965Sjdp#include "ld.h" 3133965Sjdp#include "ldmain.h" 3233965Sjdp#include "ldexp.h" 3333965Sjdp#include "ldlang.h" 34107492Sobrien#include <ldgram.h> 3533965Sjdp#include "ldlex.h" 3633965Sjdp#include "ldmisc.h" 3733965Sjdp#include "ldctor.h" 3833965Sjdp#include "ldfile.h" 3977298Sobrien#include "ldemul.h" 4033965Sjdp#include "fnmatch.h" 4160484Sobrien#include "demangle.h" 42130561Sobrien#include "hashtab.h" 4333965Sjdp 44130561Sobrien#ifndef offsetof 45130561Sobrien#define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE*) 0)->MEMBER)) 46130561Sobrien#endif 4733965Sjdp 48130561Sobrien/* Locals variables. */ 4933965Sjdpstatic struct obstack stat_obstack; 50218822Sdimstatic struct obstack map_obstack; 5133965Sjdp 5233965Sjdp#define obstack_chunk_alloc xmalloc 5333965Sjdp#define obstack_chunk_free free 5477298Sobrienstatic const char *startup_file; 55130561Sobrienstatic bfd_boolean placed_commons = FALSE; 56218822Sdimstatic bfd_boolean stripped_excluded_sections = FALSE; 5733965Sjdpstatic lang_output_section_statement_type *default_common_section; 58130561Sobrienstatic bfd_boolean map_option_f; 5933965Sjdpstatic bfd_vma print_dot; 6033965Sjdpstatic lang_input_statement_type *first_file; 6177298Sobrienstatic const char *current_target; 6277298Sobrienstatic const char *output_target; 6333965Sjdpstatic lang_statement_list_type statement_list; 64130561Sobrienstatic struct bfd_hash_table lang_definedness_table; 6533965Sjdp 66130561Sobrien/* Forward declarations. */ 67130561Sobrienstatic void exp_init_os (etree_type *); 68218822Sdimstatic void init_map_userdata (bfd *, asection *, void *); 69130561Sobrienstatic lang_input_statement_type *lookup_name (const char *); 70130561Sobrienstatic struct bfd_hash_entry *lang_definedness_newfunc 71130561Sobrien (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); 72130561Sobrienstatic void insert_undefined (const char *); 73218822Sdimstatic bfd_boolean sort_def_symbol (struct bfd_link_hash_entry *, void *); 74130561Sobrienstatic void print_statement (lang_statement_union_type *, 75130561Sobrien lang_output_section_statement_type *); 76130561Sobrienstatic void print_statement_list (lang_statement_union_type *, 77130561Sobrien lang_output_section_statement_type *); 78130561Sobrienstatic void print_statements (void); 79218822Sdimstatic void print_input_section (asection *); 80130561Sobrienstatic bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *); 81130561Sobrienstatic void lang_record_phdrs (void); 82130561Sobrienstatic void lang_do_version_exports_section (void); 83218822Sdimstatic void lang_finalize_version_expr_head 84218822Sdim (struct bfd_elf_version_expr_head *); 8533965Sjdp 86130561Sobrien/* Exported variables. */ 8733965Sjdplang_output_section_statement_type *abs_output_section; 8868765Sobrienlang_statement_list_type lang_output_section_statement; 8933965Sjdplang_statement_list_type *stat_ptr = &statement_list; 9060484Sobrienlang_statement_list_type file_chain = { NULL, NULL }; 91218822Sdimlang_statement_list_type input_file_chain; 92104834Sobrienstruct bfd_sym_chain entry_symbol = { NULL, NULL }; 93218822Sdimstatic const char *entry_symbol_default = "start"; 9491041Sobrienconst char *entry_section = ".text"; 95130561Sobrienbfd_boolean entry_from_cmdline; 96130561Sobrienbfd_boolean lang_has_input_file = FALSE; 97130561Sobrienbfd_boolean had_output_filename = FALSE; 98130561Sobrienbfd_boolean lang_float_flag = FALSE; 99130561Sobrienbfd_boolean delete_output_file_on_failure = FALSE; 100218822Sdimstruct lang_phdr *lang_phdr_list; 10133965Sjdpstruct lang_nocrossrefs *nocrossref_list; 102218822Sdimstatic struct unique_sections *unique_section_list; 103130561Sobrienstatic bfd_boolean ldlang_sysrooted_script = FALSE; 104218822Sdim 105218822Sdim /* Functions that traverse the linker script and might evaluate 106218822Sdim DEFINED() need to increment this. */ 107130561Sobrienint lang_statement_iteration = 0; 10833965Sjdp 10933965Sjdpetree_type *base; /* Relocation base - or null */ 11033965Sjdp 111218822Sdim/* Return TRUE if the PATTERN argument is a wildcard pattern. 112218822Sdim Although backslashes are treated specially if a pattern contains 113218822Sdim wildcards, we do not consider the mere presence of a backslash to 114218822Sdim be enough to cause the pattern to be treated as a wildcard. 115218822Sdim That lets us handle DOS filenames more naturally. */ 116218822Sdim#define wildcardp(pattern) (strpbrk ((pattern), "?*[") != NULL) 117218822Sdim 11878828Sobrien#define new_stat(x, y) \ 119130561Sobrien (x##_type *) new_statement (x##_enum, sizeof (x##_type), y) 12033965Sjdp 12178828Sobrien#define outside_section_address(q) \ 12278828Sobrien ((q)->output_offset + (q)->output_section->vma) 12333965Sjdp 12478828Sobrien#define outside_symbol_address(q) \ 12578828Sobrien ((q)->value + outside_section_address (q->section)) 12633965Sjdp 12733965Sjdp#define SECTION_NAME_MAP_LENGTH (16) 12833965Sjdp 129130561Sobrienvoid * 130130561Sobrienstat_alloc (size_t size) 13133965Sjdp{ 13233965Sjdp return obstack_alloc (&stat_obstack, size); 13333965Sjdp} 13433965Sjdp 135130561Sobrienbfd_boolean 136218822Sdimunique_section_p (const asection *sec) 13777298Sobrien{ 13877298Sobrien struct unique_sections *unam; 139218822Sdim const char *secnam; 14060484Sobrien 141218822Sdim if (link_info.relocatable 142218822Sdim && sec->owner != NULL 143218822Sdim && bfd_is_group_section (sec->owner, sec)) 144218822Sdim return TRUE; 145218822Sdim 146218822Sdim secnam = sec->name; 14777298Sobrien for (unam = unique_section_list; unam; unam = unam->next) 14877298Sobrien if (wildcardp (unam->name) 14977298Sobrien ? fnmatch (unam->name, secnam, 0) == 0 15077298Sobrien : strcmp (unam->name, secnam) == 0) 15177298Sobrien { 152130561Sobrien return TRUE; 15377298Sobrien } 15477298Sobrien 155130561Sobrien return FALSE; 15677298Sobrien} 15777298Sobrien 15877298Sobrien/* Generic traversal routines for finding matching sections. */ 15977298Sobrien 160218822Sdim/* Try processing a section against a wildcard. This just calls 161218822Sdim the callback unless the filename exclusion list is present 162218822Sdim and excludes the file. It's hardly ever present so this 163218822Sdim function is very fast. */ 164218822Sdim 16560484Sobrienstatic void 166218822Sdimwalk_wild_consider_section (lang_wild_statement_type *ptr, 167218822Sdim lang_input_statement_type *file, 168218822Sdim asection *s, 169218822Sdim struct wildcard_list *sec, 170218822Sdim callback_t callback, 171218822Sdim void *data) 17260484Sobrien{ 173218822Sdim bfd_boolean skip = FALSE; 174218822Sdim struct name_list *list_tmp; 175218822Sdim 176218822Sdim /* Don't process sections from files which were 177218822Sdim excluded. */ 178218822Sdim for (list_tmp = sec->spec.exclude_name_list; 179218822Sdim list_tmp; 180218822Sdim list_tmp = list_tmp->next) 181218822Sdim { 182218822Sdim bfd_boolean is_wildcard = wildcardp (list_tmp->name); 183218822Sdim if (is_wildcard) 184218822Sdim skip = fnmatch (list_tmp->name, file->filename, 0) == 0; 185218822Sdim else 186218822Sdim skip = strcmp (list_tmp->name, file->filename) == 0; 187218822Sdim 188218822Sdim /* If this file is part of an archive, and the archive is 189218822Sdim excluded, exclude this file. */ 190218822Sdim if (! skip && file->the_bfd != NULL 191218822Sdim && file->the_bfd->my_archive != NULL 192218822Sdim && file->the_bfd->my_archive->filename != NULL) 193218822Sdim { 194218822Sdim if (is_wildcard) 195218822Sdim skip = fnmatch (list_tmp->name, 196218822Sdim file->the_bfd->my_archive->filename, 197218822Sdim 0) == 0; 198218822Sdim else 199218822Sdim skip = strcmp (list_tmp->name, 200218822Sdim file->the_bfd->my_archive->filename) == 0; 201218822Sdim } 202218822Sdim 203218822Sdim if (skip) 204218822Sdim break; 205218822Sdim } 206218822Sdim 207218822Sdim if (!skip) 208218822Sdim (*callback) (ptr, sec, s, file, data); 209218822Sdim} 210218822Sdim 211218822Sdim/* Lowest common denominator routine that can handle everything correctly, 212218822Sdim but slowly. */ 213218822Sdim 214218822Sdimstatic void 215218822Sdimwalk_wild_section_general (lang_wild_statement_type *ptr, 216218822Sdim lang_input_statement_type *file, 217218822Sdim callback_t callback, 218218822Sdim void *data) 219218822Sdim{ 22089857Sobrien asection *s; 221218822Sdim struct wildcard_list *sec; 22289857Sobrien 22389857Sobrien for (s = file->the_bfd->sections; s != NULL; s = s->next) 22460484Sobrien { 22589857Sobrien sec = ptr->section_list; 22689857Sobrien if (sec == NULL) 22789857Sobrien (*callback) (ptr, sec, s, file, data); 22889857Sobrien 22989857Sobrien while (sec != NULL) 23077298Sobrien { 231130561Sobrien bfd_boolean skip = FALSE; 23260484Sobrien 233218822Sdim if (sec->spec.name != NULL) 23489857Sobrien { 23589857Sobrien const char *sname = bfd_get_section_name (file->the_bfd, s); 23660484Sobrien 23789857Sobrien if (wildcardp (sec->spec.name)) 23889857Sobrien skip = fnmatch (sec->spec.name, sname, 0) != 0; 23989857Sobrien else 24089857Sobrien skip = strcmp (sec->spec.name, sname) != 0; 24189857Sobrien } 24260484Sobrien 24389857Sobrien if (!skip) 244218822Sdim walk_wild_consider_section (ptr, file, s, sec, callback, data); 24560484Sobrien 24689857Sobrien sec = sec->next; 24760484Sobrien } 24860484Sobrien } 24960484Sobrien} 25060484Sobrien 251218822Sdim/* Routines to find a single section given its name. If there's more 252218822Sdim than one section with that name, we report that. */ 253218822Sdim 254218822Sdimtypedef struct 255218822Sdim{ 256218822Sdim asection *found_section; 257218822Sdim bfd_boolean multiple_sections_found; 258218822Sdim} section_iterator_callback_data; 259218822Sdim 260218822Sdimstatic bfd_boolean 261218822Sdimsection_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data) 262218822Sdim{ 263218822Sdim section_iterator_callback_data *d = data; 264218822Sdim 265218822Sdim if (d->found_section != NULL) 266218822Sdim { 267218822Sdim d->multiple_sections_found = TRUE; 268218822Sdim return TRUE; 269218822Sdim } 270218822Sdim 271218822Sdim d->found_section = s; 272218822Sdim return FALSE; 273218822Sdim} 274218822Sdim 275218822Sdimstatic asection * 276218822Sdimfind_section (lang_input_statement_type *file, 277218822Sdim struct wildcard_list *sec, 278218822Sdim bfd_boolean *multiple_sections_found) 279218822Sdim{ 280218822Sdim section_iterator_callback_data cb_data = { NULL, FALSE }; 281218822Sdim 282218822Sdim bfd_get_section_by_name_if (file->the_bfd, sec->spec.name, 283218822Sdim section_iterator_callback, &cb_data); 284218822Sdim *multiple_sections_found = cb_data.multiple_sections_found; 285218822Sdim return cb_data.found_section; 286218822Sdim} 287218822Sdim 288218822Sdim/* Code for handling simple wildcards without going through fnmatch, 289218822Sdim which can be expensive because of charset translations etc. */ 290218822Sdim 291218822Sdim/* A simple wild is a literal string followed by a single '*', 292218822Sdim where the literal part is at least 4 characters long. */ 293218822Sdim 294218822Sdimstatic bfd_boolean 295218822Sdimis_simple_wild (const char *name) 296218822Sdim{ 297218822Sdim size_t len = strcspn (name, "*?["); 298218822Sdim return len >= 4 && name[len] == '*' && name[len + 1] == '\0'; 299218822Sdim} 300218822Sdim 301218822Sdimstatic bfd_boolean 302218822Sdimmatch_simple_wild (const char *pattern, const char *name) 303218822Sdim{ 304218822Sdim /* The first four characters of the pattern are guaranteed valid 305218822Sdim non-wildcard characters. So we can go faster. */ 306218822Sdim if (pattern[0] != name[0] || pattern[1] != name[1] 307218822Sdim || pattern[2] != name[2] || pattern[3] != name[3]) 308218822Sdim return FALSE; 309218822Sdim 310218822Sdim pattern += 4; 311218822Sdim name += 4; 312218822Sdim while (*pattern != '*') 313218822Sdim if (*name++ != *pattern++) 314218822Sdim return FALSE; 315218822Sdim 316218822Sdim return TRUE; 317218822Sdim} 318218822Sdim 319218822Sdim/* Compare sections ASEC and BSEC according to SORT. */ 320218822Sdim 321218822Sdimstatic int 322218822Sdimcompare_section (sort_type sort, asection *asec, asection *bsec) 323218822Sdim{ 324218822Sdim int ret; 325218822Sdim 326218822Sdim switch (sort) 327218822Sdim { 328218822Sdim default: 329218822Sdim abort (); 330218822Sdim 331218822Sdim case by_alignment_name: 332218822Sdim ret = (bfd_section_alignment (bsec->owner, bsec) 333218822Sdim - bfd_section_alignment (asec->owner, asec)); 334218822Sdim if (ret) 335218822Sdim break; 336218822Sdim /* Fall through. */ 337218822Sdim 338218822Sdim case by_name: 339218822Sdim ret = strcmp (bfd_get_section_name (asec->owner, asec), 340218822Sdim bfd_get_section_name (bsec->owner, bsec)); 341218822Sdim break; 342218822Sdim 343218822Sdim case by_name_alignment: 344218822Sdim ret = strcmp (bfd_get_section_name (asec->owner, asec), 345218822Sdim bfd_get_section_name (bsec->owner, bsec)); 346218822Sdim if (ret) 347218822Sdim break; 348218822Sdim /* Fall through. */ 349218822Sdim 350218822Sdim case by_alignment: 351218822Sdim ret = (bfd_section_alignment (bsec->owner, bsec) 352218822Sdim - bfd_section_alignment (asec->owner, asec)); 353218822Sdim break; 354218822Sdim } 355218822Sdim 356218822Sdim return ret; 357218822Sdim} 358218822Sdim 359218822Sdim/* Build a Binary Search Tree to sort sections, unlike insertion sort 360218822Sdim used in wild_sort(). BST is considerably faster if the number of 361218822Sdim of sections are large. */ 362218822Sdim 363218822Sdimstatic lang_section_bst_type ** 364218822Sdimwild_sort_fast (lang_wild_statement_type *wild, 365218822Sdim struct wildcard_list *sec, 366218822Sdim lang_input_statement_type *file ATTRIBUTE_UNUSED, 367218822Sdim asection *section) 368218822Sdim{ 369218822Sdim lang_section_bst_type **tree; 370218822Sdim 371218822Sdim tree = &wild->tree; 372218822Sdim if (!wild->filenames_sorted 373218822Sdim && (sec == NULL || sec->spec.sorted == none)) 374218822Sdim { 375218822Sdim /* Append at the right end of tree. */ 376218822Sdim while (*tree) 377218822Sdim tree = &((*tree)->right); 378218822Sdim return tree; 379218822Sdim } 380218822Sdim 381218822Sdim while (*tree) 382218822Sdim { 383218822Sdim /* Find the correct node to append this section. */ 384218822Sdim if (compare_section (sec->spec.sorted, section, (*tree)->section) < 0) 385218822Sdim tree = &((*tree)->left); 386218822Sdim else 387218822Sdim tree = &((*tree)->right); 388218822Sdim } 389218822Sdim 390218822Sdim return tree; 391218822Sdim} 392218822Sdim 393218822Sdim/* Use wild_sort_fast to build a BST to sort sections. */ 394218822Sdim 395218822Sdimstatic void 396218822Sdimoutput_section_callback_fast (lang_wild_statement_type *ptr, 397218822Sdim struct wildcard_list *sec, 398218822Sdim asection *section, 399218822Sdim lang_input_statement_type *file, 400218822Sdim void *output ATTRIBUTE_UNUSED) 401218822Sdim{ 402218822Sdim lang_section_bst_type *node; 403218822Sdim lang_section_bst_type **tree; 404218822Sdim 405218822Sdim if (unique_section_p (section)) 406218822Sdim return; 407218822Sdim 408218822Sdim node = xmalloc (sizeof (lang_section_bst_type)); 409218822Sdim node->left = 0; 410218822Sdim node->right = 0; 411218822Sdim node->section = section; 412218822Sdim 413218822Sdim tree = wild_sort_fast (ptr, sec, file, section); 414218822Sdim if (tree != NULL) 415218822Sdim *tree = node; 416218822Sdim} 417218822Sdim 418218822Sdim/* Convert a sorted sections' BST back to list form. */ 419218822Sdim 420218822Sdimstatic void 421218822Sdimoutput_section_callback_tree_to_list (lang_wild_statement_type *ptr, 422218822Sdim lang_section_bst_type *tree, 423218822Sdim void *output) 424218822Sdim{ 425218822Sdim if (tree->left) 426218822Sdim output_section_callback_tree_to_list (ptr, tree->left, output); 427218822Sdim 428218822Sdim lang_add_section (&ptr->children, tree->section, 429218822Sdim (lang_output_section_statement_type *) output); 430218822Sdim 431218822Sdim if (tree->right) 432218822Sdim output_section_callback_tree_to_list (ptr, tree->right, output); 433218822Sdim 434218822Sdim free (tree); 435218822Sdim} 436218822Sdim 437218822Sdim/* Specialized, optimized routines for handling different kinds of 438218822Sdim wildcards */ 439218822Sdim 440218822Sdimstatic void 441218822Sdimwalk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr, 442218822Sdim lang_input_statement_type *file, 443218822Sdim callback_t callback, 444218822Sdim void *data) 445218822Sdim{ 446218822Sdim /* We can just do a hash lookup for the section with the right name. 447218822Sdim But if that lookup discovers more than one section with the name 448218822Sdim (should be rare), we fall back to the general algorithm because 449218822Sdim we would otherwise have to sort the sections to make sure they 450218822Sdim get processed in the bfd's order. */ 451218822Sdim bfd_boolean multiple_sections_found; 452218822Sdim struct wildcard_list *sec0 = ptr->handler_data[0]; 453218822Sdim asection *s0 = find_section (file, sec0, &multiple_sections_found); 454218822Sdim 455218822Sdim if (multiple_sections_found) 456218822Sdim walk_wild_section_general (ptr, file, callback, data); 457218822Sdim else if (s0) 458218822Sdim walk_wild_consider_section (ptr, file, s0, sec0, callback, data); 459218822Sdim} 460218822Sdim 461218822Sdimstatic void 462218822Sdimwalk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr, 463218822Sdim lang_input_statement_type *file, 464218822Sdim callback_t callback, 465218822Sdim void *data) 466218822Sdim{ 467218822Sdim asection *s; 468218822Sdim struct wildcard_list *wildsec0 = ptr->handler_data[0]; 469218822Sdim 470218822Sdim for (s = file->the_bfd->sections; s != NULL; s = s->next) 471218822Sdim { 472218822Sdim const char *sname = bfd_get_section_name (file->the_bfd, s); 473218822Sdim bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname); 474218822Sdim 475218822Sdim if (!skip) 476218822Sdim walk_wild_consider_section (ptr, file, s, wildsec0, callback, data); 477218822Sdim } 478218822Sdim} 479218822Sdim 480218822Sdimstatic void 481218822Sdimwalk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr, 482218822Sdim lang_input_statement_type *file, 483218822Sdim callback_t callback, 484218822Sdim void *data) 485218822Sdim{ 486218822Sdim asection *s; 487218822Sdim struct wildcard_list *sec0 = ptr->handler_data[0]; 488218822Sdim struct wildcard_list *wildsec1 = ptr->handler_data[1]; 489218822Sdim bfd_boolean multiple_sections_found; 490218822Sdim asection *s0 = find_section (file, sec0, &multiple_sections_found); 491218822Sdim 492218822Sdim if (multiple_sections_found) 493218822Sdim { 494218822Sdim walk_wild_section_general (ptr, file, callback, data); 495218822Sdim return; 496218822Sdim } 497218822Sdim 498218822Sdim /* Note that if the section was not found, s0 is NULL and 499218822Sdim we'll simply never succeed the s == s0 test below. */ 500218822Sdim for (s = file->the_bfd->sections; s != NULL; s = s->next) 501218822Sdim { 502218822Sdim /* Recall that in this code path, a section cannot satisfy more 503218822Sdim than one spec, so if s == s0 then it cannot match 504218822Sdim wildspec1. */ 505218822Sdim if (s == s0) 506218822Sdim walk_wild_consider_section (ptr, file, s, sec0, callback, data); 507218822Sdim else 508218822Sdim { 509218822Sdim const char *sname = bfd_get_section_name (file->the_bfd, s); 510218822Sdim bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname); 511218822Sdim 512218822Sdim if (!skip) 513218822Sdim walk_wild_consider_section (ptr, file, s, wildsec1, callback, 514218822Sdim data); 515218822Sdim } 516218822Sdim } 517218822Sdim} 518218822Sdim 519218822Sdimstatic void 520218822Sdimwalk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr, 521218822Sdim lang_input_statement_type *file, 522218822Sdim callback_t callback, 523218822Sdim void *data) 524218822Sdim{ 525218822Sdim asection *s; 526218822Sdim struct wildcard_list *sec0 = ptr->handler_data[0]; 527218822Sdim struct wildcard_list *wildsec1 = ptr->handler_data[1]; 528218822Sdim struct wildcard_list *wildsec2 = ptr->handler_data[2]; 529218822Sdim bfd_boolean multiple_sections_found; 530218822Sdim asection *s0 = find_section (file, sec0, &multiple_sections_found); 531218822Sdim 532218822Sdim if (multiple_sections_found) 533218822Sdim { 534218822Sdim walk_wild_section_general (ptr, file, callback, data); 535218822Sdim return; 536218822Sdim } 537218822Sdim 538218822Sdim for (s = file->the_bfd->sections; s != NULL; s = s->next) 539218822Sdim { 540218822Sdim if (s == s0) 541218822Sdim walk_wild_consider_section (ptr, file, s, sec0, callback, data); 542218822Sdim else 543218822Sdim { 544218822Sdim const char *sname = bfd_get_section_name (file->the_bfd, s); 545218822Sdim bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname); 546218822Sdim 547218822Sdim if (!skip) 548218822Sdim walk_wild_consider_section (ptr, file, s, wildsec1, callback, data); 549218822Sdim else 550218822Sdim { 551218822Sdim skip = !match_simple_wild (wildsec2->spec.name, sname); 552218822Sdim if (!skip) 553218822Sdim walk_wild_consider_section (ptr, file, s, wildsec2, callback, 554218822Sdim data); 555218822Sdim } 556218822Sdim } 557218822Sdim } 558218822Sdim} 559218822Sdim 560218822Sdimstatic void 561218822Sdimwalk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr, 562218822Sdim lang_input_statement_type *file, 563218822Sdim callback_t callback, 564218822Sdim void *data) 565218822Sdim{ 566218822Sdim asection *s; 567218822Sdim struct wildcard_list *sec0 = ptr->handler_data[0]; 568218822Sdim struct wildcard_list *sec1 = ptr->handler_data[1]; 569218822Sdim struct wildcard_list *wildsec2 = ptr->handler_data[2]; 570218822Sdim struct wildcard_list *wildsec3 = ptr->handler_data[3]; 571218822Sdim bfd_boolean multiple_sections_found; 572218822Sdim asection *s0 = find_section (file, sec0, &multiple_sections_found), *s1; 573218822Sdim 574218822Sdim if (multiple_sections_found) 575218822Sdim { 576218822Sdim walk_wild_section_general (ptr, file, callback, data); 577218822Sdim return; 578218822Sdim } 579218822Sdim 580218822Sdim s1 = find_section (file, sec1, &multiple_sections_found); 581218822Sdim if (multiple_sections_found) 582218822Sdim { 583218822Sdim walk_wild_section_general (ptr, file, callback, data); 584218822Sdim return; 585218822Sdim } 586218822Sdim 587218822Sdim for (s = file->the_bfd->sections; s != NULL; s = s->next) 588218822Sdim { 589218822Sdim if (s == s0) 590218822Sdim walk_wild_consider_section (ptr, file, s, sec0, callback, data); 591218822Sdim else 592218822Sdim if (s == s1) 593218822Sdim walk_wild_consider_section (ptr, file, s, sec1, callback, data); 594218822Sdim else 595218822Sdim { 596218822Sdim const char *sname = bfd_get_section_name (file->the_bfd, s); 597218822Sdim bfd_boolean skip = !match_simple_wild (wildsec2->spec.name, 598218822Sdim sname); 599218822Sdim 600218822Sdim if (!skip) 601218822Sdim walk_wild_consider_section (ptr, file, s, wildsec2, callback, 602218822Sdim data); 603218822Sdim else 604218822Sdim { 605218822Sdim skip = !match_simple_wild (wildsec3->spec.name, sname); 606218822Sdim if (!skip) 607218822Sdim walk_wild_consider_section (ptr, file, s, wildsec3, 608218822Sdim callback, data); 609218822Sdim } 610218822Sdim } 611218822Sdim } 612218822Sdim} 613218822Sdim 614218822Sdimstatic void 615218822Sdimwalk_wild_section (lang_wild_statement_type *ptr, 616218822Sdim lang_input_statement_type *file, 617218822Sdim callback_t callback, 618218822Sdim void *data) 619218822Sdim{ 620218822Sdim if (file->just_syms_flag) 621218822Sdim return; 622218822Sdim 623218822Sdim (*ptr->walk_wild_section_handler) (ptr, file, callback, data); 624218822Sdim} 625218822Sdim 626218822Sdim/* Returns TRUE when name1 is a wildcard spec that might match 627218822Sdim something name2 can match. We're conservative: we return FALSE 628218822Sdim only if the prefixes of name1 and name2 are different up to the 629218822Sdim first wildcard character. */ 630218822Sdim 631218822Sdimstatic bfd_boolean 632218822Sdimwild_spec_can_overlap (const char *name1, const char *name2) 633218822Sdim{ 634218822Sdim size_t prefix1_len = strcspn (name1, "?*["); 635218822Sdim size_t prefix2_len = strcspn (name2, "?*["); 636218822Sdim size_t min_prefix_len; 637218822Sdim 638218822Sdim /* Note that if there is no wildcard character, then we treat the 639218822Sdim terminating 0 as part of the prefix. Thus ".text" won't match 640218822Sdim ".text." or ".text.*", for example. */ 641218822Sdim if (name1[prefix1_len] == '\0') 642218822Sdim prefix1_len++; 643218822Sdim if (name2[prefix2_len] == '\0') 644218822Sdim prefix2_len++; 645218822Sdim 646218822Sdim min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len; 647218822Sdim 648218822Sdim return memcmp (name1, name2, min_prefix_len) == 0; 649218822Sdim} 650218822Sdim 651218822Sdim/* Select specialized code to handle various kinds of wildcard 652218822Sdim statements. */ 653218822Sdim 654218822Sdimstatic void 655218822Sdimanalyze_walk_wild_section_handler (lang_wild_statement_type *ptr) 656218822Sdim{ 657218822Sdim int sec_count = 0; 658218822Sdim int wild_name_count = 0; 659218822Sdim struct wildcard_list *sec; 660218822Sdim int signature; 661218822Sdim int data_counter; 662218822Sdim 663218822Sdim ptr->walk_wild_section_handler = walk_wild_section_general; 664218822Sdim ptr->handler_data[0] = NULL; 665218822Sdim ptr->handler_data[1] = NULL; 666218822Sdim ptr->handler_data[2] = NULL; 667218822Sdim ptr->handler_data[3] = NULL; 668218822Sdim ptr->tree = NULL; 669218822Sdim 670218822Sdim /* Count how many wildcard_specs there are, and how many of those 671218822Sdim actually use wildcards in the name. Also, bail out if any of the 672218822Sdim wildcard names are NULL. (Can this actually happen? 673218822Sdim walk_wild_section used to test for it.) And bail out if any 674218822Sdim of the wildcards are more complex than a simple string 675218822Sdim ending in a single '*'. */ 676218822Sdim for (sec = ptr->section_list; sec != NULL; sec = sec->next) 677218822Sdim { 678218822Sdim ++sec_count; 679218822Sdim if (sec->spec.name == NULL) 680218822Sdim return; 681218822Sdim if (wildcardp (sec->spec.name)) 682218822Sdim { 683218822Sdim ++wild_name_count; 684218822Sdim if (!is_simple_wild (sec->spec.name)) 685218822Sdim return; 686218822Sdim } 687218822Sdim } 688218822Sdim 689218822Sdim /* The zero-spec case would be easy to optimize but it doesn't 690218822Sdim happen in practice. Likewise, more than 4 specs doesn't 691218822Sdim happen in practice. */ 692218822Sdim if (sec_count == 0 || sec_count > 4) 693218822Sdim return; 694218822Sdim 695218822Sdim /* Check that no two specs can match the same section. */ 696218822Sdim for (sec = ptr->section_list; sec != NULL; sec = sec->next) 697218822Sdim { 698218822Sdim struct wildcard_list *sec2; 699218822Sdim for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next) 700218822Sdim { 701218822Sdim if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name)) 702218822Sdim return; 703218822Sdim } 704218822Sdim } 705218822Sdim 706218822Sdim signature = (sec_count << 8) + wild_name_count; 707218822Sdim switch (signature) 708218822Sdim { 709218822Sdim case 0x0100: 710218822Sdim ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0; 711218822Sdim break; 712218822Sdim case 0x0101: 713218822Sdim ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1; 714218822Sdim break; 715218822Sdim case 0x0201: 716218822Sdim ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1; 717218822Sdim break; 718218822Sdim case 0x0302: 719218822Sdim ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2; 720218822Sdim break; 721218822Sdim case 0x0402: 722218822Sdim ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2; 723218822Sdim break; 724218822Sdim default: 725218822Sdim return; 726218822Sdim } 727218822Sdim 728218822Sdim /* Now fill the data array with pointers to the specs, first the 729218822Sdim specs with non-wildcard names, then the specs with wildcard 730218822Sdim names. It's OK to process the specs in different order from the 731218822Sdim given order, because we've already determined that no section 732218822Sdim will match more than one spec. */ 733218822Sdim data_counter = 0; 734218822Sdim for (sec = ptr->section_list; sec != NULL; sec = sec->next) 735218822Sdim if (!wildcardp (sec->spec.name)) 736218822Sdim ptr->handler_data[data_counter++] = sec; 737218822Sdim for (sec = ptr->section_list; sec != NULL; sec = sec->next) 738218822Sdim if (wildcardp (sec->spec.name)) 739218822Sdim ptr->handler_data[data_counter++] = sec; 740218822Sdim} 741218822Sdim 74260484Sobrien/* Handle a wild statement for a single file F. */ 74360484Sobrien 74460484Sobrienstatic void 745130561Sobrienwalk_wild_file (lang_wild_statement_type *s, 746130561Sobrien lang_input_statement_type *f, 747130561Sobrien callback_t callback, 748130561Sobrien void *data) 74960484Sobrien{ 75060484Sobrien if (f->the_bfd == NULL 75160484Sobrien || ! bfd_check_format (f->the_bfd, bfd_archive)) 75289857Sobrien walk_wild_section (s, f, callback, data); 75360484Sobrien else 75460484Sobrien { 75560484Sobrien bfd *member; 75660484Sobrien 75760484Sobrien /* This is an archive file. We must map each member of the 75860484Sobrien archive separately. */ 759130561Sobrien member = bfd_openr_next_archived_file (f->the_bfd, NULL); 76060484Sobrien while (member != NULL) 76160484Sobrien { 76260484Sobrien /* When lookup_name is called, it will call the add_symbols 76360484Sobrien entry point for the archive. For each element of the 76460484Sobrien archive which is included, BFD will call ldlang_add_file, 76560484Sobrien which will set the usrdata field of the member to the 76660484Sobrien lang_input_statement. */ 76760484Sobrien if (member->usrdata != NULL) 76860484Sobrien { 769130561Sobrien walk_wild_section (s, member->usrdata, callback, data); 77060484Sobrien } 77160484Sobrien 77260484Sobrien member = bfd_openr_next_archived_file (f->the_bfd, member); 77360484Sobrien } 77460484Sobrien } 77560484Sobrien} 77660484Sobrien 77760484Sobrienstatic void 778130561Sobrienwalk_wild (lang_wild_statement_type *s, callback_t callback, void *data) 77960484Sobrien{ 78089857Sobrien const char *file_spec = s->filename; 78189857Sobrien 78289857Sobrien if (file_spec == NULL) 78360484Sobrien { 78460484Sobrien /* Perform the iteration over all files in the list. */ 78560484Sobrien LANG_FOR_EACH_INPUT_STATEMENT (f) 78660484Sobrien { 78789857Sobrien walk_wild_file (s, f, callback, data); 78860484Sobrien } 78960484Sobrien } 79089857Sobrien else if (wildcardp (file_spec)) 79160484Sobrien { 79260484Sobrien LANG_FOR_EACH_INPUT_STATEMENT (f) 79360484Sobrien { 794218822Sdim if (fnmatch (file_spec, f->filename, 0) == 0) 79589857Sobrien walk_wild_file (s, f, callback, data); 79660484Sobrien } 79760484Sobrien } 79860484Sobrien else 79960484Sobrien { 80060484Sobrien lang_input_statement_type *f; 80160484Sobrien 80260484Sobrien /* Perform the iteration over a single file. */ 80389857Sobrien f = lookup_name (file_spec); 80489857Sobrien if (f) 80589857Sobrien walk_wild_file (s, f, callback, data); 80660484Sobrien } 80777298Sobrien} 80833965Sjdp 80977298Sobrien/* lang_for_each_statement walks the parse tree and calls the provided 81077298Sobrien function for each node. */ 81177298Sobrien 81233965Sjdpstatic void 813130561Sobrienlang_for_each_statement_worker (void (*func) (lang_statement_union_type *), 814130561Sobrien lang_statement_union_type *s) 81533965Sjdp{ 816130561Sobrien for (; s != NULL; s = s->header.next) 81733965Sjdp { 81833965Sjdp func (s); 81933965Sjdp 82033965Sjdp switch (s->header.type) 82133965Sjdp { 82233965Sjdp case lang_constructors_statement_enum: 82333965Sjdp lang_for_each_statement_worker (func, constructor_list.head); 82433965Sjdp break; 82533965Sjdp case lang_output_section_statement_enum: 82633965Sjdp lang_for_each_statement_worker 827218822Sdim (func, s->output_section_statement.children.head); 82833965Sjdp break; 82933965Sjdp case lang_wild_statement_enum: 830218822Sdim lang_for_each_statement_worker (func, 831218822Sdim s->wild_statement.children.head); 83233965Sjdp break; 83333965Sjdp case lang_group_statement_enum: 83433965Sjdp lang_for_each_statement_worker (func, 83533965Sjdp s->group_statement.children.head); 83633965Sjdp break; 83733965Sjdp case lang_data_statement_enum: 83833965Sjdp case lang_reloc_statement_enum: 83933965Sjdp case lang_object_symbols_statement_enum: 84033965Sjdp case lang_output_statement_enum: 84133965Sjdp case lang_target_statement_enum: 84233965Sjdp case lang_input_section_enum: 84333965Sjdp case lang_input_statement_enum: 84433965Sjdp case lang_assignment_statement_enum: 84533965Sjdp case lang_padding_statement_enum: 84633965Sjdp case lang_address_statement_enum: 84733965Sjdp case lang_fill_statement_enum: 84833965Sjdp break; 84933965Sjdp default: 85033965Sjdp FAIL (); 85133965Sjdp break; 85233965Sjdp } 85333965Sjdp } 85433965Sjdp} 85533965Sjdp 85633965Sjdpvoid 857130561Sobrienlang_for_each_statement (void (*func) (lang_statement_union_type *)) 85833965Sjdp{ 85977298Sobrien lang_for_each_statement_worker (func, statement_list.head); 86033965Sjdp} 86133965Sjdp 86233965Sjdp/*----------------------------------------------------------------------*/ 86377298Sobrien 86433965Sjdpvoid 865130561Sobrienlang_list_init (lang_statement_list_type *list) 86633965Sjdp{ 867130561Sobrien list->head = NULL; 86833965Sjdp list->tail = &list->head; 86933965Sjdp} 87033965Sjdp 87177298Sobrien/* Build a new statement node for the parse tree. */ 87233965Sjdp 87377298Sobrienstatic lang_statement_union_type * 874130561Sobriennew_statement (enum statement_enum type, 875130561Sobrien size_t size, 876130561Sobrien lang_statement_list_type *list) 87733965Sjdp{ 878130561Sobrien lang_statement_union_type *new; 87933965Sjdp 880130561Sobrien new = stat_alloc (size); 88133965Sjdp new->header.type = type; 882130561Sobrien new->header.next = NULL; 88333965Sjdp lang_statement_append (list, new, &new->header.next); 88433965Sjdp return new; 88533965Sjdp} 88633965Sjdp 88777298Sobrien/* Build a new input file node for the language. There are several 88877298Sobrien ways in which we treat an input file, eg, we only look at symbols, 88977298Sobrien or prefix it with a -l etc. 89033965Sjdp 89177298Sobrien We can be supplied with requests for input files more than once; 892130561Sobrien they may, for example be split over several lines like foo.o(.text) 89378828Sobrien foo.o(.data) etc, so when asked for a file we check that we haven't 89477298Sobrien got it already so we don't duplicate the bfd. */ 89533965Sjdp 89633965Sjdpstatic lang_input_statement_type * 897130561Sobriennew_afile (const char *name, 898130561Sobrien lang_input_file_enum_type file_type, 899130561Sobrien const char *target, 900130561Sobrien bfd_boolean add_to_list) 90133965Sjdp{ 90233965Sjdp lang_input_statement_type *p; 90333965Sjdp 90433965Sjdp if (add_to_list) 90533965Sjdp p = new_stat (lang_input_statement, stat_ptr); 90633965Sjdp else 90733965Sjdp { 908130561Sobrien p = stat_alloc (sizeof (lang_input_statement_type)); 909218822Sdim p->header.type = lang_input_statement_enum; 91033965Sjdp p->header.next = NULL; 91133965Sjdp } 91233965Sjdp 913130561Sobrien lang_has_input_file = TRUE; 91433965Sjdp p->target = target; 915130561Sobrien p->sysrooted = FALSE; 916218822Sdim 917218822Sdim if (file_type == lang_input_file_is_l_enum 918218822Sdim && name[0] == ':' && name[1] != '\0') 919218822Sdim { 920218822Sdim file_type = lang_input_file_is_search_file_enum; 921218822Sdim name = name + 1; 922218822Sdim } 923218822Sdim 92433965Sjdp switch (file_type) 92533965Sjdp { 92633965Sjdp case lang_input_file_is_symbols_only_enum: 92733965Sjdp p->filename = name; 928130561Sobrien p->is_archive = FALSE; 929130561Sobrien p->real = TRUE; 93033965Sjdp p->local_sym_name = name; 931130561Sobrien p->just_syms_flag = TRUE; 932130561Sobrien p->search_dirs_flag = FALSE; 93333965Sjdp break; 93433965Sjdp case lang_input_file_is_fake_enum: 93533965Sjdp p->filename = name; 936130561Sobrien p->is_archive = FALSE; 937130561Sobrien p->real = FALSE; 93833965Sjdp p->local_sym_name = name; 939130561Sobrien p->just_syms_flag = FALSE; 940130561Sobrien p->search_dirs_flag = FALSE; 94133965Sjdp break; 94233965Sjdp case lang_input_file_is_l_enum: 943130561Sobrien p->is_archive = TRUE; 94433965Sjdp p->filename = name; 945130561Sobrien p->real = TRUE; 946130561Sobrien p->local_sym_name = concat ("-l", name, NULL); 947130561Sobrien p->just_syms_flag = FALSE; 948130561Sobrien p->search_dirs_flag = TRUE; 94933965Sjdp break; 95033965Sjdp case lang_input_file_is_marker_enum: 95133965Sjdp p->filename = name; 952130561Sobrien p->is_archive = FALSE; 953130561Sobrien p->real = FALSE; 95433965Sjdp p->local_sym_name = name; 955130561Sobrien p->just_syms_flag = FALSE; 956130561Sobrien p->search_dirs_flag = TRUE; 95733965Sjdp break; 95833965Sjdp case lang_input_file_is_search_file_enum: 959130561Sobrien p->sysrooted = ldlang_sysrooted_script; 96033965Sjdp p->filename = name; 961130561Sobrien p->is_archive = FALSE; 962130561Sobrien p->real = TRUE; 96333965Sjdp p->local_sym_name = name; 964130561Sobrien p->just_syms_flag = FALSE; 965130561Sobrien p->search_dirs_flag = TRUE; 96633965Sjdp break; 96733965Sjdp case lang_input_file_is_file_enum: 96833965Sjdp p->filename = name; 969130561Sobrien p->is_archive = FALSE; 970130561Sobrien p->real = TRUE; 97133965Sjdp p->local_sym_name = name; 972130561Sobrien p->just_syms_flag = FALSE; 973130561Sobrien p->search_dirs_flag = FALSE; 97433965Sjdp break; 97533965Sjdp default: 97633965Sjdp FAIL (); 97733965Sjdp } 978130561Sobrien p->the_bfd = NULL; 979130561Sobrien p->asymbols = NULL; 980130561Sobrien p->next_real_file = NULL; 981130561Sobrien p->next = NULL; 98233965Sjdp p->symbol_count = 0; 98333965Sjdp p->dynamic = config.dynamic_link; 984218822Sdim p->add_needed = add_needed; 985130561Sobrien p->as_needed = as_needed; 98633965Sjdp p->whole_archive = whole_archive; 987130561Sobrien p->loaded = FALSE; 98833965Sjdp lang_statement_append (&input_file_chain, 98933965Sjdp (lang_statement_union_type *) p, 99033965Sjdp &p->next_real_file); 99133965Sjdp return p; 99233965Sjdp} 99333965Sjdp 99433965Sjdplang_input_statement_type * 995130561Sobrienlang_add_input_file (const char *name, 996130561Sobrien lang_input_file_enum_type file_type, 997130561Sobrien const char *target) 99833965Sjdp{ 999130561Sobrien return new_afile (name, file_type, target, TRUE); 100033965Sjdp} 100133965Sjdp 1002218822Sdimstruct out_section_hash_entry 1003218822Sdim{ 1004218822Sdim struct bfd_hash_entry root; 1005218822Sdim lang_statement_union_type s; 1006218822Sdim}; 1007218822Sdim 1008218822Sdim/* The hash table. */ 1009218822Sdim 1010218822Sdimstatic struct bfd_hash_table output_section_statement_table; 1011218822Sdim 1012218822Sdim/* Support routines for the hash table used by lang_output_section_find, 1013218822Sdim initialize the table, fill in an entry and remove the table. */ 1014218822Sdim 1015218822Sdimstatic struct bfd_hash_entry * 1016218822Sdimoutput_section_statement_newfunc (struct bfd_hash_entry *entry, 1017218822Sdim struct bfd_hash_table *table, 1018218822Sdim const char *string) 1019218822Sdim{ 1020218822Sdim lang_output_section_statement_type **nextp; 1021218822Sdim struct out_section_hash_entry *ret; 1022218822Sdim 1023218822Sdim if (entry == NULL) 1024218822Sdim { 1025218822Sdim entry = bfd_hash_allocate (table, sizeof (*ret)); 1026218822Sdim if (entry == NULL) 1027218822Sdim return entry; 1028218822Sdim } 1029218822Sdim 1030218822Sdim entry = bfd_hash_newfunc (entry, table, string); 1031218822Sdim if (entry == NULL) 1032218822Sdim return entry; 1033218822Sdim 1034218822Sdim ret = (struct out_section_hash_entry *) entry; 1035218822Sdim memset (&ret->s, 0, sizeof (ret->s)); 1036218822Sdim ret->s.header.type = lang_output_section_statement_enum; 1037218822Sdim ret->s.output_section_statement.subsection_alignment = -1; 1038218822Sdim ret->s.output_section_statement.section_alignment = -1; 1039218822Sdim ret->s.output_section_statement.block_value = 1; 1040218822Sdim lang_list_init (&ret->s.output_section_statement.children); 1041218822Sdim lang_statement_append (stat_ptr, &ret->s, &ret->s.header.next); 1042218822Sdim 1043218822Sdim /* For every output section statement added to the list, except the 1044218822Sdim first one, lang_output_section_statement.tail points to the "next" 1045218822Sdim field of the last element of the list. */ 1046218822Sdim if (lang_output_section_statement.head != NULL) 1047218822Sdim ret->s.output_section_statement.prev 1048218822Sdim = ((lang_output_section_statement_type *) 1049218822Sdim ((char *) lang_output_section_statement.tail 1050218822Sdim - offsetof (lang_output_section_statement_type, next))); 1051218822Sdim 1052218822Sdim /* GCC's strict aliasing rules prevent us from just casting the 1053218822Sdim address, so we store the pointer in a variable and cast that 1054218822Sdim instead. */ 1055218822Sdim nextp = &ret->s.output_section_statement.next; 1056218822Sdim lang_statement_append (&lang_output_section_statement, 1057218822Sdim &ret->s, 1058218822Sdim (lang_statement_union_type **) nextp); 1059218822Sdim return &ret->root; 1060218822Sdim} 1061218822Sdim 1062218822Sdimstatic void 1063218822Sdimoutput_section_statement_table_init (void) 1064218822Sdim{ 1065218822Sdim if (!bfd_hash_table_init_n (&output_section_statement_table, 1066218822Sdim output_section_statement_newfunc, 1067218822Sdim sizeof (struct out_section_hash_entry), 1068218822Sdim 61)) 1069218822Sdim einfo (_("%P%F: can not create hash table: %E\n")); 1070218822Sdim} 1071218822Sdim 1072218822Sdimstatic void 1073218822Sdimoutput_section_statement_table_free (void) 1074218822Sdim{ 1075218822Sdim bfd_hash_table_free (&output_section_statement_table); 1076218822Sdim} 1077218822Sdim 107877298Sobrien/* Build enough state so that the parser can build its tree. */ 107977298Sobrien 108033965Sjdpvoid 1081130561Sobrienlang_init (void) 108233965Sjdp{ 108333965Sjdp obstack_begin (&stat_obstack, 1000); 108433965Sjdp 108533965Sjdp stat_ptr = &statement_list; 108633965Sjdp 1087218822Sdim output_section_statement_table_init (); 1088218822Sdim 108933965Sjdp lang_list_init (stat_ptr); 109033965Sjdp 109133965Sjdp lang_list_init (&input_file_chain); 109233965Sjdp lang_list_init (&lang_output_section_statement); 109333965Sjdp lang_list_init (&file_chain); 1094130561Sobrien first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum, 1095130561Sobrien NULL); 109677298Sobrien abs_output_section = 109777298Sobrien lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME); 109833965Sjdp 109933965Sjdp abs_output_section->bfd_section = bfd_abs_section_ptr; 110033965Sjdp 1101130561Sobrien /* The value "3" is ad-hoc, somewhat related to the expected number of 1102130561Sobrien DEFINED expressions in a linker script. For most default linker 1103130561Sobrien scripts, there are none. Why a hash table then? Well, it's somewhat 1104130561Sobrien simpler to re-use working machinery than using a linked list in terms 1105130561Sobrien of code-complexity here in ld, besides the initialization which just 1106130561Sobrien looks like other code here. */ 1107218822Sdim if (!bfd_hash_table_init_n (&lang_definedness_table, 1108218822Sdim lang_definedness_newfunc, 1109218822Sdim sizeof (struct lang_definedness_hash_entry), 1110218822Sdim 3)) 1111218822Sdim einfo (_("%P%F: can not create hash table: %E\n")); 1112218822Sdim} 1113130561Sobrien 1114218822Sdimvoid 1115218822Sdimlang_finish (void) 1116218822Sdim{ 1117218822Sdim output_section_statement_table_free (); 111833965Sjdp} 111933965Sjdp 112033965Sjdp/*---------------------------------------------------------------------- 112177298Sobrien A region is an area of memory declared with the 112277298Sobrien MEMORY { name:org=exp, len=exp ... } 112377298Sobrien syntax. 112433965Sjdp 112577298Sobrien We maintain a list of all the regions here. 112633965Sjdp 112777298Sobrien If no regions are specified in the script, then the default is used 1128130561Sobrien which is created when looked up to be the entire data space. 112933965Sjdp 1130130561Sobrien If create is true we are creating a region inside a MEMORY block. 1131130561Sobrien In this case it is probably an error to create a region that has 1132130561Sobrien already been created. If we are not inside a MEMORY block it is 1133130561Sobrien dubious to use an undeclared region name (except DEFAULT_MEMORY_REGION) 1134130561Sobrien and so we issue a warning. */ 1135130561Sobrien 113633965Sjdpstatic lang_memory_region_type *lang_memory_region_list; 1137218822Sdimstatic lang_memory_region_type **lang_memory_region_list_tail 1138218822Sdim = &lang_memory_region_list; 113933965Sjdp 114033965Sjdplang_memory_region_type * 1141130561Sobrienlang_memory_region_lookup (const char *const name, bfd_boolean create) 114233965Sjdp{ 114338889Sjdp lang_memory_region_type *p; 1144130561Sobrien lang_memory_region_type *new; 114533965Sjdp 1146104834Sobrien /* NAME is NULL for LMA memspecs if no region was specified. */ 1147104834Sobrien if (name == NULL) 1148104834Sobrien return NULL; 1149104834Sobrien 1150130561Sobrien for (p = lang_memory_region_list; p != NULL; p = p->next) 1151130561Sobrien if (strcmp (p->name, name) == 0) 1152130561Sobrien { 1153130561Sobrien if (create) 1154218822Sdim einfo (_("%P:%S: warning: redeclaration of memory region '%s'\n"), 1155218822Sdim name); 1156130561Sobrien return p; 1157130561Sobrien } 115833965Sjdp 1159130561Sobrien if (!create && strcmp (name, DEFAULT_MEMORY_REGION)) 1160130561Sobrien einfo (_("%P:%S: warning: memory region %s not declared\n"), name); 116133965Sjdp 1162130561Sobrien new = stat_alloc (sizeof (lang_memory_region_type)); 116333965Sjdp 1164130561Sobrien new->name = xstrdup (name); 1165130561Sobrien new->next = NULL; 1166130561Sobrien new->origin = 0; 1167218822Sdim new->length = ~(bfd_size_type) 0; 1168218822Sdim new->current = 0; 1169218822Sdim new->last_os = NULL; 1170130561Sobrien new->flags = 0; 1171130561Sobrien new->not_flags = 0; 1172130561Sobrien new->had_full_message = FALSE; 1173130561Sobrien 1174218822Sdim *lang_memory_region_list_tail = new; 1175218822Sdim lang_memory_region_list_tail = &new->next; 1176218822Sdim 1177130561Sobrien return new; 117833965Sjdp} 117933965Sjdp 118077298Sobrienstatic lang_memory_region_type * 1181130561Sobrienlang_memory_default (asection *section) 118238889Sjdp{ 118338889Sjdp lang_memory_region_type *p; 118438889Sjdp 118538889Sjdp flagword sec_flags = section->flags; 118638889Sjdp 118738889Sjdp /* Override SEC_DATA to mean a writable section. */ 118838889Sjdp if ((sec_flags & (SEC_ALLOC | SEC_READONLY | SEC_CODE)) == SEC_ALLOC) 118938889Sjdp sec_flags |= SEC_DATA; 119038889Sjdp 1191130561Sobrien for (p = lang_memory_region_list; p != NULL; p = p->next) 119238889Sjdp { 119338889Sjdp if ((p->flags & sec_flags) != 0 119438889Sjdp && (p->not_flags & sec_flags) == 0) 119538889Sjdp { 119638889Sjdp return p; 119738889Sjdp } 119838889Sjdp } 1199130561Sobrien return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE); 120038889Sjdp} 120138889Sjdp 120233965Sjdplang_output_section_statement_type * 1203130561Sobrienlang_output_section_find (const char *const name) 120433965Sjdp{ 1205218822Sdim struct out_section_hash_entry *entry; 1206218822Sdim unsigned long hash; 120733965Sjdp 1208218822Sdim entry = ((struct out_section_hash_entry *) 1209218822Sdim bfd_hash_lookup (&output_section_statement_table, name, 1210218822Sdim FALSE, FALSE)); 1211218822Sdim if (entry == NULL) 1212218822Sdim return NULL; 1213218822Sdim 1214218822Sdim hash = entry->root.hash; 1215218822Sdim do 121633965Sjdp { 1217218822Sdim if (entry->s.output_section_statement.constraint != -1) 1218218822Sdim return &entry->s.output_section_statement; 1219218822Sdim entry = (struct out_section_hash_entry *) entry->root.next; 122033965Sjdp } 1221218822Sdim while (entry != NULL 1222218822Sdim && entry->root.hash == hash 1223218822Sdim && strcmp (name, entry->s.output_section_statement.name) == 0); 1224218822Sdim 1225130561Sobrien return NULL; 122633965Sjdp} 122733965Sjdp 1228218822Sdimstatic lang_output_section_statement_type * 1229218822Sdimlang_output_section_statement_lookup_1 (const char *const name, int constraint) 1230218822Sdim{ 1231218822Sdim struct out_section_hash_entry *entry; 1232218822Sdim struct out_section_hash_entry *last_ent; 1233218822Sdim unsigned long hash; 1234218822Sdim 1235218822Sdim entry = ((struct out_section_hash_entry *) 1236218822Sdim bfd_hash_lookup (&output_section_statement_table, name, 1237218822Sdim TRUE, FALSE)); 1238218822Sdim if (entry == NULL) 1239218822Sdim { 1240218822Sdim einfo (_("%P%F: failed creating section `%s': %E\n"), name); 1241218822Sdim return NULL; 1242218822Sdim } 1243218822Sdim 1244218822Sdim if (entry->s.output_section_statement.name != NULL) 1245218822Sdim { 1246218822Sdim /* We have a section of this name, but it might not have the correct 1247218822Sdim constraint. */ 1248218822Sdim hash = entry->root.hash; 1249218822Sdim do 1250218822Sdim { 1251218822Sdim if (entry->s.output_section_statement.constraint != -1 1252218822Sdim && (constraint == 0 1253218822Sdim || (constraint == entry->s.output_section_statement.constraint 1254218822Sdim && constraint != SPECIAL))) 1255218822Sdim return &entry->s.output_section_statement; 1256218822Sdim last_ent = entry; 1257218822Sdim entry = (struct out_section_hash_entry *) entry->root.next; 1258218822Sdim } 1259218822Sdim while (entry != NULL 1260218822Sdim && entry->root.hash == hash 1261218822Sdim && strcmp (name, entry->s.output_section_statement.name) == 0); 1262218822Sdim 1263218822Sdim entry 1264218822Sdim = ((struct out_section_hash_entry *) 1265218822Sdim output_section_statement_newfunc (NULL, 1266218822Sdim &output_section_statement_table, 1267218822Sdim name)); 1268218822Sdim if (entry == NULL) 1269218822Sdim { 1270218822Sdim einfo (_("%P%F: failed creating section `%s': %E\n"), name); 1271218822Sdim return NULL; 1272218822Sdim } 1273218822Sdim entry->root = last_ent->root; 1274218822Sdim last_ent->root.next = &entry->root; 1275218822Sdim } 1276218822Sdim 1277218822Sdim entry->s.output_section_statement.name = name; 1278218822Sdim entry->s.output_section_statement.constraint = constraint; 1279218822Sdim return &entry->s.output_section_statement; 1280218822Sdim} 1281218822Sdim 128233965Sjdplang_output_section_statement_type * 1283130561Sobrienlang_output_section_statement_lookup (const char *const name) 128433965Sjdp{ 1285218822Sdim return lang_output_section_statement_lookup_1 (name, 0); 1286218822Sdim} 1287218822Sdim 1288218822Sdim/* A variant of lang_output_section_find used by place_orphan. 1289218822Sdim Returns the output statement that should precede a new output 1290218822Sdim statement for SEC. If an exact match is found on certain flags, 1291218822Sdim sets *EXACT too. */ 1292218822Sdim 1293218822Sdimlang_output_section_statement_type * 1294218822Sdimlang_output_section_find_by_flags (const asection *sec, 1295218822Sdim lang_output_section_statement_type **exact, 1296218822Sdim lang_match_sec_type_func match_type) 1297218822Sdim{ 1298218822Sdim lang_output_section_statement_type *first, *look, *found; 1299218822Sdim flagword flags; 1300218822Sdim 1301218822Sdim /* We know the first statement on this list is *ABS*. May as well 1302218822Sdim skip it. */ 1303218822Sdim first = &lang_output_section_statement.head->output_section_statement; 1304218822Sdim first = first->next; 1305218822Sdim 1306218822Sdim /* First try for an exact match. */ 1307218822Sdim found = NULL; 1308218822Sdim for (look = first; look; look = look->next) 1309218822Sdim { 1310218822Sdim flags = look->flags; 1311218822Sdim if (look->bfd_section != NULL) 1312218822Sdim { 1313218822Sdim flags = look->bfd_section->flags; 1314218822Sdim if (match_type && !match_type (output_bfd, look->bfd_section, 1315218822Sdim sec->owner, sec)) 1316218822Sdim continue; 1317218822Sdim } 1318218822Sdim flags ^= sec->flags; 1319218822Sdim if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY 1320218822Sdim | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL))) 1321218822Sdim found = look; 1322218822Sdim } 1323218822Sdim if (found != NULL) 1324218822Sdim { 1325218822Sdim if (exact != NULL) 1326218822Sdim *exact = found; 1327218822Sdim return found; 1328218822Sdim } 1329218822Sdim 1330218822Sdim if (sec->flags & SEC_CODE) 1331218822Sdim { 1332218822Sdim /* Try for a rw code section. */ 1333218822Sdim for (look = first; look; look = look->next) 1334218822Sdim { 1335218822Sdim flags = look->flags; 1336218822Sdim if (look->bfd_section != NULL) 1337218822Sdim { 1338218822Sdim flags = look->bfd_section->flags; 1339218822Sdim if (match_type && !match_type (output_bfd, look->bfd_section, 1340218822Sdim sec->owner, sec)) 1341218822Sdim continue; 1342218822Sdim } 1343218822Sdim flags ^= sec->flags; 1344218822Sdim if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD 1345218822Sdim | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL))) 1346218822Sdim found = look; 1347218822Sdim } 1348218822Sdim } 1349218822Sdim else if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL)) 1350218822Sdim { 1351218822Sdim /* .rodata can go after .text, .sdata2 after .rodata. */ 1352218822Sdim for (look = first; look; look = look->next) 1353218822Sdim { 1354218822Sdim flags = look->flags; 1355218822Sdim if (look->bfd_section != NULL) 1356218822Sdim { 1357218822Sdim flags = look->bfd_section->flags; 1358218822Sdim if (match_type && !match_type (output_bfd, look->bfd_section, 1359218822Sdim sec->owner, sec)) 1360218822Sdim continue; 1361218822Sdim } 1362218822Sdim flags ^= sec->flags; 1363218822Sdim if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD 1364218822Sdim | SEC_READONLY)) 1365218822Sdim && !(look->flags & (SEC_SMALL_DATA | SEC_THREAD_LOCAL))) 1366218822Sdim found = look; 1367218822Sdim } 1368218822Sdim } 1369218822Sdim else if (sec->flags & SEC_SMALL_DATA) 1370218822Sdim { 1371218822Sdim /* .sdata goes after .data, .sbss after .sdata. */ 1372218822Sdim for (look = first; look; look = look->next) 1373218822Sdim { 1374218822Sdim flags = look->flags; 1375218822Sdim if (look->bfd_section != NULL) 1376218822Sdim { 1377218822Sdim flags = look->bfd_section->flags; 1378218822Sdim if (match_type && !match_type (output_bfd, look->bfd_section, 1379218822Sdim sec->owner, sec)) 1380218822Sdim continue; 1381218822Sdim } 1382218822Sdim flags ^= sec->flags; 1383218822Sdim if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD 1384218822Sdim | SEC_THREAD_LOCAL)) 1385218822Sdim || ((look->flags & SEC_SMALL_DATA) 1386218822Sdim && !(sec->flags & SEC_HAS_CONTENTS))) 1387218822Sdim found = look; 1388218822Sdim } 1389218822Sdim } 1390218822Sdim else if (sec->flags & SEC_HAS_CONTENTS) 1391218822Sdim { 1392218822Sdim /* .data goes after .rodata. */ 1393218822Sdim for (look = first; look; look = look->next) 1394218822Sdim { 1395218822Sdim flags = look->flags; 1396218822Sdim if (look->bfd_section != NULL) 1397218822Sdim { 1398218822Sdim flags = look->bfd_section->flags; 1399218822Sdim if (match_type && !match_type (output_bfd, look->bfd_section, 1400218822Sdim sec->owner, sec)) 1401218822Sdim continue; 1402218822Sdim } 1403218822Sdim flags ^= sec->flags; 1404218822Sdim if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD 1405218822Sdim | SEC_SMALL_DATA | SEC_THREAD_LOCAL))) 1406218822Sdim found = look; 1407218822Sdim } 1408218822Sdim } 1409218822Sdim else 1410218822Sdim { 1411218822Sdim /* .bss goes last. */ 1412218822Sdim for (look = first; look; look = look->next) 1413218822Sdim { 1414218822Sdim flags = look->flags; 1415218822Sdim if (look->bfd_section != NULL) 1416218822Sdim { 1417218822Sdim flags = look->bfd_section->flags; 1418218822Sdim if (match_type && !match_type (output_bfd, look->bfd_section, 1419218822Sdim sec->owner, sec)) 1420218822Sdim continue; 1421218822Sdim } 1422218822Sdim flags ^= sec->flags; 1423218822Sdim if (!(flags & SEC_ALLOC)) 1424218822Sdim found = look; 1425218822Sdim } 1426218822Sdim } 1427218822Sdim 1428218822Sdim if (found || !match_type) 1429218822Sdim return found; 1430218822Sdim 1431218822Sdim return lang_output_section_find_by_flags (sec, NULL, NULL); 1432218822Sdim} 1433218822Sdim 1434218822Sdim/* Find the last output section before given output statement. 1435218822Sdim Used by place_orphan. */ 1436218822Sdim 1437218822Sdimstatic asection * 1438218822Sdimoutput_prev_sec_find (lang_output_section_statement_type *os) 1439218822Sdim{ 144033965Sjdp lang_output_section_statement_type *lookup; 144133965Sjdp 1442218822Sdim for (lookup = os->prev; lookup != NULL; lookup = lookup->prev) 144333965Sjdp { 1444218822Sdim if (lookup->constraint == -1) 1445218822Sdim continue; 144633965Sjdp 1447218822Sdim if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL) 1448218822Sdim return lookup->bfd_section; 1449218822Sdim } 145033965Sjdp 1451218822Sdim return NULL; 1452218822Sdim} 145333965Sjdp 1454218822Sdimlang_output_section_statement_type * 1455218822Sdimlang_insert_orphan (asection *s, 1456218822Sdim const char *secname, 1457218822Sdim lang_output_section_statement_type *after, 1458218822Sdim struct orphan_save *place, 1459218822Sdim etree_type *address, 1460218822Sdim lang_statement_list_type *add_child) 1461218822Sdim{ 1462218822Sdim lang_statement_list_type *old; 1463218822Sdim lang_statement_list_type add; 1464218822Sdim const char *ps; 1465218822Sdim lang_output_section_statement_type *os; 1466218822Sdim lang_output_section_statement_type **os_tail; 1467218822Sdim 1468218822Sdim /* Start building a list of statements for this section. 1469218822Sdim First save the current statement pointer. */ 1470218822Sdim old = stat_ptr; 1471218822Sdim 1472218822Sdim /* If we have found an appropriate place for the output section 1473218822Sdim statements for this orphan, add them to our own private list, 1474218822Sdim inserting them later into the global statement list. */ 1475218822Sdim if (after != NULL) 1476218822Sdim { 1477218822Sdim stat_ptr = &add; 1478218822Sdim lang_list_init (stat_ptr); 147933965Sjdp } 1480218822Sdim 1481218822Sdim if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) 1482218822Sdim address = exp_intop (0); 1483218822Sdim 1484218822Sdim os_tail = ((lang_output_section_statement_type **) 1485218822Sdim lang_output_section_statement.tail); 1486218822Sdim os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL, 1487218822Sdim NULL, 0); 1488218822Sdim 1489218822Sdim ps = NULL; 1490218822Sdim if (config.build_constructors && *os_tail == os) 1491218822Sdim { 1492218822Sdim /* If the name of the section is representable in C, then create 1493218822Sdim symbols to mark the start and the end of the section. */ 1494218822Sdim for (ps = secname; *ps != '\0'; ps++) 1495218822Sdim if (! ISALNUM ((unsigned char) *ps) && *ps != '_') 1496218822Sdim break; 1497218822Sdim if (*ps == '\0') 1498218822Sdim { 1499218822Sdim char *symname; 1500218822Sdim etree_type *e_align; 1501218822Sdim 1502218822Sdim symname = (char *) xmalloc (ps - secname + sizeof "__start_" + 1); 1503218822Sdim symname[0] = bfd_get_symbol_leading_char (output_bfd); 1504218822Sdim sprintf (symname + (symname[0] != 0), "__start_%s", secname); 1505218822Sdim e_align = exp_unop (ALIGN_K, 1506218822Sdim exp_intop ((bfd_vma) 1 << s->alignment_power)); 1507218822Sdim lang_add_assignment (exp_assop ('=', ".", e_align)); 1508218822Sdim lang_add_assignment (exp_provide (symname, 1509218822Sdim exp_unop (ABSOLUTE, 1510218822Sdim exp_nameop (NAME, ".")), 1511218822Sdim FALSE)); 1512218822Sdim } 1513218822Sdim } 1514218822Sdim 1515218822Sdim if (add_child == NULL) 1516218822Sdim add_child = &os->children; 1517218822Sdim lang_add_section (add_child, s, os); 1518218822Sdim 1519218822Sdim lang_leave_output_section_statement (0, "*default*", NULL, NULL); 1520218822Sdim 1521218822Sdim if (ps != NULL && *ps == '\0') 1522218822Sdim { 1523218822Sdim char *symname; 1524218822Sdim 1525218822Sdim /* lang_leave_ouput_section_statement resets stat_ptr. 1526218822Sdim Put stat_ptr back where we want it. */ 1527218822Sdim if (after != NULL) 1528218822Sdim stat_ptr = &add; 1529218822Sdim 1530218822Sdim symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1); 1531218822Sdim symname[0] = bfd_get_symbol_leading_char (output_bfd); 1532218822Sdim sprintf (symname + (symname[0] != 0), "__stop_%s", secname); 1533218822Sdim lang_add_assignment (exp_provide (symname, 1534218822Sdim exp_nameop (NAME, "."), 1535218822Sdim FALSE)); 1536218822Sdim } 1537218822Sdim 1538218822Sdim /* Restore the global list pointer. */ 1539218822Sdim if (after != NULL) 1540218822Sdim stat_ptr = old; 1541218822Sdim 1542218822Sdim if (after != NULL && os->bfd_section != NULL) 1543218822Sdim { 1544218822Sdim asection *snew, *as; 1545218822Sdim 1546218822Sdim snew = os->bfd_section; 1547218822Sdim 1548218822Sdim /* Shuffle the bfd section list to make the output file look 1549218822Sdim neater. This is really only cosmetic. */ 1550218822Sdim if (place->section == NULL 1551218822Sdim && after != (&lang_output_section_statement.head 1552218822Sdim ->output_section_statement)) 1553218822Sdim { 1554218822Sdim asection *bfd_section = after->bfd_section; 1555218822Sdim 1556218822Sdim /* If the output statement hasn't been used to place any input 1557218822Sdim sections (and thus doesn't have an output bfd_section), 1558218822Sdim look for the closest prior output statement having an 1559218822Sdim output section. */ 1560218822Sdim if (bfd_section == NULL) 1561218822Sdim bfd_section = output_prev_sec_find (after); 1562218822Sdim 1563218822Sdim if (bfd_section != NULL && bfd_section != snew) 1564218822Sdim place->section = &bfd_section->next; 1565218822Sdim } 1566218822Sdim 1567218822Sdim if (place->section == NULL) 1568218822Sdim place->section = &output_bfd->sections; 1569218822Sdim 1570218822Sdim as = *place->section; 1571218822Sdim 1572218822Sdim if (!as) 1573218822Sdim { 1574218822Sdim /* Put the section at the end of the list. */ 1575218822Sdim 1576218822Sdim /* Unlink the section. */ 1577218822Sdim bfd_section_list_remove (output_bfd, snew); 1578218822Sdim 1579218822Sdim /* Now tack it back on in the right place. */ 1580218822Sdim bfd_section_list_append (output_bfd, snew); 1581218822Sdim } 1582218822Sdim else if (as != snew && as->prev != snew) 1583218822Sdim { 1584218822Sdim /* Unlink the section. */ 1585218822Sdim bfd_section_list_remove (output_bfd, snew); 1586218822Sdim 1587218822Sdim /* Now tack it back on in the right place. */ 1588218822Sdim bfd_section_list_insert_before (output_bfd, as, snew); 1589218822Sdim } 1590218822Sdim 1591218822Sdim /* Save the end of this list. Further ophans of this type will 1592218822Sdim follow the one we've just added. */ 1593218822Sdim place->section = &snew->next; 1594218822Sdim 1595218822Sdim /* The following is non-cosmetic. We try to put the output 1596218822Sdim statements in some sort of reasonable order here, because they 1597218822Sdim determine the final load addresses of the orphan sections. 1598218822Sdim In addition, placing output statements in the wrong order may 1599218822Sdim require extra segments. For instance, given a typical 1600218822Sdim situation of all read-only sections placed in one segment and 1601218822Sdim following that a segment containing all the read-write 1602218822Sdim sections, we wouldn't want to place an orphan read/write 1603218822Sdim section before or amongst the read-only ones. */ 1604218822Sdim if (add.head != NULL) 1605218822Sdim { 1606218822Sdim lang_output_section_statement_type *newly_added_os; 1607218822Sdim 1608218822Sdim if (place->stmt == NULL) 1609218822Sdim { 1610218822Sdim lang_statement_union_type **where; 1611218822Sdim lang_statement_union_type **assign = NULL; 1612218822Sdim bfd_boolean ignore_first; 1613218822Sdim 1614218822Sdim /* Look for a suitable place for the new statement list. 1615218822Sdim The idea is to skip over anything that might be inside 1616218822Sdim a SECTIONS {} statement in a script, before we find 1617218822Sdim another output_section_statement. Assignments to "dot" 1618218822Sdim before an output section statement are assumed to 1619218822Sdim belong to it. An exception to this rule is made for 1620218822Sdim the first assignment to dot, otherwise we might put an 1621218822Sdim orphan before . = . + SIZEOF_HEADERS or similar 1622218822Sdim assignments that set the initial address. */ 1623218822Sdim 1624218822Sdim ignore_first = after == (&lang_output_section_statement.head 1625218822Sdim ->output_section_statement); 1626218822Sdim for (where = &after->header.next; 1627218822Sdim *where != NULL; 1628218822Sdim where = &(*where)->header.next) 1629218822Sdim { 1630218822Sdim switch ((*where)->header.type) 1631218822Sdim { 1632218822Sdim case lang_assignment_statement_enum: 1633218822Sdim if (assign == NULL) 1634218822Sdim { 1635218822Sdim lang_assignment_statement_type *ass; 1636218822Sdim ass = &(*where)->assignment_statement; 1637218822Sdim if (ass->exp->type.node_class != etree_assert 1638218822Sdim && ass->exp->assign.dst[0] == '.' 1639218822Sdim && ass->exp->assign.dst[1] == 0 1640218822Sdim && !ignore_first) 1641218822Sdim assign = where; 1642218822Sdim } 1643218822Sdim ignore_first = FALSE; 1644218822Sdim continue; 1645218822Sdim case lang_wild_statement_enum: 1646218822Sdim case lang_input_section_enum: 1647218822Sdim case lang_object_symbols_statement_enum: 1648218822Sdim case lang_fill_statement_enum: 1649218822Sdim case lang_data_statement_enum: 1650218822Sdim case lang_reloc_statement_enum: 1651218822Sdim case lang_padding_statement_enum: 1652218822Sdim case lang_constructors_statement_enum: 1653218822Sdim assign = NULL; 1654218822Sdim continue; 1655218822Sdim case lang_output_section_statement_enum: 1656218822Sdim if (assign != NULL) 1657218822Sdim where = assign; 1658218822Sdim case lang_input_statement_enum: 1659218822Sdim case lang_address_statement_enum: 1660218822Sdim case lang_target_statement_enum: 1661218822Sdim case lang_output_statement_enum: 1662218822Sdim case lang_group_statement_enum: 1663218822Sdim case lang_afile_asection_pair_statement_enum: 1664218822Sdim break; 1665218822Sdim } 1666218822Sdim break; 1667218822Sdim } 1668218822Sdim 1669218822Sdim *add.tail = *where; 1670218822Sdim *where = add.head; 1671218822Sdim 1672218822Sdim place->os_tail = &after->next; 1673218822Sdim } 1674218822Sdim else 1675218822Sdim { 1676218822Sdim /* Put it after the last orphan statement we added. */ 1677218822Sdim *add.tail = *place->stmt; 1678218822Sdim *place->stmt = add.head; 1679218822Sdim } 1680218822Sdim 1681218822Sdim /* Fix the global list pointer if we happened to tack our 1682218822Sdim new list at the tail. */ 1683218822Sdim if (*old->tail == add.head) 1684218822Sdim old->tail = add.tail; 1685218822Sdim 1686218822Sdim /* Save the end of this list. */ 1687218822Sdim place->stmt = add.tail; 1688218822Sdim 1689218822Sdim /* Do the same for the list of output section statements. */ 1690218822Sdim newly_added_os = *os_tail; 1691218822Sdim *os_tail = NULL; 1692218822Sdim newly_added_os->prev = (lang_output_section_statement_type *) 1693218822Sdim ((char *) place->os_tail 1694218822Sdim - offsetof (lang_output_section_statement_type, next)); 1695218822Sdim newly_added_os->next = *place->os_tail; 1696218822Sdim if (newly_added_os->next != NULL) 1697218822Sdim newly_added_os->next->prev = newly_added_os; 1698218822Sdim *place->os_tail = newly_added_os; 1699218822Sdim place->os_tail = &newly_added_os->next; 1700218822Sdim 1701218822Sdim /* Fixing the global list pointer here is a little different. 1702218822Sdim We added to the list in lang_enter_output_section_statement, 1703218822Sdim trimmed off the new output_section_statment above when 1704218822Sdim assigning *os_tail = NULL, but possibly added it back in 1705218822Sdim the same place when assigning *place->os_tail. */ 1706218822Sdim if (*os_tail == NULL) 1707218822Sdim lang_output_section_statement.tail 1708218822Sdim = (lang_statement_union_type **) os_tail; 1709218822Sdim } 1710218822Sdim } 1711218822Sdim return os; 171233965Sjdp} 171333965Sjdp 171438889Sjdpstatic void 1715130561Sobrienlang_map_flags (flagword flag) 171638889Sjdp{ 171738889Sjdp if (flag & SEC_ALLOC) 171838889Sjdp minfo ("a"); 171938889Sjdp 172038889Sjdp if (flag & SEC_CODE) 172138889Sjdp minfo ("x"); 172238889Sjdp 172338889Sjdp if (flag & SEC_READONLY) 172438889Sjdp minfo ("r"); 172538889Sjdp 172638889Sjdp if (flag & SEC_DATA) 172738889Sjdp minfo ("w"); 172838889Sjdp 172938889Sjdp if (flag & SEC_LOAD) 173038889Sjdp minfo ("l"); 173138889Sjdp} 173238889Sjdp 173333965Sjdpvoid 1734130561Sobrienlang_map (void) 173533965Sjdp{ 173633965Sjdp lang_memory_region_type *m; 1737218822Sdim bfd_boolean dis_header_printed = FALSE; 1738218822Sdim bfd *p; 173933965Sjdp 1740218822Sdim LANG_FOR_EACH_INPUT_STATEMENT (file) 1741218822Sdim { 1742218822Sdim asection *s; 1743218822Sdim 1744218822Sdim if ((file->the_bfd->flags & (BFD_LINKER_CREATED | DYNAMIC)) != 0 1745218822Sdim || file->just_syms_flag) 1746218822Sdim continue; 1747218822Sdim 1748218822Sdim for (s = file->the_bfd->sections; s != NULL; s = s->next) 1749218822Sdim if ((s->output_section == NULL 1750218822Sdim || s->output_section->owner != output_bfd) 1751218822Sdim && (s->flags & (SEC_LINKER_CREATED | SEC_KEEP)) == 0) 1752218822Sdim { 1753218822Sdim if (! dis_header_printed) 1754218822Sdim { 1755218822Sdim fprintf (config.map_file, _("\nDiscarded input sections\n\n")); 1756218822Sdim dis_header_printed = TRUE; 1757218822Sdim } 1758218822Sdim 1759218822Sdim print_input_section (s); 1760218822Sdim } 1761218822Sdim } 1762218822Sdim 176360484Sobrien minfo (_("\nMemory Configuration\n\n")); 176438889Sjdp fprintf (config.map_file, "%-16s %-18s %-18s %s\n", 176560484Sobrien _("Name"), _("Origin"), _("Length"), _("Attributes")); 176633965Sjdp 1767130561Sobrien for (m = lang_memory_region_list; m != NULL; m = m->next) 176833965Sjdp { 176933965Sjdp char buf[100]; 177033965Sjdp int len; 177133965Sjdp 177233965Sjdp fprintf (config.map_file, "%-16s ", m->name); 177333965Sjdp 177433965Sjdp sprintf_vma (buf, m->origin); 177533965Sjdp minfo ("0x%s ", buf); 177633965Sjdp len = strlen (buf); 177733965Sjdp while (len < 16) 177833965Sjdp { 177933965Sjdp print_space (); 178033965Sjdp ++len; 178133965Sjdp } 178233965Sjdp 178338889Sjdp minfo ("0x%V", m->length); 178438889Sjdp if (m->flags || m->not_flags) 178538889Sjdp { 178638889Sjdp#ifndef BFD64 178738889Sjdp minfo (" "); 178838889Sjdp#endif 178938889Sjdp if (m->flags) 179038889Sjdp { 179138889Sjdp print_space (); 179238889Sjdp lang_map_flags (m->flags); 179338889Sjdp } 179438889Sjdp 179538889Sjdp if (m->not_flags) 179638889Sjdp { 179738889Sjdp minfo (" !"); 179838889Sjdp lang_map_flags (m->not_flags); 179938889Sjdp } 180038889Sjdp } 180138889Sjdp 180238889Sjdp print_nl (); 180333965Sjdp } 180433965Sjdp 180560484Sobrien fprintf (config.map_file, _("\nLinker script and memory map\n\n")); 180633965Sjdp 1807218822Sdim if (! link_info.reduce_memory_overheads) 1808218822Sdim { 1809218822Sdim obstack_begin (&map_obstack, 1000); 1810218822Sdim for (p = link_info.input_bfds; p != (bfd *) NULL; p = p->link_next) 1811218822Sdim bfd_map_over_sections (p, init_map_userdata, 0); 1812218822Sdim bfd_link_hash_traverse (link_info.hash, sort_def_symbol, 0); 1813218822Sdim } 181433965Sjdp print_statements (); 181533965Sjdp} 181633965Sjdp 1817218822Sdimstatic void 1818218822Sdiminit_map_userdata (abfd, sec, data) 1819218822Sdim bfd *abfd ATTRIBUTE_UNUSED; 1820218822Sdim asection *sec; 1821218822Sdim void *data ATTRIBUTE_UNUSED; 1822218822Sdim{ 1823218822Sdim fat_section_userdata_type *new_data 1824218822Sdim = ((fat_section_userdata_type *) (stat_alloc 1825218822Sdim (sizeof (fat_section_userdata_type)))); 1826218822Sdim 1827218822Sdim ASSERT (get_userdata (sec) == NULL); 1828218822Sdim get_userdata (sec) = new_data; 1829218822Sdim new_data->map_symbol_def_tail = &new_data->map_symbol_def_head; 1830218822Sdim} 1831218822Sdim 1832218822Sdimstatic bfd_boolean 1833218822Sdimsort_def_symbol (hash_entry, info) 1834218822Sdim struct bfd_link_hash_entry *hash_entry; 1835218822Sdim void *info ATTRIBUTE_UNUSED; 1836218822Sdim{ 1837218822Sdim if (hash_entry->type == bfd_link_hash_defined 1838218822Sdim || hash_entry->type == bfd_link_hash_defweak) 1839218822Sdim { 1840218822Sdim struct fat_user_section_struct *ud; 1841218822Sdim struct map_symbol_def *def; 1842218822Sdim 1843218822Sdim ud = get_userdata (hash_entry->u.def.section); 1844218822Sdim if (! ud) 1845218822Sdim { 1846218822Sdim /* ??? What do we have to do to initialize this beforehand? */ 1847218822Sdim /* The first time we get here is bfd_abs_section... */ 1848218822Sdim init_map_userdata (0, hash_entry->u.def.section, 0); 1849218822Sdim ud = get_userdata (hash_entry->u.def.section); 1850218822Sdim } 1851218822Sdim else if (!ud->map_symbol_def_tail) 1852218822Sdim ud->map_symbol_def_tail = &ud->map_symbol_def_head; 1853218822Sdim 1854218822Sdim def = obstack_alloc (&map_obstack, sizeof *def); 1855218822Sdim def->entry = hash_entry; 1856218822Sdim *(ud->map_symbol_def_tail) = def; 1857218822Sdim ud->map_symbol_def_tail = &def->next; 1858218822Sdim } 1859218822Sdim return TRUE; 1860218822Sdim} 1861218822Sdim 186233965Sjdp/* Initialize an output section. */ 186333965Sjdp 186433965Sjdpstatic void 1865218822Sdiminit_os (lang_output_section_statement_type *s, asection *isec, 1866218822Sdim flagword flags) 186733965Sjdp{ 186833965Sjdp if (s->bfd_section != NULL) 186933965Sjdp return; 187033965Sjdp 187133965Sjdp if (strcmp (s->name, DISCARD_SECTION_NAME) == 0) 187289857Sobrien einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME); 187333965Sjdp 187433965Sjdp s->bfd_section = bfd_get_section_by_name (output_bfd, s->name); 1875130561Sobrien if (s->bfd_section == NULL) 1876218822Sdim s->bfd_section = bfd_make_section_with_flags (output_bfd, s->name, 1877218822Sdim flags); 1878130561Sobrien if (s->bfd_section == NULL) 187933965Sjdp { 188060484Sobrien einfo (_("%P%F: output format %s cannot represent section called %s\n"), 188133965Sjdp output_bfd->xvec->name, s->name); 188233965Sjdp } 188333965Sjdp s->bfd_section->output_section = s->bfd_section; 188433965Sjdp s->bfd_section->output_offset = 0; 188533965Sjdp 1886218822Sdim if (!link_info.reduce_memory_overheads) 1887218822Sdim { 1888218822Sdim fat_section_userdata_type *new 1889218822Sdim = stat_alloc (sizeof (fat_section_userdata_type)); 1890218822Sdim memset (new, 0, sizeof (fat_section_userdata_type)); 1891218822Sdim get_userdata (s->bfd_section) = new; 1892218822Sdim } 1893218822Sdim 189433965Sjdp /* If there is a base address, make sure that any sections it might 189533965Sjdp mention are initialized. */ 189633965Sjdp if (s->addr_tree != NULL) 189733965Sjdp exp_init_os (s->addr_tree); 1898130561Sobrien 1899130561Sobrien if (s->load_base != NULL) 1900130561Sobrien exp_init_os (s->load_base); 1901218822Sdim 1902218822Sdim /* If supplied an alignment, set it. */ 1903218822Sdim if (s->section_alignment != -1) 1904218822Sdim s->bfd_section->alignment_power = s->section_alignment; 1905218822Sdim 1906218822Sdim if (isec) 1907218822Sdim bfd_init_private_section_data (isec->owner, isec, 1908218822Sdim output_bfd, s->bfd_section, 1909218822Sdim &link_info); 191033965Sjdp} 191133965Sjdp 191233965Sjdp/* Make sure that all output sections mentioned in an expression are 191333965Sjdp initialized. */ 191433965Sjdp 191533965Sjdpstatic void 1916130561Sobrienexp_init_os (etree_type *exp) 191733965Sjdp{ 191833965Sjdp switch (exp->type.node_class) 191933965Sjdp { 192033965Sjdp case etree_assign: 1921218822Sdim case etree_provide: 192233965Sjdp exp_init_os (exp->assign.src); 192333965Sjdp break; 192433965Sjdp 192533965Sjdp case etree_binary: 192633965Sjdp exp_init_os (exp->binary.lhs); 192733965Sjdp exp_init_os (exp->binary.rhs); 192833965Sjdp break; 192933965Sjdp 193033965Sjdp case etree_trinary: 193133965Sjdp exp_init_os (exp->trinary.cond); 193233965Sjdp exp_init_os (exp->trinary.lhs); 193333965Sjdp exp_init_os (exp->trinary.rhs); 193433965Sjdp break; 193533965Sjdp 1936130561Sobrien case etree_assert: 1937130561Sobrien exp_init_os (exp->assert_s.child); 1938130561Sobrien break; 1939218822Sdim 194033965Sjdp case etree_unary: 194133965Sjdp exp_init_os (exp->unary.child); 194233965Sjdp break; 194333965Sjdp 194433965Sjdp case etree_name: 194533965Sjdp switch (exp->type.node_code) 194633965Sjdp { 194733965Sjdp case ADDR: 194833965Sjdp case LOADADDR: 194933965Sjdp case SIZEOF: 195033965Sjdp { 195133965Sjdp lang_output_section_statement_type *os; 195233965Sjdp 195333965Sjdp os = lang_output_section_find (exp->name.name); 195433965Sjdp if (os != NULL && os->bfd_section == NULL) 1955218822Sdim init_os (os, NULL, 0); 195633965Sjdp } 195733965Sjdp } 195833965Sjdp break; 195933965Sjdp 196033965Sjdp default: 196133965Sjdp break; 196233965Sjdp } 196333965Sjdp} 196460484Sobrien 196533965Sjdpstatic void 1966130561Sobriensection_already_linked (bfd *abfd, asection *sec, void *data) 196733965Sjdp{ 1968130561Sobrien lang_input_statement_type *entry = data; 196933965Sjdp 197033965Sjdp /* If we are only reading symbols from this object, then we want to 197133965Sjdp discard all sections. */ 197233965Sjdp if (entry->just_syms_flag) 197333965Sjdp { 1974218822Sdim bfd_link_just_syms (abfd, sec, &link_info); 197533965Sjdp return; 197633965Sjdp } 197733965Sjdp 1978218822Sdim if (!(abfd->flags & DYNAMIC)) 1979218822Sdim bfd_section_already_linked (abfd, sec, &link_info); 198033965Sjdp} 198133965Sjdp 198233965Sjdp/* The wild routines. 198333965Sjdp 198433965Sjdp These expand statements like *(.text) and foo.o to a list of 198533965Sjdp explicit actions, like foo.o(.text), bar.o(.text) and 198633965Sjdp foo.o(.text, .data). */ 198733965Sjdp 198833965Sjdp/* Add SECTION to the output section OUTPUT. Do this by creating a 198933965Sjdp lang_input_section statement which is placed at PTR. FILE is the 199033965Sjdp input file which holds SECTION. */ 199133965Sjdp 199233965Sjdpvoid 1993130561Sobrienlang_add_section (lang_statement_list_type *ptr, 1994130561Sobrien asection *section, 1995218822Sdim lang_output_section_statement_type *output) 199633965Sjdp{ 1997218822Sdim flagword flags = section->flags; 1998130561Sobrien bfd_boolean discard; 199933965Sjdp 2000218822Sdim /* Discard sections marked with SEC_EXCLUDE. */ 2001218822Sdim discard = (flags & SEC_EXCLUDE) != 0; 200233965Sjdp 200333965Sjdp /* Discard input sections which are assigned to a section named 200433965Sjdp DISCARD_SECTION_NAME. */ 200533965Sjdp if (strcmp (output->name, DISCARD_SECTION_NAME) == 0) 2006130561Sobrien discard = TRUE; 200733965Sjdp 200833965Sjdp /* Discard debugging sections if we are stripping debugging 200933965Sjdp information. */ 201033965Sjdp if ((link_info.strip == strip_debugger || link_info.strip == strip_all) 201133965Sjdp && (flags & SEC_DEBUGGING) != 0) 2012130561Sobrien discard = TRUE; 201333965Sjdp 201433965Sjdp if (discard) 201533965Sjdp { 201633965Sjdp if (section->output_section == NULL) 201733965Sjdp { 201833965Sjdp /* This prevents future calls from assigning this section. */ 201933965Sjdp section->output_section = bfd_abs_section_ptr; 202033965Sjdp } 202133965Sjdp return; 202233965Sjdp } 202333965Sjdp 202433965Sjdp if (section->output_section == NULL) 202533965Sjdp { 2026130561Sobrien bfd_boolean first; 202733965Sjdp lang_input_section_type *new; 202838889Sjdp flagword flags; 202933965Sjdp 2030218822Sdim flags = section->flags; 2031218822Sdim 2032218822Sdim /* We don't copy the SEC_NEVER_LOAD flag from an input section 2033218822Sdim to an output section, because we want to be able to include a 2034218822Sdim SEC_NEVER_LOAD section in the middle of an otherwise loaded 2035218822Sdim section (I don't know why we want to do this, but we do). 2036218822Sdim build_link_order in ldwrite.c handles this case by turning 2037218822Sdim the embedded SEC_NEVER_LOAD section into a fill. */ 2038218822Sdim 2039218822Sdim flags &= ~ SEC_NEVER_LOAD; 2040218822Sdim 2041218822Sdim switch (output->sectype) 2042218822Sdim { 2043218822Sdim case normal_section: 2044218822Sdim case overlay_section: 2045218822Sdim break; 2046218822Sdim case noalloc_section: 2047218822Sdim flags &= ~SEC_ALLOC; 2048218822Sdim break; 2049218822Sdim case noload_section: 2050218822Sdim flags &= ~SEC_LOAD; 2051218822Sdim flags |= SEC_NEVER_LOAD; 2052218822Sdim break; 2053218822Sdim } 2054218822Sdim 205533965Sjdp if (output->bfd_section == NULL) 2056218822Sdim init_os (output, section, flags); 205733965Sjdp 205878828Sobrien first = ! output->bfd_section->linker_has_input; 205978828Sobrien output->bfd_section->linker_has_input = 1; 206078828Sobrien 2061218822Sdim if (!link_info.relocatable 2062218822Sdim && !stripped_excluded_sections) 2063218822Sdim { 2064218822Sdim asection *s = output->bfd_section->map_tail.s; 2065218822Sdim output->bfd_section->map_tail.s = section; 2066218822Sdim section->map_head.s = NULL; 2067218822Sdim section->map_tail.s = s; 2068218822Sdim if (s != NULL) 2069218822Sdim s->map_head.s = section; 2070218822Sdim else 2071218822Sdim output->bfd_section->map_head.s = section; 2072218822Sdim } 2073218822Sdim 207477298Sobrien /* Add a section reference to the list. */ 207533965Sjdp new = new_stat (lang_input_section, ptr); 207633965Sjdp 207733965Sjdp new->section = section; 207833965Sjdp section->output_section = output->bfd_section; 207933965Sjdp 208038889Sjdp /* If final link, don't copy the SEC_LINK_ONCE flags, they've 208138889Sjdp already been processed. One reason to do this is that on pe 208238889Sjdp format targets, .text$foo sections go into .text and it's odd 208338889Sjdp to see .text with SEC_LINK_ONCE set. */ 208433965Sjdp 2085130561Sobrien if (! link_info.relocatable) 208638889Sjdp flags &= ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES); 208738889Sjdp 208838889Sjdp /* If this is not the first input section, and the SEC_READONLY 2089218822Sdim flag is not currently set, then don't set it just because the 2090218822Sdim input section has it set. */ 209138889Sjdp 2092218822Sdim if (! first && (output->bfd_section->flags & SEC_READONLY) == 0) 209338889Sjdp flags &= ~ SEC_READONLY; 209438889Sjdp 209589857Sobrien /* Keep SEC_MERGE and SEC_STRINGS only if they are the same. */ 209689857Sobrien if (! first 2097218822Sdim && ((output->bfd_section->flags & (SEC_MERGE | SEC_STRINGS)) 209889857Sobrien != (flags & (SEC_MERGE | SEC_STRINGS)) 209989857Sobrien || ((flags & SEC_MERGE) 2100218822Sdim && output->bfd_section->entsize != section->entsize))) 210189857Sobrien { 2102218822Sdim output->bfd_section->flags &= ~ (SEC_MERGE | SEC_STRINGS); 210389857Sobrien flags &= ~ (SEC_MERGE | SEC_STRINGS); 210489857Sobrien } 210589857Sobrien 2106218822Sdim output->bfd_section->flags |= flags; 210738889Sjdp 210889857Sobrien if (flags & SEC_MERGE) 2109218822Sdim output->bfd_section->entsize = section->entsize; 211089857Sobrien 211138889Sjdp /* If SEC_READONLY is not set in the input section, then clear 2112218822Sdim it from the output section. */ 211338889Sjdp if ((section->flags & SEC_READONLY) == 0) 2114218822Sdim output->bfd_section->flags &= ~SEC_READONLY; 211538889Sjdp 211660484Sobrien /* Copy over SEC_SMALL_DATA. */ 211760484Sobrien if (section->flags & SEC_SMALL_DATA) 2118218822Sdim output->bfd_section->flags |= SEC_SMALL_DATA; 211960484Sobrien 212033965Sjdp if (section->alignment_power > output->bfd_section->alignment_power) 212133965Sjdp output->bfd_section->alignment_power = section->alignment_power; 212233965Sjdp 2123218822Sdim if (bfd_get_arch (section->owner) == bfd_arch_tic54x 2124218822Sdim && (section->flags & SEC_TIC54X_BLOCK) != 0) 212577298Sobrien { 2126218822Sdim output->bfd_section->flags |= SEC_TIC54X_BLOCK; 212777298Sobrien /* FIXME: This value should really be obtained from the bfd... */ 212877298Sobrien output->block_value = 128; 212977298Sobrien } 213033965Sjdp } 213133965Sjdp} 213233965Sjdp 213360484Sobrien/* Handle wildcard sorting. This returns the lang_input_section which 213460484Sobrien should follow the one we are going to create for SECTION and FILE, 213560484Sobrien based on the sorting requirements of WILD. It returns NULL if the 213660484Sobrien new section should just go at the end of the current list. */ 213733965Sjdp 213860484Sobrienstatic lang_statement_union_type * 2139130561Sobrienwild_sort (lang_wild_statement_type *wild, 2140130561Sobrien struct wildcard_list *sec, 2141130561Sobrien lang_input_statement_type *file, 2142130561Sobrien asection *section) 214333965Sjdp{ 214460484Sobrien const char *section_name; 214560484Sobrien lang_statement_union_type *l; 214660484Sobrien 2147218822Sdim if (!wild->filenames_sorted 2148218822Sdim && (sec == NULL || sec->spec.sorted == none)) 214960484Sobrien return NULL; 215060484Sobrien 215160484Sobrien section_name = bfd_get_section_name (file->the_bfd, section); 215289857Sobrien for (l = wild->children.head; l != NULL; l = l->header.next) 215333965Sjdp { 215460484Sobrien lang_input_section_type *ls; 215533965Sjdp 215660484Sobrien if (l->header.type != lang_input_section_enum) 215760484Sobrien continue; 215860484Sobrien ls = &l->input_section; 215933965Sjdp 216060484Sobrien /* Sorting by filename takes precedence over sorting by section 2161218822Sdim name. */ 216260484Sobrien 216360484Sobrien if (wild->filenames_sorted) 216433965Sjdp { 216560484Sobrien const char *fn, *ln; 2166130561Sobrien bfd_boolean fa, la; 216760484Sobrien int i; 216833965Sjdp 216960484Sobrien /* The PE support for the .idata section as generated by 2170218822Sdim dlltool assumes that files will be sorted by the name of 2171218822Sdim the archive and then the name of the file within the 2172218822Sdim archive. */ 217333965Sjdp 217460484Sobrien if (file->the_bfd != NULL 217560484Sobrien && bfd_my_archive (file->the_bfd) != NULL) 217660484Sobrien { 217760484Sobrien fn = bfd_get_filename (bfd_my_archive (file->the_bfd)); 2178130561Sobrien fa = TRUE; 217960484Sobrien } 218060484Sobrien else 218160484Sobrien { 218260484Sobrien fn = file->filename; 2183130561Sobrien fa = FALSE; 218460484Sobrien } 218533965Sjdp 2186218822Sdim if (bfd_my_archive (ls->section->owner) != NULL) 218760484Sobrien { 2188218822Sdim ln = bfd_get_filename (bfd_my_archive (ls->section->owner)); 2189130561Sobrien la = TRUE; 219060484Sobrien } 219133965Sjdp else 219233965Sjdp { 2193218822Sdim ln = ls->section->owner->filename; 2194130561Sobrien la = FALSE; 219560484Sobrien } 219633965Sjdp 219760484Sobrien i = strcmp (fn, ln); 219860484Sobrien if (i > 0) 219960484Sobrien continue; 220060484Sobrien else if (i < 0) 220160484Sobrien break; 220260484Sobrien 220360484Sobrien if (fa || la) 220460484Sobrien { 220560484Sobrien if (fa) 220660484Sobrien fn = file->filename; 220760484Sobrien if (la) 2208218822Sdim ln = ls->section->owner->filename; 220960484Sobrien 221060484Sobrien i = strcmp (fn, ln); 221160484Sobrien if (i > 0) 221260484Sobrien continue; 221360484Sobrien else if (i < 0) 221460484Sobrien break; 221533965Sjdp } 221633965Sjdp } 221760484Sobrien 221860484Sobrien /* Here either the files are not sorted by name, or we are 2219218822Sdim looking at the sections for this file. */ 222060484Sobrien 2221218822Sdim if (sec != NULL && sec->spec.sorted != none) 2222218822Sdim if (compare_section (sec->spec.sorted, section, ls->section) < 0) 2223218822Sdim break; 222433965Sjdp } 222560484Sobrien 222660484Sobrien return l; 222733965Sjdp} 222833965Sjdp 222960484Sobrien/* Expand a wild statement for a particular FILE. SECTION may be 223060484Sobrien NULL, in which case it is a wild card. */ 223160484Sobrien 223260484Sobrienstatic void 2233130561Sobrienoutput_section_callback (lang_wild_statement_type *ptr, 2234130561Sobrien struct wildcard_list *sec, 2235130561Sobrien asection *section, 2236130561Sobrien lang_input_statement_type *file, 2237130561Sobrien void *output) 223860484Sobrien{ 223960484Sobrien lang_statement_union_type *before; 224077298Sobrien 224189857Sobrien /* Exclude sections that match UNIQUE_SECTION_LIST. */ 2242218822Sdim if (unique_section_p (section)) 224389857Sobrien return; 224489857Sobrien 224589857Sobrien before = wild_sort (ptr, sec, file, section); 224677298Sobrien 224760484Sobrien /* Here BEFORE points to the lang_input_section which 224860484Sobrien should follow the one we are about to add. If BEFORE 224960484Sobrien is NULL, then the section should just go at the end 225060484Sobrien of the current list. */ 225177298Sobrien 225260484Sobrien if (before == NULL) 225389857Sobrien lang_add_section (&ptr->children, section, 2254218822Sdim (lang_output_section_statement_type *) output); 225560484Sobrien else 225660484Sobrien { 225760484Sobrien lang_statement_list_type list; 225860484Sobrien lang_statement_union_type **pp; 225977298Sobrien 226060484Sobrien lang_list_init (&list); 226189857Sobrien lang_add_section (&list, section, 2262218822Sdim (lang_output_section_statement_type *) output); 226377298Sobrien 226460484Sobrien /* If we are discarding the section, LIST.HEAD will 226560484Sobrien be NULL. */ 226660484Sobrien if (list.head != NULL) 226760484Sobrien { 226889857Sobrien ASSERT (list.head->header.next == NULL); 226977298Sobrien 227060484Sobrien for (pp = &ptr->children.head; 227160484Sobrien *pp != before; 227289857Sobrien pp = &(*pp)->header.next) 227360484Sobrien ASSERT (*pp != NULL); 227477298Sobrien 227589857Sobrien list.head->header.next = *pp; 227660484Sobrien *pp = list.head; 227760484Sobrien } 227860484Sobrien } 227960484Sobrien} 228060484Sobrien 2281218822Sdim/* Check if all sections in a wild statement for a particular FILE 2282218822Sdim are readonly. */ 2283218822Sdim 2284218822Sdimstatic void 2285218822Sdimcheck_section_callback (lang_wild_statement_type *ptr ATTRIBUTE_UNUSED, 2286218822Sdim struct wildcard_list *sec ATTRIBUTE_UNUSED, 2287218822Sdim asection *section, 2288218822Sdim lang_input_statement_type *file ATTRIBUTE_UNUSED, 2289218822Sdim void *data) 2290218822Sdim{ 2291218822Sdim /* Exclude sections that match UNIQUE_SECTION_LIST. */ 2292218822Sdim if (unique_section_p (section)) 2293218822Sdim return; 2294218822Sdim 2295218822Sdim if (section->output_section == NULL && (section->flags & SEC_READONLY) == 0) 2296218822Sdim ((lang_output_section_statement_type *) data)->all_input_readonly = FALSE; 2297218822Sdim} 2298218822Sdim 229933965Sjdp/* This is passed a file name which must have been seen already and 230033965Sjdp added to the statement tree. We will see if it has been opened 230133965Sjdp already and had its symbols read. If not then we'll read it. */ 230233965Sjdp 230333965Sjdpstatic lang_input_statement_type * 2304130561Sobrienlookup_name (const char *name) 230533965Sjdp{ 230633965Sjdp lang_input_statement_type *search; 230733965Sjdp 230833965Sjdp for (search = (lang_input_statement_type *) input_file_chain.head; 2309130561Sobrien search != NULL; 231033965Sjdp search = (lang_input_statement_type *) search->next_real_file) 231133965Sjdp { 2312130561Sobrien /* Use the local_sym_name as the name of the file that has 2313130561Sobrien already been loaded as filename might have been transformed 2314130561Sobrien via the search directory lookup mechanism. */ 2315218822Sdim const char *filename = search->local_sym_name; 2316130561Sobrien 2317130561Sobrien if (filename != NULL 2318130561Sobrien && strcmp (filename, name) == 0) 231933965Sjdp break; 232033965Sjdp } 232133965Sjdp 2322130561Sobrien if (search == NULL) 2323218822Sdim search = new_afile (name, lang_input_file_is_search_file_enum, 2324218822Sdim default_target, FALSE); 232533965Sjdp 232633965Sjdp /* If we have already added this file, or this file is not real 2327218822Sdim don't add this file. */ 2328218822Sdim if (search->loaded || !search->real) 232933965Sjdp return search; 233033965Sjdp 2331130561Sobrien if (! load_symbols (search, NULL)) 233289857Sobrien return NULL; 233333965Sjdp 233433965Sjdp return search; 233533965Sjdp} 233633965Sjdp 2337218822Sdim/* Save LIST as a list of libraries whose symbols should not be exported. */ 2338218822Sdim 2339218822Sdimstruct excluded_lib 2340218822Sdim{ 2341218822Sdim char *name; 2342218822Sdim struct excluded_lib *next; 2343218822Sdim}; 2344218822Sdimstatic struct excluded_lib *excluded_libs; 2345218822Sdim 2346218822Sdimvoid 2347218822Sdimadd_excluded_libs (const char *list) 2348218822Sdim{ 2349218822Sdim const char *p = list, *end; 2350218822Sdim 2351218822Sdim while (*p != '\0') 2352218822Sdim { 2353218822Sdim struct excluded_lib *entry; 2354218822Sdim end = strpbrk (p, ",:"); 2355218822Sdim if (end == NULL) 2356218822Sdim end = p + strlen (p); 2357218822Sdim entry = xmalloc (sizeof (*entry)); 2358218822Sdim entry->next = excluded_libs; 2359218822Sdim entry->name = xmalloc (end - p + 1); 2360218822Sdim memcpy (entry->name, p, end - p); 2361218822Sdim entry->name[end - p] = '\0'; 2362218822Sdim excluded_libs = entry; 2363218822Sdim if (*end == '\0') 2364218822Sdim break; 2365218822Sdim p = end + 1; 2366218822Sdim } 2367218822Sdim} 2368218822Sdim 2369218822Sdimstatic void 2370218822Sdimcheck_excluded_libs (bfd *abfd) 2371218822Sdim{ 2372218822Sdim struct excluded_lib *lib = excluded_libs; 2373218822Sdim 2374218822Sdim while (lib) 2375218822Sdim { 2376218822Sdim int len = strlen (lib->name); 2377218822Sdim const char *filename = lbasename (abfd->filename); 2378218822Sdim 2379218822Sdim if (strcmp (lib->name, "ALL") == 0) 2380218822Sdim { 2381218822Sdim abfd->no_export = TRUE; 2382218822Sdim return; 2383218822Sdim } 2384218822Sdim 2385218822Sdim if (strncmp (lib->name, filename, len) == 0 2386218822Sdim && (filename[len] == '\0' 2387218822Sdim || (filename[len] == '.' && filename[len + 1] == 'a' 2388218822Sdim && filename[len + 2] == '\0'))) 2389218822Sdim { 2390218822Sdim abfd->no_export = TRUE; 2391218822Sdim return; 2392218822Sdim } 2393218822Sdim 2394218822Sdim lib = lib->next; 2395218822Sdim } 2396218822Sdim} 2397218822Sdim 239833965Sjdp/* Get the symbols for an input file. */ 239933965Sjdp 2400218822Sdimbfd_boolean 2401130561Sobrienload_symbols (lang_input_statement_type *entry, 2402130561Sobrien lang_statement_list_type *place) 240333965Sjdp{ 240433965Sjdp char **matching; 240533965Sjdp 240633965Sjdp if (entry->loaded) 2407130561Sobrien return TRUE; 240833965Sjdp 240933965Sjdp ldfile_open_file (entry); 241033965Sjdp 241133965Sjdp if (! bfd_check_format (entry->the_bfd, bfd_archive) 241233965Sjdp && ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching)) 241333965Sjdp { 241433965Sjdp bfd_error_type err; 241533965Sjdp lang_statement_list_type *hold; 2416130561Sobrien bfd_boolean bad_load = TRUE; 2417130561Sobrien bfd_boolean save_ldlang_sysrooted_script; 2418218822Sdim bfd_boolean save_as_needed, save_add_needed; 2419104834Sobrien 242033965Sjdp err = bfd_get_error (); 242178828Sobrien 242278828Sobrien /* See if the emulation has some special knowledge. */ 242378828Sobrien if (ldemul_unrecognized_file (entry)) 2424130561Sobrien return TRUE; 242578828Sobrien 242633965Sjdp if (err == bfd_error_file_ambiguously_recognized) 242733965Sjdp { 242833965Sjdp char **p; 242933965Sjdp 243060484Sobrien einfo (_("%B: file not recognized: %E\n"), entry->the_bfd); 243160484Sobrien einfo (_("%B: matching formats:"), entry->the_bfd); 243233965Sjdp for (p = matching; *p != NULL; p++) 243333965Sjdp einfo (" %s", *p); 243433965Sjdp einfo ("%F\n"); 243533965Sjdp } 243633965Sjdp else if (err != bfd_error_file_not_recognized 243733965Sjdp || place == NULL) 243889857Sobrien einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd); 243989857Sobrien else 2440130561Sobrien bad_load = FALSE; 2441104834Sobrien 244233965Sjdp bfd_close (entry->the_bfd); 244333965Sjdp entry->the_bfd = NULL; 244433965Sjdp 244533965Sjdp /* Try to interpret the file as a linker script. */ 244633965Sjdp ldfile_open_command_file (entry->filename); 244733965Sjdp 244833965Sjdp hold = stat_ptr; 244933965Sjdp stat_ptr = place; 2450130561Sobrien save_ldlang_sysrooted_script = ldlang_sysrooted_script; 2451130561Sobrien ldlang_sysrooted_script = entry->sysrooted; 2452218822Sdim save_as_needed = as_needed; 2453218822Sdim as_needed = entry->as_needed; 2454218822Sdim save_add_needed = add_needed; 2455218822Sdim add_needed = entry->add_needed; 245633965Sjdp 2457130561Sobrien ldfile_assumed_script = TRUE; 245833965Sjdp parser_input = input_script; 2459218822Sdim /* We want to use the same -Bdynamic/-Bstatic as the one for 2460218822Sdim ENTRY. */ 2461218822Sdim config.dynamic_link = entry->dynamic; 246233965Sjdp yyparse (); 2463130561Sobrien ldfile_assumed_script = FALSE; 246433965Sjdp 2465130561Sobrien ldlang_sysrooted_script = save_ldlang_sysrooted_script; 2466218822Sdim as_needed = save_as_needed; 2467218822Sdim add_needed = save_add_needed; 246833965Sjdp stat_ptr = hold; 246933965Sjdp 247089857Sobrien return ! bad_load; 247133965Sjdp } 247233965Sjdp 247360484Sobrien if (ldemul_recognized_file (entry)) 2474130561Sobrien return TRUE; 247560484Sobrien 247633965Sjdp /* We don't call ldlang_add_file for an archive. Instead, the 247733965Sjdp add_symbols entry point will call ldlang_add_file, via the 247833965Sjdp add_archive_element callback, for each element of the archive 247933965Sjdp which is used. */ 248033965Sjdp switch (bfd_get_format (entry->the_bfd)) 248133965Sjdp { 248233965Sjdp default: 248333965Sjdp break; 248433965Sjdp 248533965Sjdp case bfd_object: 248633965Sjdp ldlang_add_file (entry); 248733965Sjdp if (trace_files || trace_file_tries) 248833965Sjdp info_msg ("%I\n", entry); 248933965Sjdp break; 249033965Sjdp 249133965Sjdp case bfd_archive: 2492218822Sdim check_excluded_libs (entry->the_bfd); 2493218822Sdim 249433965Sjdp if (entry->whole_archive) 249533965Sjdp { 2496104834Sobrien bfd *member = NULL; 2497130561Sobrien bfd_boolean loaded = TRUE; 249889857Sobrien 249989857Sobrien for (;;) 250033965Sjdp { 250189857Sobrien member = bfd_openr_next_archived_file (entry->the_bfd, member); 250289857Sobrien 250389857Sobrien if (member == NULL) 250489857Sobrien break; 2505104834Sobrien 250633965Sjdp if (! bfd_check_format (member, bfd_object)) 250789857Sobrien { 250889857Sobrien einfo (_("%F%B: member %B in archive is not an object\n"), 250989857Sobrien entry->the_bfd, member); 2510130561Sobrien loaded = FALSE; 251189857Sobrien } 251289857Sobrien 251333965Sjdp if (! ((*link_info.callbacks->add_archive_element) 251433965Sjdp (&link_info, member, "--whole-archive"))) 251533965Sjdp abort (); 251689857Sobrien 251733965Sjdp if (! bfd_link_add_symbols (member, &link_info)) 251889857Sobrien { 251989857Sobrien einfo (_("%F%B: could not read symbols: %E\n"), member); 2520130561Sobrien loaded = FALSE; 252189857Sobrien } 252233965Sjdp } 252333965Sjdp 252489857Sobrien entry->loaded = loaded; 252589857Sobrien return loaded; 252633965Sjdp } 252789857Sobrien break; 252833965Sjdp } 252933965Sjdp 253089857Sobrien if (bfd_link_add_symbols (entry->the_bfd, &link_info)) 2531130561Sobrien entry->loaded = TRUE; 253289857Sobrien else 253360484Sobrien einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd); 253433965Sjdp 253589857Sobrien return entry->loaded; 253633965Sjdp} 253733965Sjdp 253889857Sobrien/* Handle a wild statement. S->FILENAME or S->SECTION_LIST or both 253989857Sobrien may be NULL, indicating that it is a wildcard. Separate 254089857Sobrien lang_input_section statements are created for each part of the 254189857Sobrien expansion; they are added after the wild statement S. OUTPUT is 254289857Sobrien the output section. */ 254333965Sjdp 254433965Sjdpstatic void 2545130561Sobrienwild (lang_wild_statement_type *s, 2546130561Sobrien const char *target ATTRIBUTE_UNUSED, 2547130561Sobrien lang_output_section_statement_type *output) 254833965Sjdp{ 254989857Sobrien struct wildcard_list *sec; 255033965Sjdp 2551218822Sdim if (s->handler_data[0] 2552218822Sdim && s->handler_data[0]->spec.sorted == by_name 2553218822Sdim && !s->filenames_sorted) 2554218822Sdim { 2555218822Sdim lang_section_bst_type *tree; 255689857Sobrien 2557218822Sdim walk_wild (s, output_section_callback_fast, output); 2558218822Sdim 2559218822Sdim tree = s->tree; 2560218822Sdim if (tree) 2561218822Sdim { 2562218822Sdim output_section_callback_tree_to_list (s, tree, output); 2563218822Sdim s->tree = NULL; 2564218822Sdim } 2565218822Sdim } 2566218822Sdim else 2567218822Sdim walk_wild (s, output_section_callback, output); 2568218822Sdim 2569218822Sdim if (default_common_section == NULL) 2570218822Sdim for (sec = s->section_list; sec != NULL; sec = sec->next) 257189857Sobrien if (sec->spec.name != NULL && strcmp (sec->spec.name, "COMMON") == 0) 257289857Sobrien { 257389857Sobrien /* Remember the section that common is going to in case we 2574104834Sobrien later get something which doesn't know where to put it. */ 257589857Sobrien default_common_section = output; 2576218822Sdim break; 257789857Sobrien } 257860484Sobrien} 257960484Sobrien 2580130561Sobrien/* Return TRUE iff target is the sought target. */ 258177298Sobrien 258260484Sobrienstatic int 2583130561Sobrienget_target (const bfd_target *target, void *data) 258460484Sobrien{ 2585130561Sobrien const char *sought = data; 258677298Sobrien 258760484Sobrien return strcmp (target->name, sought) == 0; 258860484Sobrien} 258960484Sobrien 259060484Sobrien/* Like strcpy() but convert to lower case as well. */ 259177298Sobrien 259260484Sobrienstatic void 2593130561Sobrienstricpy (char *dest, char *src) 259460484Sobrien{ 259560484Sobrien char c; 259677298Sobrien 259777298Sobrien while ((c = *src++) != 0) 259889857Sobrien *dest++ = TOLOWER (c); 259960484Sobrien 260077298Sobrien *dest = 0; 260160484Sobrien} 260260484Sobrien 2603130561Sobrien/* Remove the first occurrence of needle (if any) in haystack 260460484Sobrien from haystack. */ 260577298Sobrien 260660484Sobrienstatic void 2607130561Sobrienstrcut (char *haystack, char *needle) 260860484Sobrien{ 260960484Sobrien haystack = strstr (haystack, needle); 261077298Sobrien 261160484Sobrien if (haystack) 261233965Sjdp { 261377298Sobrien char *src; 261460484Sobrien 261577298Sobrien for (src = haystack + strlen (needle); *src;) 261677298Sobrien *haystack++ = *src++; 261777298Sobrien 261877298Sobrien *haystack = 0; 261933965Sjdp } 262060484Sobrien} 262133965Sjdp 262260484Sobrien/* Compare two target format name strings. 262360484Sobrien Return a value indicating how "similar" they are. */ 262477298Sobrien 262560484Sobrienstatic int 2626130561Sobrienname_compare (char *first, char *second) 262760484Sobrien{ 262877298Sobrien char *copy1; 262977298Sobrien char *copy2; 263077298Sobrien int result; 263177298Sobrien 263260484Sobrien copy1 = xmalloc (strlen (first) + 1); 263360484Sobrien copy2 = xmalloc (strlen (second) + 1); 263460484Sobrien 263560484Sobrien /* Convert the names to lower case. */ 263660484Sobrien stricpy (copy1, first); 263760484Sobrien stricpy (copy2, second); 263860484Sobrien 2639130561Sobrien /* Remove size and endian strings from the name. */ 264060484Sobrien strcut (copy1, "big"); 264160484Sobrien strcut (copy1, "little"); 264260484Sobrien strcut (copy2, "big"); 264360484Sobrien strcut (copy2, "little"); 264460484Sobrien 264560484Sobrien /* Return a value based on how many characters match, 264660484Sobrien starting from the beginning. If both strings are 264760484Sobrien the same then return 10 * their length. */ 264877298Sobrien for (result = 0; copy1[result] == copy2[result]; result++) 264977298Sobrien if (copy1[result] == 0) 265060484Sobrien { 265160484Sobrien result *= 10; 265260484Sobrien break; 265360484Sobrien } 265477298Sobrien 265560484Sobrien free (copy1); 265660484Sobrien free (copy2); 265760484Sobrien 265860484Sobrien return result; 265960484Sobrien} 266060484Sobrien 266160484Sobrien/* Set by closest_target_match() below. */ 266277298Sobrienstatic const bfd_target *winner; 266360484Sobrien 266460484Sobrien/* Scan all the valid bfd targets looking for one that has the endianness 266560484Sobrien requirement that was specified on the command line, and is the nearest 266660484Sobrien match to the original output target. */ 266777298Sobrien 266860484Sobrienstatic int 2669130561Sobrienclosest_target_match (const bfd_target *target, void *data) 267060484Sobrien{ 2671130561Sobrien const bfd_target *original = data; 267277298Sobrien 267377298Sobrien if (command_line.endian == ENDIAN_BIG 267477298Sobrien && target->byteorder != BFD_ENDIAN_BIG) 267560484Sobrien return 0; 267677298Sobrien 267777298Sobrien if (command_line.endian == ENDIAN_LITTLE 267877298Sobrien && target->byteorder != BFD_ENDIAN_LITTLE) 267960484Sobrien return 0; 268060484Sobrien 268160484Sobrien /* Must be the same flavour. */ 268260484Sobrien if (target->flavour != original->flavour) 268360484Sobrien return 0; 268460484Sobrien 268560484Sobrien /* If we have not found a potential winner yet, then record this one. */ 268660484Sobrien if (winner == NULL) 268733965Sjdp { 268860484Sobrien winner = target; 268960484Sobrien return 0; 269033965Sjdp } 269160484Sobrien 269260484Sobrien /* Oh dear, we now have two potential candidates for a successful match. 269377298Sobrien Compare their names and choose the better one. */ 269478828Sobrien if (name_compare (target->name, original->name) 269578828Sobrien > name_compare (winner->name, original->name)) 269660484Sobrien winner = target; 269760484Sobrien 269860484Sobrien /* Keep on searching until wqe have checked them all. */ 269960484Sobrien return 0; 270033965Sjdp} 270133965Sjdp 270260484Sobrien/* Return the BFD target format of the first input file. */ 270377298Sobrien 270460484Sobrienstatic char * 2705130561Sobrienget_first_input_target (void) 270660484Sobrien{ 270777298Sobrien char *target = NULL; 270860484Sobrien 270960484Sobrien LANG_FOR_EACH_INPUT_STATEMENT (s) 271060484Sobrien { 271160484Sobrien if (s->header.type == lang_input_statement_enum 271260484Sobrien && s->real) 271360484Sobrien { 271460484Sobrien ldfile_open_file (s); 271577298Sobrien 271660484Sobrien if (s->the_bfd != NULL 271760484Sobrien && bfd_check_format (s->the_bfd, bfd_object)) 271860484Sobrien { 271960484Sobrien target = bfd_get_target (s->the_bfd); 272077298Sobrien 272160484Sobrien if (target != NULL) 272260484Sobrien break; 272360484Sobrien } 272460484Sobrien } 272560484Sobrien } 272677298Sobrien 272760484Sobrien return target; 272860484Sobrien} 272960484Sobrien 2730107492Sobrienconst char * 2731130561Sobrienlang_get_output_target (void) 2732107492Sobrien{ 2733107492Sobrien const char *target; 2734107492Sobrien 2735107492Sobrien /* Has the user told us which output format to use? */ 2736130561Sobrien if (output_target != NULL) 2737107492Sobrien return output_target; 2738107492Sobrien 2739107492Sobrien /* No - has the current target been set to something other than 2740107492Sobrien the default? */ 2741107492Sobrien if (current_target != default_target) 2742107492Sobrien return current_target; 2743107492Sobrien 2744107492Sobrien /* No - can we determine the format of the first input file? */ 2745107492Sobrien target = get_first_input_target (); 2746107492Sobrien if (target != NULL) 2747107492Sobrien return target; 2748107492Sobrien 2749107492Sobrien /* Failed - use the default output target. */ 2750107492Sobrien return default_target; 2751107492Sobrien} 2752107492Sobrien 275333965Sjdp/* Open the output file. */ 275433965Sjdp 275533965Sjdpstatic bfd * 2756130561Sobrienopen_output (const char *name) 275733965Sjdp{ 275877298Sobrien bfd *output; 275933965Sjdp 2760107492Sobrien output_target = lang_get_output_target (); 276160484Sobrien 276277298Sobrien /* Has the user requested a particular endianness on the command 276377298Sobrien line? */ 276460484Sobrien if (command_line.endian != ENDIAN_UNSET) 276560484Sobrien { 276677298Sobrien const bfd_target *target; 276760484Sobrien enum bfd_endian desired_endian; 276860484Sobrien 276960484Sobrien /* Get the chosen target. */ 2770130561Sobrien target = bfd_search_for_target (get_target, (void *) output_target); 277160484Sobrien 277277298Sobrien /* If the target is not supported, we cannot do anything. */ 277377298Sobrien if (target != NULL) 277460484Sobrien { 277577298Sobrien if (command_line.endian == ENDIAN_BIG) 277677298Sobrien desired_endian = BFD_ENDIAN_BIG; 277760484Sobrien else 277877298Sobrien desired_endian = BFD_ENDIAN_LITTLE; 277977298Sobrien 278077298Sobrien /* See if the target has the wrong endianness. This should 278177298Sobrien not happen if the linker script has provided big and 278277298Sobrien little endian alternatives, but some scrips don't do 278377298Sobrien this. */ 278477298Sobrien if (target->byteorder != desired_endian) 278560484Sobrien { 278677298Sobrien /* If it does, then see if the target provides 278777298Sobrien an alternative with the correct endianness. */ 278877298Sobrien if (target->alternative_target != NULL 278977298Sobrien && (target->alternative_target->byteorder == desired_endian)) 279077298Sobrien output_target = target->alternative_target->name; 279160484Sobrien else 279277298Sobrien { 279377298Sobrien /* Try to find a target as similar as possible to 279477298Sobrien the default target, but which has the desired 279577298Sobrien endian characteristic. */ 2796130561Sobrien bfd_search_for_target (closest_target_match, 2797130561Sobrien (void *) target); 279877298Sobrien 279977298Sobrien /* Oh dear - we could not find any targets that 280077298Sobrien satisfy our requirements. */ 280177298Sobrien if (winner == NULL) 2802218822Sdim einfo (_("%P: warning: could not find any targets" 2803218822Sdim " that match endianness requirement\n")); 280477298Sobrien else 280577298Sobrien output_target = winner->name; 280677298Sobrien } 280760484Sobrien } 280860484Sobrien } 280960484Sobrien } 281077298Sobrien 281133965Sjdp output = bfd_openw (name, output_target); 281233965Sjdp 2813130561Sobrien if (output == NULL) 281433965Sjdp { 281533965Sjdp if (bfd_get_error () == bfd_error_invalid_target) 281660484Sobrien einfo (_("%P%F: target %s not found\n"), output_target); 281760484Sobrien 281860484Sobrien einfo (_("%P%F: cannot open output file %s: %E\n"), name); 281933965Sjdp } 282033965Sjdp 2821130561Sobrien delete_output_file_on_failure = TRUE; 282233965Sjdp 282333965Sjdp if (! bfd_set_format (output, bfd_object)) 282460484Sobrien einfo (_("%P%F:%s: can not make object file: %E\n"), name); 282533965Sjdp if (! bfd_set_arch_mach (output, 282633965Sjdp ldfile_output_architecture, 282733965Sjdp ldfile_output_machine)) 282860484Sobrien einfo (_("%P%F:%s: can not set architecture: %E\n"), name); 282933965Sjdp 283033965Sjdp link_info.hash = bfd_link_hash_table_create (output); 2831130561Sobrien if (link_info.hash == NULL) 2832218822Sdim einfo (_("%P%F: can not create hash table: %E\n")); 283333965Sjdp 283433965Sjdp bfd_set_gp_size (output, g_switch_value); 283533965Sjdp return output; 283633965Sjdp} 283733965Sjdp 283833965Sjdpstatic void 2839130561Sobrienldlang_open_output (lang_statement_union_type *statement) 284033965Sjdp{ 284133965Sjdp switch (statement->header.type) 284233965Sjdp { 284333965Sjdp case lang_output_statement_enum: 2844130561Sobrien ASSERT (output_bfd == NULL); 284533965Sjdp output_bfd = open_output (statement->output_statement.name); 284633965Sjdp ldemul_set_output_arch (); 2847130561Sobrien if (config.magic_demand_paged && !link_info.relocatable) 284833965Sjdp output_bfd->flags |= D_PAGED; 284933965Sjdp else 285033965Sjdp output_bfd->flags &= ~D_PAGED; 285133965Sjdp if (config.text_read_only) 285233965Sjdp output_bfd->flags |= WP_TEXT; 285333965Sjdp else 285433965Sjdp output_bfd->flags &= ~WP_TEXT; 285533965Sjdp if (link_info.traditional_format) 285633965Sjdp output_bfd->flags |= BFD_TRADITIONAL_FORMAT; 285733965Sjdp else 285833965Sjdp output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT; 285933965Sjdp break; 286033965Sjdp 286133965Sjdp case lang_target_statement_enum: 286233965Sjdp current_target = statement->target_statement.target; 286333965Sjdp break; 286433965Sjdp default: 286533965Sjdp break; 286633965Sjdp } 286733965Sjdp} 286833965Sjdp 2869130561Sobrien/* Convert between addresses in bytes and sizes in octets. 2870130561Sobrien For currently supported targets, octets_per_byte is always a power 2871130561Sobrien of two, so we can use shifts. */ 2872130561Sobrien#define TO_ADDR(X) ((X) >> opb_shift) 2873130561Sobrien#define TO_SIZE(X) ((X) << opb_shift) 2874130561Sobrien 2875130561Sobrien/* Support the above. */ 2876130561Sobrienstatic unsigned int opb_shift = 0; 2877130561Sobrien 2878130561Sobrienstatic void 2879130561Sobrieninit_opb (void) 2880130561Sobrien{ 2881130561Sobrien unsigned x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 2882130561Sobrien ldfile_output_machine); 2883130561Sobrien opb_shift = 0; 2884130561Sobrien if (x > 1) 2885130561Sobrien while ((x & 1) == 0) 2886130561Sobrien { 2887130561Sobrien x >>= 1; 2888130561Sobrien ++opb_shift; 2889130561Sobrien } 2890130561Sobrien ASSERT (x == 1); 2891130561Sobrien} 2892130561Sobrien 289333965Sjdp/* Open all the input files. */ 289433965Sjdp 289533965Sjdpstatic void 2896130561Sobrienopen_input_bfds (lang_statement_union_type *s, bfd_boolean force) 289733965Sjdp{ 2898130561Sobrien for (; s != NULL; s = s->header.next) 289933965Sjdp { 290033965Sjdp switch (s->header.type) 290133965Sjdp { 290233965Sjdp case lang_constructors_statement_enum: 290333965Sjdp open_input_bfds (constructor_list.head, force); 290433965Sjdp break; 290533965Sjdp case lang_output_section_statement_enum: 290633965Sjdp open_input_bfds (s->output_section_statement.children.head, force); 290733965Sjdp break; 290833965Sjdp case lang_wild_statement_enum: 290977298Sobrien /* Maybe we should load the file's symbols. */ 291033965Sjdp if (s->wild_statement.filename 291133965Sjdp && ! wildcardp (s->wild_statement.filename)) 2912130561Sobrien lookup_name (s->wild_statement.filename); 291333965Sjdp open_input_bfds (s->wild_statement.children.head, force); 291433965Sjdp break; 291533965Sjdp case lang_group_statement_enum: 291633965Sjdp { 291733965Sjdp struct bfd_link_hash_entry *undefs; 291833965Sjdp 291933965Sjdp /* We must continually search the entries in the group 292077298Sobrien until no new symbols are added to the list of undefined 292177298Sobrien symbols. */ 292233965Sjdp 292333965Sjdp do 292433965Sjdp { 292533965Sjdp undefs = link_info.hash->undefs_tail; 2926130561Sobrien open_input_bfds (s->group_statement.children.head, TRUE); 292733965Sjdp } 292833965Sjdp while (undefs != link_info.hash->undefs_tail); 292933965Sjdp } 293033965Sjdp break; 293133965Sjdp case lang_target_statement_enum: 293233965Sjdp current_target = s->target_statement.target; 293333965Sjdp break; 293433965Sjdp case lang_input_statement_enum: 293560484Sobrien if (s->input_statement.real) 293633965Sjdp { 293733965Sjdp lang_statement_list_type add; 293833965Sjdp 293933965Sjdp s->input_statement.target = current_target; 294033965Sjdp 294133965Sjdp /* If we are being called from within a group, and this 2942218822Sdim is an archive which has already been searched, then 2943218822Sdim force it to be researched unless the whole archive 294477298Sobrien has been loaded already. */ 294533965Sjdp if (force 294677298Sobrien && !s->input_statement.whole_archive 294733965Sjdp && s->input_statement.loaded 294833965Sjdp && bfd_check_format (s->input_statement.the_bfd, 294933965Sjdp bfd_archive)) 2950130561Sobrien s->input_statement.loaded = FALSE; 295133965Sjdp 295233965Sjdp lang_list_init (&add); 295333965Sjdp 295489857Sobrien if (! load_symbols (&s->input_statement, &add)) 2955130561Sobrien config.make_executable = FALSE; 295633965Sjdp 295733965Sjdp if (add.head != NULL) 295833965Sjdp { 295989857Sobrien *add.tail = s->header.next; 296089857Sobrien s->header.next = add.head; 296133965Sjdp } 296233965Sjdp } 296333965Sjdp break; 296433965Sjdp default: 296533965Sjdp break; 296633965Sjdp } 296733965Sjdp } 296833965Sjdp} 296933965Sjdp 2970130561Sobrien/* Add a symbol to a hash of symbols used in DEFINED (NAME) expressions. */ 2971130561Sobrien 2972130561Sobrienvoid 2973130561Sobrienlang_track_definedness (const char *name) 2974130561Sobrien{ 2975130561Sobrien if (bfd_hash_lookup (&lang_definedness_table, name, TRUE, FALSE) == NULL) 2976130561Sobrien einfo (_("%P%F: bfd_hash_lookup failed creating symbol %s\n"), name); 2977130561Sobrien} 2978130561Sobrien 2979130561Sobrien/* New-function for the definedness hash table. */ 2980130561Sobrien 2981130561Sobrienstatic struct bfd_hash_entry * 2982130561Sobrienlang_definedness_newfunc (struct bfd_hash_entry *entry, 2983130561Sobrien struct bfd_hash_table *table ATTRIBUTE_UNUSED, 2984130561Sobrien const char *name ATTRIBUTE_UNUSED) 2985130561Sobrien{ 2986130561Sobrien struct lang_definedness_hash_entry *ret 2987130561Sobrien = (struct lang_definedness_hash_entry *) entry; 2988130561Sobrien 2989130561Sobrien if (ret == NULL) 2990130561Sobrien ret = (struct lang_definedness_hash_entry *) 2991130561Sobrien bfd_hash_allocate (table, sizeof (struct lang_definedness_hash_entry)); 2992130561Sobrien 2993130561Sobrien if (ret == NULL) 2994130561Sobrien einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name); 2995130561Sobrien 2996130561Sobrien ret->iteration = -1; 2997130561Sobrien return &ret->root; 2998130561Sobrien} 2999130561Sobrien 3000130561Sobrien/* Return the iteration when the definition of NAME was last updated. A 3001130561Sobrien value of -1 means that the symbol is not defined in the linker script 3002130561Sobrien or the command line, but may be defined in the linker symbol table. */ 3003130561Sobrien 3004130561Sobrienint 3005130561Sobrienlang_symbol_definition_iteration (const char *name) 3006130561Sobrien{ 3007130561Sobrien struct lang_definedness_hash_entry *defentry 3008130561Sobrien = (struct lang_definedness_hash_entry *) 3009130561Sobrien bfd_hash_lookup (&lang_definedness_table, name, FALSE, FALSE); 3010130561Sobrien 3011130561Sobrien /* We've already created this one on the presence of DEFINED in the 3012130561Sobrien script, so it can't be NULL unless something is borked elsewhere in 3013130561Sobrien the code. */ 3014130561Sobrien if (defentry == NULL) 3015130561Sobrien FAIL (); 3016130561Sobrien 3017130561Sobrien return defentry->iteration; 3018130561Sobrien} 3019130561Sobrien 3020130561Sobrien/* Update the definedness state of NAME. */ 3021130561Sobrien 3022130561Sobrienvoid 3023130561Sobrienlang_update_definedness (const char *name, struct bfd_link_hash_entry *h) 3024130561Sobrien{ 3025130561Sobrien struct lang_definedness_hash_entry *defentry 3026130561Sobrien = (struct lang_definedness_hash_entry *) 3027130561Sobrien bfd_hash_lookup (&lang_definedness_table, name, FALSE, FALSE); 3028130561Sobrien 3029130561Sobrien /* We don't keep track of symbols not tested with DEFINED. */ 3030130561Sobrien if (defentry == NULL) 3031130561Sobrien return; 3032130561Sobrien 3033130561Sobrien /* If the symbol was already defined, and not from an earlier statement 3034130561Sobrien iteration, don't update the definedness iteration, because that'd 3035130561Sobrien make the symbol seem defined in the linker script at this point, and 3036130561Sobrien it wasn't; it was defined in some object. If we do anyway, DEFINED 3037130561Sobrien would start to yield false before this point and the construct "sym = 3038130561Sobrien DEFINED (sym) ? sym : X;" would change sym to X despite being defined 3039130561Sobrien in an object. */ 3040130561Sobrien if (h->type != bfd_link_hash_undefined 3041130561Sobrien && h->type != bfd_link_hash_common 3042130561Sobrien && h->type != bfd_link_hash_new 3043130561Sobrien && defentry->iteration == -1) 3044130561Sobrien return; 3045130561Sobrien 3046130561Sobrien defentry->iteration = lang_statement_iteration; 3047130561Sobrien} 3048130561Sobrien 304977298Sobrien/* Add the supplied name to the symbol table as an undefined reference. 305094536Sobrien This is a two step process as the symbol table doesn't even exist at 305194536Sobrien the time the ld command line is processed. First we put the name 305294536Sobrien on a list, then, once the output file has been opened, transfer the 305394536Sobrien name to the symbol table. */ 305494536Sobrien 3055104834Sobrientypedef struct bfd_sym_chain ldlang_undef_chain_list_type; 305633965Sjdp 3057104834Sobrien#define ldlang_undef_chain_list_head entry_symbol.next 305833965Sjdp 305933965Sjdpvoid 3060130561Sobrienldlang_add_undef (const char *const name) 306133965Sjdp{ 306233965Sjdp ldlang_undef_chain_list_type *new = 3063130561Sobrien stat_alloc (sizeof (ldlang_undef_chain_list_type)); 306433965Sjdp 306533965Sjdp new->next = ldlang_undef_chain_list_head; 306633965Sjdp ldlang_undef_chain_list_head = new; 306733965Sjdp 306878828Sobrien new->name = xstrdup (name); 306994536Sobrien 307094536Sobrien if (output_bfd != NULL) 307194536Sobrien insert_undefined (new->name); 307233965Sjdp} 307333965Sjdp 307494536Sobrien/* Insert NAME as undefined in the symbol table. */ 307594536Sobrien 307694536Sobrienstatic void 3077130561Sobrieninsert_undefined (const char *name) 307894536Sobrien{ 307994536Sobrien struct bfd_link_hash_entry *h; 308094536Sobrien 3081130561Sobrien h = bfd_link_hash_lookup (link_info.hash, name, TRUE, FALSE, TRUE); 3082130561Sobrien if (h == NULL) 308394536Sobrien einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); 308494536Sobrien if (h->type == bfd_link_hash_new) 308594536Sobrien { 308694536Sobrien h->type = bfd_link_hash_undefined; 308794536Sobrien h->u.undef.abfd = NULL; 308894536Sobrien bfd_link_add_undef (link_info.hash, h); 308994536Sobrien } 309094536Sobrien} 309194536Sobrien 309233965Sjdp/* Run through the list of undefineds created above and place them 309333965Sjdp into the linker hash table as undefined symbols belonging to the 309477298Sobrien script file. */ 309577298Sobrien 309633965Sjdpstatic void 3097130561Sobrienlang_place_undefineds (void) 309833965Sjdp{ 309933965Sjdp ldlang_undef_chain_list_type *ptr; 310033965Sjdp 3101130561Sobrien for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next) 3102130561Sobrien insert_undefined (ptr->name); 310333965Sjdp} 310433965Sjdp 3105218822Sdim/* Check for all readonly or some readwrite sections. */ 3106218822Sdim 3107218822Sdimstatic void 3108218822Sdimcheck_input_sections 3109218822Sdim (lang_statement_union_type *s, 3110218822Sdim lang_output_section_statement_type *output_section_statement) 3111218822Sdim{ 3112218822Sdim for (; s != (lang_statement_union_type *) NULL; s = s->header.next) 3113218822Sdim { 3114218822Sdim switch (s->header.type) 3115218822Sdim { 3116218822Sdim case lang_wild_statement_enum: 3117218822Sdim walk_wild (&s->wild_statement, check_section_callback, 3118218822Sdim output_section_statement); 3119218822Sdim if (! output_section_statement->all_input_readonly) 3120218822Sdim return; 3121218822Sdim break; 3122218822Sdim case lang_constructors_statement_enum: 3123218822Sdim check_input_sections (constructor_list.head, 3124218822Sdim output_section_statement); 3125218822Sdim if (! output_section_statement->all_input_readonly) 3126218822Sdim return; 3127218822Sdim break; 3128218822Sdim case lang_group_statement_enum: 3129218822Sdim check_input_sections (s->group_statement.children.head, 3130218822Sdim output_section_statement); 3131218822Sdim if (! output_section_statement->all_input_readonly) 3132218822Sdim return; 3133218822Sdim break; 3134218822Sdim default: 3135218822Sdim break; 3136218822Sdim } 3137218822Sdim } 3138218822Sdim} 3139218822Sdim 3140218822Sdim/* Update wildcard statements if needed. */ 3141218822Sdim 3142218822Sdimstatic void 3143218822Sdimupdate_wild_statements (lang_statement_union_type *s) 3144218822Sdim{ 3145218822Sdim struct wildcard_list *sec; 3146218822Sdim 3147218822Sdim switch (sort_section) 3148218822Sdim { 3149218822Sdim default: 3150218822Sdim FAIL (); 3151218822Sdim 3152218822Sdim case none: 3153218822Sdim break; 3154218822Sdim 3155218822Sdim case by_name: 3156218822Sdim case by_alignment: 3157218822Sdim for (; s != NULL; s = s->header.next) 3158218822Sdim { 3159218822Sdim switch (s->header.type) 3160218822Sdim { 3161218822Sdim default: 3162218822Sdim break; 3163218822Sdim 3164218822Sdim case lang_wild_statement_enum: 3165218822Sdim sec = s->wild_statement.section_list; 3166218822Sdim for (sec = s->wild_statement.section_list; sec != NULL; 3167218822Sdim sec = sec->next) 3168218822Sdim { 3169218822Sdim switch (sec->spec.sorted) 3170218822Sdim { 3171218822Sdim case none: 3172218822Sdim sec->spec.sorted = sort_section; 3173218822Sdim break; 3174218822Sdim case by_name: 3175218822Sdim if (sort_section == by_alignment) 3176218822Sdim sec->spec.sorted = by_name_alignment; 3177218822Sdim break; 3178218822Sdim case by_alignment: 3179218822Sdim if (sort_section == by_name) 3180218822Sdim sec->spec.sorted = by_alignment_name; 3181218822Sdim break; 3182218822Sdim default: 3183218822Sdim break; 3184218822Sdim } 3185218822Sdim } 3186218822Sdim break; 3187218822Sdim 3188218822Sdim case lang_constructors_statement_enum: 3189218822Sdim update_wild_statements (constructor_list.head); 3190218822Sdim break; 3191218822Sdim 3192218822Sdim case lang_output_section_statement_enum: 3193218822Sdim update_wild_statements 3194218822Sdim (s->output_section_statement.children.head); 3195218822Sdim break; 3196218822Sdim 3197218822Sdim case lang_group_statement_enum: 3198218822Sdim update_wild_statements (s->group_statement.children.head); 3199218822Sdim break; 3200218822Sdim } 3201218822Sdim } 3202218822Sdim break; 3203218822Sdim } 3204218822Sdim} 3205218822Sdim 3206130561Sobrien/* Open input files and attach to output sections. */ 320777298Sobrien 320833965Sjdpstatic void 3209130561Sobrienmap_input_to_output_sections 3210130561Sobrien (lang_statement_union_type *s, const char *target, 3211218822Sdim lang_output_section_statement_type *os) 321233965Sjdp{ 3213218822Sdim flagword flags; 3214218822Sdim 3215130561Sobrien for (; s != NULL; s = s->header.next) 321633965Sjdp { 321733965Sjdp switch (s->header.type) 321833965Sjdp { 321933965Sjdp case lang_wild_statement_enum: 3220218822Sdim wild (&s->wild_statement, target, os); 322133965Sjdp break; 322233965Sjdp case lang_constructors_statement_enum: 322333965Sjdp map_input_to_output_sections (constructor_list.head, 322433965Sjdp target, 3225218822Sdim os); 322633965Sjdp break; 322733965Sjdp case lang_output_section_statement_enum: 3228218822Sdim if (s->output_section_statement.constraint) 3229218822Sdim { 3230218822Sdim if (s->output_section_statement.constraint != ONLY_IF_RW 3231218822Sdim && s->output_section_statement.constraint != ONLY_IF_RO) 3232218822Sdim break; 3233218822Sdim s->output_section_statement.all_input_readonly = TRUE; 3234218822Sdim check_input_sections (s->output_section_statement.children.head, 3235218822Sdim &s->output_section_statement); 3236218822Sdim if ((s->output_section_statement.all_input_readonly 3237218822Sdim && s->output_section_statement.constraint == ONLY_IF_RW) 3238218822Sdim || (!s->output_section_statement.all_input_readonly 3239218822Sdim && s->output_section_statement.constraint == ONLY_IF_RO)) 3240218822Sdim { 3241218822Sdim s->output_section_statement.constraint = -1; 3242218822Sdim break; 3243218822Sdim } 3244218822Sdim } 3245218822Sdim 324633965Sjdp map_input_to_output_sections (s->output_section_statement.children.head, 324733965Sjdp target, 324833965Sjdp &s->output_section_statement); 324933965Sjdp break; 325033965Sjdp case lang_output_statement_enum: 325133965Sjdp break; 325233965Sjdp case lang_target_statement_enum: 325333965Sjdp target = s->target_statement.target; 325433965Sjdp break; 325533965Sjdp case lang_group_statement_enum: 325633965Sjdp map_input_to_output_sections (s->group_statement.children.head, 325733965Sjdp target, 3258218822Sdim os); 325933965Sjdp break; 3260130561Sobrien case lang_data_statement_enum: 3261130561Sobrien /* Make sure that any sections mentioned in the expression 3262130561Sobrien are initialized. */ 3263130561Sobrien exp_init_os (s->data_statement.exp); 3264218822Sdim flags = SEC_HAS_CONTENTS; 3265218822Sdim /* The output section gets contents, and then we inspect for 3266218822Sdim any flags set in the input script which override any ALLOC. */ 3267218822Sdim if (!(os->flags & SEC_NEVER_LOAD)) 3268218822Sdim flags |= SEC_ALLOC | SEC_LOAD; 3269218822Sdim if (os->bfd_section == NULL) 3270218822Sdim init_os (os, NULL, flags); 3271218822Sdim else 3272218822Sdim os->bfd_section->flags |= flags; 3273218822Sdim break; 3274218822Sdim case lang_input_section_enum: 3275218822Sdim break; 327633965Sjdp case lang_fill_statement_enum: 327733965Sjdp case lang_object_symbols_statement_enum: 327833965Sjdp case lang_reloc_statement_enum: 327933965Sjdp case lang_padding_statement_enum: 328033965Sjdp case lang_input_statement_enum: 3281218822Sdim if (os != NULL && os->bfd_section == NULL) 3282218822Sdim init_os (os, NULL, 0); 328333965Sjdp break; 328433965Sjdp case lang_assignment_statement_enum: 3285218822Sdim if (os != NULL && os->bfd_section == NULL) 3286218822Sdim init_os (os, NULL, 0); 328733965Sjdp 328833965Sjdp /* Make sure that any sections mentioned in the assignment 328977298Sobrien are initialized. */ 329033965Sjdp exp_init_os (s->assignment_statement.exp); 329133965Sjdp break; 329233965Sjdp case lang_afile_asection_pair_statement_enum: 329333965Sjdp FAIL (); 329433965Sjdp break; 329533965Sjdp case lang_address_statement_enum: 3296218822Sdim /* Mark the specified section with the supplied address. 329733965Sjdp 3298218822Sdim If this section was actually a segment marker, then the 3299218822Sdim directive is ignored if the linker script explicitly 3300218822Sdim processed the segment marker. Originally, the linker 3301218822Sdim treated segment directives (like -Ttext on the 3302218822Sdim command-line) as section directives. We honor the 3303218822Sdim section directive semantics for backwards compatibilty; 3304218822Sdim linker scripts that do not specifically check for 3305218822Sdim SEGMENT_START automatically get the old semantics. */ 3306218822Sdim if (!s->address_statement.segment 3307218822Sdim || !s->address_statement.segment->used) 3308218822Sdim { 3309218822Sdim lang_output_section_statement_type *aos 3310218822Sdim = (lang_output_section_statement_lookup 3311218822Sdim (s->address_statement.section_name)); 3312218822Sdim 3313218822Sdim if (aos->bfd_section == NULL) 3314218822Sdim init_os (aos, NULL, 0); 3315218822Sdim aos->addr_tree = s->address_statement.address; 3316218822Sdim } 331733965Sjdp break; 331833965Sjdp } 331933965Sjdp } 332033965Sjdp} 332133965Sjdp 3322104834Sobrien/* An output section might have been removed after its statement was 3323104834Sobrien added. For example, ldemul_before_allocation can remove dynamic 3324104834Sobrien sections if they turn out to be not needed. Clean them up here. */ 3325104834Sobrien 3326218822Sdimvoid 3327130561Sobrienstrip_excluded_output_sections (void) 3328104834Sobrien{ 3329218822Sdim lang_output_section_statement_type *os; 3330104834Sobrien 3331218822Sdim /* Run lang_size_sections (if not already done). */ 3332218822Sdim if (expld.phase != lang_mark_phase_enum) 3333104834Sobrien { 3334218822Sdim expld.phase = lang_mark_phase_enum; 3335218822Sdim expld.dataseg.phase = exp_dataseg_none; 3336218822Sdim one_lang_size_sections_pass (NULL, FALSE); 3337218822Sdim lang_reset_memory_regions (); 3338218822Sdim } 3339104834Sobrien 3340218822Sdim for (os = &lang_output_section_statement.head->output_section_statement; 3341218822Sdim os != NULL; 3342218822Sdim os = os->next) 3343218822Sdim { 3344218822Sdim asection *output_section; 3345218822Sdim bfd_boolean exclude; 3346218822Sdim 3347218822Sdim if (os->constraint == -1) 3348218822Sdim continue; 3349218822Sdim 3350218822Sdim output_section = os->bfd_section; 3351218822Sdim if (output_section == NULL) 3352218822Sdim continue; 3353218822Sdim 3354218822Sdim exclude = (output_section->rawsize == 0 3355218822Sdim && (output_section->flags & SEC_KEEP) == 0 3356218822Sdim && !bfd_section_removed_from_list (output_bfd, 3357218822Sdim output_section)); 3358218822Sdim 3359218822Sdim /* Some sections have not yet been sized, notably .gnu.version, 3360218822Sdim .dynsym, .dynstr and .hash. These all have SEC_LINKER_CREATED 3361218822Sdim input sections, so don't drop output sections that have such 3362218822Sdim input sections unless they are also marked SEC_EXCLUDE. */ 3363218822Sdim if (exclude && output_section->map_head.s != NULL) 3364104834Sobrien { 3365218822Sdim asection *s; 3366104834Sobrien 3367218822Sdim for (s = output_section->map_head.s; s != NULL; s = s->map_head.s) 3368218822Sdim if ((s->flags & SEC_LINKER_CREATED) != 0 3369218822Sdim && (s->flags & SEC_EXCLUDE) == 0) 3370104834Sobrien { 3371218822Sdim exclude = FALSE; 3372104834Sobrien break; 3373104834Sobrien } 3374104834Sobrien } 3375218822Sdim 3376218822Sdim /* TODO: Don't just junk map_head.s, turn them into link_orders. */ 3377218822Sdim output_section->map_head.link_order = NULL; 3378218822Sdim output_section->map_tail.link_order = NULL; 3379218822Sdim 3380218822Sdim if (exclude) 3381218822Sdim { 3382218822Sdim /* We don't set bfd_section to NULL since bfd_section of the 3383218822Sdim removed output section statement may still be used. */ 3384218822Sdim if (!os->section_relative_symbol) 3385218822Sdim os->ignored = TRUE; 3386218822Sdim output_section->flags |= SEC_EXCLUDE; 3387218822Sdim bfd_section_list_remove (output_bfd, output_section); 3388218822Sdim output_bfd->section_count--; 3389218822Sdim } 3390104834Sobrien } 3391218822Sdim 3392218822Sdim /* Stop future calls to lang_add_section from messing with map_head 3393218822Sdim and map_tail link_order fields. */ 3394218822Sdim stripped_excluded_sections = TRUE; 3395104834Sobrien} 3396104834Sobrien 3397104834Sobrienstatic void 3398130561Sobrienprint_output_section_statement 3399130561Sobrien (lang_output_section_statement_type *output_section_statement) 340033965Sjdp{ 340133965Sjdp asection *section = output_section_statement->bfd_section; 340233965Sjdp int len; 340333965Sjdp 340433965Sjdp if (output_section_statement != abs_output_section) 340533965Sjdp { 340633965Sjdp minfo ("\n%s", output_section_statement->name); 340733965Sjdp 340833965Sjdp if (section != NULL) 340933965Sjdp { 341033965Sjdp print_dot = section->vma; 341133965Sjdp 341233965Sjdp len = strlen (output_section_statement->name); 341333965Sjdp if (len >= SECTION_NAME_MAP_LENGTH - 1) 341433965Sjdp { 341533965Sjdp print_nl (); 341633965Sjdp len = 0; 341733965Sjdp } 341833965Sjdp while (len < SECTION_NAME_MAP_LENGTH) 341933965Sjdp { 342033965Sjdp print_space (); 342133965Sjdp ++len; 342233965Sjdp } 342333965Sjdp 3424218822Sdim minfo ("0x%V %W", section->vma, section->size); 342533965Sjdp 3426218822Sdim if (section->vma != section->lma) 3427218822Sdim minfo (_(" load address 0x%V"), section->lma); 342833965Sjdp } 342933965Sjdp 343033965Sjdp print_nl (); 343133965Sjdp } 343233965Sjdp 343333965Sjdp print_statement_list (output_section_statement->children.head, 343433965Sjdp output_section_statement); 343533965Sjdp} 343633965Sjdp 3437218822Sdim/* Scan for the use of the destination in the right hand side 3438218822Sdim of an expression. In such cases we will not compute the 3439218822Sdim correct expression, since the value of DST that is used on 3440218822Sdim the right hand side will be its final value, not its value 3441218822Sdim just before this expression is evaluated. */ 3442218822Sdim 3443218822Sdimstatic bfd_boolean 3444218822Sdimscan_for_self_assignment (const char * dst, etree_type * rhs) 3445218822Sdim{ 3446218822Sdim if (rhs == NULL || dst == NULL) 3447218822Sdim return FALSE; 3448218822Sdim 3449218822Sdim switch (rhs->type.node_class) 3450218822Sdim { 3451218822Sdim case etree_binary: 3452218822Sdim return scan_for_self_assignment (dst, rhs->binary.lhs) 3453218822Sdim || scan_for_self_assignment (dst, rhs->binary.rhs); 3454218822Sdim 3455218822Sdim case etree_trinary: 3456218822Sdim return scan_for_self_assignment (dst, rhs->trinary.lhs) 3457218822Sdim || scan_for_self_assignment (dst, rhs->trinary.rhs); 3458218822Sdim 3459218822Sdim case etree_assign: 3460218822Sdim case etree_provided: 3461218822Sdim case etree_provide: 3462218822Sdim if (strcmp (dst, rhs->assign.dst) == 0) 3463218822Sdim return TRUE; 3464218822Sdim return scan_for_self_assignment (dst, rhs->assign.src); 3465218822Sdim 3466218822Sdim case etree_unary: 3467218822Sdim return scan_for_self_assignment (dst, rhs->unary.child); 3468218822Sdim 3469218822Sdim case etree_value: 3470218822Sdim if (rhs->value.str) 3471218822Sdim return strcmp (dst, rhs->value.str) == 0; 3472218822Sdim return FALSE; 3473218822Sdim 3474218822Sdim case etree_name: 3475218822Sdim if (rhs->name.name) 3476218822Sdim return strcmp (dst, rhs->name.name) == 0; 3477218822Sdim return FALSE; 3478218822Sdim 3479218822Sdim default: 3480218822Sdim break; 3481218822Sdim } 3482218822Sdim 3483218822Sdim return FALSE; 3484218822Sdim} 3485218822Sdim 3486218822Sdim 348733965Sjdpstatic void 3488130561Sobrienprint_assignment (lang_assignment_statement_type *assignment, 3489130561Sobrien lang_output_section_statement_type *output_section) 349033965Sjdp{ 3491218822Sdim unsigned int i; 3492218822Sdim bfd_boolean is_dot; 3493218822Sdim bfd_boolean computation_is_valid = TRUE; 3494218822Sdim etree_type *tree; 349533965Sjdp 349633965Sjdp for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) 349733965Sjdp print_space (); 349833965Sjdp 3499218822Sdim if (assignment->exp->type.node_class == etree_assert) 3500104834Sobrien { 3501218822Sdim is_dot = FALSE; 3502218822Sdim tree = assignment->exp->assert_s.child; 3503218822Sdim computation_is_valid = TRUE; 3504218822Sdim } 3505218822Sdim else 3506218822Sdim { 3507218822Sdim const char *dst = assignment->exp->assign.dst; 3508218822Sdim 3509218822Sdim is_dot = (dst[0] == '.' && dst[1] == 0); 3510218822Sdim tree = assignment->exp->assign.src; 3511218822Sdim computation_is_valid = is_dot || (scan_for_self_assignment (dst, tree) == FALSE); 3512218822Sdim } 3513218822Sdim 3514218822Sdim exp_fold_tree (tree, output_section->bfd_section, &print_dot); 3515218822Sdim if (expld.result.valid_p) 3516218822Sdim { 3517104834Sobrien bfd_vma value; 3518104834Sobrien 3519218822Sdim if (computation_is_valid) 3520218822Sdim { 3521218822Sdim value = expld.result.value; 3522104834Sobrien 3523218822Sdim if (expld.result.section) 3524218822Sdim value += expld.result.section->vma; 3525218822Sdim 3526218822Sdim minfo ("0x%V", value); 3527218822Sdim if (is_dot) 3528218822Sdim print_dot = value; 3529218822Sdim } 3530218822Sdim else 3531218822Sdim { 3532218822Sdim struct bfd_link_hash_entry *h; 3533218822Sdim 3534218822Sdim h = bfd_link_hash_lookup (link_info.hash, assignment->exp->assign.dst, 3535218822Sdim FALSE, FALSE, TRUE); 3536218822Sdim if (h) 3537218822Sdim { 3538218822Sdim value = h->u.def.value; 3539218822Sdim 3540218822Sdim if (expld.result.section) 3541218822Sdim value += expld.result.section->vma; 3542218822Sdim 3543218822Sdim minfo ("[0x%V]", value); 3544218822Sdim } 3545218822Sdim else 3546218822Sdim minfo ("[unresolved]"); 3547218822Sdim } 3548104834Sobrien } 354933965Sjdp else 355033965Sjdp { 355133965Sjdp minfo ("*undef* "); 355233965Sjdp#ifdef BFD64 355333965Sjdp minfo (" "); 355433965Sjdp#endif 355533965Sjdp } 355633965Sjdp 355733965Sjdp minfo (" "); 355833965Sjdp exp_print_tree (assignment->exp); 355933965Sjdp print_nl (); 356033965Sjdp} 356133965Sjdp 356233965Sjdpstatic void 3563130561Sobrienprint_input_statement (lang_input_statement_type *statm) 356433965Sjdp{ 3565130561Sobrien if (statm->filename != NULL) 356633965Sjdp { 356733965Sjdp fprintf (config.map_file, "LOAD %s\n", statm->filename); 356833965Sjdp } 356933965Sjdp} 357033965Sjdp 357133965Sjdp/* Print all symbols defined in a particular section. This is called 3572218822Sdim via bfd_link_hash_traverse, or by print_all_symbols. */ 357333965Sjdp 3574130561Sobrienstatic bfd_boolean 3575130561Sobrienprint_one_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr) 357633965Sjdp{ 3577130561Sobrien asection *sec = ptr; 357833965Sjdp 357933965Sjdp if ((hash_entry->type == bfd_link_hash_defined 358033965Sjdp || hash_entry->type == bfd_link_hash_defweak) 358133965Sjdp && sec == hash_entry->u.def.section) 358233965Sjdp { 358333965Sjdp int i; 358433965Sjdp 358533965Sjdp for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) 358633965Sjdp print_space (); 358733965Sjdp minfo ("0x%V ", 358833965Sjdp (hash_entry->u.def.value 358933965Sjdp + hash_entry->u.def.section->output_offset 359033965Sjdp + hash_entry->u.def.section->output_section->vma)); 359133965Sjdp 359233965Sjdp minfo (" %T\n", hash_entry->root.string); 359333965Sjdp } 359433965Sjdp 3595130561Sobrien return TRUE; 359633965Sjdp} 359733965Sjdp 3598218822Sdimstatic void 3599218822Sdimprint_all_symbols (asection *sec) 3600218822Sdim{ 3601218822Sdim struct fat_user_section_struct *ud = get_userdata (sec); 3602218822Sdim struct map_symbol_def *def; 3603218822Sdim 3604218822Sdim if (!ud) 3605218822Sdim return; 3606218822Sdim 3607218822Sdim *ud->map_symbol_def_tail = 0; 3608218822Sdim for (def = ud->map_symbol_def_head; def; def = def->next) 3609218822Sdim print_one_symbol (def->entry, sec); 3610218822Sdim} 3611218822Sdim 361233965Sjdp/* Print information about an input section to the map file. */ 361333965Sjdp 361433965Sjdpstatic void 3615218822Sdimprint_input_section (asection *i) 361633965Sjdp{ 3617218822Sdim bfd_size_type size = i->size; 3618218822Sdim int len; 3619218822Sdim bfd_vma addr; 3620130561Sobrien 3621130561Sobrien init_opb (); 3622218822Sdim 3623218822Sdim print_space (); 3624218822Sdim minfo ("%s", i->name); 3625218822Sdim 3626218822Sdim len = 1 + strlen (i->name); 3627218822Sdim if (len >= SECTION_NAME_MAP_LENGTH - 1) 362833965Sjdp { 3629218822Sdim print_nl (); 3630218822Sdim len = 0; 3631218822Sdim } 3632218822Sdim while (len < SECTION_NAME_MAP_LENGTH) 3633218822Sdim { 363433965Sjdp print_space (); 3635218822Sdim ++len; 3636218822Sdim } 363733965Sjdp 3638218822Sdim if (i->output_section != NULL && i->output_section->owner == output_bfd) 3639218822Sdim addr = i->output_section->vma + i->output_offset; 3640218822Sdim else 3641218822Sdim { 3642218822Sdim addr = print_dot; 3643218822Sdim size = 0; 3644218822Sdim } 364533965Sjdp 3646218822Sdim minfo ("0x%V %W %B\n", addr, TO_ADDR (size), i->owner); 364733965Sjdp 3648218822Sdim if (size != i->rawsize && i->rawsize != 0) 3649218822Sdim { 3650218822Sdim len = SECTION_NAME_MAP_LENGTH + 3; 365133965Sjdp#ifdef BFD64 3652218822Sdim len += 16; 365333965Sjdp#else 3654218822Sdim len += 8; 365533965Sjdp#endif 3656218822Sdim while (len > 0) 3657218822Sdim { 3658218822Sdim print_space (); 3659218822Sdim --len; 3660218822Sdim } 366133965Sjdp 3662218822Sdim minfo (_("%W (size before relaxing)\n"), i->rawsize); 3663218822Sdim } 366433965Sjdp 3665218822Sdim if (i->output_section != NULL && i->output_section->owner == output_bfd) 3666218822Sdim { 3667218822Sdim if (link_info.reduce_memory_overheads) 3668218822Sdim bfd_link_hash_traverse (link_info.hash, print_one_symbol, i); 3669218822Sdim else 3670218822Sdim print_all_symbols (i); 367133965Sjdp 3672218822Sdim print_dot = addr + TO_ADDR (size); 367333965Sjdp } 367433965Sjdp} 367533965Sjdp 367633965Sjdpstatic void 3677130561Sobrienprint_fill_statement (lang_fill_statement_type *fill) 367833965Sjdp{ 3679104834Sobrien size_t size; 3680104834Sobrien unsigned char *p; 3681104834Sobrien fputs (" FILL mask 0x", config.map_file); 3682104834Sobrien for (p = fill->fill->data, size = fill->fill->size; size != 0; p++, size--) 3683104834Sobrien fprintf (config.map_file, "%02x", *p); 3684104834Sobrien fputs ("\n", config.map_file); 368533965Sjdp} 368633965Sjdp 368733965Sjdpstatic void 3688130561Sobrienprint_data_statement (lang_data_statement_type *data) 368933965Sjdp{ 369033965Sjdp int i; 369133965Sjdp bfd_vma addr; 369233965Sjdp bfd_size_type size; 369333965Sjdp const char *name; 369433965Sjdp 3695130561Sobrien init_opb (); 369633965Sjdp for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) 369733965Sjdp print_space (); 369833965Sjdp 3699218822Sdim addr = data->output_offset; 370033965Sjdp if (data->output_section != NULL) 370133965Sjdp addr += data->output_section->vma; 370233965Sjdp 370333965Sjdp switch (data->type) 370433965Sjdp { 370533965Sjdp default: 370633965Sjdp abort (); 370733965Sjdp case BYTE: 370833965Sjdp size = BYTE_SIZE; 370933965Sjdp name = "BYTE"; 371033965Sjdp break; 371133965Sjdp case SHORT: 371233965Sjdp size = SHORT_SIZE; 371333965Sjdp name = "SHORT"; 371433965Sjdp break; 371533965Sjdp case LONG: 371633965Sjdp size = LONG_SIZE; 371733965Sjdp name = "LONG"; 371833965Sjdp break; 371933965Sjdp case QUAD: 372033965Sjdp size = QUAD_SIZE; 372133965Sjdp name = "QUAD"; 372233965Sjdp break; 372338889Sjdp case SQUAD: 372438889Sjdp size = QUAD_SIZE; 372538889Sjdp name = "SQUAD"; 372638889Sjdp break; 372733965Sjdp } 372833965Sjdp 372933965Sjdp minfo ("0x%V %W %s 0x%v", addr, size, name, data->value); 373033965Sjdp 373133965Sjdp if (data->exp->type.node_class != etree_value) 373233965Sjdp { 373333965Sjdp print_space (); 373433965Sjdp exp_print_tree (data->exp); 373533965Sjdp } 373633965Sjdp 373733965Sjdp print_nl (); 373833965Sjdp 3739130561Sobrien print_dot = addr + TO_ADDR (size); 374033965Sjdp} 374133965Sjdp 374233965Sjdp/* Print an address statement. These are generated by options like 374333965Sjdp -Ttext. */ 374433965Sjdp 374533965Sjdpstatic void 3746130561Sobrienprint_address_statement (lang_address_statement_type *address) 374733965Sjdp{ 374860484Sobrien minfo (_("Address of section %s set to "), address->section_name); 374933965Sjdp exp_print_tree (address->address); 375033965Sjdp print_nl (); 375133965Sjdp} 375233965Sjdp 375333965Sjdp/* Print a reloc statement. */ 375433965Sjdp 375533965Sjdpstatic void 3756130561Sobrienprint_reloc_statement (lang_reloc_statement_type *reloc) 375733965Sjdp{ 375833965Sjdp int i; 375933965Sjdp bfd_vma addr; 376033965Sjdp bfd_size_type size; 376133965Sjdp 3762130561Sobrien init_opb (); 376333965Sjdp for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) 376433965Sjdp print_space (); 376533965Sjdp 3766218822Sdim addr = reloc->output_offset; 376733965Sjdp if (reloc->output_section != NULL) 376833965Sjdp addr += reloc->output_section->vma; 376933965Sjdp 377033965Sjdp size = bfd_get_reloc_size (reloc->howto); 377133965Sjdp 377233965Sjdp minfo ("0x%V %W RELOC %s ", addr, size, reloc->howto->name); 377333965Sjdp 377433965Sjdp if (reloc->name != NULL) 377533965Sjdp minfo ("%s+", reloc->name); 377633965Sjdp else 377733965Sjdp minfo ("%s+", reloc->section->name); 377833965Sjdp 377933965Sjdp exp_print_tree (reloc->addend_exp); 378033965Sjdp 378133965Sjdp print_nl (); 378233965Sjdp 3783130561Sobrien print_dot = addr + TO_ADDR (size); 378477298Sobrien} 378533965Sjdp 378633965Sjdpstatic void 3787130561Sobrienprint_padding_statement (lang_padding_statement_type *s) 378833965Sjdp{ 378933965Sjdp int len; 379033965Sjdp bfd_vma addr; 379133965Sjdp 3792130561Sobrien init_opb (); 379333965Sjdp minfo (" *fill*"); 379433965Sjdp 379533965Sjdp len = sizeof " *fill*" - 1; 379633965Sjdp while (len < SECTION_NAME_MAP_LENGTH) 379733965Sjdp { 379833965Sjdp print_space (); 379933965Sjdp ++len; 380033965Sjdp } 380133965Sjdp 380233965Sjdp addr = s->output_offset; 380333965Sjdp if (s->output_section != NULL) 380433965Sjdp addr += s->output_section->vma; 3805218822Sdim minfo ("0x%V %W ", addr, (bfd_vma) s->size); 380633965Sjdp 3807104834Sobrien if (s->fill->size != 0) 3808104834Sobrien { 3809104834Sobrien size_t size; 3810104834Sobrien unsigned char *p; 3811104834Sobrien for (p = s->fill->data, size = s->fill->size; size != 0; p++, size--) 3812104834Sobrien fprintf (config.map_file, "%02x", *p); 3813104834Sobrien } 381433965Sjdp 381533965Sjdp print_nl (); 381633965Sjdp 3817130561Sobrien print_dot = addr + TO_ADDR (s->size); 381833965Sjdp} 381933965Sjdp 382033965Sjdpstatic void 3821130561Sobrienprint_wild_statement (lang_wild_statement_type *w, 3822130561Sobrien lang_output_section_statement_type *os) 382333965Sjdp{ 382489857Sobrien struct wildcard_list *sec; 382589857Sobrien 382633965Sjdp print_space (); 382733965Sjdp 382860484Sobrien if (w->filenames_sorted) 382960484Sobrien minfo ("SORT("); 383077298Sobrien if (w->filename != NULL) 383133965Sjdp minfo ("%s", w->filename); 383233965Sjdp else 383333965Sjdp minfo ("*"); 383460484Sobrien if (w->filenames_sorted) 383560484Sobrien minfo (")"); 383633965Sjdp 383760484Sobrien minfo ("("); 383889857Sobrien for (sec = w->section_list; sec; sec = sec->next) 383989857Sobrien { 384089857Sobrien if (sec->spec.sorted) 384189857Sobrien minfo ("SORT("); 384289857Sobrien if (sec->spec.exclude_name_list != NULL) 384389857Sobrien { 384489857Sobrien name_list *tmp; 3845102729Sobrien minfo ("EXCLUDE_FILE(%s", sec->spec.exclude_name_list->name); 384689857Sobrien for (tmp = sec->spec.exclude_name_list->next; tmp; tmp = tmp->next) 3847102729Sobrien minfo (" %s", tmp->name); 3848102729Sobrien minfo (") "); 384989857Sobrien } 385089857Sobrien if (sec->spec.name != NULL) 385189857Sobrien minfo ("%s", sec->spec.name); 385289857Sobrien else 385389857Sobrien minfo ("*"); 385489857Sobrien if (sec->spec.sorted) 385589857Sobrien minfo (")"); 3856102729Sobrien if (sec->next) 3857102729Sobrien minfo (" "); 385889857Sobrien } 385960484Sobrien minfo (")"); 386033965Sjdp 386133965Sjdp print_nl (); 386233965Sjdp 386333965Sjdp print_statement_list (w->children.head, os); 386433965Sjdp} 386533965Sjdp 386633965Sjdp/* Print a group statement. */ 386733965Sjdp 386833965Sjdpstatic void 3869130561Sobrienprint_group (lang_group_statement_type *s, 3870130561Sobrien lang_output_section_statement_type *os) 387133965Sjdp{ 387233965Sjdp fprintf (config.map_file, "START GROUP\n"); 387333965Sjdp print_statement_list (s->children.head, os); 387433965Sjdp fprintf (config.map_file, "END GROUP\n"); 387533965Sjdp} 387633965Sjdp 387733965Sjdp/* Print the list of statements in S. 387833965Sjdp This can be called for any statement type. */ 387933965Sjdp 388033965Sjdpstatic void 3881130561Sobrienprint_statement_list (lang_statement_union_type *s, 3882130561Sobrien lang_output_section_statement_type *os) 388333965Sjdp{ 388433965Sjdp while (s != NULL) 388533965Sjdp { 388633965Sjdp print_statement (s, os); 388789857Sobrien s = s->header.next; 388833965Sjdp } 388933965Sjdp} 389033965Sjdp 389133965Sjdp/* Print the first statement in statement list S. 389233965Sjdp This can be called for any statement type. */ 389333965Sjdp 389433965Sjdpstatic void 3895130561Sobrienprint_statement (lang_statement_union_type *s, 3896130561Sobrien lang_output_section_statement_type *os) 389733965Sjdp{ 389833965Sjdp switch (s->header.type) 389933965Sjdp { 390033965Sjdp default: 390160484Sobrien fprintf (config.map_file, _("Fail with %d\n"), s->header.type); 390233965Sjdp FAIL (); 390333965Sjdp break; 390433965Sjdp case lang_constructors_statement_enum: 390533965Sjdp if (constructor_list.head != NULL) 390633965Sjdp { 390760484Sobrien if (constructors_sorted) 390860484Sobrien minfo (" SORT (CONSTRUCTORS)\n"); 390960484Sobrien else 391060484Sobrien minfo (" CONSTRUCTORS\n"); 391133965Sjdp print_statement_list (constructor_list.head, os); 391233965Sjdp } 391333965Sjdp break; 391433965Sjdp case lang_wild_statement_enum: 391533965Sjdp print_wild_statement (&s->wild_statement, os); 391633965Sjdp break; 391733965Sjdp case lang_address_statement_enum: 391833965Sjdp print_address_statement (&s->address_statement); 391933965Sjdp break; 392033965Sjdp case lang_object_symbols_statement_enum: 392133965Sjdp minfo (" CREATE_OBJECT_SYMBOLS\n"); 392233965Sjdp break; 392333965Sjdp case lang_fill_statement_enum: 392433965Sjdp print_fill_statement (&s->fill_statement); 392533965Sjdp break; 392633965Sjdp case lang_data_statement_enum: 392733965Sjdp print_data_statement (&s->data_statement); 392833965Sjdp break; 392933965Sjdp case lang_reloc_statement_enum: 393033965Sjdp print_reloc_statement (&s->reloc_statement); 393133965Sjdp break; 393233965Sjdp case lang_input_section_enum: 3933218822Sdim print_input_section (s->input_section.section); 393433965Sjdp break; 393533965Sjdp case lang_padding_statement_enum: 393633965Sjdp print_padding_statement (&s->padding_statement); 393733965Sjdp break; 393833965Sjdp case lang_output_section_statement_enum: 393933965Sjdp print_output_section_statement (&s->output_section_statement); 394033965Sjdp break; 394133965Sjdp case lang_assignment_statement_enum: 394233965Sjdp print_assignment (&s->assignment_statement, os); 394333965Sjdp break; 394433965Sjdp case lang_target_statement_enum: 394533965Sjdp fprintf (config.map_file, "TARGET(%s)\n", s->target_statement.target); 394633965Sjdp break; 394733965Sjdp case lang_output_statement_enum: 394833965Sjdp minfo ("OUTPUT(%s", s->output_statement.name); 394933965Sjdp if (output_target != NULL) 395033965Sjdp minfo (" %s", output_target); 395133965Sjdp minfo (")\n"); 395233965Sjdp break; 395333965Sjdp case lang_input_statement_enum: 395433965Sjdp print_input_statement (&s->input_statement); 395533965Sjdp break; 395633965Sjdp case lang_group_statement_enum: 395733965Sjdp print_group (&s->group_statement, os); 395833965Sjdp break; 395933965Sjdp case lang_afile_asection_pair_statement_enum: 396033965Sjdp FAIL (); 396133965Sjdp break; 396233965Sjdp } 396333965Sjdp} 396433965Sjdp 396533965Sjdpstatic void 3966130561Sobrienprint_statements (void) 396733965Sjdp{ 396833965Sjdp print_statement_list (statement_list.head, abs_output_section); 396933965Sjdp} 397033965Sjdp 397133965Sjdp/* Print the first N statements in statement list S to STDERR. 397233965Sjdp If N == 0, nothing is printed. 397333965Sjdp If N < 0, the entire list is printed. 397433965Sjdp Intended to be called from GDB. */ 397533965Sjdp 397633965Sjdpvoid 3977130561Sobriendprint_statement (lang_statement_union_type *s, int n) 397833965Sjdp{ 397933965Sjdp FILE *map_save = config.map_file; 398033965Sjdp 398133965Sjdp config.map_file = stderr; 398233965Sjdp 398333965Sjdp if (n < 0) 398433965Sjdp print_statement_list (s, abs_output_section); 398533965Sjdp else 398633965Sjdp { 398733965Sjdp while (s && --n >= 0) 398833965Sjdp { 398933965Sjdp print_statement (s, abs_output_section); 399089857Sobrien s = s->header.next; 399133965Sjdp } 399233965Sjdp } 399333965Sjdp 399433965Sjdp config.map_file = map_save; 399533965Sjdp} 399633965Sjdp 399789857Sobrienstatic void 3998130561Sobrieninsert_pad (lang_statement_union_type **ptr, 3999130561Sobrien fill_type *fill, 4000130561Sobrien unsigned int alignment_needed, 4001130561Sobrien asection *output_section, 4002130561Sobrien bfd_vma dot) 400333965Sjdp{ 4004104834Sobrien static fill_type zero_fill = { 1, { 0 } }; 4005218822Sdim lang_statement_union_type *pad = NULL; 400633965Sjdp 4007218822Sdim if (ptr != &statement_list.head) 4008218822Sdim pad = ((lang_statement_union_type *) 4009218822Sdim ((char *) ptr - offsetof (lang_statement_union_type, header.next))); 4010218822Sdim if (pad != NULL 401189857Sobrien && pad->header.type == lang_padding_statement_enum 401289857Sobrien && pad->padding_statement.output_section == output_section) 401333965Sjdp { 4014218822Sdim /* Use the existing pad statement. */ 401533965Sjdp } 4016218822Sdim else if ((pad = *ptr) != NULL 4017218822Sdim && pad->header.type == lang_padding_statement_enum 4018218822Sdim && pad->padding_statement.output_section == output_section) 4019218822Sdim { 4020218822Sdim /* Use the existing pad statement. */ 4021218822Sdim } 402289857Sobrien else 402333965Sjdp { 402489857Sobrien /* Make a new padding statement, linked into existing chain. */ 4025130561Sobrien pad = stat_alloc (sizeof (lang_padding_statement_type)); 402689857Sobrien pad->header.next = *ptr; 402789857Sobrien *ptr = pad; 402889857Sobrien pad->header.type = lang_padding_statement_enum; 402989857Sobrien pad->padding_statement.output_section = output_section; 4030130561Sobrien if (fill == NULL) 4031104834Sobrien fill = &zero_fill; 403289857Sobrien pad->padding_statement.fill = fill; 403333965Sjdp } 403489857Sobrien pad->padding_statement.output_offset = dot - output_section->vma; 403589857Sobrien pad->padding_statement.size = alignment_needed; 4036218822Sdim output_section->size += alignment_needed; 403733965Sjdp} 403833965Sjdp 403977298Sobrien/* Work out how much this section will move the dot point. */ 404077298Sobrien 404133965Sjdpstatic bfd_vma 4042218822Sdimsize_input_section 4043218822Sdim (lang_statement_union_type **this_ptr, 4044218822Sdim lang_output_section_statement_type *output_section_statement, 4045218822Sdim fill_type *fill, 4046218822Sdim bfd_vma dot) 404733965Sjdp{ 404833965Sjdp lang_input_section_type *is = &((*this_ptr)->input_section); 404933965Sjdp asection *i = is->section; 405033965Sjdp 4051218822Sdim if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag 4052218822Sdim && (i->flags & SEC_EXCLUDE) == 0) 405333965Sjdp { 405489857Sobrien unsigned int alignment_needed; 405589857Sobrien asection *o; 405689857Sobrien 405789857Sobrien /* Align this section first to the input sections requirement, 405889857Sobrien then to the output section's requirement. If this alignment 405989857Sobrien is greater than any seen before, then record it too. Perform 406089857Sobrien the alignment by inserting a magic 'padding' statement. */ 406189857Sobrien 406233965Sjdp if (output_section_statement->subsection_alignment != -1) 406389857Sobrien i->alignment_power = output_section_statement->subsection_alignment; 406433965Sjdp 406589857Sobrien o = output_section_statement->bfd_section; 406689857Sobrien if (o->alignment_power < i->alignment_power) 406789857Sobrien o->alignment_power = i->alignment_power; 406833965Sjdp 406989857Sobrien alignment_needed = align_power (dot, i->alignment_power) - dot; 407089857Sobrien 407189857Sobrien if (alignment_needed != 0) 407289857Sobrien { 4073130561Sobrien insert_pad (this_ptr, fill, TO_SIZE (alignment_needed), o, dot); 407489857Sobrien dot += alignment_needed; 407589857Sobrien } 407689857Sobrien 407777298Sobrien /* Remember where in the output section this input section goes. */ 407833965Sjdp 407989857Sobrien i->output_offset = dot - o->vma; 408033965Sjdp 408177298Sobrien /* Mark how big the output section must be to contain this now. */ 4082218822Sdim dot += TO_ADDR (i->size); 4083218822Sdim o->size = TO_SIZE (dot - o->vma); 408433965Sjdp } 408533965Sjdp else 408633965Sjdp { 408733965Sjdp i->output_offset = i->vma - output_section_statement->bfd_section->vma; 408833965Sjdp } 408933965Sjdp 409033965Sjdp return dot; 409133965Sjdp} 409233965Sjdp 4093218822Sdimstatic int 4094218822Sdimsort_sections_by_lma (const void *arg1, const void *arg2) 4095218822Sdim{ 4096218822Sdim const asection *sec1 = *(const asection **) arg1; 4097218822Sdim const asection *sec2 = *(const asection **) arg2; 409860484Sobrien 4099218822Sdim if (bfd_section_lma (sec1->owner, sec1) 4100218822Sdim < bfd_section_lma (sec2->owner, sec2)) 4101218822Sdim return -1; 4102218822Sdim else if (bfd_section_lma (sec1->owner, sec1) 4103218822Sdim > bfd_section_lma (sec2->owner, sec2)) 4104218822Sdim return 1; 4105218822Sdim 4106218822Sdim return 0; 4107218822Sdim} 4108218822Sdim 4109218822Sdim#define IGNORE_SECTION(s) \ 4110218822Sdim ((s->flags & SEC_NEVER_LOAD) != 0 \ 4111218822Sdim || (s->flags & SEC_ALLOC) == 0 \ 4112218822Sdim || ((s->flags & SEC_THREAD_LOCAL) != 0 \ 4113218822Sdim && (s->flags & SEC_LOAD) == 0)) 4114218822Sdim 411560484Sobrien/* Check to see if any allocated sections overlap with other allocated 4116218822Sdim sections. This can happen if a linker script specifies the output 4117218822Sdim section addresses of the two sections. */ 411877298Sobrien 411960484Sobrienstatic void 4120130561Sobrienlang_check_section_addresses (void) 412160484Sobrien{ 4122218822Sdim asection *s, *os; 4123218822Sdim asection **sections, **spp; 4124218822Sdim unsigned int count; 4125218822Sdim bfd_vma s_start; 4126218822Sdim bfd_vma s_end; 4127218822Sdim bfd_vma os_start; 4128218822Sdim bfd_vma os_end; 4129218822Sdim bfd_size_type amt; 413060484Sobrien 4131218822Sdim if (bfd_count_sections (output_bfd) <= 1) 4132218822Sdim return; 4133218822Sdim 4134218822Sdim amt = bfd_count_sections (output_bfd) * sizeof (asection *); 4135218822Sdim sections = xmalloc (amt); 4136218822Sdim 413760484Sobrien /* Scan all sections in the output list. */ 4138218822Sdim count = 0; 413960484Sobrien for (s = output_bfd->sections; s != NULL; s = s->next) 414060484Sobrien { 4141218822Sdim /* Only consider loadable sections with real contents. */ 4142218822Sdim if (IGNORE_SECTION (s) || s->size == 0) 414360484Sobrien continue; 414477298Sobrien 4145218822Sdim sections[count] = s; 4146218822Sdim count++; 4147218822Sdim } 414877298Sobrien 4149218822Sdim if (count <= 1) 4150218822Sdim return; 415160484Sobrien 4152218822Sdim qsort (sections, (size_t) count, sizeof (asection *), 4153218822Sdim sort_sections_by_lma); 415477298Sobrien 4155218822Sdim spp = sections; 4156218822Sdim s = *spp++; 4157218822Sdim s_start = bfd_section_lma (output_bfd, s); 4158218822Sdim s_end = s_start + TO_ADDR (s->size) - 1; 4159218822Sdim for (count--; count; count--) 4160218822Sdim { 4161218822Sdim /* We must check the sections' LMA addresses not their VMA 4162218822Sdim addresses because overlay sections can have overlapping VMAs 4163218822Sdim but they must have distinct LMAs. */ 4164218822Sdim os = s; 4165218822Sdim os_start = s_start; 4166218822Sdim os_end = s_end; 4167218822Sdim s = *spp++; 4168218822Sdim s_start = bfd_section_lma (output_bfd, s); 4169218822Sdim s_end = s_start + TO_ADDR (s->size) - 1; 417077298Sobrien 4171218822Sdim /* Look for an overlap. */ 4172218822Sdim if (s_end >= os_start && s_start <= os_end) 4173218822Sdim einfo (_("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"), 4174218822Sdim s->name, s_start, s_end, os->name, os_start, os_end); 4175218822Sdim } 417677298Sobrien 4177218822Sdim free (sections); 417860484Sobrien} 417960484Sobrien 418060484Sobrien/* Make sure the new address is within the region. We explicitly permit the 418160484Sobrien current address to be at the exact end of the region when the address is 418260484Sobrien non-zero, in case the region is at the end of addressable memory and the 418377298Sobrien calculation wraps around. */ 418460484Sobrien 418560484Sobrienstatic void 4186130561Sobrienos_region_check (lang_output_section_statement_type *os, 4187130561Sobrien lang_memory_region_type *region, 4188130561Sobrien etree_type *tree, 4189130561Sobrien bfd_vma base) 419060484Sobrien{ 419160484Sobrien if ((region->current < region->origin 419260484Sobrien || (region->current - region->origin > region->length)) 419360484Sobrien && ((region->current != region->origin + region->length) 4194104834Sobrien || base == 0)) 419560484Sobrien { 4196130561Sobrien if (tree != NULL) 4197104834Sobrien { 4198218822Sdim einfo (_("%X%P: address 0x%v of %B section %s" 4199218822Sdim " is not within region %s\n"), 4200104834Sobrien region->current, 4201104834Sobrien os->bfd_section->owner, 4202104834Sobrien os->bfd_section->name, 4203104834Sobrien region->name); 4204104834Sobrien } 420560484Sobrien else 4206104834Sobrien { 4207104834Sobrien einfo (_("%X%P: region %s is full (%B section %s)\n"), 4208104834Sobrien region->name, 4209104834Sobrien os->bfd_section->owner, 4210104834Sobrien os->bfd_section->name); 4211104834Sobrien } 421260484Sobrien /* Reset the region pointer. */ 421360484Sobrien region->current = region->origin; 421460484Sobrien } 421560484Sobrien} 421660484Sobrien 421733965Sjdp/* Set the sizes for all the output sections. */ 421833965Sjdp 4219104834Sobrienstatic bfd_vma 4220130561Sobrienlang_size_sections_1 4221130561Sobrien (lang_statement_union_type *s, 4222130561Sobrien lang_output_section_statement_type *output_section_statement, 4223130561Sobrien lang_statement_union_type **prev, 4224130561Sobrien fill_type *fill, 4225130561Sobrien bfd_vma dot, 4226130561Sobrien bfd_boolean *relax, 4227130561Sobrien bfd_boolean check_regions) 422833965Sjdp{ 422960484Sobrien /* Size up the sections from their constituent parts. */ 4230130561Sobrien for (; s != NULL; s = s->header.next) 423133965Sjdp { 423260484Sobrien switch (s->header.type) 423360484Sobrien { 423460484Sobrien case lang_output_section_statement_enum: 423560484Sobrien { 4236218822Sdim bfd_vma newdot, after; 423778828Sobrien lang_output_section_statement_type *os; 4238218822Sdim lang_memory_region_type *r; 423933965Sjdp 424078828Sobrien os = &s->output_section_statement; 4241218822Sdim if (os->addr_tree != NULL) 4242218822Sdim { 4243218822Sdim os->processed_vma = FALSE; 4244218822Sdim exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot); 4245218822Sdim 4246218822Sdim if (!expld.result.valid_p 4247218822Sdim && expld.phase != lang_mark_phase_enum) 4248218822Sdim einfo (_("%F%S: non constant or forward reference" 4249218822Sdim " address expression for section %s\n"), 4250218822Sdim os->name); 4251218822Sdim 4252218822Sdim dot = expld.result.value + expld.result.section->vma; 4253218822Sdim } 4254218822Sdim 425560484Sobrien if (os->bfd_section == NULL) 4256218822Sdim /* This section was removed or never actually created. */ 425760484Sobrien break; 425833965Sjdp 425960484Sobrien /* If this is a COFF shared library section, use the size and 426060484Sobrien address from the input section. FIXME: This is COFF 426160484Sobrien specific; it would be cleaner if there were some other way 426260484Sobrien to do this, but nothing simple comes to mind. */ 4263218822Sdim if ((bfd_get_flavour (output_bfd) == bfd_target_ecoff_flavour 4264218822Sdim || bfd_get_flavour (output_bfd) == bfd_target_coff_flavour) 4265218822Sdim && (os->bfd_section->flags & SEC_COFF_SHARED_LIBRARY) != 0) 426660484Sobrien { 426777298Sobrien asection *input; 426833965Sjdp 426960484Sobrien if (os->children.head == NULL 427089857Sobrien || os->children.head->header.next != NULL 4271218822Sdim || (os->children.head->header.type 4272218822Sdim != lang_input_section_enum)) 4273218822Sdim einfo (_("%P%X: Internal error on COFF shared library" 4274218822Sdim " section %s\n"), os->name); 427533965Sjdp 427660484Sobrien input = os->children.head->input_section.section; 4277222206Sbenl (void) bfd_set_section_vma (os->bfd_section->owner, 4278222206Sbenl os->bfd_section, 4279222206Sbenl bfd_section_vma (input->owner, 4280222206Sbenl input)); 4281218822Sdim os->bfd_section->size = input->size; 428260484Sobrien break; 428360484Sobrien } 428433965Sjdp 4285218822Sdim newdot = dot; 428660484Sobrien if (bfd_is_abs_section (os->bfd_section)) 428760484Sobrien { 428860484Sobrien /* No matter what happens, an abs section starts at zero. */ 428960484Sobrien ASSERT (os->bfd_section->vma == 0); 429060484Sobrien } 429160484Sobrien else 429260484Sobrien { 4293218822Sdim int align; 4294218822Sdim 4295130561Sobrien if (os->addr_tree == NULL) 429660484Sobrien { 429760484Sobrien /* No address specified for this section, get one 429860484Sobrien from the region specification. */ 4299130561Sobrien if (os->region == NULL 4300218822Sdim || ((os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD)) 430160484Sobrien && os->region->name[0] == '*' 4302218822Sdim && strcmp (os->region->name, 4303218822Sdim DEFAULT_MEMORY_REGION) == 0)) 430460484Sobrien { 430560484Sobrien os->region = lang_memory_default (os->bfd_section); 430660484Sobrien } 430733965Sjdp 430860484Sobrien /* If a loadable section is using the default memory 430960484Sobrien region, and some non default memory regions were 4310130561Sobrien defined, issue an error message. */ 4311218822Sdim if (!os->ignored 4312218822Sdim && !IGNORE_SECTION (os->bfd_section) 4313130561Sobrien && ! link_info.relocatable 4314130561Sobrien && check_regions 4315218822Sdim && strcmp (os->region->name, 4316218822Sdim DEFAULT_MEMORY_REGION) == 0 431760484Sobrien && lang_memory_region_list != NULL 431878828Sobrien && (strcmp (lang_memory_region_list->name, 4319130561Sobrien DEFAULT_MEMORY_REGION) != 0 4320218822Sdim || lang_memory_region_list->next != NULL) 4321218822Sdim && expld.phase != lang_mark_phase_enum) 4322130561Sobrien { 4323130561Sobrien /* By default this is an error rather than just a 4324130561Sobrien warning because if we allocate the section to the 4325130561Sobrien default memory region we can end up creating an 4326130561Sobrien excessively large binary, or even seg faulting when 4327130561Sobrien attempting to perform a negative seek. See 4328218822Sdim sources.redhat.com/ml/binutils/2003-04/msg00423.html 4329130561Sobrien for an example of this. This behaviour can be 4330130561Sobrien overridden by the using the --no-check-sections 4331130561Sobrien switch. */ 4332130561Sobrien if (command_line.check_section_addresses) 4333218822Sdim einfo (_("%P%F: error: no memory region specified" 4334218822Sdim " for loadable section `%s'\n"), 4335130561Sobrien bfd_get_section_name (output_bfd, 4336130561Sobrien os->bfd_section)); 4337130561Sobrien else 4338218822Sdim einfo (_("%P: warning: no memory region specified" 4339218822Sdim " for loadable section `%s'\n"), 4340130561Sobrien bfd_get_section_name (output_bfd, 4341130561Sobrien os->bfd_section)); 4342130561Sobrien } 434338889Sjdp 4344218822Sdim newdot = os->region->current; 4345218822Sdim align = os->bfd_section->alignment_power; 434660484Sobrien } 434760484Sobrien else 4348218822Sdim align = os->section_alignment; 4349218822Sdim 4350218822Sdim /* Align to what the section needs. */ 4351218822Sdim if (align > 0) 435260484Sobrien { 4353218822Sdim bfd_vma savedot = newdot; 4354218822Sdim newdot = align_power (newdot, align); 435533965Sjdp 4356218822Sdim if (newdot != savedot 4357218822Sdim && (config.warn_section_align 4358218822Sdim || os->addr_tree != NULL) 4359218822Sdim && expld.phase != lang_mark_phase_enum) 4360218822Sdim einfo (_("%P: warning: changing start of section" 4361218822Sdim " %s by %lu bytes\n"), 4362218822Sdim os->name, (unsigned long) (newdot - savedot)); 436360484Sobrien } 436477298Sobrien 4365222206Sbenl (void) bfd_set_section_vma (0, os->bfd_section, newdot); 436633965Sjdp 436760484Sobrien os->bfd_section->output_offset = 0; 436860484Sobrien } 436933965Sjdp 4370104834Sobrien lang_size_sections_1 (os->children.head, os, &os->children.head, 4371218822Sdim os->fill, newdot, relax, check_regions); 437277298Sobrien 4373218822Sdim os->processed_vma = TRUE; 437433965Sjdp 4375218822Sdim if (bfd_is_abs_section (os->bfd_section) || os->ignored) 4376218822Sdim /* Except for some special linker created sections, 4377218822Sdim no output section should change from zero size 4378218822Sdim after strip_excluded_output_sections. A non-zero 4379218822Sdim size on an ignored section indicates that some 4380218822Sdim input section was not sized early enough. */ 4381218822Sdim ASSERT (os->bfd_section->size == 0); 438260484Sobrien else 4383218822Sdim { 4384218822Sdim dot = os->bfd_section->vma; 4385104834Sobrien 4386218822Sdim /* Put the section within the requested block size, or 4387218822Sdim align at the block boundary. */ 4388218822Sdim after = ((dot 4389218822Sdim + TO_ADDR (os->bfd_section->size) 4390218822Sdim + os->block_value - 1) 4391218822Sdim & - (bfd_vma) os->block_value); 4392218822Sdim 4393218822Sdim os->bfd_section->size = TO_SIZE (after - os->bfd_section->vma); 4394218822Sdim } 4395218822Sdim 4396218822Sdim /* Set section lma. */ 4397218822Sdim r = os->region; 4398218822Sdim if (r == NULL) 4399218822Sdim r = lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE); 4400218822Sdim 4401218822Sdim if (os->load_base) 4402218822Sdim { 4403218822Sdim bfd_vma lma = exp_get_abs_int (os->load_base, 0, "load base"); 4404218822Sdim os->bfd_section->lma = lma; 4405218822Sdim } 4406218822Sdim else if (os->region != NULL 4407218822Sdim && os->lma_region != NULL 4408218822Sdim && os->lma_region != os->region) 4409218822Sdim { 4410218822Sdim bfd_vma lma = os->lma_region->current; 4411218822Sdim 4412218822Sdim if (os->section_alignment != -1) 4413218822Sdim lma = align_power (lma, os->section_alignment); 4414218822Sdim os->bfd_section->lma = lma; 4415218822Sdim } 4416218822Sdim else if (r->last_os != NULL 4417218822Sdim && (os->bfd_section->flags & SEC_ALLOC) != 0) 4418218822Sdim { 4419218822Sdim bfd_vma lma; 4420218822Sdim asection *last; 4421218822Sdim 4422218822Sdim last = r->last_os->output_section_statement.bfd_section; 4423218822Sdim 4424218822Sdim /* A backwards move of dot should be accompanied by 4425218822Sdim an explicit assignment to the section LMA (ie. 4426218822Sdim os->load_base set) because backwards moves can 4427218822Sdim create overlapping LMAs. */ 4428218822Sdim if (dot < last->vma 4429218822Sdim && os->bfd_section->size != 0 4430218822Sdim && dot + os->bfd_section->size <= last->vma) 4431218822Sdim { 4432218822Sdim /* If dot moved backwards then leave lma equal to 4433218822Sdim vma. This is the old default lma, which might 4434218822Sdim just happen to work when the backwards move is 4435218822Sdim sufficiently large. Nag if this changes anything, 4436218822Sdim so people can fix their linker scripts. */ 4437218822Sdim 4438218822Sdim if (last->vma != last->lma) 4439218822Sdim einfo (_("%P: warning: dot moved backwards before `%s'\n"), 4440218822Sdim os->name); 4441218822Sdim } 4442218822Sdim else 4443218822Sdim { 4444218822Sdim /* If this is an overlay, set the current lma to that 4445218822Sdim at the end of the previous section. */ 4446218822Sdim if (os->sectype == overlay_section) 4447218822Sdim lma = last->lma + last->size; 4448218822Sdim 4449218822Sdim /* Otherwise, keep the same lma to vma relationship 4450218822Sdim as the previous section. */ 4451218822Sdim else 4452218822Sdim lma = dot + last->lma - last->vma; 4453218822Sdim 4454218822Sdim if (os->section_alignment != -1) 4455218822Sdim lma = align_power (lma, os->section_alignment); 4456218822Sdim os->bfd_section->lma = lma; 4457218822Sdim } 4458218822Sdim } 4459218822Sdim os->processed_lma = TRUE; 4460218822Sdim 4461218822Sdim if (bfd_is_abs_section (os->bfd_section) || os->ignored) 4462218822Sdim break; 4463218822Sdim 4464218822Sdim /* Keep track of normal sections using the default 4465218822Sdim lma region. We use this to set the lma for 4466218822Sdim following sections. Overlays or other linker 4467218822Sdim script assignment to lma might mean that the 4468218822Sdim default lma == vma is incorrect. 4469218822Sdim To avoid warnings about dot moving backwards when using 4470218822Sdim -Ttext, don't start tracking sections until we find one 4471218822Sdim of non-zero size or with lma set differently to vma. */ 4472218822Sdim if (((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0 4473218822Sdim || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0) 4474218822Sdim && (os->bfd_section->flags & SEC_ALLOC) != 0 4475218822Sdim && (os->bfd_section->size != 0 4476218822Sdim || (r->last_os == NULL 4477218822Sdim && os->bfd_section->vma != os->bfd_section->lma) 4478218822Sdim || (r->last_os != NULL 4479218822Sdim && dot >= (r->last_os->output_section_statement 4480218822Sdim .bfd_section->vma))) 4481218822Sdim && os->lma_region == NULL 4482218822Sdim && !link_info.relocatable) 4483218822Sdim r->last_os = s; 4484218822Sdim 4485130561Sobrien /* .tbss sections effectively have zero size. */ 4486130561Sobrien if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0 4487130561Sobrien || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0 4488130561Sobrien || link_info.relocatable) 4489218822Sdim dot += TO_ADDR (os->bfd_section->size); 449033965Sjdp 4491104834Sobrien if (os->update_dot_tree != 0) 4492218822Sdim exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr, &dot); 4493104834Sobrien 449460484Sobrien /* Update dot in the region ? 449560484Sobrien We only do this if the section is going to be allocated, 449660484Sobrien since unallocated sections do not contribute to the region's 449760484Sobrien overall size in memory. 449877298Sobrien 449960484Sobrien If the SEC_NEVER_LOAD bit is not set, it will affect the 450060484Sobrien addresses of sections after it. We have to update 450160484Sobrien dot. */ 4502130561Sobrien if (os->region != NULL 4503218822Sdim && ((os->bfd_section->flags & SEC_NEVER_LOAD) == 0 4504218822Sdim || (os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD)))) 450560484Sobrien { 450660484Sobrien os->region->current = dot; 450777298Sobrien 4508130561Sobrien if (check_regions) 4509130561Sobrien /* Make sure the new address is within the region. */ 4510130561Sobrien os_region_check (os, os->region, os->addr_tree, 4511130561Sobrien os->bfd_section->vma); 451233965Sjdp 4513104834Sobrien if (os->lma_region != NULL && os->lma_region != os->region) 451477298Sobrien { 4515218822Sdim os->lma_region->current 4516218822Sdim = os->bfd_section->lma + TO_ADDR (os->bfd_section->size); 4517218822Sdim 4518130561Sobrien if (check_regions) 4519130561Sobrien os_region_check (os, os->lma_region, NULL, 4520130561Sobrien os->bfd_section->lma); 452177298Sobrien } 452260484Sobrien } 452360484Sobrien } 452460484Sobrien break; 452533965Sjdp 452660484Sobrien case lang_constructors_statement_enum: 4527104834Sobrien dot = lang_size_sections_1 (constructor_list.head, 4528104834Sobrien output_section_statement, 4529104834Sobrien &s->wild_statement.children.head, 4530130561Sobrien fill, dot, relax, check_regions); 453160484Sobrien break; 453233965Sjdp 453360484Sobrien case lang_data_statement_enum: 453460484Sobrien { 453560484Sobrien unsigned int size = 0; 453633965Sjdp 4537218822Sdim s->data_statement.output_offset = 453877298Sobrien dot - output_section_statement->bfd_section->vma; 453960484Sobrien s->data_statement.output_section = 454060484Sobrien output_section_statement->bfd_section; 454133965Sjdp 4542130561Sobrien /* We might refer to provided symbols in the expression, and 4543130561Sobrien need to mark them as needed. */ 4544218822Sdim exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot); 4545130561Sobrien 454660484Sobrien switch (s->data_statement.type) 454760484Sobrien { 454877298Sobrien default: 454977298Sobrien abort (); 455060484Sobrien case QUAD: 455160484Sobrien case SQUAD: 455260484Sobrien size = QUAD_SIZE; 455360484Sobrien break; 455460484Sobrien case LONG: 455560484Sobrien size = LONG_SIZE; 455660484Sobrien break; 455760484Sobrien case SHORT: 455860484Sobrien size = SHORT_SIZE; 455960484Sobrien break; 456060484Sobrien case BYTE: 456160484Sobrien size = BYTE_SIZE; 456260484Sobrien break; 456360484Sobrien } 4564130561Sobrien if (size < TO_SIZE ((unsigned) 1)) 4565130561Sobrien size = TO_SIZE ((unsigned) 1); 4566130561Sobrien dot += TO_ADDR (size); 4567218822Sdim output_section_statement->bfd_section->size += size; 456860484Sobrien } 456960484Sobrien break; 457033965Sjdp 457160484Sobrien case lang_reloc_statement_enum: 457260484Sobrien { 457360484Sobrien int size; 457433965Sjdp 4575218822Sdim s->reloc_statement.output_offset = 457660484Sobrien dot - output_section_statement->bfd_section->vma; 457760484Sobrien s->reloc_statement.output_section = 457860484Sobrien output_section_statement->bfd_section; 457960484Sobrien size = bfd_get_reloc_size (s->reloc_statement.howto); 4580130561Sobrien dot += TO_ADDR (size); 4581218822Sdim output_section_statement->bfd_section->size += size; 458260484Sobrien } 458360484Sobrien break; 458477298Sobrien 458560484Sobrien case lang_wild_statement_enum: 4586104834Sobrien dot = lang_size_sections_1 (s->wild_statement.children.head, 4587104834Sobrien output_section_statement, 4588104834Sobrien &s->wild_statement.children.head, 4589130561Sobrien fill, dot, relax, check_regions); 459060484Sobrien break; 459133965Sjdp 459260484Sobrien case lang_object_symbols_statement_enum: 459360484Sobrien link_info.create_object_symbols_section = 459460484Sobrien output_section_statement->bfd_section; 459560484Sobrien break; 4596218822Sdim 459760484Sobrien case lang_output_statement_enum: 459860484Sobrien case lang_target_statement_enum: 459960484Sobrien break; 4600218822Sdim 460160484Sobrien case lang_input_section_enum: 460233965Sjdp { 460360484Sobrien asection *i; 460433965Sjdp 460560484Sobrien i = (*prev)->input_section.section; 4606218822Sdim if (relax) 460760484Sobrien { 4608130561Sobrien bfd_boolean again; 460960484Sobrien 461060484Sobrien if (! bfd_relax_section (i->owner, i, &link_info, &again)) 461160484Sobrien einfo (_("%P%F: can't relax section: %E\n")); 461260484Sobrien if (again) 4613130561Sobrien *relax = TRUE; 461460484Sobrien } 461589857Sobrien dot = size_input_section (prev, output_section_statement, 461689857Sobrien output_section_statement->fill, dot); 461733965Sjdp } 461860484Sobrien break; 4619218822Sdim 462060484Sobrien case lang_input_statement_enum: 462160484Sobrien break; 4622218822Sdim 462360484Sobrien case lang_fill_statement_enum: 462477298Sobrien s->fill_statement.output_section = 462577298Sobrien output_section_statement->bfd_section; 462633965Sjdp 462760484Sobrien fill = s->fill_statement.fill; 462860484Sobrien break; 4629218822Sdim 463060484Sobrien case lang_assignment_statement_enum: 463160484Sobrien { 463260484Sobrien bfd_vma newdot = dot; 4633218822Sdim etree_type *tree = s->assignment_statement.exp; 463433965Sjdp 4635218822Sdim exp_fold_tree (tree, 4636218822Sdim output_section_statement->bfd_section, 463760484Sobrien &newdot); 463833965Sjdp 4639218822Sdim /* This symbol is relative to this section. */ 4640218822Sdim if ((tree->type.node_class == etree_provided 4641218822Sdim || tree->type.node_class == etree_assign) 4642218822Sdim && (tree->assign.dst [0] != '.' 4643218822Sdim || tree->assign.dst [1] != '\0')) 4644218822Sdim output_section_statement->section_relative_symbol = 1; 4645218822Sdim 4646218822Sdim if (!output_section_statement->ignored) 464760484Sobrien { 464860484Sobrien if (output_section_statement == abs_output_section) 464960484Sobrien { 465060484Sobrien /* If we don't have an output section, then just adjust 465160484Sobrien the default memory address. */ 4652218822Sdim lang_memory_region_lookup (DEFAULT_MEMORY_REGION, 4653218822Sdim FALSE)->current = newdot; 465460484Sobrien } 4655218822Sdim else if (newdot != dot) 465660484Sobrien { 465789857Sobrien /* Insert a pad after this statement. We can't 465889857Sobrien put the pad before when relaxing, in case the 465989857Sobrien assignment references dot. */ 4660130561Sobrien insert_pad (&s->header.next, fill, TO_SIZE (newdot - dot), 466189857Sobrien output_section_statement->bfd_section, dot); 466233965Sjdp 466389857Sobrien /* Don't neuter the pad below when relaxing. */ 466489857Sobrien s = s->header.next; 4665218822Sdim 4666218822Sdim /* If dot is advanced, this implies that the section 4667218822Sdim should have space allocated to it, unless the 4668218822Sdim user has explicitly stated that the section 4669218822Sdim should never be loaded. */ 4670218822Sdim if (!(output_section_statement->flags 4671218822Sdim & (SEC_NEVER_LOAD | SEC_ALLOC))) 4672218822Sdim output_section_statement->bfd_section->flags |= SEC_ALLOC; 467360484Sobrien } 467460484Sobrien dot = newdot; 467560484Sobrien } 467660484Sobrien } 467760484Sobrien break; 467833965Sjdp 467960484Sobrien case lang_padding_statement_enum: 468089857Sobrien /* If this is the first time lang_size_sections is called, 468189857Sobrien we won't have any padding statements. If this is the 468289857Sobrien second or later passes when relaxing, we should allow 468389857Sobrien padding to shrink. If padding is needed on this pass, it 468489857Sobrien will be added back in. */ 468589857Sobrien s->padding_statement.size = 0; 468689857Sobrien 468789857Sobrien /* Make sure output_offset is valid. If relaxation shrinks 468889857Sobrien the section and this pad isn't needed, it's possible to 468989857Sobrien have output_offset larger than the final size of the 469089857Sobrien section. bfd_set_section_contents will complain even for 469189857Sobrien a pad size of zero. */ 469289857Sobrien s->padding_statement.output_offset 469389857Sobrien = dot - output_section_statement->bfd_section->vma; 469460484Sobrien break; 469533965Sjdp 469660484Sobrien case lang_group_statement_enum: 4697104834Sobrien dot = lang_size_sections_1 (s->group_statement.children.head, 4698104834Sobrien output_section_statement, 4699104834Sobrien &s->group_statement.children.head, 4700130561Sobrien fill, dot, relax, check_regions); 470160484Sobrien break; 470233965Sjdp 470360484Sobrien default: 470460484Sobrien FAIL (); 470560484Sobrien break; 470633965Sjdp 470789857Sobrien /* We can only get here when relaxing is turned on. */ 470860484Sobrien case lang_address_statement_enum: 470960484Sobrien break; 471060484Sobrien } 471160484Sobrien prev = &s->header.next; 471233965Sjdp } 471333965Sjdp return dot; 471433965Sjdp} 471533965Sjdp 4716218822Sdim/* Callback routine that is used in _bfd_elf_map_sections_to_segments. 4717218822Sdim The BFD library has set NEW_SEGMENT to TRUE iff it thinks that 4718218822Sdim CURRENT_SECTION and PREVIOUS_SECTION ought to be placed into different 4719218822Sdim segments. We are allowed an opportunity to override this decision. */ 4720218822Sdim 4721218822Sdimbfd_boolean 4722218822Sdimldlang_override_segment_assignment (struct bfd_link_info * info ATTRIBUTE_UNUSED, 4723218822Sdim bfd * abfd ATTRIBUTE_UNUSED, 4724218822Sdim asection * current_section, 4725218822Sdim asection * previous_section, 4726218822Sdim bfd_boolean new_segment) 4727104834Sobrien{ 4728218822Sdim lang_output_section_statement_type * cur; 4729218822Sdim lang_output_section_statement_type * prev; 4730104834Sobrien 4731218822Sdim /* The checks below are only necessary when the BFD library has decided 4732218822Sdim that the two sections ought to be placed into the same segment. */ 4733218822Sdim if (new_segment) 4734218822Sdim return TRUE; 4735218822Sdim 4736218822Sdim /* Paranoia checks. */ 4737218822Sdim if (current_section == NULL || previous_section == NULL) 4738218822Sdim return new_segment; 4739218822Sdim 4740218822Sdim /* Find the memory regions associated with the two sections. 4741218822Sdim We call lang_output_section_find() here rather than scanning the list 4742218822Sdim of output sections looking for a matching section pointer because if 4743218822Sdim we have a large number of sections then a hash lookup is faster. */ 4744218822Sdim cur = lang_output_section_find (current_section->name); 4745218822Sdim prev = lang_output_section_find (previous_section->name); 4746218822Sdim 4747218822Sdim /* More paranoia. */ 4748218822Sdim if (cur == NULL || prev == NULL) 4749218822Sdim return new_segment; 4750218822Sdim 4751218822Sdim /* If the regions are different then force the sections to live in 4752218822Sdim different segments. See the email thread starting at the following 4753218822Sdim URL for the reasons why this is necessary: 4754218822Sdim http://sourceware.org/ml/binutils/2007-02/msg00216.html */ 4755218822Sdim return cur->region != prev->region; 4756218822Sdim} 4757218822Sdim 4758218822Sdimvoid 4759218822Sdimone_lang_size_sections_pass (bfd_boolean *relax, bfd_boolean check_regions) 4760218822Sdim{ 4761130561Sobrien lang_statement_iteration++; 4762218822Sdim lang_size_sections_1 (statement_list.head, abs_output_section, 4763218822Sdim &statement_list.head, 0, 0, relax, check_regions); 4764218822Sdim} 4765130561Sobrien 4766218822Sdimvoid 4767218822Sdimlang_size_sections (bfd_boolean *relax, bfd_boolean check_regions) 4768218822Sdim{ 4769218822Sdim expld.phase = lang_allocating_phase_enum; 4770218822Sdim expld.dataseg.phase = exp_dataseg_none; 4771218822Sdim 4772218822Sdim one_lang_size_sections_pass (relax, check_regions); 4773218822Sdim if (expld.dataseg.phase == exp_dataseg_end_seen 4774218822Sdim && link_info.relro && expld.dataseg.relro_end) 4775104834Sobrien { 4776218822Sdim /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END pair was seen, try 4777218822Sdim to put expld.dataseg.relro on a (common) page boundary. */ 4778218822Sdim bfd_vma old_min_base, relro_end, maxpage; 4779218822Sdim 4780218822Sdim expld.dataseg.phase = exp_dataseg_relro_adjust; 4781218822Sdim old_min_base = expld.dataseg.min_base; 4782218822Sdim maxpage = expld.dataseg.maxpagesize; 4783218822Sdim expld.dataseg.base += (-expld.dataseg.relro_end 4784218822Sdim & (expld.dataseg.pagesize - 1)); 4785218822Sdim /* Compute the expected PT_GNU_RELRO segment end. */ 4786218822Sdim relro_end = (expld.dataseg.relro_end + expld.dataseg.pagesize - 1) 4787218822Sdim & ~(expld.dataseg.pagesize - 1); 4788218822Sdim if (old_min_base + maxpage < expld.dataseg.base) 4789218822Sdim { 4790218822Sdim expld.dataseg.base -= maxpage; 4791218822Sdim relro_end -= maxpage; 4792218822Sdim } 4793218822Sdim lang_reset_memory_regions (); 4794218822Sdim one_lang_size_sections_pass (relax, check_regions); 4795218822Sdim if (expld.dataseg.relro_end > relro_end) 4796218822Sdim { 4797218822Sdim /* The alignment of sections between DATA_SEGMENT_ALIGN 4798218822Sdim and DATA_SEGMENT_RELRO_END caused huge padding to be 4799218822Sdim inserted at DATA_SEGMENT_RELRO_END. Try some other base. */ 4800218822Sdim asection *sec; 4801218822Sdim unsigned int max_alignment_power = 0; 4802218822Sdim 4803218822Sdim /* Find maximum alignment power of sections between 4804218822Sdim DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END. */ 4805218822Sdim for (sec = output_bfd->sections; sec; sec = sec->next) 4806218822Sdim if (sec->vma >= expld.dataseg.base 4807218822Sdim && sec->vma < expld.dataseg.relro_end 4808218822Sdim && sec->alignment_power > max_alignment_power) 4809218822Sdim max_alignment_power = sec->alignment_power; 4810218822Sdim 4811218822Sdim if (((bfd_vma) 1 << max_alignment_power) < expld.dataseg.pagesize) 4812218822Sdim { 4813218822Sdim if (expld.dataseg.base - (1 << max_alignment_power) 4814218822Sdim < old_min_base) 4815218822Sdim expld.dataseg.base += expld.dataseg.pagesize; 4816218822Sdim expld.dataseg.base -= (1 << max_alignment_power); 4817218822Sdim lang_reset_memory_regions (); 4818218822Sdim one_lang_size_sections_pass (relax, check_regions); 4819218822Sdim } 4820218822Sdim } 4821218822Sdim link_info.relro_start = expld.dataseg.base; 4822218822Sdim link_info.relro_end = expld.dataseg.relro_end; 4823218822Sdim } 4824218822Sdim else if (expld.dataseg.phase == exp_dataseg_end_seen) 4825218822Sdim { 4826104834Sobrien /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_END pair was seen, check whether 4827104834Sobrien a page could be saved in the data segment. */ 4828104834Sobrien bfd_vma first, last; 4829104834Sobrien 4830218822Sdim first = -expld.dataseg.base & (expld.dataseg.pagesize - 1); 4831218822Sdim last = expld.dataseg.end & (expld.dataseg.pagesize - 1); 4832104834Sobrien if (first && last 4833218822Sdim && ((expld.dataseg.base & ~(expld.dataseg.pagesize - 1)) 4834218822Sdim != (expld.dataseg.end & ~(expld.dataseg.pagesize - 1))) 4835218822Sdim && first + last <= expld.dataseg.pagesize) 4836104834Sobrien { 4837218822Sdim expld.dataseg.phase = exp_dataseg_adjust; 4838218822Sdim lang_reset_memory_regions (); 4839218822Sdim one_lang_size_sections_pass (relax, check_regions); 4840104834Sobrien } 4841104834Sobrien } 4842104834Sobrien 4843218822Sdim expld.phase = lang_final_phase_enum; 4844104834Sobrien} 4845104834Sobrien 4846130561Sobrien/* Worker function for lang_do_assignments. Recursiveness goes here. */ 4847130561Sobrien 4848130561Sobrienstatic bfd_vma 4849218822Sdimlang_do_assignments_1 (lang_statement_union_type *s, 4850218822Sdim lang_output_section_statement_type *current_os, 4851218822Sdim fill_type *fill, 4852218822Sdim bfd_vma dot) 485333965Sjdp{ 4854130561Sobrien for (; s != NULL; s = s->header.next) 485533965Sjdp { 485633965Sjdp switch (s->header.type) 485733965Sjdp { 485833965Sjdp case lang_constructors_statement_enum: 4859130561Sobrien dot = lang_do_assignments_1 (constructor_list.head, 4860218822Sdim current_os, fill, dot); 486133965Sjdp break; 486233965Sjdp 486333965Sjdp case lang_output_section_statement_enum: 486433965Sjdp { 486578828Sobrien lang_output_section_statement_type *os; 486633965Sjdp 486778828Sobrien os = &(s->output_section_statement); 4868218822Sdim if (os->bfd_section != NULL && !os->ignored) 486933965Sjdp { 487033965Sjdp dot = os->bfd_section->vma; 4871218822Sdim 4872130561Sobrien lang_do_assignments_1 (os->children.head, os, os->fill, dot); 487360484Sobrien 4874218822Sdim /* .tbss sections effectively have zero size. */ 4875218822Sdim if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0 4876218822Sdim || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0 4877218822Sdim || link_info.relocatable) 4878218822Sdim dot += TO_ADDR (os->bfd_section->size); 487933965Sjdp } 488033965Sjdp } 488133965Sjdp break; 4882218822Sdim 488333965Sjdp case lang_wild_statement_enum: 488433965Sjdp 4885130561Sobrien dot = lang_do_assignments_1 (s->wild_statement.children.head, 4886218822Sdim current_os, fill, dot); 488733965Sjdp break; 488833965Sjdp 488933965Sjdp case lang_object_symbols_statement_enum: 489033965Sjdp case lang_output_statement_enum: 489133965Sjdp case lang_target_statement_enum: 489233965Sjdp break; 4893218822Sdim 489433965Sjdp case lang_data_statement_enum: 4895218822Sdim exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot); 4896218822Sdim if (expld.result.valid_p) 4897218822Sdim s->data_statement.value = (expld.result.value 4898218822Sdim + expld.result.section->vma); 4899218822Sdim else 4900218822Sdim einfo (_("%F%P: invalid data statement\n")); 490133965Sjdp { 4902104834Sobrien unsigned int size; 490377298Sobrien switch (s->data_statement.type) 490477298Sobrien { 490577298Sobrien default: 490677298Sobrien abort (); 490777298Sobrien case QUAD: 490877298Sobrien case SQUAD: 490977298Sobrien size = QUAD_SIZE; 491077298Sobrien break; 491177298Sobrien case LONG: 491277298Sobrien size = LONG_SIZE; 491377298Sobrien break; 491477298Sobrien case SHORT: 491577298Sobrien size = SHORT_SIZE; 491677298Sobrien break; 491777298Sobrien case BYTE: 491877298Sobrien size = BYTE_SIZE; 491977298Sobrien break; 492077298Sobrien } 4921130561Sobrien if (size < TO_SIZE ((unsigned) 1)) 4922130561Sobrien size = TO_SIZE ((unsigned) 1); 4923130561Sobrien dot += TO_ADDR (size); 492477298Sobrien } 492533965Sjdp break; 492633965Sjdp 492733965Sjdp case lang_reloc_statement_enum: 4928218822Sdim exp_fold_tree (s->reloc_statement.addend_exp, 4929218822Sdim bfd_abs_section_ptr, &dot); 4930218822Sdim if (expld.result.valid_p) 4931218822Sdim s->reloc_statement.addend_value = expld.result.value; 4932218822Sdim else 4933218822Sdim einfo (_("%F%P: invalid reloc statement\n")); 4934130561Sobrien dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto)); 493533965Sjdp break; 493633965Sjdp 493733965Sjdp case lang_input_section_enum: 493833965Sjdp { 493933965Sjdp asection *in = s->input_section.section; 494033965Sjdp 4941218822Sdim if ((in->flags & SEC_EXCLUDE) == 0) 4942218822Sdim dot += TO_ADDR (in->size); 494333965Sjdp } 494433965Sjdp break; 494533965Sjdp 494633965Sjdp case lang_input_statement_enum: 494733965Sjdp break; 4948218822Sdim 494933965Sjdp case lang_fill_statement_enum: 495033965Sjdp fill = s->fill_statement.fill; 495133965Sjdp break; 4952218822Sdim 495333965Sjdp case lang_assignment_statement_enum: 4954218822Sdim exp_fold_tree (s->assignment_statement.exp, 4955218822Sdim current_os->bfd_section, 4956218822Sdim &dot); 4957218822Sdim break; 495833965Sjdp 495933965Sjdp case lang_padding_statement_enum: 4960130561Sobrien dot += TO_ADDR (s->padding_statement.size); 496133965Sjdp break; 496233965Sjdp 496333965Sjdp case lang_group_statement_enum: 4964130561Sobrien dot = lang_do_assignments_1 (s->group_statement.children.head, 4965218822Sdim current_os, fill, dot); 496633965Sjdp break; 496733965Sjdp 496833965Sjdp default: 496933965Sjdp FAIL (); 497033965Sjdp break; 4971218822Sdim 497233965Sjdp case lang_address_statement_enum: 497333965Sjdp break; 497433965Sjdp } 497533965Sjdp } 497633965Sjdp return dot; 497733965Sjdp} 497833965Sjdp 4979130561Sobrienvoid 4980218822Sdimlang_do_assignments (void) 4981130561Sobrien{ 4982130561Sobrien lang_statement_iteration++; 4983218822Sdim lang_do_assignments_1 (statement_list.head, abs_output_section, NULL, 0); 4984130561Sobrien} 4985130561Sobrien 498633965Sjdp/* Fix any .startof. or .sizeof. symbols. When the assemblers see the 498733965Sjdp operator .startof. (section_name), it produces an undefined symbol 498833965Sjdp .startof.section_name. Similarly, when it sees 498933965Sjdp .sizeof. (section_name), it produces an undefined symbol 499033965Sjdp .sizeof.section_name. For all the output sections, we look for 499133965Sjdp such symbols, and set them to the correct value. */ 499233965Sjdp 499333965Sjdpstatic void 4994130561Sobrienlang_set_startof (void) 499533965Sjdp{ 499633965Sjdp asection *s; 499733965Sjdp 4998130561Sobrien if (link_info.relocatable) 499933965Sjdp return; 500033965Sjdp 500133965Sjdp for (s = output_bfd->sections; s != NULL; s = s->next) 500233965Sjdp { 500333965Sjdp const char *secname; 500433965Sjdp char *buf; 500533965Sjdp struct bfd_link_hash_entry *h; 500633965Sjdp 500733965Sjdp secname = bfd_get_section_name (output_bfd, s); 500833965Sjdp buf = xmalloc (10 + strlen (secname)); 500933965Sjdp 501033965Sjdp sprintf (buf, ".startof.%s", secname); 5011130561Sobrien h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE); 501233965Sjdp if (h != NULL && h->type == bfd_link_hash_undefined) 501333965Sjdp { 501433965Sjdp h->type = bfd_link_hash_defined; 501533965Sjdp h->u.def.value = bfd_get_section_vma (output_bfd, s); 501633965Sjdp h->u.def.section = bfd_abs_section_ptr; 501733965Sjdp } 501833965Sjdp 501933965Sjdp sprintf (buf, ".sizeof.%s", secname); 5020130561Sobrien h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE); 502133965Sjdp if (h != NULL && h->type == bfd_link_hash_undefined) 502233965Sjdp { 502333965Sjdp h->type = bfd_link_hash_defined; 5024218822Sdim h->u.def.value = TO_ADDR (s->size); 502533965Sjdp h->u.def.section = bfd_abs_section_ptr; 502633965Sjdp } 502733965Sjdp 502833965Sjdp free (buf); 502933965Sjdp } 503033965Sjdp} 503133965Sjdp 503233965Sjdpstatic void 5033218822Sdimlang_end (void) 503433965Sjdp{ 503533965Sjdp struct bfd_link_hash_entry *h; 5036130561Sobrien bfd_boolean warn; 503733965Sjdp 5038130561Sobrien if (link_info.relocatable || link_info.shared) 5039130561Sobrien warn = FALSE; 504033965Sjdp else 5041130561Sobrien warn = TRUE; 504233965Sjdp 5043130561Sobrien if (entry_symbol.name == NULL) 504433965Sjdp { 5045218822Sdim /* No entry has been specified. Look for the default entry, but 5046218822Sdim don't warn if we don't find it. */ 5047218822Sdim entry_symbol.name = entry_symbol_default; 5048130561Sobrien warn = FALSE; 504933965Sjdp } 505033965Sjdp 5051104834Sobrien h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name, 5052130561Sobrien FALSE, FALSE, TRUE); 5053130561Sobrien if (h != NULL 505433965Sjdp && (h->type == bfd_link_hash_defined 505533965Sjdp || h->type == bfd_link_hash_defweak) 505633965Sjdp && h->u.def.section->output_section != NULL) 505733965Sjdp { 505833965Sjdp bfd_vma val; 505933965Sjdp 506033965Sjdp val = (h->u.def.value 506133965Sjdp + bfd_get_section_vma (output_bfd, 506233965Sjdp h->u.def.section->output_section) 506333965Sjdp + h->u.def.section->output_offset); 506433965Sjdp if (! bfd_set_start_address (output_bfd, val)) 5065104834Sobrien einfo (_("%P%F:%s: can't set start address\n"), entry_symbol.name); 506633965Sjdp } 506733965Sjdp else 506833965Sjdp { 506960484Sobrien bfd_vma val; 507077298Sobrien const char *send; 507133965Sjdp 507260484Sobrien /* We couldn't find the entry symbol. Try parsing it as a 5073218822Sdim number. */ 5074104834Sobrien val = bfd_scan_vma (entry_symbol.name, &send, 0); 507560484Sobrien if (*send == '\0') 507633965Sjdp { 507760484Sobrien if (! bfd_set_start_address (output_bfd, val)) 507860484Sobrien einfo (_("%P%F: can't set start address\n")); 507933965Sjdp } 508033965Sjdp else 508133965Sjdp { 508260484Sobrien asection *ts; 508360484Sobrien 508460484Sobrien /* Can't find the entry symbol, and it's not a number. Use 508560484Sobrien the first address in the text section. */ 508691041Sobrien ts = bfd_get_section_by_name (output_bfd, entry_section); 5087130561Sobrien if (ts != NULL) 508860484Sobrien { 508960484Sobrien if (warn) 5090218822Sdim einfo (_("%P: warning: cannot find entry symbol %s;" 5091218822Sdim " defaulting to %V\n"), 5092104834Sobrien entry_symbol.name, 5093104834Sobrien bfd_get_section_vma (output_bfd, ts)); 509460484Sobrien if (! bfd_set_start_address (output_bfd, 509560484Sobrien bfd_get_section_vma (output_bfd, 509660484Sobrien ts))) 509760484Sobrien einfo (_("%P%F: can't set start address\n")); 509860484Sobrien } 509960484Sobrien else 510060484Sobrien { 510160484Sobrien if (warn) 5102218822Sdim einfo (_("%P: warning: cannot find entry symbol %s;" 5103218822Sdim " not setting start address\n"), 5104104834Sobrien entry_symbol.name); 510560484Sobrien } 510633965Sjdp } 510733965Sjdp } 5108130561Sobrien 5109218822Sdim /* Don't bfd_hash_table_free (&lang_definedness_table); 5110218822Sdim map file output may result in a call of lang_track_definedness. */ 511133965Sjdp} 511233965Sjdp 511338889Sjdp/* This is a small function used when we want to ignore errors from 511438889Sjdp BFD. */ 511538889Sjdp 511638889Sjdpstatic void 511760484Sobrienignore_bfd_errors (const char *s ATTRIBUTE_UNUSED, ...) 511838889Sjdp{ 511938889Sjdp /* Don't do anything. */ 512038889Sjdp} 512138889Sjdp 512233965Sjdp/* Check that the architecture of all the input files is compatible 512333965Sjdp with the output file. Also call the backend to let it do any 512433965Sjdp other checking that is needed. */ 512533965Sjdp 512633965Sjdpstatic void 5127130561Sobrienlang_check (void) 512833965Sjdp{ 512933965Sjdp lang_statement_union_type *file; 513033965Sjdp bfd *input_bfd; 513177298Sobrien const bfd_arch_info_type *compatible; 513233965Sjdp 5133130561Sobrien for (file = file_chain.head; file != NULL; file = file->input_statement.next) 513433965Sjdp { 513533965Sjdp input_bfd = file->input_statement.the_bfd; 5136218822Sdim compatible 5137218822Sdim = bfd_arch_get_compatible (input_bfd, output_bfd, 5138218822Sdim command_line.accept_unknown_input_arch); 513994536Sobrien 514094536Sobrien /* In general it is not possible to perform a relocatable 514194536Sobrien link between differing object formats when the input 514294536Sobrien file has relocations, because the relocations in the 514394536Sobrien input format may not have equivalent representations in 514494536Sobrien the output format (and besides BFD does not translate 514594536Sobrien relocs for other link purposes than a final link). */ 5146130561Sobrien if ((link_info.relocatable || link_info.emitrelocations) 514794536Sobrien && (compatible == NULL 514894536Sobrien || bfd_get_flavour (input_bfd) != bfd_get_flavour (output_bfd)) 514994536Sobrien && (bfd_get_file_flags (input_bfd) & HAS_RELOC) != 0) 515094536Sobrien { 5151218822Sdim einfo (_("%P%F: Relocatable linking with relocations from" 5152218822Sdim " format %s (%B) to format %s (%B) is not supported\n"), 515394536Sobrien bfd_get_target (input_bfd), input_bfd, 515494536Sobrien bfd_get_target (output_bfd), output_bfd); 515594536Sobrien /* einfo with %F exits. */ 515694536Sobrien } 515794536Sobrien 515833965Sjdp if (compatible == NULL) 515938889Sjdp { 516038889Sjdp if (command_line.warn_mismatch) 5161218822Sdim einfo (_("%P%X: %s architecture of input file `%B'" 5162218822Sdim " is incompatible with %s output\n"), 516338889Sjdp bfd_printable_name (input_bfd), input_bfd, 516438889Sjdp bfd_printable_name (output_bfd)); 516538889Sjdp } 516677298Sobrien else if (bfd_count_sections (input_bfd)) 516738889Sjdp { 516877298Sobrien /* If the input bfd has no contents, it shouldn't set the 5169104834Sobrien private data of the output bfd. */ 517077298Sobrien 517138889Sjdp bfd_error_handler_type pfn = NULL; 517233965Sjdp 517338889Sjdp /* If we aren't supposed to warn about mismatched input 5174218822Sdim files, temporarily set the BFD error handler to a 5175218822Sdim function which will do nothing. We still want to call 5176218822Sdim bfd_merge_private_bfd_data, since it may set up 5177218822Sdim information which is needed in the output file. */ 517838889Sjdp if (! command_line.warn_mismatch) 517938889Sjdp pfn = bfd_set_error_handler (ignore_bfd_errors); 518038889Sjdp if (! bfd_merge_private_bfd_data (input_bfd, output_bfd)) 518138889Sjdp { 518238889Sjdp if (command_line.warn_mismatch) 5183218822Sdim einfo (_("%P%X: failed to merge target specific data" 5184218822Sdim " of file %B\n"), input_bfd); 518538889Sjdp } 518638889Sjdp if (! command_line.warn_mismatch) 518738889Sjdp bfd_set_error_handler (pfn); 518838889Sjdp } 518933965Sjdp } 519033965Sjdp} 519133965Sjdp 519233965Sjdp/* Look through all the global common symbols and attach them to the 519333965Sjdp correct section. The -sort-common command line switch may be used 519433965Sjdp to roughly sort the entries by size. */ 519533965Sjdp 519633965Sjdpstatic void 5197130561Sobrienlang_common (void) 519833965Sjdp{ 519989857Sobrien if (command_line.inhibit_common_definition) 520089857Sobrien return; 5201130561Sobrien if (link_info.relocatable 520233965Sjdp && ! command_line.force_common_definition) 520333965Sjdp return; 520433965Sjdp 520533965Sjdp if (! config.sort_common) 5206130561Sobrien bfd_link_hash_traverse (link_info.hash, lang_one_common, NULL); 520733965Sjdp else 520833965Sjdp { 520933965Sjdp int power; 521033965Sjdp 521133965Sjdp for (power = 4; power >= 0; power--) 5212130561Sobrien bfd_link_hash_traverse (link_info.hash, lang_one_common, &power); 521333965Sjdp } 521433965Sjdp} 521533965Sjdp 521633965Sjdp/* Place one common symbol in the correct section. */ 521733965Sjdp 5218130561Sobrienstatic bfd_boolean 5219130561Sobrienlang_one_common (struct bfd_link_hash_entry *h, void *info) 522033965Sjdp{ 522133965Sjdp unsigned int power_of_two; 522233965Sjdp bfd_vma size; 522333965Sjdp asection *section; 522433965Sjdp 522533965Sjdp if (h->type != bfd_link_hash_common) 5226130561Sobrien return TRUE; 522733965Sjdp 522833965Sjdp size = h->u.c.size; 522933965Sjdp power_of_two = h->u.c.p->alignment_power; 523033965Sjdp 523133965Sjdp if (config.sort_common 523233965Sjdp && power_of_two < (unsigned int) *(int *) info) 5233130561Sobrien return TRUE; 523433965Sjdp 523533965Sjdp section = h->u.c.p->section; 523633965Sjdp 5237130561Sobrien /* Increase the size of the section to align the common sym. */ 5238218822Sdim section->size += ((bfd_vma) 1 << (power_of_two + opb_shift)) - 1; 5239218822Sdim section->size &= (- (bfd_vma) 1 << (power_of_two + opb_shift)); 524033965Sjdp 524133965Sjdp /* Adjust the alignment if necessary. */ 524233965Sjdp if (power_of_two > section->alignment_power) 524333965Sjdp section->alignment_power = power_of_two; 524433965Sjdp 524533965Sjdp /* Change the symbol from common to defined. */ 524633965Sjdp h->type = bfd_link_hash_defined; 524733965Sjdp h->u.def.section = section; 5248218822Sdim h->u.def.value = section->size; 524933965Sjdp 525033965Sjdp /* Increase the size of the section. */ 5251218822Sdim section->size += size; 525233965Sjdp 525333965Sjdp /* Make sure the section is allocated in memory, and make sure that 525433965Sjdp it is no longer a common section. */ 525533965Sjdp section->flags |= SEC_ALLOC; 525677298Sobrien section->flags &= ~SEC_IS_COMMON; 525733965Sjdp 525833965Sjdp if (config.map_file != NULL) 525933965Sjdp { 5260130561Sobrien static bfd_boolean header_printed; 526133965Sjdp int len; 526233965Sjdp char *name; 526333965Sjdp char buf[50]; 526433965Sjdp 526533965Sjdp if (! header_printed) 526633965Sjdp { 526760484Sobrien minfo (_("\nAllocating common symbols\n")); 526860484Sobrien minfo (_("Common symbol size file\n\n")); 5269130561Sobrien header_printed = TRUE; 527033965Sjdp } 527133965Sjdp 5272218822Sdim name = bfd_demangle (output_bfd, h->root.string, 5273218822Sdim DMGL_ANSI | DMGL_PARAMS); 5274218822Sdim if (name == NULL) 5275218822Sdim { 5276218822Sdim minfo ("%s", h->root.string); 5277218822Sdim len = strlen (h->root.string); 5278218822Sdim } 5279218822Sdim else 5280218822Sdim { 5281218822Sdim minfo ("%s", name); 5282218822Sdim len = strlen (name); 5283218822Sdim free (name); 5284218822Sdim } 528533965Sjdp 528633965Sjdp if (len >= 19) 528733965Sjdp { 528833965Sjdp print_nl (); 528933965Sjdp len = 0; 529033965Sjdp } 529133965Sjdp while (len < 20) 529233965Sjdp { 529333965Sjdp print_space (); 529433965Sjdp ++len; 529533965Sjdp } 529633965Sjdp 529733965Sjdp minfo ("0x"); 529833965Sjdp if (size <= 0xffffffff) 529933965Sjdp sprintf (buf, "%lx", (unsigned long) size); 530033965Sjdp else 530133965Sjdp sprintf_vma (buf, size); 530233965Sjdp minfo ("%s", buf); 530333965Sjdp len = strlen (buf); 530433965Sjdp 530533965Sjdp while (len < 16) 530633965Sjdp { 530733965Sjdp print_space (); 530833965Sjdp ++len; 530933965Sjdp } 531033965Sjdp 531133965Sjdp minfo ("%B\n", section->owner); 531233965Sjdp } 531333965Sjdp 5314130561Sobrien return TRUE; 531533965Sjdp} 531633965Sjdp 531777298Sobrien/* Run through the input files and ensure that every input section has 531877298Sobrien somewhere to go. If one is found without a destination then create 531977298Sobrien an input request and place it into the statement tree. */ 532033965Sjdp 532133965Sjdpstatic void 5322130561Sobrienlang_place_orphans (void) 532333965Sjdp{ 532460484Sobrien LANG_FOR_EACH_INPUT_STATEMENT (file) 532533965Sjdp { 532633965Sjdp asection *s; 532733965Sjdp 5328130561Sobrien for (s = file->the_bfd->sections; s != NULL; s = s->next) 532933965Sjdp { 5330130561Sobrien if (s->output_section == NULL) 533133965Sjdp { 5332130561Sobrien /* This section of the file is not attached, root 5333218822Sdim around for a sensible place for it to go. */ 533433965Sjdp 533533965Sjdp if (file->just_syms_flag) 5336218822Sdim bfd_link_just_syms (file->the_bfd, s, &link_info); 5337218822Sdim else if ((s->flags & SEC_EXCLUDE) != 0) 5338218822Sdim s->output_section = bfd_abs_section_ptr; 533933965Sjdp else if (strcmp (s->name, "COMMON") == 0) 534033965Sjdp { 534133965Sjdp /* This is a lonely common section which must have 534233965Sjdp come from an archive. We attach to the section 534333965Sjdp with the wildcard. */ 5344130561Sobrien if (! link_info.relocatable 534533965Sjdp || command_line.force_common_definition) 534633965Sjdp { 534733965Sjdp if (default_common_section == NULL) 534833965Sjdp { 534933965Sjdp default_common_section = 535033965Sjdp lang_output_section_statement_lookup (".bss"); 535133965Sjdp 535233965Sjdp } 535389857Sobrien lang_add_section (&default_common_section->children, s, 5354218822Sdim default_common_section); 535533965Sjdp } 535633965Sjdp } 5357218822Sdim else if (ldemul_place_orphan (s)) 535833965Sjdp ; 535933965Sjdp else 536033965Sjdp { 536189857Sobrien lang_output_section_statement_type *os; 536233965Sjdp 536389857Sobrien os = lang_output_section_statement_lookup (s->name); 5364218822Sdim lang_add_section (&os->children, s, os); 536533965Sjdp } 536633965Sjdp } 536733965Sjdp } 536833965Sjdp } 536933965Sjdp} 537033965Sjdp 537133965Sjdpvoid 5372130561Sobrienlang_set_flags (lang_memory_region_type *ptr, const char *flags, int invert) 537333965Sjdp{ 537460484Sobrien flagword *ptr_flags; 537533965Sjdp 537660484Sobrien ptr_flags = invert ? &ptr->not_flags : &ptr->flags; 537733965Sjdp while (*flags) 537833965Sjdp { 537933965Sjdp switch (*flags) 538033965Sjdp { 538138889Sjdp case 'A': case 'a': 538238889Sjdp *ptr_flags |= SEC_ALLOC; 538333965Sjdp break; 538438889Sjdp 538538889Sjdp case 'R': case 'r': 538638889Sjdp *ptr_flags |= SEC_READONLY; 538733965Sjdp break; 538838889Sjdp 538938889Sjdp case 'W': case 'w': 539038889Sjdp *ptr_flags |= SEC_DATA; 539133965Sjdp break; 539238889Sjdp 539338889Sjdp case 'X': case 'x': 539438889Sjdp *ptr_flags |= SEC_CODE; 539538889Sjdp break; 539638889Sjdp 539738889Sjdp case 'L': case 'l': 539838889Sjdp case 'I': case 'i': 539938889Sjdp *ptr_flags |= SEC_LOAD; 540038889Sjdp break; 540138889Sjdp 540233965Sjdp default: 540360484Sobrien einfo (_("%P%F: invalid syntax in flags\n")); 540433965Sjdp break; 540533965Sjdp } 540633965Sjdp flags++; 540733965Sjdp } 540833965Sjdp} 540933965Sjdp 541033965Sjdp/* Call a function on each input file. This function will be called 541133965Sjdp on an archive, but not on the elements. */ 541233965Sjdp 541333965Sjdpvoid 5414130561Sobrienlang_for_each_input_file (void (*func) (lang_input_statement_type *)) 541533965Sjdp{ 541633965Sjdp lang_input_statement_type *f; 541733965Sjdp 541833965Sjdp for (f = (lang_input_statement_type *) input_file_chain.head; 541933965Sjdp f != NULL; 542033965Sjdp f = (lang_input_statement_type *) f->next_real_file) 542133965Sjdp func (f); 542233965Sjdp} 542333965Sjdp 542433965Sjdp/* Call a function on each file. The function will be called on all 542533965Sjdp the elements of an archive which are included in the link, but will 542633965Sjdp not be called on the archive file itself. */ 542733965Sjdp 542833965Sjdpvoid 5429130561Sobrienlang_for_each_file (void (*func) (lang_input_statement_type *)) 543033965Sjdp{ 543160484Sobrien LANG_FOR_EACH_INPUT_STATEMENT (f) 543233965Sjdp { 543333965Sjdp func (f); 543433965Sjdp } 543533965Sjdp} 543633965Sjdp 543733965Sjdpvoid 5438130561Sobrienldlang_add_file (lang_input_statement_type *entry) 543933965Sjdp{ 544033965Sjdp lang_statement_append (&file_chain, 544133965Sjdp (lang_statement_union_type *) entry, 544233965Sjdp &entry->next); 544333965Sjdp 544433965Sjdp /* The BFD linker needs to have a list of all input BFDs involved in 544533965Sjdp a link. */ 5446130561Sobrien ASSERT (entry->the_bfd->link_next == NULL); 544733965Sjdp ASSERT (entry->the_bfd != output_bfd); 5448218822Sdim 5449218822Sdim *link_info.input_bfds_tail = entry->the_bfd; 5450218822Sdim link_info.input_bfds_tail = &entry->the_bfd->link_next; 5451130561Sobrien entry->the_bfd->usrdata = entry; 545233965Sjdp bfd_set_gp_size (entry->the_bfd, g_switch_value); 545333965Sjdp 545433965Sjdp /* Look through the sections and check for any which should not be 545533965Sjdp included in the link. We need to do this now, so that we can 545633965Sjdp notice when the backend linker tries to report multiple 545733965Sjdp definition errors for symbols which are in sections we aren't 545833965Sjdp going to link. FIXME: It might be better to entirely ignore 545933965Sjdp symbols which are defined in sections which are going to be 546033965Sjdp discarded. This would require modifying the backend linker for 546133965Sjdp each backend which might set the SEC_LINK_ONCE flag. If we do 546233965Sjdp this, we should probably handle SEC_EXCLUDE in the same way. */ 546333965Sjdp 5464130561Sobrien bfd_map_over_sections (entry->the_bfd, section_already_linked, entry); 546533965Sjdp} 546633965Sjdp 546733965Sjdpvoid 5468130561Sobrienlang_add_output (const char *name, int from_script) 546933965Sjdp{ 547033965Sjdp /* Make -o on command line override OUTPUT in script. */ 5471107492Sobrien if (!had_output_filename || !from_script) 547233965Sjdp { 547333965Sjdp output_filename = name; 5474130561Sobrien had_output_filename = TRUE; 547533965Sjdp } 547633965Sjdp} 547733965Sjdp 547833965Sjdpstatic lang_output_section_statement_type *current_section; 547933965Sjdp 548033965Sjdpstatic int 5481130561Sobrientopower (int x) 548233965Sjdp{ 548333965Sjdp unsigned int i = 1; 548433965Sjdp int l; 548533965Sjdp 548633965Sjdp if (x < 0) 548733965Sjdp return -1; 548833965Sjdp 548977298Sobrien for (l = 0; l < 32; l++) 549033965Sjdp { 549133965Sjdp if (i >= (unsigned int) x) 549233965Sjdp return l; 549333965Sjdp i <<= 1; 549433965Sjdp } 549533965Sjdp 549633965Sjdp return 0; 549733965Sjdp} 549833965Sjdp 549968765Sobrienlang_output_section_statement_type * 5500130561Sobrienlang_enter_output_section_statement (const char *output_section_statement_name, 5501130561Sobrien etree_type *address_exp, 5502130561Sobrien enum section_type sectype, 5503130561Sobrien etree_type *align, 5504130561Sobrien etree_type *subalign, 5505218822Sdim etree_type *ebase, 5506218822Sdim int constraint) 550733965Sjdp{ 550833965Sjdp lang_output_section_statement_type *os; 550933965Sjdp 5510218822Sdim os = lang_output_section_statement_lookup_1 (output_section_statement_name, 5511218822Sdim constraint); 5512218822Sdim current_section = os; 551333965Sjdp 551477298Sobrien /* Make next things chain into subchain of this. */ 551533965Sjdp 5516130561Sobrien if (os->addr_tree == NULL) 551777298Sobrien { 551877298Sobrien os->addr_tree = address_exp; 551977298Sobrien } 552033965Sjdp os->sectype = sectype; 552133965Sjdp if (sectype != noload_section) 552233965Sjdp os->flags = SEC_NO_FLAGS; 552333965Sjdp else 552433965Sjdp os->flags = SEC_NEVER_LOAD; 5525130561Sobrien os->block_value = 1; 552633965Sjdp stat_ptr = &os->children; 552733965Sjdp 552877298Sobrien os->subsection_alignment = 5529218822Sdim topower (exp_get_value_int (subalign, -1, "subsection alignment")); 553077298Sobrien os->section_alignment = 5531218822Sdim topower (exp_get_value_int (align, -1, "section alignment")); 553233965Sjdp 553333965Sjdp os->load_base = ebase; 553468765Sobrien return os; 553533965Sjdp} 553633965Sjdp 553733965Sjdpvoid 5538130561Sobrienlang_final (void) 553933965Sjdp{ 5540218822Sdim lang_output_statement_type *new; 554133965Sjdp 5542218822Sdim new = new_stat (lang_output_statement, stat_ptr); 554333965Sjdp new->name = output_filename; 554433965Sjdp} 554533965Sjdp 554677298Sobrien/* Reset the current counters in the regions. */ 554777298Sobrien 554891041Sobrienvoid 5549130561Sobrienlang_reset_memory_regions (void) 555033965Sjdp{ 555133965Sjdp lang_memory_region_type *p = lang_memory_region_list; 555289857Sobrien asection *o; 5553218822Sdim lang_output_section_statement_type *os; 555433965Sjdp 5555130561Sobrien for (p = lang_memory_region_list; p != NULL; p = p->next) 555633965Sjdp { 555733965Sjdp p->current = p->origin; 5558218822Sdim p->last_os = NULL; 555933965Sjdp } 556089857Sobrien 5561218822Sdim for (os = &lang_output_section_statement.head->output_section_statement; 5562218822Sdim os != NULL; 5563218822Sdim os = os->next) 5564218822Sdim { 5565218822Sdim os->processed_vma = FALSE; 5566218822Sdim os->processed_lma = FALSE; 5567218822Sdim } 5568218822Sdim 556989857Sobrien for (o = output_bfd->sections; o != NULL; o = o->next) 5570218822Sdim { 5571218822Sdim /* Save the last size for possible use by bfd_relax_section. */ 5572218822Sdim o->rawsize = o->size; 5573218822Sdim o->size = 0; 5574218822Sdim } 557533965Sjdp} 557633965Sjdp 5577218822Sdim/* Worker for lang_gc_sections_1. */ 557860484Sobrien 557960484Sobrienstatic void 5580130561Sobriengc_section_callback (lang_wild_statement_type *ptr, 5581130561Sobrien struct wildcard_list *sec ATTRIBUTE_UNUSED, 5582130561Sobrien asection *section, 5583130561Sobrien lang_input_statement_type *file ATTRIBUTE_UNUSED, 5584130561Sobrien void *data ATTRIBUTE_UNUSED) 558560484Sobrien{ 5586218822Sdim /* If the wild pattern was marked KEEP, the member sections 5587218822Sdim should be as well. */ 558860484Sobrien if (ptr->keep_sections) 558960484Sobrien section->flags |= SEC_KEEP; 559060484Sobrien} 559160484Sobrien 559260484Sobrien/* Iterate over sections marking them against GC. */ 559360484Sobrien 559460484Sobrienstatic void 5595130561Sobrienlang_gc_sections_1 (lang_statement_union_type *s) 559660484Sobrien{ 5597130561Sobrien for (; s != NULL; s = s->header.next) 559860484Sobrien { 559960484Sobrien switch (s->header.type) 560060484Sobrien { 560160484Sobrien case lang_wild_statement_enum: 5602218822Sdim walk_wild (&s->wild_statement, gc_section_callback, NULL); 560360484Sobrien break; 560460484Sobrien case lang_constructors_statement_enum: 560560484Sobrien lang_gc_sections_1 (constructor_list.head); 560660484Sobrien break; 560760484Sobrien case lang_output_section_statement_enum: 560860484Sobrien lang_gc_sections_1 (s->output_section_statement.children.head); 560960484Sobrien break; 561060484Sobrien case lang_group_statement_enum: 561160484Sobrien lang_gc_sections_1 (s->group_statement.children.head); 561260484Sobrien break; 561360484Sobrien default: 561460484Sobrien break; 561560484Sobrien } 561660484Sobrien } 561760484Sobrien} 561860484Sobrien 561960484Sobrienstatic void 5620130561Sobrienlang_gc_sections (void) 562160484Sobrien{ 562260484Sobrien struct bfd_link_hash_entry *h; 5623104834Sobrien ldlang_undef_chain_list_type *ulist; 562460484Sobrien 562560484Sobrien /* Keep all sections so marked in the link script. */ 562660484Sobrien 562760484Sobrien lang_gc_sections_1 (statement_list.head); 562860484Sobrien 5629104834Sobrien /* Keep all sections containing symbols undefined on the command-line, 5630104834Sobrien and the section containing the entry symbol. */ 563177298Sobrien 5632104834Sobrien for (ulist = link_info.gc_sym_list; ulist; ulist = ulist->next) 563360484Sobrien { 563477298Sobrien h = bfd_link_hash_lookup (link_info.hash, ulist->name, 5635130561Sobrien FALSE, FALSE, FALSE); 563660484Sobrien 5637130561Sobrien if (h != NULL 563877298Sobrien && (h->type == bfd_link_hash_defined 563977298Sobrien || h->type == bfd_link_hash_defweak) 564060484Sobrien && ! bfd_is_abs_section (h->u.def.section)) 564160484Sobrien { 564260484Sobrien h->u.def.section->flags |= SEC_KEEP; 564360484Sobrien } 564460484Sobrien } 564560484Sobrien 5646218822Sdim /* SEC_EXCLUDE is ignored when doing a relocatable link, except in 5647218822Sdim the special case of debug info. (See bfd/stabs.c) 5648218822Sdim Twiddle the flag here, to simplify later linker code. */ 5649218822Sdim if (link_info.relocatable) 5650218822Sdim { 5651218822Sdim LANG_FOR_EACH_INPUT_STATEMENT (f) 5652218822Sdim { 5653218822Sdim asection *sec; 5654218822Sdim for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next) 5655218822Sdim if ((sec->flags & SEC_DEBUGGING) == 0) 5656218822Sdim sec->flags &= ~SEC_EXCLUDE; 5657218822Sdim } 5658218822Sdim } 5659218822Sdim 5660218822Sdim if (link_info.gc_sections) 5661218822Sdim bfd_gc_sections (output_bfd, &link_info); 566260484Sobrien} 566360484Sobrien 5664218822Sdim/* Relax all sections until bfd_relax_section gives up. */ 5665218822Sdim 5666218822Sdimstatic void 5667218822Sdimrelax_sections (void) 5668218822Sdim{ 5669218822Sdim /* Keep relaxing until bfd_relax_section gives up. */ 5670218822Sdim bfd_boolean relax_again; 5671218822Sdim 5672218822Sdim link_info.relax_trip = -1; 5673218822Sdim do 5674218822Sdim { 5675218822Sdim relax_again = FALSE; 5676218822Sdim link_info.relax_trip++; 5677218822Sdim 5678218822Sdim /* Note: pe-dll.c does something like this also. If you find 5679218822Sdim you need to change this code, you probably need to change 5680218822Sdim pe-dll.c also. DJ */ 5681218822Sdim 5682218822Sdim /* Do all the assignments with our current guesses as to 5683218822Sdim section sizes. */ 5684218822Sdim lang_do_assignments (); 5685218822Sdim 5686218822Sdim /* We must do this after lang_do_assignments, because it uses 5687218822Sdim size. */ 5688218822Sdim lang_reset_memory_regions (); 5689218822Sdim 5690218822Sdim /* Perform another relax pass - this time we know where the 5691218822Sdim globals are, so can make a better guess. */ 5692218822Sdim lang_size_sections (&relax_again, FALSE); 5693218822Sdim } 5694218822Sdim while (relax_again); 5695218822Sdim} 5696218822Sdim 569733965Sjdpvoid 5698130561Sobrienlang_process (void) 569933965Sjdp{ 5700218822Sdim /* Finalize dynamic list. */ 5701218822Sdim if (link_info.dynamic_list) 5702218822Sdim lang_finalize_version_expr_head (&link_info.dynamic_list->head); 5703218822Sdim 570433965Sjdp current_target = default_target; 570533965Sjdp 570677298Sobrien /* Open the output file. */ 570777298Sobrien lang_for_each_statement (ldlang_open_output); 5708130561Sobrien init_opb (); 570933965Sjdp 571033965Sjdp ldemul_create_output_section_statements (); 571133965Sjdp 571277298Sobrien /* Add to the hash table all undefineds on the command line. */ 571333965Sjdp lang_place_undefineds (); 571433965Sjdp 5715218822Sdim if (!bfd_section_already_linked_table_init ()) 5716218822Sdim einfo (_("%P%F: Failed to create hash table\n")); 571760484Sobrien 571877298Sobrien /* Create a bfd for each input file. */ 571933965Sjdp current_target = default_target; 5720130561Sobrien open_input_bfds (statement_list.head, FALSE); 572133965Sjdp 5722104834Sobrien link_info.gc_sym_list = &entry_symbol; 5723104834Sobrien if (entry_symbol.name == NULL) 5724104834Sobrien link_info.gc_sym_list = ldlang_undef_chain_list_head; 5725104834Sobrien 572633965Sjdp ldemul_after_open (); 572733965Sjdp 5728218822Sdim bfd_section_already_linked_table_free (); 572960484Sobrien 573033965Sjdp /* Make sure that we're not mixing architectures. We call this 573133965Sjdp after all the input files have been opened, but before we do any 573233965Sjdp other processing, so that any operations merge_private_bfd_data 573333965Sjdp does on the output file will be known during the rest of the 573433965Sjdp link. */ 573533965Sjdp lang_check (); 573633965Sjdp 573760484Sobrien /* Handle .exports instead of a version script if we're told to do so. */ 573860484Sobrien if (command_line.version_exports_section) 573960484Sobrien lang_do_version_exports_section (); 574060484Sobrien 574133965Sjdp /* Build all sets based on the information gathered from the input 574233965Sjdp files. */ 574333965Sjdp ldctor_build_sets (); 574433965Sjdp 574560484Sobrien /* Remove unreferenced sections if asked to. */ 5746218822Sdim lang_gc_sections (); 574760484Sobrien 574877298Sobrien /* Size up the common data. */ 574933965Sjdp lang_common (); 575033965Sjdp 5751218822Sdim /* Update wild statements. */ 5752218822Sdim update_wild_statements (statement_list.head); 5753218822Sdim 575433965Sjdp /* Run through the contours of the script and attach input sections 575577298Sobrien to the correct output sections. */ 5756130561Sobrien map_input_to_output_sections (statement_list.head, NULL, NULL); 575733965Sjdp 575877298Sobrien /* Find any sections not attached explicitly and handle them. */ 575933965Sjdp lang_place_orphans (); 576033965Sjdp 5761130561Sobrien if (! link_info.relocatable) 576294536Sobrien { 5763218822Sdim asection *found; 5764218822Sdim 5765218822Sdim /* Merge SEC_MERGE sections. This has to be done after GC of 5766218822Sdim sections, so that GCed sections are not merged, but before 5767218822Sdim assigning dynamic symbols, since removing whole input sections 5768218822Sdim is hard then. */ 5769218822Sdim bfd_merge_sections (output_bfd, &link_info); 5770218822Sdim 577194536Sobrien /* Look for a text section and set the readonly attribute in it. */ 5772218822Sdim found = bfd_get_section_by_name (output_bfd, ".text"); 577394536Sobrien 5774130561Sobrien if (found != NULL) 577594536Sobrien { 577694536Sobrien if (config.text_read_only) 577794536Sobrien found->flags |= SEC_READONLY; 577894536Sobrien else 577994536Sobrien found->flags &= ~SEC_READONLY; 578094536Sobrien } 578194536Sobrien } 578294536Sobrien 578394536Sobrien /* Do anything special before sizing sections. This is where ELF 578494536Sobrien and other back-ends size dynamic sections. */ 578533965Sjdp ldemul_before_allocation (); 578633965Sjdp 578733965Sjdp /* We must record the program headers before we try to fix the 578833965Sjdp section positions, since they will affect SIZEOF_HEADERS. */ 578933965Sjdp lang_record_phdrs (); 579033965Sjdp 579189857Sobrien /* Size up the sections. */ 5792218822Sdim lang_size_sections (NULL, !command_line.relax); 579389857Sobrien 579477298Sobrien /* Now run around and relax if we can. */ 579533965Sjdp if (command_line.relax) 579633965Sjdp { 5797218822Sdim /* We may need more than one relaxation pass. */ 5798218822Sdim int i = link_info.relax_pass; 579933965Sjdp 5800218822Sdim /* The backend can use it to determine the current pass. */ 5801218822Sdim link_info.relax_pass = 0; 5802218822Sdim 5803218822Sdim while (i--) 580433965Sjdp { 5805218822Sdim relax_sections (); 5806218822Sdim link_info.relax_pass++; 580733965Sjdp } 5808130561Sobrien 5809130561Sobrien /* Final extra sizing to report errors. */ 5810218822Sdim lang_do_assignments (); 5811130561Sobrien lang_reset_memory_regions (); 5812218822Sdim lang_size_sections (NULL, TRUE); 581333965Sjdp } 581433965Sjdp 581533965Sjdp /* See if anything special should be done now we know how big 581633965Sjdp everything is. */ 581733965Sjdp ldemul_after_allocation (); 581833965Sjdp 581933965Sjdp /* Fix any .startof. or .sizeof. symbols. */ 582033965Sjdp lang_set_startof (); 582133965Sjdp 582277298Sobrien /* Do all the assignments, now that we know the final resting places 582377298Sobrien of all the symbols. */ 582433965Sjdp 5825218822Sdim lang_do_assignments (); 582633965Sjdp 5827218822Sdim ldemul_finish (); 5828218822Sdim 582960484Sobrien /* Make sure that the section addresses make sense. */ 5830130561Sobrien if (! link_info.relocatable 583160484Sobrien && command_line.check_section_addresses) 583260484Sobrien lang_check_section_addresses (); 583333965Sjdp 5834218822Sdim lang_end (); 583533965Sjdp} 583633965Sjdp 583733965Sjdp/* EXPORTED TO YACC */ 583833965Sjdp 583933965Sjdpvoid 5840130561Sobrienlang_add_wild (struct wildcard_spec *filespec, 5841130561Sobrien struct wildcard_list *section_list, 5842130561Sobrien bfd_boolean keep_sections) 584333965Sjdp{ 584489857Sobrien struct wildcard_list *curr, *next; 584589857Sobrien lang_wild_statement_type *new; 584633965Sjdp 584789857Sobrien /* Reverse the list as the parser puts it back to front. */ 584889857Sobrien for (curr = section_list, section_list = NULL; 584989857Sobrien curr != NULL; 585089857Sobrien section_list = curr, curr = next) 585133965Sjdp { 585289857Sobrien if (curr->spec.name != NULL && strcmp (curr->spec.name, "COMMON") == 0) 5853130561Sobrien placed_commons = TRUE; 585489857Sobrien 585589857Sobrien next = curr->next; 585689857Sobrien curr->next = section_list; 585733965Sjdp } 585889857Sobrien 585989857Sobrien if (filespec != NULL && filespec->name != NULL) 586033965Sjdp { 586189857Sobrien if (strcmp (filespec->name, "*") == 0) 586289857Sobrien filespec->name = NULL; 586389857Sobrien else if (! wildcardp (filespec->name)) 5864130561Sobrien lang_has_input_file = TRUE; 586533965Sjdp } 586689857Sobrien 586789857Sobrien new = new_stat (lang_wild_statement, stat_ptr); 586889857Sobrien new->filename = NULL; 5869130561Sobrien new->filenames_sorted = FALSE; 587089857Sobrien if (filespec != NULL) 587189857Sobrien { 587289857Sobrien new->filename = filespec->name; 5873218822Sdim new->filenames_sorted = filespec->sorted == by_name; 587489857Sobrien } 587589857Sobrien new->section_list = section_list; 587660484Sobrien new->keep_sections = keep_sections; 587733965Sjdp lang_list_init (&new->children); 5878218822Sdim analyze_walk_wild_section_handler (new); 587933965Sjdp} 588033965Sjdp 588133965Sjdpvoid 5882218822Sdimlang_section_start (const char *name, etree_type *address, 5883218822Sdim const segment_type *segment) 588433965Sjdp{ 588578828Sobrien lang_address_statement_type *ad; 588633965Sjdp 588778828Sobrien ad = new_stat (lang_address_statement, stat_ptr); 588833965Sjdp ad->section_name = name; 588933965Sjdp ad->address = address; 5890218822Sdim ad->segment = segment; 589133965Sjdp} 589233965Sjdp 589333965Sjdp/* Set the start symbol to NAME. CMDLINE is nonzero if this is called 589433965Sjdp because of a -e argument on the command line, or zero if this is 589533965Sjdp called by ENTRY in a linker script. Command line arguments take 589633965Sjdp precedence. */ 589733965Sjdp 589833965Sjdpvoid 5899130561Sobrienlang_add_entry (const char *name, bfd_boolean cmdline) 590033965Sjdp{ 5901104834Sobrien if (entry_symbol.name == NULL 590233965Sjdp || cmdline 590333965Sjdp || ! entry_from_cmdline) 590433965Sjdp { 5905104834Sobrien entry_symbol.name = name; 590633965Sjdp entry_from_cmdline = cmdline; 590733965Sjdp } 590833965Sjdp} 590933965Sjdp 5910218822Sdim/* Set the default start symbol to NAME. .em files should use this, 5911218822Sdim not lang_add_entry, to override the use of "start" if neither the 5912218822Sdim linker script nor the command line specifies an entry point. NAME 5913218822Sdim must be permanently allocated. */ 591433965Sjdpvoid 5915218822Sdimlang_default_entry (const char *name) 5916218822Sdim{ 5917218822Sdim entry_symbol_default = name; 5918218822Sdim} 5919218822Sdim 5920218822Sdimvoid 5921130561Sobrienlang_add_target (const char *name) 592233965Sjdp{ 5923218822Sdim lang_target_statement_type *new; 592433965Sjdp 5925218822Sdim new = new_stat (lang_target_statement, stat_ptr); 592633965Sjdp new->target = name; 592733965Sjdp} 592833965Sjdp 592933965Sjdpvoid 5930130561Sobrienlang_add_map (const char *name) 593133965Sjdp{ 593233965Sjdp while (*name) 593333965Sjdp { 593433965Sjdp switch (*name) 593533965Sjdp { 593677298Sobrien case 'F': 5937130561Sobrien map_option_f = TRUE; 593833965Sjdp break; 593933965Sjdp } 594033965Sjdp name++; 594133965Sjdp } 594233965Sjdp} 594333965Sjdp 594433965Sjdpvoid 5945130561Sobrienlang_add_fill (fill_type *fill) 594633965Sjdp{ 5947218822Sdim lang_fill_statement_type *new; 594833965Sjdp 5949218822Sdim new = new_stat (lang_fill_statement, stat_ptr); 5950104834Sobrien new->fill = fill; 595133965Sjdp} 595233965Sjdp 595333965Sjdpvoid 5954130561Sobrienlang_add_data (int type, union etree_union *exp) 595533965Sjdp{ 5956218822Sdim lang_data_statement_type *new; 595733965Sjdp 5958218822Sdim new = new_stat (lang_data_statement, stat_ptr); 595933965Sjdp new->exp = exp; 596033965Sjdp new->type = type; 596133965Sjdp} 596233965Sjdp 596333965Sjdp/* Create a new reloc statement. RELOC is the BFD relocation type to 596433965Sjdp generate. HOWTO is the corresponding howto structure (we could 596533965Sjdp look this up, but the caller has already done so). SECTION is the 596633965Sjdp section to generate a reloc against, or NAME is the name of the 596733965Sjdp symbol to generate a reloc against. Exactly one of SECTION and 596833965Sjdp NAME must be NULL. ADDEND is an expression for the addend. */ 596933965Sjdp 597033965Sjdpvoid 5971130561Sobrienlang_add_reloc (bfd_reloc_code_real_type reloc, 5972130561Sobrien reloc_howto_type *howto, 5973130561Sobrien asection *section, 5974130561Sobrien const char *name, 5975130561Sobrien union etree_union *addend) 597633965Sjdp{ 597733965Sjdp lang_reloc_statement_type *p = new_stat (lang_reloc_statement, stat_ptr); 597877298Sobrien 597933965Sjdp p->reloc = reloc; 598033965Sjdp p->howto = howto; 598133965Sjdp p->section = section; 598233965Sjdp p->name = name; 598333965Sjdp p->addend_exp = addend; 598433965Sjdp 598533965Sjdp p->addend_value = 0; 598633965Sjdp p->output_section = NULL; 5987218822Sdim p->output_offset = 0; 598833965Sjdp} 598933965Sjdp 599060484Sobrienlang_assignment_statement_type * 5991130561Sobrienlang_add_assignment (etree_type *exp) 599233965Sjdp{ 5993218822Sdim lang_assignment_statement_type *new; 599433965Sjdp 5995218822Sdim new = new_stat (lang_assignment_statement, stat_ptr); 599633965Sjdp new->exp = exp; 599760484Sobrien return new; 599833965Sjdp} 599933965Sjdp 600033965Sjdpvoid 6001130561Sobrienlang_add_attribute (enum statement_enum attribute) 600233965Sjdp{ 6003218822Sdim new_statement (attribute, sizeof (lang_statement_header_type), stat_ptr); 600433965Sjdp} 600533965Sjdp 600633965Sjdpvoid 6007130561Sobrienlang_startup (const char *name) 600833965Sjdp{ 6009130561Sobrien if (startup_file != NULL) 601033965Sjdp { 6011218822Sdim einfo (_("%P%F: multiple STARTUP files\n")); 601233965Sjdp } 601333965Sjdp first_file->filename = name; 601433965Sjdp first_file->local_sym_name = name; 6015130561Sobrien first_file->real = TRUE; 601633965Sjdp 601733965Sjdp startup_file = name; 601833965Sjdp} 601933965Sjdp 602033965Sjdpvoid 6021130561Sobrienlang_float (bfd_boolean maybe) 602233965Sjdp{ 602333965Sjdp lang_float_flag = maybe; 602433965Sjdp} 602533965Sjdp 6026104834Sobrien 6027104834Sobrien/* Work out the load- and run-time regions from a script statement, and 6028104834Sobrien store them in *LMA_REGION and *REGION respectively. 6029104834Sobrien 6030130561Sobrien MEMSPEC is the name of the run-time region, or the value of 6031130561Sobrien DEFAULT_MEMORY_REGION if the statement didn't specify one. 6032130561Sobrien LMA_MEMSPEC is the name of the load-time region, or null if the 6033130561Sobrien statement didn't specify one.HAVE_LMA_P is TRUE if the statement 6034130561Sobrien had an explicit load address. 6035104834Sobrien 6036104834Sobrien It is an error to specify both a load region and a load address. */ 6037104834Sobrien 6038104834Sobrienstatic void 6039130561Sobrienlang_get_regions (lang_memory_region_type **region, 6040130561Sobrien lang_memory_region_type **lma_region, 6041130561Sobrien const char *memspec, 6042130561Sobrien const char *lma_memspec, 6043130561Sobrien bfd_boolean have_lma, 6044130561Sobrien bfd_boolean have_vma) 6045104834Sobrien{ 6046130561Sobrien *lma_region = lang_memory_region_lookup (lma_memspec, FALSE); 6047104834Sobrien 6048218822Sdim /* If no runtime region or VMA has been specified, but the load region 6049218822Sdim has been specified, then use the load region for the runtime region 6050218822Sdim as well. */ 6051130561Sobrien if (lma_memspec != NULL 6052130561Sobrien && ! have_vma 6053130561Sobrien && strcmp (memspec, DEFAULT_MEMORY_REGION) == 0) 6054104834Sobrien *region = *lma_region; 6055104834Sobrien else 6056130561Sobrien *region = lang_memory_region_lookup (memspec, FALSE); 6057104834Sobrien 6058130561Sobrien if (have_lma && lma_memspec != 0) 6059104834Sobrien einfo (_("%X%P:%S: section has both a load address and a load region\n")); 6060104834Sobrien} 6061104834Sobrien 606233965Sjdpvoid 6063130561Sobrienlang_leave_output_section_statement (fill_type *fill, const char *memspec, 6064130561Sobrien lang_output_section_phdr_list *phdrs, 6065130561Sobrien const char *lma_memspec) 606633965Sjdp{ 6067104834Sobrien lang_get_regions (¤t_section->region, 6068104834Sobrien ¤t_section->lma_region, 6069104834Sobrien memspec, lma_memspec, 6070130561Sobrien current_section->load_base != NULL, 6071130561Sobrien current_section->addr_tree != NULL); 607233965Sjdp current_section->fill = fill; 607333965Sjdp current_section->phdrs = phdrs; 607433965Sjdp stat_ptr = &statement_list; 607533965Sjdp} 607633965Sjdp 607777298Sobrien/* Create an absolute symbol with the given name with the value of the 607877298Sobrien address of first byte of the section named. 607933965Sjdp 608077298Sobrien If the symbol already exists, then do nothing. */ 608177298Sobrien 608233965Sjdpvoid 6083130561Sobrienlang_abs_symbol_at_beginning_of (const char *secname, const char *name) 608433965Sjdp{ 608533965Sjdp struct bfd_link_hash_entry *h; 608633965Sjdp 6087130561Sobrien h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE); 6088130561Sobrien if (h == NULL) 608960484Sobrien einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); 609033965Sjdp 609133965Sjdp if (h->type == bfd_link_hash_new 609233965Sjdp || h->type == bfd_link_hash_undefined) 609333965Sjdp { 609433965Sjdp asection *sec; 609533965Sjdp 609633965Sjdp h->type = bfd_link_hash_defined; 609733965Sjdp 609833965Sjdp sec = bfd_get_section_by_name (output_bfd, secname); 6099130561Sobrien if (sec == NULL) 610033965Sjdp h->u.def.value = 0; 610133965Sjdp else 610233965Sjdp h->u.def.value = bfd_get_section_vma (output_bfd, sec); 610333965Sjdp 610433965Sjdp h->u.def.section = bfd_abs_section_ptr; 610533965Sjdp } 610633965Sjdp} 610733965Sjdp 610877298Sobrien/* Create an absolute symbol with the given name with the value of the 610977298Sobrien address of the first byte after the end of the section named. 611033965Sjdp 611177298Sobrien If the symbol already exists, then do nothing. */ 611277298Sobrien 611333965Sjdpvoid 6114130561Sobrienlang_abs_symbol_at_end_of (const char *secname, const char *name) 611533965Sjdp{ 611633965Sjdp struct bfd_link_hash_entry *h; 611733965Sjdp 6118130561Sobrien h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE); 6119130561Sobrien if (h == NULL) 612060484Sobrien einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); 612133965Sjdp 612233965Sjdp if (h->type == bfd_link_hash_new 612333965Sjdp || h->type == bfd_link_hash_undefined) 612433965Sjdp { 612533965Sjdp asection *sec; 612633965Sjdp 612733965Sjdp h->type = bfd_link_hash_defined; 612833965Sjdp 612933965Sjdp sec = bfd_get_section_by_name (output_bfd, secname); 6130130561Sobrien if (sec == NULL) 613133965Sjdp h->u.def.value = 0; 613233965Sjdp else 613333965Sjdp h->u.def.value = (bfd_get_section_vma (output_bfd, sec) 6134218822Sdim + TO_ADDR (sec->size)); 613533965Sjdp 613633965Sjdp h->u.def.section = bfd_abs_section_ptr; 613733965Sjdp } 613833965Sjdp} 613933965Sjdp 614033965Sjdpvoid 6141130561Sobrienlang_statement_append (lang_statement_list_type *list, 6142130561Sobrien lang_statement_union_type *element, 6143130561Sobrien lang_statement_union_type **field) 614433965Sjdp{ 614533965Sjdp *(list->tail) = element; 614633965Sjdp list->tail = field; 614733965Sjdp} 614833965Sjdp 614933965Sjdp/* Set the output format type. -oformat overrides scripts. */ 615033965Sjdp 615133965Sjdpvoid 6152130561Sobrienlang_add_output_format (const char *format, 6153130561Sobrien const char *big, 6154130561Sobrien const char *little, 6155130561Sobrien int from_script) 615633965Sjdp{ 615733965Sjdp if (output_target == NULL || !from_script) 615833965Sjdp { 615933965Sjdp if (command_line.endian == ENDIAN_BIG 616033965Sjdp && big != NULL) 616133965Sjdp format = big; 616233965Sjdp else if (command_line.endian == ENDIAN_LITTLE 616333965Sjdp && little != NULL) 616433965Sjdp format = little; 616533965Sjdp 616633965Sjdp output_target = format; 616733965Sjdp } 616833965Sjdp} 616933965Sjdp 617033965Sjdp/* Enter a group. This creates a new lang_group_statement, and sets 617133965Sjdp stat_ptr to build new statements within the group. */ 617233965Sjdp 617333965Sjdpvoid 6174130561Sobrienlang_enter_group (void) 617533965Sjdp{ 617633965Sjdp lang_group_statement_type *g; 617733965Sjdp 617833965Sjdp g = new_stat (lang_group_statement, stat_ptr); 617933965Sjdp lang_list_init (&g->children); 618033965Sjdp stat_ptr = &g->children; 618133965Sjdp} 618233965Sjdp 618333965Sjdp/* Leave a group. This just resets stat_ptr to start writing to the 618433965Sjdp regular list of statements again. Note that this will not work if 618533965Sjdp groups can occur inside anything else which can adjust stat_ptr, 618633965Sjdp but currently they can't. */ 618733965Sjdp 618833965Sjdpvoid 6189130561Sobrienlang_leave_group (void) 619033965Sjdp{ 619133965Sjdp stat_ptr = &statement_list; 619233965Sjdp} 619333965Sjdp 619433965Sjdp/* Add a new program header. This is called for each entry in a PHDRS 619533965Sjdp command in a linker script. */ 619633965Sjdp 619733965Sjdpvoid 6198130561Sobrienlang_new_phdr (const char *name, 6199130561Sobrien etree_type *type, 6200130561Sobrien bfd_boolean filehdr, 6201130561Sobrien bfd_boolean phdrs, 6202130561Sobrien etree_type *at, 6203130561Sobrien etree_type *flags) 620433965Sjdp{ 620533965Sjdp struct lang_phdr *n, **pp; 620633965Sjdp 6207130561Sobrien n = stat_alloc (sizeof (struct lang_phdr)); 620833965Sjdp n->next = NULL; 620933965Sjdp n->name = name; 6210218822Sdim n->type = exp_get_value_int (type, 0, "program header type"); 621133965Sjdp n->filehdr = filehdr; 621233965Sjdp n->phdrs = phdrs; 621333965Sjdp n->at = at; 621433965Sjdp n->flags = flags; 621533965Sjdp 621633965Sjdp for (pp = &lang_phdr_list; *pp != NULL; pp = &(*pp)->next) 621733965Sjdp ; 621833965Sjdp *pp = n; 621933965Sjdp} 622033965Sjdp 622133965Sjdp/* Record the program header information in the output BFD. FIXME: We 622233965Sjdp should not be calling an ELF specific function here. */ 622333965Sjdp 622433965Sjdpstatic void 6225130561Sobrienlang_record_phdrs (void) 622633965Sjdp{ 622733965Sjdp unsigned int alc; 622833965Sjdp asection **secs; 6229130561Sobrien lang_output_section_phdr_list *last; 623033965Sjdp struct lang_phdr *l; 6231218822Sdim lang_output_section_statement_type *os; 623233965Sjdp 623333965Sjdp alc = 10; 6234130561Sobrien secs = xmalloc (alc * sizeof (asection *)); 623533965Sjdp last = NULL; 6236218822Sdim 623733965Sjdp for (l = lang_phdr_list; l != NULL; l = l->next) 623833965Sjdp { 623933965Sjdp unsigned int c; 624033965Sjdp flagword flags; 624133965Sjdp bfd_vma at; 624233965Sjdp 624333965Sjdp c = 0; 6244218822Sdim for (os = &lang_output_section_statement.head->output_section_statement; 6245218822Sdim os != NULL; 6246218822Sdim os = os->next) 624733965Sjdp { 6248130561Sobrien lang_output_section_phdr_list *pl; 624933965Sjdp 6250218822Sdim if (os->constraint == -1) 6251218822Sdim continue; 625233965Sjdp 625333965Sjdp pl = os->phdrs; 625433965Sjdp if (pl != NULL) 625533965Sjdp last = pl; 625633965Sjdp else 625733965Sjdp { 625833965Sjdp if (os->sectype == noload_section 625933965Sjdp || os->bfd_section == NULL 626033965Sjdp || (os->bfd_section->flags & SEC_ALLOC) == 0) 626133965Sjdp continue; 6262218822Sdim 6263218822Sdim if (last) 6264218822Sdim pl = last; 6265218822Sdim else 6266218822Sdim { 6267218822Sdim lang_output_section_statement_type * tmp_os; 6268218822Sdim 6269218822Sdim /* If we have not run across a section with a program 6270218822Sdim header assigned to it yet, then scan forwards to find 6271218822Sdim one. This prevents inconsistencies in the linker's 6272218822Sdim behaviour when a script has specified just a single 6273218822Sdim header and there are sections in that script which are 6274218822Sdim not assigned to it, and which occur before the first 6275218822Sdim use of that header. See here for more details: 6276218822Sdim http://sourceware.org/ml/binutils/2007-02/msg00291.html */ 6277218822Sdim for (tmp_os = os; tmp_os; tmp_os = tmp_os->next) 6278218822Sdim if (tmp_os->phdrs) 6279218822Sdim break; 6280218822Sdim pl = tmp_os->phdrs; 6281218822Sdim } 628233965Sjdp } 628333965Sjdp 628433965Sjdp if (os->bfd_section == NULL) 628533965Sjdp continue; 628633965Sjdp 628733965Sjdp for (; pl != NULL; pl = pl->next) 628833965Sjdp { 628933965Sjdp if (strcmp (pl->name, l->name) == 0) 629033965Sjdp { 629133965Sjdp if (c >= alc) 629233965Sjdp { 629333965Sjdp alc *= 2; 6294130561Sobrien secs = xrealloc (secs, alc * sizeof (asection *)); 629533965Sjdp } 629633965Sjdp secs[c] = os->bfd_section; 629733965Sjdp ++c; 6298130561Sobrien pl->used = TRUE; 629933965Sjdp } 630033965Sjdp } 630133965Sjdp } 630233965Sjdp 630333965Sjdp if (l->flags == NULL) 630433965Sjdp flags = 0; 630533965Sjdp else 6306218822Sdim flags = exp_get_vma (l->flags, 0, "phdr flags"); 630733965Sjdp 630833965Sjdp if (l->at == NULL) 630933965Sjdp at = 0; 631033965Sjdp else 6311218822Sdim at = exp_get_vma (l->at, 0, "phdr load address"); 631233965Sjdp 631333965Sjdp if (! bfd_record_phdr (output_bfd, l->type, 631478828Sobrien l->flags != NULL, flags, l->at != NULL, 631533965Sjdp at, l->filehdr, l->phdrs, c, secs)) 631660484Sobrien einfo (_("%F%P: bfd_record_phdr failed: %E\n")); 631733965Sjdp } 631833965Sjdp 631933965Sjdp free (secs); 632033965Sjdp 632133965Sjdp /* Make sure all the phdr assignments succeeded. */ 6322218822Sdim for (os = &lang_output_section_statement.head->output_section_statement; 6323218822Sdim os != NULL; 6324218822Sdim os = os->next) 632533965Sjdp { 6326130561Sobrien lang_output_section_phdr_list *pl; 632733965Sjdp 6328218822Sdim if (os->constraint == -1 6329218822Sdim || os->bfd_section == NULL) 633033965Sjdp continue; 633133965Sjdp 6332218822Sdim for (pl = os->phdrs; 633333965Sjdp pl != NULL; 633433965Sjdp pl = pl->next) 633533965Sjdp if (! pl->used && strcmp (pl->name, "NONE") != 0) 633660484Sobrien einfo (_("%X%P: section `%s' assigned to non-existent phdr `%s'\n"), 6337218822Sdim os->name, pl->name); 633833965Sjdp } 633933965Sjdp} 634033965Sjdp 634133965Sjdp/* Record a list of sections which may not be cross referenced. */ 634233965Sjdp 634333965Sjdpvoid 6344130561Sobrienlang_add_nocrossref (lang_nocrossref_type *l) 634533965Sjdp{ 634633965Sjdp struct lang_nocrossrefs *n; 634733965Sjdp 6348130561Sobrien n = xmalloc (sizeof *n); 634933965Sjdp n->next = nocrossref_list; 635033965Sjdp n->list = l; 635133965Sjdp nocrossref_list = n; 635233965Sjdp 635333965Sjdp /* Set notice_all so that we get informed about all symbols. */ 6354130561Sobrien link_info.notice_all = TRUE; 635533965Sjdp} 635633965Sjdp 635733965Sjdp/* Overlay handling. We handle overlays with some static variables. */ 635833965Sjdp 635933965Sjdp/* The overlay virtual address. */ 636033965Sjdpstatic etree_type *overlay_vma; 6361130561Sobrien/* And subsection alignment. */ 6362130561Sobrienstatic etree_type *overlay_subalign; 636333965Sjdp 636433965Sjdp/* An expression for the maximum section size seen so far. */ 636533965Sjdpstatic etree_type *overlay_max; 636633965Sjdp 636733965Sjdp/* A list of all the sections in this overlay. */ 636833965Sjdp 636977298Sobrienstruct overlay_list { 637033965Sjdp struct overlay_list *next; 637133965Sjdp lang_output_section_statement_type *os; 637233965Sjdp}; 637333965Sjdp 637433965Sjdpstatic struct overlay_list *overlay_list; 637533965Sjdp 637633965Sjdp/* Start handling an overlay. */ 637733965Sjdp 637833965Sjdpvoid 6379130561Sobrienlang_enter_overlay (etree_type *vma_expr, etree_type *subalign) 638033965Sjdp{ 638133965Sjdp /* The grammar should prevent nested overlays from occurring. */ 6382130561Sobrien ASSERT (overlay_vma == NULL 6383130561Sobrien && overlay_subalign == NULL 6384130561Sobrien && overlay_max == NULL); 638533965Sjdp 638633965Sjdp overlay_vma = vma_expr; 6387130561Sobrien overlay_subalign = subalign; 638833965Sjdp} 638933965Sjdp 639033965Sjdp/* Start a section in an overlay. We handle this by calling 6391104834Sobrien lang_enter_output_section_statement with the correct VMA. 6392104834Sobrien lang_leave_overlay sets up the LMA and memory regions. */ 639333965Sjdp 639433965Sjdpvoid 6395130561Sobrienlang_enter_overlay_section (const char *name) 639633965Sjdp{ 639733965Sjdp struct overlay_list *n; 639833965Sjdp etree_type *size; 639933965Sjdp 6400218822Sdim lang_enter_output_section_statement (name, overlay_vma, overlay_section, 6401218822Sdim 0, overlay_subalign, 0, 0); 640233965Sjdp 6403104834Sobrien /* If this is the first section, then base the VMA of future 640433965Sjdp sections on this one. This will work correctly even if `.' is 640533965Sjdp used in the addresses. */ 640633965Sjdp if (overlay_list == NULL) 6407104834Sobrien overlay_vma = exp_nameop (ADDR, name); 640833965Sjdp 640933965Sjdp /* Remember the section. */ 6410130561Sobrien n = xmalloc (sizeof *n); 641133965Sjdp n->os = current_section; 641233965Sjdp n->next = overlay_list; 641333965Sjdp overlay_list = n; 641433965Sjdp 641533965Sjdp size = exp_nameop (SIZEOF, name); 641633965Sjdp 641733965Sjdp /* Arrange to work out the maximum section end address. */ 641833965Sjdp if (overlay_max == NULL) 641933965Sjdp overlay_max = size; 642033965Sjdp else 642160484Sobrien overlay_max = exp_binop (MAX_K, overlay_max, size); 642233965Sjdp} 642333965Sjdp 642433965Sjdp/* Finish a section in an overlay. There isn't any special to do 642533965Sjdp here. */ 642633965Sjdp 642733965Sjdpvoid 6428130561Sobrienlang_leave_overlay_section (fill_type *fill, 6429130561Sobrien lang_output_section_phdr_list *phdrs) 643033965Sjdp{ 643133965Sjdp const char *name; 643233965Sjdp char *clean, *s2; 643333965Sjdp const char *s1; 643433965Sjdp char *buf; 643533965Sjdp 643633965Sjdp name = current_section->name; 643733965Sjdp 6438130561Sobrien /* For now, assume that DEFAULT_MEMORY_REGION is the run-time memory 6439130561Sobrien region and that no load-time region has been specified. It doesn't 6440130561Sobrien really matter what we say here, since lang_leave_overlay will 6441130561Sobrien override it. */ 6442130561Sobrien lang_leave_output_section_statement (fill, DEFAULT_MEMORY_REGION, phdrs, 0); 644333965Sjdp 644433965Sjdp /* Define the magic symbols. */ 644533965Sjdp 644633965Sjdp clean = xmalloc (strlen (name) + 1); 644733965Sjdp s2 = clean; 644833965Sjdp for (s1 = name; *s1 != '\0'; s1++) 644989857Sobrien if (ISALNUM (*s1) || *s1 == '_') 645033965Sjdp *s2++ = *s1; 645133965Sjdp *s2 = '\0'; 645233965Sjdp 645333965Sjdp buf = xmalloc (strlen (clean) + sizeof "__load_start_"); 645433965Sjdp sprintf (buf, "__load_start_%s", clean); 6455218822Sdim lang_add_assignment (exp_provide (buf, 6456218822Sdim exp_nameop (LOADADDR, name), 6457218822Sdim FALSE)); 645833965Sjdp 645933965Sjdp buf = xmalloc (strlen (clean) + sizeof "__load_stop_"); 646033965Sjdp sprintf (buf, "__load_stop_%s", clean); 6461218822Sdim lang_add_assignment (exp_provide (buf, 6462218822Sdim exp_binop ('+', 6463218822Sdim exp_nameop (LOADADDR, name), 6464218822Sdim exp_nameop (SIZEOF, name)), 6465218822Sdim FALSE)); 646633965Sjdp 646733965Sjdp free (clean); 646833965Sjdp} 646933965Sjdp 647033965Sjdp/* Finish an overlay. If there are any overlay wide settings, this 647133965Sjdp looks through all the sections in the overlay and sets them. */ 647233965Sjdp 647333965Sjdpvoid 6474130561Sobrienlang_leave_overlay (etree_type *lma_expr, 6475130561Sobrien int nocrossrefs, 6476130561Sobrien fill_type *fill, 6477130561Sobrien const char *memspec, 6478130561Sobrien lang_output_section_phdr_list *phdrs, 6479130561Sobrien const char *lma_memspec) 648033965Sjdp{ 648133965Sjdp lang_memory_region_type *region; 648260484Sobrien lang_memory_region_type *lma_region; 648333965Sjdp struct overlay_list *l; 6484130561Sobrien lang_nocrossref_type *nocrossref; 648533965Sjdp 6486104834Sobrien lang_get_regions (®ion, &lma_region, 6487104834Sobrien memspec, lma_memspec, 6488130561Sobrien lma_expr != NULL, FALSE); 648980016Sobrien 6490104834Sobrien nocrossref = NULL; 649133965Sjdp 6492104834Sobrien /* After setting the size of the last section, set '.' to end of the 6493104834Sobrien overlay region. */ 6494104834Sobrien if (overlay_list != NULL) 6495104834Sobrien overlay_list->os->update_dot_tree 6496104834Sobrien = exp_assop ('=', ".", exp_binop ('+', overlay_vma, overlay_max)); 649760484Sobrien 649833965Sjdp l = overlay_list; 649933965Sjdp while (l != NULL) 650033965Sjdp { 650133965Sjdp struct overlay_list *next; 650233965Sjdp 6503130561Sobrien if (fill != NULL && l->os->fill == NULL) 650433965Sjdp l->os->fill = fill; 650580016Sobrien 6506104834Sobrien l->os->region = region; 6507104834Sobrien l->os->lma_region = lma_region; 650880016Sobrien 6509104834Sobrien /* The first section has the load address specified in the 6510104834Sobrien OVERLAY statement. The rest are worked out from that. 6511104834Sobrien The base address is not needed (and should be null) if 6512104834Sobrien an LMA region was specified. */ 6513104834Sobrien if (l->next == 0) 6514218822Sdim { 6515218822Sdim l->os->load_base = lma_expr; 6516218822Sdim l->os->sectype = normal_section; 6517218822Sdim } 651833965Sjdp if (phdrs != NULL && l->os->phdrs == NULL) 651933965Sjdp l->os->phdrs = phdrs; 652033965Sjdp 6521104834Sobrien if (nocrossrefs) 652233965Sjdp { 6523130561Sobrien lang_nocrossref_type *nc; 652433965Sjdp 6525130561Sobrien nc = xmalloc (sizeof *nc); 652633965Sjdp nc->name = l->os->name; 652733965Sjdp nc->next = nocrossref; 652833965Sjdp nocrossref = nc; 652933965Sjdp } 653033965Sjdp 653133965Sjdp next = l->next; 653233965Sjdp free (l); 653333965Sjdp l = next; 653433965Sjdp } 653533965Sjdp 653633965Sjdp if (nocrossref != NULL) 653733965Sjdp lang_add_nocrossref (nocrossref); 653833965Sjdp 653933965Sjdp overlay_vma = NULL; 654033965Sjdp overlay_list = NULL; 654133965Sjdp overlay_max = NULL; 654233965Sjdp} 654333965Sjdp 654433965Sjdp/* Version handling. This is only useful for ELF. */ 654533965Sjdp 654633965Sjdp/* This global variable holds the version tree that we build. */ 654733965Sjdp 654833965Sjdpstruct bfd_elf_version_tree *lang_elf_version_info; 654933965Sjdp 6550130561Sobrien/* If PREV is NULL, return first version pattern matching particular symbol. 6551130561Sobrien If PREV is non-NULL, return first version pattern matching particular 6552130561Sobrien symbol after PREV (previously returned by lang_vers_match). */ 655360484Sobrien 6554130561Sobrienstatic struct bfd_elf_version_expr * 6555130561Sobrienlang_vers_match (struct bfd_elf_version_expr_head *head, 6556130561Sobrien struct bfd_elf_version_expr *prev, 6557130561Sobrien const char *sym) 655860484Sobrien{ 6559130561Sobrien const char *cxx_sym = sym; 6560130561Sobrien const char *java_sym = sym; 6561130561Sobrien struct bfd_elf_version_expr *expr = NULL; 656260484Sobrien 6563130561Sobrien if (head->mask & BFD_ELF_VERSION_CXX_TYPE) 6564130561Sobrien { 6565130561Sobrien cxx_sym = cplus_demangle (sym, DMGL_PARAMS | DMGL_ANSI); 6566130561Sobrien if (!cxx_sym) 6567130561Sobrien cxx_sym = sym; 6568130561Sobrien } 6569130561Sobrien if (head->mask & BFD_ELF_VERSION_JAVA_TYPE) 6570130561Sobrien { 6571130561Sobrien java_sym = cplus_demangle (sym, DMGL_JAVA); 6572130561Sobrien if (!java_sym) 6573130561Sobrien java_sym = sym; 6574130561Sobrien } 657560484Sobrien 6576130561Sobrien if (head->htab && (prev == NULL || prev->symbol)) 657760484Sobrien { 6578130561Sobrien struct bfd_elf_version_expr e; 6579130561Sobrien 6580130561Sobrien switch (prev ? prev->mask : 0) 6581130561Sobrien { 6582130561Sobrien case 0: 6583130561Sobrien if (head->mask & BFD_ELF_VERSION_C_TYPE) 6584130561Sobrien { 6585130561Sobrien e.symbol = sym; 6586130561Sobrien expr = htab_find (head->htab, &e); 6587130561Sobrien while (expr && strcmp (expr->symbol, sym) == 0) 6588130561Sobrien if (expr->mask == BFD_ELF_VERSION_C_TYPE) 6589130561Sobrien goto out_ret; 6590218822Sdim else 6591218822Sdim expr = expr->next; 6592130561Sobrien } 6593130561Sobrien /* Fallthrough */ 6594130561Sobrien case BFD_ELF_VERSION_C_TYPE: 6595130561Sobrien if (head->mask & BFD_ELF_VERSION_CXX_TYPE) 6596130561Sobrien { 6597130561Sobrien e.symbol = cxx_sym; 6598130561Sobrien expr = htab_find (head->htab, &e); 6599130561Sobrien while (expr && strcmp (expr->symbol, cxx_sym) == 0) 6600130561Sobrien if (expr->mask == BFD_ELF_VERSION_CXX_TYPE) 6601130561Sobrien goto out_ret; 6602218822Sdim else 6603218822Sdim expr = expr->next; 6604130561Sobrien } 6605130561Sobrien /* Fallthrough */ 6606130561Sobrien case BFD_ELF_VERSION_CXX_TYPE: 6607130561Sobrien if (head->mask & BFD_ELF_VERSION_JAVA_TYPE) 6608130561Sobrien { 6609130561Sobrien e.symbol = java_sym; 6610130561Sobrien expr = htab_find (head->htab, &e); 6611130561Sobrien while (expr && strcmp (expr->symbol, java_sym) == 0) 6612130561Sobrien if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE) 6613130561Sobrien goto out_ret; 6614218822Sdim else 6615218822Sdim expr = expr->next; 6616130561Sobrien } 6617130561Sobrien /* Fallthrough */ 6618130561Sobrien default: 6619130561Sobrien break; 6620130561Sobrien } 662160484Sobrien } 6622130561Sobrien 6623130561Sobrien /* Finally, try the wildcards. */ 6624130561Sobrien if (prev == NULL || prev->symbol) 6625130561Sobrien expr = head->remaining; 662660484Sobrien else 6627130561Sobrien expr = prev->next; 6628218822Sdim for (; expr; expr = expr->next) 662960484Sobrien { 6630130561Sobrien const char *s; 6631130561Sobrien 6632218822Sdim if (!expr->pattern) 6633218822Sdim continue; 6634218822Sdim 6635130561Sobrien if (expr->pattern[0] == '*' && expr->pattern[1] == '\0') 6636130561Sobrien break; 6637130561Sobrien 6638130561Sobrien if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE) 6639130561Sobrien s = java_sym; 6640130561Sobrien else if (expr->mask == BFD_ELF_VERSION_CXX_TYPE) 6641130561Sobrien s = cxx_sym; 6642130561Sobrien else 6643130561Sobrien s = sym; 6644130561Sobrien if (fnmatch (expr->pattern, s, 0) == 0) 6645130561Sobrien break; 664660484Sobrien } 664760484Sobrien 6648130561Sobrienout_ret: 6649130561Sobrien if (cxx_sym != sym) 6650130561Sobrien free ((char *) cxx_sym); 6651130561Sobrien if (java_sym != sym) 6652130561Sobrien free ((char *) java_sym); 6653130561Sobrien return expr; 665460484Sobrien} 665560484Sobrien 6656130561Sobrien/* Return NULL if the PATTERN argument is a glob pattern, otherwise, 6657130561Sobrien return a string pointing to the symbol name. */ 6658130561Sobrien 6659130561Sobrienstatic const char * 6660130561Sobrienrealsymbol (const char *pattern) 666160484Sobrien{ 6662130561Sobrien const char *p; 6663130561Sobrien bfd_boolean changed = FALSE, backslash = FALSE; 6664130561Sobrien char *s, *symbol = xmalloc (strlen (pattern) + 1); 666560484Sobrien 6666130561Sobrien for (p = pattern, s = symbol; *p != '\0'; ++p) 6667130561Sobrien { 6668130561Sobrien /* It is a glob pattern only if there is no preceding 6669130561Sobrien backslash. */ 6670130561Sobrien if (! backslash && (*p == '?' || *p == '*' || *p == '[')) 6671130561Sobrien { 6672130561Sobrien free (symbol); 6673130561Sobrien return NULL; 6674130561Sobrien } 667560484Sobrien 6676130561Sobrien if (backslash) 6677130561Sobrien { 6678130561Sobrien /* Remove the preceding backslash. */ 6679130561Sobrien *(s - 1) = *p; 6680130561Sobrien changed = TRUE; 6681130561Sobrien } 6682130561Sobrien else 6683130561Sobrien *s++ = *p; 6684130561Sobrien 6685130561Sobrien backslash = *p == '\\'; 6686130561Sobrien } 6687130561Sobrien 6688130561Sobrien if (changed) 668960484Sobrien { 6690130561Sobrien *s = '\0'; 6691130561Sobrien return symbol; 669260484Sobrien } 669360484Sobrien else 669460484Sobrien { 6695130561Sobrien free (symbol); 6696130561Sobrien return pattern; 669760484Sobrien } 669860484Sobrien} 669960484Sobrien 6700218822Sdim/* This is called for each variable name or match expression. NEW is 6701218822Sdim the name of the symbol to match, or, if LITERAL_P is FALSE, a glob 6702218822Sdim pattern to be matched against symbol names. */ 670333965Sjdp 670433965Sjdpstruct bfd_elf_version_expr * 6705130561Sobrienlang_new_vers_pattern (struct bfd_elf_version_expr *orig, 6706130561Sobrien const char *new, 6707218822Sdim const char *lang, 6708218822Sdim bfd_boolean literal_p) 670933965Sjdp{ 671033965Sjdp struct bfd_elf_version_expr *ret; 671133965Sjdp 6712130561Sobrien ret = xmalloc (sizeof *ret); 671333965Sjdp ret->next = orig; 6714218822Sdim ret->pattern = literal_p ? NULL : new; 6715104834Sobrien ret->symver = 0; 6716104834Sobrien ret->script = 0; 6717218822Sdim ret->symbol = literal_p ? new : realsymbol (new); 671860484Sobrien 671960484Sobrien if (lang == NULL || strcasecmp (lang, "C") == 0) 6720130561Sobrien ret->mask = BFD_ELF_VERSION_C_TYPE; 672160484Sobrien else if (strcasecmp (lang, "C++") == 0) 6722130561Sobrien ret->mask = BFD_ELF_VERSION_CXX_TYPE; 672360484Sobrien else if (strcasecmp (lang, "Java") == 0) 6724130561Sobrien ret->mask = BFD_ELF_VERSION_JAVA_TYPE; 672560484Sobrien else 672660484Sobrien { 672760484Sobrien einfo (_("%X%P: unknown language `%s' in version information\n"), 672860484Sobrien lang); 6729130561Sobrien ret->mask = BFD_ELF_VERSION_C_TYPE; 673060484Sobrien } 673160484Sobrien 6732104834Sobrien return ldemul_new_vers_pattern (ret); 673333965Sjdp} 673433965Sjdp 673533965Sjdp/* This is called for each set of variable names and match 673633965Sjdp expressions. */ 673733965Sjdp 673833965Sjdpstruct bfd_elf_version_tree * 6739130561Sobrienlang_new_vers_node (struct bfd_elf_version_expr *globals, 6740130561Sobrien struct bfd_elf_version_expr *locals) 674133965Sjdp{ 674233965Sjdp struct bfd_elf_version_tree *ret; 674333965Sjdp 6744130561Sobrien ret = xcalloc (1, sizeof *ret); 6745130561Sobrien ret->globals.list = globals; 6746130561Sobrien ret->locals.list = locals; 6747130561Sobrien ret->match = lang_vers_match; 674833965Sjdp ret->name_indx = (unsigned int) -1; 674933965Sjdp return ret; 675033965Sjdp} 675133965Sjdp 675233965Sjdp/* This static variable keeps track of version indices. */ 675333965Sjdp 675433965Sjdpstatic int version_index; 675533965Sjdp 6756130561Sobrienstatic hashval_t 6757130561Sobrienversion_expr_head_hash (const void *p) 6758130561Sobrien{ 6759130561Sobrien const struct bfd_elf_version_expr *e = p; 6760130561Sobrien 6761130561Sobrien return htab_hash_string (e->symbol); 6762130561Sobrien} 6763130561Sobrien 6764130561Sobrienstatic int 6765130561Sobrienversion_expr_head_eq (const void *p1, const void *p2) 6766130561Sobrien{ 6767130561Sobrien const struct bfd_elf_version_expr *e1 = p1; 6768130561Sobrien const struct bfd_elf_version_expr *e2 = p2; 6769130561Sobrien 6770130561Sobrien return strcmp (e1->symbol, e2->symbol) == 0; 6771130561Sobrien} 6772130561Sobrien 6773130561Sobrienstatic void 6774130561Sobrienlang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head) 6775130561Sobrien{ 6776130561Sobrien size_t count = 0; 6777130561Sobrien struct bfd_elf_version_expr *e, *next; 6778130561Sobrien struct bfd_elf_version_expr **list_loc, **remaining_loc; 6779130561Sobrien 6780130561Sobrien for (e = head->list; e; e = e->next) 6781130561Sobrien { 6782130561Sobrien if (e->symbol) 6783130561Sobrien count++; 6784130561Sobrien head->mask |= e->mask; 6785130561Sobrien } 6786130561Sobrien 6787130561Sobrien if (count) 6788130561Sobrien { 6789130561Sobrien head->htab = htab_create (count * 2, version_expr_head_hash, 6790130561Sobrien version_expr_head_eq, NULL); 6791130561Sobrien list_loc = &head->list; 6792130561Sobrien remaining_loc = &head->remaining; 6793130561Sobrien for (e = head->list; e; e = next) 6794130561Sobrien { 6795130561Sobrien next = e->next; 6796130561Sobrien if (!e->symbol) 6797130561Sobrien { 6798130561Sobrien *remaining_loc = e; 6799130561Sobrien remaining_loc = &e->next; 6800130561Sobrien } 6801130561Sobrien else 6802130561Sobrien { 6803130561Sobrien void **loc = htab_find_slot (head->htab, e, INSERT); 6804130561Sobrien 6805130561Sobrien if (*loc) 6806130561Sobrien { 6807130561Sobrien struct bfd_elf_version_expr *e1, *last; 6808130561Sobrien 6809130561Sobrien e1 = *loc; 6810130561Sobrien last = NULL; 6811130561Sobrien do 6812130561Sobrien { 6813130561Sobrien if (e1->mask == e->mask) 6814130561Sobrien { 6815130561Sobrien last = NULL; 6816130561Sobrien break; 6817130561Sobrien } 6818130561Sobrien last = e1; 6819130561Sobrien e1 = e1->next; 6820130561Sobrien } 6821130561Sobrien while (e1 && strcmp (e1->symbol, e->symbol) == 0); 6822130561Sobrien 6823130561Sobrien if (last == NULL) 6824130561Sobrien { 6825130561Sobrien /* This is a duplicate. */ 6826130561Sobrien /* FIXME: Memory leak. Sometimes pattern is not 6827130561Sobrien xmalloced alone, but in larger chunk of memory. */ 6828130561Sobrien /* free (e->symbol); */ 6829130561Sobrien free (e); 6830130561Sobrien } 6831130561Sobrien else 6832130561Sobrien { 6833130561Sobrien e->next = last->next; 6834130561Sobrien last->next = e; 6835130561Sobrien } 6836130561Sobrien } 6837130561Sobrien else 6838130561Sobrien { 6839130561Sobrien *loc = e; 6840130561Sobrien *list_loc = e; 6841130561Sobrien list_loc = &e->next; 6842130561Sobrien } 6843130561Sobrien } 6844130561Sobrien } 6845130561Sobrien *remaining_loc = NULL; 6846130561Sobrien *list_loc = head->remaining; 6847130561Sobrien } 6848130561Sobrien else 6849130561Sobrien head->remaining = head->list; 6850130561Sobrien} 6851130561Sobrien 685233965Sjdp/* This is called when we know the name and dependencies of the 685333965Sjdp version. */ 685433965Sjdp 685533965Sjdpvoid 6856130561Sobrienlang_register_vers_node (const char *name, 6857130561Sobrien struct bfd_elf_version_tree *version, 6858130561Sobrien struct bfd_elf_version_deps *deps) 685933965Sjdp{ 686033965Sjdp struct bfd_elf_version_tree *t, **pp; 686133965Sjdp struct bfd_elf_version_expr *e1; 686233965Sjdp 686389857Sobrien if (name == NULL) 686489857Sobrien name = ""; 686589857Sobrien 686689857Sobrien if ((name[0] == '\0' && lang_elf_version_info != NULL) 686789857Sobrien || (lang_elf_version_info && lang_elf_version_info->name[0] == '\0')) 686889857Sobrien { 6869218822Sdim einfo (_("%X%P: anonymous version tag cannot be combined" 6870218822Sdim " with other version tags\n")); 6871130561Sobrien free (version); 687289857Sobrien return; 687389857Sobrien } 687489857Sobrien 687533965Sjdp /* Make sure this node has a unique name. */ 687633965Sjdp for (t = lang_elf_version_info; t != NULL; t = t->next) 687733965Sjdp if (strcmp (t->name, name) == 0) 687860484Sobrien einfo (_("%X%P: duplicate version tag `%s'\n"), name); 687933965Sjdp 6880130561Sobrien lang_finalize_version_expr_head (&version->globals); 6881130561Sobrien lang_finalize_version_expr_head (&version->locals); 6882130561Sobrien 688333965Sjdp /* Check the global and local match names, and make sure there 688433965Sjdp aren't any duplicates. */ 688533965Sjdp 6886130561Sobrien for (e1 = version->globals.list; e1 != NULL; e1 = e1->next) 688733965Sjdp { 688833965Sjdp for (t = lang_elf_version_info; t != NULL; t = t->next) 688933965Sjdp { 689033965Sjdp struct bfd_elf_version_expr *e2; 689133965Sjdp 6892130561Sobrien if (t->locals.htab && e1->symbol) 6893130561Sobrien { 6894130561Sobrien e2 = htab_find (t->locals.htab, e1); 6895130561Sobrien while (e2 && strcmp (e1->symbol, e2->symbol) == 0) 6896130561Sobrien { 6897130561Sobrien if (e1->mask == e2->mask) 6898218822Sdim einfo (_("%X%P: duplicate expression `%s'" 6899218822Sdim " in version information\n"), e1->symbol); 6900130561Sobrien e2 = e2->next; 6901130561Sobrien } 6902130561Sobrien } 6903130561Sobrien else if (!e1->symbol) 6904130561Sobrien for (e2 = t->locals.remaining; e2 != NULL; e2 = e2->next) 6905218822Sdim if (strcmp (e1->pattern, e2->pattern) == 0 6906218822Sdim && e1->mask == e2->mask) 6907218822Sdim einfo (_("%X%P: duplicate expression `%s'" 6908218822Sdim " in version information\n"), e1->pattern); 690933965Sjdp } 691033965Sjdp } 691133965Sjdp 6912130561Sobrien for (e1 = version->locals.list; e1 != NULL; e1 = e1->next) 691333965Sjdp { 691433965Sjdp for (t = lang_elf_version_info; t != NULL; t = t->next) 691533965Sjdp { 691633965Sjdp struct bfd_elf_version_expr *e2; 691733965Sjdp 6918130561Sobrien if (t->globals.htab && e1->symbol) 6919130561Sobrien { 6920130561Sobrien e2 = htab_find (t->globals.htab, e1); 6921130561Sobrien while (e2 && strcmp (e1->symbol, e2->symbol) == 0) 6922130561Sobrien { 6923130561Sobrien if (e1->mask == e2->mask) 6924218822Sdim einfo (_("%X%P: duplicate expression `%s'" 6925218822Sdim " in version information\n"), 6926130561Sobrien e1->symbol); 6927130561Sobrien e2 = e2->next; 6928130561Sobrien } 6929130561Sobrien } 6930130561Sobrien else if (!e1->symbol) 6931130561Sobrien for (e2 = t->globals.remaining; e2 != NULL; e2 = e2->next) 6932218822Sdim if (strcmp (e1->pattern, e2->pattern) == 0 6933218822Sdim && e1->mask == e2->mask) 6934218822Sdim einfo (_("%X%P: duplicate expression `%s'" 6935218822Sdim " in version information\n"), e1->pattern); 693633965Sjdp } 693733965Sjdp } 693833965Sjdp 693933965Sjdp version->deps = deps; 694033965Sjdp version->name = name; 694189857Sobrien if (name[0] != '\0') 694289857Sobrien { 694389857Sobrien ++version_index; 694489857Sobrien version->vernum = version_index; 694589857Sobrien } 694689857Sobrien else 694789857Sobrien version->vernum = 0; 694833965Sjdp 694933965Sjdp for (pp = &lang_elf_version_info; *pp != NULL; pp = &(*pp)->next) 695033965Sjdp ; 695133965Sjdp *pp = version; 695233965Sjdp} 695333965Sjdp 695433965Sjdp/* This is called when we see a version dependency. */ 695533965Sjdp 695633965Sjdpstruct bfd_elf_version_deps * 6957130561Sobrienlang_add_vers_depend (struct bfd_elf_version_deps *list, const char *name) 695833965Sjdp{ 695933965Sjdp struct bfd_elf_version_deps *ret; 696033965Sjdp struct bfd_elf_version_tree *t; 696133965Sjdp 6962130561Sobrien ret = xmalloc (sizeof *ret); 696333965Sjdp ret->next = list; 696433965Sjdp 696533965Sjdp for (t = lang_elf_version_info; t != NULL; t = t->next) 696633965Sjdp { 696733965Sjdp if (strcmp (t->name, name) == 0) 696833965Sjdp { 696933965Sjdp ret->version_needed = t; 697033965Sjdp return ret; 697133965Sjdp } 697233965Sjdp } 697333965Sjdp 697460484Sobrien einfo (_("%X%P: unable to find version dependency `%s'\n"), name); 697533965Sjdp 697633965Sjdp return ret; 697733965Sjdp} 697860484Sobrien 697960484Sobrienstatic void 6980130561Sobrienlang_do_version_exports_section (void) 698160484Sobrien{ 698260484Sobrien struct bfd_elf_version_expr *greg = NULL, *lreg; 698360484Sobrien 698460484Sobrien LANG_FOR_EACH_INPUT_STATEMENT (is) 698560484Sobrien { 698660484Sobrien asection *sec = bfd_get_section_by_name (is->the_bfd, ".exports"); 698760484Sobrien char *contents, *p; 698860484Sobrien bfd_size_type len; 698960484Sobrien 699060484Sobrien if (sec == NULL) 6991104834Sobrien continue; 699260484Sobrien 6993218822Sdim len = sec->size; 699460484Sobrien contents = xmalloc (len); 699560484Sobrien if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len)) 699689857Sobrien einfo (_("%X%P: unable to read .exports section contents\n"), sec); 699760484Sobrien 699860484Sobrien p = contents; 699977298Sobrien while (p < contents + len) 700060484Sobrien { 7001218822Sdim greg = lang_new_vers_pattern (greg, p, NULL, FALSE); 700260484Sobrien p = strchr (p, '\0') + 1; 700360484Sobrien } 700460484Sobrien 700560484Sobrien /* Do not free the contents, as we used them creating the regex. */ 700660484Sobrien 700760484Sobrien /* Do not include this section in the link. */ 7008218822Sdim sec->flags |= SEC_EXCLUDE | SEC_KEEP; 700960484Sobrien } 701060484Sobrien 7011218822Sdim lreg = lang_new_vers_pattern (NULL, "*", NULL, FALSE); 701260484Sobrien lang_register_vers_node (command_line.version_exports_section, 701360484Sobrien lang_new_vers_node (greg, lreg), NULL); 701460484Sobrien} 701577298Sobrien 701677298Sobrienvoid 7017130561Sobrienlang_add_unique (const char *name) 701877298Sobrien{ 701977298Sobrien struct unique_sections *ent; 702077298Sobrien 702177298Sobrien for (ent = unique_section_list; ent; ent = ent->next) 702277298Sobrien if (strcmp (ent->name, name) == 0) 702377298Sobrien return; 702477298Sobrien 7025130561Sobrien ent = xmalloc (sizeof *ent); 702677298Sobrien ent->name = xstrdup (name); 702777298Sobrien ent->next = unique_section_list; 702877298Sobrien unique_section_list = ent; 702977298Sobrien} 7030218822Sdim 7031218822Sdim/* Append the list of dynamic symbols to the existing one. */ 7032218822Sdim 7033218822Sdimvoid 7034218822Sdimlang_append_dynamic_list (struct bfd_elf_version_expr *dynamic) 7035218822Sdim{ 7036218822Sdim if (link_info.dynamic_list) 7037218822Sdim { 7038218822Sdim struct bfd_elf_version_expr *tail; 7039218822Sdim for (tail = dynamic; tail->next != NULL; tail = tail->next) 7040218822Sdim ; 7041218822Sdim tail->next = link_info.dynamic_list->head.list; 7042218822Sdim link_info.dynamic_list->head.list = dynamic; 7043218822Sdim } 7044218822Sdim else 7045218822Sdim { 7046218822Sdim struct bfd_elf_dynamic_list *d; 7047218822Sdim 7048218822Sdim d = xcalloc (1, sizeof *d); 7049218822Sdim d->head.list = dynamic; 7050218822Sdim d->match = lang_vers_match; 7051218822Sdim link_info.dynamic_list = d; 7052218822Sdim } 7053218822Sdim} 7054218822Sdim 7055218822Sdim/* Append the list of C++ typeinfo dynamic symbols to the existing 7056218822Sdim one. */ 7057218822Sdim 7058218822Sdimvoid 7059218822Sdimlang_append_dynamic_list_cpp_typeinfo (void) 7060218822Sdim{ 7061218822Sdim const char * symbols [] = 7062218822Sdim { 7063218822Sdim "typeinfo name for*", 7064218822Sdim "typeinfo for*" 7065218822Sdim }; 7066218822Sdim struct bfd_elf_version_expr *dynamic = NULL; 7067218822Sdim unsigned int i; 7068218822Sdim 7069218822Sdim for (i = 0; i < ARRAY_SIZE (symbols); i++) 7070218822Sdim dynamic = lang_new_vers_pattern (dynamic, symbols [i], "C++", 7071218822Sdim FALSE); 7072218822Sdim 7073218822Sdim lang_append_dynamic_list (dynamic); 7074218822Sdim} 7075218822Sdim 7076218822Sdim/* Append the list of C++ operator new and delete dynamic symbols to the 7077218822Sdim existing one. */ 7078218822Sdim 7079218822Sdimvoid 7080218822Sdimlang_append_dynamic_list_cpp_new (void) 7081218822Sdim{ 7082218822Sdim const char * symbols [] = 7083218822Sdim { 7084218822Sdim "operator new*", 7085218822Sdim "operator delete*" 7086218822Sdim }; 7087218822Sdim struct bfd_elf_version_expr *dynamic = NULL; 7088218822Sdim unsigned int i; 7089218822Sdim 7090218822Sdim for (i = 0; i < ARRAY_SIZE (symbols); i++) 7091218822Sdim dynamic = lang_new_vers_pattern (dynamic, symbols [i], "C++", 7092218822Sdim FALSE); 7093218822Sdim 7094218822Sdim lang_append_dynamic_list (dynamic); 7095218822Sdim} 7096