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

📄 write.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
	  if (symbol_equated_p (symp)	      && (! S_IS_DEFINED (symp) || S_IS_COMMON (symp)))	    {	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);	      continue;	    }	  /* So far, common symbols have been treated like undefined symbols.	     Put them in the common section now.  */	  if (S_IS_DEFINED (symp) == 0	      && S_GET_VALUE (symp) != 0)	    S_SET_SEGMENT (symp, bfd_com_section_ptr);#if 0	  printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",		  S_GET_NAME (symp), symp,		  S_GET_VALUE (symp),		  symbol_get_bfdsym (symp)->flags,		  segment_name (S_GET_SEGMENT (symp)));#endif#ifdef obj_frob_symbol	  obj_frob_symbol (symp, punt);#endif#ifdef tc_frob_symbol	  if (! punt || symbol_used_in_reloc_p (symp))	    tc_frob_symbol (symp, punt);#endif	  /* If we don't want to keep this symbol, splice it out of	     the chain now.  If EMIT_SECTION_SYMBOLS is 0, we never	     want section symbols.  Otherwise, we skip local symbols	     and symbols that the frob_symbol macros told us to punt,	     but we keep such symbols if they are used in relocs.  */	  if ((! EMIT_SECTION_SYMBOLS	       && symbol_section_p (symp))	      /* Note that S_IS_EXTERN and S_IS_LOCAL are not always		 opposites.  Sometimes the former checks flags and the		 latter examines the name...  */	      || (!S_IS_EXTERN (symp)		  && (S_IS_LOCAL (symp) || punt)		  && ! symbol_used_in_reloc_p (symp)))	    {	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);	      /* After symbol_remove, symbol_next(symp) still returns		 the one that came after it in the chain.  So we don't		 need to do any extra cleanup work here.  */	      continue;	    }	  /* Make sure we really got a value for the symbol.  */	  if (! symbol_resolved_p (symp))	    {	      as_bad (_("can't resolve value for symbol \"%s\""),		      S_GET_NAME (symp));	      symbol_mark_resolved (symp);	    }	  /* Set the value into the BFD symbol.  Up til now the value	     has only been kept in the gas symbolS struct.  */	  symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp);	}    }  PROGRESS (1);  /* Now do any format-specific adjustments to the symbol table, such     as adding file symbols.  */#ifdef tc_adjust_symtab  tc_adjust_symtab ();#endif#ifdef obj_adjust_symtab  obj_adjust_symtab ();#endif  /* Now that all the sizes are known, and contents correct, we can     start writing to the file.  */  set_symtab ();  /* If *_frob_file changes the symbol value at this point, it is     responsible for moving the changed value into symp->bsym->value     as well.  Hopefully all symbol value changing can be done in     *_frob_symbol.  */#ifdef tc_frob_file  tc_frob_file ();#endif#ifdef obj_frob_file  obj_frob_file ();#endif  bfd_map_over_sections (stdoutput, write_relocs, (char *) 0);#ifdef tc_frob_file_after_relocs  tc_frob_file_after_relocs ();#endif#ifdef obj_frob_file_after_relocs  obj_frob_file_after_relocs ();#endif  bfd_map_over_sections (stdoutput, write_contents, (char *) 0);#endif /* BFD_ASSEMBLER  */}#endif /* ! BFD  */#ifdef TC_GENERIC_RELAX_TABLE/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE.  */longrelax_frag (segment, fragP, stretch)     segT segment;     fragS *fragP;     long stretch;{  const relax_typeS *this_type;  const relax_typeS *start_type;  relax_substateT next_state;  relax_substateT this_state;  long growth;  offsetT aim;  addressT target;  addressT address;  symbolS *symbolP;  const relax_typeS *table;  target = fragP->fr_offset;  address = fragP->fr_address;  table = TC_GENERIC_RELAX_TABLE;  this_state = fragP->fr_subtype;  start_type = this_type = table + this_state;  symbolP = fragP->fr_symbol;  if (symbolP)    {      fragS *sym_frag;      sym_frag = symbol_get_frag (symbolP);#ifndef DIFF_EXPR_OK#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)      know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)	    || (S_GET_SEGMENT (symbolP) == SEG_DATA)	    || (S_GET_SEGMENT (symbolP) == SEG_BSS)	    || (S_GET_SEGMENT (symbolP) == SEG_TEXT));#endif      know (sym_frag != NULL);#endif      know (!(S_GET_SEGMENT (symbolP) == absolute_section)	    || sym_frag == &zero_address_frag);      target += S_GET_VALUE (symbolP) + sym_frag->fr_address;      /* If frag has yet to be reached on this pass,	 assume it will move by STRETCH just as we did.	 If this is not so, it will be because some frag	 between grows, and that will force another pass.  */      if (stretch != 0	  && sym_frag->relax_marker != fragP->relax_marker	  && S_GET_SEGMENT (symbolP) == segment)	{	  target += stretch;	}    }  aim = target - address - fragP->fr_fix;#ifdef TC_PCREL_ADJUST  /* Currently only the ns32k family needs this.  */  aim += TC_PCREL_ADJUST (fragP);/* #else */  /* This machine doesn't want to use pcrel_adjust.     In that case, pcrel_adjust should be zero.  */#if 0  assert (fragP->fr_targ.ns32k.pcrel_adjust == 0);#endif#endif#ifdef md_prepare_relax_scan /* formerly called M68K_AIM_KLUDGE  */  md_prepare_relax_scan (fragP, address, aim, this_state, this_type);#endif  if (aim < 0)    {      /* Look backwards.  */      for (next_state = this_type->rlx_more; next_state;)	if (aim >= this_type->rlx_backward)	  next_state = 0;	else	  {	    /* Grow to next state.  */	    this_state = next_state;	    this_type = table + this_state;	    next_state = this_type->rlx_more;	  }    }  else    {      /* Look forwards.  */      for (next_state = this_type->rlx_more; next_state;)	if (aim <= this_type->rlx_forward)	  next_state = 0;	else	  {	    /* Grow to next state.  */	    this_state = next_state;	    this_type = table + this_state;	    next_state = this_type->rlx_more;	  }    }  growth = this_type->rlx_length - start_type->rlx_length;  if (growth != 0)    fragP->fr_subtype = this_state;  return growth;}#endif /* defined (TC_GENERIC_RELAX_TABLE)  *//* Relax_align. Advance location counter to next address that has 'alignment'   lowest order bits all 0s, return size of adjustment made.  */static relax_addressTrelax_align (address, alignment)     register relax_addressT address;	/* Address now.  */     register int alignment;	/* Alignment (binary).  */{  relax_addressT mask;  relax_addressT new_address;  mask = ~((~0) << alignment);  new_address = (address + mask) & (~mask);#ifdef LINKER_RELAXING_SHRINKS_ONLY  if (linkrelax)    /* We must provide lots of padding, so the linker can discard it       when needed.  The linker will not add extra space, ever.  */    new_address += (1 << alignment);#endif  return (new_address - address);}/* Now we have a segment, not a crowd of sub-segments, we can make   fr_address values.   Relax the frags.   After this, all frags in this segment have addresses that are correct   within the segment. Since segments live in different file addresses,   these frag addresses may not be the same as final object-file   addresses.  */voidrelax_segment (segment_frag_root, segment)     struct frag *segment_frag_root;     segT segment;{  register struct frag *fragP;  register relax_addressT address;#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)  know (segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS);#endif  /* In case md_estimate_size_before_relax() wants to make fixSs.  */  subseg_change (segment, 0);  /* For each frag in segment: count and store  (a 1st guess of)     fr_address.  */  address = 0;  for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)    {      fragP->relax_marker = 0;      fragP->fr_address = address;      address += fragP->fr_fix;      switch (fragP->fr_type)	{	case rs_fill:	  address += fragP->fr_offset * fragP->fr_var;	  break;	case rs_align:	case rs_align_code:	case rs_align_test:	  {	    addressT offset = relax_align (address, (int) fragP->fr_offset);	    if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype)	      offset = 0;	    if (offset % fragP->fr_var != 0)	      {		as_bad (_("alignment padding (%lu bytes) not a multiple of %ld"),			(unsigned long) offset, (long) fragP->fr_var);		offset -= (offset % fragP->fr_var);	      }	    address += offset;	  }	  break;	case rs_org:	case rs_space:	  /* Assume .org is nugatory. It will grow with 1st relax.  */	  break;	case rs_machine_dependent:	  address += md_estimate_size_before_relax (fragP, segment);	  break;#ifndef WORKING_DOT_WORD	  /* Broken words don't concern us yet.  */	case rs_broken_word:	  break;#endif	case rs_leb128:	  /* Initial guess is always 1; doing otherwise can result in	     stable solutions that are larger than the minimum.  */	  address += fragP->fr_offset = 1;	  break;	case rs_cfa:	  address += eh_frame_estimate_size_before_relax (fragP);	  break;	case rs_dwarf2dbg:	  address += dwarf2dbg_estimate_size_before_relax (fragP);	  break;	default:	  BAD_CASE (fragP->fr_type);	  break;	}    }  /* Do relax().  */  {    long stretch;	/* May be any size, 0 or negative.  */    /* Cumulative number of addresses we have relaxed this pass.       We may have relaxed more than one address.  */    int stretched;	/* Have we stretched on this pass?  */    /* This is 'cuz stretch may be zero, when, in fact some piece of code       grew, and another shrank.  If a branch instruction doesn't fit anymore,       we could be scrod.  */    do      {	stretch = 0;	stretched = 0;	for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)	  {	    long growth = 0;	    addressT was_address;	    offsetT offset;	    symbolS *symbolP;	    fragP->relax_marker ^= 1;	    was_address = fragP->fr_address;	    address = fragP->fr_address += stretch;	    symbolP = fragP->fr_symbol;	    offset = fragP->fr_offset;	    switch (fragP->fr_type)	      {	      case rs_fill:	/* .fill never relaxes.  */		growth = 0;		break;#ifndef WORKING_DOT_WORD		/* JF:  This is RMS's idea.  I do *NOT* want to be blamed		   for it I do not want to write it.  I do not want to have		   anything to do with it.  This is not the proper way to		   implement this misfeature.  */	      case rs_broken_word:		{		  struct broken_word *lie;		  struct broken_word *untruth;		  /* Yes this is ugly (storing the broken_word pointer		     in the symbol slot).  Still, this whole chunk of		     code is ugly, and I don't feel like doing anything		     about it.  Think of it as stubbornness in action.  */		  growth = 0;		  for (lie = (struct broken_word *) (fragP->fr_symbol);		       lie && lie->dispfrag == fragP;		       lie = lie->next_broken_word)		    {		      if (lie->added)			continue;		      offset = (symbol_get_frag (lie->add)->fr_address				+ S_GET_VALUE (lie->add)				+ lie->addnum				- (symbol_get_frag (lie->sub)->fr_address				   + S_GET_VALUE (lie->sub)));		      if (offset <= -32768 || offset >= 32767)			{			  if (flag_warn_displacement)			    {			      char buf[50];			      sprint_value (buf, (addressT) lie->addnum);			      as_warn (_(".word %s-%s+%s didn't fit"),				       S_GET_NAME (lie->add),				       S_GET_NAME (lie->sub),				       buf);			    }			  lie->added = 1;			  if (fragP->fr_subtype == 0)			    {			      fragP->fr_subtype++;			      growth += md_short_jump_size;			    }			  for (untruth = lie->next_broken_word;			       untruth && untruth->dispfrag == lie->dispfrag;			       untruth = untruth->next_broken_word)			    if ((symbol_get_frag (untruth->add)				 == symbol_get_frag (lie->add))				&& (S_GET_VALUE (untruth->add)				    == S_GET_VALUE (lie->add)))			      {				untruth->added = 2;				untruth->use_jump = lie;			      }			  growth += md_long_jump_size;			}		    }		  break;		}		/* case rs_broken_word  */#endif	      case rs_align:	      case rs_align_code:	      case rs_align_test:		{		  addressT oldoff, newoff;		  oldoff = relax_align (was_address + fragP->fr_fix,					(int) offset);		  newoff = relax_align (address + fragP->fr_fix,					(int) offset);		  if (fragP->fr_subtype != 0)		    {		      if (oldoff > fragP->fr_subtype)			oldoff = 0;		      if (newoff > fragP->fr_subtype)			newoff = 0;		    }		  growth = newoff - oldoff;		}		break;	      case rs_org:		{		  addressT target = offset;		  addressT after;		  if (symbolP)		    {#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)		      know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)			    || (S_GET_SEGMENT (symbolP) == SEG_DATA)			    || (S_GET_SEGMENT (symbolP) == SEG_TEXT)			    || S_GET_SEGMENT (symbolP) == SEG_BSS);		      know (symbolP->sy_frag);		      know (!(S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)			    || (symbolP->sy_frag == &zero_address_frag));#endif		      target += (S_GET_VALUE (symbolP)				 + symbol_get_frag (symbolP)->fr_address);		    }		/* if we have a symbol  */		  know (fragP->fr_next);		  after = fragP->fr_next->fr_address;		  growth = target - after;		  if (growth < 0)		    {		      /* Growth may be negative, but variable part of frag			 cannot ha

⌨️ 快捷键说明

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