📄 asparse.c
字号:
case ILONG: curlen = NBPW; goto elist; elist: seg_type = val; shift; /* * Expression List processing */ if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ do{ /* * expression list consists of a list of : * <expr> * <expr> : <expr> * (pack expr2 into expr1 bits */ expr(locxp, val); /* * now, pointing at the next token */ if (val == COLON){ shiftover(COLON); expr(pval, val); if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ yyerror("Width not absolute"); field_width = locxp->e_xvalue; locxp = pval; if (bitoff + field_width > curlen) flushfield(curlen); if (field_width > curlen) yyerror("Expression crosses field boundary"); } else { field_width = curlen; flushfield(curlen); } if ((locxp->e_xtype & XTYPE) != XABS) { if (bitoff) yyerror("Illegal relocation in field"); switch(curlen){ case NBPW/4: reloc_how = TYPB; break; case NBPW/2: reloc_how = TYPW; break; case NBPW: reloc_how = TYPL; break; } if (passno == 1){ dotp->e_xvalue += ty_nbyte[reloc_how]; } else { outrel(locxp, reloc_how); } } else { /* * * See if we are doing a case instruction. * If so, then see if the branch distance, * stored as a word, * is going to loose sig bits. */ if (passno == 2 && incasetable){ if ( (locxp->e_xvalue < -32768) ||(locxp->e_xvalue > 32767)){ yyerror("Case will branch too far: try -bswitch flag"); } } field_value = locxp->e_xvalue & ( (1L << field_width)-1); bitfield |= field_value << bitoff; bitoff += field_width; } xp = explist; if (auxval = (val == CM)) shift; } while (auxval); } /* there existed an expression at all */ flushfield(curlen); if ( ( curlen == NBPW/4) && bitoff) dotp->e_xvalue ++; break; /*end of case IBYTE, IWORD, ILONG, IINT*/ case ISPACE: /* .space <expr> */ shift; expr(locxp, val); if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ yyerror("Space size not absolute"); space_value = locxp->e_xvalue; if (space_value < 0) /* jlr005 */ yyerror("Space size negative"); ospace: flushfield(NBPW/4); { static char spacebuf[128]; while (space_value > sizeof(spacebuf)){ outs(spacebuf, sizeof(spacebuf)); space_value -= sizeof(spacebuf); } outs(spacebuf, space_value); } break; /* * .fill rep, size, value * repeat rep times: fill size bytes with (truncated) value * size must be between 1 and 8 */ case IFILL: shift; expr(locxp, val); if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ yyerror("Fill repetition count not absolute"); fill_rep = locxp->e_xvalue; shiftover(CM); expr(locxp, val); if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ yyerror("Fill size not absolute"); fill_size = locxp->e_xvalue; if (fill_size <= 0 || fill_size > 8) yyerror("Fill count not in in 1..8"); shiftover(CM); expr(locxp, val); if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ yyerror("Fill value not absolute"); flushfield(NBPW/4); /*RAP001 Update the location counter on both passes. Used to do it only for pass 1, causing a relocation problem. Whoever may have thought bwrite did update it (like Outb, outs, ..) but it doesn't, so it has to be done here. */ dotp->e_xvalue += fill_rep * fill_size; if (passno == 2) { while(fill_rep-- > 0) bwrite((char *)&locxp->e_xvalue, fill_size, txtfil); } break; case IASCII: /* .ascii [ <stringlist> ] */ case IASCIZ: /* .asciz [ <stringlist> ] */ auxval = val; shift; /* * Code to consume a string list * * stringlist: empty | STRING | stringlist STRING */ while (val == STRING){ int mystrlen; flushfield(NBPW/4); if (bitoff) dotp->e_xvalue++; stringp = (struct strdesc *)yylval; /* * utilize the string scanner cheat; * the scanner appended a null byte on the string, * but didn't charge it to sd_strlen */ mystrlen = stringp->sd_strlen; mystrlen += (auxval == IASCIZ) ? 1 : 0; if (passno == 2){ if (stringp->sd_place & STR_CORE){ outs(stringp->sd_string, mystrlen); } else { int i, nread; fseek(strfile, stringp->sd_stroff, 0); for (i = 0; i < mystrlen;/*VOID*/){ nread = fread(yytext, 1, min(mystrlen - i, sizeof(yytext)), strfile); outs(yytext, nread); i += nread; } } } else { dotp->e_xvalue += mystrlen; } shift; /*over the STRING*/ if (val == CM) /*could be a split string*/ shift; } break; case IORG: /* .org <expr> */ shift; expr(locxp, val); if ((locxp->e_xtype & XTYPE) == XABS) /* tekmdp */ orgwarn++; else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype) yyerror("Illegal expression to set origin"); space_value = locxp->e_xvalue - dotp->e_xvalue; if (space_value < 0) yyerror("Backwards 'org'"); goto ospace; break;/* * * Process stabs. Stabs are created only by the f77 * and the C compiler with the -g flag set. * We only look at the stab ONCE, during pass 1, and * virtually remove the stab from the intermediate file * so it isn't seen during pass2. This makes for some * hairy processing to handle labels occuring in * stab entries, but since most expressions in the * stab are integral we save lots of time in the second * pass by not looking at the stabs. * A stab that is tagged floating will be bumped during * the jxxx resolution phase. A stab tagged fixed will * not be be bumped. * * .stab: Old fashioned stabs * .stabn: For stabs without names * .stabs: For stabs with string names * .stabd: For stabs for line numbers or bracketing, * without a string name, without * a final expression. The value of the * final expression is taken to be the current * location counter, and is patched by the 2nd pass * * .stab{<expr>,}*NCPName,<expr>, <expr>, <expr>, <expr> * .stabn <expr>, <expr>, <expr>, <expr> * .stabs STRING, <expr>, <expr>, <expr>, <expr> * .stabd <expr>, <expr>, <expr> # . */ case ISTAB: yyerror(".stab directive no longer supported"); goto errorfix; tailstab: expr(locxp, val); if (! (locxp->e_xvalue & STABTYPS)){ yyerror("Invalid type in %s", stabname); goto errorfix; } stpt->s_ptype = locxp->e_xvalue; shiftover(CM); expr(locxp, val); stpt->s_other = locxp->e_xvalue; shiftover(CM); expr(locxp, val); stpt->s_desc = locxp->e_xvalue; shiftover(CM); exprisname = 0; expr(locxp, val); p = locxp->e_xname; if ((locxp->e_xtype&XTYPE)!=XUNDEF) { /* 004 not forward reference */ stpt->s_value = locxp->e_xvalue; stpt->s_index = dotp - usedot; if (exprisname){ switch(stpt->s_ptype) { case N_GSYM: case N_FNAME: case N_RSYM: case N_SSYM: case N_LSYM: case N_PSYM: case N_BCOMM: case N_ECOMM: case N_LENG: stpt->s_tag = FIXEDSTAB; break; /* Special handling of LCSYM. Although * the named symbol representing the lcomm has * been seen, the address (s_value field) * will be changed in freezesymtab() once * the start address of BSS is known. * So treat this as a forward reference. */ case N_LCSYM: stpt->s_tag = FIXEDSTAB; stpt->s_dest = p; stpt->s_index = p->s_index; stpt->s_type = p->s_type | STABFLAG; stpt->s_value = 0; break; default: stpt->s_tag = FLOATINGSTAB; break; } } else stpt->s_tag = FIXEDSTAB; /* Forward reference. */ /* Final address will be calculated in stabfix(), when */ /* stpt->s_dest->s_value has been assigned its final */ /* address. */ } else { stpt->s_tag = FORWARDSTAB; stpt->s_dest = p; stpt->s_index = p->s_index; stpt->s_type = p->s_type | STABFLAG; /* e_xvalue may contain an offset, as in the case v.4+2; */ /* although the address of v.4 is unknown here, the 2 */ /* will be added in stabfix(). */ stpt->s_value = locxp->e_xvalue; } /* * tokptr now points at one token beyond * the current token stored in val and yylval, * which are the next tokens after the end of * this .stab directive. This next token must * be either a SEMI or NL, so is of width just * one. Therefore, to point to the next token * after the end of this stab, just back up one.. */ buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); break; /*end of the .stab*/ case ISTABDOT: stabname = ".stabd"; stpt = (struct symtab *)yylval; /* * We clobber everything after the * .stabd and its pointer... we MUST * be able to get back to this .stabd * so that we can resolve its final value */ stabstart = tokptr; shift; /*over the ISTABDOT*/ if (passno == 1){ expr(locxp, val); if (! (locxp->e_xvalue & STABTYPS)){ yyerror("Invalid type in .stabd"); goto errorfix; } stpt->s_ptype = locxp->e_xvalue; shiftover(CM); expr(locxp, val); stpt->s_other = locxp->e_xvalue; shiftover(CM); expr(locxp, val); stpt->s_desc = locxp->e_xvalue; /* * * Now, clobber everything but the * .stabd pseudo and the pointer * to its symbol table entry * tokptr points to the next token, * build the skip up to this */ buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); } /* * pass 1: Assign a good guess for its position * (ensures they are sorted into right place)/ * pass 2: Fix the actual value */ stpt->s_value = dotp->e_xvalue; stpt->s_index = dotp - usedot; stpt->s_tag = FLOATINGSTAB; /*although it has no effect in pass 2*/ break; case ISTABNONE: case ISTABSTR: stabname = ((val == ISTABSTR) ? ".stabs" : ".stabn"); auxval = val; if (passno == 2) goto errorfix; stpt = (struct symtab *)yylval; stabstart = tokptr; (bytetoktype *)stabstart -= sizeof(struct symtab *); (bytetoktype *)stabstart -= sizeof(bytetoktype); shift; if (auxval == ISTABSTR){ stringp = (struct strdesc *)yylval; shiftover(STRING); stpt->s_name = (char *)stringp; /* * We want the trailing null included in this string. * We utilize the cheat the string scanner used, * and merely increment the string length */ stringp->sd_strlen += 1; shiftover(CM); } else { stpt->s_name = (char *)savestr("\0", 0, STR_BOTH); } goto tailstab; break; case ICOMM: /* .comm <name> , <expr> */ case ILCOMM: /* .lcomm <name> , <expr> */ auxval = val; shift; np = (struct symtab *)yylval; shiftover(NAME); shiftover(CM); expr(locxp, val); if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ yyerror("comm size not absolute"); if (passno == 1 && (np->s_type&XTYPE) != XUNDEF) yyerror("Redefinition of %s", FETCHNAME(np)); if (passno==1) { np->s_value = locxp->e_xvalue; if (auxval == ICOMM) np->s_type |= XXTRN; else { np->s_type &= ~XTYPE; np->s_type |= XBSS; } } break; case IALIGN: /* .align <align_expr> [, <fill_expr> ]*/ { int align_expr; int fill_expr; /* Get the .align statement, and shift over .align. */ stpt = (struct symtab *)yylval; shift; /* Evaluate the alignment expression. */ expr(locxp, val); if ( (locxp->e_xtype & XTYPE) != XABS) { yyerror("Alignment expression not absolute"); break ; } else if ( ! LEGAL_ALIGN_VAL(locxp->e_xvalue)) { yyerror("Illegal value for alignment expression"); break ; } else if (locxp->e_xvalue > ALIGN_GUARANTEE) { /* * If more alignment was specified, than is guaranteed * by the loader, then issue a warning and convert * the value to the maximum guaranteed by the loader. */ if (passno == 1){ yywarning( ".align %d is NOT preserved by the loader", locxp->e_xvalue); yywarning(".align %d converted to .align %d", locxp->e_xvalue, ALIGN_GUARANTEE); } align_expr = ALIGN_GUARANTEE; } else { /* Use the user specified alignment expression. */ align_expr = locxp->e_xvalue; } /* Evalutate the fill expression if there is one, else use 0. */ if (val == CM) { shiftover(CM); expr(locxp, val); if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS) { yyerror("Fill expression not absolute"); break; } else { fill_expr = locxp->e_xvalue; } } else { fill_expr = 0; /* default to 0 */ } /* Create the appropriate entry for the .align, so it * can be used in calculating positions for symbols. */ jalign(align_expr, fill_expr, stpt); } break; case VINST0: /* vector instructions w/o arguments*/ np = (struct symtab *)yylval; incasetable = 0; shift; vmod.imod = 0; if (val == VMODIFIER){ vmod.imod = yylval; /* save vector instr modifiers */ shift; /* now bring in the first token for the arg list*/ } /* end if VMODIFIER */ format_vinst (np, &vmod, (struct arg *)0); break; case INST0: /* instructions w/o arguments*/ incasetable = 0; insout(yyopcode, (struct arg *)0, 0); shift; break; case INSTn: /* instructions with arguments*/ case IJXXX: /* UNIX style jump instructions */ case VINSTn: /* vector instructions with arguments*/ if (val == VINSTn){ np = (struct symtab *)yylval; auxval = val; shift; /* bring in the first token for the arg list*/ vmod.imod = 0; if (val == VMODIFIER){ vmod.imod = yylval; /* save vector instr modifiers */ shift; /* now bring in the first token for the arg list*/ } /* end if VMODIFIER */ /* * Code to process an argument list */ ap = arglist; xp = explist; } /* end if VINSTn */ else { auxval = val; /* * Code to process an argument list */ ap = arglist; xp = explist;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -