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

📄 write.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
/* write.c - emit .o file   Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,   1998, 1999, 2000, 2001   Free Software Foundation, Inc.   This file is part of GAS, the GNU Assembler.   GAS is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   GAS is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with GAS; see the file COPYING.  If not, write to the Free   Software Foundation, 59 Temple Place - Suite 330, Boston, MA   02111-1307, USA.  *//* This thing should be set up to do byteordering correctly.  But...  */#include "as.h"#include "subsegs.h"#include "obstack.h"#include "output-file.h"#include "dwarf2dbg.h"/* This looks like a good idea.  Let's try turning it on always, for now.  */#undef  BFD_FAST_SECTION_FILL#define BFD_FAST_SECTION_FILL#ifndef TC_ADJUST_RELOC_COUNT#define TC_ADJUST_RELOC_COUNT(FIXP,COUNT)#endif#ifndef TC_FORCE_RELOCATION#define TC_FORCE_RELOCATION(FIXP) 0#endif#ifndef TC_FORCE_RELOCATION_SECTION#define TC_FORCE_RELOCATION_SECTION(FIXP,SEG) TC_FORCE_RELOCATION(FIXP)#endif#ifndef TC_LINKRELAX_FIXUP#define TC_LINKRELAX_FIXUP(SEG) 1#endif#ifndef TC_FIX_ADJUSTABLE#define TC_FIX_ADJUSTABLE(fix) 1#endif#ifndef	MD_PCREL_FROM_SECTION#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from(FIXP)#endif#ifndef WORKING_DOT_WORDextern CONST int md_short_jump_size;extern CONST int md_long_jump_size;#endifint symbol_table_frozen;void print_fixup PARAMS ((fixS *));#ifdef BFD_ASSEMBLERstatic void renumber_sections PARAMS ((bfd *, asection *, PTR));/* We generally attach relocs to frag chains.  However, after we have   chained these all together into a segment, any relocs we add after   that must be attached to a segment.  This will include relocs added   in md_estimate_size_for_relax, for example.  */static int frags_chained = 0;#endif#ifndef BFD_ASSEMBLER#ifndef MANY_SEGMENTSstruct frag *text_frag_root;struct frag *data_frag_root;struct frag *bss_frag_root;struct frag *text_last_frag;	/* Last frag in segment.  */struct frag *data_last_frag;	/* Last frag in segment.  */static struct frag *bss_last_frag;	/* Last frag in segment.  */#endif#ifndef BFDstatic object_headers headers;#endiflong string_byte_count;char *next_object_file_charP;	/* Tracks object file bytes.  */#ifndef OBJ_VMSint magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE;#endif#endif /* BFD_ASSEMBLER  */static int n_fixups;#ifdef BFD_ASSEMBLERstatic fixS *fix_new_internal PARAMS ((fragS *, int where, int size,				       symbolS *add, symbolS *sub,				       offsetT offset, int pcrel,				       bfd_reloc_code_real_type r_type));#elsestatic fixS *fix_new_internal PARAMS ((fragS *, int where, int size,				       symbolS *add, symbolS *sub,				       offsetT offset, int pcrel,				       int r_type));#endif#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))static long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type));#endifstatic relax_addressT relax_align PARAMS ((relax_addressT addr, int align));#if defined (BFD_ASSEMBLER) || ! defined (BFD)static fragS *chain_frchains_together_1 PARAMS ((segT, struct frchain *));#endif#ifdef BFD_ASSEMBLERstatic void chain_frchains_together PARAMS ((bfd *, segT, PTR));static void cvt_frag_to_fill PARAMS ((segT, fragS *));static void relax_seg PARAMS ((bfd *, asection *, PTR));static void size_seg PARAMS ((bfd *, asection *, PTR));static void adjust_reloc_syms PARAMS ((bfd *, asection *, PTR));static void write_relocs PARAMS ((bfd *, asection *, PTR));static void write_contents PARAMS ((bfd *, asection *, PTR));static void set_symtab PARAMS ((void));#endif#if defined (BFD_ASSEMBLER) || (! defined (BFD) && ! defined (OBJ_AOUT))static void merge_data_into_text PARAMS ((void));#endif#if ! defined (BFD_ASSEMBLER) && ! defined (BFD)static void cvt_frag_to_fill PARAMS ((object_headers *, segT, fragS *));static void remove_subsegs PARAMS ((frchainS *, int, fragS **, fragS **));static void relax_and_size_all_segments PARAMS ((void));#endif#if defined (BFD_ASSEMBLER) && defined (OBJ_COFF) && defined (TE_GO32)static void set_segment_vma PARAMS ((bfd *, asection *, PTR));#endif/* Create a fixS in obstack 'notes'.  */static fixS *fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,		  r_type)     fragS *frag;		/* Which frag?  */     int where;			/* Where in that frag?  */     int size;			/* 1, 2, or 4 usually.  */     symbolS *add_symbol;	/* X_add_symbol.  */     symbolS *sub_symbol;	/* X_op_symbol.  */     offsetT offset;		/* X_add_number.  */     int pcrel;			/* TRUE if PC-relative relocation.  */#ifdef BFD_ASSEMBLER     bfd_reloc_code_real_type r_type; /* Relocation type.  */#else     int r_type;		/* Relocation type.  */#endif{  fixS *fixP;  n_fixups++;  fixP = (fixS *) obstack_alloc (&notes, sizeof (fixS));  fixP->fx_frag = frag;  fixP->fx_where = where;  fixP->fx_size = size;  /* We've made fx_size a narrow field; check that it's wide enough.  */  if (fixP->fx_size != size)    {      as_bad (_("field fx_size too small to hold %d"), size);      abort ();    }  fixP->fx_addsy = add_symbol;  fixP->fx_subsy = sub_symbol;  fixP->fx_offset = offset;  fixP->fx_pcrel = pcrel;  fixP->fx_plt = 0;#if defined(NEED_FX_R_TYPE) || defined (BFD_ASSEMBLER)  fixP->fx_r_type = r_type;#endif  fixP->fx_im_disp = 0;  fixP->fx_pcrel_adjust = 0;  fixP->fx_bit_fixP = 0;  fixP->fx_addnumber = 0;  fixP->fx_tcbit = 0;  fixP->fx_done = 0;  fixP->fx_no_overflow = 0;  fixP->fx_signed = 0;#ifdef USING_CGEN  fixP->fx_cgen.insn = NULL;  fixP->fx_cgen.opinfo = 0;#endif#ifdef TC_FIX_TYPE  TC_INIT_FIX_DATA (fixP);#endif  as_where (&fixP->fx_file, &fixP->fx_line);  /* Usually, we want relocs sorted numerically, but while     comparing to older versions of gas that have relocs     reverse sorted, it is convenient to have this compile     time option.  xoxorich.  */  {#ifdef BFD_ASSEMBLER    fixS **seg_fix_rootP = (frags_chained			    ? &seg_info (now_seg)->fix_root			    : &frchain_now->fix_root);    fixS **seg_fix_tailP = (frags_chained			    ? &seg_info (now_seg)->fix_tail			    : &frchain_now->fix_tail);#endif#ifdef REVERSE_SORT_RELOCS    fixP->fx_next = *seg_fix_rootP;    *seg_fix_rootP = fixP;#else /* REVERSE_SORT_RELOCS  */    fixP->fx_next = NULL;    if (*seg_fix_tailP)      (*seg_fix_tailP)->fx_next = fixP;    else      *seg_fix_rootP = fixP;    *seg_fix_tailP = fixP;#endif /* REVERSE_SORT_RELOCS  */  }  return fixP;}/* Create a fixup relative to a symbol (plus a constant).  */fixS *fix_new (frag, where, size, add_symbol, offset, pcrel, r_type)     fragS *frag;		/* Which frag?  */     int where;			/* Where in that frag?  */     int size;			/* 1, 2, or 4 usually.  */     symbolS *add_symbol;	/* X_add_symbol.  */     offsetT offset;		/* X_add_number.  */     int pcrel;			/* TRUE if PC-relative relocation.  */#ifdef BFD_ASSEMBLER     bfd_reloc_code_real_type r_type; /* Relocation type.  */#else     int r_type;		/* Relocation type.  */#endif{  return fix_new_internal (frag, where, size, add_symbol,			   (symbolS *) NULL, offset, pcrel, r_type);}/* Create a fixup for an expression.  Currently we only support fixups   for difference expressions.  That is itself more than most object   file formats support anyhow.  */fixS *fix_new_exp (frag, where, size, exp, pcrel, r_type)     fragS *frag;		/* Which frag?  */     int where;			/* Where in that frag?  */     int size;			/* 1, 2, or 4 usually.  */     expressionS *exp;		/* Expression.  */     int pcrel;			/* TRUE if PC-relative relocation.  */#ifdef BFD_ASSEMBLER     bfd_reloc_code_real_type r_type; /* Relocation type.  */#else     int r_type;		/* Relocation type.  */#endif{  symbolS *add = NULL;  symbolS *sub = NULL;  offsetT off = 0;  switch (exp->X_op)    {    case O_absent:      break;    case O_register:      as_bad (_("register value used as expression"));      break;    case O_add:      /* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if	 the difference expression cannot immediately be reduced.  */      {	symbolS *stmp = make_expr_symbol (exp);	exp->X_op = O_symbol;	exp->X_op_symbol = 0;	exp->X_add_symbol = stmp;	exp->X_add_number = 0;	return fix_new_exp (frag, where, size, exp, pcrel, r_type);      }    case O_symbol_rva:      add = exp->X_add_symbol;      off = exp->X_add_number;#if defined(BFD_ASSEMBLER)      r_type = BFD_RELOC_RVA;#else#if defined(TC_RVA_RELOC)      r_type = TC_RVA_RELOC;#else      as_fatal (_("rva not supported"));#endif#endif      break;    case O_uminus:      sub = exp->X_add_symbol;      off = exp->X_add_number;      break;    case O_subtract:      sub = exp->X_op_symbol;      /* Fall through.  */    case O_symbol:      add = exp->X_add_symbol;      /* Fall through.  */    case O_constant:      off = exp->X_add_number;      break;    default:      add = make_expr_symbol (exp);      break;    }  return fix_new_internal (frag, where, size, add, sub, off, pcrel, r_type);}/* Append a string onto another string, bumping the pointer along.  */voidappend (charPP, fromP, length)     char **charPP;     char *fromP;     unsigned long length;{  /* Don't trust memcpy() of 0 chars.  */  if (length == 0)    return;  memcpy (*charPP, fromP, length);  *charPP += length;}#ifndef BFD_ASSEMBLERint section_alignment[SEG_MAXIMUM_ORDINAL];#endif/* This routine records the largest alignment seen for each segment.   If the beginning of the segment is aligned on the worst-case   boundary, all of the other alignments within it will work.  At   least one object format really uses this info.  */voidrecord_alignment (seg, align)     /* Segment to which alignment pertains.  */     segT seg;     /* Alignment, as a power of 2 (e.g., 1 => 2-byte boundary, 2 => 4-byte	boundary, etc.)  */     int align;{  if (seg == absolute_section)    return;#ifdef BFD_ASSEMBLER  if ((unsigned int) align > bfd_get_section_alignment (stdoutput, seg))    bfd_set_section_alignment (stdoutput, seg, align);#else  if (align > section_alignment[(int) seg])    section_alignment[(int) seg] = align;#endif}intget_recorded_alignment (seg)     segT seg;{  if (seg == absolute_section)    return 0;#ifdef BFD_ASSEMBLER  return bfd_get_section_alignment (stdoutput, seg);#else  return section_alignment[(int) seg];#endif}#ifdef BFD_ASSEMBLER/* Reset the section indices after removing the gas created sections.  */static voidrenumber_sections (abfd, sec, countparg)     bfd *abfd ATTRIBUTE_UNUSED;     asection *sec;     PTR countparg;{  int *countp = (int *) countparg;  sec->index = *countp;  ++*countp;}#endif /* defined (BFD_ASSEMBLER)  */#if defined (BFD_ASSEMBLER) || ! defined (BFD)static fragS *chain_frchains_together_1 (section, frchp)     segT section;     struct frchain *frchp;{  fragS dummy, *prev_frag = &dummy;#ifdef BFD_ASSEMBLER  fixS fix_dummy, *prev_fix = &fix_dummy;#endif  for (; frchp && frchp->frch_seg == section; frchp = frchp->frch_next)    {      prev_frag->fr_next = frchp->frch_root;      prev_frag = frchp->frch_last;      assert (prev_frag->fr_type != 0);#ifdef BFD_ASSEMBLER      if (frchp->fix_root != (fixS *) NULL)	{	  if (seg_info (section)->fix_root == (fixS *) NULL)	    seg_info (section)->fix_root = frchp->fix_root;	  prev_fix->fx_next = frchp->fix_root;	  seg_info (section)->fix_tail = frchp->fix_tail;	  prev_fix = frchp->fix_tail;	}#endif    }  assert (prev_frag->fr_type != 0);  prev_frag->fr_next = 0;  return prev_frag;}#endif#ifdef BFD_ASSEMBLERstatic voidchain_frchains_together (abfd, section, xxx)     bfd *abfd ATTRIBUTE_UNUSED;     segT section;     PTR xxx ATTRIBUTE_UNUSED;{  segment_info_type *info;  /* BFD may have introduced its own sections without using     subseg_new, so it is possible that seg_info is NULL.  */  info = seg_info (section);  if (info != (segment_info_type *) NULL)    info->frchainP->frch_last      = chain_frchains_together_1 (section, info->frchainP);  /* Now that we've chained the frags together, we must add new fixups     to the segment, not to the frag chain.  */  frags_chained = 1;}#endif#if !defined (BFD) && !defined (BFD_ASSEMBLER)static void

⌨️ 快捷键说明

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