github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/5a/lex.c (about) 1 // Inferno utils/5a/lex.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/5a/lex.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 #define EXTERN 32 #include <u.h> 33 #include <libc.h> 34 #include "a.h" 35 #include "y.tab.h" 36 37 enum 38 { 39 Plan9 = 1<<0, 40 Unix = 1<<1, 41 Windows = 1<<2, 42 }; 43 44 int 45 systemtype(int sys) 46 { 47 #ifdef _WIN32 48 return sys&Windows; 49 #else 50 return sys&Plan9; 51 #endif 52 } 53 54 void 55 main(int argc, char *argv[]) 56 { 57 char *p; 58 int c; 59 60 thechar = '5'; 61 thestring = "arm"; 62 63 ensuresymb(NSYMB); 64 memset(debug, 0, sizeof(debug)); 65 cinit(); 66 outfile = 0; 67 setinclude("."); 68 ARGBEGIN { 69 default: 70 c = ARGC(); 71 if(c >= 0 && c < sizeof(debug)) 72 debug[c] = 1; 73 break; 74 75 case 'o': 76 outfile = ARGF(); 77 break; 78 79 case 'D': 80 p = ARGF(); 81 if(p) { 82 if (nDlist%8 == 0) 83 Dlist = allocn(Dlist, nDlist*sizeof(char *), 84 8*sizeof(char *)); 85 Dlist[nDlist++] = p; 86 } 87 break; 88 89 case 'I': 90 p = ARGF(); 91 setinclude(p); 92 break; 93 case 't': 94 thechar = 't'; 95 thestring = "thumb"; 96 break; 97 } ARGEND 98 if(*argv == 0) { 99 print("usage: %ca [-options] file.s\n", thechar); 100 errorexit(); 101 } 102 if(argc > 1){ 103 print("can't assemble multiple files\n"); 104 errorexit(); 105 } 106 if(assemble(argv[0])) 107 errorexit(); 108 exits(0); 109 } 110 111 int 112 assemble(char *file) 113 { 114 char *ofile, *p; 115 int i, of; 116 117 ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar) 118 strcpy(ofile, file); 119 p = utfrrune(ofile, '/'); 120 if(p) { 121 include[0] = ofile; 122 *p++ = 0; 123 } else 124 p = ofile; 125 if(outfile == 0) { 126 outfile = p; 127 if(outfile){ 128 p = utfrrune(outfile, '.'); 129 if(p) 130 if(p[1] == 's' && p[2] == 0) 131 p[0] = 0; 132 p = utfrune(outfile, 0); 133 p[0] = '.'; 134 p[1] = thechar; 135 p[2] = 0; 136 } else 137 outfile = "/dev/null"; 138 } 139 140 of = create(outfile, OWRITE, 0664); 141 if(of < 0) { 142 yyerror("%ca: cannot create %s", thechar, outfile); 143 errorexit(); 144 } 145 Binit(&obuf, of, OWRITE); 146 147 pass = 1; 148 pinit(file); 149 150 Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); 151 152 for(i=0; i<nDlist; i++) 153 dodefine(Dlist[i]); 154 yyparse(); 155 if(nerrors) { 156 cclean(); 157 return nerrors; 158 } 159 160 Bprint(&obuf, "\n!\n"); 161 162 pass = 2; 163 outhist(); 164 pinit(file); 165 for(i=0; i<nDlist; i++) 166 dodefine(Dlist[i]); 167 yyparse(); 168 cclean(); 169 return nerrors; 170 } 171 172 struct 173 { 174 char *name; 175 ushort type; 176 ushort value; 177 } itab[] = 178 { 179 "SP", LSP, D_AUTO, 180 "SB", LSB, D_EXTERN, 181 "FP", LFP, D_PARAM, 182 "PC", LPC, D_BRANCH, 183 184 "R", LR, 0, 185 "R0", LREG, 0, 186 "R1", LREG, 1, 187 "R2", LREG, 2, 188 "R3", LREG, 3, 189 "R4", LREG, 4, 190 "R5", LREG, 5, 191 "R6", LREG, 6, 192 "R7", LREG, 7, 193 "R8", LREG, 8, 194 "m", LREG, 9, // avoid unintentionally clobber m/g using R9/R10 195 "g", LREG, 10, 196 "R11", LREG, 11, 197 "R12", LREG, 12, 198 "R13", LREG, 13, 199 "R14", LREG, 14, 200 "R15", LREG, 15, 201 202 "F", LF, 0, 203 204 "F0", LFREG, 0, 205 "F1", LFREG, 1, 206 "F2", LFREG, 2, 207 "F3", LFREG, 3, 208 "F4", LFREG, 4, 209 "F5", LFREG, 5, 210 "F6", LFREG, 6, 211 "F7", LFREG, 7, 212 "F8", LFREG, 8, 213 "F9", LFREG, 9, 214 "F10", LFREG, 10, 215 "F11", LFREG, 11, 216 "F12", LFREG, 12, 217 "F13", LFREG, 13, 218 "F14", LFREG, 14, 219 "F15", LFREG, 15, 220 221 "C", LC, 0, 222 223 "C0", LCREG, 0, 224 "C1", LCREG, 1, 225 "C2", LCREG, 2, 226 "C3", LCREG, 3, 227 "C4", LCREG, 4, 228 "C5", LCREG, 5, 229 "C6", LCREG, 6, 230 "C7", LCREG, 7, 231 "C8", LCREG, 8, 232 "C9", LCREG, 9, 233 "C10", LCREG, 10, 234 "C11", LCREG, 11, 235 "C12", LCREG, 12, 236 "C13", LCREG, 13, 237 "C14", LCREG, 14, 238 "C15", LCREG, 15, 239 240 "CPSR", LPSR, 0, 241 "SPSR", LPSR, 1, 242 243 "FPSR", LFCR, 0, 244 "FPCR", LFCR, 1, 245 246 ".EQ", LCOND, 0, 247 ".NE", LCOND, 1, 248 ".CS", LCOND, 2, 249 ".HS", LCOND, 2, 250 ".CC", LCOND, 3, 251 ".LO", LCOND, 3, 252 ".MI", LCOND, 4, 253 ".PL", LCOND, 5, 254 ".VS", LCOND, 6, 255 ".VC", LCOND, 7, 256 ".HI", LCOND, 8, 257 ".LS", LCOND, 9, 258 ".GE", LCOND, 10, 259 ".LT", LCOND, 11, 260 ".GT", LCOND, 12, 261 ".LE", LCOND, 13, 262 ".AL", LCOND, Always, 263 264 ".U", LS, C_UBIT, 265 ".S", LS, C_SBIT, 266 ".W", LS, C_WBIT, 267 ".P", LS, C_PBIT, 268 ".PW", LS, C_WBIT|C_PBIT, 269 ".WP", LS, C_WBIT|C_PBIT, 270 271 ".F", LS, C_FBIT, 272 273 ".IBW", LS, C_WBIT|C_PBIT|C_UBIT, 274 ".IAW", LS, C_WBIT|C_UBIT, 275 ".DBW", LS, C_WBIT|C_PBIT, 276 ".DAW", LS, C_WBIT, 277 ".IB", LS, C_PBIT|C_UBIT, 278 ".IA", LS, C_UBIT, 279 ".DB", LS, C_PBIT, 280 ".DA", LS, 0, 281 282 "@", LAT, 0, 283 284 "AND", LTYPE1, AAND, 285 "EOR", LTYPE1, AEOR, 286 "SUB", LTYPE1, ASUB, 287 "RSB", LTYPE1, ARSB, 288 "ADD", LTYPE1, AADD, 289 "ADC", LTYPE1, AADC, 290 "SBC", LTYPE1, ASBC, 291 "RSC", LTYPE1, ARSC, 292 "ORR", LTYPE1, AORR, 293 "BIC", LTYPE1, ABIC, 294 295 "SLL", LTYPE1, ASLL, 296 "SRL", LTYPE1, ASRL, 297 "SRA", LTYPE1, ASRA, 298 299 "MUL", LTYPE1, AMUL, 300 "MULA", LTYPEN, AMULA, 301 "DIV", LTYPE1, ADIV, 302 "MOD", LTYPE1, AMOD, 303 304 "MULL", LTYPEM, AMULL, 305 "MULAL", LTYPEM, AMULAL, 306 "MULLU", LTYPEM, AMULLU, 307 "MULALU", LTYPEM, AMULALU, 308 309 "MVN", LTYPE2, AMVN, /* op2 ignored */ 310 311 "MOVB", LTYPE3, AMOVB, 312 "MOVBU", LTYPE3, AMOVBU, 313 "MOVH", LTYPE3, AMOVH, 314 "MOVHU", LTYPE3, AMOVHU, 315 "MOVW", LTYPE3, AMOVW, 316 317 "MOVD", LTYPE3, AMOVD, 318 "MOVDF", LTYPE3, AMOVDF, 319 "MOVDW", LTYPE3, AMOVDW, 320 "MOVF", LTYPE3, AMOVF, 321 "MOVFD", LTYPE3, AMOVFD, 322 "MOVFW", LTYPE3, AMOVFW, 323 "MOVWD", LTYPE3, AMOVWD, 324 "MOVWF", LTYPE3, AMOVWF, 325 326 "LDREX", LTYPE3, ALDREX, 327 "LDREXD", LTYPE3, ALDREXD, 328 "STREX", LTYPE9, ASTREX, 329 "STREXD", LTYPE9, ASTREXD, 330 331 /* 332 "NEGF", LTYPEI, ANEGF, 333 "NEGD", LTYPEI, ANEGD, 334 "SQTF", LTYPEI, ASQTF, 335 "SQTD", LTYPEI, ASQTD, 336 "RNDF", LTYPEI, ARNDF, 337 "RNDD", LTYPEI, ARNDD, 338 "URDF", LTYPEI, AURDF, 339 "URDD", LTYPEI, AURDD, 340 "NRMF", LTYPEI, ANRMF, 341 "NRMD", LTYPEI, ANRMD, 342 */ 343 344 "ABSF", LTYPEI, AABSF, 345 "ABSD", LTYPEI, AABSD, 346 "SQRTF", LTYPEI, ASQRTF, 347 "SQRTD", LTYPEI, ASQRTD, 348 "CMPF", LTYPEL, ACMPF, 349 "CMPD", LTYPEL, ACMPD, 350 "ADDF", LTYPEK, AADDF, 351 "ADDD", LTYPEK, AADDD, 352 "SUBF", LTYPEK, ASUBF, 353 "SUBD", LTYPEK, ASUBD, 354 "MULF", LTYPEK, AMULF, 355 "MULD", LTYPEK, AMULD, 356 "DIVF", LTYPEK, ADIVF, 357 "DIVD", LTYPEK, ADIVD, 358 359 "B", LTYPE4, AB, 360 "BL", LTYPE4, ABL, 361 "BX", LTYPEBX, ABX, 362 363 "BEQ", LTYPE5, ABEQ, 364 "BNE", LTYPE5, ABNE, 365 "BCS", LTYPE5, ABCS, 366 "BHS", LTYPE5, ABHS, 367 "BCC", LTYPE5, ABCC, 368 "BLO", LTYPE5, ABLO, 369 "BMI", LTYPE5, ABMI, 370 "BPL", LTYPE5, ABPL, 371 "BVS", LTYPE5, ABVS, 372 "BVC", LTYPE5, ABVC, 373 "BHI", LTYPE5, ABHI, 374 "BLS", LTYPE5, ABLS, 375 "BGE", LTYPE5, ABGE, 376 "BLT", LTYPE5, ABLT, 377 "BGT", LTYPE5, ABGT, 378 "BLE", LTYPE5, ABLE, 379 "BCASE", LTYPE5, ABCASE, 380 381 "SWI", LTYPE6, ASWI, 382 383 "CMP", LTYPE7, ACMP, 384 "TST", LTYPE7, ATST, 385 "TEQ", LTYPE7, ATEQ, 386 "CMN", LTYPE7, ACMN, 387 388 "MOVM", LTYPE8, AMOVM, 389 390 "SWPBU", LTYPE9, ASWPBU, 391 "SWPW", LTYPE9, ASWPW, 392 393 "RET", LTYPEA, ARET, 394 "RFE", LTYPEA, ARFE, 395 396 "TEXT", LTYPEB, ATEXT, 397 "GLOBL", LTYPEB, AGLOBL, 398 "DATA", LTYPEC, ADATA, 399 "CASE", LTYPED, ACASE, 400 "END", LTYPEE, AEND, 401 "WORD", LTYPEH, AWORD, 402 "NOP", LTYPEI, ANOP, 403 404 "MCR", LTYPEJ, 0, 405 "MRC", LTYPEJ, 1, 406 407 "PLD", LTYPEPLD, APLD, 408 "UNDEF", LTYPEE, AUNDEF, 409 "CLZ", LTYPE2, ACLZ, 410 411 "MULWT", LTYPE1, AMULWT, 412 "MULWB", LTYPE1, AMULWB, 413 "MULAWT", LTYPEN, AMULAWT, 414 "MULAWB", LTYPEN, AMULAWB, 415 416 "USEFIELD", LTYPEN, AUSEFIELD, 417 "PCDATA", LTYPEPC, APCDATA, 418 "FUNCDATA", LTYPEF, AFUNCDATA, 419 420 0 421 }; 422 423 void 424 cinit(void) 425 { 426 Sym *s; 427 int i; 428 429 nullgen.sym = S; 430 nullgen.offset = 0; 431 nullgen.type = D_NONE; 432 nullgen.name = D_NONE; 433 nullgen.reg = NREG; 434 if(FPCHIP) 435 nullgen.dval = 0; 436 for(i=0; i<sizeof(nullgen.sval); i++) 437 nullgen.sval[i] = 0; 438 439 nerrors = 0; 440 iostack = I; 441 iofree = I; 442 peekc = IGN; 443 nhunk = 0; 444 for(i=0; i<NHASH; i++) 445 hash[i] = S; 446 for(i=0; itab[i].name; i++) { 447 s = slookup(itab[i].name); 448 s->type = itab[i].type; 449 s->value = itab[i].value; 450 } 451 452 pathname = allocn(pathname, 0, 100); 453 if(getwd(pathname, 99) == 0) { 454 pathname = allocn(pathname, 100, 900); 455 if(getwd(pathname, 999) == 0) 456 strcpy(pathname, "/???"); 457 } 458 } 459 460 void 461 syminit(Sym *s) 462 { 463 464 s->type = LNAME; 465 s->value = 0; 466 } 467 468 int 469 isreg(Gen *g) 470 { 471 472 USED(g); 473 return 1; 474 } 475 476 void 477 cclean(void) 478 { 479 480 outcode(AEND, Always, &nullgen, NREG, &nullgen); 481 Bflush(&obuf); 482 } 483 484 void 485 zname(char *n, int t, int s) 486 { 487 488 BPUTC(&obuf, ANAME); 489 BPUTC(&obuf, t); /* type */ 490 BPUTC(&obuf, s); /* sym */ 491 while(*n) { 492 BPUTC(&obuf, *n); 493 n++; 494 } 495 BPUTC(&obuf, 0); 496 } 497 498 void 499 zaddr(Gen *a, int s) 500 { 501 int32 l; 502 int i; 503 char *n; 504 Ieee e; 505 506 BPUTC(&obuf, a->type); 507 BPUTC(&obuf, a->reg); 508 BPUTC(&obuf, s); 509 BPUTC(&obuf, a->name); 510 BPUTC(&obuf, 0); 511 switch(a->type) { 512 default: 513 print("unknown type %d\n", a->type); 514 exits("arg"); 515 516 case D_NONE: 517 case D_REG: 518 case D_FREG: 519 case D_PSR: 520 case D_FPCR: 521 break; 522 523 case D_REGREG: 524 case D_REGREG2: 525 BPUTC(&obuf, a->offset); 526 break; 527 528 case D_CONST2: 529 l = a->offset2; 530 BPUTLE4(&obuf, l); 531 // fall through 532 case D_OREG: 533 case D_CONST: 534 case D_BRANCH: 535 case D_SHIFT: 536 l = a->offset; 537 BPUTLE4(&obuf, l); 538 break; 539 540 case D_SCONST: 541 n = a->sval; 542 for(i=0; i<NSNAME; i++) { 543 BPUTC(&obuf, *n); 544 n++; 545 } 546 break; 547 548 case D_FCONST: 549 ieeedtod(&e, a->dval); 550 BPUTLE4(&obuf, e.l); 551 BPUTLE4(&obuf, e.h); 552 break; 553 } 554 } 555 556 static int bcode[] = 557 { 558 ABEQ, 559 ABNE, 560 ABCS, 561 ABCC, 562 ABMI, 563 ABPL, 564 ABVS, 565 ABVC, 566 ABHI, 567 ABLS, 568 ABGE, 569 ABLT, 570 ABGT, 571 ABLE, 572 AB, 573 ANOP, 574 }; 575 576 void 577 outcode(int a, int scond, Gen *g1, int reg, Gen *g2) 578 { 579 int sf, st, t; 580 Sym *s; 581 582 /* hack to make B.NE etc. work: turn it into the corresponding conditional */ 583 if(a == AB){ 584 a = bcode[scond&0xf]; 585 scond = (scond & ~0xf) | Always; 586 } 587 588 if(pass == 1) 589 goto out; 590 jackpot: 591 sf = 0; 592 s = g1->sym; 593 while(s != S) { 594 sf = s->sym; 595 if(sf < 0 || sf >= NSYM) 596 sf = 0; 597 t = g1->name; 598 if(h[sf].type == t) 599 if(h[sf].sym == s) 600 break; 601 zname(s->name, t, sym); 602 s->sym = sym; 603 h[sym].sym = s; 604 h[sym].type = t; 605 sf = sym; 606 sym++; 607 if(sym >= NSYM) 608 sym = 1; 609 break; 610 } 611 st = 0; 612 s = g2->sym; 613 while(s != S) { 614 st = s->sym; 615 if(st < 0 || st >= NSYM) 616 st = 0; 617 t = g2->name; 618 if(h[st].type == t) 619 if(h[st].sym == s) 620 break; 621 zname(s->name, t, sym); 622 s->sym = sym; 623 h[sym].sym = s; 624 h[sym].type = t; 625 st = sym; 626 sym++; 627 if(sym >= NSYM) 628 sym = 1; 629 if(st == sf) 630 goto jackpot; 631 break; 632 } 633 BPUTC(&obuf, a); 634 BPUTC(&obuf, scond); 635 BPUTC(&obuf, reg); 636 BPUTLE4(&obuf, stmtline); 637 zaddr(g1, sf); 638 zaddr(g2, st); 639 640 out: 641 if(a != AGLOBL && a != ADATA) 642 pc++; 643 } 644 645 void 646 outhist(void) 647 { 648 Gen g; 649 Hist *h; 650 char *p, *q, *op, c; 651 int n; 652 char *tofree; 653 static int first = 1; 654 static char *goroot, *goroot_final; 655 656 if(first) { 657 // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL. 658 first = 0; 659 goroot = getenv("GOROOT"); 660 goroot_final = getenv("GOROOT_FINAL"); 661 if(goroot == nil) 662 goroot = ""; 663 if(goroot_final == nil) 664 goroot_final = goroot; 665 if(strcmp(goroot, goroot_final) == 0) { 666 goroot = nil; 667 goroot_final = nil; 668 } 669 } 670 671 tofree = nil; 672 g = nullgen; 673 c = '/'; 674 for(h = hist; h != H; h = h->link) { 675 p = h->name; 676 if(p != nil && goroot != nil) { 677 n = strlen(goroot); 678 if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') { 679 tofree = smprint("%s%s", goroot_final, p+n); 680 p = tofree; 681 } 682 } 683 op = 0; 684 if(systemtype(Windows) && p && p[1] == ':'){ 685 c = p[2]; 686 } else if(p && p[0] != c && h->offset == 0 && pathname){ 687 if(systemtype(Windows) && pathname[1] == ':') { 688 op = p; 689 p = pathname; 690 c = p[2]; 691 } else if(pathname[0] == c){ 692 op = p; 693 p = pathname; 694 } 695 } 696 while(p) { 697 q = strchr(p, c); 698 if(q) { 699 n = q-p; 700 if(n == 0){ 701 n = 1; /* leading "/" */ 702 *p = '/'; /* don't emit "\" on windows */ 703 } 704 q++; 705 } else { 706 n = strlen(p); 707 q = 0; 708 } 709 if(n) { 710 BPUTC(&obuf, ANAME); 711 BPUTC(&obuf, D_FILE); /* type */ 712 BPUTC(&obuf, 1); /* sym */ 713 BPUTC(&obuf, '<'); 714 Bwrite(&obuf, p, n); 715 BPUTC(&obuf, 0); 716 } 717 p = q; 718 if(p == 0 && op) { 719 p = op; 720 op = 0; 721 } 722 } 723 g.offset = h->offset; 724 725 BPUTC(&obuf, AHISTORY); 726 BPUTC(&obuf, Always); 727 BPUTC(&obuf, 0); 728 BPUTLE4(&obuf, h->line); 729 zaddr(&nullgen, 0); 730 zaddr(&g, 0); 731 732 if(tofree) { 733 free(tofree); 734 tofree = nil; 735 } 736 } 737 } 738 739 #include "../cc/lexbody" 740 #include "../cc/macbody"