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

📄 write.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	  know( fragP -> fr_next );	  fragP -> fr_offset	    =     fragP -> fr_next -> fr_address	      -   fragP -> fr_address		- fragP -> fr_fix;	  break;	case rs_fill:	  break;	case rs_machine_dependent:	  md_convert_frag (fragP);	  /*	   * After md_convert_frag, we make the frag into a ".space 0".	   * Md_convert_frag() should set up any fixSs and constants	   * required.	   */	  frag_wane (fragP);	  break;#ifndef WORKING_DOT_WORD	case rs_broken_word:	  {	    struct broken_word *lie;	    extern md_short_jump_size;	    extern md_long_jump_size;	    if(fragP->fr_subtype) {	      fragP->fr_fix+=md_short_jump_size;	      for(lie=(struct broken_word *)(fragP->fr_symbol);lie && lie->dispfrag==fragP;lie=lie->next_broken_word)		if(lie->added==1)		  fragP->fr_fix+=md_long_jump_size;	    }	    frag_wane(fragP);	  }	  break;#endif	default:	  BAD_CASE( fragP -> fr_type );	  break;	}			/* switch (fr_type) */    }				/* for each frag. */#ifndef WORKING_DOT_WORD    {      struct broken_word *lie;      struct broken_word **prevP;      prevP= &broken_words;      for(lie=broken_words; lie; lie=lie->next_broken_word)	if(!lie->added) {#if defined(SPARC) || defined(I860)	  fix_new(	lie->frag,  lie->word_goes_here - lie->frag->fr_literal,	  		2,  lie->add,			lie->sub,  lie->addnum,			0,  NO_RELOC);#endif#ifdef NS32K	  fix_new_ns32k(lie->frag,	  		lie->word_goes_here - lie->frag->fr_literal,			2,			lie->add,			lie->sub,			lie->addnum,			0, 0, 2, 0, 0);#endif#if !defined(SPARC) && !defined(NS32K) && !defined(I860)	  fix_new(	lie->frag,  lie->word_goes_here - lie->frag->fr_literal,	  		2,  lie->add,			lie->sub,  lie->addnum,			0);#endif	  /* md_number_to_chars(lie->word_goes_here,			       lie->add->sy_value			       + lie->addnum			       - (lie->sub->sy_value),			     2); */	  *prevP=lie->next_broken_word;	} else	  prevP= &(lie->next_broken_word);      for(lie=broken_words;lie;) {	struct broken_word *untruth;	char	*table_ptr;	long	table_addr;	long	from_addr,		to_addr;	int	n,		m;	extern	md_short_jump_size;	extern	md_long_jump_size;	void	md_create_short_jump();	void	md_create_long_jump();	fragP=lie->dispfrag;	/* Find out how many broken_words go here */	n=0;	for(untruth=lie;untruth && untruth->dispfrag==fragP;untruth=untruth->next_broken_word)	  if(untruth->added==1)	    n++;	table_ptr=lie->dispfrag->fr_opcode;	table_addr=lie->dispfrag->fr_address+(table_ptr - lie->dispfrag->fr_literal);	/* Create the jump around the long jumps */	/* This is a short jump from table_ptr+0 to table_ptr+n*long_jump_size */	from_addr=table_addr;	to_addr = table_addr + md_short_jump_size + n * md_long_jump_size;	md_create_short_jump(table_ptr,from_addr,to_addr,lie->dispfrag,lie->add);	table_ptr+=md_short_jump_size;	table_addr+=md_short_jump_size;	for(m=0;lie && lie->dispfrag==fragP;m++,lie=lie->next_broken_word) {	  if(lie->added==2)	    continue;	  /* Patch the jump table */	  /* This is the offset from ??? to table_ptr+0 */	  to_addr =   table_addr	            - (lie->sub->sy_value);	  md_number_to_chars(lie->word_goes_here,to_addr,2);	  for(untruth=lie->next_broken_word;untruth && untruth->dispfrag==fragP;untruth=untruth->next_broken_word) {	    if(untruth->use_jump==lie)	      md_number_to_chars(untruth->word_goes_here,to_addr,2);	  }	  /* Install the long jump */	  /* this is a long jump from table_ptr+0 to the final target */	  from_addr=table_addr;	  to_addr=lie->add->sy_value+lie->addnum;	  md_create_long_jump(table_ptr,from_addr,to_addr,lie->dispfrag,lie->add);	  table_ptr+=md_long_jump_size;	  table_addr+=md_long_jump_size;	}      }    }#endif#ifndef	VMS  /*   * Scan every FixS performing fixups. We had to wait until now to do   * this because md_convert_frag() may have made some fixSs.   */  /* the_exec . a_trsize    = sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT);  the_exec . a_drsize    = sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA); */  tr_siz=sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT);  md_number_to_chars((char *)&the_exec.a_trsize, tr_siz ,sizeof(the_exec.a_trsize));  dr_siz=sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA);  md_number_to_chars((char *)&the_exec.a_drsize, dr_siz, sizeof(the_exec.a_drsize));  md_number_to_chars((char *)&the_exec.a_info,omagic,sizeof(the_exec.a_info));  md_number_to_chars((char *)&the_exec.a_entry,0,sizeof(the_exec.a_entry));#ifdef EXEC_MACHINE_TYPE  md_number_to_chars((char *)&the_exec.a_machtype, EXEC_MACHINE_TYPE, sizeof(the_exec.a_machtype));#endif#ifdef EXEC_VERSION  md_number_to_chars((char *)&the_exec.a_version,EXEC_VERSION,sizeof(the_exec.a_version));#endif    /* the_exec . a_entry = 0; */  size_of_the_object_file =    sizeof( the_exec ) +      text_siz +        data_siz +	  syms_siz +	    tr_siz +	      dr_siz +		string_byte_count;	  next_object_file_charP    = the_object_file      = xmalloc ( size_of_the_object_file );  output_file_create (out_file_name);  append (& next_object_file_charP, (char *)(&the_exec), (unsigned long)sizeof(the_exec));  /*   * Emit code.   */  for (fragP = text_frag_root;  fragP;  fragP = fragP -> fr_next)    {      register long int		count;      register char *		fill_literal;      register long int		fill_size;      know( fragP -> fr_type == rs_fill );      append (& next_object_file_charP, fragP -> fr_literal, (unsigned long)fragP -> fr_fix);      fill_literal= fragP -> fr_literal + fragP -> fr_fix;      fill_size   = fragP -> fr_var;      know( fragP -> fr_offset >= 0 );      for (count = fragP -> fr_offset;  count;  count --)	  append (& next_object_file_charP, fill_literal, (unsigned long)fill_size);    }				/* for each code frag. */  /*   * Emit relocations.   */  emit_relocations (text_fix_root, (relax_addressT)0);  emit_relocations (data_fix_root, text_last_frag -> fr_address);  /*   * Emit all symbols left in the symbol chain.   * Any symbol still undefined is made N_EXT.   */  for (   symbolP = symbol_rootP;   symbolP;   symbolP = symbolP -> sy_next   )    {      register char *	temp;      temp = symbolP -> sy_nlist . n_un . n_name;      /* JF fix the numbers up. Call by value RULES! */      md_number_to_chars((char *)&(symbolP -> sy_nlist  . n_un . n_strx ),symbolP -> sy_name_offset,sizeof(symbolP -> sy_nlist  . n_un . n_strx ));      md_number_to_chars((char *)&(symbolP->sy_nlist.n_desc),symbolP->sy_nlist.n_desc,sizeof(symbolP -> sy_nlist  . n_desc));      md_number_to_chars((char *)&(symbolP->sy_nlist.n_value),symbolP->sy_nlist.n_value,sizeof(symbolP->sy_nlist.n_value));      /* symbolP -> sy_nlist  . n_un . n_strx = symbolP -> sy_name_offset; JF replaced by md above */      if (symbolP -> sy_type == N_UNDF)	  symbolP -> sy_type |= N_EXT; /* Any undefined symbols become N_EXT. */      append (& next_object_file_charP, (char *)(& symbolP -> sy_nlist),	      (unsigned long)sizeof(struct nlist));      symbolP -> sy_nlist . n_un . n_name = temp;    }				/* for each symbol */  /*   * next_object_file_charP -> slot for next object byte.   * Emit strings.   * Find strings by crawling along symbol table chain.   *//* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */  md_number_to_chars((char *)&string_byte_count, string_byte_count, sizeof(string_byte_count));  append (& next_object_file_charP, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count));  for (   symbolP = symbol_rootP;   symbolP;   symbolP = symbolP -> sy_next   )    {      if (symbolP -> sy_name)	{			/* Ordinary case: not .stabd. */	  append (& next_object_file_charP, symbolP -> sy_name,		  (unsigned long)(strlen (symbolP -> sy_name) + 1));	}    }				/* for each symbol */  know( next_object_file_charP == the_object_file + size_of_the_object_file );  output_file_append (the_object_file, size_of_the_object_file, out_file_name);#ifdef DONTDEF  if (flagseen['G'])		/* GDB symbol file to be appended? */    {      gdb_emit (out_file_name);      gdb_end ();    }#endif  output_file_close (out_file_name);#else	/* VMS */  /*   *	Now do the VMS-dependent part of writing the object file   */  VMS_write_object_file(text_siz, data_siz, text_frag_root, data_frag_root);#endif	/* VMS */}				/* write_object_file() *//* *			relax_segment() * * 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. */#ifndef	VMSstatic#endif	/* not VMS */voidrelax_segment (segment_frag_root, segment_type)     struct frag *	segment_frag_root;     segT		segment_type; /* N_DATA or N_TEXT */{  register struct frag *	fragP;  register relax_addressT	address;  /* register relax_addressT	old_address; JF unused */  /* register relax_addressT	new_address; JF unused */  know( segment_type == SEG_DATA || segment_type == SEG_TEXT );  /* In case md_estimate_size_before_relax() wants to make fixSs. */  subseg_change (segment_type, 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 -> 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:	  address += relax_align (address, fragP -> fr_offset);	  break;	case rs_org:	  /*	   * Assume .org is nugatory. It will grow with 1st relax.	   */	  break;	case rs_machine_dependent:	  address += md_estimate_size_before_relax	    (fragP, seg_N_TYPE [(int) segment_type]);	  break;#ifndef WORKING_DOT_WORD		/* Broken words don't concern us yet */	case rs_broken_word:		break;#endif	default:	  BAD_CASE( fragP -> fr_type );	  break;	}			/* switch(fr_type) */    }				/* for each frag in the segment */  /*   * Do relax().   */  {    register long int	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. */    register long 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 = stretched = 0;	for (fragP = segment_frag_root;  fragP;  fragP = fragP -> fr_next)	  {	    register long int	growth;	    register long int	was_address;	    /* register long int	var; */	    register long int	offset;	    register symbolS *	symbolP;	    register long int	target;	    register long int	after;	    register long int	aim;	    was_address = fragP -> fr_address;	    address = fragP -> fr_address += stretch;	    symbolP = fragP -> fr_symbol;	    offset = fragP -> fr_offset;	    /* var = fragP -> fr_var; */	    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;		extern int md_short_jump_size;		extern int md_long_jump_size;			/* 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=  lie->add->sy_frag->fr_address+lie->add->sy_value + lie->addnum -				(lie->sub->sy_frag->fr_address+lie->sub->sy_value);			if(offset<=-32768 || offset>=32767) {				if(flagseen['k'])					as_warn(".word %s-%s+%ld didn't fit",lie->add->sy_name,lie->sub->sy_name,lie->addnum);				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(untruth->add->sy_frag==lie->add->sy_frag && untruth->add->sy_value==lie->add->sy_value) {						untruth->added=2;						untruth->use_jump=lie;					}				growth+=md_long_jump_size;			}		    }		}		break;#endif

⌨️ 快捷键说明

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