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

📄 read.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	input_line_pointer ++;	*end_name = 0;	if(name[0]=='.' && name[1]=='\0') {	  /* Turn '. = mumble' into a .org mumble */	  register segT segment;	  expressionS exp;	  register char *ptr;	  segment = get_known_segmented_expression(& exp);	  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;	  } /* if (ok to make frag) */	  *end_name = delim;	  return;	}	symbolP = symbol_find_or_make (name);	*end_name = delim;	pseudo_set (symbolP);	demand_empty_rest_of_line ();}voids_space(){	long int temp_repeat;	register long int temp_fill;	register char *p;	/* Just like .fill, but temp_size = 1 */	if ( get_absolute_expression_and_terminator( & temp_repeat) == ',' ) {		temp_fill = get_absolute_expression ();	} else {		input_line_pointer --; /* Backup over what was not a ','. */		temp_fill = 0;	}	if ( temp_repeat <= 0 ) {		as_warn("Repeat < 0, .space ignored");		ignore_rest_of_line();		return;	}	if ( ! need_pass_2 ) {		p = frag_var (rs_fill, 1, 1, (relax_substateT)0, (symbolS *)0, temp_repeat, (char *)0);		* p = temp_fill;	}	demand_empty_rest_of_line();}voids_text(){	register int temp;	temp = get_absolute_expression ();	subseg_new (SEG_TEXT, (subsegT)temp);	demand_empty_rest_of_line();}/*( JF was static, but can't be if machine dependent pseudo-ops are to use it */voiddemand_empty_rest_of_line(){  SKIP_WHITESPACE();  if ( is_end_of_line [* input_line_pointer] )    {      input_line_pointer ++;    }  else    {      ignore_rest_of_line();    }				/* Return having already swallowed end-of-line. */}				/* Return pointing just after end-of-line. */voidignore_rest_of_line()		/* For suspect lines: gives warning. */{  if ( ! is_end_of_line [* input_line_pointer])    {      as_warn("Rest of line ignored. 1st junk character valued %d (%c)."	      , * input_line_pointer, *input_line_pointer);      while (   input_line_pointer < buffer_limit	     && ! is_end_of_line [* input_line_pointer] )	{	  input_line_pointer ++;	}    }  input_line_pointer ++;	/* Return pointing just after end-of-line. */  know( is_end_of_line [input_line_pointer [-1]] );}/* *			stab() * * Handle .stabX directives, which used to be open-coded. * So much creeping featurism overloaded the semantics that we decided * to put all .stabX thinking in one place. Here. * * We try to make any .stabX directive legal. Other people's AS will often * do assembly-time consistency checks: eg assigning meaning to n_type bits * and "protecting" you from setting them to certain values. (They also zero * certain bits before emitting symbols. Tut tut.) * * If an expression is not absolute we either gripe or use the relocation * information. Other people's assemblers silently forget information they * don't need and invent information they need that you didn't supply. * * .stabX directives always make a symbol table entry. It may be junk if * the rest of your .stabX directive is malformed. */static voidstab (what)int what;{  register symbolS *	symbolP;  register char *	string;	   int		saved_type;  	   int		length;  	   int		goof;	/* TRUE if we have aborted. */	   long int	longint;/* * Enter with input_line_pointer pointing past .stabX and any following * whitespace. */	goof = FALSE; /* JF who forgot this?? */	if (what == 's') {		string = demand_copy_C_string (& length);		SKIP_WHITESPACE();		if (* input_line_pointer == ',')			input_line_pointer ++;		else {			as_warn( "I need a comma after symbol's name" );			goof = TRUE;		}	} else		string = "";/* * Input_line_pointer->after ','.  String -> symbol name. */	if (! goof) {		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;		case 'n':			symbolP->sy_frag = &zero_address_frag;			break;		case 's':			symbolP->sy_frag = & zero_address_frag;			break;		default:			BAD_CASE( what );			break;		}		if (get_absolute_expression_and_terminator (& longint) == ',')			symbolP->sy_type = saved_type = longint;		else {			as_warn( "I want a comma after the n_type expression" );			goof = TRUE;			input_line_pointer --; /* Backup over a non-',' char. */		}	}	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;			input_line_pointer --; /* Backup over a non-',' char. */		}	}	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" );				goof = TRUE;			} else {				input_line_pointer ++;			}		}	}	if ((! goof) && (what=='s' || what=='n')) {		pseudo_set (symbolP);		symbolP->sy_type = saved_type;	}	if (goof)		ignore_rest_of_line ();	else		demand_empty_rest_of_line ();}/* *			pseudo_set() * * In:	Pointer to a symbol. *	Input_line_pointer -> expression. * * Out:	Input_line_pointer -> just after any whitespace after expression. *	Tried to set symbol to value of expression. *	Will change sy_type, sy_value, sy_frag; *	May set need_pass_2 == TRUE. */static voidpseudo_set (symbolP)     symbolS *	symbolP;{  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" );      exp . X_seg		= SEG_ABSOLUTE;      exp . X_add_number	= 0;    }  switch (segment)    {    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)) {	if(exp.X_add_symbol->sy_frag != exp.X_subtract_symbol->sy_frag) {	  as_bad("Unknown expression: symbols %s and %s are in different frags.",exp.X_add_symbol->sy_name, exp.X_subtract_symbol->sy_name);	  need_pass_2++;	}	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;     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;          case SEG_PASS1:		/* Not an error. Just try another pass. */      symbolP->sy_forward=exp.X_add_symbol;      as_warn("Unknown expression");      know( need_pass_2 == TRUE );      break;          case SEG_UNKNOWN:      symbolP->sy_forward=exp.X_add_symbol;      /* as_warn("unknown symbol"); */      /* need_pass_2 = TRUE; */      break;          default:      BAD_CASE( segment );      break;    }}/* * stabs(file), stabf(func) and stabd(line) -- for the purpose of * source file debugging of assembly files, generate file, * function and line number stabs, respectively. * These functions have corresponding functions named * filestab(), funcstab() and linestab() in input-scrub.c, * where logical files and logical line numbers are handled. */#include <stab.h>stabs(file)     char *file;{  /* .stabs "file",100,0,0,. */  (void) symbol_new(file,		    N_SO,		    0,		    0,		    obstack_next_free(& frags) - frag_now->fr_literal,		    frag_now);}stabf(func)     char *func;{  symbolS *symbolP;  static int void_undefined = 1;  /* crudely filter uninteresting labels: require an initial '_' */  if (*func++ != '_')    return;  /* assembly functions are assumed to have void type */  if (void_undefined)    {      /* .stabs "void:t15=15",128,0,0,0 */      (void) symbol_new("void:t1=1",			N_LSYM,			0,			0,			0,			&zero_address_frag);      void_undefined = 0;    }  /* .stabs "func:F1",36,0,0,. */  symbolP = symbol_new((char *) 0,		       N_FUN,		       0,		       0,		       obstack_next_free(& frags) - frag_now->fr_literal,		       frag_now);  obstack_grow(&notes, func, strlen(func));  obstack_1grow(&notes, ':');  obstack_1grow(&notes, 'F');  obstack_1grow(&notes, '1');  obstack_1grow(&notes, '\0');  symbolP->sy_name = obstack_finish(&notes);}stabd(line)     unsigned line;{  /* .stabd 68,0,line */  (void) symbol_new((char *)0,		    N_SLINE,		    0,		    line,		    obstack_next_free(& frags) - frag_now->fr_literal,		    frag_now);}/* *			cons() * * CONStruct more frag of .bytes, or .words etc. * Should need_pass_2 be TRUE then emit no frag(s). * This understands EXPRESSIONS, as opposed to big_cons(). * * Bug (?) * * This has a split personality. We use expression() to read the * value. We can detect if the value won't fit in a byte or word. * But we can't detect if expression() discarded significant digits * in the case of a long. Not worth the crocks required to fix it. */voidcons(nbytes)			/* worker to do .byte etc statements */				/* clobbers input_line_pointer, checks */				/* end-of-line. */     register int	nbytes;	/* 1=.byte, 2=.word, 4=.long */{  register char		c;  register long int	mask;	/* High-order bits we will left-truncate, */				/* but includes sign bit also. */  register long int     get;	/* what we get */  register long int	use;	/* get after truncation. */  register long int	unmask;	/* what bits we will store */  register char *	p;  register segT		segment;           expressionS	exp;#ifdef NS32K  void fix_new_ns32k();#else  void	fix_new();#endif  /*   * Input_line_pointer -> 1st char after pseudo-op-code and could legally   * be a end-of-line. (Or, less legally an eof - which we cope with.)   */  /* JF << of >= number of bits in the object is undefined.  In particular     SPARC (Sun 4) has problems */  if(nbytes>=sizeof(long int))    mask = 0;  else     mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */  unmask = ~ mask;		/* Do store these bits. */#ifdef NEVER  "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";  mask = ~ (unmask >> 1);	/* Includes sign bit now. */#endif  /*   * The following awkward logic is to parse ZERO or more expressions,   * comma seperated. Recall an expression includes its leading &   * trailing blanks. We fake a leading ',' if there is (supposed to   * be) a 1st expression, and keep demanding 1 expression for each ','.   */  if (is_it_end_of_statement())    {      c = 0;			/* Skip loop. */      input_line_pointer ++;	/* Matches end-of-loop 'correction'. */    }  else      c = ',';			/* Do loop. */  while ( c == ','  )    {      segment = expression( &exp ); /* At least scan over the expression. */      if ( ! need_pass_2 )	{			/* Still worthwhile making frags. */	  /* Don't call this if we are going to junk this pass anyway! */	  know( segment != SEG_PASS1 );	  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. */	    }	  p = frag_more (nbytes);	  switch (segment)	    {	    case SEG_BIG:	      as_warn( "%s number illegal. Absolute 0 assumed.",		      exp . X_add_number > 0 ? "Bignum" : "Floating-Point");	      md_number_to_chars (p, (long)0, nbytes);	      break;	    case SEG_NONE:	      as_warn( "0 assumed for missing expression" );	      exp . X_add_number = 0;	      know( exp . X_add_symbol == NULL );	      /* fall into SEG_ABSOLUTE */	    case SEG_ABSOLUTE:	      get = exp . X_add_number;	      use = get & unmask;	      if ( (get & mask) && (get & mask) != mask )		{		/* Leading bits contain both 0s & 1s. */		  as_warn("Value x%x truncated to x%x.", get, use);		}	      md_number_to_chars (p, use, nbytes); /* put bytes in right order. */	      break;	    case SEG_DIFFERENCE:#ifndef WORKING_DOT_WORD	      if(nbytes==2) {		struct broken_word *x;		x=(struct broken_word *)xmalloc(sizeof(struct broken_word));		x->next_broken_word=broken_words;		broken_words=x;		x->frag=frag_now;		x->word_goes_here=p;		x->dispfrag=0;		x->add=exp.X_add_symbol;		x->sub=exp.X_subtract_symbol;		x->addnum=exp.X_add_number;		x->added=0;		new_broken_words++;		break;	      }	      /* Else Fall through into. . . */#endif	    case SEG_BSS:	    case SEG_UNKNOWN:	    case SEG_TEXT:	    case SEG_DATA:#if defined(SPARC) || defined(I860)	      fix_new (frag_now, p - frag_now -> fr_literal, nbytes,		       exp . X_add_symbol, exp . X_subtract_symbol,		       exp . X_add_number, 0, RELOC_32);#endif#ifdef NS32K	      fix_new_ns32k (frag_now, p - frag_now -> fr_literal, nbytes,		       exp . X_add_symbol, exp . X_subtract_symbol,		       exp . X_add_number, 0, 0, 2, 0, 0);#endif#if !defined(SPARC) && !defined(NS32K) && !defined(I860)	      fix_new (frag_now, p - frag_now -> fr_literal, nbytes,		       exp . X_add_symbol, exp . X_subtract_symbol,		       exp . X_add_number, 0);#endif	      break;	    default:	      BAD_CASE( segment );	      break;	    }			/* switch(segment) */	}			/* if(!need_pass_2) */      c = * input_line_pointer ++;    }				/* while(c==',') */  input_line_pointer --;	/* Put terminator back into stream. */  demand_empty_rest_of_line();}				/* cons() *//* *			big_cons() * * CONStruct more frag(s) of .quads, or .octa etc. * Makes 0 or more new frags. * If need_pass_2 == TRUE, generate no frag. * This understands only bignums, not expressions. Cons() understands * expressions. * * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal). * * This creates objects with struct obstack_control objs, destroying * any context objs held about a partially completed object. Beware! * * * I think it sucks to have 2 different types of integers, with 2 * routines to read them, store them etc. * It would be nicer to permit bignums in expressions and only * complain if the result overflowed. However, due to "efficiency"... */voidbig_cons(nbytes)		/* worker to do .quad etc statements */				/* clobbers input_line_pointer, checks */

⌨️ 快捷键说明

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