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

📄 sunos.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
struct bfd_link_needed_list *bfd_sunos_get_needed_list (abfd, info)     bfd *abfd ATTRIBUTE_UNUSED;     struct bfd_link_info *info;{  if (info->hash->creator != &MY(vec))    return NULL;  return sunos_hash_table (info)->needed;}/* Record an assignment made to a symbol by a linker script.  We need   this in case some dynamic object refers to this symbol.  */booleanbfd_sunos_record_link_assignment (output_bfd, info, name)     bfd *output_bfd;     struct bfd_link_info *info;     const char *name;{  struct sunos_link_hash_entry *h;  if (output_bfd->xvec != &MY(vec))    return true;  /* This is called after we have examined all the input objects.  If     the symbol does not exist, it merely means that no object refers     to it, and we can just ignore it at this point.  */  h = sunos_link_hash_lookup (sunos_hash_table (info), name,			      false, false, false);  if (h == NULL)    return true;  /* In a shared library, the __DYNAMIC symbol does not appear in the     dynamic symbol table.  */  if (! info->shared || strcmp (name, "__DYNAMIC") != 0)    {      h->flags |= SUNOS_DEF_REGULAR;      if (h->dynindx == -1)	{	  ++sunos_hash_table (info)->dynsymcount;	  h->dynindx = -2;	}    }  return true;}/* Set up the sizes and contents of the dynamic sections created in   sunos_add_dynamic_symbols.  This is called by the SunOS linker   emulation before_allocation routine.  We must set the sizes of the   sections before the linker sets the addresses of the various   sections.  This unfortunately requires reading all the relocs so   that we can work out which ones need to become dynamic relocs.  If   info->keep_memory is true, we keep the relocs in memory; otherwise,   we discard them, and will read them again later.  */booleanbfd_sunos_size_dynamic_sections (output_bfd, info, sdynptr, sneedptr,				 srulesptr)     bfd *output_bfd;     struct bfd_link_info *info;     asection **sdynptr;     asection **sneedptr;     asection **srulesptr;{  bfd *dynobj;  size_t dynsymcount;  struct sunos_link_hash_entry *h;  asection *s;  size_t bucketcount;  size_t hashalloc;  size_t i;  bfd *sub;  *sdynptr = NULL;  *sneedptr = NULL;  *srulesptr = NULL;  if (info->relocateable)    return true;  if (output_bfd->xvec != &MY(vec))    return true;  /* Look through all the input BFD's and read their relocs.  It would     be better if we didn't have to do this, but there is no other way     to determine the number of dynamic relocs we need, and, more     importantly, there is no other way to know which symbols should     get an entry in the procedure linkage table.  */  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)    {      if ((sub->flags & DYNAMIC) == 0	  && sub->xvec == output_bfd->xvec)	{	  if (! sunos_scan_relocs (info, sub, obj_textsec (sub),				   exec_hdr (sub)->a_trsize)	      || ! sunos_scan_relocs (info, sub, obj_datasec (sub),				      exec_hdr (sub)->a_drsize))	    return false;	}    }  dynobj = sunos_hash_table (info)->dynobj;  dynsymcount = sunos_hash_table (info)->dynsymcount;  /* If there were no dynamic objects in the link, and we don't need     to build a global offset table, there is nothing to do here.  */  if (! sunos_hash_table (info)->dynamic_sections_needed      && ! sunos_hash_table (info)->got_needed)    return true;  /* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it.  */  h = sunos_link_hash_lookup (sunos_hash_table (info),			      "__GLOBAL_OFFSET_TABLE_", false, false, false);  if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0)    {      h->flags |= SUNOS_DEF_REGULAR;      if (h->dynindx == -1)	{	  ++sunos_hash_table (info)->dynsymcount;	  h->dynindx = -2;	}      h->root.root.type = bfd_link_hash_defined;      h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got");      /* If the .got section is more than 0x1000 bytes, we set         __GLOBAL_OFFSET_TABLE_ to be 0x1000 bytes into the section,         so that 13 bit relocations have a greater chance of working.  */      s = bfd_get_section_by_name (dynobj, ".got");      BFD_ASSERT (s != NULL);      if (s->_raw_size >= 0x1000)	h->root.root.u.def.value = 0x1000;      else	h->root.root.u.def.value = 0;      sunos_hash_table (info)->got_base = h->root.root.u.def.value;    }  /* If there are any shared objects in the link, then we need to set     up the dynamic linking information.  */  if (sunos_hash_table (info)->dynamic_sections_needed)    {      *sdynptr = bfd_get_section_by_name (dynobj, ".dynamic");      /* The .dynamic section is always the same size.  */      s = *sdynptr;      BFD_ASSERT (s != NULL);      s->_raw_size = (sizeof (struct external_sun4_dynamic)		      + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE		      + sizeof (struct external_sun4_dynamic_link));      /* Set the size of the .dynsym and .hash sections.  We counted	 the number of dynamic symbols as we read the input files.  We	 will build the dynamic symbol table (.dynsym) and the hash	 table (.hash) when we build the final symbol table, because	 until then we do not know the correct value to give the	 symbols.  We build the dynamic symbol string table (.dynstr)	 in a traversal of the symbol table using	 sunos_scan_dynamic_symbol.  */      s = bfd_get_section_by_name (dynobj, ".dynsym");      BFD_ASSERT (s != NULL);      s->_raw_size = dynsymcount * sizeof (struct external_nlist);      s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);      if (s->contents == NULL && s->_raw_size != 0)	return false;      /* The number of buckets is just the number of symbols divided	 by four.  To compute the final size of the hash table, we	 must actually compute the hash table.  Normally we need	 exactly as many entries in the hash table as there are	 dynamic symbols, but if some of the buckets are not used we	 will need additional entries.  In the worst case, every	 symbol will hash to the same bucket, and we will need	 BUCKETCOUNT - 1 extra entries.  */      if (dynsymcount >= 4)	bucketcount = dynsymcount / 4;      else if (dynsymcount > 0)	bucketcount = dynsymcount;      else	bucketcount = 1;      s = bfd_get_section_by_name (dynobj, ".hash");      BFD_ASSERT (s != NULL);      hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE;      s->contents = (bfd_byte *) bfd_alloc (dynobj, hashalloc);      if (s->contents == NULL && dynsymcount > 0)	return false;      memset (s->contents, 0, hashalloc);      for (i = 0; i < bucketcount; i++)	PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE);      s->_raw_size = bucketcount * HASH_ENTRY_SIZE;      sunos_hash_table (info)->bucketcount = bucketcount;      /* Scan all the symbols, place them in the dynamic symbol table,	 and build the dynamic hash table.  We reuse dynsymcount as a	 counter for the number of symbols we have added so far.  */      sunos_hash_table (info)->dynsymcount = 0;      sunos_link_hash_traverse (sunos_hash_table (info),				sunos_scan_dynamic_symbol,				(PTR) info);      BFD_ASSERT (sunos_hash_table (info)->dynsymcount == dynsymcount);      /* The SunOS native linker seems to align the total size of the	 symbol strings to a multiple of 8.  I don't know if this is	 important, but it can't hurt much.  */      s = bfd_get_section_by_name (dynobj, ".dynstr");      BFD_ASSERT (s != NULL);      if ((s->_raw_size & 7) != 0)	{	  bfd_size_type add;	  bfd_byte *contents;	  add = 8 - (s->_raw_size & 7);	  contents = (bfd_byte *) bfd_realloc (s->contents,					       (size_t) (s->_raw_size + add));	  if (contents == NULL)	    return false;	  memset (contents + s->_raw_size, 0, (size_t) add);	  s->contents = contents;	  s->_raw_size += add;	}    }  /* Now that we have worked out the sizes of the procedure linkage     table and the dynamic relocs, allocate storage for them.  */  s = bfd_get_section_by_name (dynobj, ".plt");  BFD_ASSERT (s != NULL);  if (s->_raw_size != 0)    {      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);      if (s->contents == NULL)	return false;      /* Fill in the first entry in the table.  */      switch (bfd_get_arch (dynobj))	{	case bfd_arch_sparc:	  memcpy (s->contents, sparc_plt_first_entry, SPARC_PLT_ENTRY_SIZE);	  break;	case bfd_arch_m68k:	  memcpy (s->contents, m68k_plt_first_entry, M68K_PLT_ENTRY_SIZE);	  break;	default:	  abort ();	}    }  s = bfd_get_section_by_name (dynobj, ".dynrel");  if (s->_raw_size != 0)    {      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);      if (s->contents == NULL)	return false;    }  /* We use the reloc_count field to keep track of how many of the     relocs we have output so far.  */  s->reloc_count = 0;  /* Make space for the global offset table.  */  s = bfd_get_section_by_name (dynobj, ".got");  s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);  if (s->contents == NULL)    return false;  *sneedptr = bfd_get_section_by_name (dynobj, ".need");  *srulesptr = bfd_get_section_by_name (dynobj, ".rules");  return true;}/* Scan the relocs for an input section.  */static booleansunos_scan_relocs (info, abfd, sec, rel_size)     struct bfd_link_info *info;     bfd *abfd;     asection *sec;     bfd_size_type rel_size;{  PTR relocs;  PTR free_relocs = NULL;  if (rel_size == 0)    return true;  if (! info->keep_memory)    relocs = free_relocs = bfd_malloc ((size_t) rel_size);  else    {      struct aout_section_data_struct *n;      n = ((struct aout_section_data_struct *)	   bfd_alloc (abfd, sizeof (struct aout_section_data_struct)));      if (n == NULL)	relocs = NULL;      else	{	  set_aout_section_data (sec, n);	  relocs = bfd_malloc ((size_t) rel_size);	  aout_section_data (sec)->relocs = relocs;	}    }  if (relocs == NULL)    return false;  if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0      || bfd_read (relocs, 1, rel_size, abfd) != rel_size)    goto error_return;  if (obj_reloc_entry_size (abfd) == RELOC_STD_SIZE)    {      if (! sunos_scan_std_relocs (info, abfd, sec,				   (struct reloc_std_external *) relocs,				   rel_size))	goto error_return;    }  else    {      if (! sunos_scan_ext_relocs (info, abfd, sec,				   (struct reloc_ext_external *) relocs,				   rel_size))	goto error_return;    }  if (free_relocs != NULL)    free (free_relocs);  return true; error_return:  if (free_relocs != NULL)    free (free_relocs);  return false;}/* Scan the relocs for an input section using standard relocs.  We   need to figure out what to do for each reloc against a dynamic   symbol.  If the symbol is in the .text section, an entry is made in   the procedure linkage table.  Note that this will do the wrong   thing if the symbol is actually data; I don't think the Sun 3   native linker handles this case correctly either.  If the symbol is   not in the .text section, we must preserve the reloc as a dynamic   reloc.  FIXME: We should also handle the PIC relocs here by   building global offset table entries.  */static booleansunos_scan_std_relocs (info, abfd, sec, relocs, rel_size)     struct bfd_link_info *info;     bfd *abfd;     asection *sec ATTRIBUTE_UNUSED;     const struct reloc_std_external *relocs;     bfd_size_type rel_size;{  bfd *dynobj;  asection *splt = NULL;  asection *srel = NULL;  struct sunos_link_hash_entry **sym_hashes;  const struct reloc_std_external *rel, *relend;  /* We only know how to handle m68k plt entries.  */  if (bfd_get_arch (abfd) != bfd_arch_m68k)    {      bfd_set_error (bfd_error_invalid_target);      return false;    }  dynobj = NULL;  sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd);  relend = relocs + rel_size / RELOC_STD_SIZE;  for (rel = relocs; rel < relend; rel++)    {      int r_index;      struct sunos_link_hash_entry *h;      /* We only want relocs against external symbols.  */      if (bfd_header_big_endian (abfd))	{	  if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG) == 0)	    continue;	}      else	{	  if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE) == 0)	    continue;	}      /* Get the symbol index.  */      if (bfd_header_big_endian (abfd))	r_index = ((rel->r_index[0] << 16)		   | (rel->r_index[1] << 8)		   | rel->r_index[2]);      else	r_index = ((rel->r_index[2] << 16)		   | (rel->r_index[1] << 8)		   | rel->r_index[0]);      /* Get the hash table entry.  */      h = sym_hashes[r_index];      if (h == NULL)	{	  /* This should not normally happen, but it will in any case	     be caught in the relocation phase.  */	  continue;	}      /* At this point common symbols have already been allocated, so	 we don't have to worry about them.  We need to consider that	 we may have already seen this symbol and marked it undefined;	 if the symbol is really undefined, then SUNOS_DEF_DYNAMIC	 will be zero.  */      if (h->root.root.type != bfd_link_hash_defined	  && h->root.root.type != bfd_link_hash_defweak	  && h->root.root.type != bfd_link_hash_undefined)	continue;

⌨️ 快捷键说明

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