elflink.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 548 行 · 第 1/2 页

C
548
字号
	}      else	{	  alc = bfd_malloc (p - name + 1);	  if (alc == NULL)	    return false;	  strncpy (alc, name, p - name);	  alc[p - name] = '\0';	  name = alc;	  copy = true;	}      indx = _bfd_stringtab_add (dynstr, name, true, copy);      if (alc != NULL)	free (alc);      if (indx == (bfd_size_type) -1)	return false;      h->dynstr_index = indx;    }  return true;}/* Return the dynindex of a local dynamic symbol.  */long_bfd_elf_link_lookup_local_dynindx (info, input_bfd, input_indx)     struct bfd_link_info *info;     bfd *input_bfd;     long input_indx;{  struct elf_link_local_dynamic_entry *e;  for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)    if (e->input_bfd == input_bfd && e->input_indx == input_indx)      return e->dynindx;  return -1;}/* This function is used to renumber the dynamic symbols, if some of   them are removed because they are marked as local.  This is called   via elf_link_hash_traverse.  */static boolean elf_link_renumber_hash_table_dynsyms  PARAMS ((struct elf_link_hash_entry *, PTR));static booleanelf_link_renumber_hash_table_dynsyms (h, data)     struct elf_link_hash_entry *h;     PTR data;{  size_t *count = (size_t *) data;  if (h->dynindx != -1)    h->dynindx = ++(*count);  return true;}/* Assign dynsym indices.  In a shared library we generate a section   symbol for each output section, which come first.  Next come all of   the back-end allocated local dynamic syms, followed by the rest of   the global symbols.  */unsigned long_bfd_elf_link_renumber_dynsyms (output_bfd, info)     bfd *output_bfd;     struct bfd_link_info *info;{  unsigned long dynsymcount = 0;  if (info->shared)    {      asection *p;      for (p = output_bfd->sections; p ; p = p->next)	elf_section_data (p)->dynindx = ++dynsymcount;    }  if (elf_hash_table (info)->dynlocal)    {      struct elf_link_local_dynamic_entry *p;      for (p = elf_hash_table (info)->dynlocal; p ; p = p->next)	p->dynindx = ++dynsymcount;    }  elf_link_hash_traverse (elf_hash_table (info),			  elf_link_renumber_hash_table_dynsyms,			  &dynsymcount);  /* There is an unused NULL entry at the head of the table which     we must account for in our count.  Unless there weren't any     symbols, which means we'll have no table at all.  */  if (dynsymcount != 0)    ++dynsymcount;  return elf_hash_table (info)->dynsymcount = dynsymcount;}/* Create a special linker section, or return a pointer to a linker   section already created */elf_linker_section_t *_bfd_elf_create_linker_section (abfd, info, which, defaults)     bfd *abfd;     struct bfd_link_info *info;     enum elf_linker_section_enum which;     elf_linker_section_t *defaults;{  bfd *dynobj = elf_hash_table (info)->dynobj;  elf_linker_section_t *lsect;  /* Record the first bfd section that needs the special section */  if (!dynobj)    dynobj = elf_hash_table (info)->dynobj = abfd;  /* If this is the first time, create the section */  lsect = elf_linker_section (dynobj, which);  if (!lsect)    {      asection *s;      lsect = (elf_linker_section_t *)	bfd_alloc (dynobj, sizeof (elf_linker_section_t));      *lsect = *defaults;      elf_linker_section (dynobj, which) = lsect;      lsect->which = which;      lsect->hole_written_p = false;      /* See if the sections already exist */      lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name);      if (!s || (s->flags & defaults->flags) != defaults->flags)	{	  lsect->section = s = bfd_make_section_anyway (dynobj, lsect->name);	  if (s == NULL)	    return (elf_linker_section_t *)0;	  bfd_set_section_flags (dynobj, s, defaults->flags);	  bfd_set_section_alignment (dynobj, s, lsect->alignment);	}      else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment)	bfd_set_section_alignment (dynobj, s, lsect->alignment);      s->_raw_size = align_power (s->_raw_size, lsect->alignment);      /* Is there a hole we have to provide?  If so check whether the segment is	 too big already */      if (lsect->hole_size)	{	  lsect->hole_offset = s->_raw_size;	  s->_raw_size += lsect->hole_size;	  if (lsect->hole_offset > lsect->max_hole_offset)	    {	      (*_bfd_error_handler) (_("%s: Section %s is already to large to put hole of %ld bytes in"),				     bfd_get_filename (abfd),				     lsect->name,				     (long)lsect->hole_size);	      bfd_set_error (bfd_error_bad_value);	      return (elf_linker_section_t *)0;	    }	}#ifdef DEBUG      fprintf (stderr, "Creating section %s, current size = %ld\n",	       lsect->name, (long)s->_raw_size);#endif      if (lsect->sym_name)	{	  struct elf_link_hash_entry *h = NULL;#ifdef DEBUG	  fprintf (stderr, "Adding %s to section %s\n",		   lsect->sym_name,		   lsect->name);#endif	  h = (struct elf_link_hash_entry *)	    bfd_link_hash_lookup (info->hash, lsect->sym_name, false, false, false);	  if ((h == NULL || h->root.type == bfd_link_hash_undefined)	      && !(_bfd_generic_link_add_one_symbol (info,						     abfd,						     lsect->sym_name,						     BSF_GLOBAL,						     s,						     ((lsect->hole_size)						      ? s->_raw_size - lsect->hole_size + lsect->sym_offset						      : lsect->sym_offset),						     (const char *) NULL,						     false,						     get_elf_backend_data (abfd)->collect,						     (struct bfd_link_hash_entry **) &h)))	    return (elf_linker_section_t *)0;	  if ((defaults->which != LINKER_SECTION_SDATA)	      && (defaults->which != LINKER_SECTION_SDATA2))	    h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;	  h->type = STT_OBJECT;	  lsect->sym_hash = h;	  if (info->shared	      && ! _bfd_elf_link_record_dynamic_symbol (info, h))	    return (elf_linker_section_t *)0;	}    }#if 0  /* This does not make sense.  The sections which may exist in the     object file have nothing to do with the sections we want to     create.  */  /* Find the related sections if they have been created */  if (lsect->bss_name && !lsect->bss_section)    lsect->bss_section = bfd_get_section_by_name (dynobj, lsect->bss_name);  if (lsect->rel_name && !lsect->rel_section)    lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);#endif  return lsect;}/* Find a linker generated pointer with a given addend and type.  */elf_linker_section_pointers_t *_bfd_elf_find_pointer_linker_section (linker_pointers, addend, which)     elf_linker_section_pointers_t *linker_pointers;     bfd_signed_vma addend;     elf_linker_section_enum_t which;{  for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)    {      if (which == linker_pointers->which && addend == linker_pointers->addend)	return linker_pointers;    }  return (elf_linker_section_pointers_t *)0;}/* Make the .rela section corresponding to the generated linker section.  */boolean_bfd_elf_make_linker_section_rela (dynobj, lsect, alignment)     bfd *dynobj;     elf_linker_section_t *lsect;     int alignment;{  if (lsect->rel_section)    return true;  lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);  if (lsect->rel_section == NULL)    {      lsect->rel_section = bfd_make_section (dynobj, lsect->rel_name);      if (lsect->rel_section == NULL	  || ! bfd_set_section_flags (dynobj,				      lsect->rel_section,				      (SEC_ALLOC				       | SEC_LOAD				       | SEC_HAS_CONTENTS				       | SEC_IN_MEMORY				       | SEC_LINKER_CREATED				       | SEC_READONLY))	  || ! bfd_set_section_alignment (dynobj, lsect->rel_section, alignment))	return false;    }  return true;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?