elf32-i370.c

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

C
1,723
字号
    i370_elf_howto_init ();  local_got_offsets = elf_local_got_offsets (input_bfd);  for (; rel < relend; rel++)    {      enum i370_reloc_type r_type	= (enum i370_reloc_type)ELF32_R_TYPE (rel->r_info);      bfd_vma offset			= rel->r_offset;      bfd_vma addend			= rel->r_addend;      bfd_reloc_status_type r		= bfd_reloc_other;      Elf_Internal_Sym *sym		= (Elf_Internal_Sym *)0;      asection *sec			= (asection *)0;      struct elf_link_hash_entry *h	= (struct elf_link_hash_entry *)0;      const char *sym_name		= (const char *)0;      reloc_howto_type *howto;      unsigned long r_symndx;      bfd_vma relocation;      /* Unknown relocation handling */      if ((unsigned)r_type >= (unsigned)R_I370_max	  || !i370_elf_howto_table[(int)r_type])	{	  (*_bfd_error_handler) ("%s: unknown relocation type %d",				 bfd_get_filename (input_bfd),				 (int)r_type);	  bfd_set_error (bfd_error_bad_value);	  ret = false;	  continue;	}      howto = i370_elf_howto_table[(int)r_type];      r_symndx = ELF32_R_SYM (rel->r_info);      if (info->relocateable)	{	  /* This is a relocateable link.  We don't have to change	     anything, unless the reloc is against a section symbol,	     in which case we have to adjust according to where the	     section symbol winds up in the output section.  */	  if (r_symndx < symtab_hdr->sh_info)	    {	      sym = local_syms + r_symndx;	      if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION)		{		  sec = local_sections[r_symndx];		  addend = rel->r_addend += sec->output_offset + sym->st_value;		}	    }#ifdef DEBUG	  fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",		   howto->name,		   (int)r_type,		   r_symndx,		   (long)offset,		   (long)addend);#endif	  continue;	}      /* This is a final link.  */      if (r_symndx < symtab_hdr->sh_info)	{	  sym = local_syms + r_symndx;	  sec = local_sections[r_symndx];	  sym_name = "<local symbol>";	  relocation = (sec->output_section->vma			+ sec->output_offset			+ sym->st_value);	}      else	{	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];	  while (h->root.type == bfd_link_hash_indirect		 || h->root.type == bfd_link_hash_warning)	    h = (struct elf_link_hash_entry *) h->root.u.i.link;	  sym_name = h->root.root.string;	  if (h->root.type == bfd_link_hash_defined	      || h->root.type == bfd_link_hash_defweak)	    {	      sec = h->root.u.def.section;	      if (info->shared		  && ((! info->symbolic && h->dynindx != -1)		      || (h->elf_link_hash_flags			  & ELF_LINK_HASH_DEF_REGULAR) == 0)		  && (input_section->flags & SEC_ALLOC) != 0		  && (r_type == R_I370_ADDR31		      || r_type == R_I370_COPY		      || r_type == R_I370_ADDR16		      || r_type == R_I370_RELATIVE))		{		  /* In these cases, we don't need the relocation                     value.  We check specially because in some                     obscure cases sec->output_section will be NULL.  */		  relocation = 0;		}	      else		relocation = (h->root.u.def.value			      + sec->output_section->vma			      + sec->output_offset);	    }	  else if (h->root.type == bfd_link_hash_undefweak)	    relocation = 0;	  else if (info->shared		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)	    relocation = 0;	  else	    {	      (*info->callbacks->undefined_symbol) (info,						    h->root.root.string,						    input_bfd,						    input_section,						    rel->r_offset,						    true);	      ret = false;	      continue;	    }	}      switch ((int)r_type)	{	default:	  (*_bfd_error_handler) ("%s: unknown relocation type %d for symbol %s",				 bfd_get_filename (input_bfd),				 (int)r_type, sym_name);	  bfd_set_error (bfd_error_bad_value);	  ret = false;	  continue;	/* Relocations that may need to be propagated if this is a shared           object.  */	case (int)R_I370_REL31:	  /* If these relocations are not to a named symbol, they can be	     handled right here, no need to bother the dynamic linker.  */	  if (h == NULL	      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)	    break;	/* fall through */	/* Relocations that always need to be propagated if this is a shared           object.  */	case (int)R_I370_NONE:	case (int)R_I370_ADDR31:	case (int)R_I370_ADDR16:	  if (info->shared)	    {	      Elf_Internal_Rela outrel;	      boolean skip;#ifdef DEBUG	      fprintf (stderr,		       "i370_elf_relocate_section needs to create relocation for %s\n",		       (h && h->root.root.string) ? h->root.root.string : "<unknown>");#endif	      /* When generating a shared object, these relocations                 are copied into the output file to be resolved at run                 time.  */	      if (sreloc == NULL)		{		  const char *name;		  name = (bfd_elf_string_from_elf_section			  (input_bfd,			   elf_elfheader (input_bfd)->e_shstrndx,			   elf_section_data (input_section)->rel_hdr.sh_name));		  if (name == NULL)		    return false;		  BFD_ASSERT (strncmp (name, ".rela", 5) == 0			      && strcmp (bfd_get_section_name (input_bfd,							       input_section),					 name + 5) == 0);		  sreloc = bfd_get_section_by_name (dynobj, name);		  BFD_ASSERT (sreloc != NULL);		}	      skip = false;	      if (elf_section_data (input_section)->stab_info == NULL)		outrel.r_offset = rel->r_offset;	      else		{		  bfd_vma off;		  off = (_bfd_stab_section_offset			 (output_bfd, &elf_hash_table (info)->stab_info,			  input_section,			  &elf_section_data (input_section)->stab_info,			  rel->r_offset));		  if (off == (bfd_vma) -1)		    skip = true;		  outrel.r_offset = off;		}	      outrel.r_offset += (input_section->output_section->vma				  + input_section->output_offset);	      if (skip)		memset (&outrel, 0, sizeof outrel);	      /* h->dynindx may be -1 if this symbol was marked to                 become local.  */	      else if (h != NULL		       && ((! info->symbolic && h->dynindx != -1)			   || (h->elf_link_hash_flags			       & ELF_LINK_HASH_DEF_REGULAR) == 0))		{		  BFD_ASSERT (h->dynindx != -1);		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);		  outrel.r_addend = rel->r_addend;		}	      else		{		  if (r_type == R_I370_ADDR31)		    {		      outrel.r_info = ELF32_R_INFO (0, R_I370_RELATIVE);		      outrel.r_addend = relocation + rel->r_addend;		    }		  else		    {		      long indx;		      if (h == NULL)			sec = local_sections[r_symndx];		      else			{			  BFD_ASSERT (h->root.type == bfd_link_hash_defined				      || (h->root.type					  == bfd_link_hash_defweak));			  sec = h->root.u.def.section;			}		      if (sec != NULL && bfd_is_abs_section (sec))			indx = 0;		      else if (sec == NULL || sec->owner == NULL)			{			  bfd_set_error (bfd_error_bad_value);			  return false;			}		      else			{			  asection *osec;			  osec = sec->output_section;			  indx = elf_section_data (osec)->dynindx;			  BFD_ASSERT(indx > 0);#ifdef DEBUG			  if (indx <= 0)			    {			      printf ("indx=%d section=%s flags=%08x name=%s\n",				      indx, osec->name, osec->flags,				      h->root.root.string);			    }#endif			}		      outrel.r_info = ELF32_R_INFO (indx, r_type);		      outrel.r_addend = relocation + rel->r_addend;		    }		}	      bfd_elf32_swap_reloca_out (output_bfd, &outrel,					 (((Elf32_External_Rela *)					   sreloc->contents)					  + sreloc->reloc_count));	      ++sreloc->reloc_count;	      /* This reloc will be computed at runtime, so there's no                 need to do anything now, unless this is a RELATIVE                 reloc in an unallocated section.  */	      if (skip		  || (input_section->flags & SEC_ALLOC) != 0		  || ELF32_R_TYPE (outrel.r_info) != R_I370_RELATIVE)		continue;	    }	  break;	case (int)R_I370_COPY:	case (int)R_I370_RELATIVE:	  (*_bfd_error_handler) ("%s: Relocation %s is not yet supported for symbol %s.",				 bfd_get_filename (input_bfd),				 i370_elf_howto_table[ (int)r_type ]->name,				 sym_name);	  bfd_set_error (bfd_error_invalid_operation);	  ret = false;	  continue;	}#ifdef DEBUG      fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, offset = %ld, addend = %ld\n",	       howto->name,	       (int)r_type,	       sym_name,	       r_symndx,	       (long)offset,	       (long)addend);#endif      r = _bfd_final_link_relocate (howto,				    input_bfd,				    input_section,				    contents,				    offset,				    relocation,				    addend);      if (r != bfd_reloc_ok)	{	  ret = false;	  switch (r)	    {	    default:	      break;	    case bfd_reloc_overflow:	      {		const char *name;		if (h != NULL)		  name = h->root.root.string;		else		  {		    name = bfd_elf_string_from_elf_section (input_bfd,							    symtab_hdr->sh_link,							    sym->st_name);		    if (name == NULL)		      break;		    if (*name == '\0')		      name = bfd_section_name (input_bfd, sec);		  }		(*info->callbacks->reloc_overflow) (info,						    name,						    howto->name,						    (bfd_vma) 0,						    input_bfd,						    input_section,						    offset);	      }	      break;	    }	}    }#ifdef DEBUG  fprintf (stderr, "\n");#endif  return ret;}static voidi370_elf_post_process_headers (abfd, link_info)    bfd * abfd;    struct bfd_link_info * link_info ATTRIBUTE_UNUSED;{  Elf_Internal_Ehdr * i_ehdrp;  /* Elf file header, internal form */  i_ehdrp = elf_elfheader (abfd);  i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX;}#define TARGET_BIG_SYM		bfd_elf32_i370_vec#define TARGET_BIG_NAME		"elf32-i370"#define ELF_ARCH		bfd_arch_i370#define ELF_MACHINE_CODE	EM_S370#ifdef EM_I370_OLD#define ELF_MACHINE_ALT1	EM_I370_OLD#endif#define ELF_MAXPAGESIZE		0x1000#define elf_info_to_howto	i370_elf_info_to_howto#define elf_backend_plt_not_loaded 1#define elf_backend_got_symbol_offset 4#define bfd_elf32_bfd_reloc_type_lookup		i370_elf_reloc_type_lookup#define bfd_elf32_bfd_set_private_flags		i370_elf_set_private_flags#define bfd_elf32_bfd_copy_private_bfd_data	i370_elf_copy_private_bfd_data#define bfd_elf32_bfd_merge_private_bfd_data	i370_elf_merge_private_bfd_data#define elf_backend_relocate_section		i370_elf_relocate_section/* dynamic loader support is mostly broken; just enough here to be able to * link glibc's ld.so without errors. */#define elf_backend_create_dynamic_sections	i370_elf_create_dynamic_sections#define elf_backend_size_dynamic_sections	i370_elf_size_dynamic_sections#define elf_backend_finish_dynamic_sections	i370_elf_finish_dynamic_sections#define elf_backend_fake_sections		i370_elf_fake_sections#define elf_backend_section_from_shdr		i370_elf_section_from_shdr#define elf_backend_adjust_dynamic_symbol	i370_elf_adjust_dynamic_symbol#define elf_backend_check_relocs		i370_elf_check_relocs/*#define elf_backend_add_symbol_hook		i370_elf_add_symbol_hook#define elf_backend_finish_dynamic_symbol	i370_elf_finish_dynamic_symbol#define elf_backend_additional_program_headers	i370_elf_additional_program_headers#define elf_backend_modify_segment_map		i370_elf_modify_segment_map*/#define elf_backend_post_process_headers	i370_elf_post_process_headersint i370_noop(){  return 1;}/* we need to define these at least as no-ops to link glibc ld.so */#define elf_backend_add_symbol_hook \  (boolean (*) PARAMS ((bfd *, struct bfd_link_info *, \			const Elf_Internal_Sym *, const char **, flagword *, \			asection **, bfd_vma *))) 		i370_noop#define elf_backend_finish_dynamic_symbol \  (boolean (*) PARAMS ((bfd *, struct bfd_link_info *, \			struct elf_link_hash_entry *, \			Elf_Internal_Sym *)))			i370_noop#define elf_backend_additional_program_headers \  (int (*) PARAMS ((bfd *)))					i370_noop#define elf_backend_modify_segment_map \  (boolean (*) PARAMS ((bfd *)))				i370_noop#include "elf32-target.h"

⌨️ 快捷键说明

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