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

📄 coff-mips.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
	  count = bfd_get_symcount (output_bfd);	  sym = bfd_get_outsymbols (output_bfd);	  if (sym == (asymbol **) NULL)	    i = count;	  else	    {	      for (i = 0; i < count; i++, sym++)		{		  register CONST char *name;		  name = bfd_asymbol_name (*sym);		  if (*name == '_' && strcmp (name, "_gp") == 0)		    {		      gp = bfd_asymbol_value (*sym);		      _bfd_set_gp_value (output_bfd, gp);		      break;		    }		}	    }	  if (i >= count)	    {	      /* Only get the error once.  */	      gp = 4;	      _bfd_set_gp_value (output_bfd, gp);	      *error_message =		(char *) _("GP relative relocation when _gp not defined");	      return bfd_reloc_dangerous;	    }	}    }  if (bfd_is_com_section (symbol->section))    relocation = 0;  else    relocation = symbol->value;  relocation += symbol->section->output_section->vma;  relocation += symbol->section->output_offset;  if (reloc_entry->address > input_section->_cooked_size)    return bfd_reloc_outofrange;  insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);  /* Set val to the offset into the section or symbol.  */  val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;  if (val & 0x8000)    val -= 0x10000;  /* Adjust val for the final section location and GP value.  If we     are producing relocateable output, we don't want to do this for     an external symbol.  */  if (relocateable == false      || (symbol->flags & BSF_SECTION_SYM) != 0)    val += relocation - gp;  insn = (insn &~ 0xffff) | (val & 0xffff);  bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);  if (relocateable != false)    reloc_entry->address += input_section->output_offset;  /* Make sure it fit in 16 bits.  */  if ((long) val >= 0x8000 || (long) val < -0x8000)    return bfd_reloc_overflow;  return bfd_reloc_ok;}/* Do a RELHI relocation.  We do this in conjunction with a RELLO   reloc, just as REFHI and REFLO are done together.  RELHI and RELLO   are Cygnus extensions used when generating position independent   code for embedded systems.  *//* FIXME: This should not be a static variable.  */static struct mips_hi *mips_relhi_list;static bfd_reloc_status_typemips_relhi_reloc (abfd,		  reloc_entry,		  symbol,		  data,		  input_section,		  output_bfd,		  error_message)     bfd *abfd ATTRIBUTE_UNUSED;     arelent *reloc_entry;     asymbol *symbol;     PTR data;     asection *input_section;     bfd *output_bfd;     char **error_message ATTRIBUTE_UNUSED;{  bfd_reloc_status_type ret;  bfd_vma relocation;  struct mips_hi *n;  /* If this is a reloc against a section symbol, then it is correct     in the object file.  The only time we want to change this case is     when we are relaxing, and that is handled entirely by     mips_relocate_section and never calls this function.  */  if ((symbol->flags & BSF_SECTION_SYM) != 0)    {      if (output_bfd != (bfd *) NULL)	reloc_entry->address += input_section->output_offset;      return bfd_reloc_ok;    }  /* This is an external symbol.  If we're relocating, we don't want     to change anything.  */  if (output_bfd != (bfd *) NULL)    {      reloc_entry->address += input_section->output_offset;      return bfd_reloc_ok;    }  ret = bfd_reloc_ok;  if (bfd_is_und_section (symbol->section)      && output_bfd == (bfd *) NULL)    ret = bfd_reloc_undefined;  if (bfd_is_com_section (symbol->section))    relocation = 0;  else    relocation = symbol->value;  relocation += symbol->section->output_section->vma;  relocation += symbol->section->output_offset;  relocation += reloc_entry->addend;  if (reloc_entry->address > input_section->_cooked_size)    return bfd_reloc_outofrange;  /* Save the information, and let RELLO do the actual relocation.  */  n = (struct mips_hi *) bfd_malloc (sizeof *n);  if (n == NULL)    return bfd_reloc_outofrange;  n->addr = (bfd_byte *) data + reloc_entry->address;  n->addend = relocation;  n->next = mips_relhi_list;  mips_relhi_list = n;  if (output_bfd != (bfd *) NULL)    reloc_entry->address += input_section->output_offset;  return ret;}/* Do a RELLO relocation.  This is a straightforward 16 bit PC   relative relocation; this function exists in order to do the RELHI   relocation described above.  */static bfd_reloc_status_typemips_rello_reloc (abfd,		  reloc_entry,		  symbol,		  data,		  input_section,		  output_bfd,		  error_message)     bfd *abfd;     arelent *reloc_entry;     asymbol *symbol;     PTR data;     asection *input_section;     bfd *output_bfd;     char **error_message;{  if (mips_relhi_list != NULL)    {      struct mips_hi *l;      l = mips_relhi_list;      while (l != NULL)	{	  unsigned long insn;	  unsigned long val;	  unsigned long vallo;	  struct mips_hi *next;	  /* Do the RELHI relocation.  Note that we actually don't	     need to know anything about the RELLO itself, except	     where to find the low 16 bits of the addend needed by the	     RELHI.  */	  insn = bfd_get_32 (abfd, l->addr);	  vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)		   & 0xffff);	  val = ((insn & 0xffff) << 16) + vallo;	  val += l->addend;	  /* If the symbol is defined, make val PC relative.  If the	     symbol is not defined we don't want to do this, because	     we don't want the value in the object file to incorporate	     the address of the reloc.  */	  if (! bfd_is_und_section (bfd_get_section (symbol))	      && ! bfd_is_com_section (bfd_get_section (symbol)))	    val -= (input_section->output_section->vma		    + input_section->output_offset		    + reloc_entry->address);	  /* The low order 16 bits are always treated as a signed	     value.  Therefore, a negative value in the low order bits	     requires an adjustment in the high order bits.  We need	     to make this adjustment in two ways: once for the bits we	     took from the data, and once for the bits we are putting	     back in to the data.  */	  if ((vallo & 0x8000) != 0)	    val -= 0x10000;	  if ((val & 0x8000) != 0)	    val += 0x10000;	  insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);	  bfd_put_32 (abfd, insn, l->addr);	  next = l->next;	  free (l);	  l = next;	}      mips_relhi_list = NULL;    }  /* If this is a reloc against a section symbol, then it is correct     in the object file.  The only time we want to change this case is     when we are relaxing, and that is handled entirely by     mips_relocate_section and never calls this function.  */  if ((symbol->flags & BSF_SECTION_SYM) != 0)    {      if (output_bfd != (bfd *) NULL)	reloc_entry->address += input_section->output_offset;      return bfd_reloc_ok;    }  /* bfd_perform_relocation does not handle pcrel_offset relocations     correctly when generating a relocateable file, so handle them     directly here.  */  if (output_bfd != (bfd *) NULL)    {      reloc_entry->address += input_section->output_offset;      return bfd_reloc_ok;    }  /* Now do the RELLO reloc in the usual way.  */  return mips_generic_reloc (abfd, reloc_entry, symbol, data,			      input_section, output_bfd, error_message);}/* This is the special function for the MIPS_R_SWITCH reloc.  This   special reloc is normally correct in the object file, and only   requires special handling when relaxing.  We don't want   bfd_perform_relocation to tamper with it at all.  */static bfd_reloc_status_typemips_switch_reloc (abfd,		   reloc_entry,		   symbol,		   data,		   input_section,		   output_bfd,		   error_message)     bfd *abfd ATTRIBUTE_UNUSED;     arelent *reloc_entry ATTRIBUTE_UNUSED;     asymbol *symbol ATTRIBUTE_UNUSED;     PTR data ATTRIBUTE_UNUSED;     asection *input_section ATTRIBUTE_UNUSED;     bfd *output_bfd ATTRIBUTE_UNUSED;     char **error_message ATTRIBUTE_UNUSED;{  return bfd_reloc_ok;}/* Get the howto structure for a generic reloc type.  */static reloc_howto_type *mips_bfd_reloc_type_lookup (abfd, code)     bfd *abfd ATTRIBUTE_UNUSED;     bfd_reloc_code_real_type code;{  int mips_type;  switch (code)    {    case BFD_RELOC_16:      mips_type = MIPS_R_REFHALF;      break;    case BFD_RELOC_32:    case BFD_RELOC_CTOR:      mips_type = MIPS_R_REFWORD;      break;    case BFD_RELOC_MIPS_JMP:      mips_type = MIPS_R_JMPADDR;      break;    case BFD_RELOC_HI16_S:      mips_type = MIPS_R_REFHI;      break;    case BFD_RELOC_LO16:      mips_type = MIPS_R_REFLO;      break;    case BFD_RELOC_MIPS_GPREL:      mips_type = MIPS_R_GPREL;      break;    case BFD_RELOC_MIPS_LITERAL:      mips_type = MIPS_R_LITERAL;      break;    case BFD_RELOC_16_PCREL_S2:      mips_type = MIPS_R_PCREL16;      break;    case BFD_RELOC_PCREL_HI16_S:      mips_type = MIPS_R_RELHI;      break;    case BFD_RELOC_PCREL_LO16:      mips_type = MIPS_R_RELLO;      break;    case BFD_RELOC_GPREL32:      mips_type = MIPS_R_SWITCH;      break;    default:      return (reloc_howto_type *) NULL;    }  return &mips_howto_table[mips_type];}/* A helper routine for mips_relocate_section which handles the REFHI   and RELHI relocations.  The REFHI relocation must be followed by a   REFLO relocation (and RELHI by a RELLO), and the addend used is   formed from the addends of both instructions.  */static voidmips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust,		  relocation, pcrel)     struct internal_reloc *refhi;     struct internal_reloc *reflo;     bfd *input_bfd;     asection *input_section;     bfd_byte *contents;     size_t adjust;     bfd_vma relocation;     boolean pcrel;{  unsigned long insn;  unsigned long val;  unsigned long vallo;  if (refhi == NULL)    return;  insn = bfd_get_32 (input_bfd,		     contents + adjust + refhi->r_vaddr - input_section->vma);  if (reflo == NULL)    vallo = 0;  else    vallo = (bfd_get_32 (input_bfd,			 contents + adjust + reflo->r_vaddr - input_section->vma)	     & 0xffff);  val = ((insn & 0xffff) << 16) + vallo;  val += relocation;  /* The low order 16 bits are always treated as a signed value.     Therefore, a negative value in the low order bits requires an     adjustment in the high order bits.  We need to make this     adjustment in two ways: once for the bits we took from the data,     and once for the bits we are putting back in to the data.  */  if ((vallo & 0x8000) != 0)    val -= 0x10000;  if (pcrel)    val -= (input_section->output_section->vma	    + input_section->output_offset	    + (reflo->r_vaddr - input_section->vma + adjust));  if ((val & 0x8000) != 0)    val += 0x10000;  insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);  bfd_put_32 (input_bfd, (bfd_vma) insn,	      contents + adjust + refhi->r_vaddr - input_section->vma);}/* Relocate a section while linking a MIPS ECOFF file.  */static booleanmips_relocate_section (output_bfd, info, input_bfd, input_section,		       contents, external_relocs)     bfd *output_bfd;     struct bfd_link_info *info;     bfd *input_bfd;     asection *input_section;     bfd_byte *contents;     PTR external_relocs;{  asection **symndx_to_section;  struct ecoff_link_hash_entry **sym_hashes;  bfd_vma gp;  boolean gp_undefined;  size_t adjust;  long *offsets;  struct external_reloc *ext_rel;  struct external_reloc *ext_rel_end;  unsigned int i;  boolean got_lo;  struct internal_reloc lo_int_rel;  BFD_ASSERT (input_bfd->xvec->byteorder	      == output_bfd->xvec->byteorder);  /* We keep a table mapping the symndx found in an internal reloc to     the appropriate section.  This is faster than looking up the     section by name each time.  */  symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;  if (symndx_to_section == (asection **) NULL)    {      symndx_to_section = ((asection **)			   bfd_alloc (input_bfd,				      (NUM_RELOC_SECTIONS				       * sizeof (asection *))));      if (!symndx_to_section)	return false;

⌨️ 快捷键说明

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