gas-1.36 patches for COFF generation

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


*** m68k.c	Wed May 16 16:47:44 1990
--- /lasvegas/spare/usenet/port/gas-1.36/m68k.c	Sat Oct 13 09:21:00 1990
***************
*** 22,27 ****
--- 22,28 ----
  #include <ctype.h>
  
  #include "m68k-opcode.h"
+ #include "oformat.h"
  #include "as.h"
  #include "obstack.h"
  #include "frags.h"
***************
*** 2669,2675 ****
    know(fragP->fr_symbol);
  
    /* The displacement of the address, from current location.  */
!   disp = (fragP->fr_symbol->sy_value + fragP->fr_offset) - object_address;
  
    switch(fragP->fr_subtype) {
    case TAB(BCC68000,BYTE):
--- 2670,2676 ----
    know(fragP->fr_symbol);
  
    /* The displacement of the address, from current location.  */
!   disp = (S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset) - object_address;
  
    switch(fragP->fr_subtype) {
    case TAB(BCC68000,BYTE):
***************
*** 2798,2804 ****
  	/* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
  	switch(fragP->fr_subtype) {
  	case TAB(DBCC,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(DBCC,SHORT);
  			fragP->fr_var+=2;
  			break;
--- 2799,2805 ----
  	/* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
  	switch(fragP->fr_subtype) {
  	case TAB(DBCC,SZ_UNDEF):
!                 if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(DBCC,SHORT);
  			fragP->fr_var+=2;
  			break;
***************
*** 2820,2826 ****
  		break;
  
  	case TAB(BCC68000,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(BCC68000,BYTE);
  			break;
  		}
--- 2821,2827 ----
  		break;
  
  	case TAB(BCC68000,SZ_UNDEF):
!                 if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(BCC68000,BYTE);
  			break;
  		}
***************
*** 2839,2845 ****
  		break;
  
  	case TAB(BRANCH,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
  			break;
  		} else if(flagseen['m']) {
--- 2840,2846 ----
  		break;
  
  	case TAB(BRANCH,SZ_UNDEF):
! 		if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
  			break;
  		} else if(flagseen['m']) {
***************
*** 2880,2886 ****
  	case TAB(BRANCH,BYTE):
  			/* We can't do a short jump to the next instruction,
  			   so we force word mode.  */
! 		if(fragP->fr_symbol && fragP->fr_symbol->sy_value==0 &&
   fragP->fr_symbol->sy_frag==fragP->fr_next) {
  			fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT);
  			fragP->fr_var+=2;
--- 2881,2887 ----
  	case TAB(BRANCH,BYTE):
  			/* We can't do a short jump to the next instruction,
  			   so we force word mode.  */
! 		if(fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 &&
   fragP->fr_symbol->sy_frag==fragP->fr_next) {
  			fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT);
  			fragP->fr_var+=2;
***************
*** 2887,2893 ****
  		}
  		break;
  	case TAB(FBRANCH,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(FBRANCH,SHORT);
  			fragP->fr_var+=2;
  		} else {
--- 2888,2894 ----
  		}
  		break;
  	case TAB(FBRANCH,SZ_UNDEF):
! 		if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(FBRANCH,SHORT);
  			fragP->fr_var+=2;
  		} else {
***************
*** 2896,2902 ****
  		}
  		break;
  	case TAB(PCREL,SZ_UNDEF):
! 		if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  			fragP->fr_subtype=TAB(PCREL,SHORT);
  			fragP->fr_var+=2;
  		} else {
--- 2897,2903 ----
  		}
  		break;
  	case TAB(PCREL,SZ_UNDEF):
! 		if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) {
  			fragP->fr_subtype=TAB(PCREL,SHORT);
  			fragP->fr_var+=2;
  		} else {
***************
*** 2910,2915 ****
--- 2911,2917 ----
  	return fragP->fr_var + fragP->fr_fix - old_fix;
  }
  
+ #ifdef aout
  /* the bit-field entries in the relocation_info struct plays hell 
     with the byte-order problems of cross-assembly.  So as a hack,
     I added this mach. dependent ri twiddler.  Ugly, but it gets
***************
*** 2935,2940 ****
--- 2937,2943 ----
    /* now put it back where you found it */
    bcopy (the_bytes, (char *)ri_p, sizeof(struct relocation_info));
  }
+ #endif /* aout */
  
  #ifndef WORKING_DOT_WORD
  int md_short_jump_size = 4;
*** read.c	Tue Mar  6 22:08:29 1990
--- /lasvegas/spare/usenet/port/gas-1.36/read.c	Mon Oct 15 11:31:29 1990
***************
*** 35,40 ****
--- 35,41 ----
  #include <ctype.h>
  #include <sys/types.h>
  #include <sys/stat.h>
+ #include "oformat.h"
  #include "as.h"
  #include "read.h"
  #include "md.h"
***************
*** 115,121 ****
--- 116,127 ----
  static int		is_it_end_of_statement();
  static void		pobegin();
  static void		pseudo_set();
+ #ifdef coff
+ static void		def();
+ static void		line();
+ #else /* coff */
  static void		stab();
+ #endif /* coff */
  static void		stringer();
  
  extern char line_comment_chars[];
***************
*** 131,136 ****
--- 137,149 ----
  static char *old_input;
  static char *old_limit;
  
+ #ifdef coff
+ static struct hash_control* tag_hash;
+ static void		    tag_init();
+ static void		    tag_insert();
+ static symbolS*		    tag_find();
+ #endif /* coff */
+ 
  #ifndef WORKING_DOT_WORD
  struct broken_word *broken_words;
  int new_broken_words = 0;
***************
*** 143,148 ****
--- 156,164 ----
  read_begin()
  {
    pobegin();
+ #ifdef coff
+   tag_init();
+ #endif /* coff */
    obstack_begin( &notes, 5000 );
  #define BIGNUM_BEGIN_SIZE (16)
    bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE);
***************
*** 155,162 ****
  po_hash = NULL;			/* use before set up: NULL-> address error */
  
  
  void	s_abort(),	s_align(),	s_comm(),	s_data();
! void	s_desc(),	s_even(),	s_file(),	s_fill();
  void	s_globl(),	s_lcomm(),	s_line(),	s_lsym();
  void	s_org(),	s_set(),	s_space(),	s_text();
  
--- 171,181 ----
  po_hash = NULL;			/* use before set up: NULL-> address error */
  
  
+ #ifdef aout
+ void s_desc();
+ #endif /* aout */
  void	s_abort(),	s_align(),	s_comm(),	s_data();
! void	s_even(),	s_file(),	s_fill();
  void	s_globl(),	s_lcomm(),	s_line(),	s_lsym();
  void	s_org(),	s_set(),	s_space(),	s_text();
  
***************
*** 181,187 ****
--- 200,208 ----
    { "byte",	cons,		1	},
    { "comm",	s_comm,		0	},
    { "data",	s_data,		0	},
+ #ifdef aout
    { "desc",	s_desc,		0	},
+ #endif /* aout */
    { "double",	float_cons,	'd'	},
    { "file",	s_file,		0	},
    { "fill",	s_fill,		0	},
***************
*** 207,215 ****
--- 228,241 ----
    { "short",	cons,		2	},
    { "single",	float_cons,	'f'	},
    { "space",	s_space,	0	},
+ #ifdef coff
+   { "def",	def,		0	},
+   { "ln",	line,		0	},
+ #else /* coff */
    { "stabd",	stab,		'd'	},
    { "stabn",	stab,		'n'	},
    { "stabs",	stab,		's'	},
+ #endif /* coff */
    { "text",	s_text,		0	},
  #ifndef SPARC
    { "word",	cons,		2	},
***************
*** 570,588 ****
  	*p = 0;
  	symbolP = symbol_find_or_make (name);
  	*p = c;
! 	if (   (symbolP -> sy_type & N_TYPE) != N_UNDF ||
!  symbolP -> sy_other != 0 || symbolP -> sy_desc != 0) {
  		as_warn( "Ignoring attempt to re-define symbol");
  		ignore_rest_of_line();
  		return;
  	}
! 	if (symbolP -> sy_value) {
! 		if (symbolP -> sy_value != temp)
  			as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.",
!  symbolP -> sy_name, symbolP -> sy_value, temp);
  	} else {
! 		symbolP -> sy_value = temp;
! 		symbolP -> sy_type |= N_EXT;
  	}
  	know( symbolP -> sy_frag == &zero_address_frag );
  	demand_empty_rest_of_line();
--- 596,619 ----
  	*p = 0;
  	symbolP = symbol_find_or_make (name);
  	*p = c;
! 	if (S_IS_DEFINED(symbolP) 
! #ifdef aout
! 	    || S_GET_OTHER(symbolP) != 0 || S_GET_DESC(symbolP) != 0
! #endif /* aout */
! 	    ) {
  		as_warn( "Ignoring attempt to re-define symbol");
  		ignore_rest_of_line();
  		return;
  	}
! 	if (S_GET_VALUE(symbolP)) {
! 		if (S_GET_VALUE(symbolP) != temp)
  			as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.",
! 				S_GET_NAME(symbolP),
! 				S_GET_VALUE(symbolP),
! 				temp);
  	} else {
! 		S_SET_VALUE(symbolP, temp);
! 		S_SET_EXTERNAL(symbolP);
  	}
  	know( symbolP -> sy_frag == &zero_address_frag );
  	demand_empty_rest_of_line();
***************
*** 598,603 ****
--- 629,635 ----
  	demand_empty_rest_of_line();
  }
  
+ #ifdef aout
  void
  s_desc()
  {
***************
*** 627,648 ****
  		*p = 0;
  		symbolP = symbol_find_or_make (name);
  		*p = c;
! 		symbolP -> sy_desc = temp;
  	}
  	demand_empty_rest_of_line();
  }
  
  void
  s_file()
  {
! 	register char *s;
! 	int	length;
! 
! 	/* Some assemblers tolerate immediately following '"' */
! 	if ( s = demand_copy_string( & length ) ) {
! 		new_logical_line (s, -1);
! 		demand_empty_rest_of_line();
! 	}
  }
  
  void
--- 659,684 ----
  		*p = 0;
  		symbolP = symbol_find_or_make (name);
  		*p = c;
! 		S_SET_DESC(symbolP,temp);
  	}
  	demand_empty_rest_of_line();
  }
+ #endif /* aout */
  
  void
  s_file()
  {
!     register char *s;
!     int	length;
!     
!     /* Some assemblers tolerate immediately following '"' */
!     if ( s = demand_copy_string( & length ) ) {
! 	new_logical_line (s, -1);
! 	demand_empty_rest_of_line();
!     }
! #ifdef coff
!     c_dot_file_symbol(s);
! #endif /* coff */
  }
  
  void
***************
*** 825,831 ****
  		symbolP = symbol_find_or_make (name);
  		* input_line_pointer = c;
  		SKIP_WHITESPACE();
! 		symbolP -> sy_type |= N_EXT;
  		if(c==',') {
  			input_line_pointer++;
  			SKIP_WHITESPACE();
--- 861,867 ----
  		symbolP = symbol_find_or_make (name);
  		* input_line_pointer = c;
  		SKIP_WHITESPACE();
! 		S_SET_EXTERNAL(symbolP);
  		if(c==',') {
  			input_line_pointer++;
  			SKIP_WHITESPACE();
***************
*** 864,882 ****
  	*p = 0;
  	symbolP = symbol_find_or_make (name);
  	*p = c;
! 	if (   symbolP -> sy_other == 0
! 	    && symbolP -> sy_desc  == 0
! 	    && (   (   symbolP -> sy_type  == N_BSS
! 	    && symbolP -> sy_value == local_bss_counter)
! 	    || (   (symbolP -> sy_type & N_TYPE) == N_UNDF
! 	    && symbolP -> sy_value == 0))) {
! 		symbolP -> sy_value = local_bss_counter;
! 		symbolP -> sy_type  = N_BSS;
  		symbolP -> sy_frag  = & bss_address_frag;
  		local_bss_counter += temp;
  	} else
  		as_warn( "Ignoring attempt to re-define symbol from %d. to %d.",
!  symbolP -> sy_value, local_bss_counter );
  	demand_empty_rest_of_line();
  }
  
--- 900,926 ----
  	*p = 0;
  	symbolP = symbol_find_or_make (name);
  	*p = c;
! 	if (
! #ifdef aout
! 	    S_GET_OTHER(symbolP) == 0 &&
! 	    S_GET_DESC(symbolP)  == 0 &&
! #endif /* aout */  
! 	    (S_IS_BSS(symbolP) && S_GET_VALUE(symbolP) == local_bss_counter)
! /* What S_GET_VALUE(symbolP) == 0 is supposed to mean (in aout case) ? 
!    In the coff case it clearly does not mean anything (the only case
!    where a symbol is not defined is from an external declaration (extern a)
!    and this kind of symbol have a 0 value. */
! 	    || (!S_IS_DEFINED(symbolP) && S_GET_VALUE(symbolP) == 0)) {
! 		S_SET_VALUE(symbolP,local_bss_counter);
! 		S_SET_BSS(symbolP);
! #ifdef coff
! 		S_SET_STORAGE_CLASS(symbolP, C_STAT);
! #endif /* coff */
  		symbolP -> sy_frag  = & bss_address_frag;
  		local_bss_counter += temp;
  	} else
  		as_warn( "Ignoring attempt to re-define symbol from %d. to %d.",
!  S_GET_VALUE(symbolP), local_bss_counter );
  	demand_empty_rest_of_line();
  }
  
***************
*** 929,942 ****
  	segment = expression (& exp);
  	if (   segment != SEG_ABSOLUTE && segment != SEG_DATA &&
   segment != SEG_TEXT && segment != SEG_BSS) {
! 		as_warn("Bad expression: %s", seg_name [(int)segment]);
  		ignore_rest_of_line();
  		return;
  	}
   know(   segment == SEG_ABSOLUTE || segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS );
  	*p = 0;
! 	symbolP = symbol_new (name,(unsigned char)(seg_N_TYPE [(int) segment]),
   0, 0, (valueT)(exp . X_add_number), & zero_address_frag);
  	*p = c;
  	demand_empty_rest_of_line();
  }
--- 973,991 ----
  	segment = expression (& exp);
  	if (   segment != SEG_ABSOLUTE && segment != SEG_DATA &&
   segment != SEG_TEXT && segment != SEG_BSS) {
! 		as_warn("Bad expression: %s", segment_name((int)segment));
  		ignore_rest_of_line();
  		return;
  	}
   know(   segment == SEG_ABSOLUTE || segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS );
  	*p = 0;
! #ifdef coff
! 	symbolP = symbol_new(name, segment, (valueT)(exp . X_add_number),
! 			     0, &zero_address_frag);
! #else /* coff */
! 	symbolP = symbol_new (name,(unsigned char)(seg_SEG((int) segment)),
   0, 0, (valueT)(exp . X_add_number), & zero_address_frag);
+ #endif /* coff */
  	*p = c;
  	demand_empty_rest_of_line();
  }
***************
*** 972,978 ****
  	if ( ! need_pass_2 ) {
  		if (segment != now_seg && segment != SEG_ABSOLUTE)
  			as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
!  seg_name [(int) segment], seg_name [(int) now_seg]);
  		p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol,
   exp . X_add_number, (char *)0);
  		* p = temp_fill;
--- 1021,1027 ----
  	if ( ! need_pass_2 ) {
  		if (segment != now_seg && segment != SEG_ABSOLUTE)
  			as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
!  segment_name((int) segment), segment_name((int) now_seg));
  		p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol,
   exp . X_add_number, (char *)0);
  		* p = temp_fill;
***************
*** 1017,1023 ****
  	  if ( ! need_pass_2 ) {
  	    if (segment != now_seg && segment != SEG_ABSOLUTE)
  	      as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
! 		      seg_name [(int) segment], seg_name [(int) now_seg]);
  	    ptr = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
  			  exp.X_add_number, (char *)0);
  	    *ptr= 0;
--- 1066,1073 ----
  	  if ( ! need_pass_2 ) {
  	    if (segment != now_seg && segment != SEG_ABSOLUTE)
  	      as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
! 		      segment_name((int) segment),
! 		      segment_name((int) now_seg));
  	    ptr = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
  			  exp.X_add_number, (char *)0);
  	    *ptr= 0;
***************
*** 1104,1109 ****
--- 1154,1476 ----
    know( is_end_of_line [input_line_pointer [-1]] );
  }
  
+ #ifdef coff
+ /*
+  * Handle .ln directives.
+  */
+ 
+ static void
+ line(what)
+ int what;
+ {
+     c_line_new(obstack_next_free(&frags) - frag_now->fr_literal,
+ 	       get_absolute_expression(),
+ 	       frag_now);
+     demand_empty_rest_of_line();
+ 
+     return;
+ }
+ /*
+  *			def()
+  *
+  * Handle .def directives.
+  *
+  * One would say : why can't we symbol_new if the symbol does not
+  * allready exists 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++;
+ 
+ #define NEXT_DEF_DIRECTIVE() 	SKIP_SEMI_COLON(); SKIP_WHITESPACES()
+ #define equal			!strcmp
+ #define MAX_DIRECTIVE		20
+ 
+ static void
+ def(what)
+ int what;
+ {
+     char	name_end;		/* Char after the end of name */
+     symbolS*	symbolP;		/* Debug symbol just created */
+     symbolS	symbol;			/* Temporary symbol to hold .def */
+     char*	symbol_name;		/* Name of the debug symbol */
+     char*	symbol_name_copy;	/* Temporary copy of the name */
+     unsigned int symbol_name_length;	/* */
+     char*	directiveP;		/* Name of the pseudo opcode */
+     char	directive[MAX_DIRECTIVE]; /* Backup of the directive */
+     char	end = 0;		/* If 1, stop parsing */
+     
+     SKIP_WHITESPACES();
+ 
+     symbolP = &symbol;
+     memset((char*)symbolP, '\0', sizeof(symbolS));
+ 
+     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);
+     
+     /* Initialize the new symbol */
+ #if STRIP_UNDERSCORE
+     S_SET_NAME(symbolP, *symbol_name_copy == '_' ? symbol_name_copy + 1 :
+ 	                                           symbol_name_copy);
+ #else /* STRIP_UNDERSCORE */
+     S_SET_NAME(symbolP, symbol_name_copy);
+ #endif /* STRIP_UNDERSCORE */
+     symbolP->sy_name_offset = ~0;
+     symbolP->sy_number = ~0;
+     symbolP->sy_frag = &zero_address_frag;
+     if(S_IS_STRING(symbolP))
+ 	SF_SET_STRING(symbolP);
+ 
+     *input_line_pointer = name_end;
+ 
+     while(!end) {
+ 	NEXT_DEF_DIRECTIVE();
+ 	directiveP = input_line_pointer;
+ 	name_end = get_symbol_end();
+ 	strncpy(directive, directiveP, MAX_DIRECTIVE);
+ 	*input_line_pointer = name_end;
+ 	SKIP_WHITESPACES();
+ 	switch(directive[1]) {
+ 	  case 'd':
+ 	    if(equal(directive, ".dim")) {
+ 		register int dim_index;
+ 		register int dimension;
+ 
+ 		S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ 		for(dim_index = 0; dim_index < DIMNUM; dim_index++) {
+ 		    SKIP_WHITESPACES();
+ 		    SA_SET_SYM_DIMEN(symbolP, dim_index,
+ 				     get_absolute_expression());
+ 		    switch(*input_line_pointer) {
+ 		      case ',':
+ 			input_line_pointer++;
+ 			break;
+ 		      default:
+ 			as_warn("badly formed .dim directive");
+ 		      case ';':
+ 			dim_index = DIMNUM;
+ 			break;
+ 		    }
+ 		}
+ 	    } else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 'e':
+ 	    if(equal(directive, ".endef"))
+ 		end = 1;
+ 	    else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 'l':
+ 	    if(equal(directive, ".line")) {
+ 		S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ 		SA_SET_SYM_LNNO(symbolP, get_absolute_expression());
+ 	    } else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 's':
+ 	    if(equal(directive, ".size")) {
+ 		S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ 		SA_SET_SYM_SIZE(symbolP, get_absolute_expression());
+ 	    } else if(equal(directive, ".scl"))
+ 		S_SET_STORAGE_CLASS(symbolP, get_absolute_expression());
+ 	    else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 't':
+ 	    if(equal(directive, ".tag")) {
+ 		symbolS * tag_symbolP;
+ 
+ 		S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ 		symbol_name = input_line_pointer;
+ 		name_end = get_symbol_end();
+ 		/* Assume that the symbol referred to by .tag is 
+ 		   always defined. */
+ 		SA_SET_SYM_TAGNDX(symbolP, (long)tag_find(symbol_name));
+ 		if(SA_GET_SYM_TAGNDX(symbolP) == 0L)
+ 		    as_warn("tag not found for .tag %s", symbol_name);
+ 		SF_SET_TAGGED(symbolP);
+ 		*input_line_pointer = name_end;
+ 	    } else if(equal(directive, ".type")) {
+ 		S_SET_DATA_TYPE(symbolP, get_absolute_expression());
+ 		if(ISFCN(S_GET_DATA_TYPE(symbolP)) &&
+ 		   S_GET_STORAGE_CLASS(symbolP) != C_TPDEF)
+ 		    SF_SET_FUNCTION(symbolP);
+ 	    } else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  case 'v':
+ 	    if(equal(directive, ".val")) {
+ 		if(is_name_beginner(*input_line_pointer)) {
+ 		    symbol_name = input_line_pointer;
+ 		    name_end = get_symbol_end();
+ 		    if(equal(symbol_name, ".")) {
+ 			symbolP->sy_frag = frag_now;
+ 			S_SET_VALUE(symbolP, obstack_next_free(&frags) -
+ 				             frag_now->fr_literal);
+ 			/* If the .val is != from the .def (i.e. statics) */
+ 		    } else if(strcmp(symbol_name_copy, symbol_name)) {
+ 			register symbolS* forwardP;
+ 			if(forwardP = symbol_find(symbol_name))
+ 			    symbolP->sy_forward = forwardP;
+ 			else
+ 			    /* Create a new undefined symbol. */
+ 			    symbolP->sy_forward =
+ 				symbol_new (symbol_name, SEG_UNKNOWN,
+ 					    0, 0, &zero_address_frag);
+ 		    }
+ 		    /* Otherwise, it is the name of a non debug symbol and its
+ 		       value will be calculated later. */
+ 		    *input_line_pointer = name_end;
+ 		} else
+ 		    S_SET_VALUE(symbolP, get_absolute_expression());
+ 	    } else
+ 		as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	  default:
+ 	    as_warn("unknown debug directive : %s", directive);
+ 	    break;
+ 	}
+     }
+     demand_empty_rest_of_line();
+ 
+     /* Set the section number according to storage class. */
+     switch(S_GET_STORAGE_CLASS(symbolP)) {
+       case C_STRTAG: case C_ENTAG: case C_UNTAG:
+ 	SF_SET_TAG(symbolP);
+       case C_FILE:
+       case C_TPDEF:
+ 	SF_SET_DEBUG(symbolP);
+ 	S_SET_SEGMENT(symbolP, C_DEBUG_SECTION);
+ 	break;
+       case C_EFCN:
+ 	SF_SET_LOCAL(symbolP);   /* Do not emit this symbol. */
+       case C_BLOCK:
+ 	SF_SET_PROCESS(symbolP); /* Will need processing before writing */
+       case C_FCN:
+ 	S_SET_SEGMENT(symbolP, C_TEXT_SECTION);
+ 	break;
+       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(symbolP);
+ 	S_SET_SEGMENT(symbolP, C_ABS_SECTION);
+ 	break;
+       case C_EXT:
+       case C_STAT:
+ 	/* Valid but set somewhere else (s_comm, s_lcomm, colon) */
+ 	break;
+       case C_USTATIC:
+       case C_EXTDEF:
+       case C_LABEL:
+       case C_ULABEL:
+ 	as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(symbolP));
+ 	break;
+     }
+     /* Now that we have build up a debug symbol, try to find if we should
+        merge with an existing symbol or not. */
+     /* If symbol does not exist, or symbol is a end function mark,
+        or symbol is in debug or abs section,
+        insert it in the list of symbols. */
+     if(S_GET_STORAGE_CLASS(symbolP) == C_EFCN ||
+        S_GET_SEGMENT(symbolP) == C_DEBUG_SECTION ||
+        S_GET_SEGMENT(symbolP) == C_ABS_SECTION ||
+        (symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP)) ==
+ 	(symbolS*)0) {
+ 
+ 	symbolP = (symbolS *)obstack_alloc(&notes, sizeof(symbolS));
+ 	memcpy((char*)symbolP, &symbol, sizeof(symbolS));
+ 
+ 	symbol_lastP->sy_next = symbolP;
+ 	symbolP->sy_previous = symbol_lastP;
+ 	symbol_lastP = symbolP;
+ 
+     } else {
+ 	/* This symbol allready exists, merge the newly created symbol into
+ 	   the old one. This is not mandatory. The linker can handle
+ 	   duplicate symbols correctly. But I guess that it save a *lot*
+ 	   of space if the assembly file defines a lot of symbols. */
+ 	/* The debug entry (symbol) is merged into symbolP. */
+ 	c_symbol_merge(&symbol, symbolP);
+ 	/* For the function, the symbol *must* be were the debug symbol
+ 	   appear. Move the existing symbol to the current place. */
+ 	/* Do not take in account special cases where symbolP is first 
+ 	   in the list. It is always after a .bf */
+ 	if(SF_GET_FUNCTION(symbolP)) {
+ 	    /* If it already is at the end of the symbol list, do nothing */
+ 	    if(symbolP != symbol_lastP) {
+ 		/* Remove from the list */
+ 		symbolP->sy_next->sy_previous = symbolP->sy_previous;
+ 		symbolP->sy_previous->sy_next = symbolP->sy_next;
+ 		/* Append at the end of the list */
+ 		symbol_lastP->sy_next = symbolP;
+ 		symbolP->sy_previous = symbol_lastP;
+ 		symbol_lastP = symbolP;
+ 	    }
+ 	} else
+ 	    free(symbol_name_copy);
+     }
+     
+     /* If symbol is a {structure,union} tag, associate symbol to its name. */
+     if(SF_GET_TAG(symbolP))
+ 	tag_insert(S_GET_NAME(symbolP), symbolP);
+ 
+     /* Create the line number entry pointing on the function being defined */
+     if(SF_GET_FUNCTION(symbolP)) {
+ 	c_line_new((long)S_GET_NAME(symbolP), 0, &zero_address_frag);
+ 	SF_SET_PROCESS(symbolP);
+     }
+ }
+ 
+ /* 
+  *  Maintain a list of the tagnames of the structres.
+  */
+ 
+ static void
+ tag_init()
+ {
+     tag_hash = hash_new();
+     return ;
+ }
+ 
+ static void
+ tag_insert(name, symbolP)
+ char* name;
+ symbolS* symbolP;
+ {
+     register char *	error_string;
+ 
+     if(*(error_string = hash_jam (tag_hash, name, (char *)symbolP))) {
+ 	as_fatal("Inserting \"%s\" into structure table failed: %s",
+ 		 name, error_string);
+     }
+     return ;
+ }
+ 
+ static symbolS*
+ tag_find(name)
+ char* name;
+ {
+ #if STRIP_UNDERSCORE
+     if(*name == '_') name++;
+ #endif /* STRIP_UNDERSCORE */
+     return((symbolS*)hash_find(tag_hash, name));
+ }
+ #else /* coff */
  /*
   *			stab()
   *
***************
*** 1158,1165 ****
  		symbolP = symbol_new (string, 0,0,0,0,(struct frag *)0);
  		switch (what) {
  		case 'd':
! 			symbolP->sy_name = NULL; /* .stabd feature. */
! 			symbolP->sy_value = obstack_next_free(& frags) - frag_now->fr_literal;
  			symbolP->sy_frag = frag_now;
  			break;
  
--- 1525,1533 ----
  		symbolP = symbol_new (string, 0,0,0,0,(struct frag *)0);
  		switch (what) {
  		case 'd':
! 			S_SET_NAME(symbolP,NULL); /* .stabd feature. */
! 			S_SET_VALUE(symbolP,obstack_next_free(&frags) - 
! 				    frag_now->fr_literal);
  			symbolP->sy_frag = frag_now;
  			break;
  
***************
*** 1185,1191 ****
  	}
  	if (! goof) {
  		if (get_absolute_expression_and_terminator (& longint) == ',')
! 			symbolP->sy_other = longint;
  		else {
  			as_warn( "I want a comma after the n_other expression" );
  			goof = TRUE;
--- 1553,1559 ----
  	}
  	if (! goof) {
  		if (get_absolute_expression_and_terminator (& longint) == ',')
! 			S_SET_OTHER(symbolP,longint);
  		else {
  			as_warn( "I want a comma after the n_other expression" );
  			goof = TRUE;
***************
*** 1193,1199 ****
  		}
  	}
  	if (! goof) {
! 		symbolP->sy_desc = get_absolute_expression ();
  		if (what == 's' || what == 'n') {
  			if (* input_line_pointer != ',') {
  				as_warn( "I want a comma after the n_desc expression" );
--- 1561,1567 ----
  		}
  	}
  	if (! goof) {
! 		S_SET_DESC(symbolP, get_absolute_expression ());
  		if (what == 's' || what == 'n') {
  			if (* input_line_pointer != ',') {
  				as_warn( "I want a comma after the n_desc expression" );
***************
*** 1212,1217 ****
--- 1580,1586 ----
  	else
  		demand_empty_rest_of_line ();
  }
+ #endif /* coff */
  
  /*
   *			pseudo_set()
***************
*** 1230,1239 ****
  {
    expressionS	exp;
    register segT	segment;
    int ext;
  
    know( symbolP );		/* NULL pointer is logic error. */
!   ext=(symbolP->sy_type&N_EXT);
    if ((segment = expression( & exp )) == SEG_NONE)
      {
        as_warn( "Missing expression: absolute 0 assumed" );
--- 1599,1612 ----
  {
    expressionS	exp;
    register segT	segment;
+ #ifdef aout
    int ext;
+ #endif /* aout */
  
    know( symbolP );		/* NULL pointer is logic error. */
! #ifdef aout
!   ext=S_IS_EXTERNAL(symbolP);
! #endif /* aout */
    if ((segment = expression( & exp )) == SEG_NONE)
      {
        as_warn( "Missing expression: absolute 0 assumed" );
***************
*** 1245,1272 ****
      case SEG_BIG:
        as_warn( "%s number illegal. Absolute 0 assumed.",
  	      exp . X_add_number > 0 ? "Bignum" : "Floating-Point" );
!       symbolP -> sy_type = N_ABS | ext;
!       symbolP -> sy_value = 0;
        symbolP -> sy_frag = & zero_address_frag;
        break;
  
      case SEG_NONE:
        as_warn("No expression:  Using absolute 0");
!       symbolP -> sy_type = N_ABS | ext;
!       symbolP -> sy_value = 0;
        symbolP -> sy_frag = & zero_address_frag;
        break;
  
      case SEG_DIFFERENCE:
        if (exp.X_add_symbol && exp.X_subtract_symbol
!           &&    (exp.X_add_symbol->sy_type & N_TYPE)
! 	     == (exp.X_subtract_symbol->sy_type & N_TYPE))
  	exp.X_add_number+=exp.X_add_symbol->sy_value - exp.X_subtract_symbol->sy_value;
        else
  	as_warn( "Complex expression. Absolute segment assumed." );
      case SEG_ABSOLUTE:
!       symbolP -> sy_type = N_ABS | ext;
!       symbolP -> sy_value = exp . X_add_number;
        symbolP -> sy_frag = & zero_address_frag;
        break;
   
--- 1618,1657 ----
      case SEG_BIG:
        as_warn( "%s number illegal. Absolute 0 assumed.",
  	      exp . X_add_number > 0 ? "Bignum" : "Floating-Point" );
!       S_SET_ABS(symbolP); 
! #ifdef aout
!       ext ? S_SET_EXTERNAL(symbolP) : 
! 	    S_CLEAR_EXTERNAL(symbolP);
! #endif /* aout */
!       S_SET_VALUE(symbolP, 0);
        symbolP -> sy_frag = & zero_address_frag;
        break;
  
      case SEG_NONE:
        as_warn("No expression:  Using absolute 0");
!       S_SET_ABS(symbolP); 
! #ifdef aout
!       ext ? S_SET_EXTERNAL(symbolP) : 
! 	    S_CLEAR_EXTERNAL(symbolP);
! #endif /* aout */
!       S_SET_VALUE(symbolP, 0);
        symbolP -> sy_frag = & zero_address_frag;
        break;
  
      case SEG_DIFFERENCE:
        if (exp.X_add_symbol && exp.X_subtract_symbol
!           && (S_GET_SEGMENT(exp.X_add_symbol) ==
! 	      S_GET_SEGMENT(exp.X_subtract_symbol)))
  	exp.X_add_number+=exp.X_add_symbol->sy_value - exp.X_subtract_symbol->sy_value;
        else
  	as_warn( "Complex expression. Absolute segment assumed." );
      case SEG_ABSOLUTE:
!       S_SET_ABS(symbolP); 
! #ifdef aout
!       ext ? S_SET_EXTERNAL(symbolP) : 
! 	    S_CLEAR_EXTERNAL(symbolP);
! #endif /* aout */
!       S_SET_VALUE(symbolP, exp.X_add_number);
        symbolP -> sy_frag = & zero_address_frag;
        break;
   
***************
*** 1273,1280 ****
      case SEG_DATA:
      case SEG_TEXT:
      case SEG_BSS:
!       symbolP -> sy_type = seg_N_TYPE [(int) segment] | ext;
!       symbolP -> sy_value= exp . X_add_number + exp . X_add_symbol -> sy_value;
        symbolP -> sy_frag = exp . X_add_symbol -> sy_frag;
        break;
        
--- 1658,1673 ----
      case SEG_DATA:
      case SEG_TEXT:
      case SEG_BSS:
!       switch(segment) {
! 	case SEG_DATA:	  S_SET_DATA(symbolP); break;
! 	case SEG_TEXT:	  S_SET_TEXT(symbolP); break;
! 	case SEG_BSS:	  S_SET_BSS(symbolP); break;
!       }
! #ifdef aout
!       ext ? S_SET_EXTERNAL(symbolP) : 
! 	    S_CLEAR_EXTERNAL(symbolP);
! #endif /* aout */
!       S_SET_VALUE(symbolP, exp.X_add_number + S_GET_VALUE(exp.X_add_symbol));
        symbolP -> sy_frag = exp . X_add_symbol -> sy_frag;
        break;
        
***************
*** 1371,1378 ****
  	  if ( segment == SEG_DIFFERENCE && exp . X_add_symbol == NULL )
  	    {
  	      as_warn( "Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
! 		      exp . X_subtract_symbol -> sy_name,
! 		      seg_name [(int) N_TYPE_seg [exp . X_subtract_symbol -> sy_type & N_TYPE]]);
  	      segment = SEG_ABSOLUTE;
  	      /* Leave exp . X_add_number alone. */
  	    }
--- 1764,1771 ----
  	  if ( segment == SEG_DIFFERENCE && exp . X_add_symbol == NULL )
  	    {
  	      as_warn( "Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
! 		 S_GET_NAME(exp.X_subtract_symbol),
! 	         segment_name((int)SEG_seg(S_GET_SEGMENT(exp.X_subtract_symbol))));
  	      segment = SEG_ABSOLUTE;
  	      /* Leave exp . X_add_number alone. */
  	    }
***************
*** 1853,1860 ****
    if (   (retval = get_segmented_expression (expP)) == SEG_UNKNOWN
        )
      {
!       name1 = expP -> X_add_symbol ? expP -> X_add_symbol -> sy_name : "";
!       name2 = expP -> X_subtract_symbol ? expP -> X_subtract_symbol -> sy_name : "";
        if ( name1 && name2 )
  	{
  	  as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
--- 2246,2255 ----
    if (   (retval = get_segmented_expression (expP)) == SEG_UNKNOWN
        )
      {
!       name1 = expP->X_add_symbol ? S_GET_NAME(expP->X_add_symbol) : "";
!       name2 = expP->X_subtract_symbol ?
! 	      S_GET_NAME(expP->X_subtract_symbol) :
! 		  "";
        if ( name1 && name2 )
  	{
  	  as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
***************
*** 1988,1994 ****
  equals(sym_name)
  char *sym_name;
  {
!   register struct symbol * symbolP; /* symbol we are working with */
  
    if(sym_name[0]=='.' && sym_name[1]=='\0') {
      /* Turn '. = mumble' into a .org mumble */
--- 2383,2389 ----
  equals(sym_name)
  char *sym_name;
  {
!   register symbolS * symbolP; /* symbol we are working with */
  
    if(sym_name[0]=='.' && sym_name[1]=='\0') {
      /* Turn '. = mumble' into a .org mumble */
***************
*** 2006,2012 ****
      if ( ! need_pass_2 ) {
        if (segment != now_seg && segment != SEG_ABSOLUTE)
          as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
!                 seg_name [(int) segment], seg_name [(int) now_seg]);
        p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
                      exp.X_add_number, (char *)0);
        * p = 0;
--- 2401,2408 ----
      if ( ! need_pass_2 ) {
        if (segment != now_seg && segment != SEG_ABSOLUTE)
          as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
!                 segment_name((int) segment),
! 		segment_name((int) now_seg));
        p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
                      exp.X_add_number, (char *)0);
        * p = 0;
--
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