github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/ld/lib.c (about) 1 // Derived from Inferno utils/6l/obj.c and utils/6l/span.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c 3 // http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c 4 // 5 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 6 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 7 // Portions Copyright © 1997-1999 Vita Nuova Limited 8 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 9 // Portions Copyright © 2004,2006 Bruce Ellis 10 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 11 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 12 // Portions Copyright © 2009 The Go Authors. All rights reserved. 13 // 14 // Permission is hereby granted, free of charge, to any person obtaining a copy 15 // of this software and associated documentation files (the "Software"), to deal 16 // in the Software without restriction, including without limitation the rights 17 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 // copies of the Software, and to permit persons to whom the Software is 19 // furnished to do so, subject to the following conditions: 20 // 21 // The above copyright notice and this permission notice shall be included in 22 // all copies or substantial portions of the Software. 23 // 24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 // THE SOFTWARE. 31 32 #include "l.h" 33 #include "lib.h" 34 #include "../ld/elf.h" 35 #include "../../pkg/runtime/stack.h" 36 37 #include <ar.h> 38 39 int iconv(Fmt*); 40 41 char symname[] = SYMDEF; 42 char pkgname[] = "__.PKGDEF"; 43 char** libdir; 44 int nlibdir = 0; 45 static int maxlibdir = 0; 46 static int cout = -1; 47 48 // Set if we see an object compiled by the host compiler that is not 49 // from a package that is known to support internal linking mode. 50 static int externalobj = 0; 51 52 static void hostlinksetup(void); 53 54 char* goroot; 55 char* goarch; 56 char* goos; 57 char* theline; 58 59 void 60 Lflag(char *arg) 61 { 62 char **p; 63 64 if(nlibdir >= maxlibdir) { 65 if (maxlibdir == 0) 66 maxlibdir = 8; 67 else 68 maxlibdir *= 2; 69 p = erealloc(libdir, maxlibdir * sizeof(*p)); 70 libdir = p; 71 } 72 libdir[nlibdir++] = arg; 73 } 74 75 void 76 libinit(void) 77 { 78 char *race; 79 80 fmtinstall('i', iconv); 81 fmtinstall('Y', Yconv); 82 fmtinstall('Z', Zconv); 83 mywhatsys(); // get goroot, goarch, goos 84 if(strcmp(goarch, thestring) != 0) 85 print("goarch is not known: %s\n", goarch); 86 87 // add goroot to the end of the libdir list. 88 race = ""; 89 if(flag_race) 90 race = "_race"; 91 Lflag(smprint("%s/pkg/%s_%s%s", goroot, goos, goarch, race)); 92 93 // Unix doesn't like it when we write to a running (or, sometimes, 94 // recently run) binary, so remove the output file before writing it. 95 // On Windows 7, remove() can force the following create() to fail. 96 #ifndef _WIN32 97 remove(outfile); 98 #endif 99 cout = create(outfile, 1, 0775); 100 if(cout < 0) { 101 diag("cannot create %s: %r", outfile); 102 errorexit(); 103 } 104 105 if(INITENTRY == nil) { 106 INITENTRY = mal(strlen(goarch)+strlen(goos)+10); 107 sprint(INITENTRY, "_rt0_%s_%s", goarch, goos); 108 } 109 lookup(INITENTRY, 0)->type = SXREF; 110 if(flag_shared) { 111 if(LIBINITENTRY == nil) { 112 LIBINITENTRY = mal(strlen(goarch)+strlen(goos)+20); 113 sprint(LIBINITENTRY, "_rt0_%s_%s_lib", goarch, goos); 114 } 115 lookup(LIBINITENTRY, 0)->type = SXREF; 116 } 117 } 118 119 void 120 errorexit(void) 121 { 122 if(nerrors) { 123 if(cout >= 0) 124 remove(outfile); 125 exits("error"); 126 } 127 exits(0); 128 } 129 130 void 131 addlib(char *src, char *obj) 132 { 133 char name[1024], pname[1024], comp[256], *p; 134 int i, search; 135 136 if(histfrogp <= 0) 137 return; 138 139 search = 0; 140 if(histfrog[0]->name[1] == '/') { 141 sprint(name, ""); 142 i = 1; 143 } else 144 if(isalpha((uchar)histfrog[0]->name[1]) && histfrog[0]->name[2] == ':') { 145 strcpy(name, histfrog[0]->name+1); 146 i = 1; 147 } else 148 if(histfrog[0]->name[1] == '.') { 149 sprint(name, "."); 150 i = 0; 151 } else { 152 sprint(name, ""); 153 i = 0; 154 search = 1; 155 } 156 157 for(; i<histfrogp; i++) { 158 snprint(comp, sizeof comp, "%s", histfrog[i]->name+1); 159 for(;;) { 160 p = strstr(comp, "$O"); 161 if(p == 0) 162 break; 163 memmove(p+1, p+2, strlen(p+2)+1); 164 p[0] = thechar; 165 } 166 for(;;) { 167 p = strstr(comp, "$M"); 168 if(p == 0) 169 break; 170 if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) { 171 diag("library component too long"); 172 return; 173 } 174 memmove(p+strlen(thestring), p+2, strlen(p+2)+1); 175 memmove(p, thestring, strlen(thestring)); 176 } 177 if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { 178 diag("library component too long"); 179 return; 180 } 181 if(i > 0 || !search) 182 strcat(name, "/"); 183 strcat(name, comp); 184 } 185 cleanname(name); 186 187 // runtime.a -> runtime 188 p = nil; 189 if(strlen(name) > 2 && name[strlen(name)-2] == '.') { 190 p = name+strlen(name)-2; 191 *p = '\0'; 192 } 193 194 // already loaded? 195 for(i=0; i<libraryp; i++) 196 if(strcmp(library[i].pkg, name) == 0) 197 return; 198 199 // runtime -> runtime.a for search 200 if(p != nil) 201 *p = '.'; 202 203 if(search) { 204 // try dot, -L "libdir", and then goroot. 205 for(i=0; i<nlibdir; i++) { 206 snprint(pname, sizeof pname, "%s/%s", libdir[i], name); 207 if(access(pname, AEXIST) >= 0) 208 break; 209 } 210 }else 211 strcpy(pname, name); 212 cleanname(pname); 213 214 /* runtime.a -> runtime */ 215 if(p != nil) 216 *p = '\0'; 217 218 if(debug['v']) 219 Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname); 220 221 addlibpath(src, obj, pname, name); 222 } 223 224 /* 225 * add library to library list. 226 * srcref: src file referring to package 227 * objref: object file referring to package 228 * file: object file, e.g., /home/rsc/go/pkg/container/vector.a 229 * pkg: package import path, e.g. container/vector 230 */ 231 void 232 addlibpath(char *srcref, char *objref, char *file, char *pkg) 233 { 234 int i; 235 Library *l; 236 char *p; 237 238 for(i=0; i<libraryp; i++) 239 if(strcmp(file, library[i].file) == 0) 240 return; 241 242 if(debug['v'] > 1) 243 Bprint(&bso, "%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s\n", 244 cputime(), srcref, objref, file, pkg); 245 246 if(libraryp == nlibrary){ 247 nlibrary = 50 + 2*libraryp; 248 library = erealloc(library, sizeof library[0] * nlibrary); 249 } 250 251 l = &library[libraryp++]; 252 253 p = mal(strlen(objref) + 1); 254 strcpy(p, objref); 255 l->objref = p; 256 257 p = mal(strlen(srcref) + 1); 258 strcpy(p, srcref); 259 l->srcref = p; 260 261 p = mal(strlen(file) + 1); 262 strcpy(p, file); 263 l->file = p; 264 265 p = mal(strlen(pkg) + 1); 266 strcpy(p, pkg); 267 l->pkg = p; 268 } 269 270 void 271 loadinternal(char *name) 272 { 273 char pname[1024]; 274 int i, found; 275 276 found = 0; 277 for(i=0; i<nlibdir; i++) { 278 snprint(pname, sizeof pname, "%s/%s.a", libdir[i], name); 279 if(debug['v']) 280 Bprint(&bso, "searching for %s.a in %s\n", name, pname); 281 if(access(pname, AEXIST) >= 0) { 282 addlibpath("internal", "internal", pname, name); 283 found = 1; 284 break; 285 } 286 } 287 if(!found) 288 Bprint(&bso, "warning: unable to find %s.a\n", name); 289 } 290 291 void 292 loadlib(void) 293 { 294 int i, w, x; 295 Sym *s; 296 297 loadinternal("runtime"); 298 if(thechar == '5') 299 loadinternal("math"); 300 if(flag_race) 301 loadinternal("runtime/race"); 302 if(linkmode == LinkExternal) { 303 // This indicates a user requested -linkmode=external. 304 // The startup code uses an import of runtime/cgo to decide 305 // whether to initialize the TLS. So give it one. This could 306 // be handled differently but it's an unusual case. 307 loadinternal("runtime/cgo"); 308 // Pretend that we really imported the package. 309 // This will do no harm if we did in fact import it. 310 s = lookup("go.importpath.runtime/cgo.", 0); 311 s->type = SDATA; 312 s->dupok = 1; 313 s->reachable = 1; 314 } 315 316 for(i=0; i<libraryp; i++) { 317 if(debug['v']) 318 Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i].file, library[i].objref); 319 iscgo |= strcmp(library[i].pkg, "runtime/cgo") == 0; 320 objfile(library[i].file, library[i].pkg); 321 } 322 323 if(linkmode == LinkAuto) { 324 if(iscgo && externalobj) 325 linkmode = LinkExternal; 326 else 327 linkmode = LinkInternal; 328 } 329 330 if(linkmode == LinkInternal) { 331 // Drop all the cgo_import_static declarations. 332 // Turns out we won't be needing them. 333 for(s = allsym; s != S; s = s->allsym) 334 if(s->type == SHOSTOBJ) { 335 // If a symbol was marked both 336 // cgo_import_static and cgo_import_dynamic, 337 // then we want to make it cgo_import_dynamic 338 // now. 339 if(s->extname != nil && s->dynimplib != nil && s->cgoexport == 0) { 340 s->type = SDYNIMPORT; 341 } else 342 s->type = 0; 343 } 344 } 345 346 // Now that we know the link mode, trim the dynexp list. 347 x = CgoExportDynamic; 348 if(linkmode == LinkExternal) 349 x = CgoExportStatic; 350 w = 0; 351 for(i=0; i<ndynexp; i++) 352 if(dynexp[i]->cgoexport & x) 353 dynexp[w++] = dynexp[i]; 354 ndynexp = w; 355 356 // In internal link mode, read the host object files. 357 if(linkmode == LinkInternal) 358 hostobjs(); 359 else 360 hostlinksetup(); 361 362 // We've loaded all the code now. 363 // If there are no dynamic libraries needed, gcc disables dynamic linking. 364 // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13) 365 // assumes that a dynamic binary always refers to at least one dynamic library. 366 // Rather than be a source of test cases for glibc, disable dynamic linking 367 // the same way that gcc would. 368 // 369 // Exception: on OS X, programs such as Shark only work with dynamic 370 // binaries, so leave it enabled on OS X (Mach-O) binaries. 371 if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin) 372 debug['d'] = 1; 373 374 importcycles(); 375 } 376 377 /* 378 * look for the next file in an archive. 379 * adapted from libmach. 380 */ 381 int 382 nextar(Biobuf *bp, int off, struct ar_hdr *a) 383 { 384 int r; 385 int32 arsize; 386 char *buf; 387 388 if (off&01) 389 off++; 390 Bseek(bp, off, 0); 391 buf = Brdline(bp, '\n'); 392 r = Blinelen(bp); 393 if(buf == nil) { 394 if(r == 0) 395 return 0; 396 return -1; 397 } 398 if(r != SAR_HDR) 399 return -1; 400 memmove(a, buf, SAR_HDR); 401 if(strncmp(a->fmag, ARFMAG, sizeof a->fmag)) 402 return -1; 403 arsize = strtol(a->size, 0, 0); 404 if (arsize&1) 405 arsize++; 406 return arsize + r; 407 } 408 409 void 410 objfile(char *file, char *pkg) 411 { 412 int32 off, l; 413 Biobuf *f; 414 char magbuf[SARMAG]; 415 char pname[150]; 416 struct ar_hdr arhdr; 417 418 pkg = smprint("%i", pkg); 419 420 if(debug['v']) 421 Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg); 422 Bflush(&bso); 423 f = Bopen(file, 0); 424 if(f == nil) { 425 diag("cannot open file: %s", file); 426 errorexit(); 427 } 428 l = Bread(f, magbuf, SARMAG); 429 if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ 430 /* load it as a regular file */ 431 l = Bseek(f, 0L, 2); 432 Bseek(f, 0L, 0); 433 ldobj(f, pkg, l, file, file, FileObj); 434 Bterm(f); 435 free(pkg); 436 return; 437 } 438 439 /* skip over __.GOSYMDEF */ 440 off = Boffset(f); 441 if((l = nextar(f, off, &arhdr)) <= 0) { 442 diag("%s: short read on archive file symbol header", file); 443 goto out; 444 } 445 if(strncmp(arhdr.name, symname, strlen(symname))) { 446 diag("%s: first entry not symbol header", file); 447 goto out; 448 } 449 off += l; 450 451 /* skip over (or process) __.PKGDEF */ 452 if((l = nextar(f, off, &arhdr)) <= 0) { 453 diag("%s: short read on archive file symbol header", file); 454 goto out; 455 } 456 if(strncmp(arhdr.name, pkgname, strlen(pkgname))) { 457 diag("%s: second entry not package header", file); 458 goto out; 459 } 460 off += l; 461 462 if(debug['u']) 463 ldpkg(f, pkg, atolwhex(arhdr.size), file, Pkgdef); 464 465 /* 466 * load all the object files from the archive now. 467 * this gives us sequential file access and keeps us 468 * from needing to come back later to pick up more 469 * objects. it breaks the usual C archive model, but 470 * this is Go, not C. the common case in Go is that 471 * we need to load all the objects, and then we throw away 472 * the individual symbols that are unused. 473 * 474 * loading every object will also make it possible to 475 * load foreign objects not referenced by __.GOSYMDEF. 476 */ 477 for(;;) { 478 l = nextar(f, off, &arhdr); 479 if(l == 0) 480 break; 481 if(l < 0) { 482 diag("%s: malformed archive", file); 483 goto out; 484 } 485 off += l; 486 487 l = SARNAME; 488 while(l > 0 && arhdr.name[l-1] == ' ') 489 l--; 490 snprint(pname, sizeof pname, "%s(%.*s)", file, utfnlen(arhdr.name, l), arhdr.name); 491 l = atolwhex(arhdr.size); 492 ldobj(f, pkg, l, pname, file, ArchiveObj); 493 } 494 495 out: 496 Bterm(f); 497 free(pkg); 498 } 499 500 static void 501 dowrite(int fd, char *p, int n) 502 { 503 int m; 504 505 while(n > 0) { 506 m = write(fd, p, n); 507 if(m <= 0) { 508 cursym = S; 509 diag("write error: %r"); 510 errorexit(); 511 } 512 n -= m; 513 p += m; 514 } 515 } 516 517 typedef struct Hostobj Hostobj; 518 519 struct Hostobj 520 { 521 void (*ld)(Biobuf*, char*, int64, char*); 522 char *pkg; 523 char *pn; 524 char *file; 525 int64 off; 526 int64 len; 527 }; 528 529 Hostobj *hostobj; 530 int nhostobj; 531 int mhostobj; 532 533 // These packages can use internal linking mode. 534 // Others trigger external mode. 535 const char *internalpkg[] = { 536 "crypto/x509", 537 "net", 538 "os/user", 539 "runtime/cgo", 540 "runtime/race" 541 }; 542 543 void 544 ldhostobj(void (*ld)(Biobuf*, char*, int64, char*), Biobuf *f, char *pkg, int64 len, char *pn, char *file) 545 { 546 int i, isinternal; 547 Hostobj *h; 548 549 isinternal = 0; 550 for(i=0; i<nelem(internalpkg); i++) { 551 if(strcmp(pkg, internalpkg[i]) == 0) { 552 isinternal = 1; 553 break; 554 } 555 } 556 557 if(!isinternal) 558 externalobj = 1; 559 560 if(nhostobj >= mhostobj) { 561 if(mhostobj == 0) 562 mhostobj = 16; 563 else 564 mhostobj *= 2; 565 hostobj = erealloc(hostobj, mhostobj*sizeof hostobj[0]); 566 } 567 h = &hostobj[nhostobj++]; 568 h->ld = ld; 569 h->pkg = estrdup(pkg); 570 h->pn = estrdup(pn); 571 h->file = estrdup(file); 572 h->off = Boffset(f); 573 h->len = len; 574 } 575 576 void 577 hostobjs(void) 578 { 579 int i; 580 Biobuf *f; 581 Hostobj *h; 582 583 for(i=0; i<nhostobj; i++) { 584 h = &hostobj[i]; 585 f = Bopen(h->file, OREAD); 586 if(f == nil) { 587 cursym = S; 588 diag("cannot reopen %s: %r", h->pn); 589 errorexit(); 590 } 591 Bseek(f, h->off, 0); 592 h->ld(f, h->pkg, h->len, h->pn); 593 Bterm(f); 594 } 595 } 596 597 // provided by lib9 598 int runcmd(char**); 599 char* mktempdir(void); 600 void removeall(char*); 601 602 static void 603 rmtemp(void) 604 { 605 removeall(tmpdir); 606 } 607 608 static void 609 hostlinksetup(void) 610 { 611 char *p; 612 613 if(linkmode != LinkExternal) 614 return; 615 616 // create temporary directory and arrange cleanup 617 if(tmpdir == nil) { 618 tmpdir = mktempdir(); 619 atexit(rmtemp); 620 } 621 622 // change our output to temporary object file 623 close(cout); 624 p = smprint("%s/go.o", tmpdir); 625 cout = create(p, 1, 0775); 626 if(cout < 0) { 627 diag("cannot create %s: %r", p); 628 errorexit(); 629 } 630 free(p); 631 } 632 633 void 634 hostlink(void) 635 { 636 char *p, **argv; 637 int c, i, w, n, argc, len; 638 Hostobj *h; 639 Biobuf *f; 640 static char buf[64<<10]; 641 642 if(linkmode != LinkExternal || nerrors > 0) 643 return; 644 645 c = 0; 646 p = extldflags; 647 while(p != nil) { 648 while(*p == ' ') 649 p++; 650 if(*p == '\0') 651 break; 652 c++; 653 p = strchr(p + 1, ' '); 654 } 655 656 argv = malloc((10+nhostobj+nldflag+c)*sizeof argv[0]); 657 argc = 0; 658 if(extld == nil) 659 extld = "gcc"; 660 argv[argc++] = extld; 661 switch(thechar){ 662 case '8': 663 argv[argc++] = "-m32"; 664 break; 665 case '6': 666 argv[argc++] = "-m64"; 667 break; 668 } 669 if(!debug['s']) 670 argv[argc++] = "-gdwarf-2"; 671 if(HEADTYPE == Hdarwin) 672 argv[argc++] = "-Wl,-no_pie,-pagezero_size,4000000"; 673 argv[argc++] = "-o"; 674 argv[argc++] = outfile; 675 676 if(rpath) 677 argv[argc++] = smprint("-Wl,-rpath,%s", rpath); 678 679 // Force global symbols to be exported for dlopen, etc. 680 if(iself) 681 argv[argc++] = "-rdynamic"; 682 683 // already wrote main object file 684 // copy host objects to temporary directory 685 for(i=0; i<nhostobj; i++) { 686 h = &hostobj[i]; 687 f = Bopen(h->file, OREAD); 688 if(f == nil) { 689 cursym = S; 690 diag("cannot reopen %s: %r", h->pn); 691 errorexit(); 692 } 693 Bseek(f, h->off, 0); 694 p = smprint("%s/%06d.o", tmpdir, i); 695 argv[argc++] = p; 696 w = create(p, 1, 0775); 697 if(w < 0) { 698 cursym = S; 699 diag("cannot create %s: %r", p); 700 errorexit(); 701 } 702 len = h->len; 703 while(len > 0 && (n = Bread(f, buf, sizeof buf)) > 0){ 704 if(n > len) 705 n = len; 706 dowrite(w, buf, n); 707 len -= n; 708 } 709 if(close(w) < 0) { 710 cursym = S; 711 diag("cannot write %s: %r", p); 712 errorexit(); 713 } 714 Bterm(f); 715 } 716 717 argv[argc++] = smprint("%s/go.o", tmpdir); 718 for(i=0; i<nldflag; i++) 719 argv[argc++] = ldflag[i]; 720 721 p = extldflags; 722 while(p != nil) { 723 while(*p == ' ') 724 *p++ = '\0'; 725 if(*p == '\0') 726 break; 727 argv[argc++] = p; 728 p = strchr(p + 1, ' '); 729 } 730 731 argv[argc] = nil; 732 733 quotefmtinstall(); 734 if(debug['v']) { 735 Bprint(&bso, "host link:"); 736 for(i=0; i<argc; i++) 737 Bprint(&bso, " %q", argv[i]); 738 Bprint(&bso, "\n"); 739 Bflush(&bso); 740 } 741 742 if(runcmd(argv) < 0) { 743 cursym = S; 744 diag("%s: running %s failed: %r", argv0, argv[0]); 745 errorexit(); 746 } 747 } 748 749 void 750 ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence) 751 { 752 char *line; 753 int n, c1, c2, c3, c4; 754 uint32 magic; 755 vlong import0, import1, eof; 756 char *t; 757 758 eof = Boffset(f) + len; 759 760 pn = estrdup(pn); 761 762 c1 = Bgetc(f); 763 c2 = Bgetc(f); 764 c3 = Bgetc(f); 765 c4 = Bgetc(f); 766 Bungetc(f); 767 Bungetc(f); 768 Bungetc(f); 769 Bungetc(f); 770 771 magic = c1<<24 | c2<<16 | c3<<8 | c4; 772 if(magic == 0x7f454c46) { // \x7F E L F 773 ldhostobj(ldelf, f, pkg, len, pn, file); 774 return; 775 } 776 if((magic&~1) == 0xfeedface || (magic&~0x01000000) == 0xcefaedfe) { 777 ldhostobj(ldmacho, f, pkg, len, pn, file); 778 return; 779 } 780 if(c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86) { 781 ldhostobj(ldpe, f, pkg, len, pn, file); 782 return; 783 } 784 785 /* check the header */ 786 line = Brdline(f, '\n'); 787 if(line == nil) { 788 if(Blinelen(f) > 0) { 789 diag("%s: not an object file", pn); 790 return; 791 } 792 goto eof; 793 } 794 n = Blinelen(f) - 1; 795 line[n] = '\0'; 796 if(strncmp(line, "go object ", 10) != 0) { 797 if(strlen(pn) > 3 && strcmp(pn+strlen(pn)-3, ".go") == 0) { 798 print("%cl: input %s is not .%c file (use %cg to compile .go files)\n", thechar, pn, thechar, thechar); 799 errorexit(); 800 } 801 if(strcmp(line, thestring) == 0) { 802 // old header format: just $GOOS 803 diag("%s: stale object file", pn); 804 return; 805 } 806 diag("%s: not an object file", pn); 807 free(pn); 808 return; 809 } 810 811 // First, check that the basic goos, string, and version match. 812 t = smprint("%s %s %s ", goos, thestring, getgoversion()); 813 line[n] = ' '; 814 if(strncmp(line+10, t, strlen(t)) != 0 && !debug['f']) { 815 line[n] = '\0'; 816 diag("%s: object is [%s] expected [%s]", pn, line+10, t); 817 free(t); 818 free(pn); 819 return; 820 } 821 822 // Second, check that longer lines match each other exactly, 823 // so that the Go compiler and write additional information 824 // that must be the same from run to run. 825 line[n] = '\0'; 826 if(n-10 > strlen(t)) { 827 if(theline == nil) 828 theline = estrdup(line+10); 829 else if(strcmp(theline, line+10) != 0) { 830 line[n] = '\0'; 831 diag("%s: object is [%s] expected [%s]", pn, line+10, theline); 832 free(t); 833 free(pn); 834 return; 835 } 836 } 837 free(t); 838 line[n] = '\n'; 839 840 /* skip over exports and other info -- ends with \n!\n */ 841 import0 = Boffset(f); 842 c1 = '\n'; // the last line ended in \n 843 c2 = Bgetc(f); 844 c3 = Bgetc(f); 845 while(c1 != '\n' || c2 != '!' || c3 != '\n') { 846 c1 = c2; 847 c2 = c3; 848 c3 = Bgetc(f); 849 if(c3 == Beof) 850 goto eof; 851 } 852 import1 = Boffset(f); 853 854 Bseek(f, import0, 0); 855 ldpkg(f, pkg, import1 - import0 - 2, pn, whence); // -2 for !\n 856 Bseek(f, import1, 0); 857 858 ldobj1(f, pkg, eof - Boffset(f), pn); 859 free(pn); 860 return; 861 862 eof: 863 diag("truncated object file: %s", pn); 864 free(pn); 865 } 866 867 Sym* 868 newsym(char *symb, int v) 869 { 870 Sym *s; 871 int l; 872 873 l = strlen(symb) + 1; 874 s = mal(sizeof(*s)); 875 if(debug['v'] > 1) 876 Bprint(&bso, "newsym %s\n", symb); 877 878 s->dynid = -1; 879 s->plt = -1; 880 s->got = -1; 881 s->name = mal(l + 1); 882 memmove(s->name, symb, l); 883 884 s->type = 0; 885 s->version = v; 886 s->value = 0; 887 s->sig = 0; 888 s->size = 0; 889 nsymbol++; 890 891 s->allsym = allsym; 892 allsym = s; 893 894 return s; 895 } 896 897 static Sym* 898 _lookup(char *symb, int v, int creat) 899 { 900 Sym *s; 901 char *p; 902 int32 h; 903 int c; 904 905 h = v; 906 for(p=symb; c = *p; p++) 907 h = h+h+h + c; 908 // not if(h < 0) h = ~h, because gcc 4.3 -O2 miscompiles it. 909 h &= 0xffffff; 910 h %= NHASH; 911 for(s = hash[h]; s != S; s = s->hash) 912 if(strcmp(s->name, symb) == 0) 913 return s; 914 if(!creat) 915 return nil; 916 917 s = newsym(symb, v); 918 s->extname = s->name; 919 s->hash = hash[h]; 920 hash[h] = s; 921 922 return s; 923 } 924 925 Sym* 926 lookup(char *name, int v) 927 { 928 return _lookup(name, v, 1); 929 } 930 931 // read-only lookup 932 Sym* 933 rlookup(char *name, int v) 934 { 935 return _lookup(name, v, 0); 936 } 937 938 void 939 copyhistfrog(char *buf, int nbuf) 940 { 941 char *p, *ep; 942 int i; 943 944 p = buf; 945 ep = buf + nbuf; 946 for(i=0; i<histfrogp; i++) { 947 p = seprint(p, ep, "%s", histfrog[i]->name+1); 948 if(i+1<histfrogp && (p == buf || p[-1] != '/')) 949 p = seprint(p, ep, "/"); 950 } 951 } 952 953 void 954 addhist(int32 line, int type) 955 { 956 Auto *u; 957 Sym *s; 958 int i, j, k; 959 960 u = mal(sizeof(Auto)); 961 s = mal(sizeof(Sym)); 962 s->name = mal(2*(histfrogp+1) + 1); 963 964 u->asym = s; 965 u->type = type; 966 u->aoffset = line; 967 u->link = curhist; 968 curhist = u; 969 970 s->name[0] = 0; 971 j = 1; 972 for(i=0; i<histfrogp; i++) { 973 k = histfrog[i]->value; 974 s->name[j+0] = k>>8; 975 s->name[j+1] = k; 976 j += 2; 977 } 978 s->name[j] = 0; 979 s->name[j+1] = 0; 980 } 981 982 void 983 histtoauto(void) 984 { 985 Auto *l; 986 987 while(l = curhist) { 988 curhist = l->link; 989 l->link = curauto; 990 curauto = l; 991 } 992 } 993 994 void 995 collapsefrog(Sym *s) 996 { 997 int i; 998 999 /* 1000 * bad encoding of path components only allows 1001 * MAXHIST components. if there is an overflow, 1002 * first try to collapse xxx/.. 1003 */ 1004 for(i=1; i<histfrogp; i++) 1005 if(strcmp(histfrog[i]->name+1, "..") == 0) { 1006 memmove(histfrog+i-1, histfrog+i+1, 1007 (histfrogp-i-1)*sizeof(histfrog[0])); 1008 histfrogp--; 1009 goto out; 1010 } 1011 1012 /* 1013 * next try to collapse . 1014 */ 1015 for(i=0; i<histfrogp; i++) 1016 if(strcmp(histfrog[i]->name+1, ".") == 0) { 1017 memmove(histfrog+i, histfrog+i+1, 1018 (histfrogp-i-1)*sizeof(histfrog[0])); 1019 goto out; 1020 } 1021 1022 /* 1023 * last chance, just truncate from front 1024 */ 1025 memmove(histfrog+0, histfrog+1, 1026 (histfrogp-1)*sizeof(histfrog[0])); 1027 1028 out: 1029 histfrog[histfrogp-1] = s; 1030 } 1031 1032 void 1033 nuxiinit(void) 1034 { 1035 int i, c; 1036 1037 for(i=0; i<4; i++) { 1038 c = find1(0x04030201L, i+1); 1039 if(i < 2) 1040 inuxi2[i] = c; 1041 if(i < 1) 1042 inuxi1[i] = c; 1043 inuxi4[i] = c; 1044 if(c == i) { 1045 inuxi8[i] = c; 1046 inuxi8[i+4] = c+4; 1047 } else { 1048 inuxi8[i] = c+4; 1049 inuxi8[i+4] = c; 1050 } 1051 fnuxi4[i] = c; 1052 fnuxi8[i] = c; 1053 fnuxi8[i+4] = c+4; 1054 } 1055 if(debug['v']) { 1056 Bprint(&bso, "inuxi = "); 1057 for(i=0; i<1; i++) 1058 Bprint(&bso, "%d", inuxi1[i]); 1059 Bprint(&bso, " "); 1060 for(i=0; i<2; i++) 1061 Bprint(&bso, "%d", inuxi2[i]); 1062 Bprint(&bso, " "); 1063 for(i=0; i<4; i++) 1064 Bprint(&bso, "%d", inuxi4[i]); 1065 Bprint(&bso, " "); 1066 for(i=0; i<8; i++) 1067 Bprint(&bso, "%d", inuxi8[i]); 1068 Bprint(&bso, "\nfnuxi = "); 1069 for(i=0; i<4; i++) 1070 Bprint(&bso, "%d", fnuxi4[i]); 1071 Bprint(&bso, " "); 1072 for(i=0; i<8; i++) 1073 Bprint(&bso, "%d", fnuxi8[i]); 1074 Bprint(&bso, "\n"); 1075 } 1076 Bflush(&bso); 1077 } 1078 1079 int 1080 find1(int32 l, int c) 1081 { 1082 char *p; 1083 int i; 1084 1085 p = (char*)&l; 1086 for(i=0; i<4; i++) 1087 if(*p++ == c) 1088 return i; 1089 return 0; 1090 } 1091 1092 int 1093 find2(int32 l, int c) 1094 { 1095 union { 1096 int32 l; 1097 short p[2]; 1098 } u; 1099 short *p; 1100 int i; 1101 1102 u.l = l; 1103 p = u.p; 1104 for(i=0; i<4; i+=2) { 1105 if(((*p >> 8) & 0xff) == c) 1106 return i; 1107 if((*p++ & 0xff) == c) 1108 return i+1; 1109 } 1110 return 0; 1111 } 1112 1113 int32 1114 ieeedtof(Ieee *e) 1115 { 1116 int exp; 1117 int32 v; 1118 1119 if(e->h == 0) 1120 return 0; 1121 exp = (e->h>>20) & ((1L<<11)-1L); 1122 exp -= (1L<<10) - 2L; 1123 v = (e->h & 0xfffffL) << 3; 1124 v |= (e->l >> 29) & 0x7L; 1125 if((e->l >> 28) & 1) { 1126 v++; 1127 if(v & 0x800000L) { 1128 v = (v & 0x7fffffL) >> 1; 1129 exp++; 1130 } 1131 } 1132 if(-148 <= exp && exp <= -126) { 1133 v |= 1<<23; 1134 v >>= -125 - exp; 1135 exp = -126; 1136 } 1137 else if(exp < -148 || exp >= 130) 1138 diag("double fp to single fp overflow: %.17g", ieeedtod(e)); 1139 v |= ((exp + 126) & 0xffL) << 23; 1140 v |= e->h & 0x80000000L; 1141 return v; 1142 } 1143 1144 double 1145 ieeedtod(Ieee *ieeep) 1146 { 1147 Ieee e; 1148 double fr; 1149 int exp; 1150 1151 if(ieeep->h & (1L<<31)) { 1152 e.h = ieeep->h & ~(1L<<31); 1153 e.l = ieeep->l; 1154 return -ieeedtod(&e); 1155 } 1156 if(ieeep->l == 0 && ieeep->h == 0) 1157 return 0; 1158 exp = (ieeep->h>>20) & ((1L<<11)-1L); 1159 exp -= (1L<<10) - 2L; 1160 fr = ieeep->l & ((1L<<16)-1L); 1161 fr /= 1L<<16; 1162 fr += (ieeep->l>>16) & ((1L<<16)-1L); 1163 fr /= 1L<<16; 1164 if(exp == -(1L<<10) - 2L) { 1165 fr += (ieeep->h & (1L<<20)-1L); 1166 exp++; 1167 } else 1168 fr += (ieeep->h & (1L<<20)-1L) | (1L<<20); 1169 fr /= 1L<<21; 1170 return ldexp(fr, exp); 1171 } 1172 1173 void 1174 zerosig(char *sp) 1175 { 1176 Sym *s; 1177 1178 s = lookup(sp, 0); 1179 s->sig = 0; 1180 } 1181 1182 int32 1183 Bget4(Biobuf *f) 1184 { 1185 uchar p[4]; 1186 1187 if(Bread(f, p, 4) != 4) 1188 return 0; 1189 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); 1190 } 1191 1192 void 1193 mywhatsys(void) 1194 { 1195 goroot = getgoroot(); 1196 goos = getgoos(); 1197 goarch = thestring; // ignore $GOARCH - we know who we are 1198 } 1199 1200 int 1201 pathchar(void) 1202 { 1203 return '/'; 1204 } 1205 1206 static uchar* hunk; 1207 static uint32 nhunk; 1208 #define NHUNK (10UL<<20) 1209 1210 void* 1211 mal(uint32 n) 1212 { 1213 void *v; 1214 1215 n = (n+7)&~7; 1216 if(n > NHUNK) { 1217 v = malloc(n); 1218 if(v == nil) { 1219 diag("out of memory"); 1220 errorexit(); 1221 } 1222 memset(v, 0, n); 1223 return v; 1224 } 1225 if(n > nhunk) { 1226 hunk = malloc(NHUNK); 1227 if(hunk == nil) { 1228 diag("out of memory"); 1229 errorexit(); 1230 } 1231 nhunk = NHUNK; 1232 } 1233 1234 v = hunk; 1235 nhunk -= n; 1236 hunk += n; 1237 1238 memset(v, 0, n); 1239 return v; 1240 } 1241 1242 void 1243 unmal(void *v, uint32 n) 1244 { 1245 n = (n+7)&~7; 1246 if(hunk - n == v) { 1247 hunk -= n; 1248 nhunk += n; 1249 } 1250 } 1251 1252 // Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync. 1253 /* 1254 * Convert raw string to the prefix that will be used in the symbol table. 1255 * Invalid bytes turn into %xx. Right now the only bytes that need 1256 * escaping are %, ., and ", but we escape all control characters too. 1257 * 1258 * Must be same as ../gc/subr.c:/^pathtoprefix. 1259 */ 1260 static char* 1261 pathtoprefix(char *s) 1262 { 1263 static char hex[] = "0123456789abcdef"; 1264 char *p, *r, *w, *l; 1265 int n; 1266 1267 // find first character past the last slash, if any. 1268 l = s; 1269 for(r=s; *r; r++) 1270 if(*r == '/') 1271 l = r+1; 1272 1273 // check for chars that need escaping 1274 n = 0; 1275 for(r=s; *r; r++) 1276 if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f) 1277 n++; 1278 1279 // quick exit 1280 if(n == 0) 1281 return s; 1282 1283 // escape 1284 p = mal((r-s)+1+2*n); 1285 for(r=s, w=p; *r; r++) { 1286 if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f) { 1287 *w++ = '%'; 1288 *w++ = hex[(*r>>4)&0xF]; 1289 *w++ = hex[*r&0xF]; 1290 } else 1291 *w++ = *r; 1292 } 1293 *w = '\0'; 1294 return p; 1295 } 1296 1297 int 1298 iconv(Fmt *fp) 1299 { 1300 char *p; 1301 1302 p = va_arg(fp->args, char*); 1303 if(p == nil) { 1304 fmtstrcpy(fp, "<nil>"); 1305 return 0; 1306 } 1307 p = pathtoprefix(p); 1308 fmtstrcpy(fp, p); 1309 return 0; 1310 } 1311 1312 void 1313 mangle(char *file) 1314 { 1315 fprint(2, "%s: mangled input file\n", file); 1316 errorexit(); 1317 } 1318 1319 Section* 1320 addsection(Segment *seg, char *name, int rwx) 1321 { 1322 Section **l; 1323 Section *sect; 1324 1325 for(l=&seg->sect; *l; l=&(*l)->next) 1326 ; 1327 sect = mal(sizeof *sect); 1328 sect->rwx = rwx; 1329 sect->name = name; 1330 sect->seg = seg; 1331 sect->align = PtrSize; // everything is at least pointer-aligned 1332 *l = sect; 1333 return sect; 1334 } 1335 1336 void 1337 pclntab(void) 1338 { 1339 vlong oldpc; 1340 Prog *p; 1341 int32 oldlc, v, s; 1342 Sym *sym; 1343 uchar *bp; 1344 1345 sym = lookup("pclntab", 0); 1346 sym->type = SPCLNTAB; 1347 sym->reachable = 1; 1348 if(debug['s']) 1349 return; 1350 1351 oldpc = INITTEXT; 1352 oldlc = 0; 1353 for(cursym = textp; cursym != nil; cursym = cursym->next) { 1354 for(p = cursym->text; p != P; p = p->link) { 1355 if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { 1356 if(debug['O']) 1357 Bprint(&bso, "%6llux %P\n", 1358 (vlong)p->pc, p); 1359 continue; 1360 } 1361 if(debug['O']) 1362 Bprint(&bso, "\t\t%6d", lcsize); 1363 v = (p->pc - oldpc) / MINLC; 1364 while(v) { 1365 s = 127; 1366 if(v < 127) 1367 s = v; 1368 symgrow(sym, lcsize+1); 1369 bp = sym->p + lcsize; 1370 *bp = s+128; /* 129-255 +pc */ 1371 if(debug['O']) 1372 Bprint(&bso, " pc+%d*%d(%d)", s, MINLC, s+128); 1373 v -= s; 1374 lcsize++; 1375 } 1376 s = p->line - oldlc; 1377 oldlc = p->line; 1378 oldpc = p->pc + MINLC; 1379 if(s > 64 || s < -64) { 1380 symgrow(sym, lcsize+5); 1381 bp = sym->p + lcsize; 1382 *bp++ = 0; /* 0 vv +lc */ 1383 *bp++ = s>>24; 1384 *bp++ = s>>16; 1385 *bp++ = s>>8; 1386 *bp = s; 1387 if(debug['O']) { 1388 if(s > 0) 1389 Bprint(&bso, " lc+%d(%d,%d)\n", 1390 s, 0, s); 1391 else 1392 Bprint(&bso, " lc%d(%d,%d)\n", 1393 s, 0, s); 1394 Bprint(&bso, "%6llux %P\n", 1395 (vlong)p->pc, p); 1396 } 1397 lcsize += 5; 1398 continue; 1399 } 1400 symgrow(sym, lcsize+1); 1401 bp = sym->p + lcsize; 1402 if(s > 0) { 1403 *bp = 0+s; /* 1-64 +lc */ 1404 if(debug['O']) { 1405 Bprint(&bso, " lc+%d(%d)\n", s, 0+s); 1406 Bprint(&bso, "%6llux %P\n", 1407 (vlong)p->pc, p); 1408 } 1409 } else { 1410 *bp = 64-s; /* 65-128 -lc */ 1411 if(debug['O']) { 1412 Bprint(&bso, " lc%d(%d)\n", s, 64-s); 1413 Bprint(&bso, "%6llux %P\n", 1414 (vlong)p->pc, p); 1415 } 1416 } 1417 lcsize++; 1418 } 1419 } 1420 if(lcsize & 1) { 1421 symgrow(sym, lcsize+1); 1422 sym->p[lcsize] = 129; 1423 lcsize++; 1424 } 1425 sym->size = lcsize; 1426 lcsize = 0; 1427 1428 if(debug['v'] || debug['O']) 1429 Bprint(&bso, "lcsize = %d\n", lcsize); 1430 Bflush(&bso); 1431 } 1432 1433 #define LOG 5 1434 void 1435 mkfwd(void) 1436 { 1437 Prog *p; 1438 int i; 1439 int32 dwn[LOG], cnt[LOG]; 1440 Prog *lst[LOG]; 1441 1442 for(i=0; i<LOG; i++) { 1443 if(i == 0) 1444 cnt[i] = 1; 1445 else 1446 cnt[i] = LOG * cnt[i-1]; 1447 dwn[i] = 1; 1448 lst[i] = P; 1449 } 1450 i = 0; 1451 for(cursym = textp; cursym != nil; cursym = cursym->next) { 1452 for(p = cursym->text; p != P; p = p->link) { 1453 if(p->link == P) { 1454 if(cursym->next) 1455 p->forwd = cursym->next->text; 1456 break; 1457 } 1458 i--; 1459 if(i < 0) 1460 i = LOG-1; 1461 p->forwd = P; 1462 dwn[i]--; 1463 if(dwn[i] <= 0) { 1464 dwn[i] = cnt[i]; 1465 if(lst[i] != P) 1466 lst[i]->forwd = p; 1467 lst[i] = p; 1468 } 1469 } 1470 } 1471 } 1472 1473 uint16 1474 le16(uchar *b) 1475 { 1476 return b[0] | b[1]<<8; 1477 } 1478 1479 uint32 1480 le32(uchar *b) 1481 { 1482 return b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24; 1483 } 1484 1485 uint64 1486 le64(uchar *b) 1487 { 1488 return le32(b) | (uint64)le32(b+4)<<32; 1489 } 1490 1491 uint16 1492 be16(uchar *b) 1493 { 1494 return b[0]<<8 | b[1]; 1495 } 1496 1497 uint32 1498 be32(uchar *b) 1499 { 1500 return b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3]; 1501 } 1502 1503 uint64 1504 be64(uchar *b) 1505 { 1506 return (uvlong)be32(b)<<32 | be32(b+4); 1507 } 1508 1509 Endian be = { be16, be32, be64 }; 1510 Endian le = { le16, le32, le64 }; 1511 1512 typedef struct Chain Chain; 1513 struct Chain 1514 { 1515 Sym *sym; 1516 Chain *up; 1517 int limit; // limit on entry to sym 1518 }; 1519 1520 static int stkcheck(Chain*, int); 1521 static void stkprint(Chain*, int); 1522 static void stkbroke(Chain*, int); 1523 static Sym *morestack; 1524 static Sym *newstack; 1525 1526 enum 1527 { 1528 HasLinkRegister = (thechar == '5'), 1529 CallSize = (!HasLinkRegister)*PtrSize, // bytes of stack required for a call 1530 }; 1531 1532 void 1533 dostkcheck(void) 1534 { 1535 Chain ch; 1536 Sym *s; 1537 1538 morestack = lookup("runtime.morestack", 0); 1539 newstack = lookup("runtime.newstack", 0); 1540 1541 // First the nosplits on their own. 1542 for(s = textp; s != nil; s = s->next) { 1543 if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) == 0) 1544 continue; 1545 cursym = s; 1546 ch.up = nil; 1547 ch.sym = s; 1548 ch.limit = StackLimit - CallSize; 1549 stkcheck(&ch, 0); 1550 s->stkcheck = 1; 1551 } 1552 1553 // Check calling contexts. 1554 // Some nosplits get called a little further down, 1555 // like newproc and deferproc. We could hard-code 1556 // that knowledge but it's more robust to look at 1557 // the actual call sites. 1558 for(s = textp; s != nil; s = s->next) { 1559 if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) != 0) 1560 continue; 1561 cursym = s; 1562 ch.up = nil; 1563 ch.sym = s; 1564 ch.limit = StackLimit - CallSize; 1565 stkcheck(&ch, 0); 1566 } 1567 } 1568 1569 static int 1570 stkcheck(Chain *up, int depth) 1571 { 1572 Chain ch, ch1; 1573 Prog *p; 1574 Sym *s; 1575 int limit, prolog; 1576 1577 limit = up->limit; 1578 s = up->sym; 1579 p = s->text; 1580 1581 // Small optimization: don't repeat work at top. 1582 if(s->stkcheck && limit == StackLimit-CallSize) 1583 return 0; 1584 1585 if(depth > 100) { 1586 diag("nosplit stack check too deep"); 1587 stkbroke(up, 0); 1588 return -1; 1589 } 1590 1591 if(p == nil || p->link == nil) { 1592 // external function. 1593 // should never be called directly. 1594 // only diagnose the direct caller. 1595 if(depth == 1) 1596 diag("call to external function %s", s->name); 1597 return -1; 1598 } 1599 1600 if(limit < 0) { 1601 stkbroke(up, limit); 1602 return -1; 1603 } 1604 1605 // morestack looks like it calls functions, 1606 // but it switches the stack pointer first. 1607 if(s == morestack) 1608 return 0; 1609 1610 ch.up = up; 1611 prolog = (s->text->textflag & NOSPLIT) == 0; 1612 for(p = s->text; p != P; p = p->link) { 1613 limit -= p->spadj; 1614 if(prolog && p->spadj != 0) { 1615 // The first stack adjustment in a function with a 1616 // split-checking prologue marks the end of the 1617 // prologue. Assuming the split check is correct, 1618 // after the adjustment there should still be at least 1619 // StackLimit bytes available below the stack pointer. 1620 // If this is not the top call in the chain, no need 1621 // to duplicate effort, so just stop. 1622 if(depth > 0) 1623 return 0; 1624 prolog = 0; 1625 limit = StackLimit; 1626 } 1627 if(limit < 0) { 1628 stkbroke(up, limit); 1629 return -1; 1630 } 1631 if(iscall(p)) { 1632 limit -= CallSize; 1633 ch.limit = limit; 1634 if(p->to.type == D_BRANCH) { 1635 // Direct call. 1636 ch.sym = p->to.sym; 1637 if(stkcheck(&ch, depth+1) < 0) 1638 return -1; 1639 } else { 1640 // Indirect call. Assume it is a splitting function, 1641 // so we have to make sure it can call morestack. 1642 limit -= CallSize; 1643 ch.sym = nil; 1644 ch1.limit = limit; 1645 ch1.up = &ch; 1646 ch1.sym = morestack; 1647 if(stkcheck(&ch1, depth+2) < 0) 1648 return -1; 1649 limit += CallSize; 1650 } 1651 limit += CallSize; 1652 } 1653 1654 } 1655 return 0; 1656 } 1657 1658 static void 1659 stkbroke(Chain *ch, int limit) 1660 { 1661 diag("nosplit stack overflow"); 1662 stkprint(ch, limit); 1663 } 1664 1665 static void 1666 stkprint(Chain *ch, int limit) 1667 { 1668 char *name; 1669 1670 if(ch->sym) 1671 name = ch->sym->name; 1672 else 1673 name = "function pointer"; 1674 1675 if(ch->up == nil) { 1676 // top of chain. ch->sym != nil. 1677 if(ch->sym->text->textflag & NOSPLIT) 1678 print("\t%d\tassumed on entry to %s\n", ch->limit, name); 1679 else 1680 print("\t%d\tguaranteed after split check in %s\n", ch->limit, name); 1681 } else { 1682 stkprint(ch->up, ch->limit + (!HasLinkRegister)*PtrSize); 1683 if(!HasLinkRegister) 1684 print("\t%d\ton entry to %s\n", ch->limit, name); 1685 } 1686 if(ch->limit != limit) 1687 print("\t%d\tafter %s uses %d\n", limit, name, ch->limit - limit); 1688 } 1689 1690 int 1691 headtype(char *name) 1692 { 1693 int i; 1694 1695 for(i=0; headers[i].name; i++) 1696 if(strcmp(name, headers[i].name) == 0) { 1697 headstring = headers[i].name; 1698 return headers[i].val; 1699 } 1700 fprint(2, "unknown header type -H %s\n", name); 1701 errorexit(); 1702 return -1; // not reached 1703 } 1704 1705 char* 1706 headstr(int v) 1707 { 1708 static char buf[20]; 1709 int i; 1710 1711 for(i=0; headers[i].name; i++) 1712 if(v == headers[i].val) 1713 return headers[i].name; 1714 snprint(buf, sizeof buf, "%d", v); 1715 return buf; 1716 } 1717 1718 void 1719 undef(void) 1720 { 1721 Sym *s; 1722 1723 for(s = allsym; s != S; s = s->allsym) 1724 if(s->type == SXREF) 1725 diag("%s(%d): not defined", s->name, s->version); 1726 } 1727 1728 int 1729 Yconv(Fmt *fp) 1730 { 1731 Sym *s; 1732 Fmt fmt; 1733 int i; 1734 char *str; 1735 1736 s = va_arg(fp->args, Sym*); 1737 if (s == S) { 1738 fmtprint(fp, "<nil>"); 1739 } else { 1740 fmtstrinit(&fmt); 1741 fmtprint(&fmt, "%s @0x%08llx [%lld]", s->name, (vlong)s->value, (vlong)s->size); 1742 for (i = 0; i < s->size; i++) { 1743 if (!(i%8)) fmtprint(&fmt, "\n\t0x%04x ", i); 1744 fmtprint(&fmt, "%02x ", s->p[i]); 1745 } 1746 fmtprint(&fmt, "\n"); 1747 for (i = 0; i < s->nr; i++) { 1748 fmtprint(&fmt, "\t0x%04x[%x] %d %s[%llx]\n", 1749 s->r[i].off, 1750 s->r[i].siz, 1751 s->r[i].type, 1752 s->r[i].sym->name, 1753 (vlong)s->r[i].add); 1754 } 1755 str = fmtstrflush(&fmt); 1756 fmtstrcpy(fp, str); 1757 free(str); 1758 } 1759 1760 return 0; 1761 } 1762 1763 vlong coutpos; 1764 1765 void 1766 cflush(void) 1767 { 1768 int n; 1769 1770 if(cbpmax < cbp) 1771 cbpmax = cbp; 1772 n = cbpmax - buf.cbuf; 1773 dowrite(cout, buf.cbuf, n); 1774 coutpos += n; 1775 cbp = buf.cbuf; 1776 cbc = sizeof(buf.cbuf); 1777 cbpmax = cbp; 1778 } 1779 1780 vlong 1781 cpos(void) 1782 { 1783 return coutpos + cbp - buf.cbuf; 1784 } 1785 1786 void 1787 cseek(vlong p) 1788 { 1789 vlong start; 1790 int delta; 1791 1792 if(cbpmax < cbp) 1793 cbpmax = cbp; 1794 start = coutpos; 1795 if(start <= p && p <= start+(cbpmax - buf.cbuf)) { 1796 //print("cseek %lld in [%lld,%lld] (%lld)\n", p, start, start+sizeof(buf.cbuf), cpos()); 1797 delta = p - (start + cbp - buf.cbuf); 1798 cbp += delta; 1799 cbc -= delta; 1800 //print("now at %lld\n", cpos()); 1801 return; 1802 } 1803 1804 cflush(); 1805 seek(cout, p, 0); 1806 coutpos = p; 1807 } 1808 1809 void 1810 cwrite(void *buf, int n) 1811 { 1812 cflush(); 1813 if(n <= 0) 1814 return; 1815 dowrite(cout, buf, n); 1816 coutpos += n; 1817 } 1818 1819 void 1820 usage(void) 1821 { 1822 fprint(2, "usage: %cl [options] main.%c\n", thechar, thechar); 1823 flagprint(2); 1824 exits("usage"); 1825 } 1826 1827 void 1828 setheadtype(char *s) 1829 { 1830 HEADTYPE = headtype(s); 1831 } 1832 1833 void 1834 setinterp(char *s) 1835 { 1836 debug['I'] = 1; // denote cmdline interpreter override 1837 interpreter = s; 1838 } 1839 1840 void 1841 doversion(void) 1842 { 1843 print("%cl version %s\n", thechar, getgoversion()); 1844 errorexit(); 1845 } 1846 1847 void 1848 genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*)) 1849 { 1850 Auto *a; 1851 Sym *s; 1852 int32 off; 1853 1854 // These symbols won't show up in the first loop below because we 1855 // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. 1856 s = lookup("text", 0); 1857 if(s->type == STEXT) 1858 put(s, s->name, 'T', s->value, s->size, s->version, 0); 1859 s = lookup("etext", 0); 1860 if(s->type == STEXT) 1861 put(s, s->name, 'T', s->value, s->size, s->version, 0); 1862 1863 for(s=allsym; s!=S; s=s->allsym) { 1864 if(s->hide || (s->name[0] == '.' && s->version == 0 && strcmp(s->name, ".rathole") != 0)) 1865 continue; 1866 switch(s->type&SMASK) { 1867 case SCONST: 1868 case SRODATA: 1869 case SSYMTAB: 1870 case SPCLNTAB: 1871 case SDATA: 1872 case SNOPTRDATA: 1873 case SELFROSECT: 1874 case SMACHOGOT: 1875 case STYPE: 1876 case SSTRING: 1877 case SGOSTRING: 1878 case SWINDOWS: 1879 if(!s->reachable) 1880 continue; 1881 put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype); 1882 continue; 1883 1884 case SBSS: 1885 case SNOPTRBSS: 1886 if(!s->reachable) 1887 continue; 1888 if(s->np > 0) 1889 diag("%s should not be bss (size=%d type=%d special=%d)", s->name, (int)s->np, s->type, s->special); 1890 put(s, s->name, 'B', symaddr(s), s->size, s->version, s->gotype); 1891 continue; 1892 1893 case SFILE: 1894 put(nil, s->name, 'f', s->value, 0, s->version, 0); 1895 continue; 1896 } 1897 } 1898 1899 for(s = textp; s != nil; s = s->next) { 1900 if(s->text == nil) 1901 continue; 1902 1903 /* filenames first */ 1904 for(a=s->autom; a; a=a->link) 1905 if(a->type == D_FILE) 1906 put(nil, a->asym->name, 'z', a->aoffset, 0, 0, 0); 1907 else 1908 if(a->type == D_FILE1) 1909 put(nil, a->asym->name, 'Z', a->aoffset, 0, 0, 0); 1910 1911 put(s, s->name, 'T', s->value, s->size, s->version, s->gotype); 1912 1913 /* frame, locals, args, auto and param after */ 1914 put(nil, ".frame", 'm', (uint32)s->text->to.offset+PtrSize, 0, 0, 0); 1915 put(nil, ".locals", 'm', s->locals, 0, 0, 0); 1916 if(s->text->textflag & NOSPLIT) 1917 put(nil, ".args", 'm', ArgsSizeUnknown, 0, 0, 0); 1918 else 1919 put(nil, ".args", 'm', s->args, 0, 0, 0); 1920 1921 for(a=s->autom; a; a=a->link) { 1922 // Emit a or p according to actual offset, even if label is wrong. 1923 // This avoids negative offsets, which cannot be encoded. 1924 if(a->type != D_AUTO && a->type != D_PARAM) 1925 continue; 1926 1927 // compute offset relative to FP 1928 if(a->type == D_PARAM) 1929 off = a->aoffset; 1930 else 1931 off = a->aoffset - PtrSize; 1932 1933 // FP 1934 if(off >= 0) { 1935 put(nil, a->asym->name, 'p', off, 0, 0, a->gotype); 1936 continue; 1937 } 1938 1939 // SP 1940 if(off <= -PtrSize) { 1941 put(nil, a->asym->name, 'a', -(off+PtrSize), 0, 0, a->gotype); 1942 continue; 1943 } 1944 1945 // Otherwise, off is addressing the saved program counter. 1946 // Something underhanded is going on. Say nothing. 1947 } 1948 } 1949 if(debug['v'] || debug['n']) 1950 Bprint(&bso, "symsize = %ud\n", symsize); 1951 Bflush(&bso); 1952 } 1953 1954 char* 1955 estrdup(char *p) 1956 { 1957 p = strdup(p); 1958 if(p == nil) { 1959 cursym = S; 1960 diag("out of memory"); 1961 errorexit(); 1962 } 1963 return p; 1964 } 1965 1966 void* 1967 erealloc(void *p, long n) 1968 { 1969 p = realloc(p, n); 1970 if(p == nil) { 1971 cursym = S; 1972 diag("out of memory"); 1973 errorexit(); 1974 } 1975 return p; 1976 }