⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elf.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* If the section has relocs, set up a section header for the     SHT_REL[A] section.  If two relocation sections are required for     this section, it is up to the processor-specific back-end to     create the other.  */  if ((asect->flags & SEC_RELOC) != 0      && !_bfd_elf_init_reloc_shdr (abfd,				    &elf_section_data (asect)->rel_hdr,				    asect,				    elf_section_data (asect)->use_rela_p))    *failedptr = true;}/* Assign all ELF section numbers.  The dummy first section is handled here   too.  The link/info pointers for the standard section types are filled   in here too, while we're at it.  */static booleanassign_section_numbers (abfd)     bfd *abfd;{  struct elf_obj_tdata *t = elf_tdata (abfd);  asection *sec;  unsigned int section_number;  Elf_Internal_Shdr **i_shdrp;  section_number = 1;  for (sec = abfd->sections; sec; sec = sec->next)    {      struct bfd_elf_section_data *d = elf_section_data (sec);      d->this_idx = section_number++;      if ((sec->flags & SEC_RELOC) == 0)	d->rel_idx = 0;      else	d->rel_idx = section_number++;      if (d->rel_hdr2)	d->rel_idx2 = section_number++;      else	d->rel_idx2 = 0;    }  t->shstrtab_section = section_number++;  elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;  t->shstrtab_hdr.sh_size = _bfd_stringtab_size (elf_shstrtab (abfd));  if (bfd_get_symcount (abfd) > 0)    {      t->symtab_section = section_number++;      t->strtab_section = section_number++;    }  elf_elfheader (abfd)->e_shnum = section_number;  /* Set up the list of section header pointers, in agreement with the     indices.  */  i_shdrp = ((Elf_Internal_Shdr **)	     bfd_alloc (abfd, section_number * sizeof (Elf_Internal_Shdr *)));  if (i_shdrp == NULL)    return false;  i_shdrp[0] = ((Elf_Internal_Shdr *)		bfd_alloc (abfd, sizeof (Elf_Internal_Shdr)));  if (i_shdrp[0] == NULL)    {      bfd_release (abfd, i_shdrp);      return false;    }  memset (i_shdrp[0], 0, sizeof (Elf_Internal_Shdr));  elf_elfsections (abfd) = i_shdrp;  i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;  if (bfd_get_symcount (abfd) > 0)    {      i_shdrp[t->symtab_section] = &t->symtab_hdr;      i_shdrp[t->strtab_section] = &t->strtab_hdr;      t->symtab_hdr.sh_link = t->strtab_section;    }  for (sec = abfd->sections; sec; sec = sec->next)    {      struct bfd_elf_section_data *d = elf_section_data (sec);      asection *s;      const char *name;      i_shdrp[d->this_idx] = &d->this_hdr;      if (d->rel_idx != 0)	i_shdrp[d->rel_idx] = &d->rel_hdr;      if (d->rel_idx2 != 0)	i_shdrp[d->rel_idx2] = d->rel_hdr2;      /* Fill in the sh_link and sh_info fields while we're at it.  */      /* sh_link of a reloc section is the section index of the symbol	 table.  sh_info is the section index of the section to which	 the relocation entries apply.  */      if (d->rel_idx != 0)	{	  d->rel_hdr.sh_link = t->symtab_section;	  d->rel_hdr.sh_info = d->this_idx;	}      if (d->rel_idx2 != 0)	{	  d->rel_hdr2->sh_link = t->symtab_section;	  d->rel_hdr2->sh_info = d->this_idx;	}      switch (d->this_hdr.sh_type)	{	case SHT_REL:	case SHT_RELA:	  /* A reloc section which we are treating as a normal BFD	     section.  sh_link is the section index of the symbol	     table.  sh_info is the section index of the section to	     which the relocation entries apply.  We assume that an	     allocated reloc section uses the dynamic symbol table.	     FIXME: How can we be sure?  */	  s = bfd_get_section_by_name (abfd, ".dynsym");	  if (s != NULL)	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;	  /* We look up the section the relocs apply to by name.  */	  name = sec->name;	  if (d->this_hdr.sh_type == SHT_REL)	    name += 4;	  else	    name += 5;	  s = bfd_get_section_by_name (abfd, name);	  if (s != NULL)	    d->this_hdr.sh_info = elf_section_data (s)->this_idx;	  break;	case SHT_STRTAB:	  /* We assume that a section named .stab*str is a stabs	     string section.  We look for a section with the same name	     but without the trailing ``str'', and set its sh_link	     field to point to this section.  */	  if (strncmp (sec->name, ".stab", sizeof ".stab" - 1) == 0	      && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)	    {	      size_t len;	      char *alc;	      len = strlen (sec->name);	      alc = (char *) bfd_malloc (len - 2);	      if (alc == NULL)		return false;	      strncpy (alc, sec->name, len - 3);	      alc[len - 3] = '\0';	      s = bfd_get_section_by_name (abfd, alc);	      free (alc);	      if (s != NULL)		{		  elf_section_data (s)->this_hdr.sh_link = d->this_idx;		  /* This is a .stab section.  */		  elf_section_data (s)->this_hdr.sh_entsize =		    4 + 2 * bfd_get_arch_size (abfd) / 8;		}	    }	  break;	case SHT_DYNAMIC:	case SHT_DYNSYM:	case SHT_GNU_verneed:	case SHT_GNU_verdef:	  /* sh_link is the section header index of the string table	     used for the dynamic entries, or the symbol table, or the	     version strings.  */	  s = bfd_get_section_by_name (abfd, ".dynstr");	  if (s != NULL)	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;	  break;	case SHT_HASH:	case SHT_GNU_versym:	  /* sh_link is the section header index of the symbol table	     this hash table or version table is for.  */	  s = bfd_get_section_by_name (abfd, ".dynsym");	  if (s != NULL)	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;	  break;	}    }  return true;}/* Map symbol from it's internal number to the external number, moving   all local symbols to be at the head of the list.  */static INLINE intsym_is_global (abfd, sym)     bfd *abfd;     asymbol *sym;{  /* If the backend has a special mapping, use it.  */  if (get_elf_backend_data (abfd)->elf_backend_sym_is_global)    return ((*get_elf_backend_data (abfd)->elf_backend_sym_is_global)	    (abfd, sym));  return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0	  || bfd_is_und_section (bfd_get_section (sym))	  || bfd_is_com_section (bfd_get_section (sym)));}static booleanelf_map_symbols (abfd)     bfd *abfd;{  int symcount = bfd_get_symcount (abfd);  asymbol **syms = bfd_get_outsymbols (abfd);  asymbol **sect_syms;  int num_locals = 0;  int num_globals = 0;  int num_locals2 = 0;  int num_globals2 = 0;  int max_index = 0;  int num_sections = 0;  int idx;  asection *asect;  asymbol **new_syms;  asymbol *sym;#ifdef DEBUG  fprintf (stderr, "elf_map_symbols\n");  fflush (stderr);#endif  /* Add a section symbol for each BFD section.  FIXME: Is this really     necessary?  */  for (asect = abfd->sections; asect; asect = asect->next)    {      if (max_index < asect->index)	max_index = asect->index;    }  max_index++;  sect_syms = (asymbol **) bfd_zalloc (abfd, max_index * sizeof (asymbol *));  if (sect_syms == NULL)    return false;  elf_section_syms (abfd) = sect_syms;  for (idx = 0; idx < symcount; idx++)    {      sym = syms[idx];      if ((sym->flags & BSF_SECTION_SYM) != 0	  && sym->value == 0)	{	  asection *sec;	  sec = sym->section;	  if (sec->owner != NULL)	    {	      if (sec->owner != abfd)		{		  if (sec->output_offset != 0)		    continue;		  sec = sec->output_section;		  /* Empty sections in the input files may have had a section		     symbol created for them.  (See the comment near the end of		     _bfd_generic_link_output_symbols in linker.c).  If the linker		     script discards such sections then we will reach this point.		     Since we know that we cannot avoid this case, we detect it		     and skip the abort and the assignment to the sect_syms array.		     To reproduce this particular case try running the linker		     testsuite test ld-scripts/weak.exp for an ELF port that uses		     the generic linker.  */		  if (sec->owner == NULL)		    continue;		  BFD_ASSERT (sec->owner == abfd);		}	      sect_syms[sec->index] = syms[idx];	    }	}    }  for (asect = abfd->sections; asect; asect = asect->next)    {      if (sect_syms[asect->index] != NULL)	continue;      sym = bfd_make_empty_symbol (abfd);      if (sym == NULL)	return false;      sym->the_bfd = abfd;      sym->name = asect->name;      sym->value = 0;      /* Set the flags to 0 to indicate that this one was newly added.  */      sym->flags = 0;      sym->section = asect;      sect_syms[asect->index] = sym;      num_sections++;#ifdef DEBUG      fprintf (stderr, _("creating section symbol, name = %s, value = 0x%.8lx, index = %d, section = 0x%.8lx\n"),	       asect->name, (long) asect->vma, asect->index, (long) asect);#endif    }  /* Classify all of the symbols.  */  for (idx = 0; idx < symcount; idx++)    {      if (!sym_is_global (abfd, syms[idx]))	num_locals++;      else	num_globals++;    }  for (asect = abfd->sections; asect; asect = asect->next)    {      if (sect_syms[asect->index] != NULL	  && sect_syms[asect->index]->flags == 0)	{	  sect_syms[asect->index]->flags = BSF_SECTION_SYM;	  if (!sym_is_global (abfd, sect_syms[asect->index]))	    num_locals++;	  else	    num_globals++;	  sect_syms[asect->index]->flags = 0;	}    }  /* Now sort the symbols so the local symbols are first.  */  new_syms = ((asymbol **)	      bfd_alloc (abfd,			 (num_locals + num_globals) * sizeof (asymbol *)));  if (new_syms == NULL)    return false;  for (idx = 0; idx < symcount; idx++)    {      asymbol *sym = syms[idx];      int i;      if (!sym_is_global (abfd, sym))	i = num_locals2++;      else	i = num_locals + num_globals2++;      new_syms[i] = sym;      sym->udata.i = i + 1;    }  for (asect = abfd->sections; asect; asect = asect->next)    {      if (sect_syms[asect->index] != NULL	  && sect_syms[asect->index]->flags == 0)	{	  asymbol *sym = sect_syms[asect->index];	  int i;	  sym->flags = BSF_SECTION_SYM;	  if (!sym_is_global (abfd, sym))	    i = num_locals2++;	  else	    i = num_locals + num_globals2++;	  new_syms[i] = sym;	  sym->udata.i = i + 1;	}    }  bfd_set_symtab (abfd, new_syms, num_locals + num_globals);  elf_num_locals (abfd) = num_locals;  elf_num_globals (abfd) = num_globals;  return true;}/* Align to the maximum file alignment that could be required for any   ELF data structure.  */static INLINE file_ptr align_file_position PARAMS ((file_ptr, int));static INLINE file_ptralign_file_position (off, align)     file_ptr off;     int align;{  return (off + align - 1) & ~(align - 1);}/* Assign a file position to a section, optionally aligning to the   required section alignment.  */INLINE file_ptr_bfd_elf_assign_file_position_for_section (i_shdrp, offset, align)     Elf_Internal_Shdr *i_shdrp;     file_ptr offset;     boolean align;{  if (align)    {      unsigned int al;      al = i_shdrp->sh_addralign;      if (al > 1)	offset = BFD_ALIGN (offset, al);    }  i_shdrp->sh_offset = offset;  if (i_shdrp->bfd_section != NULL)    i_shdrp->bfd_section->filepos = offset;  if (i_shdrp->sh_type != SHT_NOBITS)    offset += i_shdrp->sh_size;  return offset;}/* Compute the file positions we are going to put the sections at, and   otherwise prepare to begin writing out the ELF file.  If LINK_INFO   is not NULL, this is being called by the ELF backend linker.  */boolean_bfd_elf_compute_section_file_positions (abfd, link_info)     bfd *abfd;     struct bfd_link_info *link_info;{  struct elf_backend_data *bed = get_elf_backend_data (abfd);  boolean failed;  struct bfd_strtab_hash *strtab;  Elf_Internal_Shdr *shstrtab_hdr;  if (abfd->output_has_begun)    return true;  /* Do any elf backend specific processing first.  */  if (bed->elf_backend_begin_write_processing)    (*bed->elf_backend_begin_write_processing) (abfd, link_info);  if (! prep_headers (abfd))    return false;  /* Post process the headers if necessary.  */  if (bed->elf_backend_post_process_headers)    (*bed->elf_backend_post_process_headers) (abfd, link_info);  failed = false;  bfd_map_over_sections (abfd, elf_fake_sections, &failed);  if (failed)    return false;  if (!assign_section_numbers (abfd))    return false;  /* The backend linker builds symbol table information itself.  */  if (link_info == NULL && bfd_get_symcount (abfd) > 0)    {      

⌨️ 快捷键说明

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