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

📄 write.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
  for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)    {      arelent *reloc;      bfd_reloc_status_type s;      symbolS *sym;      if (fixp->fx_done)	{	  n--;	  continue;	}      /* If this is an undefined symbol which was equated to another         symbol, then use generate the reloc against the latter symbol         rather than the former.  */      sym = fixp->fx_addsy;      while (symbol_equated_p (sym)	     && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))	{	  symbolS *n;	  /* We must avoid looping, as that can occur with a badly	     written program.  */	  n = symbol_get_value_expression (sym)->X_add_symbol;	  if (n == sym)	    break;	  fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;	  sym = n;	}      fixp->fx_addsy = sym;      reloc = tc_gen_reloc (sec, fixp);      if (!reloc)	{	  n--;	  continue;	}#if 0      /* This test is triggered inappropriately for the SH.  */      if (fixp->fx_where + fixp->fx_size	  > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)	abort ();#endif      s = bfd_install_relocation (stdoutput, reloc,				  fixp->fx_frag->fr_literal,				  fixp->fx_frag->fr_address,				  sec, &err);      switch (s)	{	case bfd_reloc_ok:	  break;	case bfd_reloc_overflow:	  as_bad_where (fixp->fx_file, fixp->fx_line, _("relocation overflow"));	  break;	case bfd_reloc_outofrange:	  as_bad_where (fixp->fx_file, fixp->fx_line, _("relocation out of range"));	  break;	default:	  as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),		    fixp->fx_file, fixp->fx_line, s);	}      relocs[i++] = reloc;    }#else  n = n * MAX_RELOC_EXPANSION;  /* Set up reloc information as well.  */  relocs = (arelent **) xmalloc (n * sizeof (arelent *));  i = 0;  for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)    {      arelent **reloc;      char *data;      bfd_reloc_status_type s;      symbolS *sym;      int j;      if (fixp->fx_done)	{	  n--;	  continue;	}      /* If this is an undefined symbol which was equated to another         symbol, then generate the reloc against the latter symbol         rather than the former.  */      sym = fixp->fx_addsy;      while (symbol_equated_p (sym)	     && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))	sym = symbol_get_value_expression (sym)->X_add_symbol;      fixp->fx_addsy = sym;      reloc = tc_gen_reloc (sec, fixp);      for (j = 0; reloc[j]; j++)	{	  relocs[i++] = reloc[j];	  assert (i <= n);	}      data = fixp->fx_frag->fr_literal + fixp->fx_where;      if (fixp->fx_where + fixp->fx_size	  > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)	as_bad_where (fixp->fx_file, fixp->fx_line,		      _("internal error: fixup not contained within frag"));      for (j = 0; reloc[j]; j++)	{	  s = bfd_install_relocation (stdoutput, reloc[j],				      fixp->fx_frag->fr_literal,				      fixp->fx_frag->fr_address,				      sec, &err);	  switch (s)	    {	    case bfd_reloc_ok:	      break;	    case bfd_reloc_overflow:	      as_bad_where (fixp->fx_file, fixp->fx_line,			    _("relocation overflow"));	      break;	    default:	      as_fatal (_("%s:%u: bad return from bfd_install_relocation"),			fixp->fx_file, fixp->fx_line);	    }	}    }  n = i;#endif#ifdef DEBUG4  {    int i, j, nsyms;    asymbol **sympp;    sympp = bfd_get_outsymbols (stdoutput);    nsyms = bfd_get_symcount (stdoutput);    for (i = 0; i < n; i++)      if (((*relocs[i]->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)	{	  for (j = 0; j < nsyms; j++)	    if (sympp[j] == *relocs[i]->sym_ptr_ptr)	      break;	  if (j == nsyms)	    abort ();	}  }#endif  if (n)    bfd_set_reloc (stdoutput, sec, relocs, n);  else    bfd_set_section_flags (abfd, sec,			   (bfd_get_section_flags (abfd, sec)			    & (flagword) ~SEC_RELOC));#ifdef SET_SECTION_RELOCS  SET_SECTION_RELOCS (sec, relocs, n);#endif#ifdef DEBUG3  {    int i;    arelent *r;    asymbol *s;    fprintf (stderr, "relocs for sec %s\n", sec->name);    for (i = 0; i < n; i++)      {	r = relocs[i];	s = *r->sym_ptr_ptr;	fprintf (stderr, "  reloc %2d @%08x off %4x : sym %-10s addend %x\n",		 i, r, r->address, s->name, r->addend);      }  }#endif}static voidwrite_contents (abfd, sec, xxx)     bfd *abfd ATTRIBUTE_UNUSED;     asection *sec;     PTR xxx ATTRIBUTE_UNUSED;{  segment_info_type *seginfo = seg_info (sec);  unsigned long offset = 0;  fragS *f;  /* Write out the frags.  */  if (seginfo == NULL      || !(bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS))    return;  for (f = seginfo->frchainP->frch_root;       f;       f = f->fr_next)    {      int x;      unsigned long fill_size;      char *fill_literal;      long count;      assert (f->fr_type == rs_fill);      if (f->fr_fix)	{	  x = bfd_set_section_contents (stdoutput, sec,					f->fr_literal, (file_ptr) offset,					(bfd_size_type) f->fr_fix);	  if (x == false)	    {	      bfd_perror (stdoutput->filename);	      as_perror (_("FATAL: Can't write %s"), stdoutput->filename);	      exit (EXIT_FAILURE);	    }	  offset += f->fr_fix;	}      fill_literal = f->fr_literal + f->fr_fix;      fill_size = f->fr_var;      count = f->fr_offset;      assert (count >= 0);      if (fill_size && count)	{	  char buf[256];	  if (fill_size > sizeof (buf))	    {	      /* Do it the old way. Can this ever happen?  */	      while (count--)		{		  x = bfd_set_section_contents (stdoutput, sec,						fill_literal,						(file_ptr) offset,						(bfd_size_type) fill_size);		  if (x == false)		    {		      bfd_perror (stdoutput->filename);		      as_perror (_("FATAL: Can't write %s"),				 stdoutput->filename);		      exit (EXIT_FAILURE);		    }		  offset += fill_size;		}	    }	  else	    {	      /* Build a buffer full of fill objects and output it as		 often as necessary. This saves on the overhead of		 potentially lots of bfd_set_section_contents calls.  */	      int n_per_buf, i;	      if (fill_size == 1)		{		  n_per_buf = sizeof (buf);		  memset (buf, *fill_literal, n_per_buf);		}	      else		{		  char *bufp;		  n_per_buf = sizeof (buf) / fill_size;		  for (i = n_per_buf, bufp = buf; i; i--, bufp += fill_size)		    memcpy (bufp, fill_literal, fill_size);		}	      for (; count > 0; count -= n_per_buf)		{		  n_per_buf = n_per_buf > count ? count : n_per_buf;		  x = bfd_set_section_contents		    (stdoutput, sec, buf, (file_ptr) offset,		     (bfd_size_type) n_per_buf * fill_size);		  if (x != true)		    as_fatal (_("Cannot write to output file."));		  offset += n_per_buf * fill_size;		}	    }	}    }}#endif#if defined(BFD_ASSEMBLER) || (!defined (BFD) && !defined(OBJ_AOUT))static voidmerge_data_into_text (){#if defined(BFD_ASSEMBLER) || defined(MANY_SEGMENTS)  seg_info (text_section)->frchainP->frch_last->fr_next =    seg_info (data_section)->frchainP->frch_root;  seg_info (text_section)->frchainP->frch_last =    seg_info (data_section)->frchainP->frch_last;  seg_info (data_section)->frchainP = 0;#else  fixS *tmp;  text_last_frag->fr_next = data_frag_root;  text_last_frag = data_last_frag;  data_last_frag = NULL;  data_frag_root = NULL;  if (text_fix_root)    {      for (tmp = text_fix_root; tmp->fx_next; tmp = tmp->fx_next);;      tmp->fx_next = data_fix_root;      text_fix_tail = data_fix_tail;    }  else    text_fix_root = data_fix_root;  data_fix_root = NULL;#endif}#endif /* BFD_ASSEMBLER || (! BFD && ! OBJ_AOUT)  */#if !defined (BFD_ASSEMBLER) && !defined (BFD)static voidrelax_and_size_all_segments (){  fragS *fragP;  relax_segment (text_frag_root, SEG_TEXT);  relax_segment (data_frag_root, SEG_DATA);  relax_segment (bss_frag_root, SEG_BSS);  /* Now the addresses of frags are correct within the segment.  */  know (text_last_frag->fr_type == rs_fill && text_last_frag->fr_offset == 0);  H_SET_TEXT_SIZE (&headers, text_last_frag->fr_address);  text_last_frag->fr_address = H_GET_TEXT_SIZE (&headers);  /* Join the 2 segments into 1 huge segment.     To do this, re-compute every rn_address in the SEG_DATA frags.     Then join the data frags after the text frags.     Determine a_data [length of data segment].  */  if (data_frag_root)    {      register relax_addressT slide;      know ((text_last_frag->fr_type == rs_fill)	    && (text_last_frag->fr_offset == 0));      H_SET_DATA_SIZE (&headers, data_last_frag->fr_address);      data_last_frag->fr_address = H_GET_DATA_SIZE (&headers);      slide = H_GET_TEXT_SIZE (&headers);	/* & in file of the data segment.  */#ifdef OBJ_BOUT#define RoundUp(N,S) (((N)+(S)-1)&-(S))      /* For b.out: If the data section has a strict alignment	 requirement, its load address in the .o file will be	 rounded up from the size of the text section.  These	 two values are *not* the same!  Similarly for the bss	 section....  */      slide = RoundUp (slide, 1 << section_alignment[SEG_DATA]);#endif      for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)	fragP->fr_address += slide;      know (text_last_frag != 0);      text_last_frag->fr_next = data_frag_root;    }  else    {      H_SET_DATA_SIZE (&headers, 0);    }#ifdef OBJ_BOUT  /* See above comments on b.out data section address.  */  {    long bss_vma;    if (data_last_frag == 0)      bss_vma = H_GET_TEXT_SIZE (&headers);    else      bss_vma = data_last_frag->fr_address;    bss_vma = RoundUp (bss_vma, 1 << section_alignment[SEG_BSS]);    bss_address_frag.fr_address = bss_vma;  }#else /* ! OBJ_BOUT  */  bss_address_frag.fr_address = (H_GET_TEXT_SIZE (&headers) +				 H_GET_DATA_SIZE (&headers));#endif /* ! OBJ_BOUT  */  /* Slide all the frags.  */  if (bss_frag_root)    {      relax_addressT slide = bss_address_frag.fr_address;      for (fragP = bss_frag_root; fragP; fragP = fragP->fr_next)	fragP->fr_address += slide;    }  if (bss_last_frag)    H_SET_BSS_SIZE (&headers,		    bss_last_frag->fr_address - bss_frag_root->fr_address);  else    H_SET_BSS_SIZE (&headers, 0);}#endif /* ! BFD_ASSEMBLER && ! BFD  */#if defined (BFD_ASSEMBLER) || !defined (BFD)#ifdef BFD_ASSEMBLERstatic voidset_symtab (){  int nsyms;  asymbol **asympp;  symbolS *symp;  boolean result;  extern PTR bfd_alloc PARAMS ((bfd *, size_t));  /* Count symbols.  We can't rely on a count made by the loop in     write_object_file, because *_frob_file may add a new symbol or     two.  */  nsyms = 0;  for (symp = symbol_rootP; symp; symp = symbol_next (symp))    nsyms++;  if (nsyms)    {      int i;      asympp = (asymbol **) bfd_alloc (stdoutput,				       nsyms * sizeof (asymbol *));      symp = symbol_rootP;      for (i = 0; i < nsyms; i++, symp = symbol_next (symp))	{	  asympp[i] = symbol_get_bfdsym (symp);	  symbol_mark_written (symp);	}    }  else    asympp = 0;  result = bfd_set_symtab (stdoutput, asympp, nsyms);  assert (result == true);  symbol_table_frozen = 1;}#endif#if defined (BFD_ASSEMBLER) && defined (OBJ_COFF) && defined (TE_GO32)static voidset_segment_vma (abfd, sec, xxx)     bfd *abfd;     asection *sec;     PTR xxx ATTRIBUTE_UNUSED;{  static bfd_vma addr = 0;  bfd_set_section_vma (abfd, sec, addr);  addr += bfd_section_size (abfd, sec);}#endif /* BFD_ASSEMBLER && OBJ_COFF && !TE_PE  *//* Finish the subsegments.  After every sub-segment, we fake an   ".align ...".  This conforms to BSD4.2 brane-damage.  We then fake   ".fill 0" because that is the kind of frag that requires least   thought.  ".align" frags like to have a following frag since that   makes calculating their intended length trivial.  */#ifndef SUB_SEGMENT_ALIGN#ifdef BFD_ASSEMBLER#define SUB_SEGMENT_ALIGN(SEG) (0)#else#define SUB_SEGMENT_ALIGN(SEG) (2)#endif#endifvoidsubsegs_finish (){  struct frchain *frchainP;  for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)    {      int alignment;      subseg_set (frchainP->frch_seg, frchainP->frch_subseg);      /* This now gets called even if we had errors.  In that case,         any alignment is meaningless, and, moreover, will look weird         if we are generating a listing.  */      alignment = had_errors () ? 0 : SUB_SEGMENT_ALIGN (now_seg);      /* The last subsegment gets an aligment corresponding to the	 alignment of the section.  This allows proper nop-filling	 at the end of code-bearing sections.  */      if (!frchainP->frch_next || frchainP->frch_next->frch_seg != now_seg)	alignment = get_recorded_alignment (now_seg);

⌨️ 快捷键说明

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