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

📄 som.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
	{	  bfd_put_8 (abfd, R_NO_RELOCATION + 24 + (((skip >> 2) - 1) >> 8), p);	  bfd_put_8 (abfd, (skip >> 2) - 1, p + 1);	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);	}      /* Handle it with a three byte R_NO_RELOCATION entry.  */      else	{	  bfd_put_8 (abfd, R_NO_RELOCATION + 28 + (((skip >> 2) - 1) >> 16), p);	  bfd_put_16 (abfd, (skip >> 2) - 1, p + 1);	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);	}    }  /* Ugh.  Punt and use a 4 byte entry.  */  else if (skip > 0)    {      bfd_put_8 (abfd, R_NO_RELOCATION + 31, p);      bfd_put_8 (abfd, (skip - 1) >> 16, p + 1);      bfd_put_16 (abfd, skip - 1, p + 2);      p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);    }  return p;}/* Emit the proper R_DATA_OVERRIDE fixups to handle a nonzero addend   from a BFD relocation.  Update the size of the subspace relocation   stream via SUBSPACE_RELOC_SIZE_P; also return the current pointer   into the relocation stream.  */static unsigned char *som_reloc_addend (abfd, addend, p, subspace_reloc_sizep, queue)     bfd *abfd;     int addend;     unsigned char *p;     unsigned int *subspace_reloc_sizep;     struct reloc_queue *queue;{  if ((unsigned) (addend) + 0x80 < 0x100)    {      bfd_put_8 (abfd, R_DATA_OVERRIDE + 1, p);      bfd_put_8 (abfd, addend, p + 1);      p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);    }  else if ((unsigned) (addend) + 0x8000 < 0x10000)    {      bfd_put_8 (abfd, R_DATA_OVERRIDE + 2, p);      bfd_put_16 (abfd, addend, p + 1);      p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);    }  else if ((unsigned) (addend) + 0x800000 < 0x1000000)    {      bfd_put_8 (abfd, R_DATA_OVERRIDE + 3, p);      bfd_put_8 (abfd, addend >> 16, p + 1);      bfd_put_16 (abfd, addend, p + 2);      p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);    }  else    {      bfd_put_8 (abfd, R_DATA_OVERRIDE + 4, p);      bfd_put_32 (abfd, addend, p + 1);      p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);    }  return p;}/* Handle a single function call relocation.  */static unsigned char *som_reloc_call (abfd, p, subspace_reloc_sizep, bfd_reloc, sym_num, queue)     bfd *abfd;     unsigned char *p;     unsigned int *subspace_reloc_sizep;     arelent *bfd_reloc;     int sym_num;     struct reloc_queue *queue;{  int arg_bits = HPPA_R_ARG_RELOC (bfd_reloc->addend);  int rtn_bits = arg_bits & 0x3;  int type, done = 0;  /* You'll never believe all this is necessary to handle relocations     for function calls.  Having to compute and pack the argument     relocation bits is the real nightmare.     If you're interested in how this works, just forget it.  You really     do not want to know about this braindamage.  */  /* First see if this can be done with a "simple" relocation.  Simple     relocations have a symbol number < 0x100 and have simple encodings     of argument relocations.  */  if (sym_num < 0x100)    {      switch (arg_bits)	{	case 0:	case 1:	  type = 0;	  break;	case 1 << 8:	case 1 << 8 | 1:	  type = 1;	  break;	case 1 << 8 | 1 << 6:	case 1 << 8 | 1 << 6 | 1:	  type = 2;	  break;	case 1 << 8 | 1 << 6 | 1 << 4:	case 1 << 8 | 1 << 6 | 1 << 4 | 1:	  type = 3;	  break;	case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2:	case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2 | 1:	  type = 4;	  break;	default:	  /* Not one of the easy encodings.  This will have to be	     handled by the more complex code below.  */	  type = -1;	  break;	}      if (type != -1)	{	  /* Account for the return value too.  */	  if (rtn_bits)	    type += 5;	  /* Emit a 2 byte relocation.  Then see if it can be handled	     with a relocation which is already in the relocation queue.  */	  bfd_put_8 (abfd, bfd_reloc->howto->type + type, p);	  bfd_put_8 (abfd, sym_num, p + 1);	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);	  done = 1;	}    }  /* If this could not be handled with a simple relocation, then do a hard     one.  Hard relocations occur if the symbol number was too high or if     the encoding of argument relocation bits is too complex.  */  if (! done)    {      /* Don't ask about these magic sequences.  I took them straight	 from gas-1.36 which took them from the a.out man page.  */      type = rtn_bits;      if ((arg_bits >> 6 & 0xf) == 0xe)	type += 9 * 40;      else	type += (3 * (arg_bits >> 8 & 3) + (arg_bits >> 6 & 3)) * 40;      if ((arg_bits >> 2 & 0xf) == 0xe)	type += 9 * 4;      else	type += (3 * (arg_bits >> 4 & 3) + (arg_bits >> 2 & 3)) * 4;      /* Output the first two bytes of the relocation.  These describe	 the length of the relocation and encoding style.  */      bfd_put_8 (abfd, bfd_reloc->howto->type + 10		 + 2 * (sym_num >= 0x100) + (type >= 0x100),		 p);      bfd_put_8 (abfd, type, p + 1);      /* Now output the symbol index and see if this bizarre relocation	 just happened to be in the relocation queue.  */      if (sym_num < 0x100)	{	  bfd_put_8 (abfd, sym_num, p + 2);	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);	}      else	{	  bfd_put_8 (abfd, sym_num >> 16, p + 2);	  bfd_put_16 (abfd, sym_num, p + 3);	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);	}    }  return p;}/* Return the logarithm of X, base 2, considering X unsigned.   Abort -1 if X is not a power or two or is zero.  */static intlog2 (x)     unsigned int x;{  int log = 0;  /* Test for 0 or a power of 2.  */  if (x == 0 || x != (x & -x))    return -1;  while ((x >>= 1) != 0)    log++;  return log;}static bfd_reloc_status_typehppa_som_reloc (abfd, reloc_entry, symbol_in, data,		input_section, output_bfd, error_message)     bfd *abfd ATTRIBUTE_UNUSED;     arelent *reloc_entry;     asymbol *symbol_in ATTRIBUTE_UNUSED;     PTR data ATTRIBUTE_UNUSED;     asection *input_section;     bfd *output_bfd;     char **error_message ATTRIBUTE_UNUSED;{  if (output_bfd)    {      reloc_entry->address += input_section->output_offset;      return bfd_reloc_ok;    }  return bfd_reloc_ok;}/* Given a generic HPPA relocation type, the instruction format,   and a field selector, return one or more appropriate SOM relocations.  */int **hppa_som_gen_reloc_type (abfd, base_type, format, field, sym_diff, sym)     bfd *abfd;     int base_type;     int format;     enum hppa_reloc_field_selector_type_alt field;     int sym_diff;     asymbol *sym;{  int *final_type, **final_types;  final_types = (int **) bfd_alloc (abfd, sizeof (int *) * 6);  final_type = (int *) bfd_alloc (abfd, sizeof (int));  if (!final_types || !final_type)    return NULL;  /* The field selector may require additional relocations to be     generated.  It's impossible to know at this moment if additional     relocations will be needed, so we make them.  The code to actually     write the relocation/fixup stream is responsible for removing     any redundant relocations.  */  switch (field)    {    case e_fsel:    case e_psel:    case e_lpsel:    case e_rpsel:      final_types[0] = final_type;      final_types[1] = NULL;      final_types[2] = NULL;      *final_type = base_type;      break;    case e_tsel:    case e_ltsel:    case e_rtsel:      final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));      if (!final_types[0])	return NULL;      if (field == e_tsel)	*final_types[0] = R_FSEL;      else if (field == e_ltsel)	*final_types[0] = R_LSEL;      else	*final_types[0] = R_RSEL;      final_types[1] = final_type;      final_types[2] = NULL;      *final_type = base_type;      break;    case e_lssel:    case e_rssel:      final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));      if (!final_types[0])	return NULL;      *final_types[0] = R_S_MODE;      final_types[1] = final_type;      final_types[2] = NULL;      *final_type = base_type;      break;    case e_lsel:    case e_rsel:      final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));      if (!final_types[0])	return NULL;      *final_types[0] = R_N_MODE;      final_types[1] = final_type;      final_types[2] = NULL;      *final_type = base_type;      break;    case e_ldsel:    case e_rdsel:      final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));      if (!final_types[0])	return NULL;      *final_types[0] = R_D_MODE;      final_types[1] = final_type;      final_types[2] = NULL;      *final_type = base_type;      break;    case e_lrsel:    case e_rrsel:      final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));      if (!final_types[0])	return NULL;      *final_types[0] = R_R_MODE;      final_types[1] = final_type;      final_types[2] = NULL;      *final_type = base_type;      break;    case e_nsel:      final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));      if (!final_types[0])	return NULL;      *final_types[0] = R_N1SEL;      final_types[1] = final_type;      final_types[2] = NULL;      *final_type = base_type;      break;    case e_nlsel:    case e_nlrsel:      final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));      if (!final_types[0])	return NULL;      *final_types[0] = R_N0SEL;      final_types[1] = (int *) bfd_alloc (abfd, sizeof (int));      if (!final_types[1])	return NULL;      if (field == e_nlsel)	*final_types[1] = R_N_MODE;      else	*final_types[1] = R_R_MODE;      final_types[2] = final_type;      final_types[3] = NULL;      *final_type = base_type;      break;    }  switch (base_type)    {    case R_HPPA:      /* The difference of two symbols needs *very* special handling.  */      if (sym_diff)	{	  final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));	  final_types[1] = (int *) bfd_alloc (abfd, sizeof (int));	  final_types[2] = (int *) bfd_alloc (abfd, sizeof (int));	  final_types[3] = (int *) bfd_alloc (abfd, sizeof (int));	  if (!final_types[0] || !final_types[1] || !final_types[2])	    return NULL;	  if (field == e_fsel)	    *final_types[0] = R_FSEL;	  else if (field == e_rsel)	    *final_types[0] = R_RSEL;	  else if (field == e_lsel)	    *final_types[0] = R_LSEL;	  *final_types[1] = R_COMP2;	  *final_types[2] = R_COMP2;	  *final_types[3] = R_COMP1;	  final_types[4] = final_type;	  if (format == 32)	    *final_types[4] = R_DATA_EXPR;	  else	    *final_types[4] = R_CODE_EXPR;	  final_types[5] = NULL;	  break;	}      /* PLABELs get their own relocation type.  */      else if (field == e_psel	       || field == e_lpsel	       || field == e_rpsel)	{	  /* A PLABEL relocation that has a size of 32 bits must	     be a R_DATA_PLABEL.  All others are R_CODE_PLABELs.  */	  if (format == 32)	    *final_type = R_DATA_PLABEL;	  else	    *final_type = R_CODE_PLABEL;	}      /* PIC stuff.  */      else if (field == e_tsel	       || field == e_ltsel	       || field == e_rtsel)	*final_type = R_DLT_REL;      /* A relocation in the data space is always a full 32bits.  */      else if (format == 32)	{	  *final_type = R_DATA_ONE_SYMBOL;	  /* If there's no SOM symbol type associated with this BFD	     symbol, then set the symbol type to ST_DATA.	     Only do this if the type is going to default later when	     we write the object file.	     This is done so that the linker never encounters an	     R_DATA_ONE_SYMBOL reloc involving an ST_CODE symbol.	     This allows the compiler to generate exception handling	     tables.	     Note that one day we may need to also emit BEGIN_BRTAB and	     END_BRTAB to prevent the linker from optimizing away insns	     in exception handling regions.  */	  if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN	      && (sym->flags & BSF_SECTION_SYM) == 0	      && (sym->flags & BSF_FUNCTION) == 0

⌨️ 快捷键说明

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