obj-coff.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,530 行 · 第 1/5 页

C
2,530
字号
			  (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);			  ext_ptr++;			}#endif		    }		  fix_ptr = fix_ptr->fx_next;		}#ifdef TE_AUX	      /* Sort the reloc table */	      qsort ((PTR) external_reloc_vec, nrelocs,		     sizeof (struct external_reloc), compare_external_relocs);#endif	      /* Write out the reloc table */	      bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size,			 abfd);	      free (external_reloc_vec);	      /* Fill in section header info.  */	      segment_info[idx].scnhdr.s_relptr = *file_cursor;	      *file_cursor += external_reloc_size;	      segment_info[idx].scnhdr.s_nreloc = nrelocs;	    }	  else	    {	      /* No relocs */	      segment_info[idx].scnhdr.s_relptr = 0;	    }	}    }  /* Set relocation_size field in file headers */  H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0);}/* run through a frag chain and write out the data to go with it, fill   in the scnhdrs with the info on the file postions*/static voidfill_section (abfd, h, file_cursor)     bfd * abfd;     object_headers *h ATTRIBUTE_UNUSED;     unsigned long *file_cursor;{  unsigned int i;  unsigned int paddr = 0;  for (i = SEG_E0; i < SEG_UNKNOWN; i++)    {      unsigned int offset = 0;      struct internal_scnhdr *s = &(segment_info[i].scnhdr);      PROGRESS (1);      if (s->s_name[0])	{	  fragS *frag = segment_info[i].frchainP->frch_root;	  char *buffer = NULL;	  if (s->s_size == 0)	    s->s_scnptr = 0;	  else	    {	      buffer = xmalloc (s->s_size);	      s->s_scnptr = *file_cursor;	    }	  know (s->s_paddr == paddr);	  if (strcmp (s->s_name, ".text") == 0)	    s->s_flags |= STYP_TEXT;	  else if (strcmp (s->s_name, ".data") == 0)	    s->s_flags |= STYP_DATA;	  else if (strcmp (s->s_name, ".bss") == 0)	    {	      s->s_scnptr = 0;	      s->s_flags |= STYP_BSS;	      /* @@ Should make the i386 and a29k coff targets define		 COFF_NOLOAD_PROBLEM, and have only one test here.  */#ifndef TC_I386#ifndef TC_A29K#ifndef COFF_NOLOAD_PROBLEM	      /* Apparently the SVR3 linker (and exec syscall) and UDI		 mondfe progrem are confused by noload sections.  */	      s->s_flags |= STYP_NOLOAD;#endif#endif#endif	    }	  else if (strcmp (s->s_name, ".lit") == 0)	    s->s_flags = STYP_LIT | STYP_TEXT;	  else if (strcmp (s->s_name, ".init") == 0)	    s->s_flags |= STYP_TEXT;	  else if (strcmp (s->s_name, ".fini") == 0)	    s->s_flags |= STYP_TEXT;	  else if (strncmp (s->s_name, ".comment", 8) == 0)	    s->s_flags |= STYP_INFO;	  while (frag)	    {	      unsigned int fill_size;	      switch (frag->fr_type)		{		case rs_machine_dependent:		  if (frag->fr_fix)		    {		      memcpy (buffer + frag->fr_address,			      frag->fr_literal,			      (unsigned int) frag->fr_fix);		      offset += frag->fr_fix;		    }		  break;		case rs_space:		  assert (frag->fr_symbol == 0);		case rs_fill:		case rs_align:		case rs_align_code:		case rs_align_test:		case rs_org:		  if (frag->fr_fix)		    {		      memcpy (buffer + frag->fr_address,			      frag->fr_literal,			      (unsigned int) frag->fr_fix);		      offset += frag->fr_fix;		    }		  fill_size = frag->fr_var;		  if (fill_size && frag->fr_offset > 0)		    {		      unsigned int count;		      unsigned int off = frag->fr_fix;		      for (count = frag->fr_offset; count; count--)			{			  if (fill_size + frag->fr_address + off <= s->s_size)			    {			      memcpy (buffer + frag->fr_address + off,				      frag->fr_literal + frag->fr_fix,				      fill_size);			      off += fill_size;			      offset += fill_size;			    }			}		    }		  break;		case rs_broken_word:		  break;		default:		  abort ();		}	      frag = frag->fr_next;	    }	  if (s->s_size != 0)	    {	      if (s->s_scnptr != 0)		{		  bfd_write (buffer, s->s_size, 1, abfd);		  *file_cursor += s->s_size;		}	      free (buffer);	    }	  paddr += s->s_size;	}    }}/* Coff file generation & utilities */static voidcoff_header_append (abfd, h)     bfd * abfd;     object_headers * h;{  unsigned int i;  char buffer[1000];  char buffero[1000];#ifdef COFF_LONG_SECTION_NAMES  unsigned long string_size = 4;#endif  bfd_seek (abfd, 0, 0);#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER  H_SET_MAGIC_NUMBER (h, COFF_MAGIC);  H_SET_VERSION_STAMP (h, 0);  H_SET_ENTRY_POINT (h, 0);  H_SET_TEXT_START (h, segment_info[SEG_E0].frchainP->frch_root->fr_address);  H_SET_DATA_START (h, segment_info[SEG_E1].frchainP->frch_root->fr_address);  H_SET_SIZEOF_OPTIONAL_HEADER (h, bfd_coff_swap_aouthdr_out(abfd, &h->aouthdr,							     buffero));#else /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */  H_SET_SIZEOF_OPTIONAL_HEADER (h, 0);#endif /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */  i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);  bfd_write (buffer, i, 1, abfd);  bfd_write (buffero, H_GET_SIZEOF_OPTIONAL_HEADER (h), 1, abfd);  for (i = SEG_E0; i < SEG_LAST; i++)    {      if (segment_info[i].scnhdr.s_name[0])	{	  unsigned int size;#ifdef COFF_LONG_SECTION_NAMES	  /* Support long section names as found in PE.  This code             must coordinate with that in write_object_file and             w_strings.  */	  if (strlen (segment_info[i].name) > SCNNMLEN)	    {	      memset (segment_info[i].scnhdr.s_name, 0, SCNNMLEN);	      sprintf (segment_info[i].scnhdr.s_name, "/%lu", string_size);	      string_size += strlen (segment_info[i].name) + 1;	    }#endif	  size = bfd_coff_swap_scnhdr_out (abfd,					   &(segment_info[i].scnhdr),					   buffer);	  if (size == 0)	    as_bad (_("bfd_coff_swap_scnhdr_out failed"));	  bfd_write (buffer, size, 1, abfd);	}    }}char *symbol_to_chars (abfd, where, symbolP)     bfd * abfd;     char *where;     symbolS * symbolP;{  unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;  unsigned int i;  valueT val;  /* Turn any symbols with register attributes into abs symbols */  if (S_GET_SEGMENT (symbolP) == reg_section)    {      S_SET_SEGMENT (symbolP, absolute_section);    }  /* At the same time, relocate all symbols to their output value */#ifndef TE_PE  val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr	 + S_GET_VALUE (symbolP));#else  val = S_GET_VALUE (symbolP);#endif  S_SET_VALUE (symbolP, val);  symbolP->sy_symbol.ost_entry.n_value = val;  where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,				  where);  for (i = 0; i < numaux; i++)    {      where += bfd_coff_swap_aux_out (abfd,				      &symbolP->sy_symbol.ost_auxent[i],				      S_GET_DATA_TYPE (symbolP),				      S_GET_STORAGE_CLASS (symbolP),				      i, numaux, where);    }  return where;}voidcoff_obj_symbol_new_hook (symbolP)     symbolS *symbolP;{  char underscore = 0;		/* Symbol has leading _ */  /* Effective symbol */  /* Store the pointer in the offset.  */  S_SET_ZEROES (symbolP, 0L);  S_SET_DATA_TYPE (symbolP, T_NULL);  S_SET_STORAGE_CLASS (symbolP, 0);  S_SET_NUMBER_AUXILIARY (symbolP, 0);  /* Additional information */  symbolP->sy_symbol.ost_flags = 0;  /* Auxiliary entries */  memset ((char *) &symbolP->sy_symbol.ost_auxent[0], 0, AUXESZ);  if (S_IS_STRING (symbolP))    SF_SET_STRING (symbolP);  if (!underscore && S_IS_LOCAL (symbolP))    SF_SET_LOCAL (symbolP);}/* * Handle .ln directives. */static voidobj_coff_ln (appline)     int appline;{  int l;  if (! appline && def_symbol_in_progress != NULL)    {      as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));      demand_empty_rest_of_line ();      return;    }				/* wrong context */  l = get_absolute_expression ();  c_line_new (0, frag_now_fix (), l, frag_now);  if (appline)    new_logical_line ((char *) NULL, l - 1);#ifndef NO_LISTING  {    extern int listing;    if (listing)      {	if (! appline)	  l += line_base - 1;	listing_source_line ((unsigned int) l);      }  }#endif  demand_empty_rest_of_line ();}/* *			def() * * Handle .def directives. * * One might ask : why can't we symbol_new if the symbol does not * already exist and fill it with debug information.  Because of * the C_EFCN special symbol. It would clobber the value of the * function symbol before we have a chance to notice that it is * a C_EFCN. And a second reason is that the code is more clear this * way. (at least I think it is :-). * */#define SKIP_SEMI_COLON()	while (*input_line_pointer++ != ';')#define SKIP_WHITESPACES()	while (*input_line_pointer == ' ' || \				      *input_line_pointer == '\t') \                                         input_line_pointer++;static voidobj_coff_def (what)     int what ATTRIBUTE_UNUSED;{  char name_end;		/* Char after the end of name */  char *symbol_name;		/* Name of the debug symbol */  char *symbol_name_copy;	/* Temporary copy of the name */  unsigned int symbol_name_length;  if (def_symbol_in_progress != NULL)    {      as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));      demand_empty_rest_of_line ();      return;    }				/* if not inside .def/.endef */  SKIP_WHITESPACES ();  def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));  memset (def_symbol_in_progress, 0, sizeof (*def_symbol_in_progress));  symbol_name = input_line_pointer;  name_end = get_symbol_end ();  symbol_name_length = strlen (symbol_name);  symbol_name_copy = xmalloc (symbol_name_length + 1);  strcpy (symbol_name_copy, symbol_name);#ifdef tc_canonicalize_symbol_name  symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);#endif  /* Initialize the new symbol */#ifdef STRIP_UNDERSCORE  S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'				       ? symbol_name_copy + 1				       : symbol_name_copy));#else /* STRIP_UNDERSCORE */  S_SET_NAME (def_symbol_in_progress, symbol_name_copy);#endif /* STRIP_UNDERSCORE */  /* free(symbol_name_copy); */  def_symbol_in_progress->sy_name_offset = (unsigned long) ~0;  def_symbol_in_progress->sy_number = ~0;  def_symbol_in_progress->sy_frag = &zero_address_frag;  S_SET_VALUE (def_symbol_in_progress, 0);  if (S_IS_STRING (def_symbol_in_progress))    SF_SET_STRING (def_symbol_in_progress);  *input_line_pointer = name_end;  demand_empty_rest_of_line ();}unsigned int dim_index;static voidobj_coff_endef (ignore)     int ignore ATTRIBUTE_UNUSED;{  symbolS *symbolP = 0;  /* DIM BUG FIX sac@cygnus.com */  dim_index = 0;  if (def_symbol_in_progress == NULL)    {      as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));      demand_empty_rest_of_line ();      return;    }				/* if not inside .def/.endef */  /* Set the section number according to storage class.  */  switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))    {    case C_STRTAG:    case C_ENTAG:    case C_UNTAG:      SF_SET_TAG (def_symbol_in_progress);      /* intentional fallthrough */    case C_FILE:    case C_TPDEF:      SF_SET_DEBUG (def_symbol_in_progress);      S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);      break;    case C_EFCN:      SF_SET_LOCAL (def_symbol_in_progress);	/* Do not emit this symbol.  */      /* intentional fallthrough */    case C_BLOCK:      SF_SET_PROCESS (def_symbol_in_progress);	/* Will need processing before writing */      /* intentional fallthrough */    case C_FCN:      S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);      if (strcmp (S_GET_NAME (def_symbol_in_progress), ".bf") == 0)	{			/* .bf */	  if (function_lineoff < 0)	    {	      fprintf (stderr, _("`.bf' symbol without preceding function\n"));	    }			/* missing function symbol */	  SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;	  SF_SET_PROCESS (last_line_symbol);	  SF_SET_ADJ_LNNOPTR (last_line_symbol);	  SF_SET_PROCESS (def_symbol_in_progress);	  function_lineoff = -1;	}      /* Value is always set to .  */      def_symbol_in_progress->sy_frag = frag_now;      S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());      break;#ifdef C_AUTOARG    case C_AUTOARG:#endif /* C_AUTOARG */    case C_AUTO:    case C_REG:    case C_MOS:    case C_MOE:    case C_MOU:    case C_ARG:    case C_REGPARM:    case C_FIELD:    case C_EOS:      SF_SET_DEBUG (def_symbol_in_progress);      S_SET_SEGMENT (def_symbol_in_progress, absolute_section);      break;    case C_EXT:    case C_WEAKEXT:#ifdef TE_PE    case C_NT_WEAK:#endif    case C_STAT:    case C_LABEL:      /* Valid but set somewhere else (s_comm, s_lcomm, colon) */      break;    case C_USTATIC:    case C_EXTDEF:    case C_ULABEL:      as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress));      break;    }				/* switch on storage class */  /* Now that we have built a debug symbol, try to find if we should     merge with an existing symbol or not.  If a symbol is C_EFCN or     absolute_section or untagged SEG_DEBUG it never merges.  We also     don't merge labels, which are in a different namespace, nor     symbols which have not yet been defined since they are typically     unique, nor do we merge tags with non-tags.  */  /* Two cases for functions.  Either debug followed by definition or     definition followed by debug.  For definition first, we will

⌨️ 快捷键说明

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