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

📄 elf-m10300.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
		    {		      long r_type;		      unsigned long r_index;		      unsigned char code;		      r_type = ELF32_R_TYPE (irel->r_info);		      r_index = ELF32_R_SYM (irel->r_info);		      if (r_type < 0 || r_type >= (int) R_MN10300_MAX)			goto error_return;		      /* We need the name and hash table entry of the target			 symbol!  */		      hash = NULL;		      sym = NULL;		      sym_sec = NULL;		      if (r_index < symtab_hdr->sh_info)			{			  /* A local symbol.  */			  Elf_Internal_Sym isym;			  bfd_elf32_swap_symbol_in (input_bfd,						    extsyms + r_index, &isym);			  if (isym.st_shndx == SHN_UNDEF)			    sym_sec = bfd_und_section_ptr;			  else if (isym.st_shndx > 0				   && isym.st_shndx < SHN_LORESERVE)			    sym_sec			      = bfd_section_from_elf_index (input_bfd,							    isym.st_shndx);			  else if (isym.st_shndx == SHN_ABS)			    sym_sec = bfd_abs_section_ptr;			  else if (isym.st_shndx == SHN_COMMON)			    sym_sec = bfd_com_section_ptr;			  sym_name = bfd_elf_string_from_elf_section (input_bfd,							   symtab_hdr->sh_link,							   isym.st_name);			  /* If it isn't a function, then we don't care			     about it.  */			  if (r_index < symtab_hdr->sh_info			      && ELF_ST_TYPE (isym.st_info) != STT_FUNC)			    continue;			  /* Tack on an ID so we can uniquely identify this			     local symbol in the global hash table.  */			  new_name = bfd_malloc (strlen (sym_name) + 10);			  if (new_name == 0)			    goto error_return;			  sprintf (new_name, "%s_%08x",				   sym_name, (int) sym_sec);			  sym_name = new_name;			  hash = (struct elf32_mn10300_link_hash_entry *)				   elf_link_hash_lookup (&hash_table->static_hash_table->root,						         sym_name, true,						         true, false);			  free (new_name);			}		      else			{			  r_index -= symtab_hdr->sh_info;			  hash = (struct elf32_mn10300_link_hash_entry *)				   elf_sym_hashes (input_bfd)[r_index];			}		      /* If this is not a "call" instruction, then we			 should convert "call" instructions to "calls"			 instructions.  */		      code = bfd_get_8 (input_bfd,					contents + irel->r_offset - 1);		      if (code != 0xdd && code != 0xcd)			hash->flags |= MN10300_CONVERT_CALL_TO_CALLS;		      /* If this is a jump/call, then bump the direct_calls			 counter.  Else force "call" to "calls" conversions.  */		      if (r_type == R_MN10300_PCREL32			  || r_type == R_MN10300_PCREL16)			hash->direct_calls++;		      else			hash->flags |= MN10300_CONVERT_CALL_TO_CALLS;		    }		}	      /* Now look at the actual contents to get the stack size,		 and a list of what registers were saved in the prologue		 (ie movm_args).  */	      if ((section->flags & SEC_CODE) != 0)		{		  Elf32_External_Sym *esym, *esymend;		  int idx, shndx;		  shndx = _bfd_elf_section_from_bfd_section (input_bfd,							     section);		  /* Look at each function defined in this section and		     update info for that function.  */		  esym = extsyms;		  esymend = esym + symtab_hdr->sh_info;		  for (; esym < esymend; esym++)		    {		      Elf_Internal_Sym isym;		      bfd_elf32_swap_symbol_in (input_bfd, esym, &isym);		      if (isym.st_shndx == shndx			  && ELF_ST_TYPE (isym.st_info) == STT_FUNC)			{			  if (isym.st_shndx == SHN_UNDEF)			    sym_sec = bfd_und_section_ptr;			  else if (isym.st_shndx > 0				   && isym.st_shndx < SHN_LORESERVE)			    sym_sec			      = bfd_section_from_elf_index (input_bfd,							    isym.st_shndx);			  else if (isym.st_shndx == SHN_ABS)			    sym_sec = bfd_abs_section_ptr;			  else if (isym.st_shndx == SHN_COMMON)			    sym_sec = bfd_com_section_ptr;			  sym_name = bfd_elf_string_from_elf_section (input_bfd,							symtab_hdr->sh_link,							isym.st_name);			  /* Tack on an ID so we can uniquely identify this			     local symbol in the global hash table.  */			  new_name = bfd_malloc (strlen (sym_name) + 10);			  if (new_name == 0)			    goto error_return;			  sprintf (new_name, "%s_%08x",				   sym_name, (int) sym_sec);			  sym_name = new_name;			  hash = (struct elf32_mn10300_link_hash_entry *)				    elf_link_hash_lookup (&hash_table->static_hash_table->root,						          sym_name, true,						          true, false);			  free (new_name);			  compute_function_info (input_bfd, hash,						 isym.st_value, contents);			}		    }		  esym = extsyms + symtab_hdr->sh_info;		  esymend = extsyms + (symtab_hdr->sh_size				       / sizeof (Elf32_External_Sym));		  for (idx = 0; esym < esymend; esym++, idx++)		    {		      Elf_Internal_Sym isym;		      bfd_elf32_swap_symbol_in (input_bfd, esym, &isym);		      hash = (struct elf32_mn10300_link_hash_entry *)			       elf_sym_hashes (input_bfd)[idx];		      if (isym.st_shndx == shndx			  && ELF_ST_TYPE (isym.st_info) == STT_FUNC			  && (hash)->root.root.u.def.section == section			  && ((hash)->root.root.type == bfd_link_hash_defined			      || (hash)->root.root.type == bfd_link_hash_defweak))			compute_function_info (input_bfd, hash,					       (hash)->root.root.u.def.value,					       contents);		    }		}	      /* Cache or free any memory we allocated for the relocs.  */	      if (free_relocs != NULL)		{		  free (free_relocs);		  free_relocs = NULL;		}	      /* Cache or free any memory we allocated for the contents.  */	      if (free_contents != NULL)		{		  if (! link_info->keep_memory)		    free (free_contents);		  else		    {		      /* Cache the section contents for elf_link_input_bfd.  */		      elf_section_data (section)->this_hdr.contents = contents;		    }		  free_contents = NULL;		}	    }	  /* Cache or free any memory we allocated for the symbols.  */	  if (free_extsyms != NULL)	    {	      if (! link_info->keep_memory)		free (free_extsyms);	      else		{		  /* Cache the symbols for elf_link_input_bfd.  */		  symtab_hdr->contents = extsyms;		}	      free_extsyms = NULL;	    }	}      /* Now iterate on each symbol in the hash table and perform	 the final initialization steps on each.  */      elf32_mn10300_link_hash_traverse (hash_table,					elf32_mn10300_finish_hash_table_entry,					NULL);      elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,					elf32_mn10300_finish_hash_table_entry,					NULL);      /* All entries in the hash table are fully initialized.  */      hash_table->flags |= MN10300_HASH_ENTRIES_INITIALIZED;      /* Now that everything has been initialized, go through each	 code section and delete any prologue insns which will be	 redundant because their operations will be performed by	 a "call" instruction.  */      for (input_bfd = link_info->input_bfds;	   input_bfd != NULL;	   input_bfd = input_bfd->link_next)	{	  asection *section;	  /* We're going to need all the symbols for each bfd.  */	  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;	  /* Get cached copy if it exists.  */	  if (symtab_hdr->contents != NULL)	    extsyms = (Elf32_External_Sym *) symtab_hdr->contents;	  else	    {	      /* Go get them off disk.  */	      extsyms = ((Elf32_External_Sym *)			 bfd_malloc (symtab_hdr->sh_size));	      if (extsyms == NULL)		goto error_return;	      free_extsyms = extsyms;	      if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0		  || (bfd_read (extsyms, 1, symtab_hdr->sh_size, input_bfd)		      != symtab_hdr->sh_size))		goto error_return;	    }	  /* Walk over each section in this bfd.  */	  for (section = input_bfd->sections;	       section != NULL;	       section = section->next)	    {	      int shndx;	      Elf32_External_Sym *esym, *esymend;	      int idx;	      /* Skip non-code sections and empty sections.  */	      if ((section->flags & SEC_CODE) == 0 || section->_raw_size == 0)		continue;	      if (section->reloc_count != 0)		{		  /* Get a copy of the native relocations.  */		  internal_relocs = (_bfd_elf32_link_read_relocs				     (input_bfd, section, (PTR) NULL,				      (Elf_Internal_Rela *) NULL,				      link_info->keep_memory));		  if (internal_relocs == NULL)		    goto error_return;		  if (! link_info->keep_memory)		    free_relocs = internal_relocs;		}	      /* Get cached copy of section contents if it exists.  */	      if (elf_section_data (section)->this_hdr.contents != NULL)		contents = elf_section_data (section)->this_hdr.contents;	      else		{		  /* Go get them off disk.  */		  contents = (bfd_byte *) bfd_malloc (section->_raw_size);		  if (contents == NULL)		    goto error_return;		  free_contents = contents;		  if (!bfd_get_section_contents (input_bfd, section,						 contents, (file_ptr) 0,						 section->_raw_size))		    goto error_return;		}	      shndx = _bfd_elf_section_from_bfd_section (input_bfd, section);	      /* Now look for any function in this section which needs		 insns deleted from its prologue.  */	      esym = extsyms;	      esymend = esym + symtab_hdr->sh_info;	      for (; esym < esymend; esym++)		{		  Elf_Internal_Sym isym;		  struct elf32_mn10300_link_hash_entry *sym_hash;		  asection *sym_sec = NULL;		  const char *sym_name;		  char *new_name;		  bfd_elf32_swap_symbol_in (input_bfd, esym, &isym);		  if (isym.st_shndx != shndx)		    continue;		  if (isym.st_shndx == SHN_UNDEF)		    sym_sec = bfd_und_section_ptr;		  else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)		    sym_sec		      = bfd_section_from_elf_index (input_bfd, isym.st_shndx);		  else if (isym.st_shndx == SHN_ABS)		    sym_sec = bfd_abs_section_ptr;		  else if (isym.st_shndx == SHN_COMMON)		    sym_sec = bfd_com_section_ptr;		  else		    abort ();		  sym_name = bfd_elf_string_from_elf_section (input_bfd,							symtab_hdr->sh_link,							isym.st_name);		  /* Tack on an ID so we can uniquely identify this		     local symbol in the global hash table.  */		  new_name = bfd_malloc (strlen (sym_name) + 10);		  if (new_name == 0)		    goto error_return;		  sprintf (new_name, "%s_%08x", sym_name, (int) sym_sec);		  sym_name = new_name;		  sym_hash = (struct elf32_mn10300_link_hash_entry *)			    elf_link_hash_lookup (&hash_table->static_hash_table->root,					          sym_name, false,					          false, false);		  free (new_name);		  if (sym_hash == NULL)		    continue;		  if (! ((sym_hash)->flags & MN10300_CONVERT_CALL_TO_CALLS)		      && ! ((sym_hash)->flags & MN10300_DELETED_PROLOGUE_BYTES))		    {		      int bytes = 0;		      /* Note that we've changed things.  */		      elf_section_data (section)->relocs = internal_relocs;		      free_relocs = NULL;		      elf_section_data (section)->this_hdr.contents = contents;		      free_contents = NULL;		      symtab_hdr->contents = (bfd_byte *) extsyms;		      free_extsyms = NULL;		      /* Count how many bytes we're going to delete.  */		      if (sym_hash->movm_args)			bytes += 2;		      if (sym_hash->stack_size && sym_hash->stack_size <= 128)			bytes += 3;		      else if (sym_hash->stack_size			       && sym_hash->stack_size < 256)			bytes += 4;		      /* Note that we've deleted prologue bytes for this			 function.  */		      sym_hash->flags |= MN10300_DELETED_PROLOGUE_BYTES;		      /* Actually delete the bytes.  */		      if (!mn10300_elf_relax_delete_bytes (input_bfd,							   section,							   isym.st_value,							   bytes))			goto error_return;		      /* Something changed.  Not strictly necessary, but			 may lead to more relaxing opportunities.  */		      *again = true;		    }		}	      /* Look for any global functions in this section which		 need insns deleted from their prologues.  */	      esym = extsyms + symtab_hdr->sh_info;	      esymend = extsyms + (symtab_hdr->sh_size				   / sizeof (Elf32_External_Sym));	      for (idx = 0; esym < esymend; esym++, idx++)		{		  Elf_Internal_Sym isym;		  struct elf32_mn10300_link_hash_entry *sym_hash;		  bfd_elf32_swap_symbol_in (input_bfd, esym, &isym);		  sym_hash = (struct elf32_mn10300_link_hash_entry *)			       (elf_sym_hashes (input_bfd)[idx]);		  if (isym.st_shndx == shndx		      && (sym_hash)->root.root.u.def.section == section		      && ! ((sym_hash)->flags & MN10300_CONVERT_CALL_TO_CALLS)		      && ! ((sym_hash)->flags & MN10300_DELETED_PROLOGUE_BYTES))		    {		      int bytes = 0;		      /* Note that we've changed things.  */		      elf_section_data (section)->relocs = internal_relocs;		      free_relocs = NULL;		      elf_section_data (section)->this_hdr.contents = contents;		      free_contents = NULL;		      symtab_hdr->contents = (bfd_byte *) extsyms;		      free_extsyms = NULL;		      /* Count how many bytes we're going to delete.  */		      if (sym_hash->movm_args)			bytes += 2;		      if (sym_hash->stack_size && sym_hash->stack_size <= 128)			bytes += 3;		      else if (sym_hash->stack_size			       && sym_hash->stack_size < 256)			bytes += 4;		      /* Note that we've deleted prologue bytes for this			 function.  */		      sym_hash->flags |= MN10300_DELETED_PROLOGUE_BYTES;		      /* Actually delete the bytes.  */		      if (!mn10300_elf_relax_delete_bytes (input_bfd,							   section,							   (sym_hash)->root.root.u.def.value,							   bytes))			goto error_return;		      /* Something changed.  Not strictly necessary, but			 may lead to more relaxing opportunities.  */		      *again = true;		    }		}	      /* Cache or free any memory we allocated for the relocs.  */	      if (free_relocs != NULL)		{		  free (free_relocs);

⌨️ 快捷键说明

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