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 + -
显示快捷键?