github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/6l/obj.c (about) 1 // Inferno utils/6l/obj.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.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 // Reading object files. 32 33 #define EXTERN 34 #include "l.h" 35 #include "../ld/lib.h" 36 #include "../ld/elf.h" 37 #include "../ld/macho.h" 38 #include "../ld/dwarf.h" 39 #include "../ld/pe.h" 40 #include <ar.h> 41 42 char *noname = "<none>"; 43 char* thestring = "amd64"; 44 char* paramspace = "FP"; 45 46 Header headers[] = { 47 "plan9x32", Hplan9x32, 48 "plan9", Hplan9x64, 49 "elf", Helf, 50 "darwin", Hdarwin, 51 "dragonfly", Hdragonfly, 52 "linux", Hlinux, 53 "freebsd", Hfreebsd, 54 "netbsd", Hnetbsd, 55 "openbsd", Hopenbsd, 56 "windows", Hwindows, 57 "windowsgui", Hwindows, 58 0, 0 59 }; 60 61 /* 62 * -Hplan9x32 -T4128 -R4096 is plan9 32-bit format 63 * -Hplan9 -T0x200028 -R0x200000 is plan9 64-bit format 64 * -Helf -T0x80110000 -R4096 is ELF32 65 * -Hdarwin -Tx -Rx is apple MH-exec 66 * -Hdragonfly -Tx -Rx is DragonFly elf-exec 67 * -Hlinux -Tx -Rx is linux elf-exec 68 * -Hfreebsd -Tx -Rx is FreeBSD elf-exec 69 * -Hnetbsd -Tx -Rx is NetBSD elf-exec 70 * -Hopenbsd -Tx -Rx is OpenBSD elf-exec 71 * -Hwindows -Tx -Rx is MS Windows PE32+ 72 */ 73 74 void 75 main(int argc, char *argv[]) 76 { 77 Binit(&bso, 1, OWRITE); 78 listinit(); 79 memset(debug, 0, sizeof(debug)); 80 nerrors = 0; 81 outfile = nil; 82 HEADTYPE = -1; 83 INITTEXT = -1; 84 INITDAT = -1; 85 INITRND = -1; 86 INITENTRY = 0; 87 linkmode = LinkAuto; 88 nuxiinit(); 89 90 flagcount("1", "use alternate profiling code", &debug['1']); 91 flagcount("8", "assume 64-bit addresses", &debug['8']); 92 flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo); 93 flagint64("D", "addr: data address", &INITDAT); 94 flagstr("E", "sym: entry symbol", &INITENTRY); 95 flagfn1("I", "interp: set ELF interp", setinterp); 96 flagfn1("L", "dir: add dir to library path", Lflag); 97 flagfn1("H", "head: header type", setheadtype); 98 flagcount("K", "add stack underflow checks", &debug['K']); 99 flagcount("O", "print pc-line tables", &debug['O']); 100 flagcount("Q", "debug byte-register code gen", &debug['Q']); 101 flagint32("R", "rnd: address rounding", &INITRND); 102 flagcount("S", "check type signatures", &debug['S']); 103 flagint64("T", "addr: text address", &INITTEXT); 104 flagfn0("V", "print version and exit", doversion); 105 flagcount("W", "disassemble input", &debug['W']); 106 flagfn2("X", "name value: define string data", addstrdata); 107 flagcount("Z", "clear stack frame on entry", &debug['Z']); 108 flagcount("a", "disassemble output", &debug['a']); 109 flagcount("c", "dump call graph", &debug['c']); 110 flagcount("d", "disable dynamic executable", &debug['d']); 111 flagstr("extld", "linker to run in external mode", &extld); 112 flagstr("extldflags", "flags for external linker", &extldflags); 113 flagcount("f", "ignore version mismatch", &debug['f']); 114 flagcount("g", "disable go package data checks", &debug['g']); 115 flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix); 116 flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode); 117 flagstr("k", "sym: set field tracking symbol", &tracksym); 118 flagcount("n", "dump symbol table", &debug['n']); 119 flagstr("o", "outfile: set output file", &outfile); 120 flagcount("p", "insert profiling code", &debug['p']); 121 flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath); 122 flagcount("race", "enable race detector", &flag_race); 123 flagcount("s", "disable symbol table", &debug['s']); 124 flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared); 125 flagstr("tmpdir", "leave temporary files in this directory", &tmpdir); 126 flagcount("u", "reject unsafe packages", &debug['u']); 127 flagcount("v", "print link trace", &debug['v']); 128 flagcount("w", "disable DWARF generation", &debug['w']); 129 130 flagparse(&argc, &argv, usage); 131 132 if(argc != 1) 133 usage(); 134 135 mywhatsys(); // get goos 136 137 if(HEADTYPE == -1) 138 HEADTYPE = headtype(goos); 139 140 // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when 141 // Go was built; see ../../make.bash. 142 if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0) 143 linkmode = LinkInternal; 144 145 if(flag_shared) 146 linkmode = LinkExternal; 147 148 switch(HEADTYPE) { 149 default: 150 if(linkmode == LinkAuto) 151 linkmode = LinkInternal; 152 if(linkmode == LinkExternal && strcmp(getgoextlinkenabled(), "1") != 0) 153 sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE)); 154 break; 155 case Hdarwin: 156 case Hdragonfly: 157 case Hfreebsd: 158 case Hlinux: 159 case Hnetbsd: 160 case Hopenbsd: 161 break; 162 } 163 164 if(outfile == nil) { 165 if(HEADTYPE == Hwindows) 166 outfile = "6.out.exe"; 167 else 168 outfile = "6.out"; 169 } 170 171 libinit(); 172 173 switch(HEADTYPE) { 174 default: 175 diag("unknown -H option"); 176 errorexit(); 177 case Hplan9x32: /* plan 9 */ 178 HEADR = 32L; 179 if(INITTEXT == -1) 180 INITTEXT = 4096+HEADR; 181 if(INITDAT == -1) 182 INITDAT = 0; 183 if(INITRND == -1) 184 INITRND = 4096; 185 break; 186 case Hplan9x64: /* plan 9 */ 187 HEADR = 32L + 8L; 188 if(INITTEXT == -1) 189 INITTEXT = 0x200000+HEADR; 190 if(INITDAT == -1) 191 INITDAT = 0; 192 if(INITRND == -1) 193 INITRND = 0x200000; 194 break; 195 case Helf: /* elf32 executable */ 196 HEADR = rnd(52L+3*32L, 16); 197 if(INITTEXT == -1) 198 INITTEXT = 0x80110000L; 199 if(INITDAT == -1) 200 INITDAT = 0; 201 if(INITRND == -1) 202 INITRND = 4096; 203 break; 204 case Hdarwin: /* apple MACH */ 205 /* 206 * OS X system constant - offset from 0(GS) to our TLS. 207 * Explained in ../../pkg/runtime/cgo/gcc_darwin_amd64.c. 208 */ 209 tlsoffset = 0x8a0; 210 machoinit(); 211 HEADR = INITIAL_MACHO_HEADR; 212 if(INITRND == -1) 213 INITRND = 4096; 214 if(INITTEXT == -1) 215 INITTEXT = 4096+HEADR; 216 if(INITDAT == -1) 217 INITDAT = 0; 218 break; 219 case Hlinux: /* elf64 executable */ 220 case Hfreebsd: /* freebsd */ 221 case Hnetbsd: /* netbsd */ 222 case Hopenbsd: /* openbsd */ 223 case Hdragonfly: /* dragonfly */ 224 /* 225 * ELF uses TLS offset negative from FS. 226 * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS). 227 * Also known to ../../pkg/runtime/sys_linux_amd64.s 228 * and ../../pkg/runtime/cgo/gcc_linux_amd64.c. 229 */ 230 tlsoffset = -16; 231 elfinit(); 232 HEADR = ELFRESERVE; 233 if(INITTEXT == -1) 234 INITTEXT = (1<<22)+HEADR; 235 if(INITDAT == -1) 236 INITDAT = 0; 237 if(INITRND == -1) 238 INITRND = 4096; 239 break; 240 case Hwindows: /* PE executable */ 241 peinit(); 242 HEADR = PEFILEHEADR; 243 if(INITTEXT == -1) 244 INITTEXT = PEBASE+PESECTHEADR; 245 if(INITDAT == -1) 246 INITDAT = 0; 247 if(INITRND == -1) 248 INITRND = PESECTALIGN; 249 break; 250 } 251 if(INITDAT != 0 && INITRND != 0) 252 print("warning: -D0x%llux is ignored because of -R0x%ux\n", 253 INITDAT, INITRND); 254 if(debug['v']) 255 Bprint(&bso, "HEADER = -H%d -T0x%llux -D0x%llux -R0x%ux\n", 256 HEADTYPE, INITTEXT, INITDAT, INITRND); 257 Bflush(&bso); 258 instinit(); 259 260 zprg.link = P; 261 zprg.pcond = P; 262 zprg.back = 2; 263 zprg.as = AGOK; 264 zprg.from.type = D_NONE; 265 zprg.from.index = D_NONE; 266 zprg.from.scale = 1; 267 zprg.to = zprg.from; 268 zprg.mode = 64; 269 270 pcstr = "%.6llux "; 271 histgen = 0; 272 pc = 0; 273 dtype = 4; 274 version = 0; 275 cbp = buf.cbuf; 276 cbc = sizeof(buf.cbuf); 277 278 addlibpath("command line", "command line", argv[0], "main"); 279 loadlib(); 280 deadcode(); 281 patch(); 282 follow(); 283 doelf(); 284 if(HEADTYPE == Hdarwin) 285 domacho(); 286 dostkoff(); 287 dostkcheck(); 288 paramspace = "SP"; /* (FP) now (SP) on output */ 289 if(debug['p']) 290 if(debug['1']) 291 doprof1(); 292 else 293 doprof2(); 294 span(); 295 if(HEADTYPE == Hwindows) 296 dope(); 297 addexport(); 298 textaddress(); 299 pclntab(); 300 symtab(); 301 dodata(); 302 address(); 303 doweak(); 304 reloc(); 305 asmb(); 306 undef(); 307 hostlink(); 308 if(debug['v']) { 309 Bprint(&bso, "%5.2f cpu time\n", cputime()); 310 Bprint(&bso, "%d symbols\n", nsymbol); 311 Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); 312 Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); 313 } 314 Bflush(&bso); 315 316 errorexit(); 317 } 318 319 static Sym* 320 zsym(char *pn, Biobuf *f, Sym *h[]) 321 { 322 int o; 323 324 o = BGETC(f); 325 if(o < 0 || o >= NSYM || h[o] == nil) 326 mangle(pn); 327 return h[o]; 328 } 329 330 static void 331 zaddr(char *pn, Biobuf *f, Adr *a, Sym *h[]) 332 { 333 int t; 334 int32 l; 335 Sym *s; 336 Auto *u; 337 338 t = BGETC(f); 339 a->index = D_NONE; 340 a->scale = 0; 341 if(t & T_INDEX) { 342 a->index = BGETC(f); 343 a->scale = BGETC(f); 344 } 345 a->offset = 0; 346 if(t & T_OFFSET) { 347 a->offset = BGETLE4(f); 348 if(t & T_64) { 349 a->offset &= 0xFFFFFFFFULL; 350 a->offset |= (uvlong)BGETLE4(f) << 32; 351 } 352 } 353 a->sym = S; 354 if(t & T_SYM) 355 a->sym = zsym(pn, f, h); 356 a->type = D_NONE; 357 if(t & T_FCONST) { 358 a->ieee.l = BGETLE4(f); 359 a->ieee.h = BGETLE4(f); 360 a->type = D_FCONST; 361 } else 362 if(t & T_SCONST) { 363 Bread(f, a->scon, NSNAME); 364 a->type = D_SCONST; 365 } 366 if(t & T_TYPE) 367 a->type = BGETC(f); 368 if(a->type < 0 || a->type >= D_SIZE) 369 mangle(pn); 370 adrgotype = S; 371 if(t & T_GOTYPE) 372 adrgotype = zsym(pn, f, h); 373 s = a->sym; 374 t = a->type; 375 if(t == D_INDIR+D_GS || a->index == D_GS) 376 a->offset += tlsoffset; 377 if(t != D_AUTO && t != D_PARAM) { 378 if(s && adrgotype) 379 s->gotype = adrgotype; 380 return; 381 } 382 l = a->offset; 383 for(u=curauto; u; u=u->link) { 384 if(u->asym == s) 385 if(u->type == t) { 386 if(u->aoffset > l) 387 u->aoffset = l; 388 if(adrgotype) 389 u->gotype = adrgotype; 390 return; 391 } 392 } 393 394 switch(t) { 395 case D_FILE: 396 case D_FILE1: 397 case D_AUTO: 398 case D_PARAM: 399 if(s == S) 400 mangle(pn); 401 } 402 403 u = mal(sizeof(*u)); 404 u->link = curauto; 405 curauto = u; 406 u->asym = s; 407 u->aoffset = l; 408 u->type = t; 409 u->gotype = adrgotype; 410 } 411 412 void 413 nopout(Prog *p) 414 { 415 p->as = ANOP; 416 p->from.type = D_NONE; 417 p->to.type = D_NONE; 418 } 419 420 void 421 ldobj1(Biobuf *f, char *pkg, int64 len, char *pn) 422 { 423 vlong ipc; 424 Prog *p; 425 int v, o, r, skip, mode; 426 Sym *h[NSYM], *s; 427 uint32 sig; 428 char *name, *x; 429 int ntext; 430 vlong eof; 431 char src[1024]; 432 Prog *lastp; 433 434 lastp = nil; 435 ntext = 0; 436 eof = Boffset(f) + len; 437 src[0] = 0; 438 pn = estrdup(pn); // we keep it in Sym* references 439 440 newloop: 441 memset(h, 0, sizeof(h)); 442 version++; 443 histfrogp = 0; 444 ipc = pc; 445 skip = 0; 446 mode = 64; 447 448 loop: 449 if(f->state == Bracteof || Boffset(f) >= eof) 450 goto eof; 451 o = BGETC(f); 452 if(o == Beof) 453 goto eof; 454 o |= BGETC(f) << 8; 455 if(o <= AXXX || o >= ALAST) { 456 if(o < 0) 457 goto eof; 458 diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o); 459 print(" probably not a .6 file\n"); 460 errorexit(); 461 } 462 463 if(o == ANAME || o == ASIGNAME) { 464 sig = 0; 465 if(o == ASIGNAME) 466 sig = BGETLE4(f); 467 v = BGETC(f); /* type */ 468 o = BGETC(f); /* sym */ 469 r = 0; 470 if(v == D_STATIC) 471 r = version; 472 name = Brdline(f, '\0'); 473 if(name == nil) { 474 if(Blinelen(f) > 0) { 475 fprint(2, "%s: name too long\n", pn); 476 errorexit(); 477 } 478 goto eof; 479 } 480 x = expandpkg(name, pkg); 481 s = lookup(x, r); 482 if(x != name) 483 free(x); 484 485 if(debug['S'] && r == 0) 486 sig = 1729; 487 if(sig != 0){ 488 if(s->sig != 0 && s->sig != sig) 489 diag("incompatible type signatures " 490 "%ux(%s) and %ux(%s) for %s", 491 s->sig, s->file, sig, pn, s->name); 492 s->sig = sig; 493 s->file = pn; 494 } 495 496 if(debug['W']) 497 print(" ANAME %s\n", s->name); 498 if(o < 0 || o >= nelem(h)) 499 mangle(pn); 500 h[o] = s; 501 if((v == D_EXTERN || v == D_STATIC) && s->type == 0) 502 s->type = SXREF; 503 if(v == D_FILE) { 504 if(s->type != SFILE) { 505 histgen++; 506 s->type = SFILE; 507 s->value = histgen; 508 } 509 if(histfrogp < MAXHIST) { 510 histfrog[histfrogp] = s; 511 histfrogp++; 512 } else 513 collapsefrog(s); 514 dwarfaddfrag(s->value, s->name); 515 } 516 goto loop; 517 } 518 519 p = mal(sizeof(*p)); 520 p->as = o; 521 p->line = BGETLE4(f); 522 p->back = 2; 523 p->mode = mode; 524 zaddr(pn, f, &p->from, h); 525 fromgotype = adrgotype; 526 zaddr(pn, f, &p->to, h); 527 528 switch(p->as) { 529 case ATEXT: 530 case ADATA: 531 case AGLOBL: 532 if(p->from.sym == S) 533 mangle(pn); 534 break; 535 } 536 537 if(debug['W']) 538 print("%P\n", p); 539 540 switch(p->as) { 541 case AHISTORY: 542 if(p->to.offset == -1) { 543 addlib(src, pn); 544 histfrogp = 0; 545 goto loop; 546 } 547 if(src[0] == '\0') 548 copyhistfrog(src, sizeof src); 549 addhist(p->line, D_FILE); /* 'z' */ 550 if(p->to.offset) 551 addhist(p->to.offset, D_FILE1); /* 'Z' */ 552 savehist(p->line, p->to.offset); 553 histfrogp = 0; 554 goto loop; 555 556 case AEND: 557 histtoauto(); 558 if(cursym != nil && cursym->text) 559 cursym->autom = curauto; 560 curauto = 0; 561 cursym = nil; 562 if(Boffset(f) == eof) 563 return; 564 goto newloop; 565 566 case AGLOBL: 567 s = p->from.sym; 568 if(s->type == 0 || s->type == SXREF) { 569 s->type = SBSS; 570 s->size = 0; 571 } 572 if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) { 573 diag("%s: redefinition: %s in %s", 574 pn, s->name, TNAME); 575 s->type = SBSS; 576 s->size = 0; 577 } 578 if(p->to.offset > s->size) 579 s->size = p->to.offset; 580 if(p->from.scale & DUPOK) 581 s->dupok = 1; 582 if(p->from.scale & RODATA) 583 s->type = SRODATA; 584 else if(p->from.scale & NOPTR) 585 s->type = SNOPTRBSS; 586 goto loop; 587 588 case ADATA: 589 // Assume that AGLOBL comes after ADATA. 590 // If we've seen an AGLOBL that said this sym was DUPOK, 591 // ignore any more ADATA we see, which must be 592 // redefinitions. 593 s = p->from.sym; 594 if(s->dupok) { 595 // if(debug['v']) 596 // Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn); 597 goto loop; 598 } 599 if(s->file == nil) 600 s->file = pn; 601 else if(s->file != pn) { 602 diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn); 603 errorexit(); 604 } 605 savedata(s, p, pn); 606 unmal(p, sizeof *p); 607 goto loop; 608 609 case AGOK: 610 diag("%s: GOK opcode in %s", pn, TNAME); 611 pc++; 612 goto loop; 613 614 case ATYPE: 615 if(skip) 616 goto casdef; 617 pc++; 618 goto loop; 619 620 case ATEXT: 621 s = p->from.sym; 622 if(s->text != nil) { 623 if(p->from.scale & DUPOK) { 624 skip = 1; 625 goto casdef; 626 } 627 diag("%s: %s: redefinition", pn, s->name); 628 return; 629 } 630 if(ntext++ == 0 && s->type != 0 && s->type != SXREF) { 631 /* redefinition, so file has probably been seen before */ 632 if(debug['v']) 633 Bprint(&bso, "skipping: %s: redefinition: %s", pn, s->name); 634 return; 635 } 636 if(cursym != nil && cursym->text) { 637 histtoauto(); 638 cursym->autom = curauto; 639 curauto = 0; 640 } 641 skip = 0; 642 if(etextp) 643 etextp->next = s; 644 else 645 textp = s; 646 etextp = s; 647 s->text = p; 648 cursym = s; 649 if(s->type != 0 && s->type != SXREF) { 650 if(p->from.scale & DUPOK) { 651 skip = 1; 652 goto casdef; 653 } 654 diag("%s: redefinition: %s\n%P", pn, s->name, p); 655 } 656 if(fromgotype) { 657 if(s->gotype && s->gotype != fromgotype) 658 diag("%s: type mismatch for %s", pn, s->name); 659 s->gotype = fromgotype; 660 } 661 s->type = STEXT; 662 s->hist = gethist(); 663 s->value = pc; 664 s->args = p->to.offset >> 32; 665 lastp = p; 666 p->pc = pc++; 667 goto loop; 668 669 case AMODE: 670 if(p->from.type == D_CONST || p->from.type == D_INDIR+D_NONE){ 671 switch((int)p->from.offset){ 672 case 16: case 32: case 64: 673 mode = p->from.offset; 674 break; 675 } 676 } 677 goto loop; 678 679 case AFMOVF: 680 case AFADDF: 681 case AFSUBF: 682 case AFSUBRF: 683 case AFMULF: 684 case AFDIVF: 685 case AFDIVRF: 686 case AFCOMF: 687 case AFCOMFP: 688 case AMOVSS: 689 case AADDSS: 690 case ASUBSS: 691 case AMULSS: 692 case ADIVSS: 693 case ACOMISS: 694 case AUCOMISS: 695 if(skip) 696 goto casdef; 697 if(p->from.type == D_FCONST) { 698 /* size sb 9 max */ 699 sprint(literal, "$%ux", ieeedtof(&p->from.ieee)); 700 s = lookup(literal, 0); 701 if(s->type == 0) { 702 s->type = SRODATA; 703 adduint32(s, ieeedtof(&p->from.ieee)); 704 s->reachable = 0; 705 } 706 p->from.type = D_EXTERN; 707 p->from.sym = s; 708 p->from.offset = 0; 709 } 710 goto casdef; 711 712 case AFMOVD: 713 case AFADDD: 714 case AFSUBD: 715 case AFSUBRD: 716 case AFMULD: 717 case AFDIVD: 718 case AFDIVRD: 719 case AFCOMD: 720 case AFCOMDP: 721 case AMOVSD: 722 case AADDSD: 723 case ASUBSD: 724 case AMULSD: 725 case ADIVSD: 726 case ACOMISD: 727 case AUCOMISD: 728 if(skip) 729 goto casdef; 730 if(p->from.type == D_FCONST) { 731 /* size sb 18 max */ 732 sprint(literal, "$%ux.%ux", 733 p->from.ieee.l, p->from.ieee.h); 734 s = lookup(literal, 0); 735 if(s->type == 0) { 736 s->type = SRODATA; 737 adduint32(s, p->from.ieee.l); 738 adduint32(s, p->from.ieee.h); 739 s->reachable = 0; 740 } 741 p->from.type = D_EXTERN; 742 p->from.sym = s; 743 p->from.offset = 0; 744 } 745 goto casdef; 746 747 casdef: 748 default: 749 if(skip) 750 nopout(p); 751 p->pc = pc; 752 pc++; 753 754 if(p->to.type == D_BRANCH) 755 p->to.offset += ipc; 756 if(lastp == nil) { 757 if(p->as != ANOP) 758 diag("unexpected instruction: %P", p); 759 goto loop; 760 } 761 lastp->link = p; 762 lastp = p; 763 goto loop; 764 } 765 766 eof: 767 diag("truncated object file: %s", pn); 768 } 769 770 Prog* 771 prg(void) 772 { 773 Prog *p; 774 775 p = mal(sizeof(*p)); 776 777 *p = zprg; 778 return p; 779 } 780 781 Prog* 782 copyp(Prog *q) 783 { 784 Prog *p; 785 786 p = prg(); 787 *p = *q; 788 return p; 789 } 790 791 Prog* 792 appendp(Prog *q) 793 { 794 Prog *p; 795 796 p = prg(); 797 p->link = q->link; 798 q->link = p; 799 p->line = q->line; 800 p->mode = q->mode; 801 return p; 802 }