ldlang.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,418 行 · 第 1/5 页
C
2,418 行
for (l = already_linked_list->entry; l != NULL; l = l->next) { if (sec->comdat == NULL || l->sec->comdat == NULL || strcmp (sec->comdat->name, l->sec->comdat->name) == 0) { /* The section has already been linked. See if we should issue a warning. */ switch (flags & SEC_LINK_DUPLICATES) { default: abort (); case SEC_LINK_DUPLICATES_DISCARD: break; case SEC_LINK_DUPLICATES_ONE_ONLY: if (sec->comdat == NULL) einfo (_("%P: %B: warning: ignoring duplicate section `%s'\n"), abfd, name); else einfo (_("%P: %B: warning: ignoring duplicate `%s' section symbol `%s'\n"), abfd, name, sec->comdat->name); break; case SEC_LINK_DUPLICATES_SAME_CONTENTS: /* FIXME: We should really dig out the contents of both sections and memcmp them. The COFF/PE spec says that the Microsoft linker does not implement this correctly, so I'm not going to bother doing it either. */ /* Fall through. */ case SEC_LINK_DUPLICATES_SAME_SIZE: if (bfd_section_size (abfd, sec) != bfd_section_size (l->sec->owner, l->sec)) einfo (_("%P: %B: warning: duplicate section `%s' has different size\n"), abfd, name); break; } /* Set the output_section field so that wild_doit does not create a lang_input_section structure for this section. Since there might be a symbol in the section being discarded, we must retain a pointer to the section which we are really going to use. */ sec->output_section = bfd_abs_section_ptr; sec->kept_section = l->sec; return; } } /* This is the first section with this name. Record it. Allocate the memory from the same obstack as the hash table is kept in. */ l = ((struct already_linked *) bfd_hash_allocate (&already_linked_table, sizeof *l)); l->sec = sec; l->next = already_linked_list->entry; already_linked_list->entry = l;}/* Support routines for the hash table used by section_already_linked, initialize the table, fill in an entry and remove the table. */static struct bfd_hash_entry *already_linked_newfunc (entry, table, string) struct bfd_hash_entry *entry ATTRIBUTE_UNUSED; struct bfd_hash_table *table; const char *string ATTRIBUTE_UNUSED;{ struct already_linked_hash_entry *ret = bfd_hash_allocate (table, sizeof (struct already_linked_hash_entry)); ret->entry = NULL; return (struct bfd_hash_entry *) ret;}static voidalready_linked_table_init (){ if (! bfd_hash_table_init_n (&already_linked_table, already_linked_newfunc, 42)) einfo (_("%P%F: Failed to create hash table\n"));}static voidalready_linked_table_free (){ bfd_hash_table_free (&already_linked_table);}/* The wild routines. These expand statements like *(.text) and foo.o to a list of explicit actions, like foo.o(.text), bar.o(.text) and foo.o(.text, .data). *//* Return true if the PATTERN argument is a wildcard pattern. Although backslashes are treated specially if a pattern contains wildcards, we do not consider the mere presence of a backslash to be enough to cause the the pattern to be treated as a wildcard. That lets us handle DOS filenames more naturally. */static booleanwildcardp (pattern) const char *pattern;{ const char *s; for (s = pattern; *s != '\0'; ++s) if (*s == '?' || *s == '*' || *s == '[') return true; return false;}/* Add SECTION to the output section OUTPUT. Do this by creating a lang_input_section statement which is placed at PTR. FILE is the input file which holds SECTION. */voidwild_doit (ptr, section, output, file) lang_statement_list_type *ptr; asection *section; lang_output_section_statement_type *output; lang_input_statement_type *file;{ flagword flags; boolean discard; flags = bfd_get_section_flags (section->owner, section); discard = false; /* If we are doing a final link, discard sections marked with SEC_EXCLUDE. */ if (! link_info.relocateable && (flags & SEC_EXCLUDE) != 0) discard = true; /* Discard input sections which are assigned to a section named DISCARD_SECTION_NAME. */ if (strcmp (output->name, DISCARD_SECTION_NAME) == 0) discard = true; /* Discard debugging sections if we are stripping debugging information. */ if ((link_info.strip == strip_debugger || link_info.strip == strip_all) && (flags & SEC_DEBUGGING) != 0) discard = true; if (discard) { if (section->output_section == NULL) { /* This prevents future calls from assigning this section. */ section->output_section = bfd_abs_section_ptr; } return; } if (section->output_section == NULL) { boolean first; lang_input_section_type *new; flagword flags; if (output->bfd_section == NULL) init_os (output); first = ! output->bfd_section->linker_has_input; output->bfd_section->linker_has_input = 1; /* Add a section reference to the list. */ new = new_stat (lang_input_section, ptr); new->section = section; new->ifile = file; section->output_section = output->bfd_section; flags = section->flags; /* We don't copy the SEC_NEVER_LOAD flag from an input section to an output section, because we want to be able to include a SEC_NEVER_LOAD section in the middle of an otherwise loaded section (I don't know why we want to do this, but we do). build_link_order in ldwrite.c handles this case by turning the embedded SEC_NEVER_LOAD section into a fill. */ flags &= ~ SEC_NEVER_LOAD; /* If final link, don't copy the SEC_LINK_ONCE flags, they've already been processed. One reason to do this is that on pe format targets, .text$foo sections go into .text and it's odd to see .text with SEC_LINK_ONCE set. */ if (! link_info.relocateable) flags &= ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES); /* If this is not the first input section, and the SEC_READONLY flag is not currently set, then don't set it just because the input section has it set. */ if (! first && (section->output_section->flags & SEC_READONLY) == 0) flags &= ~ SEC_READONLY; section->output_section->flags |= flags; /* If SEC_READONLY is not set in the input section, then clear it from the output section. */ if ((section->flags & SEC_READONLY) == 0) section->output_section->flags &= ~SEC_READONLY; switch (output->sectype) { case normal_section: break; case dsect_section: case copy_section: case info_section: case overlay_section: output->bfd_section->flags &= ~SEC_ALLOC; break; case noload_section: output->bfd_section->flags &= ~SEC_LOAD; output->bfd_section->flags |= SEC_NEVER_LOAD; break; } /* Copy over SEC_SMALL_DATA. */ if (section->flags & SEC_SMALL_DATA) section->output_section->flags |= SEC_SMALL_DATA; if (section->alignment_power > output->bfd_section->alignment_power) output->bfd_section->alignment_power = section->alignment_power; /* If supplied an aligment, then force it. */ if (output->section_alignment != -1) output->bfd_section->alignment_power = output->section_alignment; if (section->flags & SEC_BLOCK) { section->output_section->flags |= SEC_BLOCK; /* FIXME: This value should really be obtained from the bfd... */ output->block_value = 128; } }}/* Handle wildcard sorting. This returns the lang_input_section which should follow the one we are going to create for SECTION and FILE, based on the sorting requirements of WILD. It returns NULL if the new section should just go at the end of the current list. */static lang_statement_union_type *wild_sort (wild, file, section) lang_wild_statement_type *wild; lang_input_statement_type *file; asection *section;{ const char *section_name; lang_statement_union_type *l; if (! wild->filenames_sorted && ! wild->sections_sorted) return NULL; section_name = bfd_get_section_name (file->the_bfd, section); for (l = wild->children.head; l != NULL; l = l->next) { lang_input_section_type *ls; if (l->header.type != lang_input_section_enum) continue; ls = &l->input_section; /* Sorting by filename takes precedence over sorting by section name. */ if (wild->filenames_sorted) { const char *fn, *ln; boolean fa, la; int i; /* The PE support for the .idata section as generated by dlltool assumes that files will be sorted by the name of the archive and then the name of the file within the archive. */ if (file->the_bfd != NULL && bfd_my_archive (file->the_bfd) != NULL) { fn = bfd_get_filename (bfd_my_archive (file->the_bfd)); fa = true; } else { fn = file->filename; fa = false; } if (ls->ifile->the_bfd != NULL && bfd_my_archive (ls->ifile->the_bfd) != NULL) { ln = bfd_get_filename (bfd_my_archive (ls->ifile->the_bfd)); la = true; } else { ln = ls->ifile->filename; la = false; } i = strcmp (fn, ln); if (i > 0) continue; else if (i < 0) break; if (fa || la) { if (fa) fn = file->filename; if (la) ln = ls->ifile->filename; i = strcmp (fn, ln); if (i > 0) continue; else if (i < 0) break; } } /* Here either the files are not sorted by name, or we are looking at the sections for this file. */ if (wild->sections_sorted) { if (strcmp (section_name, bfd_get_section_name (ls->ifile->the_bfd, ls->section)) < 0) break; } } return l;}/* Expand a wild statement for a particular FILE. SECTION may be NULL, in which case it is a wild card. */static voidoutput_section_callback (ptr, section, file, output) lang_wild_statement_type *ptr; asection *section; lang_input_statement_type *file; PTR output;{ lang_statement_union_type *before; /* If the wild pattern was marked KEEP, the member sections should be as well. */ if (ptr->keep_sections) section->flags |= SEC_KEEP; before = wild_sort (ptr, file, section); /* Here BEFORE points to the lang_input_section which should follow the one we are about to add. If BEFORE is NULL, then the section should just go at the end of the current list. */ if (before == NULL) wild_doit (&ptr->children, section, (lang_output_section_statement_type *) output, file); else { lang_statement_list_type list; lang_statement_union_type **pp; lang_list_init (&list); wild_doit (&list, section, (lang_output_section_statement_type *) output, file); /* If we are discarding the section, LIST.HEAD will be NULL. */ if (list.head != NULL) { ASSERT (list.head->next == NULL); for (pp = &ptr->children.head; *pp != before; pp = &(*pp)->next) ASSERT (*pp != NULL); list.head->next = *pp; *pp = list.head; } }}/* This is passed a file name which must have been seen already and added to the statement tree. We will see if it has been opened already and had its symbols read. If not then we'll read it. */static lang_input_statement_type *lookup_name (name) const char *name;{ lang_input_statement_type *search; for (search = (lang_input_statement_type *) input_file_chain.head; search != (lang_input_statement_type *) NULL; search = (lang_input_statement_type *) search->next_real_file) { if (search->filename == (char *) NULL && name == (char *) NULL) return search; if (search->filename != (char *) NULL && name != (char *) NULL && strcmp (search->filename, name) == 0) break; } if (search == (lang_input_statement_type *) NULL) search = new_afile (name, lang_input_file_is_file_enum, default_target, false); /* If we have already added this file, or this file is not real (FIXME: can that ever actually happen?) or the name is NULL (FIXME: can that ever actually happen?) don't add this file. */ if (search->loaded || ! search->real || search->filename == (const char *) NULL) return search; load_symbols (search, (lang_statement_list_type *) NULL); return search;}/* Get the symbols for an input file. */static voidload_symbols (entry, place) lang_input_statement_type *entry; lang_statement_list_type *place;{ char **matching; if (entry->loaded) return; ldfile_open_file (entry); if (! bfd_check_format (entry->the_bfd, bfd_archive) && ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching)) { bfd_error_type err; lang_statement_list_type *hold; err = bfd_get_error (); /* See if the emulation has some special knowledge. */ if (ldemul_unrecognized_file (entry)) return; if (err == bfd_error_file_ambiguously_recognized) { char **p; einfo (_("%B: file not recognized: %E\n"), entry->the_bfd); einfo (_("%B: matching formats:"), entry->the_bfd); for (p = matching; *p != NULL; p++) einfo (" %s", *p);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?