gas-1.36 patches for COFF generation

Loic Dachary loic at adesign.uucp
Tue Oct 16 18:36:26 AEST 1990


*** write.c	Thu Apr 12 17:23:42 1990
--- /lasvegas/spare/usenet/port/gas-1.36/write.c	Mon Oct 15 12:35:38 1990
***************
*** 30,35 ****
--- 30,36 ----
     trouble.
   */
  
+ #include "oformat.h"
  #include "as.h"
  #include "md.h"
  #include "subsegs.h"
***************
*** 37,64 ****
  #include "struc-symbol.h"
  #include "write.h"
  #include "symbols.h"
  
  #ifdef SPARC
  #include "sparc.h"
  #endif
  
- void	append();
- 
  #ifdef hpux
  #define EXEC_MACHINE_TYPE HP9000S200_ID
  #endif
  
! /*
!  * In: length of relocation (or of address) in chars: 1, 2 or 4.
!  * Out: GNU LD relocation length code: 0, 1, or 2.
!  */
! 
! static unsigned char
! 
! nbytes_r_length [] = {
!   42, 0, 1, 42, 2
!   };
! 
  
  static struct frag *	text_frag_root;
  static struct frag *	data_frag_root;
--- 38,59 ----
  #include "struc-symbol.h"
  #include "write.h"
  #include "symbols.h"
+ #include "append.h"
+ #ifdef coff
+ #include <sys/types.h>
+ #endif /* coff */
  
  #ifdef SPARC
  #include "sparc.h"
  #endif
  
  #ifdef hpux
  #define EXEC_MACHINE_TYPE HP9000S200_ID
  #endif
  
! #ifdef coff
! extern time_t		time();
! #endif /* coff */
  
  static struct frag *	text_frag_root;
  static struct frag *	data_frag_root;
***************
*** 66,84 ****
  static struct frag *	text_last_frag;	/* Last frag in segment. */
  static struct frag *	data_last_frag;	/* Last frag in segment. */
  
! static struct exec	the_exec;
  
  static long int string_byte_count;
  
  static char *		the_object_file;
  
- #ifndef SPARC
- static
- #endif
  char *		next_object_file_charP;	/* Tracks object file bytes. */
  
- static long int		size_of_the_object_file; /* # bytes in object file. */
- 
  /* static long int		length; JF unused */	/* String length, including trailing '\0'. */
  
  static void	relax_segment();
--- 61,74 ----
  static struct frag *	text_last_frag;	/* Last frag in segment. */
  static struct frag *	data_last_frag;	/* Last frag in segment. */
  
! static object_headers	headers;
  
  static long int string_byte_count;
  
  static char *		the_object_file;
  
  char *		next_object_file_charP;	/* Tracks object file bytes. */
  
  /* static long int		length; JF unused */	/* String length, including trailing '\0'. */
  
  static void	relax_segment();
***************
*** 85,93 ****
  void		emit_segment();
  static relax_addressT	relax_align();
  static long int	fixup_segment();
- #ifndef SPARC
- static void		emit_relocations();
- #endif
  /*
   *			fix_new()
   *
--- 75,80 ----
***************
*** 144,150 ****
    register struct frchain *	next_frchainP;
    register fragS * *		prev_fragPP;
    register char *		name;
!   register symbolS *		symbolP;
    register symbolS **		symbolPP;
    /* register fixS *		fixP; JF unused */
    unsigned
--- 131,137 ----
    register struct frchain *	next_frchainP;
    register fragS * *		prev_fragPP;
    register char *		name;
!   symbolS *			symbolP;
    register symbolS **		symbolPP;
    /* register fixS *		fixP; JF unused */
    unsigned
***************
*** 153,158 ****
--- 140,152 ----
  	syms_siz,
  	tr_siz,
  	dr_siz;
+ #ifdef coff
+   SCNHDR			text_section_header;
+   SCNHDR			data_section_header;
+   SCNHDR			bss_section_header;
+   symbolS*			last_functionP = (symbolS*)0;
+   symbolS*			last_tagP;
+ #endif /* coff */
    void output_file_create();
    void output_file_append();
    void output_file_close();
***************
*** 160,168 ****
--- 154,168 ----
    void gdb_emit();
    void gdb_end();
  #endif
+   long int object_file_size;
    extern long omagic;		/* JF magic # to write out.  Is different for
  				   Suns and Vaxen and other boxes */
  
+ #ifdef coff
+   /* Initialize the stack used to keep track of the matching .bb .be */
+   stack* block_stack = stack_init(512, sizeof(symbolS*));
+ #endif /* coff */
+ 
  #ifdef	VMS
    /*
     *	Under VMS we try to be compatible with VAX-11 "C".  Thus, we
***************
*** 261,273 ****
     */
  
    know(   text_last_frag -> fr_type   == rs_fill && text_last_frag -> fr_offset == 0 );
!   text_siz=text_last_frag->fr_address;
  #ifdef SPARC
!   text_siz= (text_siz+7)&(~7);
!   text_last_frag->fr_address=text_siz;
  #endif
-   md_number_to_chars((char *)&the_exec.a_text,text_siz, sizeof(the_exec.a_text));
-   /* the_exec . a_text = text_last_frag -> fr_address; */
  
    /*
     * Join the 2 segments into 1 huge segment.
--- 261,272 ----
     */
  
    know(   text_last_frag -> fr_type   == rs_fill && text_last_frag -> fr_offset == 0 );
!   H_SET_TEXT_SIZE(&headers,text_last_frag->fr_address);
  #ifdef SPARC
!   H_SET_TEXT_SIZE(&headers,H_GET_TEXT_SIZE(&headers) + 
! 		           (H_GET_TEXT_SIZE(&headers)+7)&(~7));
!   text_last_frag->fr_address=H_GET_TEXT_SIZE(&headers);
  #endif
  
    /*
     * Join the 2 segments into 1 huge segment.
***************
*** 281,294 ****
        register relax_addressT	slide;
  
        know(   text_last_frag -> fr_type   == rs_fill && text_last_frag -> fr_offset == 0 );
!       data_siz=data_last_frag->fr_address;
  #ifdef SPARC
!       data_siz += (8 - (data_siz % 8)) % 8;
!       data_last_frag->fr_address = data_siz;
  #endif
!       md_number_to_chars((char *)&the_exec.a_data,data_siz,sizeof(the_exec.a_data));
!       /* the_exec . a_data = data_last_frag -> fr_address; */
!       slide = text_siz; /* Address in file of the data segment. */
        for (fragP = data_frag_root;
  	   fragP;
  	   fragP = fragP -> fr_next)
--- 280,292 ----
        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);
  #ifdef SPARC
!       H_SET_DATA_SIZE(&headers,(H_GET_DATA_SIZE(&headers) + 
! 				(8 - (H_GET_DATA_SIZE(&headers) % 8)) % 8));
!       data_last_frag->fr_address = H_GET_DATA_SIZE(&headers);
  #endif
!       slide = H_GET_TEXT_SIZE(&headers); /* & in file of the data segment. */
        for (fragP = data_frag_root;
  	   fragP;
  	   fragP = fragP -> fr_next)
***************
*** 298,314 ****
        know( text_last_frag );
        text_last_frag -> fr_next = data_frag_root;
      }
!   else {
!       md_number_to_chars((char *)&the_exec.a_data,0,sizeof(the_exec.a_data));
!       data_siz = 0;
!   }
  
!   bss_address_frag . fr_address = text_siz + data_siz;
  #ifdef SPARC
    local_bss_counter=(local_bss_counter+7)&(~7);
  #endif
!   md_number_to_chars((char *)&the_exec.a_bss,local_bss_counter,sizeof(the_exec.a_bss));
! 
  	      
    /*
     *
--- 296,310 ----
        know( text_last_frag );
        text_last_frag -> fr_next = data_frag_root;
      }
!   else
!       H_SET_DATA_SIZE(&headers,0);
  
!   bss_address_frag . fr_address = H_GET_TEXT_SIZE(&headers) + 
!                                   H_GET_DATA_SIZE(&headers);
  #ifdef SPARC
    local_bss_counter=(local_bss_counter+7)&(~7);
  #endif
!   H_SET_BSS_SIZE(&headers,local_bss_counter);
  	      
    /*
     *
***************
*** 340,380 ****
  		symbolP->sy_forward=0;
  	}
    }
!   symbolPP = & symbol_rootP;	/* -> last symbol chain link. */
    {
!     register long int		symbol_number;
  
!     symbol_number = 0;
      while (symbolP  = * symbolPP)
        {
! 	name = symbolP -> sy_name;
! 	if(flagseen['R'] && (symbolP->sy_nlist.n_type&N_DATA)) {
! 	  symbolP->sy_nlist.n_type&= ~N_DATA;
! 	  symbolP->sy_nlist.n_type|= N_TEXT;
! 	}
! 	/* if(symbolP->sy_forward) {
! 	  symbolP->sy_value += symbolP->sy_forward->sy_value + symbolP->sy_forward->sy_frag->fr_address;
! 	} */
  	
  	symbolP -> sy_value += symbolP -> sy_frag -> fr_address;
- 		/* JF the 128 bit is a hack so stabs like
- 		   "LET_STMT:23. . ."  don't go away */
- 	/* CPH: 128 bit hack is moby loser.  N_SO for file "Lower.c"
- 	   fell through the cracks.  I think that N_STAB should be
- 	   used instead of 128. */
  		/* JF the \001 bit is to make sure that local labels
  		   ( 1: - 9: don't make it into the symtable either */
  #ifndef	VMS	/* Under VMS we need to keep local symbols */
! 	if ( !name || (symbolP->sy_nlist.n_type&N_STAB)
! 	    || (name[0]!='\001' && (flagseen ['L'] || name [0] != 'L' )))
  #endif	/* not VMS */
  	  {
- 	    symbolP -> sy_number = symbol_number ++;
  #ifndef	VMS
! 	    if (name)
  	      {			/* Ordinary case. */
  		symbolP -> sy_name_offset = string_byte_count;
! 		string_byte_count += strlen (symbolP  -> sy_name) + 1;
  	      }
  	    else			/* .Stabd case. */
  #endif	/* not VMS */
--- 336,581 ----
  		symbolP->sy_forward=0;
  	}
    }
! 
    {
!       register int	symbol_number = 0;
! #if defined(coff)
!       symbolS*		symbol_externP = (symbolS*)0;
!       symbolS*		symbol_extern_lastP = (symbolS*)0;
!       
!   /* The symbol list should be ordered according to the following sequence
!    * order :
!    * . .file symbol
!    * . debug entries for functions
!    * . fake symbols for .text .data and .bss
!    * . defined symbols
!    * . undefined symbols
!    * But this is not mandatory. The only important point is to put the
!    * undefined symbols at the end of the list.
!    */
! 
!       {
! 	  /* Is there a .file symbol ? If not insert one at the beginning. */
! 	  if(symbol_rootP == NULL ||
! 	     S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE)
! 	      c_dot_file_symbol("fake");
! 	  
! 	  /*
! 	   * Build up static symbols for .text, .data and .bss
! 	   */
! 	  dot_text_symbol = (symbolS*)
! 	      c_section_symbol(".text", 0, H_GET_TEXT_SIZE(&headers),
! 			 0/*text_relocation_number*/, 0/*text_lineno_number*/);
! 	  dot_data_symbol = (symbolS*)
! 	      c_section_symbol(".data", H_GET_TEXT_SIZE(&headers),
! 			H_GET_DATA_SIZE(&headers),
! 			0/*data_relocation_number*/,
! 			0); /* There is no data lineno entries */
! 	  dot_bss_symbol = (symbolS*)
! 	      c_section_symbol(".bss", H_GET_TEXT_SIZE(&headers) +
! 			H_GET_DATA_SIZE(&headers),
! 			H_GET_BSS_SIZE(&headers),
! 			0, /* No relocation for a bss section. */
! 			0); /* There is no bss lineno entries */
!       }
! 	      
!       symbolP = symbol_rootP;
!       if(symbolP) {
! 	   while(symbolP) {
! 	      /* If the symbol has a tagndx entry, resolve it */
! 	      if(SF_GET_TAGGED(symbolP)) {
! 		  SA_SET_SYM_TAGNDX(symbolP,
! 				    ((symbolS*)SA_GET_SYM_TAGNDX(symbolP))->sy_number);
! 	      }
! 	      /* Debug symbol do not need all this rubbish */
! 	      if(!SF_GET_DEBUG(symbolP)) {
! 		  symbolS* real_symbolP;
! 		  /* L* and C_EFCN symbols never merge. */
! 		  if(!SF_GET_LOCAL(symbolP) &&
! 		     (real_symbolP =
! 		      symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP)) &&
! 		     real_symbolP != symbolP) {
! 		      /* Move the debug data from the debug symbol to the
! 			 real symbol. Do NOT do the oposite (i.e. move from
! 			 real symbol to symbol and remove real symbol from the
! 			 list.) Because some pointers refer to the real symbol
! 			 whereas no pointers refer to the symbol. */
! 		      c_symbol_merge(symbolP, real_symbolP);
! 		      /* Replace the current symbol by the real one */
! 		      /* The symbols will never be the last or the first
! 			 because : 1st symbol is .file and 3 last symbols are
! 			 .text, .data, .bss */
! 		      real_symbolP->sy_previous->sy_next = real_symbolP->sy_next;
! 		      real_symbolP->sy_next->sy_previous = real_symbolP->sy_previous;
! 		      symbolP->sy_previous->sy_next = real_symbolP;
! 		      symbolP->sy_next->sy_previous = real_symbolP;
! 		      real_symbolP->sy_next = symbolP->sy_next;
! 		      real_symbolP->sy_previous = symbolP->sy_previous;
! 		      symbolP = real_symbolP;
! 		  }
! 		  if(flagseen['R'] && S_IS_DATA(symbolP))
! 		      S_SET_TEXT(symbolP);
! 		  
! 		  symbolP->sy_value += symbolP->sy_frag->fr_address;
! 		  
! 		  if(!S_IS_DEFINED(symbolP))
! 		      S_SET_EXTERNAL(symbolP);
! 		  else if(S_GET_STORAGE_CLASS(symbolP) == C_NULL)
! 		      S_SET_STORAGE_CLASS(symbolP, C_STAT);
! 		  
! 		  /* Mainly to speed up if not -g */
! 		  if(SF_GET_PROCESS(symbolP)) {
! 		      /* Handle the nested blocks auxiliary info. */
! 		      if(S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) {
! 			  if(!strcmp(S_GET_NAME(symbolP), ".bb"))
! 			      stack_push(block_stack, &symbolP);
! 			  else { /* .eb */
! 			      register symbolS* begin_symbolP;
! 			      begin_symbolP = *(symbolS**)stack_pop(block_stack);
! 			      if(begin_symbolP == (symbolS*)0)
! 				  as_warn("mismatched .eb");
! 			      else
! 				  SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number);
! 			  }
! 		      }
! 		      /* If we are able to identify the type of a function, and we
! 			 are out of a function (last_functionP == 0) then, the
! 			 function symbol will be associated with an auxiliary
! 			 entry. */
! 		      if(last_functionP == (symbolS*)0 &&
! 			 SF_GET_FUNCTION(symbolP)) {
! 			  last_functionP = symbolP;
! 			  S_SET_NUMBER_AUXILIARY(symbolP, 1);
! 			  /* Clobber possible stale .dim information. */
! 			  memset(&symbolP->sy_auxent, '\0', sizeof(union auxent));
! 		      }
! 		      /* The C_FCN do not need any additional information.
! 			 I don't even know if this is needed for sdb. But the
! 			 standard assembler generate it, so...
! 			 */
! 		      if(S_GET_STORAGE_CLASS(symbolP) == C_EFCN) {
! 			  if(last_functionP == (symbolS*)0)
! 			      as_fatal("C_EFCN symbol out of scope");
! 			  SA_SET_SYM_FSIZE(last_functionP,
! 					   (long)(symbolP->sy_value -
! 						  last_functionP->sy_value));
! 			  SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
! 			  last_functionP = (symbolS*)0;
! 		      }
! 		  }
! 	      } else {
! 		  /* First descriptor of a structure must point to the next
! 		     slot outside the structure description. */
! 		  if(SF_GET_TAG(symbolP))
! 		      last_tagP = symbolP;
! 		  else if(S_GET_STORAGE_CLASS(symbolP) == C_EOS)
! 		      /* +2 take in account the current symbol */
! 		      SA_SET_SYM_ENDNDX(last_tagP, symbol_number+2);
! 	      }
! 
! 	      /* We must put the external symbols appart. The loader
! 		 does not bomb if we do not. But the references in
! 		 the endndx field for a .bb symbol are not corrected
! 		 if an external symbol is removed between .bb and .be.
! 		 I.e int the following case :
! 		 [20] .bb endndx = 22
! 		 [21] foo external
! 		 [22] .be
! 		 ld will move the symbol 21 to the end of the list but
! 		 endndx will still be 22 instead of 21. */
! 	      {
! 		  register symbolS* thisP = symbolP;
! 
! 		  symbolP = thisP->sy_next;
! 		  /* remove C_EFCN and LOCAL (L...) symbols */
! 		  if(SF_GET_LOCAL(thisP)) {
! 		      thisP->sy_next->sy_previous = thisP->sy_previous;
! 		      thisP->sy_previous->sy_next = thisP->sy_next;
! 		  } else {
! 		      if(S_GET_STORAGE_CLASS(thisP) == C_EXT &&
! 			 !SF_GET_FUNCTION(thisP)) {
! 			  /* Remove from the list */
! 			  thisP->sy_next->sy_previous = thisP->sy_previous;
! 			  thisP->sy_previous->sy_next = thisP->sy_next;
! 			  /* Move at the end of the list */
! 			  if (symbol_extern_lastP) {
! 			      symbol_extern_lastP->sy_next = thisP;
! 			      thisP->sy_previous = symbol_extern_lastP;
! 			  } else {
! 			      symbol_externP = thisP;
! 			  }
! 			  thisP->sy_next = (symbolS*)0;
! 			  symbol_extern_lastP = thisP;
! 		      } else {
! 			  if(SF_GET_STRING(thisP)) {
! 			      thisP->sy_name_offset = string_byte_count;
! 			      string_byte_count += strlen(S_GET_NAME(thisP)) + 1;
! 			  } else
! 			      thisP->sy_name_offset = 0;
! 			  thisP->sy_number = symbol_number;
! 			  symbol_number += 1 + S_GET_NUMBER_AUXILIARY(thisP);
! 		      }
! 		  }
! 	      }
! 	  }
  
! 	  symbol_lastP->sy_next = symbol_externP;
! 	  symbolP = symbol_externP;
! 	  while(symbolP) {
! 	      if(SF_GET_STRING(symbolP)) {
! 		  symbolP->sy_name_offset = string_byte_count;
! 		  string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
! 	      } else
! 		  symbolP->sy_name_offset = 0;
! 	      symbolP->sy_number = symbol_number;
! 	      symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
! 	      symbolP = symbolP->sy_next;
! 	  }
!       }
!       {
! 	  lineno* lineP;
! 	  for(lineP = lineno_rootP; lineP; lineP = lineP->next) {
! 	      if(lineP->line.l_lnno)
! 		  lineP->line.l_addr.l_paddr +=
! 		      ((fragS*)lineP->frag)->fr_address;
! 	      else {
! 		  /* There is a good chance that the symbol pointed to
! 		     is not the one that will be emitted and that the 
! 		     sy_number is not accurate. */
! 		  char* name;
! 		  name = (char*)lineP->line.l_addr.l_symndx;
! 		  if((symbolP = symbol_find_base(name, DO_NOT_STRIP)) ==
! 		     (symbolS*)0)
! 		      as_warn("line number lost symbol %s", name);
! 		  else
! 		      lineP->line.l_addr.l_symndx = symbolP->sy_number;
! 	      }
! 	      text_lineno_number++;
! 	  }
!       }
! #elif defined(aout)
!     symbolPP = & symbol_rootP;	/* -> last symbol chain link. */
      while (symbolP  = * symbolPP)
        {
! 	name = S_GET_NAME(symbolP);
! 	if(flagseen['R'] && S_IS_DATA(symbolP))
! 	  S_SET_TEXT(symbolP);
  	
  	symbolP -> sy_value += symbolP -> sy_frag -> fr_address;
  		/* JF the \001 bit is to make sure that local labels
  		   ( 1: - 9: don't make it into the symtable either */
  #ifndef	VMS	/* Under VMS we need to keep local symbols */
! 	if (!S_IS_LOCAL(symbolP))
  #endif	/* not VMS */
  	  {
  #ifndef	VMS
! /* The + 1 after strlen account for the \0 at the end of each string */
! 	    symbolP -> sy_number = symbol_number ++;
! 	    if(!S_IS_STABD(symbolP))
  	      {			/* Ordinary case. */
  		symbolP -> sy_name_offset = string_byte_count;
! 		string_byte_count += 
! 		    strlen (S_GET_NAME(symbolP)) + 1;
  	      }
  	    else			/* .Stabd case. */
  #endif	/* not VMS */
***************
*** 382,397 ****
  	    symbolPP = & (symbolP -> sy_next);
  	  }
  #ifndef	VMS
! 	else
  	    * symbolPP = symbolP -> sy_next;
  #endif	/* not VMS */
        }				/* for each symbol */
  
!     syms_siz = sizeof( struct nlist) * symbol_number;
!     md_number_to_chars((char *)&the_exec.a_syms,syms_siz,sizeof(the_exec.a_syms));
!     /* the_exec . a_syms = sizeof( struct nlist) * symbol_number; */
    }
- 
    /*
     * Addresses of frags now reflect addresses we use in the object file.
     * Symbol values are correct.
--- 583,601 ----
  	    symbolPP = & (symbolP -> sy_next);
  	  }
  #ifndef	VMS
! 	else /* skip the symbol */
  	    * symbolPP = symbolP -> sy_next;
  #endif	/* not VMS */
        }				/* for each symbol */
  
! #elif defined(elf)
!       do it yourself !
! #else
!       you lose
! #endif
!     H_SET_STRING_SIZE(&headers,string_byte_count);
!     H_SET_SYMBOL_TABLE_SIZE(&headers, symbol_number);
    }
    /*
     * Addresses of frags now reflect addresses we use in the object file.
     * Symbol values are correct.
***************
*** 553,595 ****
     * 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_magic,omagic,sizeof(the_exec.a_magic));
!   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.
--- 757,876 ----
     * Scan every FixS performing fixups. We had to wait until now to do
     * this because md_convert_frag() may have made some fixSs.
     */
!   
!   H_SET_RELOCATION_SIZE(&headers,
!        RELSZ*fixup_segment (text_fix_root, SEG_TEXT),
!        RELSZ*fixup_segment (data_fix_root, SEG_DATA));
!   H_SET_MAGIC_NUMBER(&headers,omagic);
!   H_SET_ENTRY_POINT(&headers,0);
  
  #ifdef EXEC_MACHINE_TYPE
!   H_SET_MACHINE_TYPE(&headers,EXEC_MACHINE_TYPE);
  #endif
  #ifdef EXEC_VERSION
!   H_SET_VERSION(&headers,EXEC_VERSION);
  #endif
  
! #ifdef coff
!   {
!       register int		text_relocation_number = 0;
!       register int		data_relocation_number = 0;
!       register fixS*	fixP;
! 	  
!       /* Count the number of relocation entries for text and data */
!       for(fixP = text_fix_root; fixP; fixP = fixP->fx_next)
! 	  if(fixP->fx_addsy)
! 	      text_relocation_number++;
!       SA_SET_SCN_NRELOC(dot_text_symbol, text_relocation_number);
!       /* Assign the number of line number entries for the text section */
!       SA_SET_SCN_NLINNO(dot_text_symbol, text_lineno_number);
!       /* Assign the size of the section */
!       SA_SET_SCN_SCNLEN(dot_text_symbol, H_GET_TEXT_SIZE(&headers));
!       
!       for(fixP = data_fix_root; fixP; fixP = fixP->fx_next)
! 	  if(fixP->fx_addsy)
! 	      data_relocation_number++;
!       SA_SET_SCN_NRELOC(dot_data_symbol, data_relocation_number);
!       /* Assign the size of the section */
!       SA_SET_SCN_SCNLEN(dot_data_symbol, H_GET_DATA_SIZE(&headers));
! 
!       /* Assign the size of the section */
!       SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(&headers));
!   }
! 
!   /* Fill in extra coff fields */
! 
!   /* Initialize general line number information. */
!   H_SET_LINENO_SIZE(&headers, text_lineno_number * LINESZ);
! 
!   /* filehdr */
!   H_SET_FILE_MAGIC_NUMBER(&headers, FILE_HEADER_MAGIC);
!   H_SET_NUMBER_OF_SECTIONS(&headers, 3); /* text+data+bss */
!   H_SET_TIME_STAMP(&headers, (long)time((long*)0));
!   H_SET_SYMBOL_TABLE_POINTER(&headers,
! 			     H_GET_SYMBOL_TABLE_FILE_OFFSET(&headers));
!   /* symbol table size allready set */
!   H_SET_SIZEOF_OPTIONAL_HEADER(&headers, AOUTHDRSZ);
!   H_SET_FLAGS(&headers, (text_lineno_number == 0 ? F_LNNO : 0 ) | 
! 	      BYTE_ORDERING);
! 
!   /* aouthdr */
!   /* magic number allready set */
!   H_SET_VERSION_STAMP(&headers, 0);
!   /* Text, data, bss size; entry point; text_start and data_start
!      are already set */
! 
!   /* Build section headers */
!   
!   c_section_header(&text_section_header,
! 		   ".text",
! 		   0,
! 		   H_GET_TEXT_SIZE(&headers),
! 		   H_GET_TEXT_FILE_OFFSET(&headers),
! 		   SA_GET_SCN_NRELOC(dot_text_symbol) ?
! 		     H_GET_RELOCATION_FILE_OFFSET(&headers) : 0,
! 		   text_lineno_number ? H_GET_LINENO_FILE_OFFSET(&headers) : 0,
! 		   SA_GET_SCN_NRELOC(dot_text_symbol),
! 		   text_lineno_number);
!   c_section_header(&data_section_header,
! 		   ".data",
! 		   H_GET_TEXT_SIZE(&headers),
! 		   H_GET_DATA_SIZE(&headers),
! 		   H_GET_DATA_SIZE(&headers) ?
! 		     H_GET_DATA_FILE_OFFSET(&headers) : 0,
! 		   SA_GET_SCN_NRELOC(dot_data_symbol) ?
! 		     H_GET_RELOCATION_FILE_OFFSET(&headers) +
! 		     text_section_header.s_nreloc * RELSZ : 0,
! 		   0, /* No line number information */
! 		   SA_GET_SCN_NRELOC(dot_data_symbol),
! 		   0);  /* No line number information */
!   c_section_header(&bss_section_header,
! 		   ".bss",
! 		   H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers),
! 		   H_GET_BSS_SIZE(&headers),
! 		   0, /* No file offset */
! 		   0, /* No relocation information */
! 		   0, /* No line number information */
! 		   0, /* No relocation information */
! 		   0); /* No line number information */
!   
! #endif /* coff */
!   
!   object_file_size = H_GET_FILE_SIZE(&headers);
!   next_object_file_charP = the_object_file = xmalloc ( object_file_size );
  
    output_file_create (out_file_name);
  
! 
!   H_OUTPUT(&headers, &next_object_file_charP);
! 
! #ifdef coff
!   /* Output the section headers */
!   c_section_header_append(&text_section_header, &next_object_file_charP);
!   c_section_header_append(&data_section_header, &next_object_file_charP);
!   c_section_header_append(&bss_section_header, &next_object_file_charP);
! #endif /* coff */
! 
  
    /*
     * Emit code.
***************
*** 614,642 ****
     */
    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.
     */
--- 895,914 ----
     */
    emit_relocations (text_fix_root, (relax_addressT)0);
    emit_relocations (data_fix_root, text_last_frag -> fr_address);
+ 
+ #ifdef coff
    /*
!    * Emit line number entries.
     */
!   emit_lineno(lineno_rootP, &next_object_file_charP);
! #endif /* coff */
! 
!   /*
!    * Emit symbols.
!    */
!   emit_symbols (symbol_rootP,&next_object_file_charP);
  
    /*
     * Emit strings.
     * Find strings by crawling along symbol table chain.
     */
***************
*** 644,661 ****
    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? */
--- 916,934 ----
    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) {
! #ifdef coff
!       if(SF_GET_STRING(symbolP))
! #else /* coff */
!       if(S_GET_NAME(symbolP))
! #endif /* coff */
! 	  append(&next_object_file_charP, S_GET_NAME(symbolP),
! 		 (unsigned long)(strlen (S_GET_NAME(symbolP)) + 1));
!   }
  
!   know( next_object_file_charP == the_object_file + object_file_size);
!   /* Write the data to the file */
!   output_file_append (the_object_file,object_file_size,out_file_name);
  
  #ifdef DONTDEF
    if (flagseen['G'])		/* GDB symbol file to be appended? */
***************
*** 692,698 ****
  void
  relax_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;
--- 965,971 ----
  void
  relax_segment (segment_frag_root, segment_type)
       struct frag *	segment_frag_root;
!      segT		segment_type; /* SEG_DATA or SEG_TEXT */
  {
    register struct frag *	fragP;
    register relax_addressT	address;
***************
*** 730,736 ****
  
  	case rs_machine_dependent:
  	  address += md_estimate_size_before_relax
! 	    (fragP, seg_N_TYPE [(int) segment_type]);
  	  break;
  
  #ifndef WORKING_DOT_WORD
--- 1003,1009 ----
  
  	case rs_machine_dependent:
  	  address += md_estimate_size_before_relax
! 	    (fragP, seg_SEG((int) segment_type));
  	  break;
  
  #ifndef WORKING_DOT_WORD
***************
*** 837,845 ****
  		target = offset;
  		if (symbolP)
  		  {
! 		    know(   ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type & N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT));
! 		    know( symbolP -> sy_frag );
! 		    know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag );
  		    target +=
  		      symbolP -> sy_value
  			+ symbolP -> sy_frag -> fr_address;
--- 1110,1121 ----
  		target = offset;
  		if (symbolP)
  		  {
! 		    know(S_IS_ABS(symbolP) ||
! 			 S_IS_DATA(symbolP) ||
! 			 S_IS_TEXT(symbolP))
! 		    know(symbolP -> sy_frag);
! 		    know(!S_IS_ABS(symbolP) || 
! 			 symbolP->sy_frag==&zero_address_frag );
  		    target +=
  		      symbolP -> sy_value
  			+ symbolP -> sy_frag -> fr_address;
***************
*** 866,875 ****
  		target = offset;
  		if (symbolP)
  		  {
!  know(   ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type &
!  N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT));
! 		    know( symbolP -> sy_frag );
! 		    know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag );
  		    target +=
  		      symbolP -> sy_value
  			+ symbolP -> sy_frag -> fr_address;
--- 1142,1153 ----
  		target = offset;
  		if (symbolP)
  		  {
! 		    know(S_IS_ABS(symbolP) ||
! 			 S_IS_DATA(symbolP) ||
! 			 S_IS_TEXT(symbolP))
! 		    know(symbolP -> sy_frag);
! 		    know(!S_IS_ABS(symbolP) || 
! 			 symbolP->sy_frag==&zero_address_frag );
  		    target +=
  		      symbolP -> sy_value
  			+ symbolP -> sy_frag -> fr_address;
***************
*** 1021,1045 ****
        add_number  = fixP  -> fx_offset;
        pcrel	  = fixP  -> fx_pcrel;
        if(add_symbolP)
! 	add_symbol_N_TYPE = add_symbolP -> sy_type & N_TYPE;
        if (sub_symbolP)
  	{
  	  if(!add_symbolP)	/* Its just -sym */
  	    {
! 	      if(sub_symbolP->sy_type!=N_ABS)
! 	        as_warn("Negative of non-absolute symbol %s", sub_symbolP->sy_name);
! 	      add_number-=sub_symbolP->sy_value;
  	    }
! 	  else if (   ((sub_symbolP -> sy_type ^ add_symbol_N_TYPE) & N_TYPE) == 0
! 	      && (   add_symbol_N_TYPE == N_DATA
! 		  || add_symbol_N_TYPE == N_TEXT
! 		  || add_symbol_N_TYPE == N_BSS
! 		  || add_symbol_N_TYPE == N_ABS))
  	    {
  	      /* Difference of 2 symbols from same segment. */
  	      /* Can't make difference of 2 undefineds: 'value' means */
  	      /* something different for N_UNDF. */
! 	      add_number += add_symbolP -> sy_value - sub_symbolP -> sy_value;
  	      add_symbolP = NULL;
  	      fixP -> fx_addsy = NULL;
  	    }
--- 1299,1328 ----
        add_number  = fixP  -> fx_offset;
        pcrel	  = fixP  -> fx_pcrel;
        if(add_symbolP)
! 	add_symbol_N_TYPE = SEG_seg(S_GET_SEGMENT(add_symbolP));
        if (sub_symbolP)
  	{
  	  if(!add_symbolP)	/* Its just -sym */
  	    {
! 	      if(SEG_seg(sub_symbolP->sy_type)!=SEG_ABSOLUTE)
! 	        as_warn("Negative of non-absolute symbol %s", 
! 			S_GET_NAME(sub_symbolP));
! 	      add_number-=S_GET_VALUE(sub_symbolP);
  	    }
! 	  /* if sub_symbol is in the same segment that add_symbol
! 	     and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
! 	  else if((SEG_seg(S_GET_SEGMENT(sub_symbolP)) == 
! 		   add_symbol_N_TYPE) &&
! 		  ((add_symbol_N_TYPE == SEG_DATA) ||
! 		   (add_symbol_N_TYPE == SEG_TEXT) ||
! 		   (add_symbol_N_TYPE == SEG_BSS)  ||
! 		   (add_symbol_N_TYPE == SEG_ABSOLUTE)))
  	    {
  	      /* Difference of 2 symbols from same segment. */
  	      /* Can't make difference of 2 undefineds: 'value' means */
  	      /* something different for N_UNDF. */
! 	      add_number += S_GET_VALUE(add_symbolP) - 
! 		            S_GET_VALUE(sub_symbolP);
  	      add_symbolP = NULL;
  	      fixP -> fx_addsy = NULL;
  	    }
***************
*** 1046,1059 ****
  	  else
  	    {
  	      /* Different segments in subtraction. */
! 	      know( sub_symbolP -> sy_type != (N_ABS | N_EXT))
! 		if (sub_symbolP -> sy_type == N_ABS)
! 		    add_number -= sub_symbolP -> sy_value;
  		else
  		  {
! 			   as_warn("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
! 				    seg_name[(int)N_TYPE_seg[sub_symbolP->sy_type&N_TYPE]],
! 				    sub_symbolP -> sy_name, fragP -> fr_address + where);
  		  }
  	    }
  	}
--- 1329,1342 ----
  	  else
  	    {
  	      /* Different segments in subtraction. */
! 	      know(!(S_IS_EXTERNAL(sub_symbolP) && S_IS_ABS(sub_symbolP)));
! 		if (S_IS_ABS(sub_symbolP))
! 		    add_number -= S_GET_VALUE(sub_symbolP);
  		else
  		  {
! 		    as_warn("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
! 		      segment_name((int)SEG_seg(S_GET_SEGMENT(sub_symbolP))),
! 		      S_GET_NAME(sub_symbolP), fragP -> fr_address + where);
  		  }
  	    }
  	}
***************
*** 1066,1072 ****
  	       * SEG_UNKNOWN, but it is now in the local segment.
  	       * So we know how to do the address without relocation.
  	       */
! 	      add_number += add_symbolP -> sy_value;
  	      add_number -= size + where + fragP -> fr_address;
  	      pcrel = 0;	/* Lie. Don't want further pcrel processing. */
  	      fixP -> fx_addsy = NULL; /* No relocations please. */
--- 1349,1355 ----
  	       * SEG_UNKNOWN, but it is now in the local segment.
  	       * So we know how to do the address without relocation.
  	       */
! 	      add_number += S_GET_VALUE(add_symbolP);
  	      add_number -= size + where + fragP -> fr_address;
  	      pcrel = 0;	/* Lie. Don't want further pcrel processing. */
  	      fixP -> fx_addsy = NULL; /* No relocations please. */
***************
*** 1082,1101 ****
  	    {
  	      switch (add_symbol_N_TYPE)
  		{
! 		case N_ABS:
! 		  add_number += add_symbolP -> sy_value;
  		  fixP -> fx_addsy = NULL;
  		  add_symbolP = NULL;
  		  break;
  		  
! 		case N_BSS:
! 		case N_DATA:
! 		case N_TEXT:
  		  seg_reloc_count ++;
! 		  add_number += add_symbolP -> sy_value;
  		  break;
  		  
! 		case N_UNDF:
  		  seg_reloc_count ++;
  		  break;
  		  
--- 1365,1388 ----
  	    {
  	      switch (add_symbol_N_TYPE)
  		{
! 		case SEG_ABSOLUTE:
! 		  add_number += S_GET_VALUE(add_symbolP);
  		  fixP -> fx_addsy = NULL;
  		  add_symbolP = NULL;
  		  break;
  		  
! 		case SEG_BSS:
! 		case SEG_DATA:
! 		case SEG_TEXT:
  		  seg_reloc_count ++;
! 		  add_number += S_GET_VALUE(add_symbolP);
  		  break;
  		  
! 		case SEG_UNKNOWN:
! #ifdef coff
! 		  if(S_IS_COMMON(add_symbolP))
! 		      add_number += S_GET_VALUE(add_symbolP);
! #endif /* coff */
  		  seg_reloc_count ++;
  		  break;
  		  
***************
*** 1125,1131 ****
  	case 0:
  #ifdef SPARC
  	  fixP->fx_addnumber = add_number;
! 	  md_number_to_imm(place, add_number, size, fixP, this_segment_type);
  #else
  	  md_number_to_imm (place, add_number, size);
  	  /* OVE: the immediates, like disps, have lsb at lowest address */
--- 1412,1419 ----
  	case 0:
  #ifdef SPARC
  	  fixP->fx_addnumber = add_number;
! 	  md_number_to_imm(place, add_number, size, fixP, 
! 			   seg_SEG(this_segment_type));
  #else
  	  md_number_to_imm (place, add_number, size);
  	  /* OVE: the immediates, like disps, have lsb at lowest address */
***************
*** 1149,1215 ****
    return (seg_reloc_count);
  }				/* fixup_segment() */
  
- 
- /* The sparc needs its own emit_relocations() */
- #ifndef SPARC
- /*
-  *		emit_relocations()
-  *
-  * Crawl along a fixS chain. Emit the segment's relocations.
-  */
- static void
- emit_relocations (fixP, segment_address_in_file)
-      register fixS *	fixP;	/* Fixup chain for this segment. */
-      relax_addressT	segment_address_in_file;
- {
-   struct relocation_info	ri;
-   register symbolS *		symbolP;
- 
- 	/* JF this is for paranoia */
-   bzero((char *)&ri,sizeof(ri));
-   for ( ;  fixP;  fixP = fixP -> fx_next)
-     {
-       if (symbolP = fixP -> fx_addsy)
- 	{
- 
- #ifndef hpux
- 		/* These two 'cuz of NS32K */
- 	  ri . r_bsr		= fixP -> fx_bsr;
- 	  ri . r_disp		= fixP -> fx_im_disp;
- #endif
- 
- 	  ri . r_length		= nbytes_r_length [fixP -> fx_size];
- 	  ri . r_pcrel		= fixP -> fx_pcrel;
- 	  ri . r_address	= fixP -> fx_frag -> fr_address
- 	    +   fixP -> fx_where
- 	      - segment_address_in_file;
- 	  if ((symbolP -> sy_type & N_TYPE) == N_UNDF)
- 	    {
- 	      ri . r_extern	= 1;
- 	      ri . r_symbolnum	= symbolP -> sy_number;
- 	    }
- 	  else
- 	    {
- 	      ri . r_extern	= 0;
- 	      ri . r_symbolnum	= symbolP -> sy_type & N_TYPE;
- 	    }
- 
- 	  /* 
- 	    The 68k machines assign bit-fields from higher bits to 
- 	    lower bits ("left-to-right") within the int.  VAXen assign 
- 	    bit-fields from lower bits to higher bits ("right-to-left").
- 	    Both handle multi-byte numbers in their usual fashion
- 	    (Big-endian and little-endian stuff).
- 	    Thus we need a machine dependent routine to make
- 	    sure the structure is written out correctly.  FUN!
- 	   */
- 	  md_ri_to_chars((char *) &ri, ri); 
- 	  append (&next_object_file_charP, (char *)& ri, (unsigned long)sizeof(ri));
- 	}
-     }
- 
- }
- #endif
  
  int
  is_dnrange(f1,f2)
--- 1437,1442 ----
*** write.h	Tue May 30 20:36:06 1989
--- /lasvegas/spare/usenet/port/gas-1.36/write.h	Wed Sep 12 09:29:10 1990
***************
*** 72,77 ****
--- 72,79 ----
  COMMON fixS *	data_fix_root;	/* Chains fixSs. */
  COMMON fixS **	seg_fix_rootP;	/* -> one of above. */
  
+ COMMON char *	next_object_file_charP;
+ 
  bit_fixS *bit_fix_new();
  /* end: write.h */
  
*** xmalloc.c	Wed Mar  1 23:48:34 1989
--- /lasvegas/spare/usenet/port/gas-1.36/xmalloc.c	Wed Sep 12 09:28:43 1990
***************
*** 43,48 ****
--- 43,50 ----
  #include <malloc.h>
  #endif
  
+ #define error as_fatal
+ 
  char * xmalloc(n)
       long n;
  {
*** xrealloc.c	Wed Mar  1 23:48:33 1989
--- /lasvegas/spare/usenet/port/gas-1.36/xrealloc.c	Wed Sep 12 09:28:43 1990
***************
*** 45,50 ****
--- 45,52 ----
  #include <malloc.h>
  #endif
  
+ #define error as_fatal
+ 
  char   *
  xrealloc (ptr, n)
  register char  *ptr;
--
Loic Dachary 	loic at adesign.uucp or loic at afp.uucp 
Voice		+33 1 40 35 20 20



More information about the Alt.sources mailing list