00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "bfd.h"
00028 #include "sysdep.h"
00029 #include "libiberty.h"
00030 #include "safe-ctype.h"
00031 #include "obstack.h"
00032 #include "bfdlink.h"
00033
00034 #include "ld.h"
00035 #include "ldmain.h"
00036 #include "ldexp.h"
00037 #include "ldlang.h"
00038 #include <ldgram.h>
00039 #include "ldlex.h"
00040 #include "ldmisc.h"
00041 #include "ldctor.h"
00042 #include "ldfile.h"
00043 #include "ldemul.h"
00044 #include "fnmatch.h"
00045 #include "demangle.h"
00046 #include "hashtab.h"
00047
00048 #ifdef KEY
00049 #include "ipa_ld.h"
00050 #include "elf-bfd.h"
00051 #include "libbfd.h"
00052 #include "aout/ar.h"
00053 #ifdef OSP_OPT
00054 #include <fcntl.h>
00055 #endif
00056
00057 #if !defined(EF_IRIX_ABI64)
00058 #define EF_IRIX_ABI64 0x00000010
00059 #endif
00060 #endif
00061
00062 #ifndef offsetof
00063 #define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE*) 0)->MEMBER))
00064 #endif
00065
00066 #ifdef IPA_LINK
00067 extern bfd_boolean is_ipa;
00068
00069 extern bfd_boolean
00070 ipa_is_whirl(bfd *);
00071
00072 extern void
00073 ipa_process_whirl ( bfd *);
00074
00075 #ifdef KEY
00076 extern void (*p_Ipalink_ErrMsg_EC_outfile)(char *);
00077 #endif
00078 #endif
00079
00080
00081 static struct obstack stat_obstack;
00082 static struct obstack map_obstack;
00083
00084 #define obstack_chunk_alloc xmalloc
00085 #define obstack_chunk_free free
00086 static const char *startup_file;
00087 static lang_statement_list_type input_file_chain;
00088 static bfd_boolean placed_commons = FALSE;
00089 static lang_output_section_statement_type *default_common_section;
00090 static bfd_boolean map_option_f;
00091 static bfd_vma print_dot;
00092 static lang_input_statement_type *first_file;
00093 static const char *current_target;
00094 static const char *output_target;
00095 static lang_statement_list_type statement_list;
00096 static struct lang_phdr *lang_phdr_list;
00097 static struct bfd_hash_table lang_definedness_table;
00098
00099
00100 static void exp_init_os (etree_type *);
00101 static void init_map_userdata (bfd *, asection *, void *);
00102 static lang_input_statement_type *lookup_name (const char *);
00103 static bfd_boolean load_symbols (lang_input_statement_type *,
00104 lang_statement_list_type *);
00105 static struct bfd_hash_entry *lang_definedness_newfunc
00106 (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
00107 static void insert_undefined (const char *);
00108 static void print_all_symbols (asection *);
00109 static bfd_boolean sort_def_symbol (struct bfd_link_hash_entry *, void *);
00110 static void print_statement (lang_statement_union_type *,
00111 lang_output_section_statement_type *);
00112 static void print_statement_list (lang_statement_union_type *,
00113 lang_output_section_statement_type *);
00114 static void print_statements (void);
00115 static bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *);
00116 static void lang_record_phdrs (void);
00117 static void lang_do_version_exports_section (void);
00118
00119 typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
00120 asection *, lang_input_statement_type *, void *);
00121
00122
00123 lang_output_section_statement_type *abs_output_section;
00124 lang_statement_list_type lang_output_section_statement;
00125 lang_statement_list_type *stat_ptr = &statement_list;
00126 lang_statement_list_type file_chain = { NULL, NULL };
00127 struct bfd_sym_chain entry_symbol = { NULL, NULL };
00128 const char *entry_section = ".text";
00129 bfd_boolean entry_from_cmdline;
00130 bfd_boolean lang_has_input_file = FALSE;
00131 bfd_boolean had_output_filename = FALSE;
00132 bfd_boolean lang_float_flag = FALSE;
00133 bfd_boolean delete_output_file_on_failure = FALSE;
00134 struct lang_nocrossrefs *nocrossref_list;
00135 struct unique_sections *unique_section_list;
00136 static bfd_boolean ldlang_sysrooted_script = FALSE;
00137 int lang_statement_iteration = 0;
00138
00139 etree_type *base;
00140
00141
00142
00143
00144
00145
00146 #define wildcardp(pattern) (strpbrk ((pattern), "?*[") != NULL)
00147
00148 #define new_stat(x, y) \
00149 (x##_type *) new_statement (x##_enum, sizeof (x##_type), y)
00150
00151 #define outside_section_address(q) \
00152 ((q)->output_offset + (q)->output_section->vma)
00153
00154 #define outside_symbol_address(q) \
00155 ((q)->value + outside_section_address (q->section))
00156
00157 #define SECTION_NAME_MAP_LENGTH (16)
00158
00159 void *
00160 stat_alloc (size_t size)
00161 {
00162 return obstack_alloc (&stat_obstack, size);
00163 }
00164
00165 bfd_boolean
00166 unique_section_p (const asection *sec)
00167 {
00168 struct unique_sections *unam;
00169 const char *secnam;
00170
00171 if (link_info.relocatable
00172 && sec->owner != NULL
00173 && bfd_is_group_section (sec->owner, sec))
00174 return TRUE;
00175
00176 secnam = sec->name;
00177 for (unam = unique_section_list; unam; unam = unam->next)
00178 if (wildcardp (unam->name)
00179 ? fnmatch (unam->name, secnam, 0) == 0
00180 : strcmp (unam->name, secnam) == 0)
00181 {
00182 return TRUE;
00183 }
00184
00185 return FALSE;
00186 }
00187
00188
00189
00190 static void
00191 walk_wild_section (lang_wild_statement_type *ptr,
00192 lang_input_statement_type *file,
00193 callback_t callback,
00194 void *data)
00195 {
00196 asection *s;
00197
00198 if (file->just_syms_flag)
00199 return;
00200
00201 for (s = file->the_bfd->sections; s != NULL; s = s->next)
00202 {
00203 struct wildcard_list *sec;
00204
00205 sec = ptr->section_list;
00206 if (sec == NULL)
00207 (*callback) (ptr, sec, s, file, data);
00208
00209 while (sec != NULL)
00210 {
00211 bfd_boolean skip = FALSE;
00212 struct name_list *list_tmp;
00213
00214
00215
00216 for (list_tmp = sec->spec.exclude_name_list;
00217 list_tmp;
00218 list_tmp = list_tmp->next)
00219 {
00220 if (wildcardp (list_tmp->name))
00221 skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
00222 else
00223 skip = strcmp (list_tmp->name, file->filename) == 0;
00224
00225
00226
00227 if (! skip && file->the_bfd != NULL
00228 && file->the_bfd->my_archive != NULL
00229 && file->the_bfd->my_archive->filename != NULL)
00230 {
00231 if (wildcardp (list_tmp->name))
00232 skip = fnmatch (list_tmp->name,
00233 file->the_bfd->my_archive->filename,
00234 0) == 0;
00235 else
00236 skip = strcmp (list_tmp->name,
00237 file->the_bfd->my_archive->filename) == 0;
00238 }
00239
00240 if (skip)
00241 break;
00242 }
00243
00244 if (!skip && sec->spec.name != NULL)
00245 {
00246 const char *sname = bfd_get_section_name (file->the_bfd, s);
00247
00248 if (wildcardp (sec->spec.name))
00249 skip = fnmatch (sec->spec.name, sname, 0) != 0;
00250 else
00251 skip = strcmp (sec->spec.name, sname) != 0;
00252 }
00253
00254 if (!skip)
00255 (*callback) (ptr, sec, s, file, data);
00256
00257 sec = sec->next;
00258 }
00259 }
00260 }
00261
00262
00263
00264 static void
00265 walk_wild_file (lang_wild_statement_type *s,
00266 lang_input_statement_type *f,
00267 callback_t callback,
00268 void *data)
00269 {
00270 if (f->the_bfd == NULL
00271 || ! bfd_check_format (f->the_bfd, bfd_archive))
00272 walk_wild_section (s, f, callback, data);
00273 else
00274 {
00275 bfd *member;
00276
00277
00278
00279 member = bfd_openr_next_archived_file (f->the_bfd, NULL);
00280 while (member != NULL)
00281 {
00282
00283
00284
00285
00286
00287 if (member->usrdata != NULL)
00288 {
00289 walk_wild_section (s, member->usrdata, callback, data);
00290 }
00291
00292 member = bfd_openr_next_archived_file (f->the_bfd, member);
00293 }
00294 }
00295 }
00296
00297 static void
00298 walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
00299 {
00300 const char *file_spec = s->filename;
00301
00302 if (file_spec == NULL)
00303 {
00304
00305 LANG_FOR_EACH_INPUT_STATEMENT (f)
00306 {
00307 walk_wild_file (s, f, callback, data);
00308 }
00309 }
00310 else if (wildcardp (file_spec))
00311 {
00312 LANG_FOR_EACH_INPUT_STATEMENT (f)
00313 {
00314 if (fnmatch (file_spec, f->filename, FNM_FILE_NAME) == 0)
00315 walk_wild_file (s, f, callback, data);
00316 }
00317 }
00318 else
00319 {
00320 lang_input_statement_type *f;
00321
00322
00323 f = lookup_name (file_spec);
00324 if (f)
00325 walk_wild_file (s, f, callback, data);
00326 }
00327 }
00328
00329
00330
00331
00332 static void
00333 lang_for_each_statement_worker (void (*func) (lang_statement_union_type *),
00334 lang_statement_union_type *s)
00335 {
00336 for (; s != NULL; s = s->header.next)
00337 {
00338 func (s);
00339
00340 switch (s->header.type)
00341 {
00342 case lang_constructors_statement_enum:
00343 lang_for_each_statement_worker (func, constructor_list.head);
00344 break;
00345 case lang_output_section_statement_enum:
00346 lang_for_each_statement_worker
00347 (func, s->output_section_statement.children.head);
00348 break;
00349 case lang_wild_statement_enum:
00350 lang_for_each_statement_worker (func,
00351 s->wild_statement.children.head);
00352 break;
00353 case lang_group_statement_enum:
00354 lang_for_each_statement_worker (func,
00355 s->group_statement.children.head);
00356 break;
00357 case lang_data_statement_enum:
00358 case lang_reloc_statement_enum:
00359 case lang_object_symbols_statement_enum:
00360 case lang_output_statement_enum:
00361 case lang_target_statement_enum:
00362 case lang_input_section_enum:
00363 case lang_input_statement_enum:
00364 case lang_assignment_statement_enum:
00365 case lang_padding_statement_enum:
00366 case lang_address_statement_enum:
00367 case lang_fill_statement_enum:
00368 break;
00369 default:
00370 FAIL ();
00371 break;
00372 }
00373 }
00374 }
00375
00376 void
00377 lang_for_each_statement (void (*func) (lang_statement_union_type *))
00378 {
00379 lang_for_each_statement_worker (func, statement_list.head);
00380 }
00381
00382
00383
00384 void
00385 lang_list_init (lang_statement_list_type *list)
00386 {
00387 list->head = NULL;
00388 list->tail = &list->head;
00389 }
00390
00391
00392
00393 static lang_statement_union_type *
00394 new_statement (enum statement_enum type,
00395 size_t size,
00396 lang_statement_list_type *list)
00397 {
00398 lang_statement_union_type *new;
00399
00400 new = stat_alloc (size);
00401 new->header.type = type;
00402 new->header.next = NULL;
00403 lang_statement_append (list, new, &new->header.next);
00404 return new;
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 static lang_input_statement_type *
00417 new_afile (const char *name,
00418 lang_input_file_enum_type file_type,
00419 const char *target,
00420 bfd_boolean add_to_list)
00421 {
00422 lang_input_statement_type *p;
00423
00424 if (add_to_list)
00425 p = new_stat (lang_input_statement, stat_ptr);
00426 else
00427 {
00428 p = stat_alloc (sizeof (lang_input_statement_type));
00429 p->header.next = NULL;
00430 }
00431
00432 lang_has_input_file = TRUE;
00433 p->target = target;
00434 p->sysrooted = FALSE;
00435 switch (file_type)
00436 {
00437 case lang_input_file_is_symbols_only_enum:
00438 p->filename = name;
00439 p->is_archive = FALSE;
00440 p->real = TRUE;
00441 p->local_sym_name = name;
00442 p->just_syms_flag = TRUE;
00443 p->search_dirs_flag = FALSE;
00444 break;
00445 case lang_input_file_is_fake_enum:
00446 p->filename = name;
00447 p->is_archive = FALSE;
00448 p->real = FALSE;
00449 p->local_sym_name = name;
00450 p->just_syms_flag = FALSE;
00451 p->search_dirs_flag = FALSE;
00452 break;
00453 case lang_input_file_is_l_enum:
00454 p->is_archive = TRUE;
00455 p->filename = name;
00456 p->real = TRUE;
00457 p->local_sym_name = concat ("-l", name, NULL);
00458 p->just_syms_flag = FALSE;
00459 p->search_dirs_flag = TRUE;
00460 break;
00461 case lang_input_file_is_marker_enum:
00462 p->filename = name;
00463 p->is_archive = FALSE;
00464 p->real = FALSE;
00465 p->local_sym_name = name;
00466 p->just_syms_flag = FALSE;
00467 p->search_dirs_flag = TRUE;
00468 break;
00469 case lang_input_file_is_search_file_enum:
00470 p->sysrooted = ldlang_sysrooted_script;
00471 p->filename = name;
00472 p->is_archive = FALSE;
00473 p->real = TRUE;
00474 p->local_sym_name = name;
00475 p->just_syms_flag = FALSE;
00476 p->search_dirs_flag = TRUE;
00477 break;
00478 case lang_input_file_is_file_enum:
00479 p->filename = name;
00480 p->is_archive = FALSE;
00481 p->real = TRUE;
00482 p->local_sym_name = name;
00483 p->just_syms_flag = FALSE;
00484 p->search_dirs_flag = FALSE;
00485 break;
00486 default:
00487 FAIL ();
00488 }
00489 p->the_bfd = NULL;
00490 p->asymbols = NULL;
00491 p->next_real_file = NULL;
00492 p->next = NULL;
00493 p->symbol_count = 0;
00494 p->dynamic = config.dynamic_link;
00495 p->add_needed = add_needed;
00496 p->as_needed = as_needed;
00497 p->whole_archive = whole_archive;
00498 p->loaded = FALSE;
00499 lang_statement_append (&input_file_chain,
00500 (lang_statement_union_type *) p,
00501 &p->next_real_file);
00502 return p;
00503 }
00504
00505 lang_input_statement_type *
00506 lang_add_input_file (const char *name,
00507 lang_input_file_enum_type file_type,
00508 const char *target)
00509 {
00510 lang_has_input_file = TRUE;
00511 return new_afile (name, file_type, target, TRUE);
00512 }
00513
00514
00515
00516 void
00517 lang_init (void)
00518 {
00519 obstack_begin (&stat_obstack, 1000);
00520
00521 stat_ptr = &statement_list;
00522
00523 lang_list_init (stat_ptr);
00524
00525 lang_list_init (&input_file_chain);
00526 lang_list_init (&lang_output_section_statement);
00527 lang_list_init (&file_chain);
00528 first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum,
00529 NULL);
00530 abs_output_section =
00531 lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME);
00532
00533 abs_output_section->bfd_section = bfd_abs_section_ptr;
00534
00535
00536
00537
00538
00539
00540
00541 if (!bfd_hash_table_init_n (&lang_definedness_table,
00542 lang_definedness_newfunc, 3))
00543 einfo (_("%P%F: out of memory during initialization"));
00544
00545
00546 lang_statement_iteration = 0;
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 static lang_memory_region_type *lang_memory_region_list;
00566 static lang_memory_region_type **lang_memory_region_list_tail
00567 = &lang_memory_region_list;
00568
00569 lang_memory_region_type *
00570 lang_memory_region_lookup (const char *const name, bfd_boolean create)
00571 {
00572 lang_memory_region_type *p;
00573 lang_memory_region_type *new;
00574
00575
00576 if (name == NULL)
00577 return NULL;
00578
00579 for (p = lang_memory_region_list; p != NULL; p = p->next)
00580 if (strcmp (p->name, name) == 0)
00581 {
00582 if (create)
00583 einfo (_("%P:%S: warning: redeclaration of memory region '%s'\n"),
00584 name);
00585 return p;
00586 }
00587
00588 if (!create && strcmp (name, DEFAULT_MEMORY_REGION))
00589 einfo (_("%P:%S: warning: memory region %s not declared\n"), name);
00590
00591 new = stat_alloc (sizeof (lang_memory_region_type));
00592
00593 new->name = xstrdup (name);
00594 new->next = NULL;
00595
00596 *lang_memory_region_list_tail = new;
00597 lang_memory_region_list_tail = &new->next;
00598 new->origin = 0;
00599 new->flags = 0;
00600 new->not_flags = 0;
00601 new->length = ~(bfd_size_type) 0;
00602 new->current = 0;
00603 new->had_full_message = FALSE;
00604
00605 return new;
00606 }
00607
00608 static lang_memory_region_type *
00609 lang_memory_default (asection *section)
00610 {
00611 lang_memory_region_type *p;
00612
00613 flagword sec_flags = section->flags;
00614
00615
00616 if ((sec_flags & (SEC_ALLOC | SEC_READONLY | SEC_CODE)) == SEC_ALLOC)
00617 sec_flags |= SEC_DATA;
00618
00619 for (p = lang_memory_region_list; p != NULL; p = p->next)
00620 {
00621 if ((p->flags & sec_flags) != 0
00622 && (p->not_flags & sec_flags) == 0)
00623 {
00624 return p;
00625 }
00626 }
00627 return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE);
00628 }
00629
00630 static lang_output_section_statement_type *
00631 lang_output_section_find_1 (const char *const name, int constraint)
00632 {
00633 lang_output_section_statement_type *lookup;
00634
00635 for (lookup = &lang_output_section_statement.head->output_section_statement;
00636 lookup != NULL;
00637 lookup = lookup->next)
00638 {
00639 if (strcmp (name, lookup->name) == 0
00640 && lookup->constraint != -1
00641 && (constraint == 0 || constraint == lookup->constraint))
00642 return lookup;
00643 }
00644 return NULL;
00645 }
00646
00647 lang_output_section_statement_type *
00648 lang_output_section_find (const char *const name)
00649 {
00650 return lang_output_section_find_1 (name, 0);
00651 }
00652
00653 static lang_output_section_statement_type *
00654 lang_output_section_statement_lookup_1 (const char *const name, int constraint)
00655 {
00656 lang_output_section_statement_type *lookup;
00657
00658 lookup = lang_output_section_find_1 (name, constraint);
00659 if (lookup == NULL)
00660 {
00661 lookup = new_stat (lang_output_section_statement, stat_ptr);
00662 lookup->region = NULL;
00663 lookup->lma_region = NULL;
00664 lookup->fill = 0;
00665 lookup->block_value = 1;
00666 lookup->name = name;
00667
00668 lookup->next = NULL;
00669 lookup->bfd_section = NULL;
00670 lookup->processed = 0;
00671 lookup->constraint = constraint;
00672 lookup->sectype = normal_section;
00673 lookup->addr_tree = NULL;
00674 lang_list_init (&lookup->children);
00675
00676 lookup->memspec = NULL;
00677 lookup->flags = 0;
00678 lookup->subsection_alignment = -1;
00679 lookup->section_alignment = -1;
00680 lookup->load_base = NULL;
00681 lookup->update_dot_tree = NULL;
00682 lookup->phdrs = NULL;
00683
00684 lang_statement_append (&lang_output_section_statement,
00685 (lang_statement_union_type *) lookup,
00686 (lang_statement_union_type **) &lookup->next);
00687 }
00688 return lookup;
00689 }
00690
00691 lang_output_section_statement_type *
00692 lang_output_section_statement_lookup (const char *const name)
00693 {
00694 return lang_output_section_statement_lookup_1 (name, 0);
00695 }
00696
00697
00698
00699
00700
00701
00702 lang_output_section_statement_type *
00703 lang_output_section_find_by_flags (const asection *sec,
00704 lang_output_section_statement_type **exact)
00705 {
00706 lang_output_section_statement_type *first, *look, *found;
00707 flagword flags;
00708
00709
00710
00711 first = &lang_output_section_statement.head->output_section_statement;
00712 first = first->next;
00713
00714
00715 found = NULL;
00716 for (look = first; look; look = look->next)
00717 {
00718 flags = look->flags;
00719 if (look->bfd_section != NULL)
00720 flags = look->bfd_section->flags;
00721 flags ^= sec->flags;
00722 if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY
00723 | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
00724 found = look;
00725 }
00726 if (found != NULL)
00727 {
00728 *exact = found;
00729 return found;
00730 }
00731
00732 if (sec->flags & SEC_CODE)
00733 {
00734
00735 for (look = first; look; look = look->next)
00736 {
00737 flags = look->flags;
00738 if (look->bfd_section != NULL)
00739 flags = look->bfd_section->flags;
00740 flags ^= sec->flags;
00741 if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
00742 | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
00743 found = look;
00744 }
00745 return found;
00746 }
00747
00748 if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
00749 {
00750
00751 for (look = first; look; look = look->next)
00752 {
00753 flags = look->flags;
00754 if (look->bfd_section != NULL)
00755 flags = look->bfd_section->flags;
00756 flags ^= sec->flags;
00757 if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
00758 | SEC_READONLY))
00759 && !(look->flags & (SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
00760 found = look;
00761 }
00762 return found;
00763 }
00764
00765 if (sec->flags & SEC_SMALL_DATA)
00766 {
00767
00768 for (look = first; look; look = look->next)
00769 {
00770 flags = look->flags;
00771 if (look->bfd_section != NULL)
00772 flags = look->bfd_section->flags;
00773 flags ^= sec->flags;
00774 if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
00775 | SEC_THREAD_LOCAL))
00776 || ((look->flags & SEC_SMALL_DATA)
00777 && !(sec->flags & SEC_HAS_CONTENTS)))
00778 found = look;
00779 }
00780 return found;
00781 }
00782
00783 if (sec->flags & SEC_HAS_CONTENTS)
00784 {
00785
00786 for (look = first; look; look = look->next)
00787 {
00788 flags = look->flags;
00789 if (look->bfd_section != NULL)
00790 flags = look->bfd_section->flags;
00791 flags ^= sec->flags;
00792 if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
00793 | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
00794 found = look;
00795 }
00796 return found;
00797 }
00798
00799
00800 for (look = first; look; look = look->next)
00801 {
00802 flags = look->flags;
00803 if (look->bfd_section != NULL)
00804 flags = look->bfd_section->flags;
00805 flags ^= sec->flags;
00806 if (!(flags & SEC_ALLOC))
00807 found = look;
00808 }
00809
00810 return found;
00811 }
00812
00813
00814
00815
00816 static asection *
00817 output_prev_sec_find (lang_output_section_statement_type *os)
00818 {
00819 asection *s = (asection *) NULL;
00820 lang_output_section_statement_type *lookup;
00821
00822 for (lookup = &lang_output_section_statement.head->output_section_statement;
00823 lookup != NULL;
00824 lookup = lookup->next)
00825 {
00826 if (lookup->constraint == -1)
00827 continue;
00828 if (lookup == os)
00829 return s;
00830
00831 if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL)
00832 s = lookup->bfd_section;
00833 }
00834
00835 return NULL;
00836 }
00837
00838 lang_output_section_statement_type *
00839 lang_insert_orphan (lang_input_statement_type *file,
00840 asection *s,
00841 const char *secname,
00842 lang_output_section_statement_type *after,
00843 struct orphan_save *place,
00844 etree_type *address,
00845 lang_statement_list_type *add_child)
00846 {
00847 lang_statement_list_type *old;
00848 lang_statement_list_type add;
00849 const char *ps;
00850 etree_type *load_base;
00851 lang_output_section_statement_type *os;
00852 lang_output_section_statement_type **os_tail;
00853
00854
00855
00856 old = stat_ptr;
00857
00858
00859
00860
00861 if (after != NULL)
00862 {
00863 stat_ptr = &add;
00864 lang_list_init (stat_ptr);
00865 }
00866
00867 ps = NULL;
00868 if (config.build_constructors)
00869 {
00870
00871
00872 for (ps = secname; *ps != '\0'; ps++)
00873 if (! ISALNUM ((unsigned char) *ps) && *ps != '_')
00874 break;
00875 if (*ps == '\0')
00876 {
00877 char *symname;
00878 etree_type *e_align;
00879
00880 symname = (char *) xmalloc (ps - secname + sizeof "__start_" + 1);
00881 symname[0] = bfd_get_symbol_leading_char (output_bfd);
00882 sprintf (symname + (symname[0] != 0), "__start_%s", secname);
00883 e_align = exp_unop (ALIGN_K,
00884 exp_intop ((bfd_vma) 1 << s->alignment_power));
00885 lang_add_assignment (exp_assop ('=', ".", e_align));
00886 lang_add_assignment (exp_assop ('=', symname,
00887 exp_nameop (NAME, ".")));
00888 }
00889 }
00890
00891 if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
00892 address = exp_intop (0);
00893
00894 load_base = NULL;
00895 if (after != NULL && after->load_base != NULL)
00896 {
00897 etree_type *lma_from_vma;
00898 lma_from_vma = exp_binop ('-', after->load_base,
00899 exp_nameop (ADDR, after->name));
00900 load_base = exp_binop ('+', lma_from_vma,
00901 exp_nameop (ADDR, secname));
00902 }
00903
00904 os_tail = ((lang_output_section_statement_type **)
00905 lang_output_section_statement.tail);
00906 os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
00907 load_base, 0);
00908
00909 if (add_child == NULL)
00910 add_child = &os->children;
00911 lang_add_section (add_child, s, os, file);
00912
00913 lang_leave_output_section_statement (0, "*default*", NULL, NULL);
00914
00915 if (config.build_constructors && *ps == '\0')
00916 {
00917 char *symname;
00918
00919
00920
00921 if (after != NULL)
00922 stat_ptr = &add;
00923
00924 symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1);
00925 symname[0] = bfd_get_symbol_leading_char (output_bfd);
00926 sprintf (symname + (symname[0] != 0), "__stop_%s", secname);
00927 lang_add_assignment (exp_assop ('=', symname,
00928 exp_nameop (NAME, ".")));
00929 }
00930
00931
00932 if (after != NULL)
00933 stat_ptr = old;
00934
00935 if (after != NULL && os->bfd_section != NULL)
00936 {
00937 asection *snew, **pps;
00938
00939 snew = os->bfd_section;
00940
00941
00942
00943 if (place->section == NULL
00944 && after != (&lang_output_section_statement.head
00945 ->output_section_statement))
00946 {
00947 asection *bfd_section = after->bfd_section;
00948
00949
00950
00951
00952
00953 if (bfd_section == NULL)
00954 bfd_section = output_prev_sec_find (after);
00955
00956 if (bfd_section != NULL && bfd_section != snew)
00957 place->section = &bfd_section->next;
00958 }
00959
00960 if (place->section == NULL)
00961 place->section = &output_bfd->sections;
00962
00963
00964 for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
00965 continue;
00966 bfd_section_list_remove (output_bfd, pps);
00967
00968
00969 bfd_section_list_insert (output_bfd, place->section, snew);
00970
00971
00972
00973 place->section = &snew->next;
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 if (add.head != NULL)
00985 {
00986 lang_output_section_statement_type *newly_added_os;
00987
00988 if (place->stmt == NULL)
00989 {
00990 lang_statement_union_type **where;
00991 lang_statement_union_type **assign = NULL;
00992
00993
00994
00995
00996
00997
00998
00999 for (where = &after->header.next;
01000 *where != NULL;
01001 where = &(*where)->header.next)
01002 {
01003 switch ((*where)->header.type)
01004 {
01005 case lang_assignment_statement_enum:
01006 if (assign == NULL)
01007 {
01008 lang_assignment_statement_type *ass;
01009 ass = &(*where)->assignment_statement;
01010 if (ass->exp->type.node_class != etree_assert
01011 && ass->exp->assign.dst[0] == '.'
01012 && ass->exp->assign.dst[1] == 0)
01013 assign = where;
01014 }
01015 continue;
01016 case lang_wild_statement_enum:
01017 case lang_input_section_enum:
01018 case lang_object_symbols_statement_enum:
01019 case lang_fill_statement_enum:
01020 case lang_data_statement_enum:
01021 case lang_reloc_statement_enum:
01022 case lang_padding_statement_enum:
01023 case lang_constructors_statement_enum:
01024 assign = NULL;
01025 continue;
01026 case lang_output_section_statement_enum:
01027 if (assign != NULL)
01028 where = assign;
01029 case lang_input_statement_enum:
01030 case lang_address_statement_enum:
01031 case lang_target_statement_enum:
01032 case lang_output_statement_enum:
01033 case lang_group_statement_enum:
01034 case lang_afile_asection_pair_statement_enum:
01035 break;
01036 }
01037 break;
01038 }
01039
01040 *add.tail = *where;
01041 *where = add.head;
01042
01043 place->os_tail = &after->next;
01044 }
01045 else
01046 {
01047
01048 *add.tail = *place->stmt;
01049 *place->stmt = add.head;
01050 }
01051
01052
01053
01054 if (*old->tail == add.head)
01055 old->tail = add.tail;
01056
01057
01058 place->stmt = add.tail;
01059
01060
01061 newly_added_os = *os_tail;
01062 *os_tail = NULL;
01063 newly_added_os->next = *place->os_tail;
01064 *place->os_tail = newly_added_os;
01065 place->os_tail = &newly_added_os->next;
01066
01067
01068
01069
01070
01071
01072 if (*os_tail == NULL)
01073 lang_output_section_statement.tail
01074 = (lang_statement_union_type **) os_tail;
01075 }
01076 }
01077 return os;
01078 }
01079
01080 static void
01081 lang_map_flags (flagword flag)
01082 {
01083 if (flag & SEC_ALLOC)
01084 minfo ("a");
01085
01086 if (flag & SEC_CODE)
01087 minfo ("x");
01088
01089 if (flag & SEC_READONLY)
01090 minfo ("r");
01091
01092 if (flag & SEC_DATA)
01093 minfo ("w");
01094
01095 if (flag & SEC_LOAD)
01096 minfo ("l");
01097 }
01098
01099 void
01100 lang_map (void)
01101 {
01102 lang_memory_region_type *m;
01103 bfd *p;
01104
01105 minfo (_("\nMemory Configuration\n\n"));
01106 fprintf (config.map_file, "%-16s %-18s %-18s %s\n",
01107 _("Name"), _("Origin"), _("Length"), _("Attributes"));
01108
01109 for (m = lang_memory_region_list; m != NULL; m = m->next)
01110 {
01111 char buf[100];
01112 int len;
01113
01114 fprintf (config.map_file, "%-16s ", m->name);
01115
01116 sprintf_vma (buf, m->origin);
01117 minfo ("0x%s ", buf);
01118 len = strlen (buf);
01119 while (len < 16)
01120 {
01121 print_space ();
01122 ++len;
01123 }
01124
01125 minfo ("0x%V", m->length);
01126 if (m->flags || m->not_flags)
01127 {
01128 #ifndef BFD64
01129 minfo (" ");
01130 #endif
01131 if (m->flags)
01132 {
01133 print_space ();
01134 lang_map_flags (m->flags);
01135 }
01136
01137 if (m->not_flags)
01138 {
01139 minfo (" !");
01140 lang_map_flags (m->not_flags);
01141 }
01142 }
01143
01144 print_nl ();
01145 }
01146
01147 fprintf (config.map_file, _("\nLinker script and memory map\n\n"));
01148
01149 if (! command_line.reduce_memory_overheads)
01150 {
01151 obstack_begin (&map_obstack, 1000);
01152 for (p = link_info.input_bfds; p != (bfd *) NULL; p = p->link_next)
01153 bfd_map_over_sections (p, init_map_userdata, 0);
01154 bfd_link_hash_traverse (link_info.hash, sort_def_symbol, 0);
01155 }
01156 print_statements ();
01157 }
01158
01159 static void
01160 init_map_userdata (abfd, sec, data)
01161 bfd *abfd ATTRIBUTE_UNUSED;
01162 asection *sec;
01163 void *data ATTRIBUTE_UNUSED;
01164 {
01165 fat_section_userdata_type *new_data
01166 = ((fat_section_userdata_type *) (stat_alloc
01167 (sizeof (fat_section_userdata_type))));
01168
01169 ASSERT (get_userdata (sec) == NULL);
01170 get_userdata (sec) = new_data;
01171 new_data->map_symbol_def_tail = &new_data->map_symbol_def_head;
01172 }
01173
01174 static bfd_boolean
01175 sort_def_symbol (hash_entry, info)
01176 struct bfd_link_hash_entry *hash_entry;
01177 void *info ATTRIBUTE_UNUSED;
01178 {
01179 if (hash_entry->type == bfd_link_hash_defined
01180 || hash_entry->type == bfd_link_hash_defweak)
01181 {
01182 struct fat_user_section_struct *ud;
01183 struct map_symbol_def *def;
01184
01185 ud = get_userdata (hash_entry->u.def.section);
01186 if (! ud)
01187 {
01188
01189
01190 init_map_userdata (0, hash_entry->u.def.section, 0);
01191 ud = get_userdata (hash_entry->u.def.section);
01192 }
01193 else if (!ud->map_symbol_def_tail)
01194 ud->map_symbol_def_tail = &ud->map_symbol_def_head;
01195
01196 def = obstack_alloc (&map_obstack, sizeof *def);
01197 def->entry = hash_entry;
01198 *(ud->map_symbol_def_tail) = def;
01199 ud->map_symbol_def_tail = &def->next;
01200 }
01201 return TRUE;
01202 }
01203
01204
01205
01206 static void
01207 init_os (lang_output_section_statement_type *s)
01208 {
01209 lean_section_userdata_type *new;
01210
01211 if (s->bfd_section != NULL)
01212 return;
01213
01214 if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
01215 einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
01216
01217 new = stat_alloc (SECTION_USERDATA_SIZE);
01218 memset (new, 0, SECTION_USERDATA_SIZE);
01219
01220 s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
01221 if (s->bfd_section == NULL)
01222 s->bfd_section = bfd_make_section (output_bfd, s->name);
01223 if (s->bfd_section == NULL)
01224 {
01225 einfo (_("%P%F: output format %s cannot represent section called %s\n"),
01226 output_bfd->xvec->name, s->name);
01227 }
01228 s->bfd_section->output_section = s->bfd_section;
01229
01230
01231
01232 s->bfd_section->output_offset = 0;
01233 get_userdata (s->bfd_section) = new;
01234
01235
01236
01237 if (s->addr_tree != NULL)
01238 exp_init_os (s->addr_tree);
01239
01240 if (s->load_base != NULL)
01241 exp_init_os (s->load_base);
01242 }
01243
01244
01245
01246
01247 static void
01248 exp_init_os (etree_type *exp)
01249 {
01250 switch (exp->type.node_class)
01251 {
01252 case etree_assign:
01253 exp_init_os (exp->assign.src);
01254 break;
01255
01256 case etree_binary:
01257 exp_init_os (exp->binary.lhs);
01258 exp_init_os (exp->binary.rhs);
01259 break;
01260
01261 case etree_trinary:
01262 exp_init_os (exp->trinary.cond);
01263 exp_init_os (exp->trinary.lhs);
01264 exp_init_os (exp->trinary.rhs);
01265 break;
01266
01267 case etree_assert:
01268 exp_init_os (exp->assert_s.child);
01269 break;
01270
01271 case etree_unary:
01272 exp_init_os (exp->unary.child);
01273 break;
01274
01275 case etree_name:
01276 switch (exp->type.node_code)
01277 {
01278 case ADDR:
01279 case LOADADDR:
01280 case SIZEOF:
01281 {
01282 lang_output_section_statement_type *os;
01283
01284 os = lang_output_section_find (exp->name.name);
01285 if (os != NULL && os->bfd_section == NULL)
01286 init_os (os);
01287 }
01288 }
01289 break;
01290
01291 default:
01292 break;
01293 }
01294 }
01295
01296 static void
01297 section_already_linked (bfd *abfd, asection *sec, void *data)
01298 {
01299 lang_input_statement_type *entry = data;
01300
01301
01302
01303 if (entry->just_syms_flag)
01304 {
01305 bfd_link_just_syms (abfd, sec, &link_info);
01306 return;
01307 }
01308
01309 if (!(abfd->flags & DYNAMIC))
01310 bfd_section_already_linked (abfd, sec);
01311 }
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323 void
01324 lang_add_section (lang_statement_list_type *ptr,
01325 asection *section,
01326 lang_output_section_statement_type *output,
01327 lang_input_statement_type *file)
01328 {
01329 flagword flags = section->flags;
01330 bfd_boolean discard;
01331
01332
01333 discard = (flags & SEC_EXCLUDE) != 0;
01334
01335
01336
01337 if (strcmp (output->name, DISCARD_SECTION_NAME) == 0)
01338 discard = TRUE;
01339
01340
01341
01342 if ((link_info.strip == strip_debugger || link_info.strip == strip_all)
01343 && (flags & SEC_DEBUGGING) != 0)
01344 discard = TRUE;
01345
01346 if (discard)
01347 {
01348 if (section->output_section == NULL)
01349 {
01350
01351 section->output_section = bfd_abs_section_ptr;
01352 }
01353 return;
01354 }
01355
01356 if (section->output_section == NULL)
01357 {
01358 bfd_boolean first;
01359 lang_input_section_type *new;
01360 flagword flags;
01361
01362 if (output->bfd_section == NULL)
01363 init_os (output);
01364
01365 first = ! output->bfd_section->linker_has_input;
01366 output->bfd_section->linker_has_input = 1;
01367
01368
01369 new = new_stat (lang_input_section, ptr);
01370
01371 new->section = section;
01372 new->ifile = file;
01373 section->output_section = output->bfd_section;
01374
01375 flags = section->flags;
01376
01377
01378
01379
01380
01381
01382
01383
01384 flags &= ~ SEC_NEVER_LOAD;
01385
01386
01387
01388
01389
01390
01391 if (! link_info.relocatable)
01392 flags &= ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES);
01393
01394
01395
01396
01397
01398 if (! first && (output->bfd_section->flags & SEC_READONLY) == 0)
01399 flags &= ~ SEC_READONLY;
01400
01401
01402 if (! first
01403 && ((output->bfd_section->flags & (SEC_MERGE | SEC_STRINGS))
01404 != (flags & (SEC_MERGE | SEC_STRINGS))
01405 || ((flags & SEC_MERGE)
01406 && output->bfd_section->entsize != section->entsize)))
01407 {
01408 output->bfd_section->flags &= ~ (SEC_MERGE | SEC_STRINGS);
01409 flags &= ~ (SEC_MERGE | SEC_STRINGS);
01410 }
01411
01412 output->bfd_section->flags |= flags;
01413
01414 if (flags & SEC_MERGE)
01415 output->bfd_section->entsize = section->entsize;
01416
01417
01418
01419 if ((section->flags & SEC_READONLY) == 0)
01420 output->bfd_section->flags &= ~SEC_READONLY;
01421
01422 switch (output->sectype)
01423 {
01424 case normal_section:
01425 break;
01426 case dsect_section:
01427 case copy_section:
01428 case info_section:
01429 case overlay_section:
01430 output->bfd_section->flags &= ~SEC_ALLOC;
01431 break;
01432 case noload_section:
01433 output->bfd_section->flags &= ~SEC_LOAD;
01434 output->bfd_section->flags |= SEC_NEVER_LOAD;
01435 break;
01436 }
01437
01438
01439 if (section->flags & SEC_SMALL_DATA)
01440 output->bfd_section->flags |= SEC_SMALL_DATA;
01441
01442 if (section->alignment_power > output->bfd_section->alignment_power)
01443 output->bfd_section->alignment_power = section->alignment_power;
01444
01445
01446 if (output->section_alignment != -1)
01447 output->bfd_section->alignment_power = output->section_alignment;
01448
01449 if (bfd_get_arch (section->owner) == bfd_arch_tic54x
01450 && (section->flags & SEC_TIC54X_BLOCK) != 0)
01451 {
01452 output->bfd_section->flags |= SEC_TIC54X_BLOCK;
01453
01454 output->block_value = 128;
01455 }
01456 }
01457 }
01458
01459
01460
01461 static int
01462 compare_section (sort_type sort, asection *asec, asection *bsec)
01463 {
01464 int ret;
01465
01466 switch (sort)
01467 {
01468 default:
01469 abort ();
01470
01471 case by_alignment_name:
01472 ret = (bfd_section_alignment (bsec->owner, bsec)
01473 - bfd_section_alignment (asec->owner, asec));
01474 if (ret)
01475 break;
01476
01477
01478 case by_name:
01479 ret = strcmp (bfd_get_section_name (asec->owner, asec),
01480 bfd_get_section_name (bsec->owner, bsec));
01481 break;
01482
01483 case by_name_alignment:
01484 ret = strcmp (bfd_get_section_name (asec->owner, asec),
01485 bfd_get_section_name (bsec->owner, bsec));
01486 if (ret)
01487 break;
01488
01489
01490 case by_alignment:
01491 ret = (bfd_section_alignment (bsec->owner, bsec)
01492 - bfd_section_alignment (asec->owner, asec));
01493 break;
01494 }
01495
01496 return ret;
01497 }
01498
01499
01500
01501
01502
01503
01504 static lang_statement_union_type *
01505 wild_sort (lang_wild_statement_type *wild,
01506 struct wildcard_list *sec,
01507 lang_input_statement_type *file,
01508 asection *section)
01509 {
01510 const char *section_name;
01511 lang_statement_union_type *l;
01512
01513 if (!wild->filenames_sorted
01514 && (sec == NULL || sec->spec.sorted == none))
01515 return NULL;
01516
01517 section_name = bfd_get_section_name (file->the_bfd, section);
01518 for (l = wild->children.head; l != NULL; l = l->header.next)
01519 {
01520 lang_input_section_type *ls;
01521
01522 if (l->header.type != lang_input_section_enum)
01523 continue;
01524 ls = &l->input_section;
01525
01526
01527
01528
01529 if (wild->filenames_sorted)
01530 {
01531 const char *fn, *ln;
01532 bfd_boolean fa, la;
01533 int i;
01534
01535
01536
01537
01538
01539
01540 if (file->the_bfd != NULL
01541 && bfd_my_archive (file->the_bfd) != NULL)
01542 {
01543 fn = bfd_get_filename (bfd_my_archive (file->the_bfd));
01544 fa = TRUE;
01545 }
01546 else
01547 {
01548 fn = file->filename;
01549 fa = FALSE;
01550 }
01551
01552 if (ls->ifile->the_bfd != NULL
01553 && bfd_my_archive (ls->ifile->the_bfd) != NULL)
01554 {
01555 ln = bfd_get_filename (bfd_my_archive (ls->ifile->the_bfd));
01556 la = TRUE;
01557 }
01558 else
01559 {
01560 ln = ls->ifile->filename;
01561 la = FALSE;
01562 }
01563
01564 i = strcmp (fn, ln);
01565 if (i > 0)
01566 continue;
01567 else if (i < 0)
01568 break;
01569
01570 if (fa || la)
01571 {
01572 if (fa)
01573 fn = file->filename;
01574 if (la)
01575 ln = ls->ifile->filename;
01576
01577 i = strcmp (fn, ln);
01578 if (i > 0)
01579 continue;
01580 else if (i < 0)
01581 break;
01582 }
01583 }
01584
01585
01586
01587
01588 if (sec != NULL && sec->spec.sorted != none)
01589 {
01590 if (compare_section (sec->spec.sorted, section,
01591 ls->section) < 0)
01592 break;
01593 }
01594 }
01595
01596 return l;
01597 }
01598
01599
01600
01601
01602 static void
01603 output_section_callback (lang_wild_statement_type *ptr,
01604 struct wildcard_list *sec,
01605 asection *section,
01606 lang_input_statement_type *file,
01607 void *output)
01608 {
01609 lang_statement_union_type *before;
01610
01611
01612 if (unique_section_p (section))
01613 return;
01614
01615 before = wild_sort (ptr, sec, file, section);
01616
01617
01618
01619
01620
01621
01622 if (before == NULL)
01623 lang_add_section (&ptr->children, section,
01624 (lang_output_section_statement_type *) output,
01625 file);
01626 else
01627 {
01628 lang_statement_list_type list;
01629 lang_statement_union_type **pp;
01630
01631 lang_list_init (&list);
01632 lang_add_section (&list, section,
01633 (lang_output_section_statement_type *) output,
01634 file);
01635
01636
01637
01638 if (list.head != NULL)
01639 {
01640 ASSERT (list.head->header.next == NULL);
01641
01642 for (pp = &ptr->children.head;
01643 *pp != before;
01644 pp = &(*pp)->header.next)
01645 ASSERT (*pp != NULL);
01646
01647 list.head->header.next = *pp;
01648 *pp = list.head;
01649 }
01650 }
01651 }
01652
01653
01654
01655
01656 static void
01657 check_section_callback (lang_wild_statement_type *ptr ATTRIBUTE_UNUSED,
01658 struct wildcard_list *sec ATTRIBUTE_UNUSED,
01659 asection *section,
01660 lang_input_statement_type *file ATTRIBUTE_UNUSED,
01661 void *data)
01662 {
01663
01664 if (unique_section_p (section))
01665 return;
01666
01667 if (section->output_section == NULL && (section->flags & SEC_READONLY) == 0)
01668 ((lang_output_section_statement_type *) data)->all_input_readonly = FALSE;
01669 }
01670
01671
01672
01673
01674
01675 static lang_input_statement_type *
01676 lookup_name (const char *name)
01677 {
01678 lang_input_statement_type *search;
01679
01680 for (search = (lang_input_statement_type *) input_file_chain.head;
01681 search != NULL;
01682 search = (lang_input_statement_type *) search->next_real_file)
01683 {
01684
01685
01686
01687 const char * filename = search->local_sym_name;
01688
01689 if (filename == NULL && name == NULL)
01690 return search;
01691 if (filename != NULL
01692 && name != NULL
01693 && strcmp (filename, name) == 0)
01694 break;
01695 }
01696
01697 if (search == NULL)
01698 search = new_afile (name, lang_input_file_is_search_file_enum,
01699 default_target, FALSE);
01700
01701
01702
01703
01704 if (search->loaded
01705 || ! search->real
01706 || search->filename == NULL)
01707 return search;
01708
01709 if (! load_symbols (search, NULL))
01710 return NULL;
01711
01712 return search;
01713 }
01714
01715
01716
01717 struct excluded_lib
01718 {
01719 char *name;
01720 struct excluded_lib *next;
01721 };
01722 static struct excluded_lib *excluded_libs;
01723
01724 void
01725 add_excluded_libs (const char *list)
01726 {
01727 const char *p = list, *end;
01728
01729 while (*p != '\0')
01730 {
01731 struct excluded_lib *entry;
01732 end = strpbrk (p, ",:");
01733 if (end == NULL)
01734 end = p + strlen (p);
01735 entry = xmalloc (sizeof (*entry));
01736 entry->next = excluded_libs;
01737 entry->name = xmalloc (end - p + 1);
01738 memcpy (entry->name, p, end - p);
01739 entry->name[end - p] = '\0';
01740 excluded_libs = entry;
01741 if (*end == '\0')
01742 break;
01743 p = end + 1;
01744 }
01745 }
01746
01747 static void
01748 check_excluded_libs (bfd *abfd)
01749 {
01750 struct excluded_lib *lib = excluded_libs;
01751
01752 while (lib)
01753 {
01754 int len = strlen (lib->name);
01755 const char *filename = lbasename (abfd->filename);
01756
01757 if (strcmp (lib->name, "ALL") == 0)
01758 {
01759 abfd->no_export = TRUE;
01760 return;
01761 }
01762
01763 if (strncmp (lib->name, filename, len) == 0
01764 && (filename[len] == '\0'
01765 || (filename[len] == '.' && filename[len + 1] == 'a'
01766 && filename[len + 2] == '\0')))
01767 {
01768 abfd->no_export = TRUE;
01769 return;
01770 }
01771
01772 lib = lib->next;
01773 }
01774 }
01775
01776
01777
01778 static bfd_boolean
01779 load_symbols (lang_input_statement_type *entry,
01780 lang_statement_list_type *place)
01781 {
01782 char **matching;
01783
01784
01785 #ifdef KEY
01786 char *archive_lname;
01787 char *archive_fname;
01788 #endif
01789 if (entry->loaded)
01790 return TRUE;
01791
01792 archive_lname = (char*)xmalloc(strlen(entry->filename)+3);
01793 sprintf(archive_lname, "-l%s", entry->filename);
01794 ldfile_open_file (entry);
01795
01796 if (! bfd_check_format (entry->the_bfd, bfd_archive)
01797 && ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching))
01798 {
01799 bfd_error_type err;
01800 lang_statement_list_type *hold;
01801 bfd_boolean bad_load = TRUE;
01802 bfd_boolean save_ldlang_sysrooted_script;
01803
01804 err = bfd_get_error ();
01805
01806
01807 if (ldemul_unrecognized_file (entry))
01808 return TRUE;
01809
01810 if (err == bfd_error_file_ambiguously_recognized)
01811 {
01812 char **p;
01813
01814 einfo (_("%B: file not recognized: %E\n"), entry->the_bfd);
01815 einfo (_("%B: matching formats:"), entry->the_bfd);
01816 for (p = matching; *p != NULL; p++)
01817 einfo (" %s", *p);
01818 einfo ("%F\n");
01819 }
01820 else if (err != bfd_error_file_not_recognized
01821 || place == NULL)
01822 einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd);
01823 else
01824 bad_load = FALSE;
01825
01826 bfd_close (entry->the_bfd);
01827 entry->the_bfd = NULL;
01828
01829
01830 ldfile_open_command_file (entry->filename);
01831
01832 hold = stat_ptr;
01833 stat_ptr = place;
01834 save_ldlang_sysrooted_script = ldlang_sysrooted_script;
01835 ldlang_sysrooted_script = entry->sysrooted;
01836
01837 ldfile_assumed_script = TRUE;
01838 parser_input = input_script;
01839
01840
01841 config.dynamic_link = entry->dynamic;
01842 yyparse ();
01843 ldfile_assumed_script = FALSE;
01844
01845 ldlang_sysrooted_script = save_ldlang_sysrooted_script;
01846 stat_ptr = hold;
01847
01848 return ! bad_load;
01849 }
01850
01851 if (ldemul_recognized_file (entry))
01852 return TRUE;
01853
01854
01855
01856
01857
01858 switch (bfd_get_format (entry->the_bfd))
01859 {
01860 default:
01861 break;
01862
01863 case bfd_object:
01864 ldlang_add_file (entry);
01865 if (trace_files || trace_file_tries)
01866 info_msg ("%I\n", entry);
01867 break;
01868
01869 case bfd_archive:
01870 #ifdef KEY
01871
01872
01873 if (is_ipa) {
01874 bfd_boolean seen_nonwhirl_obj = FALSE;
01875 bfd_boolean seen_whirl_obj = FALSE;
01876 bfd_boolean mixed = FALSE;
01877 bfd *member = NULL;
01878
01879
01880 member = bfd_openr_next_archived_file (entry->the_bfd, member);
01881 while(member != NULL) {
01882 if (!bfd_check_format (member, bfd_object)) {
01883 einfo (_("%F%B: member %B in archive is not an object\n"), entry->the_bfd, member);
01884 break;
01885 }
01886 if (ipa_is_whirl (member)) {
01887 seen_whirl_obj = TRUE;
01888 if(seen_nonwhirl_obj) {
01889 mixed = TRUE;
01890 break;
01891 }
01892 } else {
01893 seen_nonwhirl_obj = TRUE;
01894 if (seen_whirl_obj) {
01895 mixed = TRUE;
01896 break;
01897 }
01898 }
01899 member = bfd_openr_next_archived_file (entry->the_bfd, member);
01900 }
01901
01902 if(mixed) {
01903 archive_fname = (char*)xmalloc(strlen(entry->filename)+1);
01904 sprintf(archive_fname, "%s", entry->filename);
01905 (*p_ipa_modify_link_flag)(archive_lname, archive_fname);
01906 } else
01907 free(archive_lname);
01908
01909 if(!mixed && seen_whirl_obj) {
01910
01911 member = bfd_openr_next_archived_file (entry->the_bfd, member);
01912 #ifdef OSP_OPT
01913
01914 int fd = open(entry->filename, O_RDONLY);
01915 if (fd == -1) {
01916 einfo(("%F%B: cannot open archive file\n"), entry->the_bfd);
01917 }
01918 #endif
01919 while (member != NULL) {
01920 char *buf;
01921 struct ar_hdr *p_hdr;
01922 size_t parsed_size;
01923
01924 if (! bfd_link_add_symbols (member, &link_info)) {
01925 einfo (_("%F%B: could not read symbols from member %B in archive: %E\n"),
01926 entry->the_bfd, member);
01927 entry->loaded = FALSE;
01928 return FALSE;
01929 }
01930
01931 ld_set_cur_obj(member);
01932 p_hdr = arch_hdr(member);
01933 parsed_size = strtol (p_hdr->ar_size, NULL, 10);
01934
01935 #ifdef OSP_OPT
01936 if ((buf = ipa_mmap_file_in_archive(member, fd, parsed_size)) == NULL) {
01937 einfo(("%F%B: ipa_mmap_file_in_archive failed for member %B\n"), entry->the_bfd, member);
01938 }
01939 #else
01940 if ((buf = bfd_alloc(member, parsed_size)) == NULL) {
01941 einfo(_("%F%B: bfd_alloc failed for member %B\n"), entry->the_bfd, member);
01942 }
01943 if (bfd_seek(member, 0, SEEK_SET) != 0) {
01944 einfo(_("%F%B: bfd_seek failed for member %B\n"), entry->the_bfd, member);
01945 }
01946 if (bfd_bread(buf, parsed_size, member) != parsed_size) {
01947 einfo(_("%F%B: bfd_read failed for member %B\n"), entry->the_bfd, member);
01948 }
01949 #endif
01950
01951 member->usrdata = buf;
01952 if ((elf_elfheader(member)->e_flags & EF_IRIX_ABI64) == 0)
01953 (*p_process_whirl32) ((void *)member,
01954 elf_elfheader (member)->e_shnum,
01955 member->usrdata+elf_elfheader(member)->e_shoff,
01956 0,
01957 #ifdef OSP_OPT
01958 member->filename, parsed_size, TRUE);
01959 #else
01960 member->filename, parsed_size);
01961 #endif
01962 else
01963 (*p_process_whirl64) ((void *)member,
01964 elf_elfheader (member)->e_shnum,
01965 member->usrdata+elf_elfheader(member)->e_shoff,
01966 0,
01967 #ifdef OSP_OPT
01968 member->filename, parsed_size, TRUE);
01969 #else
01970 member->filename, parsed_size);
01971 #endif
01972
01973
01974
01975 (*p_ipa_erase_link_flag) (entry->local_sym_name);
01976 member = bfd_openr_next_archived_file (entry->the_bfd, member);
01977 }
01978
01979 entry->loaded = TRUE;
01980 return TRUE;
01981 }
01982 }
01983 #endif
01984
01985 check_excluded_libs (entry->the_bfd);
01986
01987 if (entry->whole_archive)
01988 {
01989 bfd *member = NULL;
01990 bfd_boolean loaded = TRUE;
01991
01992 for (;;)
01993 {
01994 member = bfd_openr_next_archived_file (entry->the_bfd, member);
01995
01996 if (member == NULL)
01997 break;
01998
01999 if (! bfd_check_format (member, bfd_object))
02000 {
02001 einfo (_("%F%B: member %B in archive is not an object\n"),
02002 entry->the_bfd, member);
02003 loaded = FALSE;
02004 }
02005
02006 if (! ((*link_info.callbacks->add_archive_element)
02007 (&link_info, member, "--whole-archive")))
02008 abort ();
02009
02010 if (! bfd_link_add_symbols (member, &link_info))
02011 {
02012 einfo (_("%F%B: could not read symbols: %E\n"), member);
02013 loaded = FALSE;
02014 }
02015 }
02016
02017 entry->loaded = loaded;
02018 return loaded;
02019 }
02020 break;
02021 }
02022
02023 if (bfd_link_add_symbols (entry->the_bfd, &link_info))
02024 entry->loaded = TRUE;
02025 else
02026 einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd);
02027
02028 #ifdef IPA_LINK
02029 if (is_ipa) {
02030 switch (bfd_get_format (entry->the_bfd)) {
02031 default:
02032 break;
02033
02034 case bfd_object:
02035 ld_set_cur_obj(entry->the_bfd);
02036 if (ipa_is_whirl(entry->the_bfd)) {
02037 ipa_process_whirl(entry->the_bfd);
02038 }
02039 break;
02040 }
02041 }
02042 #endif
02043
02044 return entry->loaded;
02045 }
02046
02047
02048
02049
02050
02051
02052
02053 static void
02054 wild (lang_wild_statement_type *s,
02055 const char *target ATTRIBUTE_UNUSED,
02056 lang_output_section_statement_type *output)
02057 {
02058 struct wildcard_list *sec;
02059
02060 walk_wild (s, output_section_callback, output);
02061
02062 for (sec = s->section_list; sec != NULL; sec = sec->next)
02063 {
02064 if (default_common_section != NULL)
02065 break;
02066 if (sec->spec.name != NULL && strcmp (sec->spec.name, "COMMON") == 0)
02067 {
02068
02069
02070 default_common_section = output;
02071 }
02072 }
02073 }
02074
02075
02076
02077 static int
02078 get_target (const bfd_target *target, void *data)
02079 {
02080 const char *sought = data;
02081
02082 return strcmp (target->name, sought) == 0;
02083 }
02084
02085
02086
02087 static void
02088 stricpy (char *dest, char *src)
02089 {
02090 char c;
02091
02092 while ((c = *src++) != 0)
02093 *dest++ = TOLOWER (c);
02094
02095 *dest = 0;
02096 }
02097
02098
02099
02100
02101 static void
02102 strcut (char *haystack, char *needle)
02103 {
02104 haystack = strstr (haystack, needle);
02105
02106 if (haystack)
02107 {
02108 char *src;
02109
02110 for (src = haystack + strlen (needle); *src;)
02111 *haystack++ = *src++;
02112
02113 *haystack = 0;
02114 }
02115 }
02116
02117
02118
02119
02120 static int
02121 name_compare (char *first, char *second)
02122 {
02123 char *copy1;
02124 char *copy2;
02125 int result;
02126
02127 copy1 = xmalloc (strlen (first) + 1);
02128 copy2 = xmalloc (strlen (second) + 1);
02129
02130
02131 stricpy (copy1, first);
02132 stricpy (copy2, second);
02133
02134
02135 strcut (copy1, "big");
02136 strcut (copy1, "little");
02137 strcut (copy2, "big");
02138 strcut (copy2, "little");
02139
02140
02141
02142
02143 for (result = 0; copy1[result] == copy2[result]; result++)
02144 if (copy1[result] == 0)
02145 {
02146 result *= 10;
02147 break;
02148 }
02149
02150 free (copy1);
02151 free (copy2);
02152
02153 return result;
02154 }
02155
02156
02157 static const bfd_target *winner;
02158
02159
02160
02161
02162
02163 static int
02164 closest_target_match (const bfd_target *target, void *data)
02165 {
02166 const bfd_target *original = data;
02167
02168 if (command_line.endian == ENDIAN_BIG
02169 && target->byteorder != BFD_ENDIAN_BIG)
02170 return 0;
02171
02172 if (command_line.endian == ENDIAN_LITTLE
02173 && target->byteorder != BFD_ENDIAN_LITTLE)
02174 return 0;
02175
02176
02177 if (target->flavour != original->flavour)
02178 return 0;
02179
02180
02181 if (winner == NULL)
02182 {
02183 winner = target;
02184 return 0;
02185 }
02186
02187
02188
02189 if (name_compare (target->name, original->name)
02190 > name_compare (winner->name, original->name))
02191 winner = target;
02192
02193
02194 return 0;
02195 }
02196
02197
02198
02199 static char *
02200 get_first_input_target (void)
02201 {
02202 char *target = NULL;
02203
02204 LANG_FOR_EACH_INPUT_STATEMENT (s)
02205 {
02206 if (s->header.type == lang_input_statement_enum
02207 && s->real)
02208 {
02209 ldfile_open_file (s);
02210
02211 if (s->the_bfd != NULL
02212 && bfd_check_format (s->the_bfd, bfd_object))
02213 {
02214 target = bfd_get_target (s->the_bfd);
02215
02216 if (target != NULL)
02217 break;
02218 }
02219 }
02220 }
02221
02222 return target;
02223 }
02224
02225 const char *
02226 lang_get_output_target (void)
02227 {
02228 const char *target;
02229
02230
02231 if (output_target != NULL)
02232 return output_target;
02233
02234
02235
02236 if (current_target != default_target)
02237 return current_target;
02238
02239
02240 target = get_first_input_target ();
02241 if (target != NULL)
02242 return target;
02243
02244
02245 return default_target;
02246 }
02247
02248
02249
02250 static bfd *
02251 open_output (const char *name)
02252 {
02253 bfd *output;
02254
02255 output_target = lang_get_output_target ();
02256
02257
02258
02259 if (command_line.endian != ENDIAN_UNSET)
02260 {
02261 const bfd_target *target;
02262 enum bfd_endian desired_endian;
02263
02264
02265 target = bfd_search_for_target (get_target, (void *) output_target);
02266
02267
02268 if (target != NULL)
02269 {
02270 if (command_line.endian == ENDIAN_BIG)
02271 desired_endian = BFD_ENDIAN_BIG;
02272 else
02273 desired_endian = BFD_ENDIAN_LITTLE;
02274
02275
02276
02277
02278
02279 if (target->byteorder != desired_endian)
02280 {
02281
02282
02283 if (target->alternative_target != NULL
02284 && (target->alternative_target->byteorder == desired_endian))
02285 output_target = target->alternative_target->name;
02286 else
02287 {
02288
02289
02290
02291 bfd_search_for_target (closest_target_match,
02292 (void *) target);
02293
02294
02295
02296 if (winner == NULL)
02297 einfo (_("%P: warning: could not find any targets"
02298 " that match endianness requirement\n"));
02299 else
02300 output_target = winner->name;
02301 }
02302 }
02303 }
02304 }
02305
02306 output = bfd_openw (name, output_target);
02307
02308 if (output == NULL)
02309 {
02310 if (bfd_get_error () == bfd_error_invalid_target)
02311 einfo (_("%P%F: target %s not found\n"), output_target);
02312
02313 #ifndef KEY // bug 3956
02314 (*p_Ipalink_ErrMsg_EC_outfile)(name);
02315 #else
02316 einfo (_("%P%F: cannot open output file %s: %E\n"), name);
02317 #endif
02318 }
02319
02320 delete_output_file_on_failure = TRUE;
02321
02322 if (! bfd_set_format (output, bfd_object))
02323 einfo (_("%P%F:%s: can not make object file: %E\n"), name);
02324 if (! bfd_set_arch_mach (output,
02325 ldfile_output_architecture,
02326 ldfile_output_machine))
02327 einfo (_("%P%F:%s: can not set architecture: %E\n"), name);
02328
02329 link_info.hash = bfd_link_hash_table_create (output);
02330 if (link_info.hash == NULL)
02331 einfo (_("%P%F: can not create link hash table: %E\n"));
02332
02333 bfd_set_gp_size (output, g_switch_value);
02334 return output;
02335 }
02336
02337 static void
02338 ldlang_open_output (lang_statement_union_type *statement)
02339 {
02340 switch (statement->header.type)
02341 {
02342 case lang_output_statement_enum:
02343 ASSERT (output_bfd == NULL);
02344 output_bfd = open_output (statement->output_statement.name);
02345 ldemul_set_output_arch ();
02346 if (config.magic_demand_paged && !link_info.relocatable)
02347 output_bfd->flags |= D_PAGED;
02348 else
02349 output_bfd->flags &= ~D_PAGED;
02350 if (config.text_read_only)
02351 output_bfd->flags |= WP_TEXT;
02352 else
02353 output_bfd->flags &= ~WP_TEXT;
02354 if (link_info.traditional_format)
02355 output_bfd->flags |= BFD_TRADITIONAL_FORMAT;
02356 else
02357 output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT;
02358 break;
02359
02360 case lang_target_statement_enum:
02361 current_target = statement->target_statement.target;
02362 break;
02363 default:
02364 break;
02365 }
02366 }
02367
02368
02369
02370
02371 #define TO_ADDR(X) ((X) >> opb_shift)
02372 #define TO_SIZE(X) ((X) << opb_shift)
02373
02374
02375 static unsigned int opb_shift = 0;
02376
02377 static void
02378 init_opb (void)
02379 {
02380 unsigned x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
02381 ldfile_output_machine);
02382 opb_shift = 0;
02383 if (x > 1)
02384 while ((x & 1) == 0)
02385 {
02386 x >>= 1;
02387 ++opb_shift;
02388 }
02389 ASSERT (x == 1);
02390 }
02391
02392
02393
02394 static void
02395 open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
02396 {
02397 for (; s != NULL; s = s->header.next)
02398 {
02399 switch (s->header.type)
02400 {
02401 case lang_constructors_statement_enum:
02402 open_input_bfds (constructor_list.head, force);
02403 break;
02404 case lang_output_section_statement_enum:
02405 open_input_bfds (s->output_section_statement.children.head, force);
02406 break;
02407 case lang_wild_statement_enum:
02408
02409 if (s->wild_statement.filename
02410 && ! wildcardp (s->wild_statement.filename))
02411 lookup_name (s->wild_statement.filename);
02412 open_input_bfds (s->wild_statement.children.head, force);
02413 break;
02414 case lang_group_statement_enum:
02415 {
02416 struct bfd_link_hash_entry *undefs;
02417
02418
02419
02420
02421
02422 do
02423 {
02424 undefs = link_info.hash->undefs_tail;
02425 open_input_bfds (s->group_statement.children.head, TRUE);
02426 }
02427 while (undefs != link_info.hash->undefs_tail);
02428 }
02429 break;
02430 case lang_target_statement_enum:
02431 current_target = s->target_statement.target;
02432 break;
02433 case lang_input_statement_enum:
02434 if (s->input_statement.real)
02435 {
02436 lang_statement_list_type add;
02437
02438 s->input_statement.target = current_target;
02439
02440
02441
02442
02443
02444 if (force
02445 && !s->input_statement.whole_archive
02446 && s->input_statement.loaded
02447 && bfd_check_format (s->input_statement.the_bfd,
02448 bfd_archive))
02449 s->input_statement.loaded = FALSE;
02450
02451 lang_list_init (&add);
02452
02453 if (! load_symbols (&s->input_statement, &add))
02454 config.make_executable = FALSE;
02455
02456 if (add.head != NULL)
02457 {
02458 *add.tail = s->header.next;
02459 s->header.next = add.head;
02460 }
02461 }
02462 break;
02463 default:
02464 break;
02465 }
02466 }
02467 }
02468
02469
02470
02471 void
02472 lang_track_definedness (const char *name)
02473 {
02474 if (bfd_hash_lookup (&lang_definedness_table, name, TRUE, FALSE) == NULL)
02475 einfo (_("%P%F: bfd_hash_lookup failed creating symbol %s\n"), name);
02476 }
02477
02478
02479
02480 static struct bfd_hash_entry *
02481 lang_definedness_newfunc (struct bfd_hash_entry *entry,
02482 struct bfd_hash_table *table ATTRIBUTE_UNUSED,
02483 const char *name ATTRIBUTE_UNUSED)
02484 {
02485 struct lang_definedness_hash_entry *ret
02486 = (struct lang_definedness_hash_entry *) entry;
02487
02488 if (ret == NULL)
02489 ret = (struct lang_definedness_hash_entry *)
02490 bfd_hash_allocate (table, sizeof (struct lang_definedness_hash_entry));
02491
02492 if (ret == NULL)
02493 einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name);
02494
02495 ret->iteration = -1;
02496 return &ret->root;
02497 }
02498
02499
02500
02501
02502
02503 int
02504 lang_symbol_definition_iteration (const char *name)
02505 {
02506 struct lang_definedness_hash_entry *defentry
02507 = (struct lang_definedness_hash_entry *)
02508 bfd_hash_lookup (&lang_definedness_table, name, FALSE, FALSE);
02509
02510
02511
02512
02513 if (defentry == NULL)
02514 FAIL ();
02515
02516 return defentry->iteration;
02517 }
02518
02519
02520
02521 void
02522 lang_update_definedness (const char *name, struct bfd_link_hash_entry *h)
02523 {
02524 struct lang_definedness_hash_entry *defentry
02525 = (struct lang_definedness_hash_entry *)
02526 bfd_hash_lookup (&lang_definedness_table, name, FALSE, FALSE);
02527
02528
02529 if (defentry == NULL)
02530 return;
02531
02532
02533
02534
02535
02536
02537
02538
02539 if (h->type != bfd_link_hash_undefined
02540 && h->type != bfd_link_hash_common
02541 && h->type != bfd_link_hash_new
02542 && defentry->iteration == -1)
02543 return;
02544
02545 defentry->iteration = lang_statement_iteration;
02546 }
02547
02548
02549
02550
02551
02552
02553
02554 typedef struct bfd_sym_chain ldlang_undef_chain_list_type;
02555
02556 #define ldlang_undef_chain_list_head entry_symbol.next
02557
02558 void
02559 ldlang_add_undef (const char *const name)
02560 {
02561 ldlang_undef_chain_list_type *new =
02562 stat_alloc (sizeof (ldlang_undef_chain_list_type));
02563
02564 new->next = ldlang_undef_chain_list_head;
02565 ldlang_undef_chain_list_head = new;
02566
02567 new->name = xstrdup (name);
02568
02569 if (output_bfd != NULL)
02570 insert_undefined (new->name);
02571 }
02572
02573
02574
02575 static void
02576 insert_undefined (const char *name)
02577 {
02578 struct bfd_link_hash_entry *h;
02579
02580 h = bfd_link_hash_lookup (link_info.hash, name, TRUE, FALSE, TRUE);
02581 if (h == NULL)
02582 einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
02583 if (h->type == bfd_link_hash_new)
02584 {
02585 h->type = bfd_link_hash_undefined;
02586 h->u.undef.abfd = NULL;
02587 bfd_link_add_undef (link_info.hash, h);
02588 }
02589 }
02590
02591
02592
02593
02594
02595 static void
02596 lang_place_undefineds (void)
02597 {
02598 ldlang_undef_chain_list_type *ptr;
02599
02600 for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next)
02601 insert_undefined (ptr->name);
02602 }
02603
02604
02605
02606 static void
02607 check_input_sections
02608 (lang_statement_union_type *s,
02609 lang_output_section_statement_type *output_section_statement)
02610 {
02611 for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
02612 {
02613 switch (s->header.type)
02614 {
02615 case lang_wild_statement_enum:
02616 walk_wild (&s->wild_statement, check_section_callback,
02617 output_section_statement);
02618 if (! output_section_statement->all_input_readonly)
02619 return;
02620 break;
02621 case lang_constructors_statement_enum:
02622 check_input_sections (constructor_list.head,
02623 output_section_statement);
02624 if (! output_section_statement->all_input_readonly)
02625 return;
02626 break;
02627 case lang_group_statement_enum:
02628 check_input_sections (s->group_statement.children.head,
02629 output_section_statement);
02630 if (! output_section_statement->all_input_readonly)
02631 return;
02632 break;
02633 default:
02634 break;
02635 }
02636 }
02637 }
02638
02639
02640
02641 static void
02642 update_wild_statements (lang_statement_union_type *s)
02643 {
02644 struct wildcard_list *sec;
02645
02646 switch (sort_section)
02647 {
02648 default:
02649 FAIL ();
02650
02651 case none:
02652 break;
02653
02654 case by_name:
02655 case by_alignment:
02656 for (; s != NULL; s = s->header.next)
02657 {
02658 switch (s->header.type)
02659 {
02660 default:
02661 break;
02662
02663 case lang_wild_statement_enum:
02664 sec = s->wild_statement.section_list;
02665 if (sec != NULL)
02666 {
02667 switch (sec->spec.sorted)
02668 {
02669 case none:
02670 sec->spec.sorted = sort_section;
02671 break;
02672 case by_name:
02673 if (sort_section == by_alignment)
02674 sec->spec.sorted = by_name_alignment;
02675 break;
02676 case by_alignment:
02677 if (sort_section == by_name)
02678 sec->spec.sorted = by_alignment_name;
02679 break;
02680 default:
02681 break;
02682 }
02683 }
02684 break;
02685
02686 case lang_constructors_statement_enum:
02687 update_wild_statements (constructor_list.head);
02688 break;
02689
02690 case lang_output_section_statement_enum:
02691 update_wild_statements
02692 (s->output_section_statement.children.head);
02693 break;
02694
02695 case lang_group_statement_enum:
02696 update_wild_statements (s->group_statement.children.head);
02697 break;
02698 }
02699 }
02700 break;
02701 }
02702 }
02703
02704
02705
02706 static void
02707 map_input_to_output_sections
02708 (lang_statement_union_type *s, const char *target,
02709 lang_output_section_statement_type *os)
02710 {
02711 for (; s != NULL; s = s->header.next)
02712 {
02713 switch (s->header.type)
02714 {
02715 case lang_wild_statement_enum:
02716 wild (&s->wild_statement, target, os);
02717 break;
02718 case lang_constructors_statement_enum:
02719 map_input_to_output_sections (constructor_list.head,
02720 target,
02721 os);
02722 break;
02723 case lang_output_section_statement_enum:
02724 if (s->output_section_statement.constraint)
02725 {
02726 if (s->output_section_statement.constraint == -1)
02727 break;
02728 s->output_section_statement.all_input_readonly = TRUE;
02729 check_input_sections (s->output_section_statement.children.head,
02730 &s->output_section_statement);
02731 if ((s->output_section_statement.all_input_readonly
02732 && s->output_section_statement.constraint == ONLY_IF_RW)
02733 || (!s->output_section_statement.all_input_readonly
02734 && s->output_section_statement.constraint == ONLY_IF_RO))
02735 {
02736 s->output_section_statement.constraint = -1;
02737 break;
02738 }
02739 }
02740
02741 map_input_to_output_sections (s->output_section_statement.children.head,
02742 target,
02743 &s->output_section_statement);
02744 break;
02745 case lang_output_statement_enum:
02746 break;
02747 case lang_target_statement_enum:
02748 target = s->target_statement.target;
02749 break;
02750 case lang_group_statement_enum:
02751 map_input_to_output_sections (s->group_statement.children.head,
02752 target,
02753 os);
02754 break;
02755 case lang_data_statement_enum:
02756
02757
02758 exp_init_os (s->data_statement.exp);
02759 if (os != NULL && os->bfd_section == NULL)
02760 init_os (os);
02761
02762
02763 os->bfd_section->flags |= SEC_HAS_CONTENTS;
02764 if (!(os->flags & SEC_NEVER_LOAD))
02765 os->bfd_section->flags |= SEC_ALLOC | SEC_LOAD;
02766 break;
02767 case lang_fill_statement_enum:
02768 case lang_input_section_enum:
02769 case lang_object_symbols_statement_enum:
02770 case lang_reloc_statement_enum:
02771 case lang_padding_statement_enum:
02772 case lang_input_statement_enum:
02773 if (os != NULL && os->bfd_section == NULL)
02774 init_os (os);
02775 break;
02776 case lang_assignment_statement_enum:
02777 if (os != NULL && os->bfd_section == NULL)
02778 init_os (os);
02779
02780
02781
02782 exp_init_os (s->assignment_statement.exp);
02783 break;
02784 case lang_afile_asection_pair_statement_enum:
02785 FAIL ();
02786 break;
02787 case lang_address_statement_enum:
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798 if (!s->address_statement.segment
02799 || !s->address_statement.segment->used)
02800 {
02801 lang_output_section_statement_type *aos
02802 = (lang_output_section_statement_lookup
02803 (s->address_statement.section_name));
02804
02805 if (aos->bfd_section == NULL)
02806 init_os (aos);
02807 aos->addr_tree = s->address_statement.address;
02808 }
02809 break;
02810 }
02811 }
02812 }
02813
02814
02815
02816
02817
02818 static void
02819 strip_excluded_output_sections (void)
02820 {
02821 lang_output_section_statement_type *os;
02822
02823 for (os = &lang_output_section_statement.head->output_section_statement;
02824 os != NULL;
02825 os = os->next)
02826 {
02827 asection *s;
02828
02829 if (os->constraint == -1)
02830 continue;
02831 s = os->bfd_section;
02832 if (s != NULL && (s->flags & SEC_EXCLUDE) != 0)
02833 {
02834 asection **p;
02835
02836 os->bfd_section = NULL;
02837
02838 for (p = &output_bfd->sections; *p; p = &(*p)->next)
02839 if (*p == s)
02840 {
02841 bfd_section_list_remove (output_bfd, p);
02842 output_bfd->section_count--;
02843 break;
02844 }
02845 }
02846 }
02847 }
02848
02849 static void
02850 print_output_section_statement
02851 (lang_output_section_statement_type *output_section_statement)
02852 {
02853 asection *section = output_section_statement->bfd_section;
02854 int len;
02855
02856 if (output_section_statement != abs_output_section)
02857 {
02858 minfo ("\n%s", output_section_statement->name);
02859
02860 if (section != NULL)
02861 {
02862 print_dot = section->vma;
02863
02864 len = strlen (output_section_statement->name);
02865 if (len >= SECTION_NAME_MAP_LENGTH - 1)
02866 {
02867 print_nl ();
02868 len = 0;
02869 }
02870 while (len < SECTION_NAME_MAP_LENGTH)
02871 {
02872 print_space ();
02873 ++len;
02874 }
02875
02876 minfo ("0x%V %W", section->vma, section->size);
02877
02878 if (output_section_statement->load_base != NULL)
02879 {
02880 bfd_vma addr;
02881
02882 addr = exp_get_abs_int (output_section_statement->load_base, 0,
02883 "load base", lang_final_phase_enum);
02884 minfo (_(" load address 0x%V"), addr);
02885 }
02886 }
02887
02888 print_nl ();
02889 }
02890
02891 print_statement_list (output_section_statement->children.head,
02892 output_section_statement);
02893 }
02894
02895 static void
02896 print_assignment (lang_assignment_statement_type *assignment,
02897 lang_output_section_statement_type *output_section)
02898 {
02899 int i;
02900 int is_dot;
02901 etree_type *tree;
02902 etree_value_type result;
02903
02904 for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
02905 print_space ();
02906
02907 if (assignment->exp->type.node_class == etree_assert)
02908 {
02909 is_dot = 0;
02910 tree = assignment->exp->assert_s.child;
02911 }
02912 else
02913 {
02914 const char *dst = assignment->exp->assign.dst;
02915 is_dot = dst[0] == '.' && dst[1] == 0;
02916 tree = assignment->exp->assign.src;
02917 }
02918
02919 result = exp_fold_tree (tree, output_section, lang_final_phase_enum,
02920 print_dot, &print_dot);
02921 if (result.valid_p)
02922 {
02923 bfd_vma value;
02924
02925 value = result.value + result.section->bfd_section->vma;
02926
02927 minfo ("0x%V", value);
02928 if (is_dot)
02929 print_dot = value;
02930 }
02931 else
02932 {
02933 minfo ("*undef* ");
02934 #ifdef BFD64
02935 minfo (" ");
02936 #endif
02937 }
02938
02939 minfo (" ");
02940 exp_print_tree (assignment->exp);
02941 print_nl ();
02942 }
02943
02944 static void
02945 print_input_statement (lang_input_statement_type *statm)
02946 {
02947 if (statm->filename != NULL)
02948 {
02949 fprintf (config.map_file, "LOAD %s\n", statm->filename);
02950 }
02951 }
02952
02953
02954
02955
02956 static bfd_boolean
02957 print_one_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr)
02958 {
02959 asection *sec = ptr;
02960
02961 if ((hash_entry->type == bfd_link_hash_defined
02962 || hash_entry->type == bfd_link_hash_defweak)
02963 && sec == hash_entry->u.def.section)
02964 {
02965 int i;
02966
02967 for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
02968 print_space ();
02969 minfo ("0x%V ",
02970 (hash_entry->u.def.value
02971 + hash_entry->u.def.section->output_offset
02972 + hash_entry->u.def.section->output_section->vma));
02973
02974 minfo (" %T\n", hash_entry->root.string);
02975 }
02976
02977 return TRUE;
02978 }
02979
02980 static void
02981 print_all_symbols (sec)
02982 asection *sec;
02983 {
02984 struct fat_user_section_struct *ud = get_userdata (sec);
02985 struct map_symbol_def *def;
02986
02987 if (!ud)
02988 return;
02989
02990 *ud->map_symbol_def_tail = 0;
02991 for (def = ud->map_symbol_def_head; def; def = def->next)
02992 print_one_symbol (def->entry, sec);
02993 }
02994
02995
02996
02997 static void
02998 print_input_section (lang_input_section_type *in)
02999 {
03000 asection *i = in->section;
03001 bfd_size_type size = i->size;
03002
03003 init_opb ();
03004 if (size != 0)
03005 {
03006 int len;
03007 bfd_vma addr;
03008
03009 print_space ();
03010 minfo ("%s", i->name);
03011
03012 len = 1 + strlen (i->name);
03013 if (len >= SECTION_NAME_MAP_LENGTH - 1)
03014 {
03015 print_nl ();
03016 len = 0;
03017 }
03018 while (len < SECTION_NAME_MAP_LENGTH)
03019 {
03020 print_space ();
03021 ++len;
03022 }
03023
03024 if (i->output_section != NULL && (i->flags & SEC_EXCLUDE) == 0)
03025 addr = i->output_section->vma + i->output_offset;
03026 else
03027 {
03028 addr = print_dot;
03029 size = 0;
03030 }
03031
03032 minfo ("0x%V %W %B\n", addr, TO_ADDR (size), i->owner);
03033
03034 if (size != i->rawsize && i->rawsize != 0)
03035 {
03036 len = SECTION_NAME_MAP_LENGTH + 3;
03037 #ifdef BFD64
03038 len += 16;
03039 #else
03040 len += 8;
03041 #endif
03042 while (len > 0)
03043 {
03044 print_space ();
03045 --len;
03046 }
03047
03048 minfo (_("%W (size before relaxing)\n"), i->rawsize);
03049 }
03050
03051 if (i->output_section != NULL && (i->flags & SEC_EXCLUDE) == 0)
03052 {
03053 if (command_line.reduce_memory_overheads)
03054 bfd_link_hash_traverse (link_info.hash, print_one_symbol, i);
03055 else
03056 print_all_symbols (i);
03057
03058 print_dot = addr + TO_ADDR (size);
03059 }
03060 }
03061 }
03062
03063 static void
03064 print_fill_statement (lang_fill_statement_type *fill)
03065 {
03066 size_t size;
03067 unsigned char *p;
03068 fputs (" FILL mask 0x", config.map_file);
03069 for (p = fill->fill->data, size = fill->fill->size; size != 0; p++, size--)
03070 fprintf (config.map_file, "%02x", *p);
03071 fputs ("\n", config.map_file);
03072 }
03073
03074 static void
03075 print_data_statement (lang_data_statement_type *data)
03076 {
03077 int i;
03078 bfd_vma addr;
03079 bfd_size_type size;
03080 const char *name;
03081
03082 init_opb ();
03083 for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
03084 print_space ();
03085
03086 addr = data->output_vma;
03087 if (data->output_section != NULL)
03088 addr += data->output_section->vma;
03089
03090 switch (data->type)
03091 {
03092 default:
03093 abort ();
03094 case BYTE:
03095 size = BYTE_SIZE;
03096 name = "BYTE";
03097 break;
03098 case SHORT:
03099 size = SHORT_SIZE;
03100 name = "SHORT";
03101 break;
03102 case LONG:
03103 size = LONG_SIZE;
03104 name = "LONG";
03105 break;
03106 case QUAD:
03107 size = QUAD_SIZE;
03108 name = "QUAD";
03109 break;
03110 case SQUAD:
03111 size = QUAD_SIZE;
03112 name = "SQUAD";
03113 break;
03114 }
03115
03116 minfo ("0x%V %W %s 0x%v", addr, size, name, data->value);
03117
03118 if (data->exp->type.node_class != etree_value)
03119 {
03120 print_space ();
03121 exp_print_tree (data->exp);
03122 }
03123
03124 print_nl ();
03125
03126 print_dot = addr + TO_ADDR (size);
03127 }
03128
03129
03130
03131
03132 static void
03133 print_address_statement (lang_address_statement_type *address)
03134 {
03135 minfo (_("Address of section %s set to "), address->section_name);
03136 exp_print_tree (address->address);
03137 print_nl ();
03138 }
03139
03140
03141
03142 static void
03143 print_reloc_statement (lang_reloc_statement_type *reloc)
03144 {
03145 int i;
03146 bfd_vma addr;
03147 bfd_size_type size;
03148
03149 init_opb ();
03150 for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
03151 print_space ();
03152
03153 addr = reloc->output_vma;
03154 if (reloc->output_section != NULL)
03155 addr += reloc->output_section->vma;
03156
03157 size = bfd_get_reloc_size (reloc->howto);
03158
03159 minfo ("0x%V %W RELOC %s ", addr, size, reloc->howto->name);
03160
03161 if (reloc->name != NULL)
03162 minfo ("%s+", reloc->name);
03163 else
03164 minfo ("%s+", reloc->section->name);
03165
03166 exp_print_tree (reloc->addend_exp);
03167
03168 print_nl ();
03169
03170 print_dot = addr + TO_ADDR (size);
03171 }
03172
03173 static void
03174 print_padding_statement (lang_padding_statement_type *s)
03175 {
03176 int len;
03177 bfd_vma addr;
03178
03179 init_opb ();
03180 minfo (" *fill*");
03181
03182 len = sizeof " *fill*" - 1;
03183 while (len < SECTION_NAME_MAP_LENGTH)
03184 {
03185 print_space ();
03186 ++len;
03187 }
03188
03189 addr = s->output_offset;
03190 if (s->output_section != NULL)
03191 addr += s->output_section->vma;
03192 minfo ("0x%V %W ", addr, (bfd_vma) s->size);
03193
03194 if (s->fill->size != 0)
03195 {
03196 size_t size;
03197 unsigned char *p;
03198 for (p = s->fill->data, size = s->fill->size; size != 0; p++, size--)
03199 fprintf (config.map_file, "%02x", *p);
03200 }
03201
03202 print_nl ();
03203
03204 print_dot = addr + TO_ADDR (s->size);
03205 }
03206
03207 static void
03208 print_wild_statement (lang_wild_statement_type *w,
03209 lang_output_section_statement_type *os)
03210 {
03211 struct wildcard_list *sec;
03212
03213 print_space ();
03214
03215 if (w->filenames_sorted)
03216 minfo ("SORT(");
03217 if (w->filename != NULL)
03218 minfo ("%s", w->filename);
03219 else
03220 minfo ("*");
03221 if (w->filenames_sorted)
03222 minfo (")");
03223
03224 minfo ("(");
03225 for (sec = w->section_list; sec; sec = sec->next)
03226 {
03227 if (sec->spec.sorted)
03228 minfo ("SORT(");
03229 if (sec->spec.exclude_name_list != NULL)
03230 {
03231 name_list *tmp;
03232 minfo ("EXCLUDE_FILE(%s", sec->spec.exclude_name_list->name);
03233 for (tmp = sec->spec.exclude_name_list->next; tmp; tmp = tmp->next)
03234 minfo (" %s", tmp->name);
03235 minfo (") ");
03236 }
03237 if (sec->spec.name != NULL)
03238 minfo ("%s", sec->spec.name);
03239 else
03240 minfo ("*");
03241 if (sec->spec.sorted)
03242 minfo (")");
03243 if (sec->next)
03244 minfo (" ");
03245 }
03246 minfo (")");
03247
03248 print_nl ();
03249
03250 print_statement_list (w->children.head, os);
03251 }
03252
03253
03254
03255 static void
03256 print_group (lang_group_statement_type *s,
03257 lang_output_section_statement_type *os)
03258 {
03259 fprintf (config.map_file, "START GROUP\n");
03260 print_statement_list (s->children.head, os);
03261 fprintf (config.map_file, "END GROUP\n");
03262 }
03263
03264
03265
03266
03267 static void
03268 print_statement_list (lang_statement_union_type *s,
03269 lang_output_section_statement_type *os)
03270 {
03271 while (s != NULL)
03272 {
03273 print_statement (s, os);
03274 s = s->header.next;
03275 }
03276 }
03277
03278
03279
03280
03281 static void
03282 print_statement (lang_statement_union_type *s,
03283 lang_output_section_statement_type *os)
03284 {
03285 switch (s->header.type)
03286 {
03287 default:
03288 fprintf (config.map_file, _("Fail with %d\n"), s->header.type);
03289 FAIL ();
03290 break;
03291 case lang_constructors_statement_enum:
03292 if (constructor_list.head != NULL)
03293 {
03294 if (constructors_sorted)
03295 minfo (" SORT (CONSTRUCTORS)\n");
03296 else
03297 minfo (" CONSTRUCTORS\n");
03298 print_statement_list (constructor_list.head, os);
03299 }
03300 break;
03301 case lang_wild_statement_enum:
03302 print_wild_statement (&s->wild_statement, os);
03303 break;
03304 case lang_address_statement_enum:
03305 print_address_statement (&s->address_statement);
03306 break;
03307 case lang_object_symbols_statement_enum:
03308 minfo (" CREATE_OBJECT_SYMBOLS\n");
03309 break;
03310 case lang_fill_statement_enum:
03311 print_fill_statement (&s->fill_statement);
03312 break;
03313 case lang_data_statement_enum:
03314 print_data_statement (&s->data_statement);
03315 break;
03316 case lang_reloc_statement_enum:
03317 print_reloc_statement (&s->reloc_statement);
03318 break;
03319 case lang_input_section_enum:
03320 print_input_section (&s->input_section);
03321 break;
03322 case lang_padding_statement_enum:
03323 print_padding_statement (&s->padding_statement);
03324 break;
03325 case lang_output_section_statement_enum:
03326 print_output_section_statement (&s->output_section_statement);
03327 break;
03328 case lang_assignment_statement_enum:
03329 print_assignment (&s->assignment_statement, os);
03330 break;
03331 case lang_target_statement_enum:
03332 fprintf (config.map_file, "TARGET(%s)\n", s->target_statement.target);
03333 break;
03334 case lang_output_statement_enum:
03335 minfo ("OUTPUT(%s", s->output_statement.name);
03336 if (output_target != NULL)
03337 minfo (" %s", output_target);
03338 minfo (")\n");
03339 break;
03340 case lang_input_statement_enum:
03341 print_input_statement (&s->input_statement);
03342 break;
03343 case lang_group_statement_enum:
03344 print_group (&s->group_statement, os);
03345 break;
03346 case lang_afile_asection_pair_statement_enum:
03347 FAIL ();
03348 break;
03349 }
03350 }
03351
03352 static void
03353 print_statements (void)
03354 {
03355 print_statement_list (statement_list.head, abs_output_section);
03356 }
03357
03358
03359
03360
03361
03362
03363 void
03364 dprint_statement (lang_statement_union_type *s, int n)
03365 {
03366 FILE *map_save = config.map_file;
03367
03368 config.map_file = stderr;
03369
03370 if (n < 0)
03371 print_statement_list (s, abs_output_section);
03372 else
03373 {
03374 while (s && --n >= 0)
03375 {
03376 print_statement (s, abs_output_section);
03377 s = s->header.next;
03378 }
03379 }
03380
03381 config.map_file = map_save;
03382 }
03383
03384 static void
03385 insert_pad (lang_statement_union_type **ptr,
03386 fill_type *fill,
03387 unsigned int alignment_needed,
03388 asection *output_section,
03389 bfd_vma dot)
03390 {
03391 static fill_type zero_fill = { 1, { 0 } };
03392 lang_statement_union_type *pad;
03393
03394 pad = ((lang_statement_union_type *)
03395 ((char *) ptr - offsetof (lang_statement_union_type, header.next)));
03396 if (ptr != &statement_list.head
03397 && pad->header.type == lang_padding_statement_enum
03398 && pad->padding_statement.output_section == output_section)
03399 {
03400
03401
03402 }
03403 else
03404 {
03405
03406 pad = stat_alloc (sizeof (lang_padding_statement_type));
03407 pad->header.next = *ptr;
03408 *ptr = pad;
03409 pad->header.type = lang_padding_statement_enum;
03410 pad->padding_statement.output_section = output_section;
03411 if (fill == NULL)
03412 fill = &zero_fill;
03413 pad->padding_statement.fill = fill;
03414 }
03415 pad->padding_statement.output_offset = dot - output_section->vma;
03416 pad->padding_statement.size = alignment_needed;
03417 output_section->size += alignment_needed;
03418 }
03419
03420
03421
03422 static bfd_vma
03423 size_input_section
03424 (lang_statement_union_type **this_ptr,
03425 lang_output_section_statement_type *output_section_statement,
03426 fill_type *fill,
03427 bfd_vma dot)
03428 {
03429 lang_input_section_type *is = &((*this_ptr)->input_section);
03430 asection *i = is->section;
03431
03432 if (!is->ifile->just_syms_flag && (i->flags & SEC_EXCLUDE) == 0)
03433 {
03434 unsigned int alignment_needed;
03435 asection *o;
03436
03437
03438
03439
03440
03441
03442 if (output_section_statement->subsection_alignment != -1)
03443 i->alignment_power = output_section_statement->subsection_alignment;
03444
03445 o = output_section_statement->bfd_section;
03446 if (o->alignment_power < i->alignment_power)
03447 o->alignment_power = i->alignment_power;
03448
03449 alignment_needed = align_power (dot, i->alignment_power) - dot;
03450
03451 if (alignment_needed != 0)
03452 {
03453 insert_pad (this_ptr, fill, TO_SIZE (alignment_needed), o, dot);
03454 dot += alignment_needed;
03455 }
03456
03457
03458
03459 i->output_offset = dot - o->vma;
03460
03461
03462 dot += TO_ADDR (i->size);
03463 o->size = TO_SIZE (dot - o->vma);
03464 }
03465 else
03466 {
03467 i->output_offset = i->vma - output_section_statement->bfd_section->vma;
03468 }
03469
03470 return dot;
03471 }
03472
03473 #define IGNORE_SECTION(s) \
03474 ((s->flags & SEC_NEVER_LOAD) != 0 \
03475 || (s->flags & SEC_ALLOC) == 0 \
03476 || ((s->flags & SEC_THREAD_LOCAL) != 0 \
03477 && (s->flags & SEC_LOAD) == 0))
03478
03479
03480
03481
03482
03483 static void
03484 lang_check_section_addresses (void)
03485 {
03486 asection *s;
03487
03488
03489 for (s = output_bfd->sections; s != NULL; s = s->next)
03490 {
03491 asection *os;
03492
03493
03494 if (IGNORE_SECTION (s) || s->size == 0)
03495 continue;
03496
03497
03498
03499
03500 for (os = output_bfd->sections; os != s; os = os->next)
03501 {
03502 bfd_vma s_start;
03503 bfd_vma s_end;
03504 bfd_vma os_start;
03505 bfd_vma os_end;
03506
03507
03508 if (IGNORE_SECTION (os) || os->size == 0)
03509 continue;
03510
03511
03512
03513
03514 s_start = bfd_section_lma (output_bfd, s);
03515 os_start = bfd_section_lma (output_bfd, os);
03516 s_end = s_start + TO_ADDR (s->size) - 1;
03517 os_end = os_start + TO_ADDR (os->size) - 1;
03518
03519
03520 if ((s_end < os_start) || (s_start > os_end))
03521 continue;
03522
03523 einfo (
03524 _("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
03525 s->name, s_start, s_end, os->name, os_start, os_end);
03526
03527
03528
03529 break;
03530 }
03531 }
03532 }
03533
03534
03535
03536
03537
03538
03539 static void
03540 os_region_check (lang_output_section_statement_type *os,
03541 lang_memory_region_type *region,
03542 etree_type *tree,
03543 bfd_vma base)
03544 {
03545 if ((region->current < region->origin
03546 || (region->current - region->origin > region->length))
03547 && ((region->current != region->origin + region->length)
03548 || base == 0))
03549 {
03550 if (tree != NULL)
03551 {
03552 einfo (_("%X%P: address 0x%v of %B section %s"
03553 " is not within region %s\n"),
03554 region->current,
03555 os->bfd_section->owner,
03556 os->bfd_section->name,
03557 region->name);
03558 }
03559 else
03560 {
03561 einfo (_("%X%P: region %s is full (%B section %s)\n"),
03562 region->name,
03563 os->bfd_section->owner,
03564 os->bfd_section->name);
03565 }
03566
03567 region->current = region->origin;
03568 }
03569 }
03570
03571
03572
03573 static bfd_vma
03574 lang_size_sections_1
03575 (lang_statement_union_type *s,
03576 lang_output_section_statement_type *output_section_statement,
03577 lang_statement_union_type **prev,
03578 fill_type *fill,
03579 bfd_vma dot,
03580 bfd_boolean *relax,
03581 bfd_boolean check_regions)
03582 {
03583
03584 for (; s != NULL; s = s->header.next)
03585 {
03586 switch (s->header.type)
03587 {
03588 case lang_output_section_statement_enum:
03589 {
03590 bfd_vma after;
03591 lang_output_section_statement_type *os;
03592
03593 os = &s->output_section_statement;
03594 if (os->bfd_section == NULL)
03595
03596 break;
03597
03598
03599
03600
03601
03602 if ((bfd_get_flavour (output_bfd) == bfd_target_ecoff_flavour
03603 || bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
03604 && (os->bfd_section->flags & SEC_COFF_SHARED_LIBRARY) != 0)
03605 {
03606 asection *input;
03607
03608 if (os->children.head == NULL
03609 || os->children.head->header.next != NULL
03610 || (os->children.head->header.type
03611 != lang_input_section_enum))
03612 einfo (_("%P%X: Internal error on COFF shared library"
03613 " section %s\n"), os->name);
03614
03615 input = os->children.head->input_section.section;
03616 bfd_set_section_vma (os->bfd_section->owner,
03617 os->bfd_section,
03618 bfd_section_vma (input->owner, input));
03619 os->bfd_section->size = input->size;
03620 break;
03621 }
03622
03623 if (bfd_is_abs_section (os->bfd_section))
03624 {
03625
03626 ASSERT (os->bfd_section->vma == 0);
03627 }
03628 else
03629 {
03630 if (os->addr_tree == NULL)
03631 {
03632
03633
03634 if (os->region == NULL
03635 || ((os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD))
03636 && os->region->name[0] == '*'
03637 && strcmp (os->region->name,
03638 DEFAULT_MEMORY_REGION) == 0))
03639 {
03640 os->region = lang_memory_default (os->bfd_section);
03641 }
03642
03643
03644
03645
03646 if (!IGNORE_SECTION (os->bfd_section)
03647 && ! link_info.relocatable
03648 && check_regions
03649 && strcmp (os->region->name,
03650 DEFAULT_MEMORY_REGION) == 0
03651 && lang_memory_region_list != NULL
03652 && (strcmp (lang_memory_region_list->name,
03653 DEFAULT_MEMORY_REGION) != 0
03654 || lang_memory_region_list->next != NULL))
03655 {
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665 if (command_line.check_section_addresses)
03666 einfo (_("%P%F: error: no memory region specified"
03667 " for loadable section `%s'\n"),
03668 bfd_get_section_name (output_bfd,
03669 os->bfd_section));
03670 else
03671 einfo (_("%P: warning: no memory region specified"
03672 " for loadable section `%s'\n"),
03673 bfd_get_section_name (output_bfd,
03674 os->bfd_section));
03675 }
03676
03677 dot = os->region->current;
03678
03679 if (os->section_alignment == -1)
03680 {
03681 bfd_vma olddot;
03682
03683 olddot = dot;
03684 dot = align_power (dot,
03685 os->bfd_section->alignment_power);
03686
03687 if (dot != olddot && config.warn_section_align)
03688 einfo (_("%P: warning: changing start of section"
03689 " %s by %u bytes\n"),
03690 os->name, (unsigned int) (dot - olddot));
03691 }
03692 }
03693 else
03694 {
03695 etree_value_type r;
03696
03697 os->processed = -1;
03698 r = exp_fold_tree (os->addr_tree,
03699 abs_output_section,
03700 lang_allocating_phase_enum,
03701 dot, &dot);
03702 os->processed = 0;
03703
03704 if (!r.valid_p)
03705 einfo (_("%F%S: non constant or forward reference"
03706 " address expression for section %s\n"),
03707 os->name);
03708
03709 dot = r.value + r.section->bfd_section->vma;
03710 }
03711
03712
03713
03714
03715 if (os->section_alignment != -1)
03716 dot = align_power (dot, os->section_alignment);
03717
03718 bfd_set_section_vma (0, os->bfd_section, dot);
03719
03720 os->bfd_section->output_offset = 0;
03721 }
03722
03723 lang_size_sections_1 (os->children.head, os, &os->children.head,
03724 os->fill, dot, relax, check_regions);
03725
03726
03727
03728 after = ((os->bfd_section->vma
03729 + TO_ADDR (os->bfd_section->size)
03730 + os->block_value - 1)
03731 & - (bfd_vma) os->block_value);
03732
03733 if (bfd_is_abs_section (os->bfd_section))
03734 ASSERT (after == os->bfd_section->vma);
03735 else
03736 os->bfd_section->size
03737 = TO_SIZE (after - os->bfd_section->vma);
03738
03739 dot = os->bfd_section->vma;
03740
03741 if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0
03742 || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0
03743 || link_info.relocatable)
03744 dot += TO_ADDR (os->bfd_section->size);
03745
03746 os->processed = 1;
03747
03748 if (os->update_dot_tree != 0)
03749 exp_fold_tree (os->update_dot_tree, abs_output_section,
03750 lang_allocating_phase_enum, dot, &dot);
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760 if (os->region != NULL
03761 && ((os->bfd_section->flags & SEC_NEVER_LOAD) == 0
03762 || (os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD))))
03763 {
03764 os->region->current = dot;
03765
03766 if (check_regions)
03767
03768 os_region_check (os, os->region, os->addr_tree,
03769 os->bfd_section->vma);
03770
03771
03772
03773 if (os->lma_region == NULL && os->load_base == NULL)
03774 os->lma_region = os->region;
03775
03776 if (os->lma_region != NULL && os->lma_region != os->region)
03777 {
03778
03779 os->load_base = exp_intop (os->lma_region->current);
03780 os->lma_region->current +=
03781 TO_ADDR (os->bfd_section->size);
03782 if (check_regions)
03783 os_region_check (os, os->lma_region, NULL,
03784 os->bfd_section->lma);
03785 }
03786 }
03787 }
03788 break;
03789
03790 case lang_constructors_statement_enum:
03791 dot = lang_size_sections_1 (constructor_list.head,
03792 output_section_statement,
03793 &s->wild_statement.children.head,
03794 fill, dot, relax, check_regions);
03795 break;
03796
03797 case lang_data_statement_enum:
03798 {
03799 unsigned int size = 0;
03800
03801 s->data_statement.output_vma =
03802 dot - output_section_statement->bfd_section->vma;
03803 s->data_statement.output_section =
03804 output_section_statement->bfd_section;
03805
03806
03807
03808 exp_fold_tree (s->data_statement.exp, abs_output_section,
03809 lang_allocating_phase_enum, dot, &dot);
03810
03811 switch (s->data_statement.type)
03812 {
03813 default:
03814 abort ();
03815 case QUAD:
03816 case SQUAD:
03817 size = QUAD_SIZE;
03818 break;
03819 case LONG:
03820 size = LONG_SIZE;
03821 break;
03822 case SHORT:
03823 size = SHORT_SIZE;
03824 break;
03825 case BYTE:
03826 size = BYTE_SIZE;
03827 break;
03828 }
03829 if (size < TO_SIZE ((unsigned) 1))
03830 size = TO_SIZE ((unsigned) 1);
03831 dot += TO_ADDR (size);
03832 output_section_statement->bfd_section->size += size;
03833 }
03834 break;
03835
03836 case lang_reloc_statement_enum:
03837 {
03838 int size;
03839
03840 s->reloc_statement.output_vma =
03841 dot - output_section_statement->bfd_section->vma;
03842 s->reloc_statement.output_section =
03843 output_section_statement->bfd_section;
03844 size = bfd_get_reloc_size (s->reloc_statement.howto);
03845 dot += TO_ADDR (size);
03846 output_section_statement->bfd_section->size += size;
03847 }
03848 break;
03849
03850 case lang_wild_statement_enum:
03851
03852 dot = lang_size_sections_1 (s->wild_statement.children.head,
03853 output_section_statement,
03854 &s->wild_statement.children.head,
03855 fill, dot, relax, check_regions);
03856
03857 break;
03858
03859 case lang_object_symbols_statement_enum:
03860 link_info.create_object_symbols_section =
03861 output_section_statement->bfd_section;
03862 break;
03863 case lang_output_statement_enum:
03864 case lang_target_statement_enum:
03865 break;
03866 case lang_input_section_enum:
03867 {
03868 asection *i;
03869
03870 i = (*prev)->input_section.section;
03871 if (relax)
03872 {
03873 bfd_boolean again;
03874
03875 if (! bfd_relax_section (i->owner, i, &link_info, &again))
03876 einfo (_("%P%F: can't relax section: %E\n"));
03877 if (again)
03878 *relax = TRUE;
03879 }
03880 dot = size_input_section (prev, output_section_statement,
03881 output_section_statement->fill, dot);
03882 }
03883 break;
03884 case lang_input_statement_enum:
03885 break;
03886 case lang_fill_statement_enum:
03887 s->fill_statement.output_section =
03888 output_section_statement->bfd_section;
03889
03890 fill = s->fill_statement.fill;
03891 break;
03892 case lang_assignment_statement_enum:
03893 {
03894 bfd_vma newdot = dot;
03895
03896 exp_fold_tree (s->assignment_statement.exp,
03897 output_section_statement,
03898 lang_allocating_phase_enum,
03899 dot,
03900 &newdot);
03901
03902 if (newdot != dot)
03903 {
03904 if (output_section_statement == abs_output_section)
03905 {
03906
03907
03908 lang_memory_region_lookup (DEFAULT_MEMORY_REGION,
03909 FALSE)->current = newdot;
03910 }
03911 else
03912 {
03913
03914
03915
03916 insert_pad (&s->header.next, fill, TO_SIZE (newdot - dot),
03917 output_section_statement->bfd_section, dot);
03918
03919
03920 s = s->header.next;
03921 }
03922
03923
03924
03925
03926 if (!(output_section_statement->flags
03927 & (SEC_NEVER_LOAD | SEC_ALLOC)))
03928 output_section_statement->bfd_section->flags |= SEC_ALLOC;
03929
03930 dot = newdot;
03931 }
03932 }
03933 break;
03934
03935 case lang_padding_statement_enum:
03936
03937
03938
03939
03940
03941 s->padding_statement.size = 0;
03942
03943
03944
03945
03946
03947
03948 s->padding_statement.output_offset
03949 = dot - output_section_statement->bfd_section->vma;
03950 break;
03951
03952 case lang_group_statement_enum:
03953 dot = lang_size_sections_1 (s->group_statement.children.head,
03954 output_section_statement,
03955 &s->group_statement.children.head,
03956 fill, dot, relax, check_regions);
03957 break;
03958
03959 default:
03960 FAIL ();
03961 break;
03962
03963
03964 case lang_address_statement_enum:
03965 break;
03966 }
03967 prev = &s->header.next;
03968 }
03969 return dot;
03970 }
03971
03972 bfd_vma
03973 lang_size_sections
03974 (lang_statement_union_type *s,
03975 lang_output_section_statement_type *output_section_statement,
03976 lang_statement_union_type **prev,
03977 fill_type *fill,
03978 bfd_vma dot,
03979 bfd_boolean *relax,
03980 bfd_boolean check_regions)
03981 {
03982 bfd_vma result;
03983
03984
03985 lang_statement_iteration++;
03986
03987 exp_data_seg.phase = exp_dataseg_none;
03988 result = lang_size_sections_1 (s, output_section_statement, prev, fill,
03989 dot, relax, check_regions);
03990 if (exp_data_seg.phase == exp_dataseg_end_seen
03991 && link_info.relro && exp_data_seg.relro_end)
03992 {
03993
03994
03995 bfd_vma old_min_base, relro_end, maxpage;
03996
03997 exp_data_seg.phase = exp_dataseg_relro_adjust;
03998 old_min_base = exp_data_seg.min_base;
03999 maxpage = exp_data_seg.maxpagesize;
04000 exp_data_seg.base += (-exp_data_seg.relro_end
04001 & (exp_data_seg.pagesize - 1));
04002
04003 relro_end = (exp_data_seg.relro_end + exp_data_seg.pagesize - 1)
04004 & ~(exp_data_seg.pagesize - 1);
04005 if (old_min_base + maxpage < exp_data_seg.base)
04006 {
04007 exp_data_seg.base -= maxpage;
04008 relro_end -= maxpage;
04009 }
04010 result = lang_size_sections_1 (s, output_section_statement, prev, fill,
04011 dot, relax, check_regions);
04012 if (exp_data_seg.relro_end > relro_end)
04013 {
04014
04015
04016
04017 asection *sec;
04018 unsigned int max_alignment_power = 0;
04019
04020
04021
04022 for (sec = output_bfd->sections; sec; sec = sec->next)
04023 if (sec->vma >= exp_data_seg.base
04024 && sec->vma < exp_data_seg.relro_end
04025 && sec->alignment_power > max_alignment_power)
04026 max_alignment_power = sec->alignment_power;
04027
04028 if (((bfd_vma) 1 << max_alignment_power) < exp_data_seg.pagesize)
04029 {
04030 if (exp_data_seg.base - (1 << max_alignment_power)
04031 < old_min_base)
04032 exp_data_seg.base += exp_data_seg.pagesize;
04033 exp_data_seg.base -= (1 << max_alignment_power);
04034 result = lang_size_sections_1 (s, output_section_statement,
04035 prev, fill, dot, relax,
04036 check_regions);
04037 }
04038 }
04039 link_info.relro_start = exp_data_seg.base;
04040 link_info.relro_end = exp_data_seg.relro_end;
04041 }
04042 else if (exp_data_seg.phase == exp_dataseg_end_seen)
04043 {
04044
04045
04046 bfd_vma first, last;
04047
04048 first = -exp_data_seg.base & (exp_data_seg.pagesize - 1);
04049 last = exp_data_seg.end & (exp_data_seg.pagesize - 1);
04050 if (first && last
04051 && ((exp_data_seg.base & ~(exp_data_seg.pagesize - 1))
04052 != (exp_data_seg.end & ~(exp_data_seg.pagesize - 1)))
04053 && first + last <= exp_data_seg.pagesize)
04054 {
04055 exp_data_seg.phase = exp_dataseg_adjust;
04056 lang_statement_iteration++;
04057 result = lang_size_sections_1 (s, output_section_statement, prev,
04058 fill, dot, relax, check_regions);
04059 }
04060 }
04061
04062 return result;
04063 }
04064
04065
04066
04067 static bfd_vma
04068 lang_do_assignments_1
04069 (lang_statement_union_type *s,
04070 lang_output_section_statement_type *output_section_statement,
04071 fill_type *fill,
04072 bfd_vma dot)
04073 {
04074 for (; s != NULL; s = s->header.next)
04075 {
04076 switch (s->header.type)
04077 {
04078 case lang_constructors_statement_enum:
04079 dot = lang_do_assignments_1 (constructor_list.head,
04080 output_section_statement,
04081 fill,
04082 dot);
04083 break;
04084
04085 case lang_output_section_statement_enum:
04086 {
04087 lang_output_section_statement_type *os;
04088
04089 os = &(s->output_section_statement);
04090 if (os->bfd_section != NULL)
04091 {
04092 dot = os->bfd_section->vma;
04093 lang_do_assignments_1 (os->children.head, os, os->fill, dot);
04094
04095 if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0
04096 || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0
04097 || link_info.relocatable)
04098 dot += TO_ADDR (os->bfd_section->size);
04099 }
04100 if (os->load_base)
04101 {
04102
04103
04104 if (os->bfd_section)
04105 {
04106 os->bfd_section->lma
04107 = exp_get_abs_int (os->load_base, 0, "load base",
04108 lang_final_phase_enum);
04109 }
04110 }
04111 }
04112 break;
04113 case lang_wild_statement_enum:
04114
04115 dot = lang_do_assignments_1 (s->wild_statement.children.head,
04116 output_section_statement,
04117 fill, dot);
04118
04119 break;
04120
04121 case lang_object_symbols_statement_enum:
04122 case lang_output_statement_enum:
04123 case lang_target_statement_enum:
04124 break;
04125 case lang_data_statement_enum:
04126 {
04127 etree_value_type value;
04128
04129 value = exp_fold_tree (s->data_statement.exp,
04130 abs_output_section,
04131 lang_final_phase_enum, dot, &dot);
04132 if (!value.valid_p)
04133 einfo (_("%F%P: invalid data statement\n"));
04134 s->data_statement.value
04135 = value.value + value.section->bfd_section->vma;
04136 }
04137 {
04138 unsigned int size;
04139 switch (s->data_statement.type)
04140 {
04141 default:
04142 abort ();
04143 case QUAD:
04144 case SQUAD:
04145 size = QUAD_SIZE;
04146 break;
04147 case LONG:
04148 size = LONG_SIZE;
04149 break;
04150 case SHORT:
04151 size = SHORT_SIZE;
04152 break;
04153 case BYTE:
04154 size = BYTE_SIZE;
04155 break;
04156 }
04157 if (size < TO_SIZE ((unsigned) 1))
04158 size = TO_SIZE ((unsigned) 1);
04159 dot += TO_ADDR (size);
04160 }
04161 break;
04162
04163 case lang_reloc_statement_enum:
04164 {
04165 etree_value_type value;
04166
04167 value = exp_fold_tree (s->reloc_statement.addend_exp,
04168 abs_output_section,
04169 lang_final_phase_enum, dot, &dot);
04170 s->reloc_statement.addend_value = value.value;
04171 if (!value.valid_p)
04172 einfo (_("%F%P: invalid reloc statement\n"));
04173 }
04174 dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto));
04175 break;
04176
04177 case lang_input_section_enum:
04178 {
04179 asection *in = s->input_section.section;
04180
04181 if ((in->flags & SEC_EXCLUDE) == 0)
04182 dot += TO_ADDR (in->size);
04183 }
04184 break;
04185
04186 case lang_input_statement_enum:
04187 break;
04188 case lang_fill_statement_enum:
04189 fill = s->fill_statement.fill;
04190 break;
04191 case lang_assignment_statement_enum:
04192 {
04193 exp_fold_tree (s->assignment_statement.exp,
04194 output_section_statement,
04195 lang_final_phase_enum,
04196 dot,
04197 &dot);
04198 }
04199
04200 break;
04201 case lang_padding_statement_enum:
04202 dot += TO_ADDR (s->padding_statement.size);
04203 break;
04204
04205 case lang_group_statement_enum:
04206 dot = lang_do_assignments_1 (s->group_statement.children.head,
04207 output_section_statement,
04208 fill, dot);
04209
04210 break;
04211
04212 default:
04213 FAIL ();
04214 break;
04215 case lang_address_statement_enum:
04216 break;
04217 }
04218
04219 }
04220 return dot;
04221 }
04222
04223 void
04224 lang_do_assignments
04225 (lang_statement_union_type *s,
04226 lang_output_section_statement_type *output_section_statement,
04227 fill_type *fill,
04228 bfd_vma dot)
04229 {
04230
04231 lang_statement_iteration++;
04232 lang_do_assignments_1 (s, output_section_statement, fill, dot);
04233 }
04234
04235
04236
04237
04238
04239
04240
04241
04242 static void
04243 lang_set_startof (void)
04244 {
04245 asection *s;
04246
04247 if (link_info.relocatable)
04248 return;
04249
04250 for (s = output_bfd->sections; s != NULL; s = s->next)
04251 {
04252 const char *secname;
04253 char *buf;
04254 struct bfd_link_hash_entry *h;
04255
04256 secname = bfd_get_section_name (output_bfd, s);
04257 buf = xmalloc (10 + strlen (secname));
04258
04259 sprintf (buf, ".startof.%s", secname);
04260 h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
04261 if (h != NULL && h->type == bfd_link_hash_undefined)
04262 {
04263 h->type = bfd_link_hash_defined;
04264 h->u.def.value = bfd_get_section_vma (output_bfd, s);
04265 h->u.def.section = bfd_abs_section_ptr;
04266 }
04267
04268 sprintf (buf, ".sizeof.%s", secname);
04269 h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
04270 if (h != NULL && h->type == bfd_link_hash_undefined)
04271 {
04272 h->type = bfd_link_hash_defined;
04273 h->u.def.value = TO_ADDR (s->size);
04274 h->u.def.section = bfd_abs_section_ptr;
04275 }
04276
04277 free (buf);
04278 }
04279 }
04280
04281 static void
04282 lang_finish (void)
04283 {
04284 struct bfd_link_hash_entry *h;
04285 bfd_boolean warn;
04286
04287 if (link_info.relocatable || link_info.shared)
04288 warn = FALSE;
04289 else
04290 warn = TRUE;
04291
04292 if (entry_symbol.name == NULL)
04293 {
04294
04295
04296 entry_symbol.name = "start";
04297 warn = FALSE;
04298 }
04299
04300 h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name,
04301 FALSE, FALSE, TRUE);
04302 if (h != NULL
04303 && (h->type == bfd_link_hash_defined
04304 || h->type == bfd_link_hash_defweak)
04305 && h->u.def.section->output_section != NULL)
04306 {
04307 bfd_vma val;
04308
04309 val = (h->u.def.value
04310 + bfd_get_section_vma (output_bfd,
04311 h->u.def.section->output_section)
04312 + h->u.def.section->output_offset);
04313 if (! bfd_set_start_address (output_bfd, val))
04314 einfo (_("%P%F:%s: can't set start address\n"), entry_symbol.name);
04315 }
04316 else
04317 {
04318 bfd_vma val;
04319 const char *send;
04320
04321
04322
04323 val = bfd_scan_vma (entry_symbol.name, &send, 0);
04324 if (*send == '\0')
04325 {
04326 if (! bfd_set_start_address (output_bfd, val))
04327 einfo (_("%P%F: can't set start address\n"));
04328 }
04329 else
04330 {
04331 asection *ts;
04332
04333
04334
04335 ts = bfd_get_section_by_name (output_bfd, entry_section);
04336 if (ts != NULL)
04337 {
04338 if (warn)
04339 einfo (_("%P: warning: cannot find entry symbol %s;"
04340 " defaulting to %V\n"),
04341 entry_symbol.name,
04342 bfd_get_section_vma (output_bfd, ts));
04343 if (! bfd_set_start_address (output_bfd,
04344 bfd_get_section_vma (output_bfd,
04345 ts)))
04346 einfo (_("%P%F: can't set start address\n"));
04347 }
04348 else
04349 {
04350 if (warn)
04351 einfo (_("%P: warning: cannot find entry symbol %s;"
04352 " not setting start address\n"),
04353 entry_symbol.name);
04354 }
04355 }
04356 }
04357
04358
04359
04360 }
04361
04362
04363
04364
04365 static void
04366 ignore_bfd_errors (const char *s ATTRIBUTE_UNUSED, ...)
04367 {
04368
04369 }
04370
04371
04372
04373
04374
04375 static void
04376 lang_check (void)
04377 {
04378 lang_statement_union_type *file;
04379 bfd *input_bfd;
04380 const bfd_arch_info_type *compatible;
04381
04382 for (file = file_chain.head; file != NULL; file = file->input_statement.next)
04383 {
04384 input_bfd = file->input_statement.the_bfd;
04385 compatible
04386 = bfd_arch_get_compatible (input_bfd, output_bfd,
04387 command_line.accept_unknown_input_arch);
04388
04389
04390
04391
04392
04393
04394
04395 if ((link_info.relocatable || link_info.emitrelocations)
04396 && (compatible == NULL
04397 || bfd_get_flavour (input_bfd) != bfd_get_flavour (output_bfd))
04398 && (bfd_get_file_flags (input_bfd) & HAS_RELOC) != 0)
04399 {
04400 einfo (_("%P%F: Relocatable linking with relocations from"
04401 " format %s (%B) to format %s (%B) is not supported\n"),
04402 bfd_get_target (input_bfd), input_bfd,
04403 bfd_get_target (output_bfd), output_bfd);
04404
04405 }
04406
04407 if (compatible == NULL)
04408 {
04409 if (command_line.warn_mismatch)
04410 einfo (_("%P: warning: %s architecture of input file `%B'"
04411 " is incompatible with %s output\n"),
04412 bfd_printable_name (input_bfd), input_bfd,
04413 bfd_printable_name (output_bfd));
04414 }
04415 else if (bfd_count_sections (input_bfd))
04416 {
04417
04418
04419
04420 bfd_error_handler_type pfn = NULL;
04421
04422
04423
04424
04425
04426
04427 if (! command_line.warn_mismatch)
04428 pfn = bfd_set_error_handler (ignore_bfd_errors);
04429 if (! bfd_merge_private_bfd_data (input_bfd, output_bfd))
04430 {
04431 if (command_line.warn_mismatch)
04432 einfo (_("%P%X: failed to merge target specific data"
04433 " of file %B\n"), input_bfd);
04434 }
04435 if (! command_line.warn_mismatch)
04436 bfd_set_error_handler (pfn);
04437 }
04438 }
04439 }
04440
04441
04442
04443
04444
04445 static void
04446 lang_common (void)
04447 {
04448 if (command_line.inhibit_common_definition)
04449 return;
04450 if (link_info.relocatable
04451 && ! command_line.force_common_definition)
04452 return;
04453
04454 if (! config.sort_common)
04455 bfd_link_hash_traverse (link_info.hash, lang_one_common, NULL);
04456 else
04457 {
04458 int power;
04459
04460 for (power = 4; power >= 0; power--)
04461 bfd_link_hash_traverse (link_info.hash, lang_one_common, &power);
04462 }
04463 }
04464
04465
04466
04467 static bfd_boolean
04468 lang_one_common (struct bfd_link_hash_entry *h, void *info)
04469 {
04470 unsigned int power_of_two;
04471 bfd_vma size;
04472 asection *section;
04473
04474 if (h->type != bfd_link_hash_common)
04475 return TRUE;
04476
04477 size = h->u.c.size;
04478 power_of_two = h->u.c.p->alignment_power;
04479
04480 if (config.sort_common
04481 && power_of_two < (unsigned int) *(int *) info)
04482 return TRUE;
04483
04484 section = h->u.c.p->section;
04485
04486
04487 section->size += ((bfd_vma) 1 << (power_of_two + opb_shift)) - 1;
04488 section->size &= (- (bfd_vma) 1 << (power_of_two + opb_shift));
04489
04490
04491 if (power_of_two > section->alignment_power)
04492 section->alignment_power = power_of_two;
04493
04494
04495 h->type = bfd_link_hash_defined;
04496 h->u.def.section = section;
04497 h->u.def.value = section->size;
04498
04499
04500 section->size += size;
04501
04502
04503
04504 section->flags |= SEC_ALLOC;
04505 section->flags &= ~SEC_IS_COMMON;
04506
04507 if (config.map_file != NULL)
04508 {
04509 static bfd_boolean header_printed;
04510 int len;
04511 char *name;
04512 char buf[50];
04513
04514 if (! header_printed)
04515 {
04516 minfo (_("\nAllocating common symbols\n"));
04517 minfo (_("Common symbol size file\n\n"));
04518 header_printed = TRUE;
04519 }
04520
04521 name = demangle (h->root.string);
04522 minfo ("%s", name);
04523 len = strlen (name);
04524 free (name);
04525
04526 if (len >= 19)
04527 {
04528 print_nl ();
04529 len = 0;
04530 }
04531 while (len < 20)
04532 {
04533 print_space ();
04534 ++len;
04535 }
04536
04537 minfo ("0x");
04538 if (size <= 0xffffffff)
04539 sprintf (buf, "%lx", (unsigned long) size);
04540 else
04541 sprintf_vma (buf, size);
04542 minfo ("%s", buf);
04543 len = strlen (buf);
04544
04545 while (len < 16)
04546 {
04547 print_space ();
04548 ++len;
04549 }
04550
04551 minfo ("%B\n", section->owner);
04552 }
04553
04554 return TRUE;
04555 }
04556
04557
04558
04559
04560
04561 static void
04562 lang_place_orphans (void)
04563 {
04564 LANG_FOR_EACH_INPUT_STATEMENT (file)
04565 {
04566 asection *s;
04567
04568 for (s = file->the_bfd->sections; s != NULL; s = s->next)
04569 {
04570 if (s->output_section == NULL)
04571 {
04572
04573
04574
04575 if (file->just_syms_flag)
04576 bfd_link_just_syms (file->the_bfd, s, &link_info);
04577 else if ((s->flags & SEC_EXCLUDE) != 0)
04578 s->output_section = bfd_abs_section_ptr;
04579 else if (strcmp (s->name, "COMMON") == 0)
04580 {
04581
04582
04583
04584 if (! link_info.relocatable
04585 || command_line.force_common_definition)
04586 {
04587 if (default_common_section == NULL)
04588 {
04589 default_common_section =
04590 lang_output_section_statement_lookup (".bss");
04591
04592 }
04593 lang_add_section (&default_common_section->children, s,
04594 default_common_section, file);
04595 }
04596 }
04597 else if (ldemul_place_orphan (file, s))
04598 ;
04599 else
04600 {
04601 lang_output_section_statement_type *os;
04602
04603 os = lang_output_section_statement_lookup (s->name);
04604 lang_add_section (&os->children, s, os, file);
04605 }
04606 }
04607 }
04608 }
04609 }
04610
04611 void
04612 lang_set_flags (lang_memory_region_type *ptr, const char *flags, int invert)
04613 {
04614 flagword *ptr_flags;
04615
04616 ptr_flags = invert ? &ptr->not_flags : &ptr->flags;
04617 while (*flags)
04618 {
04619 switch (*flags)
04620 {
04621 case 'A': case 'a':
04622 *ptr_flags |= SEC_ALLOC;
04623 break;
04624
04625 case 'R': case 'r':
04626 *ptr_flags |= SEC_READONLY;
04627 break;
04628
04629 case 'W': case 'w':
04630 *ptr_flags |= SEC_DATA;
04631 break;
04632
04633 case 'X': case 'x':
04634 *ptr_flags |= SEC_CODE;
04635 break;
04636
04637 case 'L': case 'l':
04638 case 'I': case 'i':
04639 *ptr_flags |= SEC_LOAD;
04640 break;
04641
04642 default:
04643 einfo (_("%P%F: invalid syntax in flags\n"));
04644 break;
04645 }
04646 flags++;
04647 }
04648 }
04649
04650
04651
04652
04653 void
04654 lang_for_each_input_file (void (*func) (lang_input_statement_type *))
04655 {
04656 lang_input_statement_type *f;
04657
04658 for (f = (lang_input_statement_type *) input_file_chain.head;
04659 f != NULL;
04660 f = (lang_input_statement_type *) f->next_real_file)
04661 func (f);
04662 }
04663
04664
04665
04666
04667
04668 void
04669 lang_for_each_file (void (*func) (lang_input_statement_type *))
04670 {
04671 LANG_FOR_EACH_INPUT_STATEMENT (f)
04672 {
04673 func (f);
04674 }
04675 }
04676
04677 void
04678 ldlang_add_file (lang_input_statement_type *entry)
04679 {
04680 bfd **pp;
04681
04682 lang_statement_append (&file_chain,
04683 (lang_statement_union_type *) entry,
04684 &entry->next);
04685
04686
04687
04688 ASSERT (entry->the_bfd->link_next == NULL);
04689 ASSERT (entry->the_bfd != output_bfd);
04690 for (pp = &link_info.input_bfds; *pp != NULL; pp = &(*pp)->link_next)
04691 ;
04692 *pp = entry->the_bfd;
04693 entry->the_bfd->usrdata = entry;
04694 bfd_set_gp_size (entry->the_bfd, g_switch_value);
04695
04696
04697
04698
04699
04700
04701
04702
04703
04704
04705
04706 bfd_map_over_sections (entry->the_bfd, section_already_linked, entry);
04707 }
04708
04709 void
04710 lang_add_output (const char *name, int from_script)
04711 {
04712
04713 if (!had_output_filename || !from_script)
04714 {
04715 output_filename = name;
04716 had_output_filename = TRUE;
04717 }
04718 }
04719
04720 static lang_output_section_statement_type *current_section;
04721
04722 static int
04723 topower (int x)
04724 {
04725 unsigned int i = 1;
04726 int l;
04727
04728 if (x < 0)
04729 return -1;
04730
04731 for (l = 0; l < 32; l++)
04732 {
04733 if (i >= (unsigned int) x)
04734 return l;
04735 i <<= 1;
04736 }
04737
04738 return 0;
04739 }
04740
04741 lang_output_section_statement_type *
04742 lang_enter_output_section_statement (const char *output_section_statement_name,
04743 etree_type *address_exp,
04744 enum section_type sectype,
04745 etree_type *align,
04746 etree_type *subalign,
04747 etree_type *ebase,
04748 int constraint)
04749 {
04750 lang_output_section_statement_type *os;
04751
04752 current_section =
04753 os =
04754 lang_output_section_statement_lookup_1 (output_section_statement_name,
04755 constraint);
04756
04757
04758
04759 if (os->addr_tree == NULL)
04760 {
04761 os->addr_tree = address_exp;
04762 }
04763 os->sectype = sectype;
04764 if (sectype != noload_section)
04765 os->flags = SEC_NO_FLAGS;
04766 else
04767 os->flags = SEC_NEVER_LOAD;
04768 os->block_value = 1;
04769 stat_ptr = &os->children;
04770
04771 os->subsection_alignment =
04772 topower (exp_get_value_int (subalign, -1, "subsection alignment", 0));
04773 os->section_alignment =
04774 topower (exp_get_value_int (align, -1, "section alignment", 0));
04775
04776 os->load_base = ebase;
04777 return os;
04778 }
04779
04780 void
04781 lang_final (void)
04782 {
04783 lang_output_statement_type *new =
04784 new_stat (lang_output_statement, stat_ptr);
04785
04786 new->name = output_filename;
04787 }
04788
04789
04790
04791 void
04792 lang_reset_memory_regions (void)
04793 {
04794 lang_memory_region_type *p = lang_memory_region_list;
04795 asection *o;
04796
04797 for (p = lang_memory_region_list; p != NULL; p = p->next)
04798 {
04799 p->old_length = (bfd_size_type) (p->current - p->origin);
04800 p->current = p->origin;
04801 }
04802
04803 for (o = output_bfd->sections; o != NULL; o = o->next)
04804 {
04805
04806 o->rawsize = o->size;
04807 o->size = 0;
04808 }
04809 }
04810
04811
04812
04813 static void
04814 gc_section_callback (lang_wild_statement_type *ptr,
04815 struct wildcard_list *sec ATTRIBUTE_UNUSED,
04816 asection *section,
04817 lang_input_statement_type *file ATTRIBUTE_UNUSED,
04818 void *data ATTRIBUTE_UNUSED)
04819 {
04820
04821
04822 if (ptr->keep_sections)
04823 section->flags |= SEC_KEEP;
04824 }
04825
04826
04827
04828 static void
04829 lang_gc_sections_1 (lang_statement_union_type *s)
04830 {
04831 for (; s != NULL; s = s->header.next)
04832 {
04833 switch (s->header.type)
04834 {
04835 case lang_wild_statement_enum:
04836 walk_wild (&s->wild_statement, gc_section_callback, NULL);
04837 break;
04838 case lang_constructors_statement_enum:
04839 lang_gc_sections_1 (constructor_list.head);
04840 break;
04841 case lang_output_section_statement_enum:
04842 lang_gc_sections_1 (s->output_section_statement.children.head);
04843 break;
04844 case lang_group_statement_enum:
04845 lang_gc_sections_1 (s->group_statement.children.head);
04846 break;
04847 default:
04848 break;
04849 }
04850 }
04851 }
04852
04853 static void
04854 lang_gc_sections (void)
04855 {
04856 struct bfd_link_hash_entry *h;
04857 ldlang_undef_chain_list_type *ulist;
04858
04859
04860
04861 lang_gc_sections_1 (statement_list.head);
04862
04863
04864
04865
04866 for (ulist = link_info.gc_sym_list; ulist; ulist = ulist->next)
04867 {
04868 h = bfd_link_hash_lookup (link_info.hash, ulist->name,
04869 FALSE, FALSE, FALSE);
04870
04871 if (h != NULL
04872 && (h->type == bfd_link_hash_defined
04873 || h->type == bfd_link_hash_defweak)
04874 && ! bfd_is_abs_section (h->u.def.section))
04875 {
04876 h->u.def.section->flags |= SEC_KEEP;
04877 }
04878 }
04879
04880
04881
04882
04883 if (link_info.relocatable)
04884 {
04885 LANG_FOR_EACH_INPUT_STATEMENT (f)
04886 {
04887 asection *sec;
04888 for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next)
04889 if ((sec->flags & SEC_DEBUGGING) == 0)
04890 sec->flags &= ~SEC_EXCLUDE;
04891 }
04892 }
04893
04894 if (command_line.gc_sections)
04895 bfd_gc_sections (output_bfd, &link_info);
04896 }
04897
04898 void
04899 lang_process (void)
04900 {
04901 current_target = default_target;
04902
04903
04904 lang_for_each_statement (ldlang_open_output);
04905 init_opb ();
04906
04907 ldemul_create_output_section_statements ();
04908
04909
04910 lang_place_undefineds ();
04911
04912 if (!bfd_section_already_linked_table_init ())
04913 einfo (_("%P%F: Failed to create hash table\n"));
04914
04915
04916 current_target = default_target;
04917 open_input_bfds (statement_list.head, FALSE);
04918
04919 link_info.gc_sym_list = &entry_symbol;
04920 if (entry_symbol.name == NULL)
04921 link_info.gc_sym_list = ldlang_undef_chain_list_head;
04922
04923 #ifdef IPA_LINK
04924 if (is_ipa)
04925 return;
04926 #endif
04927
04928 ldemul_after_open ();
04929
04930 bfd_section_already_linked_table_free ();
04931
04932
04933
04934
04935
04936
04937 lang_check ();
04938
04939
04940 if (command_line.version_exports_section)
04941 lang_do_version_exports_section ();
04942
04943
04944
04945 ldctor_build_sets ();
04946
04947
04948 lang_gc_sections ();
04949
04950
04951 lang_common ();
04952
04953
04954 update_wild_statements (statement_list.head);
04955
04956
04957
04958 map_input_to_output_sections (statement_list.head, NULL, NULL);
04959
04960
04961 lang_place_orphans ();
04962
04963 if (! link_info.relocatable)
04964 {
04965 asection *found;
04966
04967
04968
04969
04970
04971 bfd_merge_sections (output_bfd, &link_info);
04972
04973
04974 found = bfd_get_section_by_name (output_bfd, ".text");
04975
04976 if (found != NULL)
04977 {
04978 if (config.text_read_only)
04979 found->flags |= SEC_READONLY;
04980 else
04981 found->flags &= ~SEC_READONLY;
04982 }
04983 }
04984
04985
04986
04987 ldemul_before_allocation ();
04988
04989 if (!link_info.relocatable)
04990 strip_excluded_output_sections ();
04991
04992
04993
04994 lang_record_phdrs ();
04995
04996
04997 lang_size_sections (statement_list.head, abs_output_section,
04998 &statement_list.head, 0, 0, NULL,
04999 command_line.relax ? FALSE : TRUE);
05000
05001
05002 if (command_line.relax)
05003 {
05004
05005 bfd_boolean relax_again;
05006
05007 do
05008 {
05009 relax_again = FALSE;
05010
05011
05012
05013
05014
05015
05016
05017 lang_do_assignments (statement_list.head, abs_output_section,
05018 NULL, 0);
05019
05020
05021
05022 lang_reset_memory_regions ();
05023
05024
05025
05026 lang_size_sections (statement_list.head, abs_output_section,
05027 &statement_list.head, 0, 0, &relax_again, FALSE);
05028
05029
05030
05031 if (!relax_again && link_info.need_relax_finalize)
05032 {
05033 link_info.need_relax_finalize = FALSE;
05034 relax_again = TRUE;
05035 }
05036 }
05037 while (relax_again);
05038
05039
05040 lang_do_assignments (statement_list.head, abs_output_section, NULL, 0);
05041 lang_reset_memory_regions ();
05042 lang_size_sections (statement_list.head, abs_output_section,
05043 &statement_list.head, 0, 0, NULL, TRUE);
05044 }
05045
05046
05047
05048 ldemul_after_allocation ();
05049
05050
05051 lang_set_startof ();
05052
05053
05054
05055
05056 lang_do_assignments (statement_list.head, abs_output_section, NULL, 0);
05057
05058
05059 if (! link_info.relocatable
05060 && command_line.check_section_addresses)
05061 lang_check_section_addresses ();
05062
05063
05064
05065 ldemul_finish ();
05066 lang_finish ();
05067 }
05068
05069
05070
05071 void
05072 lang_add_wild (struct wildcard_spec *filespec,
05073 struct wildcard_list *section_list,
05074 bfd_boolean keep_sections)
05075 {
05076 struct wildcard_list *curr, *next;
05077 lang_wild_statement_type *new;
05078
05079
05080 for (curr = section_list, section_list = NULL;
05081 curr != NULL;
05082 section_list = curr, curr = next)
05083 {
05084 if (curr->spec.name != NULL && strcmp (curr->spec.name, "COMMON") == 0)
05085 placed_commons = TRUE;
05086
05087 next = curr->next;
05088 curr->next = section_list;
05089 }
05090
05091 if (filespec != NULL && filespec->name != NULL)
05092 {
05093 if (strcmp (filespec->name, "*") == 0)
05094 filespec->name = NULL;
05095 else if (! wildcardp (filespec->name))
05096 lang_has_input_file = TRUE;
05097 }
05098
05099 new = new_stat (lang_wild_statement, stat_ptr);
05100 new->filename = NULL;
05101 new->filenames_sorted = FALSE;
05102 if (filespec != NULL)
05103 {
05104 new->filename = filespec->name;
05105 new->filenames_sorted = filespec->sorted == by_name;
05106 }
05107 new->section_list = section_list;
05108 new->keep_sections = keep_sections;
05109 lang_list_init (&new->children);
05110 }
05111
05112 void
05113 lang_section_start (const char *name, etree_type *address,
05114 const segment_type *segment)
05115 {
05116 lang_address_statement_type *ad;
05117
05118 ad = new_stat (lang_address_statement, stat_ptr);
05119 ad->section_name = name;
05120 ad->address = address;
05121 ad->segment = segment;
05122 }
05123
05124
05125
05126
05127
05128
05129 void
05130 lang_add_entry (const char *name, bfd_boolean cmdline)
05131 {
05132 if (entry_symbol.name == NULL
05133 || cmdline
05134 || ! entry_from_cmdline)
05135 {
05136 entry_symbol.name = name;
05137 entry_from_cmdline = cmdline;
05138 }
05139 }
05140
05141 void
05142 lang_add_target (const char *name)
05143 {
05144 lang_target_statement_type *new = new_stat (lang_target_statement,
05145 stat_ptr);
05146
05147 new->target = name;
05148
05149 }
05150
05151 void
05152 lang_add_map (const char *name)
05153 {
05154 while (*name)
05155 {
05156 switch (*name)
05157 {
05158 case 'F':
05159 map_option_f = TRUE;
05160 break;
05161 }
05162 name++;
05163 }
05164 }
05165
05166 void
05167 lang_add_fill (fill_type *fill)
05168 {
05169 lang_fill_statement_type *new = new_stat (lang_fill_statement,
05170 stat_ptr);
05171
05172 new->fill = fill;
05173 }
05174
05175 void
05176 lang_add_data (int type, union etree_union *exp)
05177 {
05178
05179 lang_data_statement_type *new = new_stat (lang_data_statement,
05180 stat_ptr);
05181
05182 new->exp = exp;
05183 new->type = type;
05184
05185 }
05186
05187
05188
05189
05190
05191
05192
05193
05194 void
05195 lang_add_reloc (bfd_reloc_code_real_type reloc,
05196 reloc_howto_type *howto,
05197 asection *section,
05198 const char *name,
05199 union etree_union *addend)
05200 {
05201 lang_reloc_statement_type *p = new_stat (lang_reloc_statement, stat_ptr);
05202
05203 p->reloc = reloc;
05204 p->howto = howto;
05205 p->section = section;
05206 p->name = name;
05207 p->addend_exp = addend;
05208
05209 p->addend_value = 0;
05210 p->output_section = NULL;
05211 p->output_vma = 0;
05212 }
05213
05214 lang_assignment_statement_type *
05215 lang_add_assignment (etree_type *exp)
05216 {
05217 lang_assignment_statement_type *new = new_stat (lang_assignment_statement,
05218 stat_ptr);
05219
05220 new->exp = exp;
05221 return new;
05222 }
05223
05224 void
05225 lang_add_attribute (enum statement_enum attribute)
05226 {
05227 new_statement (attribute, sizeof (lang_statement_union_type), stat_ptr);
05228 }
05229
05230 void
05231 lang_startup (const char *name)
05232 {
05233 if (startup_file != NULL)
05234 {
05235 einfo (_("%P%Fmultiple STARTUP files\n"));
05236 }
05237 first_file->filename = name;
05238 first_file->local_sym_name = name;
05239 first_file->real = TRUE;
05240
05241 startup_file = name;
05242 }
05243
05244 void
05245 lang_float (bfd_boolean maybe)
05246 {
05247 lang_float_flag = maybe;
05248 }
05249
05250
05251
05252
05253
05254
05255
05256
05257
05258
05259
05260
05261
05262 static void
05263 lang_get_regions (lang_memory_region_type **region,
05264 lang_memory_region_type **lma_region,
05265 const char *memspec,
05266 const char *lma_memspec,
05267 bfd_boolean have_lma,
05268 bfd_boolean have_vma)
05269 {
05270 *lma_region = lang_memory_region_lookup (lma_memspec, FALSE);
05271
05272
05273
05274
05275 if (lma_memspec != NULL
05276 && ! have_vma
05277 && strcmp (memspec, DEFAULT_MEMORY_REGION) == 0)
05278 *region = *lma_region;
05279 else
05280 *region = lang_memory_region_lookup (memspec, FALSE);
05281
05282 if (have_lma && lma_memspec != 0)
05283 einfo (_("%X%P:%S: section has both a load address and a load region\n"));
05284 }
05285
05286 void
05287 lang_leave_output_section_statement (fill_type *fill, const char *memspec,
05288 lang_output_section_phdr_list *phdrs,
05289 const char *lma_memspec)
05290 {
05291 lang_get_regions (¤t_section->region,
05292 ¤t_section->lma_region,
05293 memspec, lma_memspec,
05294 current_section->load_base != NULL,
05295 current_section->addr_tree != NULL);
05296 current_section->fill = fill;
05297 current_section->phdrs = phdrs;
05298 stat_ptr = &statement_list;
05299 }
05300
05301
05302
05303
05304
05305
05306 void
05307 lang_abs_symbol_at_beginning_of (const char *secname, const char *name)
05308 {
05309 struct bfd_link_hash_entry *h;
05310
05311 h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE);
05312 if (h == NULL)
05313 einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
05314
05315 if (h->type == bfd_link_hash_new
05316 || h->type == bfd_link_hash_undefined)
05317 {
05318 asection *sec;
05319
05320 h->type = bfd_link_hash_defined;
05321
05322 sec = bfd_get_section_by_name (output_bfd, secname);
05323 if (sec == NULL)
05324 h->u.def.value = 0;
05325 else
05326 h->u.def.value = bfd_get_section_vma (output_bfd, sec);
05327
05328 h->u.def.section = bfd_abs_section_ptr;
05329 }
05330 }
05331
05332
05333
05334
05335
05336
05337 void
05338 lang_abs_symbol_at_end_of (const char *secname, const char *name)
05339 {
05340 struct bfd_link_hash_entry *h;
05341
05342 h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE);
05343 if (h == NULL)
05344 einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
05345
05346 if (h->type == bfd_link_hash_new
05347 || h->type == bfd_link_hash_undefined)
05348 {
05349 asection *sec;
05350
05351 h->type = bfd_link_hash_defined;
05352
05353 sec = bfd_get_section_by_name (output_bfd, secname);
05354 if (sec == NULL)
05355 h->u.def.value = 0;
05356 else
05357 h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
05358 + TO_ADDR (sec->size));
05359
05360 h->u.def.section = bfd_abs_section_ptr;
05361 }
05362 }
05363
05364 void
05365 lang_statement_append (lang_statement_list_type *list,
05366 lang_statement_union_type *element,
05367 lang_statement_union_type **field)
05368 {
05369 *(list->tail) = element;
05370 list->tail = field;
05371 }
05372
05373
05374
05375 void
05376 lang_add_output_format (const char *format,
05377 const char *big,
05378 const char *little,
05379 int from_script)
05380 {
05381 if (output_target == NULL || !from_script)
05382 {
05383 if (command_line.endian == ENDIAN_BIG
05384 && big != NULL)
05385 format = big;
05386 else if (command_line.endian == ENDIAN_LITTLE
05387 && little != NULL)
05388 format = little;
05389
05390 output_target = format;
05391 }
05392 }
05393
05394
05395
05396
05397 void
05398 lang_enter_group (void)
05399 {
05400 lang_group_statement_type *g;
05401
05402 g = new_stat (lang_group_statement, stat_ptr);
05403 lang_list_init (&g->children);
05404 stat_ptr = &g->children;
05405 }
05406
05407
05408
05409
05410
05411
05412 void
05413 lang_leave_group (void)
05414 {
05415 stat_ptr = &statement_list;
05416 }
05417
05418
05419
05420
05421 void
05422 lang_new_phdr (const char *name,
05423 etree_type *type,
05424 bfd_boolean filehdr,
05425 bfd_boolean phdrs,
05426 etree_type *at,
05427 etree_type *flags)
05428 {
05429 struct lang_phdr *n, **pp;
05430
05431 n = stat_alloc (sizeof (struct lang_phdr));
05432 n->next = NULL;
05433 n->name = name;
05434 n->type = exp_get_value_int (type, 0, "program header type",
05435 lang_final_phase_enum);
05436 n->filehdr = filehdr;
05437 n->phdrs = phdrs;
05438 n->at = at;
05439 n->flags = flags;
05440
05441 for (pp = &lang_phdr_list; *pp != NULL; pp = &(*pp)->next)
05442 ;
05443 *pp = n;
05444 }
05445
05446
05447
05448
05449 static void
05450 lang_record_phdrs (void)
05451 {
05452 unsigned int alc;
05453 asection **secs;
05454 lang_output_section_phdr_list *last;
05455 struct lang_phdr *l;
05456 lang_output_section_statement_type *os;
05457
05458 alc = 10;
05459 secs = xmalloc (alc * sizeof (asection *));
05460 last = NULL;
05461 for (l = lang_phdr_list; l != NULL; l = l->next)
05462 {
05463 unsigned int c;
05464 flagword flags;
05465 bfd_vma at;
05466
05467 c = 0;
05468 for (os = &lang_output_section_statement.head->output_section_statement;
05469 os != NULL;
05470 os = os->next)
05471 {
05472 lang_output_section_phdr_list *pl;
05473
05474 if (os->constraint == -1)
05475 continue;
05476
05477 pl = os->phdrs;
05478 if (pl != NULL)
05479 last = pl;
05480 else
05481 {
05482 if (os->sectype == noload_section
05483 || os->bfd_section == NULL
05484 || (os->bfd_section->flags & SEC_ALLOC) == 0)
05485 continue;
05486 pl = last;
05487 }
05488
05489 if (os->bfd_section == NULL)
05490 continue;
05491
05492 for (; pl != NULL; pl = pl->next)
05493 {
05494 if (strcmp (pl->name, l->name) == 0)
05495 {
05496 if (c >= alc)
05497 {
05498 alc *= 2;
05499 secs = xrealloc (secs, alc * sizeof (asection *));
05500 }
05501 secs[c] = os->bfd_section;
05502 ++c;
05503 pl->used = TRUE;
05504 }
05505 }
05506 }
05507
05508 if (l->flags == NULL)
05509 flags = 0;
05510 else
05511 flags = exp_get_vma (l->flags, 0, "phdr flags",
05512 lang_final_phase_enum);
05513
05514 if (l->at == NULL)
05515 at = 0;
05516 else
05517 at = exp_get_vma (l->at, 0, "phdr load address",
05518 lang_final_phase_enum);
05519
05520 if (! bfd_record_phdr (output_bfd, l->type,
05521 l->flags != NULL, flags, l->at != NULL,
05522 at, l->filehdr, l->phdrs, c, secs))
05523 einfo (_("%F%P: bfd_record_phdr failed: %E\n"));
05524 }
05525
05526 free (secs);
05527
05528
05529 for (os = &lang_output_section_statement.head->output_section_statement;
05530 os != NULL;
05531 os = os->next)
05532 {
05533 lang_output_section_phdr_list *pl;
05534
05535 if (os->constraint == -1
05536 || os->bfd_section == NULL)
05537 continue;
05538
05539 for (pl = os->phdrs;
05540 pl != NULL;
05541 pl = pl->next)
05542 if (! pl->used && strcmp (pl->name, "NONE") != 0)
05543 einfo (_("%X%P: section `%s' assigned to non-existent phdr `%s'\n"),
05544 os->name, pl->name);
05545 }
05546 }
05547
05548
05549
05550 void
05551 lang_add_nocrossref (lang_nocrossref_type *l)
05552 {
05553 struct lang_nocrossrefs *n;
05554
05555 n = xmalloc (sizeof *n);
05556 n->next = nocrossref_list;
05557 n->list = l;
05558 nocrossref_list = n;
05559
05560
05561 link_info.notice_all = TRUE;
05562 }
05563
05564
05565
05566
05567 static etree_type *overlay_vma;
05568
05569 static etree_type *overlay_subalign;
05570
05571
05572 static etree_type *overlay_max;
05573
05574
05575
05576 struct overlay_list {
05577 struct overlay_list *next;
05578 lang_output_section_statement_type *os;
05579 };
05580
05581 static struct overlay_list *overlay_list;
05582
05583
05584
05585 void
05586 lang_enter_overlay (etree_type *vma_expr, etree_type *subalign)
05587 {
05588
05589 ASSERT (overlay_vma == NULL
05590 && overlay_subalign == NULL
05591 && overlay_max == NULL);
05592
05593 overlay_vma = vma_expr;
05594 overlay_subalign = subalign;
05595 }
05596
05597
05598
05599
05600
05601 void
05602 lang_enter_overlay_section (const char *name)
05603 {
05604 struct overlay_list *n;
05605 etree_type *size;
05606
05607 lang_enter_output_section_statement (name, overlay_vma, normal_section,
05608 0, overlay_subalign, 0, 0);
05609
05610
05611
05612
05613 if (overlay_list == NULL)
05614 overlay_vma = exp_nameop (ADDR, name);
05615
05616
05617 n = xmalloc (sizeof *n);
05618 n->os = current_section;
05619 n->next = overlay_list;
05620 overlay_list = n;
05621
05622 size = exp_nameop (SIZEOF, name);
05623
05624
05625 if (overlay_max == NULL)
05626 overlay_max = size;
05627 else
05628 overlay_max = exp_binop (MAX_K, overlay_max, size);
05629 }
05630
05631
05632
05633
05634 void
05635 lang_leave_overlay_section (fill_type *fill,
05636 lang_output_section_phdr_list *phdrs)
05637 {
05638 const char *name;
05639 char *clean, *s2;
05640 const char *s1;
05641 char *buf;
05642
05643 name = current_section->name;
05644
05645
05646
05647
05648
05649 lang_leave_output_section_statement (fill, DEFAULT_MEMORY_REGION, phdrs, 0);
05650
05651
05652
05653 clean = xmalloc (strlen (name) + 1);
05654 s2 = clean;
05655 for (s1 = name; *s1 != '\0'; s1++)
05656 if (ISALNUM (*s1) || *s1 == '_')
05657 *s2++ = *s1;
05658 *s2 = '\0';
05659
05660 buf = xmalloc (strlen (clean) + sizeof "__load_start_");
05661 sprintf (buf, "__load_start_%s", clean);
05662 lang_add_assignment (exp_assop ('=', buf,
05663 exp_nameop (LOADADDR, name)));
05664
05665 buf = xmalloc (strlen (clean) + sizeof "__load_stop_");
05666 sprintf (buf, "__load_stop_%s", clean);
05667 lang_add_assignment (exp_assop ('=', buf,
05668 exp_binop ('+',
05669 exp_nameop (LOADADDR, name),
05670 exp_nameop (SIZEOF, name))));
05671
05672 free (clean);
05673 }
05674
05675
05676
05677
05678 void
05679 lang_leave_overlay (etree_type *lma_expr,
05680 int nocrossrefs,
05681 fill_type *fill,
05682 const char *memspec,
05683 lang_output_section_phdr_list *phdrs,
05684 const char *lma_memspec)
05685 {
05686 lang_memory_region_type *region;
05687 lang_memory_region_type *lma_region;
05688 struct overlay_list *l;
05689 lang_nocrossref_type *nocrossref;
05690
05691 lang_get_regions (®ion, &lma_region,
05692 memspec, lma_memspec,
05693 lma_expr != NULL, FALSE);
05694
05695 nocrossref = NULL;
05696
05697
05698
05699 if (overlay_list != NULL)
05700 overlay_list->os->update_dot_tree
05701 = exp_assop ('=', ".", exp_binop ('+', overlay_vma, overlay_max));
05702
05703 l = overlay_list;
05704 while (l != NULL)
05705 {
05706 struct overlay_list *next;
05707
05708 if (fill != NULL && l->os->fill == NULL)
05709 l->os->fill = fill;
05710
05711 l->os->region = region;
05712 l->os->lma_region = lma_region;
05713
05714
05715
05716
05717
05718 if (l->next == 0)
05719 l->os->load_base = lma_expr;
05720 else if (lma_region == 0)
05721 l->os->load_base = exp_binop ('+',
05722 exp_nameop (LOADADDR, l->next->os->name),
05723 exp_nameop (SIZEOF, l->next->os->name));
05724
05725 if (phdrs != NULL && l->os->phdrs == NULL)
05726 l->os->phdrs = phdrs;
05727
05728 if (nocrossrefs)
05729 {
05730 lang_nocrossref_type *nc;
05731
05732 nc = xmalloc (sizeof *nc);
05733 nc->name = l->os->name;
05734 nc->next = nocrossref;
05735 nocrossref = nc;
05736 }
05737
05738 next = l->next;
05739 free (l);
05740 l = next;
05741 }
05742
05743 if (nocrossref != NULL)
05744 lang_add_nocrossref (nocrossref);
05745
05746 overlay_vma = NULL;
05747 overlay_list = NULL;
05748 overlay_max = NULL;
05749 }
05750
05751
05752
05753
05754
05755 struct bfd_elf_version_tree *lang_elf_version_info;
05756
05757
05758
05759
05760
05761 static struct bfd_elf_version_expr *
05762 lang_vers_match (struct bfd_elf_version_expr_head *head,
05763 struct bfd_elf_version_expr *prev,
05764 const char *sym)
05765 {
05766 const char *cxx_sym = sym;
05767 const char *java_sym = sym;
05768 struct bfd_elf_version_expr *expr = NULL;
05769
05770 if (head->mask & BFD_ELF_VERSION_CXX_TYPE)
05771 {
05772 cxx_sym = cplus_demangle (sym, DMGL_PARAMS | DMGL_ANSI);
05773 if (!cxx_sym)
05774 cxx_sym = sym;
05775 }
05776 if (head->mask & BFD_ELF_VERSION_JAVA_TYPE)
05777 {
05778 java_sym = cplus_demangle (sym, DMGL_JAVA);
05779 if (!java_sym)
05780 java_sym = sym;
05781 }
05782
05783 if (head->htab && (prev == NULL || prev->symbol))
05784 {
05785 struct bfd_elf_version_expr e;
05786
05787 switch (prev ? prev->mask : 0)
05788 {
05789 case 0:
05790 if (head->mask & BFD_ELF_VERSION_C_TYPE)
05791 {
05792 e.symbol = sym;
05793 expr = htab_find (head->htab, &e);
05794 while (expr && strcmp (expr->symbol, sym) == 0)
05795 if (expr->mask == BFD_ELF_VERSION_C_TYPE)
05796 goto out_ret;
05797 else
05798 expr = expr->next;
05799 }
05800
05801 case BFD_ELF_VERSION_C_TYPE:
05802 if (head->mask & BFD_ELF_VERSION_CXX_TYPE)
05803 {
05804 e.symbol = cxx_sym;
05805 expr = htab_find (head->htab, &e);
05806 while (expr && strcmp (expr->symbol, cxx_sym) == 0)
05807 if (expr->mask == BFD_ELF_VERSION_CXX_TYPE)
05808 goto out_ret;
05809 else
05810 expr = expr->next;
05811 }
05812
05813 case BFD_ELF_VERSION_CXX_TYPE:
05814 if (head->mask & BFD_ELF_VERSION_JAVA_TYPE)
05815 {
05816 e.symbol = java_sym;
05817 expr = htab_find (head->htab, &e);
05818 while (expr && strcmp (expr->symbol, java_sym) == 0)
05819 if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE)
05820 goto out_ret;
05821 else
05822 expr = expr->next;
05823 }
05824
05825 default:
05826 break;
05827 }
05828 }
05829
05830
05831 if (prev == NULL || prev->symbol)
05832 expr = head->remaining;
05833 else
05834 expr = prev->next;
05835 while (expr)
05836 {
05837 const char *s;
05838
05839 if (expr->pattern[0] == '*' && expr->pattern[1] == '\0')
05840 break;
05841
05842 if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE)
05843 s = java_sym;
05844 else if (expr->mask == BFD_ELF_VERSION_CXX_TYPE)
05845 s = cxx_sym;
05846 else
05847 s = sym;
05848 if (fnmatch (expr->pattern, s, 0) == 0)
05849 break;
05850 expr = expr->next;
05851 }
05852
05853 out_ret:
05854 if (cxx_sym != sym)
05855 free ((char *) cxx_sym);
05856 if (java_sym != sym)
05857 free ((char *) java_sym);
05858 return expr;
05859 }
05860
05861
05862
05863
05864 static const char *
05865 realsymbol (const char *pattern)
05866 {
05867 const char *p;
05868 bfd_boolean changed = FALSE, backslash = FALSE;
05869 char *s, *symbol = xmalloc (strlen (pattern) + 1);
05870
05871 for (p = pattern, s = symbol; *p != '\0'; ++p)
05872 {
05873
05874
05875 if (! backslash && (*p == '?' || *p == '*' || *p == '['))
05876 {
05877 free (symbol);
05878 return NULL;
05879 }
05880
05881 if (backslash)
05882 {
05883
05884 *(s - 1) = *p;
05885 changed = TRUE;
05886 }
05887 else
05888 *s++ = *p;
05889
05890 backslash = *p == '\\';
05891 }
05892
05893 if (changed)
05894 {
05895 *s = '\0';
05896 return symbol;
05897 }
05898 else
05899 {
05900 free (symbol);
05901 return pattern;
05902 }
05903 }
05904
05905
05906
05907 struct bfd_elf_version_expr *
05908 lang_new_vers_pattern (struct bfd_elf_version_expr *orig,
05909 const char *new,
05910 const char *lang)
05911 {
05912 struct bfd_elf_version_expr *ret;
05913
05914 ret = xmalloc (sizeof *ret);
05915 ret->next = orig;
05916 ret->pattern = new;
05917 ret->symver = 0;
05918 ret->script = 0;
05919 ret->symbol = realsymbol (new);
05920
05921 if (lang == NULL || strcasecmp (lang, "C") == 0)
05922 ret->mask = BFD_ELF_VERSION_C_TYPE;
05923 else if (strcasecmp (lang, "C++") == 0)
05924 ret->mask = BFD_ELF_VERSION_CXX_TYPE;
05925 else if (strcasecmp (lang, "Java") == 0)
05926 ret->mask = BFD_ELF_VERSION_JAVA_TYPE;
05927 else
05928 {
05929 einfo (_("%X%P: unknown language `%s' in version information\n"),
05930 lang);
05931 ret->mask = BFD_ELF_VERSION_C_TYPE;
05932 }
05933
05934 return ldemul_new_vers_pattern (ret);
05935 }
05936
05937
05938
05939
05940 struct bfd_elf_version_tree *
05941 lang_new_vers_node (struct bfd_elf_version_expr *globals,
05942 struct bfd_elf_version_expr *locals)
05943 {
05944 struct bfd_elf_version_tree *ret;
05945
05946 ret = xcalloc (1, sizeof *ret);
05947 ret->globals.list = globals;
05948 ret->locals.list = locals;
05949 ret->match = lang_vers_match;
05950 ret->name_indx = (unsigned int) -1;
05951 return ret;
05952 }
05953
05954
05955
05956 static int version_index;
05957
05958 static hashval_t
05959 version_expr_head_hash (const void *p)
05960 {
05961 const struct bfd_elf_version_expr *e = p;
05962
05963 return htab_hash_string (e->symbol);
05964 }
05965
05966 static int
05967 version_expr_head_eq (const void *p1, const void *p2)
05968 {
05969 const struct bfd_elf_version_expr *e1 = p1;
05970 const struct bfd_elf_version_expr *e2 = p2;
05971
05972 return strcmp (e1->symbol, e2->symbol) == 0;
05973 }
05974
05975 static void
05976 lang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head)
05977 {
05978 size_t count = 0;
05979 struct bfd_elf_version_expr *e, *next;
05980 struct bfd_elf_version_expr **list_loc, **remaining_loc;
05981
05982 for (e = head->list; e; e = e->next)
05983 {
05984 if (e->symbol)
05985 count++;
05986 head->mask |= e->mask;
05987 }
05988
05989 if (count)
05990 {
05991 head->htab = htab_create (count * 2, version_expr_head_hash,
05992 version_expr_head_eq, NULL);
05993 list_loc = &head->list;
05994 remaining_loc = &head->remaining;
05995 for (e = head->list; e; e = next)
05996 {
05997 next = e->next;
05998 if (!e->symbol)
05999 {
06000 *remaining_loc = e;
06001 remaining_loc = &e->next;
06002 }
06003 else
06004 {
06005 void **loc = htab_find_slot (head->htab, e, INSERT);
06006
06007 if (*loc)
06008 {
06009 struct bfd_elf_version_expr *e1, *last;
06010
06011 e1 = *loc;
06012 last = NULL;
06013 do
06014 {
06015 if (e1->mask == e->mask)
06016 {
06017 last = NULL;
06018 break;
06019 }
06020 last = e1;
06021 e1 = e1->next;
06022 }
06023 while (e1 && strcmp (e1->symbol, e->symbol) == 0);
06024
06025 if (last == NULL)
06026 {
06027
06028
06029
06030
06031 free (e);
06032 }
06033 else
06034 {
06035 e->next = last->next;
06036 last->next = e;
06037 }
06038 }
06039 else
06040 {
06041 *loc = e;
06042 *list_loc = e;
06043 list_loc = &e->next;
06044 }
06045 }
06046 }
06047 *remaining_loc = NULL;
06048 *list_loc = head->remaining;
06049 }
06050 else
06051 head->remaining = head->list;
06052 }
06053
06054
06055
06056
06057 void
06058 lang_register_vers_node (const char *name,
06059 struct bfd_elf_version_tree *version,
06060 struct bfd_elf_version_deps *deps)
06061 {
06062 struct bfd_elf_version_tree *t, **pp;
06063 struct bfd_elf_version_expr *e1;
06064
06065 if (name == NULL)
06066 name = "";
06067
06068 if ((name[0] == '\0' && lang_elf_version_info != NULL)
06069 || (lang_elf_version_info && lang_elf_version_info->name[0] == '\0'))
06070 {
06071 einfo (_("%X%P: anonymous version tag cannot be combined"
06072 " with other version tags\n"));
06073 free (version);
06074 return;
06075 }
06076
06077
06078 for (t = lang_elf_version_info; t != NULL; t = t->next)
06079 if (strcmp (t->name, name) == 0)
06080 einfo (_("%X%P: duplicate version tag `%s'\n"), name);
06081
06082 lang_finalize_version_expr_head (&version->globals);
06083 lang_finalize_version_expr_head (&version->locals);
06084
06085
06086
06087
06088 for (e1 = version->globals.list; e1 != NULL; e1 = e1->next)
06089 {
06090 for (t = lang_elf_version_info; t != NULL; t = t->next)
06091 {
06092 struct bfd_elf_version_expr *e2;
06093
06094 if (t->locals.htab && e1->symbol)
06095 {
06096 e2 = htab_find (t->locals.htab, e1);
06097 while (e2 && strcmp (e1->symbol, e2->symbol) == 0)
06098 {
06099 if (e1->mask == e2->mask)
06100 einfo (_("%X%P: duplicate expression `%s'"
06101 " in version information\n"), e1->symbol);
06102 e2 = e2->next;
06103 }
06104 }
06105 else if (!e1->symbol)
06106 for (e2 = t->locals.remaining; e2 != NULL; e2 = e2->next)
06107 if (strcmp (e1->pattern, e2->pattern) == 0
06108 && e1->mask == e2->mask)
06109 einfo (_("%X%P: duplicate expression `%s'"
06110 " in version information\n"), e1->pattern);
06111 }
06112 }
06113
06114 for (e1 = version->locals.list; e1 != NULL; e1 = e1->next)
06115 {
06116 for (t = lang_elf_version_info; t != NULL; t = t->next)
06117 {
06118 struct bfd_elf_version_expr *e2;
06119
06120 if (t->globals.htab && e1->symbol)
06121 {
06122 e2 = htab_find (t->globals.htab, e1);
06123 while (e2 && strcmp (e1->symbol, e2->symbol) == 0)
06124 {
06125 if (e1->mask == e2->mask)
06126 einfo (_("%X%P: duplicate expression `%s'"
06127 " in version information\n"),
06128 e1->symbol);
06129 e2 = e2->next;
06130 }
06131 }
06132 else if (!e1->symbol)
06133 for (e2 = t->globals.remaining; e2 != NULL; e2 = e2->next)
06134 if (strcmp (e1->pattern, e2->pattern) == 0
06135 && e1->mask == e2->mask)
06136 einfo (_("%X%P: duplicate expression `%s'"
06137 " in version information\n"), e1->pattern);
06138 }
06139 }
06140
06141 version->deps = deps;
06142 version->name = name;
06143 if (name[0] != '\0')
06144 {
06145 ++version_index;
06146 version->vernum = version_index;
06147 }
06148 else
06149 version->vernum = 0;
06150
06151 for (pp = &lang_elf_version_info; *pp != NULL; pp = &(*pp)->next)
06152 ;
06153 *pp = version;
06154 }
06155
06156
06157
06158 struct bfd_elf_version_deps *
06159 lang_add_vers_depend (struct bfd_elf_version_deps *list, const char *name)
06160 {
06161 struct bfd_elf_version_deps *ret;
06162 struct bfd_elf_version_tree *t;
06163
06164 ret = xmalloc (sizeof *ret);
06165 ret->next = list;
06166
06167 for (t = lang_elf_version_info; t != NULL; t = t->next)
06168 {
06169 if (strcmp (t->name, name) == 0)
06170 {
06171 ret->version_needed = t;
06172 return ret;
06173 }
06174 }
06175
06176 einfo (_("%X%P: unable to find version dependency `%s'\n"), name);
06177
06178 return ret;
06179 }
06180
06181 static void
06182 lang_do_version_exports_section (void)
06183 {
06184 struct bfd_elf_version_expr *greg = NULL, *lreg;
06185
06186 LANG_FOR_EACH_INPUT_STATEMENT (is)
06187 {
06188 asection *sec = bfd_get_section_by_name (is->the_bfd, ".exports");
06189 char *contents, *p;
06190 bfd_size_type len;
06191
06192 if (sec == NULL)
06193 continue;
06194
06195 len = sec->size;
06196 contents = xmalloc (len);
06197 if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len))
06198 einfo (_("%X%P: unable to read .exports section contents\n"), sec);
06199
06200 p = contents;
06201 while (p < contents + len)
06202 {
06203 greg = lang_new_vers_pattern (greg, p, NULL);
06204 p = strchr (p, '\0') + 1;
06205 }
06206
06207
06208
06209
06210 sec->flags |= SEC_EXCLUDE;
06211 }
06212
06213 lreg = lang_new_vers_pattern (NULL, "*", NULL);
06214 lang_register_vers_node (command_line.version_exports_section,
06215 lang_new_vers_node (greg, lreg), NULL);
06216 }
06217
06218 void
06219 lang_add_unique (const char *name)
06220 {
06221 struct unique_sections *ent;
06222
06223 for (ent = unique_section_list; ent; ent = ent->next)
06224 if (strcmp (ent->name, name) == 0)
06225 return;
06226
06227 ent = xmalloc (sizeof *ent);
06228 ent->name = xstrdup (name);
06229 ent->next = unique_section_list;
06230 unique_section_list = ent;
06231 }